diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index a373d685e0..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,225 +0,0 @@ -version: 2.1 - -orbs: - ruby: circleci/ruby@2.0.0 - node: circleci/node@5.0.3 - -executors: - default: - parameters: - ruby-version: - type: string - docker: - - image: cimg/ruby:<< parameters.ruby-version >> - environment: - BUNDLE_JOBS: 3 - BUNDLE_RETRY: 3 - CONTINUOUS_INTEGRATION: true - DB_HOST: localhost - DB_USER: root - DISABLE_SIMPLECOV: true - RAILS_ENV: test - - image: cimg/postgres:14.5 - environment: - POSTGRES_USER: root - POSTGRES_HOST_AUTH_METHOD: trust - - image: cimg/redis:7.0 - -commands: - install-system-dependencies: - steps: - - run: - name: Install system dependencies - command: | - sudo apt-get update - sudo apt-get install -y libicu-dev libidn11-dev - install-ruby-dependencies: - parameters: - ruby-version: - type: string - steps: - - run: - command: | - bundle config clean 'true' - bundle config frozen 'true' - bundle config without 'development production' - name: Set bundler settings - - ruby/install-deps: - bundler-version: '2.3.26' - key: ruby<< parameters.ruby-version >>-gems-v1 - wait-db: - steps: - - run: - command: dockerize -wait tcp://localhost:5432 -wait tcp://localhost:6379 -timeout 1m - name: Wait for PostgreSQL and Redis - -jobs: - build: - docker: - - image: cimg/ruby:3.0-node - environment: - RAILS_ENV: test - steps: - - checkout - - install-system-dependencies - - install-ruby-dependencies: - ruby-version: '3.0' - - node/install-packages: - cache-version: v1 - pkg-manager: yarn - - run: - command: | - export NODE_OPTIONS=--openssl-legacy-provider - ./bin/rails assets:precompile - name: Precompile assets - - persist_to_workspace: - paths: - - public/assets - - public/packs-test - root: . - - test: - parameters: - ruby-version: - type: string - executor: - name: default - ruby-version: << parameters.ruby-version >> - environment: - ALLOW_NOPAM: true - PAM_ENABLED: true - PAM_DEFAULT_SERVICE: pam_test - PAM_CONTROLLED_SERVICE: pam_test_controlled - parallelism: 4 - steps: - - checkout - - install-system-dependencies - - run: - command: sudo apt-get install -y ffmpeg imagemagick libpam-dev - name: Install additional system dependencies - - run: - command: bundle config with 'pam_authentication' - name: Enable PAM authentication - - install-ruby-dependencies: - ruby-version: << parameters.ruby-version >> - - attach_workspace: - at: . - - wait-db - - run: - command: ./bin/rails db:create db:schema:load db:seed - name: Load database schema - - ruby/rspec-test - - test-migrations: - executor: - name: default - ruby-version: '3.0' - steps: - - checkout - - install-system-dependencies - - install-ruby-dependencies: - ruby-version: '3.0' - - wait-db - - run: - command: ./bin/rails db:create - name: Create database - - run: - command: ./bin/rails db:migrate VERSION=20171010025614 - name: Run migrations up to v2.0.0 - - run: - command: ./bin/rails tests:migrations:populate_v2 - name: Populate database with test data - - run: - command: ./bin/rails db:migrate VERSION=20180514140000 - name: Run migrations up to v2.4.0 - - run: - command: ./bin/rails tests:migrations:populate_v2_4 - name: Populate database with test data - - run: - command: ./bin/rails db:migrate VERSION=20180707154237 - name: Run migrations up to v2.4.3 - - run: - command: ./bin/rails tests:migrations:populate_v2_4_3 - name: Populate database with test data - - run: - command: ./bin/rails db:migrate - name: Run all remaining migrations - - run: - command: ./bin/rails tests:migrations:check_database - name: Check migration result - - test-two-step-migrations: - executor: - name: default - ruby-version: '3.0' - steps: - - checkout - - install-system-dependencies - - install-ruby-dependencies: - ruby-version: '3.0' - - wait-db - - run: - command: ./bin/rails db:create - name: Create database - - run: - command: ./bin/rails db:migrate VERSION=20171010025614 - name: Run migrations up to v2.0.0 - - run: - command: ./bin/rails tests:migrations:populate_v2 - name: Populate database with test data - - run: - command: ./bin/rails db:migrate VERSION=20180514140000 - name: Run pre-deployment migrations up to v2.4.0 - environment: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - run: - command: ./bin/rails tests:migrations:populate_v2_4 - name: Populate database with test data - - run: - command: ./bin/rails db:migrate VERSION=20180707154237 - name: Run migrations up to v2.4.3 - environment: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - run: - command: ./bin/rails tests:migrations:populate_v2_4_3 - name: Populate database with test data - - run: - command: ./bin/rails db:migrate - name: Run all remaining pre-deployment migrations - environment: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - run: - command: ./bin/rails db:migrate - name: Run all post-deployment migrations - - run: - command: ./bin/rails tests:migrations:check_database - name: Check migration result - -workflows: - version: 2 - build-and-test: - jobs: - - build - - test: - matrix: - parameters: - ruby-version: - - '2.7' - - '3.0' - name: test-ruby<< matrix.ruby-version >> - requires: - - build - - test-migrations: - requires: - - build - - test-two-step-migrations: - requires: - - build - - node/run: - cache-version: v1 - name: test-webui - pkg-manager: yarn - requires: - - build - version: '16.18' - yarn-run: test:jest diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 59051aae7a..0000000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: '2' -checks: - argument-count: - enabled: false - complex-logic: - enabled: false - file-lines: - enabled: false - method-complexity: - enabled: false - method-count: - enabled: false - method-lines: - enabled: false - nested-control-flow: - enabled: false - return-statements: - enabled: false - similar-code: - enabled: false - identical-code: - enabled: false -plugins: - brakeman: - enabled: true - bundler-audit: - enabled: true - eslint: - enabled: false - rubocop: - enabled: false - sass-lint: - enabled: false -exclude_patterns: - - spec/ - - vendor/asset/ - - - app/javascript/mastodon/locales/**/*.json - - config/locales/**/*.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 425b86a6bb..b3b1d97a24 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,16 +1,10 @@ -# [Choice] Ruby version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.1, 3.0, 2, 2.7, 2.6, 3-bullseye, 3.1-bullseye, 3.0-bullseye, 2-bullseye, 2.7-bullseye, 2.6-bullseye, 3-buster, 3.1-buster, 3.0-buster, 2-buster, 2.7-buster, 2.6-buster -ARG VARIANT=3.1-bullseye -FROM mcr.microsoft.com/vscode/devcontainers/ruby:${VARIANT} +# For details, see https://github.com/devcontainers/images/tree/main/src/ruby +FROM mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye # Install Rails # RUN gem install rails webdrivers -# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service -# The value is a comma-separated list of allowed domains -ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev" - -# [Choice] Node.js version: lts/*, 18, 16, 14 -ARG NODE_VERSION="lts/*" +ARG NODE_VERSION="16" RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1" # [Optional] Uncomment this section to install additional OS packages. @@ -22,3 +16,5 @@ RUN gem install foreman # [Optional] Uncomment this line to install global node packages. RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g yarn" 2>&1 + +COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt diff --git a/.devcontainer/codespaces/devcontainer.json b/.devcontainer/codespaces/devcontainer.json new file mode 100644 index 0000000000..ca9156fdaa --- /dev/null +++ b/.devcontainer/codespaces/devcontainer.json @@ -0,0 +1,49 @@ +{ + "name": "Mastodon on GitHub Codespaces", + "dockerComposeFile": "../docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + + "features": { + "ghcr.io/devcontainers/features/sshd:1": {} + }, + + "runServices": ["app", "db", "redis"], + + "forwardPorts": [3000, 4000], + + "portsAttributes": { + "3000": { + "label": "web", + "onAutoForward": "notify" + }, + "4000": { + "label": "stream", + "onAutoForward": "silent" + } + }, + + "otherPortsAttributes": { + "onAutoForward": "silent" + }, + + "remoteEnv": { + "LOCAL_DOMAIN": "${localEnv:CODESPACE_NAME}-3000.app.github.dev", + "LOCAL_HTTPS": "true", + "STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev", + "DISABLE_FORGERY_REQUEST_PROTECTION": "true", + "ES_ENABLED": "", + "LIBRE_TRANSLATE_ENDPOINT": "" + }, + + "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", + "postCreateCommand": ".devcontainer/post-create.sh", + "waitFor": "postCreateCommand", + + "customizations": { + "vscode": { + "settings": {}, + "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"] + } + } +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b98f6a21e0..fa8d6542c1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,33 +1,40 @@ { - "name": "Mastodon", + "name": "Mastodon on local machine", "dockerComposeFile": "docker-compose.yml", "service": "app", - "workspaceFolder": "/mastodon", - - // Set *default* container specific settings.json values on container create. - "settings": {}, - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "EditorConfig.EditorConfig", - "dbaeumer.vscode-eslint", - "rebornix.Ruby", - "webben.browserslist" - ], + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "features": { - "ghcr.io/devcontainers/features/sshd:1": { - "version": "latest" + "ghcr.io/devcontainers/features/sshd:1": {} + }, + + "forwardPorts": [3000, 4000], + + "portsAttributes": { + "3000": { + "label": "web", + "onAutoForward": "notify", + "requireLocalPort": true + }, + "4000": { + "label": "stream", + "onAutoForward": "silent", + "requireLocalPort": true } }, - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // This can be used to network with other containers or the host. - "forwardPorts": [3000, 4000], + "otherPortsAttributes": { + "onAutoForward": "silent" + }, - // Use 'postCreateCommand' to run commands after the container is created. + "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", "postCreateCommand": ".devcontainer/post-create.sh", + "waitFor": "postCreateCommand", - // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" + "customizations": { + "vscode": { + "settings": {}, + "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"] + } + } } diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 95f401379c..0369521963 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -5,19 +5,12 @@ services: build: context: . dockerfile: Dockerfile - args: - # Update 'VARIANT' to pick a version of Ruby: 3, 3.1, 3.0, 2, 2.7, 2.6 - # Append -bullseye or -buster to pin to an OS version. - # Use -bullseye variants on local arm64/Apple Silicon. - VARIANT: '3.0-bullseye' - # Optional Node.js version to install - NODE_VERSION: '16' volumes: - - ..:/mastodon:cached + - ../..:/workspaces:cached environment: RAILS_ENV: development NODE_ENV: development - + BIND: 0.0.0.0 REDIS_HOST: redis REDIS_PORT: '6379' DB_HOST: db @@ -30,10 +23,13 @@ services: LIBRE_TRANSLATE_ENDPOINT: http://libretranslate:5000 # Overrides default command so things don't shut down after the process ends. command: sleep infinity + ports: + - '127.0.0.1:3000:3000' + - '127.0.0.1:3035:3035' + - '127.0.0.1:4000:4000' networks: - external_network - internal_network - user: vscode db: image: postgres:14-alpine @@ -49,7 +45,7 @@ services: - internal_network redis: - image: redis:6-alpine + image: redis:7-alpine restart: unless-stopped volumes: - redis-data:/data @@ -74,15 +70,19 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.2.9 + image: libretranslate/libretranslate:v1.3.12 restart: unless-stopped + volumes: + - lt-data:/home/libretranslate/.local networks: + - external_network - internal_network volumes: postgres-data: redis-data: es-data: + lt-data: networks: external_network: diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 02f488f120..a075cc7b3b 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -3,17 +3,22 @@ set -e # Fail the whole script on first error # Fetch Ruby gem dependencies -bundle install --path vendor/bundle --with='development test' - -# Fetch Javascript dependencies -yarn install +bundle config path 'vendor/bundle' +bundle config with 'development test' +bundle install # Make Gemfile.lock pristine again git checkout -- Gemfile.lock +# Fetch Javascript dependencies +yarn --frozen-lockfile + # [re]create, migrate, and seed the test database RAILS_ENV=test ./bin/rails db:setup +# [re]create, migrate, and seed the development database +RAILS_ENV=development ./bin/rails db:setup + # Precompile assets for development RAILS_ENV=development ./bin/rails assets:precompile diff --git a/.devcontainer/welcome-message.txt b/.devcontainer/welcome-message.txt new file mode 100644 index 0000000000..488cf92857 --- /dev/null +++ b/.devcontainer/welcome-message.txt @@ -0,0 +1,8 @@ +👋 Welcome to "Mastodon" in GitHub Codespaces! + +🛠️ Your environment is fully setup with all the required software. + +🔍 To explore VS Code to its fullest, search using the Command Palette (Cmd/Ctrl + Shift + P or F1). + +📝 Edit away, run your app as usual, and we'll automatically make it available for you to access. + diff --git a/.editorconfig b/.editorconfig index 5f8702cf89..b5217da4af 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,4 @@ insert_final_newline = true charset = utf-8 indent_style = space indent_size = 2 +trim_trailing_whitespace = true diff --git a/.env.production.sample b/.env.production.sample index 0bf01bdc36..7bcce0f7e5 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -16,11 +16,37 @@ # ---------- LOCAL_DOMAIN=example.com +# Use this only if you need to run mastodon on a different domain than the one used for federation. +# You can read more about this option on https://docs.joinmastodon.org/admin/config/#web-domain +# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING. +# WEB_DOMAIN=mastodon.example.com + +# Use this if you want to have several aliases handler@example1.com +# handler@example2.com etc. for the same user. LOCAL_DOMAIN should not +# be added. Comma separated values +# ALTERNATE_DOMAINS=example1.com,example2.com + +# Use HTTP proxy for outgoing request (optional) +# http_proxy=http://gateway.local:8118 +# Access control for hidden service. +# ALLOW_ACCESS_TO_HIDDEN_SERVICE=true + +# Authorized fetch mode (optional) +# Require remote servers to authentify when fetching toots, see +# https://docs.joinmastodon.org/admin/config/#authorized_fetch +# AUTHORIZED_FETCH=true + +# Limited federation mode (optional) +# Only allow federation with specific domains, see +# https://docs.joinmastodon.org/admin/config/#whitelist_mode +# LIMITED_FEDERATION_MODE=true + # Redis # ----- REDIS_HOST=localhost REDIS_PORT=6379 + # PostgreSQL # ---------- DB_HOST=/var/run/postgresql @@ -29,29 +55,52 @@ DB_NAME=mastodon_production DB_PASS= DB_PORT=5432 + # Elasticsearch (optional) # ------------------------ -ES_ENABLED=true -ES_HOST=localhost -ES_PORT=9200 +#ES_ENABLED=true +#ES_HOST=localhost +#ES_PORT=9200 # Authentication for ES (optional) -ES_USER=elastic -ES_PASS=password +#ES_USER=elastic +#ES_PASS=password + # Secrets # ------- -# Make sure to use `rake secret` to generate secrets +# Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web bundle exec rake secret` if you use docker compose) # ------- SECRET_KEY_BASE= OTP_SECRET= + # Web Push # -------- -# Generate with `rake mastodon:webpush:generate_vapid_key` +# Generate with `rake mastodon:webpush:generate_vapid_key` (first is the private key, second is the public one) +# You should only generate this once per instance. If you later decide to change it, all push subscription will +# be invalidated, requiring the users to access the website again to resubscribe. # -------- VAPID_PRIVATE_KEY= VAPID_PUBLIC_KEY= + +# Registrations +# ------------- + +# Single user mode will disable registrations and redirect frontpage to the first profile +# SINGLE_USER_MODE=true + +# Prevent registrations with following e-mail domains +# EMAIL_DOMAIN_DENYLIST=example1.com|example2.de|etc + +# Only allow registrations with the following e-mail domains +# EMAIL_DOMAIN_ALLOWLIST=example1.com|example2.de|etc + +#TODO move this +# Optionally change default language +# DEFAULT_LOCALE=de + + # Sending mail # ------------ SMTP_SERVER= @@ -60,13 +109,190 @@ SMTP_LOGIN= SMTP_PASSWORD= SMTP_FROM_ADDRESS=notifications@example.com + # File storage (optional) # ----------------------- -S3_ENABLED=true -S3_BUCKET=files.example.com -AWS_ACCESS_KEY_ID= -AWS_SECRET_ACCESS_KEY= -S3_ALIAS_HOST=files.example.com +# The attachment host must allow cross origin request from WEB_DOMAIN or +# LOCAL_DOMAIN if WEB_DOMAIN is not set. For example, the server may have the +# following header field: +# Access-Control-Allow-Origin: https://192.168.1.123:9000/ +# ----------------------- +#S3_ENABLED=true +#S3_BUCKET=files.example.com +#AWS_ACCESS_KEY_ID= +#AWS_SECRET_ACCESS_KEY= +#S3_ALIAS_HOST=files.example.com + +# Swift (optional) +# The attachment host must allow cross origin request - see the description +# above. +# SWIFT_ENABLED=true +# SWIFT_USERNAME= +# For Keystone V3, the value for SWIFT_TENANT should be the project name +# SWIFT_TENANT= +# SWIFT_PASSWORD= +# Some OpenStack V3 providers require PROJECT_ID (optional) +# SWIFT_PROJECT_ID= +# Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid +# issues with token rate-limiting during high load. +# SWIFT_AUTH_URL= +# SWIFT_CONTAINER= +# SWIFT_OBJECT_URL= +# SWIFT_REGION= +# Defaults to 'default' +# SWIFT_DOMAIN_NAME= +# Defaults to 60 seconds. Set to 0 to disable +# SWIFT_CACHE_TTL= + +# Optional asset host for multi-server setups +# The asset host must allow cross origin request from WEB_DOMAIN or LOCAL_DOMAIN +# if WEB_DOMAIN is not set. For example, the server may have the +# following header field: +# Access-Control-Allow-Origin: https://example.com/ +# CDN_HOST=https://assets.example.com + +# Optional list of hosts that are allowed to serve media for your instance +# This is useful if you include external media in your custom CSS or about page, +# or if your data storage provider makes use of redirects to other domains. +# EXTRA_DATA_HOSTS=https://data.example1.com|https://data.example2.com + +# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare) +# S3_ALIAS_HOST= + +# Streaming API integration +# STREAMING_API_BASE_URL= + + +# External authentication (optional) +# ---------------------------------- +# LDAP authentication (optional) +# LDAP_ENABLED=true +# LDAP_HOST=localhost +# LDAP_PORT=389 +# LDAP_METHOD=simple_tls +# LDAP_BASE= +# LDAP_BIND_DN= +# LDAP_PASSWORD= +# LDAP_UID=cn +# LDAP_MAIL=mail +# LDAP_SEARCH_FILTER=(|(%{uid}=%{email})(%{mail}=%{email})) +# LDAP_UID_CONVERSION_ENABLED=true +# LDAP_UID_CONVERSION_SEARCH=., - +# LDAP_UID_CONVERSION_REPLACE=_ + +# PAM authentication (optional) +# PAM authentication uses for the email generation the "email" pam variable +# and optional as fallback PAM_DEFAULT_SUFFIX +# The pam environment variable "email" is provided by: +# https://github.com/devkral/pam_email_extractor +# PAM_ENABLED=true +# Fallback email domain for email address generation (LOCAL_DOMAIN by default) +# PAM_EMAIL_DOMAIN=example.com +# Name of the pam service (pam "auth" section is evaluated) +# PAM_DEFAULT_SERVICE=rpam +# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default) +# PAM_CONTROLLED_SERVICE=rpam + +# Global OAuth settings (optional) : +# If you have only one strategy, you may want to enable this +# OAUTH_REDIRECT_AT_SIGN_IN=true + +# Optional CAS authentication (cf. omniauth-cas) : +# CAS_ENABLED=true +# CAS_URL=https://sso.myserver.com/ +# CAS_HOST=sso.myserver.com/ +# CAS_PORT=443 +# CAS_SSL=true +# CAS_VALIDATE_URL= +# CAS_CALLBACK_URL= +# CAS_LOGOUT_URL= +# CAS_LOGIN_URL= +# CAS_UID_FIELD='user' +# CAS_CA_PATH= +# CAS_DISABLE_SSL_VERIFICATION=false +# CAS_UID_KEY='user' +# CAS_NAME_KEY='name' +# CAS_EMAIL_KEY='email' +# CAS_NICKNAME_KEY='nickname' +# CAS_FIRST_NAME_KEY='firstname' +# CAS_LAST_NAME_KEY='lastname' +# CAS_LOCATION_KEY='location' +# CAS_IMAGE_KEY='image' +# CAS_PHONE_KEY='phone' + +# Optional SAML authentication (cf. omniauth-saml) +# SAML_ENABLED=true +# SAML_ACS_URL=http://localhost:3000/auth/auth/saml/callback +# SAML_ISSUER=https://example.com +# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO +# SAML_IDP_CERT= +# SAML_IDP_CERT_FINGERPRINT= +# SAML_NAME_IDENTIFIER_FORMAT= +# SAML_CERT= +# SAML_PRIVATE_KEY= +# SAML_SECURITY_WANT_ASSERTION_SIGNED=true +# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true +# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true +# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1" +# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" +# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241" +# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42" +# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4" +# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1" +# SAML_ATTRIBUTES_STATEMENTS_VERIFIED= +# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL= + + +# Custom settings +# --------------- +# Various ways to customize Mastodon's behavior +# --------------- + +# Maximum allowed character count +MAX_TOOT_CHARS=500 + +# Maximum number of pinned posts +MAX_PINNED_TOOTS=5 + +# Maximum allowed bio characters +MAX_BIO_CHARS=500 + +# Maximim number of profile fields allowed +MAX_PROFILE_FIELDS=4 + +# Maximum allowed display name characters +MAX_DISPLAY_NAME_CHARS=30 + +# Maximum allowed poll options +MAX_POLL_OPTIONS=5 + +# Maximum allowed poll option characters +MAX_POLL_OPTION_CHARS=100 + +# Maximum image and video/audio upload sizes +# Units are in bytes +# 1048576 bytes equals 1 megabyte +# MAX_IMAGE_SIZE=8388608 +# MAX_VIDEO_SIZE=41943040 + +# Maximum search results to display +# Only relevant when elasticsearch is installed +# MAX_SEARCH_RESULTS=20 + +# Maximum hashtags to display +# Customize the number of hashtags shown in 'Explore' +# MAX_TRENDING_TAGS=10 + +# Maximum custom emoji file sizes +# If undefined or smaller than MAX_EMOJI_SIZE, the value +# of MAX_EMOJI_SIZE will be used for MAX_REMOTE_EMOJI_SIZE +# Units are in bytes +# MAX_EMOJI_SIZE=262144 +# MAX_REMOTE_EMOJI_SIZE=262144 + +# Optional hCaptcha support +# HCAPTCHA_SECRET_KEY= +# HCAPTCHA_SITE_KEY= # IP and session retention # ----------------------- diff --git a/.env.vagrant b/.env.vagrant index 32ed9b9229..69c1bf1fb3 100644 --- a/.env.vagrant +++ b/.env.vagrant @@ -2,3 +2,7 @@ VAGRANT=true LOCAL_DOMAIN=mastodon.local BIND=0.0.0.0 DB_HOST=/var/run/postgresql/ + +ES_ENABLED=true +ES_HOST=localhost +ES_PORT=9200 \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index ca7fc83eb9..cd1eb4c660 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,72 +4,67 @@ module.exports = { extends: [ 'eslint:recommended', 'plugin:react/recommended', + 'plugin:react-hooks/recommended', 'plugin:jsx-a11y/recommended', + 'plugin:import/recommended', + 'plugin:promise/recommended', + 'plugin:jsdoc/recommended', ], env: { browser: true, node: true, es6: true, - jest: true, }, globals: { ATTACHMENT_HOST: false, }, - parser: '@babel/eslint-parser', + parser: '@typescript-eslint/parser', plugins: [ 'react', 'jsx-a11y', 'import', 'promise', + '@typescript-eslint', + 'formatjs', ], parserOptions: { sourceType: 'module', ecmaFeatures: { - experimentalObjectRestSpread: true, jsx: true, }, ecmaVersion: 2021, + requireConfigFile: false, + babelOptions: { + configFile: false, + presets: ['@babel/react', '@babel/env'], + }, }, settings: { react: { version: 'detect', }, - 'import/extensions': [ - '.js', - ], 'import/ignore': [ 'node_modules', '\\.(css|scss|json)$', ], 'import/resolver': { - node: { - paths: ['app/javascript'], - }, + typescript: {}, }, }, rules: { - 'brace-style': 'warn', - 'comma-dangle': ['error', 'always-multiline'], - 'comma-spacing': [ - 'warn', - { - before: false, - after: true, - }, - ], - 'comma-style': ['warn', 'last'], 'consistent-return': 'error', 'dot-notation': 'error', - eqeqeq: 'error', - indent: ['warn', 2], + eqeqeq: ['error', 'always', { 'null': 'ignore' }], + 'indent': ['error', 2], 'jsx-quotes': ['error', 'prefer-single'], + 'semi': ['error', 'always'], 'no-case-declarations': 'off', 'no-catch-shadow': 'error', 'no-console': [ @@ -87,42 +82,43 @@ module.exports = { { property: 'substring', message: 'Use .slice instead of .substring.' }, { property: 'substr', message: 'Use .slice instead of .substr.' }, ], + 'no-restricted-syntax': [ + 'error', + { + // eslint-disable-next-line no-restricted-syntax + selector: 'Literal[value=/•/], JSXText[value=/•/]', + // eslint-disable-next-line no-restricted-syntax + message: "Use '·' (middle dot) instead of '•' (bullet)", + }, + ], 'no-self-assign': 'off', - 'no-trailing-spaces': 'warn', 'no-unused-expressions': 'error', - 'no-unused-vars': [ + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ 'error', { vars: 'all', args: 'after-used', + destructuredArrayIgnorePattern: '^_', ignoreRestSiblings: true, }, ], - 'no-useless-escape': 'off', - 'object-curly-spacing': ['error', 'always'], - 'padded-blocks': [ - 'error', - { - classes: 'always', - }, - ], - quotes: ['error', 'single'], - semi: 'error', 'valid-typeof': 'error', + 'react/jsx-filename-extension': ['error', { extensions: ['.jsx', 'tsx'] }], 'react/jsx-boolean-value': 'error', - 'react/jsx-closing-bracket-location': ['error', 'line-aligned'], - 'react/jsx-curly-spacing': 'error', 'react/display-name': 'off', + 'react/jsx-fragments': ['error', 'syntax'], 'react/jsx-equals-spacing': 'error', - 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'], - 'react/jsx-indent': ['error', 2], 'react/jsx-no-bind': 'error', + 'react/jsx-no-useless-fragment': 'error', 'react/jsx-no-target-blank': 'off', 'react/jsx-tag-spacing': 'error', + 'react/jsx-uses-react': 'off', // not needed with new JSX transform 'react/jsx-wrap-multilines': 'error', 'react/no-deprecated': 'off', 'react/no-unknown-property': 'off', + 'react/react-in-jsx-scope': 'off', // not needed with new JSX transform 'react/self-closing-comp': 'error', // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js @@ -178,32 +174,229 @@ module.exports = { }, ], + // See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js 'import/extensions': [ 'error', 'always', { js: 'never', + jsx: 'never', + mjs: 'never', + ts: 'never', + tsx: 'never', }, ], + 'import/first': 'error', 'import/newline-after-import': 'error', + 'import/no-anonymous-default-export': 'error', 'import/no-extraneous-dependencies': [ 'error', { devDependencies: [ 'config/webpack/**', + 'app/javascript/mastodon/performance.js', 'app/javascript/mastodon/test_setup.js', 'app/javascript/**/__tests__/**', ], }, ], - 'import/no-unresolved': 'error', + 'import/no-amd': 'error', + 'import/no-commonjs': 'error', + 'import/no-import-module-exports': 'error', + 'import/no-relative-packages': 'error', + 'import/no-self-import': 'error', + 'import/no-useless-path-segments': 'error', 'import/no-webpack-loader-syntax': 'error', + 'import/order': [ + 'error', + { + alphabetize: { order: 'asc' }, + 'newlines-between': 'always', + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + ['index', 'sibling'], + 'object', + ], + pathGroups: [ + // React core packages + { + pattern: '{react,react-dom,react-dom/client,prop-types}', + group: 'builtin', + position: 'after', + }, + // I18n + { + pattern: '{react-intl,intl-messageformat}', + group: 'builtin', + position: 'after', + }, + // Common React utilities + { + pattern: '{classnames,react-helmet,react-router-dom}', + group: 'external', + position: 'before', + }, + // Immutable / Redux / data store + { + pattern: '{immutable,react-redux,react-immutable-proptypes,react-immutable-pure-component,reselect}', + group: 'external', + position: 'before', + }, + // Internal packages + { + pattern: '{mastodon/**}', + group: 'internal', + position: 'after', + }, + { + pattern: '{flavours/glitch-soc/**}', + group: 'internal', + position: 'after', + }, + ], + pathGroupsExcludedImportTypes: [], + }, + ], + + // Forbid imports from vanilla in glitch flavour + 'import/no-restricted-paths': [ + 'error', + { + zones: [{ + target: 'app/javascript/flavours/glitch/', + from: 'app/javascript/mastodon/', + message: 'Import from /flavours/glitch/ instead' + }] + } + ], + + 'promise/always-return': 'off', 'promise/catch-or-return': [ 'error', { allowFinally: true, }, ], + 'promise/no-callback-in-promise': 'off', + 'promise/no-nesting': 'off', + 'promise/no-promise-in-callback': 'off', + + 'formatjs/blocklist-elements': 'error', + 'formatjs/enforce-default-message': ['error', 'literal'], + 'formatjs/enforce-description': 'off', // description values not currently used + 'formatjs/enforce-id': 'off', // Explicit IDs are used in the project + 'formatjs/enforce-placeholders': 'off', // Issues in short_number.jsx + 'formatjs/enforce-plural-rules': 'error', + 'formatjs/no-camel-case': 'off', // disabledAccount is only non-conforming + 'formatjs/no-complex-selectors': 'error', + 'formatjs/no-emoji': 'error', + 'formatjs/no-id': 'off', // IDs are used for translation keys + 'formatjs/no-invalid-icu': 'error', + 'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings + 'formatjs/no-multiple-plurals': 'off', // Only used by hashtag.jsx + 'formatjs/no-multiple-whitespaces': 'error', + 'formatjs/no-offset': 'error', + 'formatjs/no-useless-message': 'error', + 'formatjs/prefer-formatted-message': 'error', + 'formatjs/prefer-pound-in-plural': 'error', + + 'jsdoc/check-types': 'off', + 'jsdoc/no-undefined-types': 'off', + 'jsdoc/require-jsdoc': 'off', + 'jsdoc/require-param-description': 'off', + 'jsdoc/require-property-description': 'off', + 'jsdoc/require-returns-description': 'off', + 'jsdoc/require-returns': 'off', }, + + overrides: [ + { + files: [ + '*.config.js', + '.*rc.js', + 'ide-helper.js', + 'config/webpack/**/*', + 'config/formatjs-formatter.js', + ], + + env: { + commonjs: true, + }, + + parserOptions: { + sourceType: 'script', + }, + + rules: { + 'import/no-commonjs': 'off', + }, + }, + { + files: [ + '**/*.ts', + '**/*.tsx', + ], + + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/strict-type-checked', + 'plugin:@typescript-eslint/stylistic-type-checked', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:jsx-a11y/recommended', + 'plugin:import/recommended', + 'plugin:import/typescript', + 'plugin:promise/recommended', + 'plugin:jsdoc/recommended-typescript', + 'plugin:prettier/recommended', + ], + + parserOptions: { + project: true, + tsconfigRootDir: __dirname, + }, + + rules: { + 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], + + '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], + '@typescript-eslint/consistent-type-exports': 'error', + '@typescript-eslint/consistent-type-imports': 'error', + "@typescript-eslint/prefer-nullish-coalescing": ['error', {ignorePrimitives: {boolean: true}}], + + 'jsdoc/require-jsdoc': 'off', + + // Those rules set stricter rules for TS files + // to enforce better practices when converting from JS + 'import/no-default-export': 'warn', + 'react/prefer-stateless-function': 'warn', + 'react/function-component-definition': ['error', { namedComponents: 'arrow-function' }], + 'react/jsx-uses-react': 'off', // not needed with new JSX transform + 'react/react-in-jsx-scope': 'off', // not needed with new JSX transform + 'react/prop-types': 'off', + }, + }, + { + files: [ + '**/__tests__/*.js', + '**/__tests__/*.jsx', + ], + + env: { + jest: true, + }, + }, + { + files: [ + 'streaming/**/*', + ], + rules: { + 'import/no-commonjs': 'off', + }, + }, + ], }; diff --git a/.github/ISSUE_TEMPLATE/1.bug_report.yml b/.github/ISSUE_TEMPLATE/1.bug_report.yml deleted file mode 100644 index 22f51f7bdf..0000000000 --- a/.github/ISSUE_TEMPLATE/1.bug_report.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Bug Report -description: If something isn't working as expected -labels: [bug] -body: - - type: markdown - attributes: - value: | - Make sure that you are submitting a new bug that was not previously reported or already fixed. - - Please use a concise and distinct title for the issue. - - type: textarea - attributes: - label: Steps to reproduce the problem - description: What were you trying to do? - value: | - 1. - 2. - 3. - ... - validations: - required: true - - type: input - attributes: - label: Expected behaviour - description: What should have happened? - validations: - required: true - - type: input - attributes: - label: Actual behaviour - description: What happened? - validations: - required: true - - type: textarea - attributes: - label: Detailed description - validations: - required: false - - type: textarea - attributes: - label: Specifications - description: | - What version or commit hash of Mastodon did you find this bug in? - - If a front-end issue, what browser and operating systems were you using? - placeholder: | - Mastodon 3.5.3 (or Edge) - Ruby 2.7.6 (or v3.1.2) - Node.js 16.18.0 - - Google Chrome 106.0.5249.119 - Firefox 105.0.3 - - etc... - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/1.web_bug_report.yml b/.github/ISSUE_TEMPLATE/1.web_bug_report.yml new file mode 100644 index 0000000000..20e27d103c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1.web_bug_report.yml @@ -0,0 +1,76 @@ +name: Bug Report (Web Interface) +description: If you are using Mastodon's web interface and something is not working as expected +labels: [bug, 'status/to triage', 'area/web interface'] +body: + - type: markdown + attributes: + value: | + Make sure that you are submitting a new bug that was not previously reported or already fixed. + + Please use a concise and distinct title for the issue. + - type: textarea + attributes: + label: Steps to reproduce the problem + description: What were you trying to do? + value: | + 1. + 2. + 3. + ... + validations: + required: true + - type: input + attributes: + label: Expected behaviour + description: What should have happened? + validations: + required: true + - type: input + attributes: + label: Actual behaviour + description: What happened? + validations: + required: true + - type: textarea + attributes: + label: Detailed description + validations: + required: false + - type: input + attributes: + label: Mastodon instance + description: The address of the Mastodon instance where you experienced the issue + placeholder: mastodon.social + validations: + required: true + - type: input + attributes: + label: Mastodon version + description: | + This is displayed at the bottom of the About page, eg. `v4.1.2+nightly-20230627` + placeholder: v4.1.2 + validations: + required: true + - type: input + attributes: + label: Browser name and version + description: | + What browser are you using when getting this bug? Please specify the version as well. + placeholder: Firefox 105.0.3 + validations: + required: true + - type: input + attributes: + label: Operating system + description: | + What OS are you running? Please specify the version as well. + placeholder: macOS 13.4.1 + validations: + required: true + - type: textarea + attributes: + label: Technical details + description: | + Any additional technical details you may have. This can include the full error log, inspector's output… + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/2.server_bug_report.yml b/.github/ISSUE_TEMPLATE/2.server_bug_report.yml new file mode 100644 index 0000000000..49d5f57209 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2.server_bug_report.yml @@ -0,0 +1,65 @@ +name: Bug Report (server / API) +description: | + If something is not working as expected, but is not from using the web interface. +labels: [bug, 'status/to triage'] +body: + - type: markdown + attributes: + value: | + Make sure that you are submitting a new bug that was not previously reported or already fixed. + + Please use a concise and distinct title for the issue. + - type: textarea + attributes: + label: Steps to reproduce the problem + description: What were you trying to do? + value: | + 1. + 2. + 3. + ... + validations: + required: true + - type: input + attributes: + label: Expected behaviour + description: What should have happened? + validations: + required: true + - type: input + attributes: + label: Actual behaviour + description: What happened? + validations: + required: true + - type: textarea + attributes: + label: Detailed description + validations: + required: false + - type: input + attributes: + label: Mastodon instance + description: The address of the Mastodon instance where you experienced the issue + placeholder: mastodon.social + validations: + required: false + - type: input + attributes: + label: Mastodon version + description: | + This is displayed at the bottom of the About page, eg. `v4.1.2+nightly-20230627` + placeholder: v4.1.2 + validations: + required: false + - type: textarea + attributes: + label: Technical details + description: | + Any additional technical details you may have, like logs or error traces + value: | + If this is happening on your own Mastodon server, please fill out those: + - Ruby version: (from `ruby --version`, eg. v3.1.2) + - Node.js version: (from `node --version`, eg. v18.16.0) + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/2.feature_request.yml b/.github/ISSUE_TEMPLATE/3.feature_request.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/2.feature_request.yml rename to .github/ISSUE_TEMPLATE/3.feature_request.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index c785d4a357..0000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,30 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: npm - directory: '/' - schedule: - interval: weekly - open-pull-requests-limit: 99 - allow: - - dependency-type: direct - - - package-ecosystem: bundler - directory: '/' - schedule: - interval: weekly - open-pull-requests-limit: 99 - allow: - - dependency-type: direct - - - package-ecosystem: github-actions - directory: '/' - schedule: - interval: weekly - open-pull-requests-limit: 99 - allow: - - dependency-type: direct diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 0000000000..879a564e1c --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,124 @@ +{ + $schema: 'https://docs.renovatebot.com/renovate-schema.json', + extends: [ + 'config:recommended', + ':labels(dependencies)', + ':maintainLockFilesMonthly', // update non-direct dependencies monthly + ':prConcurrentLimitNone', // Remove limit for open PRs at any time. + ':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour. + ], + minimumReleaseAge: '3', // Wait 3 days after the package has been published before upgrading it + // packageRules order is important, they are applied from top to bottom and are merged, + // meaning the most important ones must be at the bottom, for example grouping rules + // If we do not want a package to be grouped with others, we need to set its groupName + // to `null` after any other rule set it to something. + dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).', + packageRules: [ + { + // Require Dependency Dashboard Approval for major version bumps of these node packages + matchManagers: ['npm'], + matchPackageNames: [ + 'tesseract.js', // Requires code changes + 'react-hotkeys', // Requires code changes + + // Requires Webpacker upgrade or replacement + '@types/webpack', + 'babel-loader', + 'compression-webpack-plugin', + 'css-loader', + 'imports-loader', + 'mini-css-extract-plugin', + 'postcss-loader', + 'sass-loader', + 'terser-webpack-plugin', + 'webpack', + 'webpack-assets-manifest', + 'webpack-bundle-analyzer', + 'webpack-dev-server', + 'webpack-cli', + + // react-router: Requires manual upgrade + 'history', + 'react-router-dom', + ], + matchUpdateTypes: ['major'], + dependencyDashboardApproval: true, + }, + { + // Require Dependency Dashboard Approval for major version bumps of these Ruby packages + matchManagers: ['bundler'], + matchPackageNames: [ + 'rack', // Needs to be synced with Rails version + 'sprockets', // Requires manual upgrade https://github.com/rails/sprockets/blob/master/UPGRADING.md#guide-to-upgrading-from-sprockets-3x-to-4x + 'strong_migrations', // Requires manual upgrade + 'sidekiq', // Requires manual upgrade + 'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version + 'redis', // Requires manual upgrade and sync with Sidekiq version + ], + matchUpdateTypes: ['major'], + dependencyDashboardApproval: true, + }, + { + // Update Github Actions and Docker images weekly + matchManagers: ['github-actions', 'dockerfile', 'docker-compose'], + extends: ['schedule:weekly'], + }, + { + // Require Dependency Dashboard Approval for major & minor bumps for the ruby image, this needs to be synced with .ruby-version + matchManagers: ['dockerfile'], + matchPackageNames: ['moritzheiber/ruby-jemalloc'], + matchUpdateTypes: ['minor', 'major'], + dependencyDashboardApproval: true, + }, + { + // Require Dependency Dashboard Approval for major bumps for the node image, this needs to be synced with .nvmrc + matchManagers: ['dockerfile'], + matchPackageNames: ['node'], + matchUpdateTypes: ['major'], + dependencyDashboardApproval: true, + }, + { + // Require Dependency Dashboard Approval for major postgres bumps in the docker-compose file, as those break dev environments + matchManagers: ['docker-compose'], + matchPackageNames: ['postgres'], + matchUpdateTypes: ['major'], + dependencyDashboardApproval: true, + }, + { + // Update devDependencies every week, with one grouped PR + matchDepTypes: 'devDependencies', + matchUpdateTypes: ['patch', 'minor'], + groupName: 'devDependencies (non-major)', + extends: ['schedule:weekly'], + }, + { + // Group all eslint-related packages with `eslint` in the same PR + matchManagers: ['npm'], + matchPackageNames: ['eslint'], + matchPackagePrefixes: ['eslint-', '@typescript-eslint/'], + matchUpdateTypes: ['patch', 'minor'], + groupName: 'eslint (non-major)', + }, + { + // Update @types/* packages every week, with one grouped PR + matchPackagePrefixes: '@types/', + matchUpdateTypes: ['patch', 'minor'], + groupName: 'DefinitelyTyped types (non-major)', + extends: ['schedule:weekly'], + addLabels: ['typescript'], + }, + { + // We want those packages to always have their own PR + matchManagers: ['npm'], + matchPackageNames: [ + 'typescript', // Typescript has code-impacting changes in minor versions + ], + groupName: null, // We dont want them to belong to any group + }, + // Add labels depending on package manager + { matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] }, + { matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] }, + { matchManagers: ['docker-compose', 'dockerfile'], addLabels: ['docker'] }, + { matchManagers: ['github-actions'], addLabels: ['github_actions'] }, + ], +} diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml new file mode 100644 index 0000000000..29868c72f8 --- /dev/null +++ b/.github/workflows/build-container-image.yml @@ -0,0 +1,99 @@ +on: + workflow_call: + inputs: + platforms: + required: true + type: string + cache: + type: boolean + default: true + use_native_arm64_builder: + type: boolean + push_to_images: + type: string + version_prerelease: + type: string + version_metadata: + type: string + flavor: + type: string + tags: + type: string + labels: + type: string + +jobs: + build-image: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: docker/setup-qemu-action@v3 + if: contains(inputs.platforms, 'linux/arm64') && !inputs.use_native_arm64_builder + + - uses: docker/setup-buildx-action@v3 + id: buildx + if: ${{ !(inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64')) }} + + - name: Start a local Docker Builder + if: inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64') + run: | + docker run --rm -d --name buildkitd -p 1234:1234 --privileged moby/buildkit:latest --addr tcp://0.0.0.0:1234 + + - uses: docker/setup-buildx-action@v3 + id: buildx-native + if: inputs.use_native_arm64_builder && contains(inputs.platforms, 'linux/arm64') + with: + driver: remote + endpoint: tcp://localhost:1234 + platforms: linux/amd64 + append: | + - endpoint: tcp://${{ vars.DOCKER_BUILDER_HETZNER_ARM64_01_HOST }}:13865 + platforms: linux/arm64 + name: mastodon-docker-builder-arm64-01 + driver-opts: + - servername=mastodon-docker-builder-arm64-01 + env: + BUILDER_NODE_1_AUTH_TLS_CACERT: ${{ secrets.DOCKER_BUILDER_HETZNER_ARM64_01_CACERT }} + BUILDER_NODE_1_AUTH_TLS_CERT: ${{ secrets.DOCKER_BUILDER_HETZNER_ARM64_01_CERT }} + BUILDER_NODE_1_AUTH_TLS_KEY: ${{ secrets.DOCKER_BUILDER_HETZNER_ARM64_01_KEY }} + + - name: Log in to Docker Hub + if: contains(inputs.push_to_images, 'tootsuite') + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Log in to the Github Container registry + if: contains(inputs.push_to_images, 'ghcr.io') + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/metadata-action@v5 + id: meta + if: ${{ inputs.push_to_images != '' }} + with: + images: ${{ inputs.push_to_images }} + flavor: ${{ inputs.flavor }} + tags: ${{ inputs.tags }} + labels: ${{ inputs.labels }} + + - uses: docker/build-push-action@v5 + with: + context: . + build-args: | + MASTODON_VERSION_PRERELEASE=${{ inputs.version_prerelease }} + MASTODON_VERSION_METADATA=${{ inputs.version_metadata }} + platforms: ${{ inputs.platforms }} + provenance: false + builder: ${{ steps.buildx.outputs.name || steps.buildx-native.outputs.name }} + push: ${{ inputs.push_to_images != '' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: ${{ inputs.cache && 'type=gha' || '' }} + cache-to: ${{ inputs.cache && 'type=gha,mode=max' || '' }} diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml deleted file mode 100644 index b3aa9f45c9..0000000000 --- a/.github/workflows/build-image.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Build container image -on: - workflow_dispatch: - push: - branches: - - 'main' - tags: - - '*' - pull_request: - paths: - - .github/workflows/build-image.yml - - Dockerfile -permissions: - contents: read - packages: write - -jobs: - build-image: - runs-on: ubuntu-latest - - concurrency: - group: ${{ github.ref }} - cancel-in-progress: true - - steps: - - uses: actions/checkout@v3 - - uses: hadolint/hadolint-action@v3.1.0 - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 - - - name: Log in to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - if: github.repository == 'mastodon/mastodon' && github.event_name != 'pull_request' - - - name: Log in to the Github Container registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - if: github.repository == 'mastodon/mastodon' && github.event_name != 'pull_request' - - - uses: docker/metadata-action@v4 - id: meta - with: - images: | - tootsuite/mastodon - ghcr.io/mastodon/mastodon - flavor: | - latest=auto - tags: | - type=edge,branch=main - type=pep440,pattern={{raw}} - type=pep440,pattern=v{{major}}.{{minor}} - type=ref,event=pr - - - uses: docker/build-push-action@v4 - with: - context: . - platforms: linux/amd64,linux/arm64 - provenance: false - builder: ${{ steps.buildx.outputs.name }} - push: ${{ github.repository == 'mastodon/mastodon' && github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml new file mode 100644 index 0000000000..d2c3eea197 --- /dev/null +++ b/.github/workflows/build-nightly.yml @@ -0,0 +1,41 @@ +name: Build nightly container image +on: + workflow_dispatch: + schedule: + - cron: '0 2 * * *' # run at 2 AM UTC + +permissions: + contents: read + packages: write + +jobs: + compute-suffix: + runs-on: ubuntu-latest + steps: + - id: version_vars + env: + TZ: Etc/UTC + run: | + echo mastodon_version_prerelease=nightly.$(date +'%Y-%m-%d')>> $GITHUB_OUTPUT + outputs: + prerelease: ${{ steps.version_vars.outputs.mastodon_version_prerelease }} + + build-image: + needs: compute-suffix + uses: ./.github/workflows/build-container-image.yml + with: + platforms: linux/amd64,linux/arm64 + use_native_arm64_builder: false + cache: false + push_to_images: | + ghcr.io/${{ github.repository_owner }}/mastodon + version_prerelease: ${{ needs.compute-suffix.outputs.prerelease }} + labels: | + org.opencontainers.image.description=Nightly build image used for testing purposes + flavor: | + latest=true + tags: | + type=raw,value=edge + type=raw,value=nightly + type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }} + secrets: inherit diff --git a/.github/workflows/build-push-pr.yml b/.github/workflows/build-push-pr.yml new file mode 100644 index 0000000000..b5f6cbc746 --- /dev/null +++ b/.github/workflows/build-push-pr.yml @@ -0,0 +1,41 @@ +name: Build container image for PR +on: + pull_request: + types: [labeled, synchronize, reopened, ready_for_review, opened] + +permissions: + contents: read + packages: write + +jobs: + compute-suffix: + runs-on: ubuntu-latest + # This is only allowed to run if: + # - the PR branch is in the `mastodon/mastodon` repository + # - the PR is not a draft + # - the PR has the "build-image" label + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !github.event.pull_request.draft && contains(github.event.pull_request.labels.*.name, 'build-image') }} + steps: + # Repository needs to be cloned so `git rev-parse` below works + - name: Clone repository + uses: actions/checkout@v4 + - id: version_vars + run: | + echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT + outputs: + metadata: ${{ steps.version_vars.outputs.mastodon_version_metadata }} + + build-image: + needs: compute-suffix + uses: ./.github/workflows/build-container-image.yml + with: + platforms: linux/amd64,linux/arm64 + use_native_arm64_builder: false + push_to_images: | + ghcr.io/${{ github.repository_owner }}/mastodon + version_metadata: ${{ needs.compute-suffix.outputs.metadata }} + flavor: | + latest=auto + tags: | + type=ref,event=pr + secrets: inherit diff --git a/.github/workflows/build-releases.yml b/.github/workflows/build-releases.yml new file mode 100644 index 0000000000..2b7e7aaa42 --- /dev/null +++ b/.github/workflows/build-releases.yml @@ -0,0 +1,28 @@ +name: Build container release images +on: + push: + tags: + - '*' + +permissions: + contents: read + packages: write + +jobs: + build-image: + uses: ./.github/workflows/build-container-image.yml + with: + platforms: linux/amd64,linux/arm64 + use_native_arm64_builder: false + push_to_images: | + ghcr.io/${{ github.repository_owner }}/mastodon + # Do not use cache when building releases, so apt update is always ran and the release always contain the latest packages + cache: false + # 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.2.') }} + tags: | + type=pep440,pattern={{raw}} + type=pep440,pattern=v{{major}}.{{minor}} + secrets: inherit diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml new file mode 100644 index 0000000000..bfb93a36cd --- /dev/null +++ b/.github/workflows/bundler-audit.yml @@ -0,0 +1,40 @@ +name: Bundler Audit +on: + push: + branches-ignore: + - 'dependabot/**' + paths: + - 'Gemfile*' + - '.ruby-version' + - '.bundler-audit.yml' + - '.github/workflows/bundler-audit.yml' + + pull_request: + paths: + - 'Gemfile*' + - '.ruby-version' + - '.bundler-audit.yml' + - '.github/workflows/bundler-audit.yml' + + schedule: + - cron: '0 5 * * 1' + +jobs: + security: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Run bundler-audit + run: bundle exec bundler-audit diff --git a/.github/workflows/check-i18n.yml b/.github/workflows/check-i18n.yml index b2e6197868..39cf32ddc4 100644 --- a/.github/workflows/check-i18n.yml +++ b/.github/workflows/check-i18n.yml @@ -14,24 +14,49 @@ permissions: jobs: check-i18n: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y libicu-dev libidn11-dev + - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: .ruby-version bundler-cache: true + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install all yarn packages + run: yarn --frozen-lockfile + + - name: Check for missing strings in English JSON + run: | + yarn i18n:extract --throws + git diff --exit-code + - name: Check locale file normalization run: bundle exec i18n-tasks check-normalized + - name: Check for unused strings run: bundle exec i18n-tasks unused + + - name: Check for missing strings in English YML + run: | + bundle exec i18n-tasks add-missing -l en + git diff --exit-code + - name: Check for wrong string interpolations run: bundle exec i18n-tasks check-consistent-interpolations + - name: Check that all required locale files exist run: bundle exec rake repo:check_locales_files diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8534501d4e..3b40c3fd07 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml new file mode 100644 index 0000000000..dc6fd874d1 --- /dev/null +++ b/.github/workflows/crowdin-download.yml @@ -0,0 +1,77 @@ +name: Crowdin / Download translations +on: + schedule: + - cron: '17 4 * * *' # Every day + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + download-translations: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Increase Git http.postBuffer + # This is needed due to a bug in Ubuntu's cURL version? + # See https://github.com/orgs/community/discussions/55820 + run: | + git config --global http.version HTTP/1.1 + git config --global http.postBuffer 157286400 + + # Download the translation files from Crowdin + - name: crowdin action + uses: crowdin/github-action@v1 + with: + config: crowdin-glitch.yml + upload_sources: false + upload_translations: false + download_translations: true + crowdin_branch_name: main + push_translations: false + create_pull_request: false + env: + CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + + # As the files are extracted from a Docker container, they belong to root:root + # We need to fix this before the next steps + - name: Fix file permissions + run: sudo chown -R runner:docker . + + # This is needed to run the normalize step + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Run i18n normalize task + run: bundle exec i18n-tasks normalize + + # Create or update the pull request + - name: Create Pull Request + uses: peter-evans/create-pull-request@v5.0.2 + with: + commit-message: 'New Crowdin translations' + title: 'New Crowdin Translations (automated)' + author: 'GitHub Actions ' + body: | + New Crowdin translations, automated with Github Actions + + See `.github/workflows/crowdin-download.yml` + + This PR will be updated every day with new translations. + + Due to a limitation in Github Actions, checks are not running on this PR without manual action. + If you want to run the checks, then close and re-open it. + branch: i18n/crowdin/translations + base: main + labels: i18n diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml new file mode 100644 index 0000000000..75d66c2a6b --- /dev/null +++ b/.github/workflows/crowdin-upload.yml @@ -0,0 +1,36 @@ +name: Crowdin / Upload translations + +on: + push: + branches: + - main + paths: + - crowdin.yml + - app/javascript/mastodon/locales/en.json + - config/locales/en.yml + - config/locales/simple_form.en.yml + - config/locales/activerecord.en.yml + - config/locales/devise.en.yml + - config/locales/doorkeeper.en.yml + - .github/workflows/crowdin-upload.yml + +jobs: + upload-translations: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: crowdin action + uses: crowdin/github-action@v1 + with: + config: crowdin-glitch.yml + upload_sources: true + upload_translations: false + download_translations: false + crowdin_branch_name: main + + env: + CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} diff --git a/.github/workflows/haml-lint-problem-matcher.json b/.github/workflows/haml-lint-problem-matcher.json new file mode 100644 index 0000000000..3523ea2951 --- /dev/null +++ b/.github/workflows/haml-lint-problem-matcher.json @@ -0,0 +1,17 @@ +{ + "problemMatcher": [ + { + "owner": "haml-lint", + "severity": "warning", + "pattern": [ + { + "regexp": "^(.*):(\\d+)\\s\\[W]\\s(.*):\\s(.*)$", + "file": 1, + "line": 2, + "code": 3, + "message": 4 + } + ] + } + ] +} diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml index 431b88e8de..bd775dba20 100644 --- a/.github/workflows/lint-css.yml +++ b/.github/workflows/lint-css.yml @@ -3,9 +3,11 @@ on: push: branches-ignore: - 'dependabot/**' + - 'renovate/**' paths: - 'package.json' - 'yarn.lock' + - '.nvmrc' - '.prettier*' - 'stylelint.config.js' - '**/*.css' @@ -17,6 +19,7 @@ on: paths: - 'package.json' - 'yarn.lock' + - '.nvmrc' - '.prettier*' - 'stylelint.config.js' - '**/*.css' @@ -30,12 +33,13 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: cache: yarn + node-version-file: '.nvmrc' - name: Install all yarn packages run: yarn --frozen-lockfile @@ -45,4 +49,4 @@ jobs: - run: echo "::add-matcher::.github/stylelint-matcher.json" - name: Stylelint - run: yarn test:lint:sass + run: yarn lint:sass diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml new file mode 100644 index 0000000000..ca9bd66a4a --- /dev/null +++ b/.github/workflows/lint-haml.yml @@ -0,0 +1,47 @@ +name: Haml Linting +on: + push: + branches-ignore: + - 'dependabot/**' + - 'renovate/**' + paths: + - '.github/workflows/haml-lint-problem-matcher.json' + - '.github/workflows/lint-haml.yml' + - '.haml-lint*.yml' + - '.rubocop*.yml' + - '.ruby-version' + - '**/*.haml' + - 'Gemfile*' + + pull_request: + paths: + - '.github/workflows/haml-lint-problem-matcher.json' + - '.github/workflows/lint-haml.yml' + - '.haml-lint*.yml' + - '.rubocop*.yml' + - '.ruby-version' + - '**/*.haml' + - 'Gemfile*' + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install native Ruby dependencies + run: | + sudo apt-get update + sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Run haml-lint + run: | + echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json" + bundle exec haml-lint diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index 49d989771c..67d28589cb 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -3,21 +3,32 @@ on: push: branches-ignore: - 'dependabot/**' + - 'renovate/**' paths: - 'package.json' - 'yarn.lock' + - 'tsconfig.json' + - '.nvmrc' - '.prettier*' - '.eslint*' - '**/*.js' + - '**/*.jsx' + - '**/*.ts' + - '**/*.tsx' - '.github/workflows/lint-js.yml' pull_request: paths: - 'package.json' - 'yarn.lock' + - 'tsconfig.json' + - '.nvmrc' - '.prettier*' - '.eslint*' - '**/*.js' + - '**/*.jsx' + - '**/*.ts' + - '**/*.tsx' - '.github/workflows/lint-js.yml' jobs: @@ -26,15 +37,19 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: cache: yarn + node-version-file: '.nvmrc' - name: Install all yarn packages run: yarn --frozen-lockfile - name: ESLint - run: yarn test:lint:js + run: yarn lint:js --max-warnings 0 + + - name: Typecheck + run: yarn typecheck diff --git a/.github/workflows/lint-json.yml b/.github/workflows/lint-json.yml index 524ed083aa..1d98c52673 100644 --- a/.github/workflows/lint-json.yml +++ b/.github/workflows/lint-json.yml @@ -3,9 +3,11 @@ on: push: branches-ignore: - 'dependabot/**' + - 'renovate/**' paths: - 'package.json' - 'yarn.lock' + - '.nvmrc' - '.prettier*' - '**/*.json' - '.github/workflows/lint-json.yml' @@ -15,6 +17,7 @@ on: paths: - 'package.json' - 'yarn.lock' + - '.nvmrc' - '.prettier*' - '**/*.json' - '.github/workflows/lint-json.yml' @@ -26,15 +29,16 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: cache: yarn + node-version-file: '.nvmrc' - name: Install all yarn packages run: yarn --frozen-lockfile - name: Prettier - run: yarn prettier --check "**/*.json" + run: yarn lint:json diff --git a/.github/workflows/lint-md.yml b/.github/workflows/lint-md.yml new file mode 100644 index 0000000000..1b3f92c972 --- /dev/null +++ b/.github/workflows/lint-md.yml @@ -0,0 +1,44 @@ +name: Markdown Linting +on: + push: + branches-ignore: + - 'dependabot/**' + - 'renovate/**' + paths: + - '.github/workflows/lint-md.yml' + - '.nvmrc' + - '.prettier*' + - '**/*.md' + - '!AUTHORS.md' + - 'package.json' + - 'yarn.lock' + + pull_request: + paths: + - '.github/workflows/lint-md.yml' + - '.nvmrc' + - '.prettier*' + - '**/*.md' + - '!AUTHORS.md' + - 'package.json' + - 'yarn.lock' + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install all yarn packages + run: yarn --frozen-lockfile + + - name: Prettier + run: yarn lint:md diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index b834e3053f..92882a084d 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -3,9 +3,12 @@ on: push: branches-ignore: - 'dependabot/**' + - 'renovate/**' paths: - 'Gemfile*' - - '.rubocop.yml' + - '.rubocop*.yml' + - '.ruby-version' + - 'config/brakeman.ignore' - '**/*.rb' - '**/*.rake' - '.github/workflows/lint-ruby.yml' @@ -13,7 +16,9 @@ on: pull_request: paths: - 'Gemfile*' - - '.rubocop.yml' + - '.rubocop*.yml' + - '.ruby-version' + - 'config/brakeman.ignore' - '**/*.rb' - '**/*.rake' - '.github/workflows/lint-ruby.yml' @@ -21,21 +26,26 @@ on: jobs: lint: runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Set-up RuboCop Problem Mathcher + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Set-up RuboCop Problem Matcher uses: r7kamura/rubocop-problem-matchers-action@v1 - name: Run rubocop - uses: github/super-linter@v4 - env: - DEFAULT_BRANCH: main - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - LINTER_RULES_PATH: . - RUBY_CONFIG_FILE: .rubocop.yml - VALIDATE_ALL_CODEBASE: false - VALIDATE_RUBY: true + run: bundle exec rubocop + + - name: Run brakeman + if: always() # Run both checks, even if the first failed + run: bundle exec brakeman diff --git a/.github/workflows/lint-yml.yml b/.github/workflows/lint-yml.yml index 48f8170b3b..e77cc98891 100644 --- a/.github/workflows/lint-yml.yml +++ b/.github/workflows/lint-yml.yml @@ -3,9 +3,11 @@ on: push: branches-ignore: - 'dependabot/**' + - 'renovate/**' paths: - 'package.json' - 'yarn.lock' + - '.nvmrc' - '.prettier*' - '**/*.yaml' - '**/*.yml' @@ -16,6 +18,7 @@ on: paths: - 'package.json' - 'yarn.lock' + - '.nvmrc' - '.prettier*' - '**/*.yaml' - '**/*.yml' @@ -28,15 +31,16 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: cache: yarn + node-version-file: '.nvmrc' - name: Install all yarn packages run: yarn --frozen-lockfile - name: Prettier - run: yarn prettier --check "**/*.{yml,yaml}" + run: yarn lint:yml diff --git a/.github/workflows/rebase-needed.yml b/.github/workflows/rebase-needed.yml index 6f903ee610..06d835c090 100644 --- a/.github/workflows/rebase-needed.yml +++ b/.github/workflows/rebase-needed.yml @@ -1,17 +1,27 @@ name: PR Needs Rebase on: - push: - pull_request_target: - types: [synchronize] + schedule: + - cron: '0 * * * *' + +permissions: + pull-requests: write jobs: label-rebase-needed: runs-on: ubuntu-latest + + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: - name: Check for merge conflicts uses: eps1lon/actions-label-merge-conflict@releases/2.x with: dirtyLabel: 'rebase needed :construction:' repoToken: '${{ secrets.GITHUB_TOKEN }}' + commentOnClean: This pull request has resolved merge conflicts and is ready for review. commentOnDirty: This pull request has merge conflicts that must be resolved before it can be merged. + retryMax: 30 + continueOnMissingPermissions: false diff --git a/.github/workflows/test-image-build.yml b/.github/workflows/test-image-build.yml new file mode 100644 index 0000000000..778e341771 --- /dev/null +++ b/.github/workflows/test-image-build.yml @@ -0,0 +1,21 @@ +name: Test container image build +on: + pull_request: + paths: + - .github/workflows/build-nightly.yml + - .github/workflows/build-push-pr.yml + - .github/workflows/build-releases.yml + - .github/workflows/test-image-build.yml + - Dockerfile +permissions: + contents: read + +jobs: + build-image: + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + uses: ./.github/workflows/build-container-image.yml + with: + platforms: linux/amd64 # Testing only on native platform so it is performant diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml new file mode 100644 index 0000000000..0ef1d9b7c8 --- /dev/null +++ b/.github/workflows/test-js.yml @@ -0,0 +1,48 @@ +name: JavaScript Testing +on: + push: + branches-ignore: + - 'dependabot/**' + - 'renovate/**' + paths: + - 'package.json' + - 'yarn.lock' + - '.nvmrc' + - '**/*.js' + - '**/*.jsx' + - '**/*.ts' + - '**/*.tsx' + - '**/*.snap' + - '.github/workflows/test-js.yml' + + pull_request: + paths: + - 'package.json' + - 'yarn.lock' + - '.nvmrc' + - '**/*.js' + - '**/*.jsx' + - '**/*.ts' + - '**/*.tsx' + - '**/*.snap' + - '.github/workflows/test-js.yml' + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install all yarn packages + run: yarn --frozen-lockfile + + - name: Jest testing + run: yarn jest --reporters github-actions summary diff --git a/.github/workflows/test-migrations-one-step.yml b/.github/workflows/test-migrations-one-step.yml new file mode 100644 index 0000000000..59287e88cf --- /dev/null +++ b/.github/workflows/test-migrations-one-step.yml @@ -0,0 +1,111 @@ +name: Test one step migrations +on: + push: + branches-ignore: + - 'dependabot/**' + - 'renovate/**' + pull_request: + +jobs: + pre_job: + runs-on: ubuntu-latest + + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@v5 + with: + paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml", "lib/tasks/tests.rake"]' + + test: + runs-on: ubuntu-latest + needs: pre_job + if: needs.pre_job.outputs.should_skip != 'true' + + strategy: + fail-fast: false + + matrix: + postgres: + - 14-alpine + - 15-alpine + + services: + postgres: + image: postgres:${{ matrix.postgres}} + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + env: + CONTINUOUS_INTEGRATION: true + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: true + RAILS_ENV: test + BUNDLE_CLEAN: true + BUNDLE_FROZEN: true + BUNDLE_WITHOUT: 'development production' + BUNDLE_JOBS: 3 + BUNDLE_RETRY: 3 + + steps: + - uses: actions/checkout@v4 + + - name: Install native Ruby dependencies + run: | + sudo apt-get update + sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Create database + run: './bin/rails db:create' + + - name: Run migrations up to v2.0.0 + run: './bin/rails db:migrate VERSION=20171010025614' + + - name: Populate database with test data + run: './bin/rails tests:migrations:populate_v2' + + - name: Run migrations up to v2.4.0 + run: './bin/rails db:migrate VERSION=20180514140000' + + - name: Populate database with test data + run: './bin/rails tests:migrations:populate_v2_4' + + - name: Run migrations up to v2.4.3 + run: './bin/rails db:migrate VERSION=20180707154237' + + - name: Populate database with test data + run: './bin/rails tests:migrations:populate_v2_4_3' + + - name: Run all remaining migrations + run: './bin/rails db:migrate' + + - name: Check migration result + run: './bin/rails tests:migrations:check_database' diff --git a/.github/workflows/test-migrations-two-step.yml b/.github/workflows/test-migrations-two-step.yml new file mode 100644 index 0000000000..8f3c84d8f3 --- /dev/null +++ b/.github/workflows/test-migrations-two-step.yml @@ -0,0 +1,119 @@ +name: Test two step migrations +on: + push: + branches-ignore: + - 'dependabot/**' + - 'renovate/**' + pull_request: + +jobs: + pre_job: + runs-on: ubuntu-latest + + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@v5 + with: + paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml", "lib/tasks/tests.rake"]' + + test: + runs-on: ubuntu-latest + needs: pre_job + if: needs.pre_job.outputs.should_skip != 'true' + + strategy: + fail-fast: false + + matrix: + postgres: + - 14-alpine + - 15-alpine + + services: + postgres: + image: postgres:${{ matrix.postgres}} + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + env: + CONTINUOUS_INTEGRATION: true + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: true + RAILS_ENV: test + BUNDLE_CLEAN: true + BUNDLE_FROZEN: true + BUNDLE_WITHOUT: 'development production' + BUNDLE_JOBS: 3 + BUNDLE_RETRY: 3 + + steps: + - uses: actions/checkout@v4 + + - name: Install native Ruby dependencies + run: | + sudo apt-get update + sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Create database + run: './bin/rails db:create' + + - name: Run migrations up to v2.0.0 + run: './bin/rails db:migrate VERSION=20171010025614' + + - name: Populate database with test data + run: './bin/rails tests:migrations:populate_v2' + + - name: Run pre-deployment migrations up to v2.4.0 + run: './bin/rails db:migrate VERSION=20180514140000' + env: + SKIP_POST_DEPLOYMENT_MIGRATIONS: true + + - name: Populate database with test data + run: './bin/rails tests:migrations:populate_v2_4' + + - name: Run migrations up to v2.4.3 + run: './bin/rails db:migrate VERSION=20180707154237' + env: + SKIP_POST_DEPLOYMENT_MIGRATIONS: true + + - name: Populate database with test data + run: './bin/rails tests:migrations:populate_v2_4_3' + + - name: Run all remaining pre-deployment migrations + run: './bin/rails db:migrate' + env: + SKIP_POST_DEPLOYMENT_MIGRATIONS: true + + - name: Run all post-deployment migrations + run: './bin/rails db:migrate' + + - name: Check migration result + run: './bin/rails tests:migrations:check_database' diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml new file mode 100644 index 0000000000..0d0215bc06 --- /dev/null +++ b/.github/workflows/test-ruby.yml @@ -0,0 +1,370 @@ +name: Ruby Testing + +on: + push: + branches-ignore: + - 'dependabot/**' + - 'renovate/**' + pull_request: + +env: + BUNDLE_CLEAN: true + BUNDLE_FROZEN: true + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + mode: + - production + - test + env: + RAILS_ENV: ${{ matrix.mode }} + BUNDLE_WITH: ${{ matrix.mode }} + OTP_SECRET: precompile_placeholder + SECRET_KEY_BASE: precompile_placeholder + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install native Ruby dependencies + run: | + sudo apt-get update + sudo apt-get install -y libicu-dev libidn11-dev + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: .ruby-version + bundler-cache: true + + - run: yarn --frozen-lockfile --production + - name: Precompile assets + # Previously had set this, but it's not supported + # export NODE_OPTIONS=--openssl-legacy-provider + run: |- + ./bin/rails assets:precompile + + - uses: actions/upload-artifact@v3 + if: matrix.mode == 'test' + with: + path: |- + ./public/assets + ./public/packs-test + name: ${{ github.sha }} + retention-days: 0 + + test: + runs-on: ubuntu-latest + + needs: + - build + + services: + postgres: + image: postgres:14-alpine + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + env: + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: true + RAILS_ENV: test + ALLOW_NOPAM: true + PAM_ENABLED: true + PAM_DEFAULT_SERVICE: pam_test + PAM_CONTROLLED_SERVICE: pam_test_controlled + OIDC_ENABLED: true + OIDC_SCOPE: read + SAML_ENABLED: true + CAS_ENABLED: true + BUNDLE_WITH: 'pam_authentication test' + CI_JOBS: ${{ matrix.ci_job }}/4 + + strategy: + fail-fast: false + matrix: + ruby-version: + - '3.0' + - '3.1' + - '.ruby-version' + ci_job: + - 1 + - 2 + - 3 + - 4 + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v3 + with: + path: './public' + name: ${{ github.sha }} + + - name: Update package index + run: sudo apt-get update + + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Install additional system dependencies + run: sudo apt-get install -y ffmpeg imagemagick libpam-dev + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version}} + bundler-cache: true + + - name: Load database schema + run: './bin/rails db:create db:schema:load db:seed' + + - run: bundle exec rake rspec_chunked + + test-e2e: + name: End to End testing + runs-on: ubuntu-latest + + needs: + - build + + services: + postgres: + image: postgres:14-alpine + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + env: + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: true + RAILS_ENV: test + BUNDLE_WITH: test + + strategy: + fail-fast: false + matrix: + ruby-version: + - '3.0' + - '3.1' + - '.ruby-version' + + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v3 + with: + path: './public' + name: ${{ github.sha }} + + - name: Update package index + run: sudo apt-get update + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Install additional system dependencies + run: sudo apt-get install -y ffmpeg imagemagick + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version}} + bundler-cache: true + + - run: yarn --frozen-lockfile + + - name: Load database schema + run: './bin/rails db:create db:schema:load db:seed' + + - run: bundle exec rake spec:system + + - name: Archive logs + uses: actions/upload-artifact@v3 + if: failure() + with: + name: e2e-logs-${{ matrix.ruby-version }} + path: log/ + + - name: Archive test screenshots + uses: actions/upload-artifact@v3 + if: failure() + with: + name: e2e-screenshots + path: tmp/screenshots/ + + test-search: + name: Testing search + runs-on: ubuntu-latest + + needs: + - build + + services: + postgres: + image: postgres:14-alpine + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + + search: + image: ${{ matrix.search-image }} + env: + discovery.type: single-node + xpack.security.enabled: false + options: >- + --health-cmd "curl http://localhost:9200/_cluster/health" + --health-interval 10s + --health-timeout 5s + --health-retries 10 + ports: + - 9200:9200 + + env: + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: true + RAILS_ENV: test + BUNDLE_WITH: test + ES_ENABLED: true + ES_HOST: localhost + ES_PORT: 9200 + + strategy: + fail-fast: false + matrix: + ruby-version: + - '3.0' + - '3.1' + - '.ruby-version' + search-image: + - docker.elastic.co/elasticsearch/elasticsearch:7.17.13 + include: + - ruby-version: '.ruby-version' + search-image: docker.elastic.co/elasticsearch/elasticsearch:8.10.2 + + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v3 + with: + path: './public' + name: ${{ github.sha }} + + - name: Update package index + run: sudo apt-get update + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + cache: yarn + node-version-file: '.nvmrc' + + - name: Install native Ruby dependencies + run: sudo apt-get install -y libicu-dev libidn11-dev + + - name: Install additional system dependencies + run: sudo apt-get install -y ffmpeg imagemagick + + - name: Set up bundler cache + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version}} + bundler-cache: true + + - run: yarn --frozen-lockfile + + - name: Load database schema + run: './bin/rails db:create db:schema:load db:seed' + + - run: bundle exec rake spec:search + + - name: Archive logs + uses: actions/upload-artifact@v3 + if: failure() + with: + name: test-search-logs-${{ matrix.ruby-version }} + path: log/ + + - name: Archive test screenshots + uses: actions/upload-artifact@v3 + if: failure() + with: + name: test-search-screenshots + path: tmp/screenshots/ diff --git a/.gitignore b/.gitignore index 2bc8b18c8f..d4d0c0c930 100644 --- a/.gitignore +++ b/.gitignore @@ -31,9 +31,6 @@ # Ignore Vagrant files .vagrant/ -# Ignore Capistrano customizations -/config/deploy/* - # Ignore IDE files .vscode/ .idea/ @@ -63,3 +60,10 @@ yarn-debug.log # Ignore Docker option files docker-compose.override.yml + +/public/packs +/public/packs-test +/node_modules +/yarn-error.log +yarn-debug.log* +.yarn-integrity diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.haml-lint.yml b/.haml-lint.yml index 7853d81d7c..d1ed30b260 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -1,108 +1,14 @@ -# Whether to ignore frontmatter at the beginning of HAML documents for -# frameworks such as Jekyll/Middleman -skip_frontmatter: false +inherits_from: .haml-lint_todo.yml exclude: - 'vendor/**/*' - - 'spec/**/*' - - 'lib/templates/**/*' - - 'app/views/kaminari/**/*' + - lib/templates/haml/scaffold/_form.html.haml + +require: + - ./lib/linter/haml_middle_dot.rb linters: AltText: - enabled: false - - ClassAttributeWithStaticValue: enabled: true - - ClassesBeforeIds: - enabled: true - - ConsecutiveComments: - enabled: true - - ConsecutiveSilentScripts: - enabled: true - max_consecutive: 2 - - EmptyObjectReference: - enabled: true - - EmptyScript: - enabled: true - - FinalNewline: - enabled: true - present: true - - HtmlAttributes: - enabled: true - - ImplicitDiv: - enabled: true - - LeadingCommentSpace: - enabled: true - - LineLength: - enabled: false - max: 80 - - MultilinePipe: - enabled: true - - MultilineScript: - enabled: true - - ObjectReferenceAttributes: - enabled: true - - RuboCop: - enabled: true - # These cops are incredibly noisy when it comes to HAML templates, so we - # ignore them. - ignored_cops: - - Lint/BlockAlignment - - Lint/EndAlignment - - Lint/Void - - Metrics/BlockLength - - Metrics/LineLength - - Style/AlignParameters - - Style/BlockNesting - - Style/ElseAlignment - - Style/EndOfLine - - Style/FileName - - Style/FinalNewline - - Style/FrozenStringLiteralComment - - Style/IfUnlessModifier - - Style/IndentationWidth - - Style/Next - - Style/TrailingBlankLines - - Style/TrailingWhitespace - - Style/WhileUntilModifier - - RubyComments: - enabled: true - - SpaceBeforeScript: - enabled: true - - SpaceInsideHashAttributes: - enabled: true - style: space - - Indentation: - enabled: true - character: space # or tab - - TagName: - enabled: true - - TrailingWhitespace: - enabled: true - - UnnecessaryInterpolation: - enabled: true - - UnnecessaryStringOutput: + MiddleDot: enabled: true diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml new file mode 100644 index 0000000000..69937c4c48 --- /dev/null +++ b/.haml-lint_todo.yml @@ -0,0 +1,41 @@ +# This configuration was generated by +# `haml-lint --auto-gen-config` +# on 2023-10-03 08:32:28 -0400 using Haml-Lint version 0.51.0. +# The point is for the user to remove these configuration records +# one by one as the lints are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of Haml-Lint, may require this file to be generated again. + +linters: + # Offense count: 944 + LineLength: + enabled: false + + # Offense count: 22 + UnnecessaryStringOutput: + enabled: false + + # Offense count: 44 + RuboCop: + enabled: false + + # Offense count: 3 + ViewLength: + exclude: + - 'app/views/admin/accounts/show.html.haml' + - 'app/views/admin/reports/show.html.haml' + - 'app/views/disputes/strikes/show.html.haml' + + # Offense count: 15 + InstanceVariables: + exclude: + - 'app/views/admin/reports/_actions.html.haml' + - 'app/views/auth/registrations/_status.html.haml' + - 'app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml' + - 'app/views/relationships/_account.html.haml' + + # Offense count: 2 + IdNames: + exclude: + - 'app/views/oauth/authorizations/error.html.haml' + - 'app/views/shared/_error_messages.html.haml' diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000000..d2ae35e84b --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +yarn lint-staged diff --git a/.nvmrc b/.nvmrc index b6a7d89c68..fa69d015bd 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +20.8 diff --git a/.prettierignore b/.prettierignore index 1ad4f50136..a041bdc4ca 100644 --- a/.prettierignore +++ b/.prettierignore @@ -31,9 +31,6 @@ # Ignore Vagrant files .vagrant/ -# Ignore Capistrano customizations -/config/deploy/* - # Ignore IDE files .vscode/ .idea/ @@ -51,15 +48,8 @@ *~ *.swp -# Ignore npm debug log -npm-debug.log - -# Ignore yarn log files -yarn-error.log -yarn-debug.log - -# Ignore vagrant log files -*-cloudimg-console.log +# Ignore log files +*.log # Ignore Docker option files docker-compose.override.yml @@ -68,10 +58,8 @@ docker-compose.override.yml /app/javascript/mastodon/features/emoji/emoji_map.json # Ignore locale files -/app/javascript/mastodon/locales +/app/javascript/mastodon/locales/*.json /config/locales -<<<<<<< Updated upstream -======= # Ignore vendored CSS reset app/javascript/styles/mastodon/reset.scss @@ -79,8 +67,6 @@ app/javascript/styles/mastodon/reset.scss # Ignore Javascript pending https://github.com/mastodon/mastodon/pull/23631 *.js *.jsx -*.ts -*.tsx # Ignore HTML till cleaned and included in CI *.html @@ -88,5 +74,18 @@ app/javascript/styles/mastodon/reset.scss # Ignore the generated AUTHORS.md AUTHORS.md -/Mastodon-Modern ->>>>>>> Stashed changes +# Ignore glitch-soc emoji map file +/app/javascript/flavours/glitch/features/emoji/emoji_map.json + +# Ignore glitch-soc locale files +/app/javascript/flavours/glitch/locales +/config/locales-glitch + +# Ignore glitch-soc vendored CSS reset +app/javascript/flavours/glitch/styles/reset.scss + +# Ignore win95 theme +app/javascript/styles/win95.scss + +# Ignore wobbl themes +app/javascript/flavors/glitch/styles/wobbl* diff --git a/.prettierrc.js b/.prettierrc.js index 1d70813d51..af39b253f6 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,3 +1,4 @@ module.exports = { - singleQuote: true + singleQuote: true, + jsxSingleQuote: true } diff --git a/.profile b/.profile index c6d57b609d..f4826ea303 100644 --- a/.profile +++ b/.profile @@ -1 +1 @@ -LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio +LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio:/app/.apt/usr/lib/x86_64-linux-gnu/openblas-pthread diff --git a/.rubocop.yml b/.rubocop.yml index 3c92234705..64ec766b22 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,479 +1,197 @@ +# Can be removed once all rules are addressed or moved to this file as documented overrides +inherit_from: .rubocop_todo.yml + +# Used for merging with exclude lists with .rubocop_todo.yml +inherit_mode: + merge: + - Exclude + require: - rubocop-rails - rubocop-rspec - rubocop-performance + - rubocop-capybara + - ./lib/linter/rubocop_middle_dot AllCops: - TargetRubyVersion: 2.7 + TargetRubyVersion: 3.0 # Set to minimum supported version of CI DisplayCopNames: true DisplayStyleGuide: true ExtraDetails: true UseCache: true CacheRootDirectory: tmp - NewCops: enable + NewCops: enable # Opt-in to newly added rules Exclude: - db/schema.rb - - 'app/views/**/*' - - 'config/**/*' - 'bin/*' - - 'Rakefile' - 'node_modules/**/*' - 'Vagrantfile' - 'vendor/**/*' - - 'lib/json_ld/*' + - 'lib/json_ld/*' # Generated files + - 'lib/mastodon/migration_helpers.rb' # Vendored from GitLab - 'lib/templates/**/*' -Bundler/OrderedGems: - Enabled: false - -Layout/AccessModifierIndentation: - EnforcedStyle: indent - -Layout/EmptyLineAfterMagicComment: - Enabled: false - -Layout/EmptyLineAfterGuardClause: - Enabled: false - -Layout/EmptyLineBetweenDefs: - AllowAdjacentOneLineDefs: true - -Layout/EmptyLinesAroundAttributeAccessor: - Enabled: true - +# Reason: Prefer Hashes without extreme indentation +# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation Layout/FirstHashElementIndentation: EnforcedStyle: consistent -Layout/HashAlignment: - Enabled: false - -Layout/SpaceAroundMethodCallOperator: - Enabled: true - -Layout/SpaceInsideHashLiteralBraces: - EnforcedStyle: space - -Lint/DeprecatedOpenSSLConstant: - Enabled: true - -Lint/DuplicateElsifCondition: - Enabled: true - -Lint/MixedRegexpCaptureTypes: - Enabled: true - -Lint/RaiseException: - Enabled: true - -Lint/StructNewOverride: - Enabled: true +# Reason: Currently disabled in .rubocop_todo.yml +# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength +Layout/LineLength: + Max: 320 # Default of 120 causes a duplicate entry in generated todo file +# Reason: +# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier Lint/UselessAccessModifier: ContextCreatingMethods: - class_methods -Metrics/AbcSize: - Max: 34 # RuboCop default 17 - Exclude: - - 'lib/**/*cli*.rb' - - db/*migrate/**/* - - lib/paperclip/color_extractor.rb - - app/workers/scheduler/follow_recommendations_scheduler.rb - - app/services/activitypub/fetch*_service.rb - - lib/paperclip/**/* - CountRepeatedAttributes: false - AllowedMethods: - - update_media_attachments! - - account_link_to - - attempt_oembed - - build_crutches - - calculate_scores - - cc - - dump_actor! - - filter_from_home? - - hydrate - - import_bookmarks! - - import_relationships! - - initialize - - link_to_mention - - log_target - - matches_time_window? - - parse_metadata - - perform_statuses_search! - - privatize_media_attachments! - - process_update - - publish_media_attachments! - - remotable_attachment - - render_initial_state - - render_with_cache - - searchable_by - - self.cached_filters_for - - set_fetchable_attributes! - - signed_request_actor - - statuses_to_delete - - update_poll! +## Disable most Metrics/*Length cops +# Reason: those are often triggered and force significant refactors when this happend +# but the team feel they are not really improving the code quality. +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength Metrics/BlockLength: - Max: 55 - Exclude: - - 'lib/mastodon/*_cli.rb' - CountComments: false - CountAsOne: [array, heredoc] - AllowedMethods: - - task - - namespace - - class_methods - - included - -Metrics/BlockNesting: - Max: 3 - Exclude: - - 'lib/mastodon/*_cli.rb' + Enabled: false +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength Metrics/ClassLength: - CountComments: false - Max: 500 - CountAsOne: [array, heredoc] - Exclude: - - 'lib/mastodon/*_cli.rb' - -Metrics/CyclomaticComplexity: - Max: 12 - Exclude: - - lib/mastodon/*cli*.rb - - db/*migrate/**/* - AllowedMethods: - - attempt_oembed - - blocked? - - build_crutches - - calculate_scores - - cc - - discover_endpoint! - - filter_from_home? - - hydrate - - klass - - link_to_mention - - log_target - - matches_time_window? - - patch_for_forwarding! - - preprocess_attributes! - - process_update - - remotable_attachment - - scan_text! - - self.cached_filters_for - - set_fetchable_attributes! - - setup_redis_env_url - - update_media_attachments! - -Layout/LineLength: - Max: 140 # RuboCop default 120 - AllowHeredoc: true - AllowURI: true - IgnoreCopDirectives: true - AllowedPatterns: - # Allow comments to be long lines - - !ruby/regexp / \# .*$/ - - !ruby/regexp /^\# .*$/ - Exclude: - - lib/**/*cli*.rb - - db/*migrate/**/* - - db/seeds/**/* + Enabled: false +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength Metrics/MethodLength: - CountComments: false - CountAsOne: [array, heredoc] - Max: 25 # RuboCop default 10 - Exclude: - - 'lib/mastodon/*_cli.rb' - AllowedMethods: - - account_link_to - - attempt_oembed - - body_with_limit - - build_crutches - - cached_filters_for - - calculate_scores - - check_webfinger! - - clean_feeds! - - collection_items - - collection_presenter - - copy_account_notes! - - deduplicate_accounts! - - deduplicate_conversations! - - deduplicate_local_accounts! - - deduplicate_statuses! - - deduplicate_tags! - - deduplicate_users! - - discover_endpoint! - - extract_extra_uris_with_indices - - extract_hashtags_with_indices - - extract_mentions_or_lists_with_indices - - filter_from_home? - - from_elasticsearch - - handle_explicit_update! - - handle_mark_as_sensitive! - - hsl_to_rgb - - import_bookmarks! - - import_domain_blocks! - - import_relationships! - - ldap_options - - matches_time_window? - - outbox_presenter - - pam_get_user - - parallelize_with_progress - - parse_and_transform - - patch_for_forwarding! - - populate_home - - post_process_style - - preload_cache_collection_target_statuses - - privatize_media_attachments! - - provides_callback_for - - publish_media_attachments! - - relevant_account_timestamp - - remotable_attachment - - rgb_to_hsl - - rss_status_content_format - - set_fetchable_attributes! - - setup_redis_env_url - - signed_request_actor - - to_preview_card_attributes - - upgrade_storage_filesystem - - upgrade_storage_s3 - - user_settings_params - - hydrate - - cc - - self_destruct + Enabled: false +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength Metrics/ModuleLength: - CountComments: false - Max: 200 - CountAsOne: [array, heredoc] + Enabled: false +## End Disable Metrics/*Length cops + +# Reason: Currently disabled in .rubocop_todo.yml +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize +Metrics/AbcSize: + Exclude: + - 'lib/mastodon/cli/*.rb' + - db/*migrate/**/* + +# Reason: Currently disabled in .rubocop_todo.yml +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity +Metrics/CyclomaticComplexity: + Exclude: + - lib/mastodon/cli/*.rb + - db/*migrate/**/* + +# Reason: +# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists Metrics/ParameterLists: - Max: 5 # RuboCop default 5 - CountKeywordArgs: true # RuboCop default true - MaxOptionalParameters: 3 # RuboCop default 3 - Exclude: - - app/models/concerns/account_interactions.rb - - app/services/activitypub/fetch_remote_account_service.rb - - app/services/activitypub/fetch_remote_actor_service.rb + CountKeywordArgs: false -Metrics/PerceivedComplexity: - Max: 16 # RuboCop default 8 - AllowedMethods: - - attempt_oembed - - build_crutches - - calculate_scores - - deduplicate_users! - - discover_endpoint! - - filter_from_home? - - hydrate - - patch_for_forwarding! - - process_update - - remove_orphans - - update_media_attachments! +# Reason: Prevailing style is argument file paths +# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath +Rails/FilePath: + EnforcedStyle: arguments -Naming/MemoizedInstanceVariableName: - Enabled: false - -Naming/MethodParameterName: - Enabled: true - -Rails: - Enabled: true - -Rails/ApplicationController: - Enabled: false - Exclude: - - 'app/controllers/well_known/**/*.rb' - -Rails/BelongsTo: - Enabled: false - -Rails/ContentTag: - Enabled: false - -Rails/EnumHash: - Enabled: false +# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus +# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus +Rails/HttpStatus: + EnforcedStyle: numeric +# Reason: Allowed in `tootctl` CLI code and in boot ENV checker +# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit Rails/Exit: Exclude: - - 'lib/mastodon/*' - - 'lib/cli.rb' + - 'config/boot.rb' + - 'lib/mastodon/cli/*.rb' -Rails/FilePath: - Enabled: false +# Reason: Some single letter camel case files shouldn't be split +# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath +RSpec/FilePath: + CustomTransform: + ActivityPub: activitypub # Ignore the snake_case due to the amount of files to rename + DeepL: deepl + FetchOEmbedService: fetch_oembed_service + JsonLdHelper: jsonld_helper + OEmbedController: oembed_controller + OStatus: ostatus + NodeInfoController: nodeinfo_controller # NodeInfo isn't snake_cased for any of the instances + Exclude: + - 'spec/config/initializers/rack_attack_spec.rb' # namespaces usually have separate folder + - 'spec/lib/sanitize_config_spec.rb' # namespaces usually have separate folder -Rails/HasAndBelongsToMany: - Enabled: false +# Reason: +# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject +RSpec/NamedSubject: + EnforcedStyle: named_only -Rails/HasManyOrHasOneDependent: - Enabled: false +# Reason: Prevailing style choice +# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot +RSpec/NotToNot: + EnforcedStyle: to_not -Rails/HelperInstanceVariable: - Enabled: false - -Rails/HttpStatus: - Enabled: false - -Rails/IndexBy: - Enabled: false - -Rails/InverseOf: - Enabled: false - -Rails/LexicallyScopedActionFilter: - Enabled: false - -Rails/OutputSafety: - Enabled: true - -Rails/RakeEnvironment: - Enabled: false - -Rails/RedundantForeignKey: - Enabled: false - -Rails/SkipsModelValidations: - Enabled: false - -Rails/UniqueValidationWithoutIndex: - Enabled: false - -Style/AccessorGrouping: - Enabled: true - -Style/AccessModifierDeclarations: - Enabled: false - -Style/ArrayCoercion: - Enabled: true - -Style/BisectedAttrAccessor: - Enabled: true - -Style/CaseLikeIf: - Enabled: false +# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus +# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus +RSpec/Rails/HttpStatus: + EnforcedStyle: numeric +# Reason: +# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren Style/ClassAndModuleChildren: Enabled: false -Style/CollectionMethods: - Enabled: true - PreferredMethods: - find_all: 'select' - +# Reason: Classes mostly self-document with their names +# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation Style/Documentation: Enabled: false -Style/DoubleNegation: - Enabled: true - -Style/ExpandPathArguments: - Enabled: false - -Style/ExponentialNotation: - Enabled: true - -Style/FormatString: - Enabled: false - -Style/FormatStringToken: - Enabled: false - -Style/FrozenStringLiteralComment: - Enabled: true - -Style/GuardClause: - Enabled: false - -Style/HashAsLastArrayItem: - Enabled: false - -Style/HashEachMethods: - Enabled: true - -Style/HashLikeCase: - Enabled: true - -Style/HashTransformKeys: - Enabled: true - -Style/HashTransformValues: - Enabled: false - +# Reason: Enforce modern Ruby style +# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax Style/HashSyntax: - Enabled: true EnforcedStyle: ruby19_no_mixed_keys -Style/IfUnlessModifier: - Enabled: false - -Style/InverseMethods: - Enabled: false - -Style/Lambda: - Enabled: false - -Style/MutableConstant: - Enabled: false +# Reason: +# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals +Style/NumericLiterals: + AllowedPatterns: + - \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability +# Reason: +# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters Style/PercentLiteralDelimiters: PreferredDelimiters: '%i': '()' '%w': '()' -Style/PerlBackrefs: - AutoCorrect: false - -Style/RedundantFetchBlock: - Enabled: true - -Style/RedundantFileExtensionInRequire: - Enabled: true - -Style/RedundantRegexpCharacterClass: - Enabled: false - -Style/RedundantRegexpEscape: - Enabled: false - -Style/RedundantReturn: - Enabled: true - +# Reason: Prefer less indentation in conditional assignments +# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin Style/RedundantBegin: Enabled: false -Style/RegexpLiteral: - Enabled: false - +# Reason: Overridden to reduce implicit StandardError rescues +# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror Style/RescueStandardError: - Enabled: true + EnforcedStyle: implicit -Style/SignalException: - Enabled: false - -Style/SlicingWithRange: - Enabled: true +# Reason: Simplify some spec layouts +# https://docs.rubocop.org/rubocop/cops_style.html#stylesemicolon +Style/Semicolon: + AllowAsExpressionSeparator: true +# Reason: Originally disabled for CodeClimate, and no config consensus has been found +# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray Style/SymbolArray: Enabled: false +# Reason: +# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral Style/TrailingCommaInArrayLiteral: EnforcedStyleForMultiline: 'comma' +# Reason: +# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral Style/TrailingCommaInHashLiteral: EnforcedStyleForMultiline: 'comma' -Style/UnpackFirst: - Enabled: false - -RSpec/ScatteredSetup: - Enabled: false -RSpec/ImplicitExpect: - Enabled: false -RSpec/NamedSubject: - Enabled: false -RSpec/DescribeClass: - Enabled: false -RSpec/LetSetup: - Enabled: false +Style/MiddleDot: + Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000000..63ed2fb6c9 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,810 @@ +# This configuration was generated by +# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` +# using RuboCop version 1.56.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include. +# Include: **/*.gemfile, **/Gemfile, **/gems.rb +Bundler/OrderedGems: + Exclude: + - 'Gemfile' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. +# URISchemes: http, https +Layout/LineLength: + Exclude: + - 'app/models/account.rb' + +# Configuration parameters: AllowComments, AllowEmptyLambdas. +Lint/EmptyBlock: + Exclude: + - 'spec/controllers/api/v2/search_controller_spec.rb' + - 'spec/fabricators/access_token_fabricator.rb' + - 'spec/fabricators/conversation_fabricator.rb' + - 'spec/fabricators/system_key_fabricator.rb' + - 'spec/lib/activitypub/adapter_spec.rb' + - 'spec/models/user_role_spec.rb' + +Lint/NonLocalExitFromIterator: + Exclude: + - 'app/helpers/jsonld_helper.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Lint/OrAssignmentToConstant: + Exclude: + - 'lib/sanitize_ext/sanitize_config.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. +Lint/UnusedBlockArgument: + Exclude: + - 'config/initializers/content_security_policy.rb' + - 'config/initializers/doorkeeper.rb' + - 'config/initializers/paperclip.rb' + - 'config/initializers/simple_form.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Lint/UselessAssignment: + Exclude: + - 'app/services/activitypub/process_status_update_service.rb' + - 'config/initializers/3_omniauth.rb' + - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb' + - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb' + - 'spec/controllers/api/v1/favourites_controller_spec.rb' + - 'spec/controllers/concerns/account_controller_concern_spec.rb' + - 'spec/helpers/jsonld_helper_spec.rb' + - 'spec/models/account_spec.rb' + - 'spec/models/domain_block_spec.rb' + - 'spec/models/status_spec.rb' + - 'spec/models/user_spec.rb' + - 'spec/models/webauthn_credentials_spec.rb' + - 'spec/services/account_search_service_spec.rb' + - 'spec/services/post_status_service_spec.rb' + - 'spec/services/precompute_feed_service_spec.rb' + - 'spec/services/resolve_url_service_spec.rb' + - 'spec/views/statuses/show.html.haml_spec.rb' + +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 144 + Exclude: + - 'app/serializers/initial_state_serializer.rb' + +# Configuration parameters: CountBlocks, Max. +Metrics/BlockNesting: + Exclude: + - 'lib/tasks/mastodon.rake' + +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 25 + +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/PerceivedComplexity: + Max: 27 + +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 +Naming/VariableNumber: + Exclude: + - 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb' + - 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb' + - 'db/migrate/20190820003045_update_statuses_index.rb' + - 'db/migrate/20190823221802_add_local_index_to_statuses.rb' + - 'db/migrate/20200119112504_add_public_index_to_statuses.rb' + - 'spec/models/account_spec.rb' + - 'spec/models/domain_block_spec.rb' + - 'spec/models/user_spec.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: SafeMultiline. +Performance/DeletePrefix: + Exclude: + - 'app/models/featured_tag.rb' + +Performance/MapMethodChain: + Exclude: + - 'app/models/feed.rb' + - 'lib/mastodon/cli/maintenance.rb' + - 'spec/services/bulk_import_service_spec.rb' + - 'spec/services/import_service_spec.rb' + +RSpec/AnyInstance: + Exclude: + - 'spec/controllers/activitypub/inboxes_controller_spec.rb' + - 'spec/controllers/admin/accounts_controller_spec.rb' + - 'spec/controllers/admin/resets_controller_spec.rb' + - 'spec/controllers/admin/settings/branding_controller_spec.rb' + - 'spec/controllers/api/v1/media_controller_spec.rb' + - 'spec/controllers/auth/sessions_controller_spec.rb' + - 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb' + - 'spec/controllers/settings/two_factor_authentication/recovery_codes_controller_spec.rb' + - 'spec/lib/request_spec.rb' + - 'spec/lib/status_filter_spec.rb' + - 'spec/models/account_spec.rb' + - 'spec/models/setting_spec.rb' + - 'spec/services/activitypub/process_collection_service_spec.rb' + - 'spec/validators/follow_limit_validator_spec.rb' + - 'spec/workers/activitypub/delivery_worker_spec.rb' + - 'spec/workers/web/push_notification_worker_spec.rb' + +# Configuration parameters: CountAsOne. +RSpec/ExampleLength: + Max: 22 + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: implicit, each, example +RSpec/HookArgument: + Exclude: + - 'spec/controllers/api/v1/streaming_controller_spec.rb' + - 'spec/controllers/well_known/webfinger_controller_spec.rb' + - 'spec/helpers/instance_helper_spec.rb' + - 'spec/models/user_spec.rb' + - 'spec/rails_helper.rb' + - 'spec/serializers/activitypub/note_serializer_spec.rb' + - 'spec/serializers/activitypub/update_poll_serializer_spec.rb' + - 'spec/services/import_service_spec.rb' + +# Configuration parameters: AssignmentOnly. +RSpec/InstanceVariable: + Exclude: + - 'spec/controllers/api/v1/streaming_controller_spec.rb' + - 'spec/controllers/auth/confirmations_controller_spec.rb' + - 'spec/controllers/auth/passwords_controller_spec.rb' + - 'spec/controllers/auth/sessions_controller_spec.rb' + - 'spec/controllers/concerns/export_controller_concern_spec.rb' + - 'spec/controllers/home_controller_spec.rb' + - 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb' + - 'spec/controllers/statuses_cleanup_controller_spec.rb' + - 'spec/models/concerns/account_finder_concern_spec.rb' + - 'spec/models/concerns/account_interactions_spec.rb' + - 'spec/models/public_feed_spec.rb' + - 'spec/serializers/activitypub/note_serializer_spec.rb' + - 'spec/serializers/activitypub/update_poll_serializer_spec.rb' + - 'spec/services/remove_status_service_spec.rb' + - 'spec/services/search_service_spec.rb' + - 'spec/services/unblock_domain_service_spec.rb' + +RSpec/LetSetup: + Exclude: + - 'spec/controllers/admin/accounts_controller_spec.rb' + - 'spec/controllers/admin/action_logs_controller_spec.rb' + - 'spec/controllers/admin/instances_controller_spec.rb' + - 'spec/controllers/admin/reports/actions_controller_spec.rb' + - 'spec/controllers/admin/statuses_controller_spec.rb' + - 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb' + - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb' + - 'spec/controllers/api/v1/filters_controller_spec.rb' + - 'spec/controllers/api/v1/followed_tags_controller_spec.rb' + - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb' + - 'spec/controllers/api/v2/filters/keywords_controller_spec.rb' + - 'spec/controllers/api/v2/filters/statuses_controller_spec.rb' + - 'spec/controllers/auth/confirmations_controller_spec.rb' + - 'spec/controllers/auth/passwords_controller_spec.rb' + - 'spec/controllers/auth/sessions_controller_spec.rb' + - 'spec/controllers/follower_accounts_controller_spec.rb' + - 'spec/controllers/following_accounts_controller_spec.rb' + - 'spec/controllers/oauth/authorized_applications_controller_spec.rb' + - 'spec/controllers/oauth/tokens_controller_spec.rb' + - 'spec/controllers/settings/imports_controller_spec.rb' + - 'spec/lib/activitypub/activity/delete_spec.rb' + - 'spec/lib/vacuum/applications_vacuum_spec.rb' + - 'spec/lib/vacuum/preview_cards_vacuum_spec.rb' + - 'spec/models/account_spec.rb' + - 'spec/models/account_statuses_cleanup_policy_spec.rb' + - 'spec/models/canonical_email_block_spec.rb' + - 'spec/models/status_spec.rb' + - 'spec/models/user_spec.rb' + - 'spec/services/account_statuses_cleanup_service_spec.rb' + - 'spec/services/activitypub/fetch_featured_collection_service_spec.rb' + - 'spec/services/activitypub/fetch_remote_status_service_spec.rb' + - 'spec/services/activitypub/process_account_service_spec.rb' + - 'spec/services/activitypub/process_collection_service_spec.rb' + - 'spec/services/batched_remove_status_service_spec.rb' + - 'spec/services/block_domain_service_spec.rb' + - 'spec/services/bulk_import_service_spec.rb' + - 'spec/services/delete_account_service_spec.rb' + - 'spec/services/import_service_spec.rb' + - 'spec/services/notify_service_spec.rb' + - 'spec/services/remove_status_service_spec.rb' + - 'spec/services/report_service_spec.rb' + - 'spec/services/resolve_account_service_spec.rb' + - 'spec/services/suspend_account_service_spec.rb' + - 'spec/services/unallow_domain_service_spec.rb' + - 'spec/services/unsuspend_account_service_spec.rb' + - 'spec/workers/scheduler/user_cleanup_scheduler_spec.rb' + +RSpec/MessageChain: + Exclude: + - 'spec/controllers/api/v1/media_controller_spec.rb' + - 'spec/models/concerns/remotable_spec.rb' + - 'spec/models/session_activation_spec.rb' + - 'spec/models/setting_spec.rb' + +# Configuration parameters: EnforcedStyle. +# SupportedStyles: have_received, receive +RSpec/MessageSpies: + Exclude: + - 'spec/controllers/admin/accounts_controller_spec.rb' + - 'spec/helpers/admin/account_moderation_notes_helper_spec.rb' + - 'spec/lib/webfinger_resource_spec.rb' + - 'spec/models/admin/account_action_spec.rb' + - 'spec/models/concerns/remotable_spec.rb' + - 'spec/models/follow_request_spec.rb' + - 'spec/models/identity_spec.rb' + - 'spec/models/session_activation_spec.rb' + - 'spec/models/setting_spec.rb' + - 'spec/services/activitypub/fetch_replies_service_spec.rb' + - 'spec/services/activitypub/process_collection_service_spec.rb' + - 'spec/spec_helper.rb' + - 'spec/validators/status_length_validator_spec.rb' + +RSpec/MultipleExpectations: + Max: 8 + +# Configuration parameters: AllowSubject. +RSpec/MultipleMemoizedHelpers: + Max: 21 + +# Configuration parameters: AllowedGroups. +RSpec/NestedGroups: + Max: 6 + +# This cop supports unsafe autocorrection (--autocorrect-all). +Rails/ApplicationController: + Exclude: + - 'app/controllers/health_controller.rb' + +# Configuration parameters: Include. +# Include: db/**/*.rb +Rails/CreateTableWithTimestamps: + Exclude: + - 'db/migrate/20170508230434_create_conversation_mutes.rb' + - 'db/migrate/20170823162448_create_status_pins.rb' + - 'db/migrate/20171116161857_create_list_accounts.rb' + - 'db/migrate/20180929222014_create_account_conversations.rb' + - 'db/migrate/20181007025445_create_pghero_space_stats.rb' + - 'db/migrate/20190103124649_create_scheduled_statuses.rb' + - 'db/migrate/20220824233535_create_status_trends.rb' + - 'db/migrate/20221006061337_create_preview_card_trends.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Severity. +Rails/DuplicateAssociation: + Exclude: + - 'app/serializers/activitypub/collection_serializer.rb' + - 'app/serializers/activitypub/note_serializer.rb' + +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/HasAndBelongsToMany: + Exclude: + - 'app/models/concerns/account_associations.rb' + - 'app/models/preview_card.rb' + - 'app/models/status.rb' + - 'app/models/tag.rb' + +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/HasManyOrHasOneDependent: + Exclude: + - 'app/models/concerns/account_counters.rb' + - 'app/models/conversation.rb' + - 'app/models/custom_emoji.rb' + - 'app/models/custom_emoji_category.rb' + - 'app/models/domain_block.rb' + - 'app/models/invite.rb' + - 'app/models/status.rb' + - 'app/models/user.rb' + - 'app/models/web/push_subscription.rb' + +Rails/I18nLocaleTexts: + Exclude: + - 'lib/tasks/mastodon.rake' + - 'spec/helpers/flashes_helper_spec.rb' + +# Configuration parameters: Include. +# Include: app/controllers/**/*.rb, app/mailers/**/*.rb +Rails/LexicallyScopedActionFilter: + Exclude: + - 'app/controllers/auth/passwords_controller.rb' + - 'app/controllers/auth/registrations_controller.rb' + - 'app/controllers/auth/sessions_controller.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Rails/NegateInclude: + Exclude: + - 'app/controllers/concerns/signature_verification.rb' + - 'app/helpers/jsonld_helper.rb' + - 'app/lib/activitypub/activity/create.rb' + - 'app/lib/activitypub/activity/move.rb' + - 'app/lib/feed_manager.rb' + - 'app/lib/link_details_extractor.rb' + - 'app/models/concerns/attachmentable.rb' + - 'app/models/concerns/remotable.rb' + - 'app/models/custom_filter.rb' + - 'app/services/activitypub/process_status_update_service.rb' + - 'app/services/fetch_link_card_service.rb' + - 'app/services/search_service.rb' + - 'app/workers/web/push_notification_worker.rb' + - 'lib/paperclip/color_extractor.rb' + +Rails/OutputSafety: + Exclude: + - 'config/initializers/simple_form.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: Include. +# Include: **/Rakefile, **/*.rake +Rails/RakeEnvironment: + Exclude: + - 'lib/tasks/auto_annotate_models.rake' + - 'lib/tasks/db.rake' + - 'lib/tasks/emojis.rake' + - 'lib/tasks/mastodon.rake' + - 'lib/tasks/repo.rake' + - 'lib/tasks/statistics.rake' + +# Configuration parameters: Include. +# Include: db/**/*.rb +Rails/ReversibleMigration: + Exclude: + - 'db/migrate/20160223164502_make_uris_nullable_in_statuses.rb' + - 'db/migrate/20161122163057_remove_unneeded_indexes.rb' + - 'db/migrate/20170205175257_remove_devices.rb' + - 'db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb' + - 'db/migrate/20170520145338_change_language_filter_to_opt_out.rb' + - 'db/migrate/20170609145826_remove_default_language_from_statuses.rb' + - 'db/migrate/20170711225116_fix_null_booleans.rb' + - 'db/migrate/20171129172043_add_index_on_stream_entries.rb' + - 'db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb' + - 'db/migrate/20171226094803_more_faster_index_on_notifications.rb' + - 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb' + - 'db/migrate/20180617162849_remove_unused_indexes.rb' + - 'db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb' + +# Configuration parameters: ForbiddenMethods, AllowedMethods. +# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all +Rails/SkipsModelValidations: + Exclude: + - 'app/controllers/admin/invites_controller.rb' + - 'app/controllers/concerns/session_tracking_concern.rb' + - 'app/models/concerns/account_merging.rb' + - 'app/models/concerns/expireable.rb' + - 'app/models/status.rb' + - 'app/models/trends/links.rb' + - 'app/models/trends/preview_card_batch.rb' + - 'app/models/trends/preview_card_provider_batch.rb' + - 'app/models/trends/status_batch.rb' + - 'app/models/trends/statuses.rb' + - 'app/models/trends/tag_batch.rb' + - 'app/models/trends/tags.rb' + - 'app/models/user.rb' + - 'app/services/activitypub/process_status_update_service.rb' + - 'app/services/approve_appeal_service.rb' + - 'app/services/block_domain_service.rb' + - 'app/services/delete_account_service.rb' + - 'app/services/process_mentions_service.rb' + - 'app/services/unallow_domain_service.rb' + - 'app/services/unblock_domain_service.rb' + - 'app/services/update_status_service.rb' + - 'app/workers/activitypub/post_upgrade_worker.rb' + - 'app/workers/move_worker.rb' + - 'app/workers/scheduler/ip_cleanup_scheduler.rb' + - 'app/workers/scheduler/scheduled_statuses_scheduler.rb' + - 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb' + - 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb' + - 'db/migrate/20170209184350_add_reply_to_statuses.rb' + - 'db/migrate/20170304202101_add_type_to_media_attachments.rb' + - 'db/migrate/20180528141303_fix_accounts_unique_index.rb' + - 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb' + - 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb' + - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb' + - 'db/migrate/20191007013357_update_pt_locales.rb' + - 'db/migrate/20220316233212_update_kurdish_locales.rb' + - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb' + - 'db/post_migrate/20200917193528_migrate_notifications_type.rb' + - 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb' + - 'db/post_migrate/20220617202502_migrate_roles.rb' + - 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb' + - 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb' + - 'lib/mastodon/cli/accounts.rb' + - 'lib/mastodon/cli/main.rb' + - 'lib/mastodon/cli/maintenance.rb' + - 'spec/controllers/api/v1/admin/accounts_controller_spec.rb' + - 'spec/lib/activitypub/activity/follow_spec.rb' + - 'spec/services/follow_service_spec.rb' + - 'spec/services/update_account_service_spec.rb' + +# Configuration parameters: Include. +# Include: db/**/*.rb +Rails/ThreeStateBooleanColumn: + Exclude: + - 'db/migrate/20160325130944_add_admin_to_users.rb' + - 'db/migrate/20161123093447_add_sensitive_to_statuses.rb' + - 'db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb' + - 'db/migrate/20170127165745_add_devise_two_factor_to_users.rb' + - 'db/migrate/20170209184350_add_reply_to_statuses.rb' + - 'db/migrate/20170330163835_create_imports.rb' + - 'db/migrate/20170905165803_add_local_to_statuses.rb' + - 'db/migrate/20171210213213_add_local_only_flag_to_statuses.rb' + - 'db/migrate/20181203021853_add_discoverable_to_accounts.rb' + - 'db/migrate/20190509164208_add_by_moderator_to_tombstone.rb' + - 'db/migrate/20190805123746_add_capabilities_to_tags.rb' + - 'db/migrate/20191212163405_add_hide_collections_to_accounts.rb' + - 'db/migrate/20200309150742_add_forwarded_to_reports.rb' + - 'db/migrate/20210609202149_create_login_activities.rb' + - 'db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb' + - 'db/migrate/20211031031021_create_preview_card_providers.rb' + - 'db/migrate/20211115032527_add_trendable_to_preview_cards.rb' + - 'db/migrate/20220202200743_add_trendable_to_accounts.rb' + - 'db/migrate/20220202200926_add_trendable_to_statuses.rb' + - 'db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb' + +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/UniqueValidationWithoutIndex: + Exclude: + - 'app/models/account_alias.rb' + - 'app/models/custom_filter_status.rb' + - 'app/models/identity.rb' + - 'app/models/webauthn_credential.rb' + +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/UnusedIgnoredColumns: + Exclude: + - 'app/models/account.rb' + - 'app/models/account_stat.rb' + - 'app/models/admin/action_log.rb' + - 'app/models/custom_filter.rb' + - 'app/models/email_domain_block.rb' + - 'app/models/report.rb' + - 'app/models/status_edit.rb' + - 'app/models/user.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: exists, where +Rails/WhereExists: + Exclude: + - 'app/controllers/activitypub/inboxes_controller.rb' + - 'app/controllers/admin/email_domain_blocks_controller.rb' + - 'app/controllers/auth/registrations_controller.rb' + - 'app/lib/activitypub/activity/create.rb' + - 'app/lib/delivery_failure_tracker.rb' + - 'app/lib/feed_manager.rb' + - 'app/lib/status_cache_hydrator.rb' + - 'app/lib/suspicious_sign_in_detector.rb' + - 'app/models/concerns/account_interactions.rb' + - 'app/models/featured_tag.rb' + - 'app/models/poll.rb' + - 'app/models/session_activation.rb' + - 'app/models/status.rb' + - 'app/models/user.rb' + - 'app/policies/status_policy.rb' + - 'app/serializers/rest/announcement_serializer.rb' + - 'app/serializers/rest/tag_serializer.rb' + - 'app/services/activitypub/fetch_remote_status_service.rb' + - 'app/services/app_sign_up_service.rb' + - 'app/services/vote_service.rb' + - 'app/validators/reaction_validator.rb' + - 'app/validators/vote_validator.rb' + - 'app/workers/move_worker.rb' + - 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb' + - 'lib/tasks/tests.rake' + - 'spec/models/account_spec.rb' + - 'spec/services/activitypub/process_collection_service_spec.rb' + - 'spec/services/purge_domain_service_spec.rb' + - 'spec/services/unallow_domain_service_spec.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowOnConstant, AllowOnSelfClass. +Style/CaseEquality: + Exclude: + - 'config/initializers/trusted_proxies.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowedMethods, AllowedPatterns. +# AllowedMethods: ==, equal?, eql? +Style/ClassEqualityComparison: + Exclude: + - 'app/helpers/jsonld_helper.rb' + - 'app/serializers/activitypub/outbox_serializer.rb' + +Style/ClassVars: + Exclude: + - 'config/initializers/devise.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/CombinableLoops: + Exclude: + - 'app/models/form/custom_emoji_batch.rb' + - 'app/models/form/ip_block_batch.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowedVars. +Style/FetchEnvVar: + Exclude: + - 'app/lib/redis_configuration.rb' + - 'app/lib/translation_service.rb' + - 'config/environments/development.rb' + - 'config/environments/production.rb' + - 'config/initializers/2_limited_federation_mode.rb' + - 'config/initializers/3_omniauth.rb' + - 'config/initializers/blacklists.rb' + - 'config/initializers/cache_buster.rb' + - 'config/initializers/content_security_policy.rb' + - 'config/initializers/devise.rb' + - 'config/initializers/paperclip.rb' + - 'config/initializers/vapid.rb' + - 'lib/mastodon/premailer_webpack_strategy.rb' + - 'lib/mastodon/redis_config.rb' + - 'lib/tasks/repo.rake' + - 'spec/features/profile_spec.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns. +# SupportedStyles: annotated, template, unannotated +# AllowedMethods: redirect +Style/FormatStringToken: + Exclude: + - 'app/models/privacy_policy.rb' + - 'config/initializers/devise.rb' + - 'lib/paperclip/color_extractor.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/GlobalStdStream: + Exclude: + - 'config/boot.rb' + - 'config/environments/development.rb' + - 'config/environments/production.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. +Style/GuardClause: + Exclude: + - 'app/controllers/admin/confirmations_controller.rb' + - 'app/controllers/auth/confirmations_controller.rb' + - 'app/controllers/auth/passwords_controller.rb' + - 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb' + - 'app/lib/activitypub/activity/block.rb' + - 'app/lib/request.rb' + - 'app/lib/request_pool.rb' + - 'app/lib/webfinger.rb' + - 'app/lib/webfinger_resource.rb' + - 'app/models/concerns/account_counters.rb' + - 'app/models/concerns/ldap_authenticable.rb' + - 'app/models/tag.rb' + - 'app/models/user.rb' + - 'app/services/fan_out_on_write_service.rb' + - 'app/services/post_status_service.rb' + - 'app/services/process_hashtags_service.rb' + - 'app/workers/move_worker.rb' + - 'app/workers/redownload_avatar_worker.rb' + - 'app/workers/redownload_header_worker.rb' + - 'app/workers/redownload_media_worker.rb' + - 'app/workers/remote_account_refresh_worker.rb' + - 'config/initializers/devise.rb' + - 'db/migrate/20170901141119_truncate_preview_cards.rb' + - 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb' + - 'lib/devise/two_factor_ldap_authenticatable.rb' + - 'lib/devise/two_factor_pam_authenticatable.rb' + - 'lib/mastodon/cli/accounts.rb' + - 'lib/mastodon/cli/maintenance.rb' + - 'lib/mastodon/cli/media.rb' + - 'lib/paperclip/attachment_extensions.rb' + - 'lib/tasks/repo.rake' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: braces, no_braces +Style/HashAsLastArrayItem: + Exclude: + - 'app/controllers/admin/statuses_controller.rb' + - 'app/controllers/api/v1/statuses_controller.rb' + - 'app/models/concerns/account_counters.rb' + - 'app/models/concerns/status_threading_concern.rb' + - 'app/models/status.rb' + - 'app/services/batched_remove_status_service.rb' + - 'app/services/notify_service.rb' + - 'db/migrate/20181024224956_migrate_account_conversations.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/HashTransformValues: + Exclude: + - 'app/serializers/rest/web_push_subscription_serializer.rb' + - 'app/services/import_service.rb' + +# This cop supports safe autocorrection (--autocorrect). +Style/IfUnlessModifier: + Exclude: + - 'config/environments/production.rb' + - 'config/initializers/devise.rb' + - 'config/initializers/ffmpeg.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: InverseMethods, InverseBlocks. +Style/InverseMethods: + Exclude: + - 'app/models/custom_filter.rb' + - 'app/services/update_account_service.rb' + - 'spec/controllers/activitypub/replies_controller_spec.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: line_count_dependent, lambda, literal +Style/Lambda: + Exclude: + - 'config/initializers/simple_form.rb' + - 'config/routes.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/MapToHash: + Exclude: + - 'app/models/status.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: literals, strict +Style/MutableConstant: + Exclude: + - 'app/models/tag.rb' + - 'app/services/delete_account_service.rb' + - 'lib/mastodon/migration_warning.rb' + +# This cop supports safe autocorrection (--autocorrect). +Style/NilLambda: + Exclude: + - 'config/initializers/paperclip.rb' + +# Configuration parameters: AllowedMethods. +# AllowedMethods: respond_to_missing? +Style/OptionalBooleanParameter: + Exclude: + - 'app/helpers/admin/account_moderation_notes_helper.rb' + - 'app/helpers/jsonld_helper.rb' + - 'app/lib/admin/system_check/message.rb' + - 'app/lib/request.rb' + - 'app/lib/webfinger.rb' + - 'app/services/block_domain_service.rb' + - 'app/services/fetch_resource_service.rb' + - 'app/workers/domain_block_worker.rb' + - 'app/workers/unfollow_follow_worker.rb' + - 'lib/mastodon/redis_config.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: PreferredDelimiters. +Style/PercentLiteralDelimiters: + Exclude: + - 'config/deploy.rb' + - 'config/initializers/doorkeeper.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: short, verbose +Style/PreferredHashMethods: + Exclude: + - 'config/initializers/paperclip.rb' + +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantConstantBase: + Exclude: + - 'config/environments/production.rb' + - 'config/initializers/sidekiq.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: SafeForConstants. +Style/RedundantFetchBlock: + Exclude: + - 'config/initializers/1_hosts.rb' + - 'config/initializers/chewy.rb' + - 'config/initializers/devise.rb' + - 'config/initializers/paperclip.rb' + - 'config/puma.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowMultipleReturnValues. +Style/RedundantReturn: + Exclude: + - 'app/controllers/api/v1/directories_controller.rb' + - 'app/controllers/auth/confirmations_controller.rb' + - 'app/lib/ostatus/tag_manager.rb' + - 'app/models/form/import.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. +# AllowedMethods: present?, blank?, presence, try, try! +Style/SafeNavigation: + Exclude: + - 'app/models/concerns/account_finder_concern.rb' + - 'app/models/status.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: only_raise, only_fail, semantic +Style/SignalException: + Exclude: + - 'lib/devise/two_factor_ldap_authenticatable.rb' + - 'lib/devise/two_factor_pam_authenticatable.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +Style/SingleArgumentDig: + Exclude: + - 'lib/webpacker/manifest_extensions.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: require_parentheses, require_no_parentheses +Style/StabbyLambdaParentheses: + Exclude: + - 'config/environments/production.rb' + - 'config/initializers/content_security_policy.rb' + +# This cop supports safe autocorrection (--autocorrect). +Style/StderrPuts: + Exclude: + - 'config/boot.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: Mode. +Style/StringConcatenation: + Exclude: + - 'config/initializers/paperclip.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'config/environments/production.rb' + - 'config/initializers/backtrace_silencers.rb' + - 'config/initializers/http_client_proxy.rb' + - 'config/initializers/rack_attack.rb' + - 'config/initializers/webauthn.rb' + - 'config/routes.rb' + +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments. +# AllowedMethods: define_method, mail, respond_to +Style/SymbolProc: + Exclude: + - 'config/initializers/3_omniauth.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, AllowSafeAssignment. +# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex +Style/TernaryParentheses: + Exclude: + - 'config/environments/development.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'config/initializers/paperclip.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInHashLiteral: + Exclude: + - 'config/environments/production.rb' + - 'config/environments/test.rb' + +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, MinSize, WordRegex. +# SupportedStyles: percent, brackets +Style/WordArray: + Exclude: + - 'app/helpers/languages_helper.rb' + - 'spec/controllers/settings/imports_controller_spec.rb' + - 'spec/models/form/import_spec.rb' diff --git a/.ruby-version b/.ruby-version index 818bd47abf..be94e6f53d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.0.6 +3.2.2 diff --git a/.yarnclean b/.yarnclean index 0cc2b50d7b..21eb734a6c 100644 --- a/.yarnclean +++ b/.yarnclean @@ -44,3 +44,6 @@ Gruntfile.js # for specific ignore !.svgo.yml !sass-lint/**/*.yml + +# breaks lint-staged or generally anything using https://github.com/eemeli/yaml/issues/384 +!**/yaml/dist/**/doc diff --git a/AUTHORS.md b/AUTHORS.md index 18b9f2d708..78cc37a17b 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -9,33 +9,40 @@ and provided thanks to the work of the following contributors: * [ClearlyClaire](https://github.com/ClearlyClaire) * [dependabot-preview[bot]](https://github.com/apps/dependabot-preview) * [ykzts](https://github.com/ykzts) -* [akihikodaki](https://github.com/akihikodaki) * [mjankowski](https://github.com/mjankowski) +* [akihikodaki](https://github.com/akihikodaki) +* [nschonni](https://github.com/nschonni) +* [renovate[bot]](https://github.com/apps/renovate) * [unarist](https://github.com/unarist) * [noellabo](https://github.com/noellabo) +* [tribela](https://github.com/tribela) * [abcang](https://github.com/abcang) * [yiskah](https://github.com/yiskah) -* [tribela](https://github.com/tribela) * [mayaeh](https://github.com/mayaeh) * [nolanlawson](https://github.com/nolanlawson) * [ysksn](https://github.com/ysksn) * [sorin-davidoi](https://github.com/sorin-davidoi) +* [renchap](https://github.com/renchap) * [lynlynlynx](https://github.com/lynlynlynx) * [m4sk1n](mailto:me@m4sk.in) * [Marcin Mikołajczak](mailto:me@m4sk.in) +* [danielmbrasil](https://github.com/danielmbrasil) * [shleeable](https://github.com/shleeable) +* [c960657](https://github.com/c960657) * [renatolond](https://github.com/renatolond) * [zunda](https://github.com/zunda) +* [ineffyble](https://github.com/ineffyble) +* [takayamaki](https://github.com/takayamaki) * [alpaca-tc](https://github.com/alpaca-tc) * [nclm](https://github.com/nclm) -* [ineffyble](https://github.com/ineffyble) +* [trwnh](https://github.com/trwnh) * [ariasuni](https://github.com/ariasuni) * [Masoud Abkenar](mailto:ampbox@gmail.com) * [blackle](https://github.com/blackle) +* [ThisIsMissEm](https://github.com/ThisIsMissEm) * [Quent-in](https://github.com/Quent-in) -* [Brawaru](https://github.com/Brawaru) +* [brawaru](https://github.com/brawaru) * [JantsoP](https://github.com/JantsoP) -* [trwnh](https://github.com/trwnh) * [nullkal](https://github.com/nullkal) * [yookoala](https://github.com/yookoala) * [dunn](https://github.com/dunn) @@ -46,10 +53,8 @@ and provided thanks to the work of the following contributors: * [danhunsaker](https://github.com/danhunsaker) * [eramdam](https://github.com/eramdam) * [Jeroen](mailto:jeroenpraat@users.noreply.github.com) -* [takayamaki](https://github.com/takayamaki) * [masarakki](https://github.com/masarakki) * [ticky](https://github.com/ticky) -* [ThisIsMissEm](https://github.com/ThisIsMissEm) * [hinaloe](https://github.com/hinaloe) * [hcmiya](https://github.com/hcmiya) * [stephenburgess8](https://github.com/stephenburgess8) @@ -61,14 +66,14 @@ and provided thanks to the work of the following contributors: * [rkarabut](https://github.com/rkarabut) * [jeroenpraat](mailto:jeroenpraat@users.noreply.github.com) * [marek-lach](https://github.com/marek-lach) +* [krainboltgreene](https://github.com/krainboltgreene) * [Artoria2e5](https://github.com/Artoria2e5) * [rinsuki](https://github.com/rinsuki) * [marrus-sh](https://github.com/marrus-sh) -* [krainboltgreene](https://github.com/krainboltgreene) -* [pfigel](https://github.com/pfigel) -* [BoFFire](https://github.com/BoFFire) -* [Aldarone](https://github.com/Aldarone) * [deepy](https://github.com/deepy) +* [pfigel](https://github.com/pfigel) +* [Aldarone](https://github.com/Aldarone) +* [BoFFire](https://github.com/BoFFire) * [clworld](https://github.com/clworld) * [MasterGroosha](https://github.com/MasterGroosha) * [dracos](https://github.com/dracos) @@ -76,19 +81,25 @@ and provided thanks to the work of the following contributors: * [SerCom_KC](mailto:sercom-kc@users.noreply.github.com) * [Sylvhem](https://github.com/Sylvhem) * [koyuawsmbrtn](https://github.com/koyuawsmbrtn) +* [taichi221228](https://github.com/taichi221228) * [MitarashiDango](https://github.com/MitarashiDango) * [angristan](https://github.com/angristan) * [JeanGauthier](https://github.com/JeanGauthier) * [kschaper](https://github.com/kschaper) * [beatrix-bitrot](https://github.com/beatrix-bitrot) +* [github-actions[bot]](https://github.com/apps/github-actions) * [BenLubar](https://github.com/BenLubar) * [mkljczk](https://github.com/mkljczk) * [adbelle](https://github.com/adbelle) * [evanminto](https://github.com/evanminto) * [MightyPork](https://github.com/MightyPork) * [ashleyhull-versent](https://github.com/ashleyhull-versent) +* [gunchleoc](https://github.com/gunchleoc) +* [kedamaDQ](https://github.com/kedamaDQ) * [yhirano55](https://github.com/yhirano55) * [mashirozx](https://github.com/mashirozx) +* [dariusk](https://github.com/dariusk) +* [mgmn](https://github.com/mgmn) * [devkral](https://github.com/devkral) * [camponez](https://github.com/camponez) * [Hugo Gameiro](mailto:hmgameiro@gmail.com) @@ -96,12 +107,14 @@ and provided thanks to the work of the following contributors: * [SerCom_KC](mailto:szescxz@gmail.com) * [aschmitz](https://github.com/aschmitz) * [mfmfuyu](https://github.com/mfmfuyu) -* [kedamaDQ](https://github.com/kedamaDQ) +* [mistydemeo](https://github.com/mistydemeo) * [fpiesche](https://github.com/fpiesche) * [gandaro](https://github.com/gandaro) * [johnsudaar](https://github.com/johnsudaar) * [trebmuh](https://github.com/trebmuh) * [rmhasan](https://github.com/rmhasan) +* [Trevor Wolf](mailto:teeerevor@gmail.com) +* [jsgoldstein](https://github.com/jsgoldstein) * [lindwurm](https://github.com/lindwurm) * [victorhck](mailto:victorhck@geeko.site) * [voidsatisfaction](https://github.com/voidsatisfaction) @@ -109,49 +122,58 @@ and provided thanks to the work of the following contributors: * [seefood](https://github.com/seefood) * [jackjennings](https://github.com/jackjennings) * [sunny](https://github.com/sunny) +* [VyrCossont](https://github.com/VyrCossont) +* [Izorkin](https://github.com/Izorkin) * [puckipedia](https://github.com/puckipedia) * [splaGit](https://github.com/splaGit) * [tateisu](https://github.com/tateisu) * [walf443](https://github.com/walf443) +* [progval](https://github.com/progval) * [JoelQ](https://github.com/JoelQ) -* [mistydemeo](https://github.com/mistydemeo) * [Ashley](mailto:expenses@airmail.cc) * [xqus](https://github.com/xqus) +* [CSDUMMI](https://github.com/CSDUMMI) * [pfm-eyesightjp](https://github.com/pfm-eyesightjp) +* [S-H-GAMELINKS](https://github.com/S-H-GAMELINKS) * [fakenine](https://github.com/fakenine) +* [Signez](https://github.com/Signez) * [tsuwatch](https://github.com/tsuwatch) -* [progval](https://github.com/progval) * [victorhck](https://github.com/victorhck) -* [Izorkin](https://github.com/Izorkin) +* [luzpaz](https://github.com/luzpaz) * [manuelviens](mailto:manuelviens@users.noreply.github.com) * [fvh-P](https://github.com/fvh-P) * [lfuelling](https://github.com/lfuelling) * [rtucker](https://github.com/rtucker) * [Anna e só](mailto:contraexemplos@gmail.com) * [danieljakots](https://github.com/danieljakots) -* [dariusk](https://github.com/dariusk) * [Gomasy](https://github.com/Gomasy) -* [kazu9su](https://github.com/kazu9su) -* [komic](https://github.com/komic) +* [j-f1](https://github.com/j-f1) +* [kescherCode](https://github.com/kescherCode) +* [tooooooooomy](https://github.com/tooooooooomy) +* [Komic](mailto:contact@komic.eu) * [lmorchard](https://github.com/lmorchard) * [diomed](https://github.com/diomed) * [Neetshin](mailto:neetshin@neetsh.in) * [rainyday](https://github.com/rainyday) +* [rgroothuijsen](https://github.com/rgroothuijsen) +* [rrgeorge](https://github.com/rrgeorge) * [tcitworld](https://github.com/tcitworld) +* [timetinytim](https://github.com/timetinytim) * [valentin2105](https://github.com/valentin2105) * [yuntan](https://github.com/yuntan) * [goofy-bz](mailto:goofy@babelzilla.org) * [kadiix](https://github.com/kadiix) * [kodacs](https://github.com/kodacs) -* [luzpaz](https://github.com/luzpaz) * [marcin mikołajczak](mailto:me@m4sk.in) -* [berkes](https://github.com/berkes) +* [prplecake](https://github.com/prplecake) * [KScl](https://github.com/KScl) -* [sterdev](https://github.com/sterdev) +* [deprecated-acct](https://github.com/deprecated-acct) * [TheKinrar](https://github.com/TheKinrar) * [AA4ch1](https://github.com/AA4ch1) * [alexgleason](https://github.com/alexgleason) +* [berkes](https://github.com/berkes) * [cpytel](https://github.com/cpytel) +* [connorshea](https://github.com/connorshea) * [cutls](https://github.com/cutls) * [northerner](https://github.com/northerner) * [weex](https://github.com/weex) @@ -159,21 +181,22 @@ and provided thanks to the work of the following contributors: * [fhemberger](https://github.com/fhemberger) * [greysteil](https://github.com/greysteil) * [henrycatalinismith](https://github.com/henrycatalinismith) +* [hs4man21](https://github.com/hs4man21) * [HolgerHuo](https://github.com/HolgerHuo) * [d6rkaiz](https://github.com/d6rkaiz) * [ladyisatis](https://github.com/ladyisatis) * [JMendyk](https://github.com/JMendyk) -* [kescherCode](https://github.com/kescherCode) * [JohnD28](https://github.com/JohnD28) +* [casaper](https://github.com/casaper) * [znz](https://github.com/znz) * [saper](https://github.com/saper) * [Naouak](https://github.com/Naouak) * [pawelngei](https://github.com/pawelngei) -* [rgroothuijsen](https://github.com/rgroothuijsen) * [reneklacan](https://github.com/reneklacan) * [ekiru](https://github.com/ekiru) * [unasuke](https://github.com/unasuke) * [geta6](https://github.com/geta6) +* [gol-cha](https://github.com/gol-cha) * [happycoloredbanana](https://github.com/happycoloredbanana) * [joenepraat](https://github.com/joenepraat) * [leopku](https://github.com/leopku) @@ -184,6 +207,7 @@ and provided thanks to the work of the following contributors: * [aji-su](https://github.com/aji-su) * [ikuradon](https://github.com/ikuradon) * [nzws](https://github.com/nzws) +* [moritzheiber](https://github.com/moritzheiber) * [SuperSandro2000](https://github.com/SuperSandro2000) * [178inaba](https://github.com/178inaba) * [acid-chicken](https://github.com/acid-chicken) @@ -192,17 +216,24 @@ and provided thanks to the work of the following contributors: * [aablinov](https://github.com/aablinov) * [stalker314314](https://github.com/stalker314314) * [cohosh](https://github.com/cohosh) +* [muffinista](https://github.com/muffinista) * [huertanix](https://github.com/huertanix) +* [consideRatio](https://github.com/consideRatio) * [eleboucher](https://github.com/eleboucher) +* [FrancisMurillo](https://github.com/FrancisMurillo) * [halkeye](https://github.com/halkeye) * [Hanage999](https://github.com/Hanage999) * [treby](https://github.com/treby) +* [eltociear](https://github.com/eltociear) * [jpdevries](https://github.com/jpdevries) * [gdpelican](https://github.com/gdpelican) * [pbzweihander](https://github.com/pbzweihander) * [MonaLisaOverrdrive](https://github.com/MonaLisaOverrdrive) * [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name) +* [Tak](https://github.com/Tak) * [panarom](https://github.com/panarom) +* [MFTabriz](https://github.com/MFTabriz) +* [vmstan](https://github.com/vmstan) * [Dar13](https://github.com/Dar13) * [nevillepark](https://github.com/nevillepark) * [ornithocoder](https://github.com/ornithocoder) @@ -211,8 +242,10 @@ and provided thanks to the work of the following contributors: * [qguv](https://github.com/qguv) * [Ram Lmn](mailto:ramlmn@users.noreply.github.com) * [Sascha](mailto:sascha@serenitylabs.cloud) +* [SISheogorath](https://github.com/SISheogorath) * [harukasan](https://github.com/harukasan) * [stamak](https://github.com/stamak) +* [OmmyZhang](https://github.com/OmmyZhang) * [Technowix](https://github.com/Technowix) * [Zoeille](https://github.com/Zoeille) * [Thorwegian](https://github.com/Thorwegian) @@ -220,30 +253,31 @@ and provided thanks to the work of the following contributors: * [gled-rs](https://github.com/gled-rs) * [Valentin_NC](mailto:valentin.ouvrard@nautile.sarl) * [R0ckweb](https://github.com/R0ckweb) +* [alfe](https://github.com/alfe) * [caasi](https://github.com/caasi) * [chandrn7](https://github.com/chandrn7) * [chr-1x](https://github.com/chr-1x) * [esetomo](https://github.com/esetomo) * [foxiehkins](https://github.com/foxiehkins) -* [gol-cha](https://github.com/gol-cha) * [highemerly](https://github.com/highemerly) * [hoodie](mailto:hoodiekitten@outlook.com) * [kaiyou](https://github.com/kaiyou) * [007lva](https://github.com/007lva) * [luzi82](https://github.com/luzi82) -* [prplecake](https://github.com/prplecake) * [duxovni](https://github.com/duxovni) * [slice](https://github.com/slice) * [tmm576](https://github.com/tmm576) * [unsmell](mailto:unsmell@users.noreply.github.com) * [valerauko](https://github.com/valerauko) * [Grawl](https://github.com/Grawl) -* [chriswmartin](https://github.com/chriswmartin) +* [minacle](https://github.com/minacle) * [AndreLewin](https://github.com/AndreLewin) * [0xflotus](https://github.com/0xflotus) * [redtachyons](https://github.com/redtachyons) * [thurloat](https://github.com/thurloat) +* [Akkiesoft](https://github.com/Akkiesoft) * [aaribaud](https://github.com/aaribaud) +* [Saiv46](https://github.com/Saiv46) * [pointlessone](https://github.com/pointlessone) * [Andrew](mailto:andrewlchronister@gmail.com) * [arielrodrigues](https://github.com/arielrodrigues) @@ -254,29 +288,30 @@ and provided thanks to the work of the following contributors: * [dissolve](https://github.com/dissolve) * [PurpleBooth](https://github.com/PurpleBooth) * [bradurani](https://github.com/bradurani) -* [wavebeem](https://github.com/wavebeem) +* [bramus](https://github.com/bramus) +* [Brian Mock](mailto:brian@mockbrian.com) * [thermosflasche](https://github.com/thermosflasche) * [LottieVixen](https://github.com/LottieVixen) +* [chriswmartin](https://github.com/chriswmartin) * [wchristian](https://github.com/wchristian) -* [muffinista](https://github.com/muffinista) * [cdutson](https://github.com/cdutson) * [farlistener](https://github.com/farlistener) * [baby-gnu](https://github.com/baby-gnu) * [divergentdave](https://github.com/divergentdave) +* [lochiiconnectivity](https://github.com/lochiiconnectivity) * [DavidLibeau](https://github.com/DavidLibeau) * [dmerejkowsky](https://github.com/dmerejkowsky) * [ddevault](https://github.com/ddevault) * [emilyst](https://github.com/emilyst) -* [consideRatio](https://github.com/consideRatio) * [Fjoerfoks](https://github.com/Fjoerfoks) * [fmauNeko](https://github.com/fmauNeko) * [gloaec](https://github.com/gloaec) * [unstabler](https://github.com/unstabler) * [potato4d](https://github.com/potato4d) * [h-izumi](https://github.com/h-izumi) +* [HeitorMC](https://github.com/HeitorMC) * [ErikXXon](https://github.com/ErikXXon) * [ian-kelling](https://github.com/ian-kelling) -* [eltociear](https://github.com/eltociear) * [immae](https://github.com/immae) * [J0WI](https://github.com/J0WI) * [koboldunderlord](https://github.com/koboldunderlord) @@ -285,7 +320,9 @@ and provided thanks to the work of the following contributors: * [raggi](https://github.com/raggi) * [jasonrhodes](https://github.com/jasonrhodes) * [Jason Snell](mailto:jason@newrelic.com) +* [casperisfine](https://github.com/casperisfine) * [jviide](https://github.com/jviide) +* [joshuap](https://github.com/joshuap) * [YuleZ](https://github.com/YuleZ) * [jtracey](https://github.com/jtracey) * [crakaC](https://github.com/crakaC) @@ -294,14 +331,12 @@ and provided thanks to the work of the following contributors: * [Kazhnuz](https://github.com/Kazhnuz) * [mkody](https://github.com/mkody) * [connyduck](https://github.com/connyduck) -* [Tak](https://github.com/Tak) * [LindseyB](https://github.com/LindseyB) * [Lorenz Diener](mailto:halcyon@icosahedron.website) * [Markus Amalthea Magnuson](mailto:markus.magnuson@gmail.com) * [madmath03](https://github.com/madmath03) * [mig5](https://github.com/mig5) * [mohe2015](https://github.com/mohe2015) -* [moritzheiber](https://github.com/moritzheiber) * [Nathaniel Suchy](mailto:me@lunorian.is) * [ndarville](https://github.com/ndarville) * [NimaBoscarino](https://github.com/NimaBoscarino) @@ -312,21 +347,24 @@ and provided thanks to the work of the following contributors: * [xPaw](https://github.com/xPaw) * [petzah](https://github.com/petzah) * [PeterDaveHello](https://github.com/PeterDaveHello) +* [sidp](https://github.com/sidp) * [ignisf](https://github.com/ignisf) * [postmodern](https://github.com/postmodern) * [lumenwrites](https://github.com/lumenwrites) * [remram44](https://github.com/remram44) * [sts10](https://github.com/sts10) +* [arbolitoloco1](https://github.com/arbolitoloco1) * [u1-liquid](https://github.com/u1-liquid) -* [SISheogorath](https://github.com/SISheogorath) * [rosylilly](https://github.com/rosylilly) * [withshubh](https://github.com/withshubh) * [sim6](https://github.com/sim6) * [Sir-Boops](https://github.com/Sir-Boops) * [stemid](https://github.com/stemid) * [sumdog](https://github.com/sumdog) -* [OmmyZhang](https://github.com/OmmyZhang) +* [shuuji3](https://github.com/shuuji3) +* [edent](https://github.com/edent) * [ThomasLeister](https://github.com/ThomasLeister) +* [timothyjrogers](https://github.com/timothyjrogers) * [Tom McAtee](mailto:a1608768@student.adelaide.edu.au) * [tototoshi](https://github.com/tototoshi) * [TrashMacNugget](https://github.com/TrashMacNugget) @@ -343,11 +381,13 @@ and provided thanks to the work of the following contributors: * [aus-social](https://github.com/aus-social) * [bsky](mailto:git@bsky.moe) * [bsky](mailto:me@imbsky.net) +* [cadars](https://github.com/cadars) * [codl](https://github.com/codl) * [cpsdqs](https://github.com/cpsdqs) * [dogelover911](https://github.com/dogelover911) +* [emilweth](https://github.com/emilweth) * [barzamin](https://github.com/barzamin) -* [gunchleoc](https://github.com/gunchleoc) +* [forsamori](https://github.com/forsamori) * [fhalna](https://github.com/fhalna) * [haoyayoi](https://github.com/haoyayoi) * [helloworldstack](https://github.com/helloworldstack) @@ -358,6 +398,7 @@ and provided thanks to the work of the following contributors: * [mbajur](https://github.com/mbajur) * [matsurai25](https://github.com/matsurai25) * [mecab](https://github.com/mecab) +* [nametoolong](https://github.com/nametoolong) * [nicobz25](https://github.com/nicobz25) * [niwatori24](https://github.com/niwatori24) * [noiob](https://github.com/noiob) @@ -374,14 +415,15 @@ and provided thanks to the work of the following contributors: * [vjackson725](https://github.com/vjackson725) * [wxcafe](https://github.com/wxcafe) * [新都心(Neet Shin)](mailto:nucx@dio-vox.com) -* [clarfonthey](https://github.com/clarfonthey) -* [cygnan](https://github.com/cygnan) -* [Awea](https://github.com/Awea) +* [tenderlove](https://github.com/tenderlove) +* [raboof](https://github.com/raboof) * [single-right-quote](https://github.com/single-right-quote) * [8398a7](https://github.com/8398a7) * [857b](https://github.com/857b) +* [9p4](https://github.com/9p4) * [insom](https://github.com/insom) * [tachyons](https://github.com/tachyons) +* [AcesFullOfKings](https://github.com/AcesFullOfKings) * [Esteth](https://github.com/Esteth) * [unascribed](https://github.com/unascribed) * [Aguay-val](https://github.com/Aguay-val) @@ -389,13 +431,14 @@ and provided thanks to the work of the following contributors: * [h3poteto](https://github.com/h3poteto) * [unleashed](https://github.com/unleashed) * [alxrcs](https://github.com/alxrcs) +* [alexstine](https://github.com/alexstine) * [console-cowboy](https://github.com/console-cowboy) -* [Saiv46](https://github.com/Saiv46) * [Alkarex](https://github.com/Alkarex) * [a2](https://github.com/a2) * [Alfie John](mailto:33c6c91f3bb4a391082e8a29642cafaf@alfie.wtf) * [0xa](https://github.com/0xa) * [ashpieboop](https://github.com/ashpieboop) +* [alisonw](https://github.com/alisonw) * [virtualpain](https://github.com/virtualpain) * [sapphirus](https://github.com/sapphirus) * [amandavisconti](https://github.com/amandavisconti) @@ -406,88 +449,120 @@ and provided thanks to the work of the following contributors: * [schas002](https://github.com/schas002) * [contraexemplo](https://github.com/contraexemplo) * [abackstrom](https://github.com/abackstrom) +* [AntoninDelFabbro](https://github.com/AntoninDelFabbro) * [orlea](https://github.com/orlea) * [armandfardeau](https://github.com/armandfardeau) -* [raboof](https://github.com/raboof) * [v-aisac](https://github.com/v-aisac) -* [gi-yt](https://github.com/gi-yt) -* [boahc077](https://github.com/boahc077) -* [aldatsa](https://github.com/aldatsa) -* [jumbosushi](https://github.com/jumbosushi) -* [acuteaura](https://github.com/acuteaura) -* [ayumin](https://github.com/ayumin) -* [bzg](https://github.com/bzg) -* [BastienDurel](https://github.com/BastienDurel) -* [bearice](https://github.com/bearice) -* [li-bei](https://github.com/li-bei) -* [hardillb](https://github.com/hardillb) +* [Arya K](mailto:73596856+gi-yt@users.noreply.github.com) +* [Ashish Kurmi](mailto:100655670+boahc077@users.noreply.github.com) +* [Asier Iturralde Sarasola](mailto:asier.iturralde@gmail.com) +* [Atsushi Yamamoto](mailto:yamaatsushi927@gmail.com) +* [Aurelia](mailto:aurelia@schittler.dev) +* [Avdi Grimm](mailto:avdi@users.noreply.github.com) +* [Ayumu AIZAWA](mailto:ayumu.aizawa@gmail.com) +* [Bastien](mailto:bzg@users.noreply.github.com) +* [Bastien Durel](mailto:bastien@durel.org) +* [Bearice Ren](mailto:bearice@gmail.com) +* [Bei Li](mailto:kylinroc@gmail.com) +* [Ben Hardill](mailto:b.hardill@gmail.com) * [Benedikt Geißler](mailto:benedikt@g5r.eu) -* [BenisonSebastian](https://github.com/BenisonSebastian) +* [BenisonSebastian](mailto:33474422+benisonsebastian@users.noreply.github.com) * [Blake](mailto:blake.barnett@postmates.com) +* [Botao Wang](mailto:wxt2005@gmail.com) * [Brad Janke](mailto:brad.janke@gmail.com) -* [braydofficial](https://github.com/braydofficial) -* [bclindner](https://github.com/bclindner) -* [brycied00d](https://github.com/brycied00d) -* [carlosjs23](https://github.com/carlosjs23) -* [WyriHaximus](https://github.com/WyriHaximus) -* [cgxxx](https://github.com/cgxxx) -* [kibitan](https://github.com/kibitan) -* [cdzombak](https://github.com/cdzombak) -* [chrisheninger](https://github.com/chrisheninger) -* [chris-martin](https://github.com/chris-martin) -* [offbyone](https://github.com/offbyone) -* [cclauss](https://github.com/cclauss) -* [DoubleMalt](https://github.com/DoubleMalt) -* [Moosh-be](https://github.com/Moosh-be) -* [cchoi12](https://github.com/cchoi12) -* [Motoma](https://github.com/Motoma) +* [Brayd](mailto:byronfroehlich@proton.me) +* [Brian C. Lindner](mailto:cslindner@gmail.com) +* [Brian Campbell](mailto:unlambda@gmail.com) +* [Bryce Chidester](mailto:bryce@cobryce.com) +* [BtbN](mailto:btbn@btbn.de) +* [ButterflyOfFire](mailto:42316180+boffire@users.noreply.github.com) +* [Bèr Kessels](mailto:github@berk.es) +* [Carl Schwan](mailto:carl@carlschwan.eu) +* [Carlos A. Escobar](mailto:ingcarlosandresescobar@gmail.com) +* [Cees-Jan Kiewiet](mailto:ceesjank@gmail.com) +* [CgX](mailto:github@cgx.me) +* [Chikahiro Tokoro](mailto:uzukifirst@gmail.com) +* [Chike Nwaenie](mailto:chikenwaenie@gmail.com) +* [Chris](mailto:cmarti14@artic.edu) +* [Chris Dzombak](mailto:chris@chrisdzombak.net) +* [Chris Funderburg](mailto:chris@funderburg.me) +* [Chris Heninger](mailto:heninger@gmail.com) +* [Chris Johnson](mailto:49479599+workeffortwaste@users.noreply.github.com) +* [Chris Martin](mailto:ch.martin@gmail.com) +* [Chris Rose](mailto:offbyone@github.com) +* [Christian Clauss](mailto:cclauss@me.com) +* [Christoph Witzany](mailto:christoph@web.crofting.com) +* [Christophe Gesché](mailto:moosh@php.net) +* [Christopher Choi](mailto:cdddchris@gmail.com) +* [Christopher Gilbert](mailto:motoma@gmail.com) * [Christopher Kolstad](mailto:christopher.kolstad@finn.no) -* [csu](https://github.com/csu) -* [kklleemm](https://github.com/kklleemm) -* [colindean](https://github.com/colindean) -* [CommanderRoot](https://github.com/CommanderRoot) -* [connorshea](https://github.com/connorshea) -* [DeeUnderscore](https://github.com/DeeUnderscore) -* [dachinat](https://github.com/dachinat) +* [Christopher Nethercott](mailto:ccnethercott@gmail.com) +* [Christopher Su](mailto:christophersu9@gmail.com) +* [Clar Charr](mailto:clar@charr.xyz) +* [Clar Fon](mailto:them@lightdark.xyz) +* [Clément D](mailto:kklleemm@users.noreply.github.com) +* [Colette Kerr](mailto:colette.m.y.kerr@gmail.com) +* [Colin Dean](mailto:colindean@users.noreply.github.com) +* [CommanderRoot](mailto:commanderroot@users.noreply.github.com) +* [Cygnan](mailto:email@cygnan.com) +* [Cygnan](mailto:mail@cygnan.com) +* [D Anzorge](mailto:d.anzorge@gmail.com) +* [Dachi Natsvlishvili](mailto:dachinat@gmail.com) * [Daggertooth](mailto:dev@monsterpit.net) -* [watilde](https://github.com/watilde) -* [dalehenries](https://github.com/dalehenries) -* [daprice](https://github.com/daprice) -* [da2x](https://github.com/da2x) -* [codesections](https://github.com/codesections) -* [dar5hak](https://github.com/dar5hak) -* [kant](https://github.com/kant) -* [maxolasersquad](https://github.com/maxolasersquad) +* [Daijiro Wachi](mailto:daijiro.wachi@gmail.com) +* [Dale Henries](mailto:dalehenries@gmail.com) +* [Dale Price](mailto:daprice@users.noreply.github.com) +* [Dan Peterson](mailto:danp@danp.net) +* [Daniel Aleksandersen](mailto:code@daniel.priv.no) +* [Daniel Axtens](mailto:daniel@axtens.net) +* [Daniel Sockwell](mailto:dsockwell@gmail.com) +* [Darshak Parikh](mailto:dar5hak@users.noreply.github.com) +* [Darío Hereñú](mailto:magallania@gmail.com) +* [David Authier](mailto:aweaoftheworld@gmail.com) +* [David Baucum](mailto:maxolasersquad@gmail.com) * [David Baumgold](mailto:david@davidbaumgold.com) * [David Caldwell](mailto:david+github@porkrind.org) * [David Celis](mailto:me@davidcel.is) * [David Hewitt](mailto:davidmhewitt@users.noreply.github.com) +* [David Leadbeater](mailto:dgl@dgl.cx) * [David Underwood](mailto:davefp@gmail.com) +* [David Vega](mailto:david-vega@users.noreply.github.com) * [David Yip](mailto:yipdw@member.fsf.org) +* [Dean Bassett](mailto:dean@dbassett.dev) * [Debanshu Kundu](mailto:debanshu.kundu@joshtechnologygroup.com) * [Denis Teyssier](mailto:admin@mascali.ovh) * [Derek Lewis](mailto:derekcecillewis@gmail.com) * [Devon Blandin](mailto:dblandin@gmail.com) +* [Douglas Blank](mailto:doug.blank@gmail.com) * [Drew Gates](mailto:aranaur@users.noreply.github.com) * [Drew Schuster](mailto:dtschust@gmail.com) * [Dryusdan](mailto:dryusdan@dryusdan.fr) * [Eai](mailto:eai@mizle.net) +* [Eashwar Ranganathan](mailto:eranganathan@lyft.com) * [Ed Knutson](mailto:knutsoned@gmail.com) -* [Effy Elden](mailto:effy@effy.space) +* [Elizabeth Martín Campos](mailto:me@elizabeth.sh) * [Elizabeth Myers](mailto:elizabeth@interlinked.me) +* [Ell Bradshaw](mailto:cincodenada@gmail.com) * [Eric](mailto:enewhuis@gmail.com) * [Eric Blade](mailto:blade.eric@gmail.com) * [Eshin Kunishima](mailto:mikoim@users.noreply.github.com) * [Espen Rønnevik](mailto:espen@ronnevik.net) +* [Essem](mailto:smswessem@gmail.com) +* [Evan](mailto:35814742+evanphilip@users.noreply.github.com) * [Expenses](mailto:expenses@airmail.cc) * [Fabian Schlenz](mailto:mail@fabianonline.de) * [Faye Duxovni](mailto:duxovni@duxovni.org) * [Filipe Rodrigues](mailto:shello@shello.org) * [Finariel](mailto:finariel@gmail.com) +* [Florin](mailto:csflorin@users.noreply.github.com) +* [Foritus](mailto:rich@aornis.com) * [Francis Chong](mailto:francis@ignition.hk) * [Franck Zoccolo](mailto:franck@zoccolo.com) +* [Frankie Roberto](mailto:frankie@frankieroberto.com) * [Fred Wenzel](mailto:fwenzel@users.noreply.github.com) +* [Fries](mailto:40834252+ayefries@users.noreply.github.com) * [Gabriel Rubens](mailto:gabrielrumiranda@gmail.com) +* [Gabriel Simmer](mailto:github@gmem.ca) * [Gaelan Steele](mailto:gbs@canishe.com) * [Genbu Hase](mailto:hasegenbu@gmail.com) * [Georg Gadinger](mailto:nilsding@nilsding.org) @@ -509,48 +584,65 @@ and provided thanks to the work of the following contributors: * [Hiroe Jun](mailto:jun.hiroe@gmail.com) * [Hiromi Kai](mailto:pie05041008@gmail.com) * [Hisham Muhammad](mailto:hisham@gobolinux.org) +* [HonkingGoose](mailto:34918129+honkinggoose@users.noreply.github.com) * [Hugo "Slaynash" Flores](mailto:hugoflores@hotmail.fr) * [INAGAKI Hiroshi](mailto:musashino205@users.noreply.github.com) * [IWAI, Masaharu](mailto:iwaim.sub@gmail.com) +* [Ian](mailto:ian@devolute.net) * [Ian McCowan](mailto:imccowan@gmail.com) * [Ian McDowell](mailto:me@ianmcdowell.net) * [Iijima Yasushi](mailto:kurage.cc@gmail.com) * [Ingo Blechschmidt](mailto:iblech@web.de) * [Irie Aoi](mailto:eai@mizle.net) +* [Ivan Rodriguez](mailto:104603218+irod22@users.noreply.github.com) * [J Yeary](mailto:usbsnowcrash@users.noreply.github.com) +* [JT Olio](mailto:hello@jtolio.com) * [Jack Michaud](mailto:jack-michaud@users.noreply.github.com) +* [Jaehong Kang](mailto:sinoru@me.com) * [Jakub Mendyk](mailto:jakubmendyk.szkola@gmail.com) * [James](mailto:james.allen.vaughan@gmail.com) +* [James Adney](mailto:jfadney@gmail.com) * [James Smith](mailto:james@floppy.org.uk) +* [Jamie Hoyle](mailto:j@jamiehoyle.com) * [Jarek Lipski](mailto:pub@loomchild.net) +* [Jay Prakash Kalia](mailto:jaykalia047@gmail.com) * [Jennifer Glauche](mailto:=^.^=@github19.jglauche.de) * [Jennifer Kruse](mailto:jenkr55@gmail.com) * [Jeremy Rose](mailto:nornagon@nornagon.net) * [Jessica](mailto:46502909+hyenagirl64@users.noreply.github.com) * [Jessica K. Litwin](mailto:jessica@litw.in) +* [Jim Myhrberg](mailto:contact@jimeh.me) * [Jo Decker](mailto:trolldecker@users.noreply.github.com) * [Joan Montané](mailto:jmontane@users.noreply.github.com) * [Joe](mailto:401283+htmlbyjoe@users.noreply.github.com) * [Joe Friedl](mailto:stuff@joefriedl.net) +* [Jonathan Hawkes](mailto:jonathan@thoughtbuilt.com) * [Jonathan Klee](mailto:klee.jonathan@gmail.com) * [Jordan Guerder](mailto:jguerder@fr.pulseheberg.net) * [Joseph Mingrone](mailto:jehops@users.noreply.github.com) * [Josh Leeb-du Toit](mailto:mail@joshleeb.com) +* [Josh McKinney](mailto:joshka@users.noreply.github.com) * [Josh Soref](mailto:2119212+jsoref@users.noreply.github.com) -* [Joshua Wood](mailto:josh@joshuawood.net) +* [João Pedro Marques](mailto:64037198+thedevjoao@users.noreply.github.com) +* [Juan Xavier Gomez](mailto:jgomez@codecademy.com) * [Julien](mailto:tiwy57@users.noreply.github.com) * [Julien Deswaef](mailto:juego@requiem4tv.com) +* [Jullan-M](mailto:42940512+jullan-m@users.noreply.github.com) * [June Sallou](mailto:jnsll@users.noreply.github.com) +* [Justin Hutchings](mailto:jhutchings1@users.noreply.github.com) * [Justin Thomas](mailto:justin@jdt.io) * [Jérémy Benoist](mailto:j0k3r@users.noreply.github.com) * [KEINOS](mailto:github@keinos.com) +* [Kai](mailto:2644614+schweinepriester@users.noreply.github.com) * [Kairui Song | 宋恺睿](mailto:ryncsn@gmail.com) * [Keiji Matsuzaki](mailto:futoase@gmail.com) * [Kevin Liu](mailto:kevin@potatofrom.space) * [Kit Redgrave](mailto:qwertyitis@gmail.com) * [Knut Erik](mailto:abjectio@users.noreply.github.com) +* [Kohei Ota (inductor)](mailto:kela@inductor.me) * [Kota Ouchi](mailto:k0ta0uchi@gmail.com) * [Krzysztof Jurewicz](mailto:krzysztof.jurewicz@gmail.com) +* [Kuba Suder](mailto:mackuba@users.noreply.github.com) * [Leo Wzukw](mailto:leowzukw@users.noreply.github.com) * [Leonie](mailto:62470640+bubblineyuri@users.noreply.github.com) * [Lex Alexander](mailto:l.alexander10@gmail.com) @@ -558,12 +650,17 @@ and provided thanks to the work of the following contributors: * [Lorenz Diener](mailto:lorenzd@gmail.com) * [Luc Didry](mailto:ldidry@users.noreply.github.com) * [Lukas Burk](mailto:jemus42@users.noreply.github.com) +* [Lukas Martini](mailto:lutoma@ohai.su) +* [Luxiaba](mailto:5391976+luxiaba@users.noreply.github.com) * [Manato Kameya](mailto:grabacr07+github@gmail.com) * [Mantas](mailto:mistermantas@users.noreply.github.com) * [Mareena Kunjachan](mailto:mareenakunjachan@gmail.com) * [Marek Lach](mailto:marek.brohatwack.lach@gmail.com) +* [Mark Roszko](mailto:mark.roszko@gmail.com) * [Markus Petzsch](mailto:markus@petzsch.eu) * [Markus R](mailto:wirehack7@users.noreply.github.com) +* [Markus Unterwaditzer](mailto:markus-honeypot@unterwaditzer.net) +* [Markus Unterwaditzer](mailto:markus@unterwaditzer.net) * [Marty McGuire](mailto:schmartissimo@gmail.com) * [Marvin Kopf](mailto:marvinkopf@posteo.de) * [Masafumi Otsune](mailto:info@otsune.com) @@ -571,21 +668,24 @@ and provided thanks to the work of the following contributors: * [Mateusz Bugowski](mailto:23140767+mbugowski@users.noreply.github.com) * [Mathias B](mailto:10813340+mathias-b@users.noreply.github.com) * [Mathieu Brunot](mailto:mb.mathieu.brunot@gmail.com) +* [Matias Lago Evia](mailto:matiaslagoevia@gmail.com) * [Matt](mailto:matt-auckland@users.noreply.github.com) * [Matt Corallo](mailto:649246+thebluematt@users.noreply.github.com) +* [Matt Hodges](mailto:hodgesmr1@gmail.com) * [Matt Sweetman](mailto:webroo@gmail.com) +* [Matt Williams](mailto:matt@makeable.co.uk) * [Matthias Bethke](mailto:matthias@towiski.de) * [Matthias Beyer](mailto:mail@beyermatthias.de) * [Matthias Jouan](mailto:matthias.jouan@gmail.com) * [Matthieu Paret](mailto:matthieuparet69@gmail.com) +* [Matthías Páll Gissurarson](mailto:mpg@mpg.is) * [Maxime BORGES](mailto:maxime.borges@gmail.com) -* [Mayu Laierlence](mailto:minacle@live.com) -* [Meisam](mailto:39205857+mftabriz@users.noreply.github.com) * [Michael Deeb](mailto:michaeldeeb@me.com) * [Michael Vieira](mailto:dtox94@gmail.com) * [Michel](mailto:michel@cyweo.com) * [Midgard](mailto:m1dgard@users.noreply.github.com) * [Mike Burns](mailto:mburns@thoughtbot.com) +* [Mikhail Paulyshka](mailto:me@mixaill.net) * [Milan](mailto:me@petabyteboy.de) * [Milan*](mailto:tchncs@vivaldi.net) * [Milton Mazzarri](mailto:milmazz@gmail.com) @@ -602,9 +702,12 @@ and provided thanks to the work of the following contributors: * [Nanamachi](mailto:town7.haruki@gmail.com) * [Nathaniel Ekoniak](mailto:nekoniak@ennate.tech) * [NecroTechno](mailto:necrotechno@riseup.net) +* [Neil Matatall](mailto:448516+oreoshake@users.noreply.github.com) * [Nicholas La Roux](mailto:larouxn@gmail.com) * [Nick Gerakines](mailto:nick@gerakines.net) +* [Nicolai Søborg](mailto:nicolaisoeborg@users.noreply.github.com) * [Nicolai von Neudeck](mailto:nicolai@vonneudeck.com) +* [Nikita Karamov](mailto:me@kytta.dev) * [Ninetailed](mailto:ninetailed@gmail.com) * [Nishi, Keisuke](mailto:k24@users.noreply.github.com) * [Noiob](mailto:noiob@users.noreply.github.com) @@ -616,34 +719,49 @@ and provided thanks to the work of the following contributors: * [Oskari Noppa](mailto:noppa@users.noreply.github.com) * [Otakan](mailto:otakan951@gmail.com) * [Padraig Fahy](mailto:tech@padraigfahy.com) +* [Partho Ghosh](mailto:partho.ghosh24@gmail.com) * [Patrice Ferlet](mailto:metal3d@gmail.com) * [PatrickRWells](mailto:32802366+patrickrwells@users.noreply.github.com) * [Paul](mailto:naydex.mc+github@gmail.com) +* [PauloVilarinho](mailto:33267902+paulovilarinho@users.noreply.github.com) * [Pete Keen](mailto:pete@petekeen.net) * [Pierre Bourdon](mailto:delroth@gmail.com) * [Pierre-Morgan Gate](mailto:pgate@users.noreply.github.com) +* [Plastikmensch](mailto:plastikmensch@users.noreply.github.com) +* [Pleclown](mailto:pleclown+github@gmail.com) +* [Ramūns Usovs](mailto:ramuuns@enkurs.org) * [Ratmir Karabut](mailto:rkarabut@sfmodern.ru) * [Reto Kromer](mailto:retokromer@users.noreply.github.com) +* [Riedler](mailto:github@riedler.wien) +* [Rin](mailto:36845451+ateliersnek@users.noreply.github.com) * [Rob Petti](mailto:rob.petti@gmail.com) +* [Rob Thomas](mailto:xrobau@gmail.com) * [Rob Watson](mailto:rfwatson@users.noreply.github.com) * [Robert Laurenz](mailto:8169746+laurenzcodes@users.noreply.github.com) +* [Rodion Borisov](mailto:vintprox@gmail.com) * [Rohan Sharma](mailto:i.am.lone.survivor@protonmail.com) * [Roni Laukkarinen](mailto:roni@laukkarinen.info) +* [Rose](mailto:83477269+ataridreams@users.noreply.github.com) +* [Rubicon Rowe](mailto:thislight@users.noreply.github.com) * [Ryan Freebern](mailto:ryan@freebern.org) * [Ryan Wade](mailto:ryan.wade@protonmail.com) * [Ryo Kajiwara](mailto:kfe-fecn6.prussian@s01.info) -* [S.H](mailto:gamelinks007@gmail.com) * [SJang1](mailto:git@sjang.dev) * [Sadiq Saif](mailto:staticsafe@users.noreply.github.com) +* [Sai](mailto:github@saizai.com) * [Sam Hewitt](mailto:hewittsamuel@gmail.com) +* [Samruddhi Khandale](mailto:samruddhikhandale@github.com) * [Samuel Kaiser](mailto:sk22@mailbox.org) +* [Santiago Kozak](mailto:santikzk1406@gmail.com) * [Sara Aimée Smiseth](mailto:51710585+sarasmiseth@users.noreply.github.com) * [Sara Golemon](mailto:pollita@php.net) * [Satoshi KOJIMA](mailto:skoji@mac.com) * [ScienJus](mailto:i@scienjus.com) * [Scott Larkin](mailto:scott@codeclimate.com) * [Scott Sweeny](mailto:scott@ssweeny.net) +* [Sean](mailto:64788907+seano-vs@users.noreply.github.com) * [Sean](mailto:sean@sean.taipei) +* [Sean Whalen](mailto:44679+seanthegeek@users.noreply.github.com) * [Sebastian Hübner](mailto:imolein@users.noreply.github.com) * [Sebastian Morr](mailto:sebastian@morr.cc) * [Sergei Č](mailto:noiwex1911@gmail.com) @@ -652,14 +770,19 @@ and provided thanks to the work of the following contributors: * [Shin Adachi](mailto:shn@glucose.jp) * [Shin Kojima](mailto:shin@kojima.org) * [Shouko Yu](mailto:imshouko@gmail.com) +* [Simon Elvery](mailto:simon@elvery.net) * [Sina Mashek](mailto:sina@mashek.xyz) +* [Skyler Hawthorne](mailto:skyler@dead10ck.com) * [Soft. Dev](mailto:24978+nileshkumar@users.noreply.github.com) * [Sophie Parker](mailto:dev@cortices.me) * [Soshi Kato](mailto:mail@sossii.com) * [Spanky](mailto:2788886+spankyworks@users.noreply.github.com) +* [Stan Hu](mailto:stanhu@gmail.com) * [Stanislas](mailto:stanislas.lange@pm.me) +* [Stanislav Dobrovolschii](mailto:uusername@protonmail.ch) * [StefOfficiel](mailto:pichard.stephane@free.fr) * [Stefano Pigozzi](mailto:ste.pigozzi@gmail.com) +* [Steven Munn](mailto:stevenjlm@users.noreply.github.com) * [Steven Tappert](mailto:admin@dark-it.net) * [Stéphane Guillou](mailto:stephane.guillou@member.fsf.org) * [Su Yang](mailto:soulteary@users.noreply.github.com) @@ -672,11 +795,14 @@ and provided thanks to the work of the following contributors: * [TakesxiSximada](mailto:takesxi.sximada@gmail.com) * [Tao Bror Bojlén](mailto:brortao@users.noreply.github.com) * [Taras Gogol](mailto:taras2358@gmail.com) +* [Terry Garcia](mailto:10190993+terrygarcia@users.noreply.github.com) * [The Stranjer](mailto:791672+thestranjer@users.noreply.github.com) * [TheInventrix](mailto:theinventrix@users.noreply.github.com) * [TheMainOne](mailto:50847364+theevilskeleton@users.noreply.github.com) +* [Thijs Kinkhorst](mailto:thijs@kinkhorst.com) * [Thomas Alberola](mailto:thomas@needacoffee.fr) * [Thomas Citharel](mailto:github@tcit.fr) +* [Tim Lucas](mailto:t@toolmantim.com) * [Toby Deshane](mailto:fortyseven@users.noreply.github.com) * [Toby Pinder](mailto:gigitrix@gmail.com) * [Tomonori Murakami](mailto:crosslife777@gmail.com) @@ -684,13 +810,14 @@ and provided thanks to the work of the following contributors: * [Tony Jiang](mailto:yujiang99@gmail.com) * [Treyssat-Vincent Nino](mailto:treyssatvincent@users.noreply.github.com) * [Truong Nguyen](mailto:truongnmt.dev@gmail.com) +* [Tyler Deitz](mailto:tylerdeitz@gmail.com) * [Udo Kramer](mailto:optik@fluffel.io) * [Una](mailto:una@unascribed.com) * [Ushitora Anqou](mailto:ushitora@anqou.net) * [Ushitora Anqou](mailto:ushitora_anqou@yahoo.co.jp) * [Valentin Lorentz](mailto:progval+git@progval.net) +* [Varun Sharma](mailto:varun999sharma@gmail.com) * [Vladimir Mincev](mailto:vladimir@canicinteractive.com) -* [Vyr Cossont](mailto:vyrcossont@users.noreply.github.com) * [Waldir Pimenta](mailto:waldyrious@gmail.com) * [Wenceslao Páez Chávez](mailto:wcpaez@gmail.com) * [Wesley Ellis](mailto:tahnok@gmail.com) @@ -714,8 +841,11 @@ and provided thanks to the work of the following contributors: * [Zach Neill](mailto:neillz@berea.edu) * [Zachary Spector](mailto:logicaldash@gmail.com) * [ZiiX](mailto:ziix@users.noreply.github.com) -* [asria-jp](mailto:is@alicematic.com) +* [aaaaalbert](mailto:aaaaalbert@users.noreply.github.com) +* [afontenot](mailto:adam.m.fontenot@gmail.com) +* [alfe](mailto:alfe10251+github@gmail.com) * [ava](mailto:vladooku@users.noreply.github.com) +* [awea](mailto:aweaoftheworld@gmail.com) * [benklop](mailto:benklop@gmail.com) * [bobbyd0g](mailto:93697464+bobbyd0g@users.noreply.github.com) * [bsky](mailto:git@imbsky.net) @@ -727,10 +857,10 @@ and provided thanks to the work of the following contributors: * [d0p1](mailto:dopi-sama@hush.com) * [dxwc](mailto:dxwc@users.noreply.github.com) * [eai04191](mailto:eai@mizle.net) +* [eggplants](mailto:w10776e8w@yahoo.co.jp) * [evilny0](mailto:evilny0@moomoocamp.net) * [febrezo](mailto:felixbrezo@gmail.com) * [fsubal](mailto:fsubal@users.noreply.github.com) -* [fusagiko / takayamaki](mailto:24884114+takayamaki@users.noreply.github.com) * [fusshi-](mailto:dikky1218@users.noreply.github.com) * [gentaro](mailto:gentaroooo@gmail.com) * [guigeekz](mailto:pattusg@gmail.com) @@ -753,20 +883,27 @@ and provided thanks to the work of the following contributors: * [kedama](mailto:32974885+kedamadq@users.noreply.github.com) * [keiya](mailto:keiya_21@yahoo.co.jp) * [kuro5hin](mailto:rusty@kuro5hin.org) +* [kyori19](mailto:kyori@accelf.net) +* [lenore gilbert](mailto:lenore@lenoregilbert.net) * [leo60228](mailto:leo@60228.dev) * [matildepark](mailto:matilde.park@pm.me) * [maxypy](mailto:maxime@mpigou.fr) * [mhe](mailto:mail@marcus-herrmann.com) +* [mhkhung](mailto:mhkhung@gmail.com) * [mickkael](mailto:19755421+mickkael@users.noreply.github.com) * [mike castleman](mailto:m@mlcastle.net) * [mimikun](mailto:dzdzble_effort_311@outlook.jp) * [mohemohe](mailto:mohemohe@users.noreply.github.com) +* [mon1kasenpai](mailto:ballaticseal@gmail.com) * [mshrtkch](mailto:mshrtkch@users.noreply.github.com) * [muan](mailto:muan@github.com) +* [n0toose](mailto:git@n0toose.net) * [namelessGonbai](mailto:43787036+namelessgonbai@users.noreply.github.com) * [neetshin](mailto:neetshin@neetsh.in) +* [nemobis](mailto:federicoleva@tiscali.it) * [notozeki](mailto:notozeki@users.noreply.github.com) * [ntl-purism](mailto:57806346+ntl-purism@users.noreply.github.com) +* [nyura123dev](mailto:58617294+nyura123dev@users.noreply.github.com) * [nzws](mailto:git-yuzu@svk.jp) * [pea-sys](mailto:49807271+pea-sys@users.noreply.github.com) * [potpro](mailto:pptppctt@gmail.com) @@ -775,6 +912,7 @@ and provided thanks to the work of the following contributors: * [rcombs](mailto:rcombs@rcombs.me) * [roikale](mailto:roikale@users.noreply.github.com) * [rysiekpl](mailto:rysiek@hackerspace.pl) +* [s0](mailto:s0@s0.is) * [sasanquaneuf](mailto:sasanquaneuf@gmail.com) * [saturday06](mailto:dyob@lunaport.net) * [scd31](mailto:57571338+scd31@users.noreply.github.com) @@ -794,9 +932,13 @@ and provided thanks to the work of the following contributors: * [vpzomtrrfrt](mailto:vpzomtrrfrt@gmail.com) * [walfie](mailto:walfington@gmail.com) * [y-temp4](mailto:y.temp4@gmail.com) +* [y.takahashi](mailto:eai@mizle.net) +* [ymmtmdk](mailto:ymmtmdk@gmail.com) * [ymmtmdk](mailto:ymmtmdk@gmail.com) * [yoshipc](mailto:yoooo@yoshipc.net) +* [yufushiro](mailto:62991447+yufushiro@users.noreply.github.com) * [Özcan Zafer AYAN](mailto:ozcanzaferayan@gmail.com) +* [наб](mailto:nabijaczleweli@nabijaczleweli.xyz) * [ばん](mailto:detteiu0321@gmail.com) * [ふるふる](mailto:frfs@users.noreply.github.com) * [りんすき](mailto:6533808+rinsuki@users.noreply.github.com) @@ -815,951 +957,933 @@ This document is provided for informational purposes only. Since it is only upda Following people have contributed to translation of Mastodon: - GunChleoc (*Scottish Gaelic*) -- ケインツロ ⚧️👾🛸 (KNTRO) (*Spanish, Argentina*) -- Hồ Nhất Duy (honhatduy) (*Vietnamese*) -- Sveinn í Felli (sveinki) (*Icelandic*) -- Kristaps (Kristaps_M) (*Latvian*) +- KNTRO (*Spanish, Argentina*) +- honhatduy (*Vietnamese*) +- sveinki (*Icelandic*) +- Kristaps_M (*Latvian*) - NCAA (*Danish, French*) -- Zoltán Gera (gerazo) (*Hungarian*) -- ghose (XoseM) (*Galician, Spanish*) -- Jeong Arm (Kjwon15) (*Korean, Esperanto, Japanese, Spanish*) -- Emanuel Pina (emanuelpina) (*Portuguese*) +- gerazo (*Hungarian*) +- ghose (*Galician, Spanish*) +- Kjwon15 (*Esperanto, Japanese, Korean, Spanish*) +- emanuelpina (*Portuguese*) - Reyzadren (*Ido, Malay*) -- Thai Localization (thl10n) (*Thai*) +- thl10n (*Thai*) - Besnik_b (*Albanian*) -- Joene (joenepraat) (*Dutch*) -- Cyax (Cyaxares) (*Kurmanji (Kurdish)*) +- joenepraat (*Dutch*) +- Cyaxares (*Kurmanji (Kurdish)*) - adrmzz (*Sardinian*) -- Ramdziana F Y (rafeyu) (*Indonesian*) +- rafeyu (*Indonesian*) - xatier (*Chinese Traditional, Chinese Traditional, Hong Kong*) -- qezwan (*Sorani (Kurdish), Persian*) +- qezwan (*Persian, Sorani (Kurdish)*) - spla (*Catalan, Spanish*) -- ButterflyOfFire (BoFFire) (*Arabic, French, Kabyle*) -- Martin (miles) (*Slovenian*) -- නාමල් ජයසිංහ (nimnaya) (*Sinhala*) -- Asier Iturralde Sarasola (aldatsa) (*Basque*) -- Ondřej Pokorný (unextro) (*Czech*) +- BoFFire (*Arabic, French, Kabyle*) +- miles (*Slovenian*) +- nimnaya (*Sinhala*) +- aldatsa (*Basque*) +- unextro (*Czech*) - Roboron (*Spanish*) - taicv (*Vietnamese*) - koyu (*German*) -- Daniele Lira Mereb (danilmereb) (*Portuguese, Brazilian*) -- T. E. Kalaycı (tekrei) (*Turkish*) -- Evert Prants (IcyDiamond) (*Estonian*) -- Yair Mahalalel (yairm) (*Hebrew*) -- Ihor Hordiichuk (ihor_ck) (*Ukrainian*) -- Alessandro Levati (Oct326) (*Italian*) -- Kimmo Kujansuu (mrkujansuu) (*Finnish*) -- Alix Rossi (palindromordnilap) (*Corsican, Esperanto, French*) -- Danial Behzadi (danialbehzadi) (*Persian*) -- stan ionut (stanionut12) (*Romanian*) -- Mastodon 中文译者 (mastodon-linguist) (*Chinese Simplified*) -- Kristijan Tkalec (lapor) (*Slovenian*) -Alexander Sorokin (Brawaru) (*Russian, Vietnamese, Swedish, Portuguese, Tamil, Kabyle, Polish, Italian, Catalan, Armenian, Hungarian, Albanian, Greek, Galician, Korean, Ukrainian, German, Danish, French*) +- danilmereb (*Portuguese, Brazilian*) +- tekrei (*Turkish*) +- IcyDiamond (*Estonian*) +- yairm (*Hebrew*) +- ihor_ck (*Ukrainian*) +- Oct326 (*Italian*) +- mrkujansuu (*Finnish*) +- palindromordnilap (*Corsican, Esperanto, French*) +- danialbehzadi (*Persian*) +- stanionut12 (*Romanian*) +- mastodon-linguist (*Chinese Simplified*) +- lapor (*Slovenian*) +- Brawaru (*Albanian, Armenian, Catalan, Danish, French, Galician, German, Greek, Hungarian, Italian, Kabyle, Korean, Polish, Portuguese, Russian, Swedish, Tamil, Ukrainian, Vietnamese*) - ManeraKai (*Arabic*) -- мачко (ma4ko) (*Bulgarian*) +- ma4ko (*Bulgarian*) +- Rhoslyn (*Welsh*) - kamee (*Armenian*) -- Yamagishi Kazutoshi (ykzts) (*Japanese, Icelandic, Sorani (Kurdish), Albanian, Vietnamese, Chinese Simplified*) -- Takeçi (polygoat) (*French, Italian*) +- ykzts (*Albanian, Chinese Simplified, Icelandic, Japanese, Sorani (Kurdish), Vietnamese*) +- polygoat (*French, Italian*) - REMOVED_USER (*Czech*) - borys_sh (*Ukrainian*) -- Imre Kristoffer Eilertsen (DandelionSprout) (*Norwegian*) -- Marek Ľach (mareklach) (*Slovak, Polish*) -- yeft (*Chinese Traditional, Hong Kong, Chinese Traditional*) -- D. Cederberg (cederberget) (*Swedish*) -- Miguel Mayol (mitcoes) (*Spanish, Catalan*) +- DandelionSprout (*Norwegian*) +- mareklach (*Polish, Slovak*) +- yeft (*Chinese Traditional, Chinese Traditional, Hong Kong*) +- cederberget (*Swedish*) +- mitcoes (*Catalan, Spanish*) - enolp (*Asturian*) -- Manuel Viens (manuelviens) (*French*) +- manuelviens (*French*) - cybergene (*Japanese*) - REMOVED_USER (*Turkish*) - xpil (*Polish, Scottish Gaelic*) -- Balázs Meskó (mesko.balazs) (*Hungarian, Czech*) -- Koala Yeung (yookoala) (*Chinese Traditional, Hong Kong*) +- mesko.balazs (*Czech, Hungarian*) +- yookoala (*Chinese Traditional, Hong Kong*) - Osoitz (*Basque*) -- Amir Rubinstein - TAU (AmirrTAU) (*Hebrew, Indonesian*) -- Maya Minatsuki (mayaeh) (*Japanese*) -- Peterandre (*Norwegian Nynorsk, Norwegian*) -Mélanie Chauvel (ariasuni) (*French, Esperanto, Norwegian Nynorsk, Persian, Kabyle, Sardinian, Corsican, Breton, Portuguese, Brazilian, Arabic, Chinese Simplified, Ukrainian, Slovenian, Greek, German, Czech, Hungarian*) +- AmirrTAU (*Hebrew, Indonesian*) +- mayaeh (*Japanese*) +- Peterandre (*Norwegian, Norwegian Nynorsk*) +- ariasuni (*Arabic, Breton, Chinese Simplified, Corsican, Czech, Esperanto, French, German, Greek, Hungarian, Kabyle, Norwegian Nynorsk, Persian, Portuguese, Brazilian, Sardinian, Slovenian, Ukrainian*) - tzium (*Sardinian*) - Diluns (*Occitan*) -- Galician Translator (Galician_translator) (*Galician*) -- Marcin Mikołajczak (mkljczkk) (*Polish, Czech, Russian*) -- Jeff Huang (s8321414) (*Chinese Traditional*) -- Pixelcode (realpixelcode) (*German*) -- Allen Zhong (AstroProfundis) (*Chinese Simplified*) +- REMOVED_USER (*Galician*) +- mkljczkk (*Czech, Polish, Russian*) +- s8321414 (*Chinese Traditional*) +- realpixelcode (*German*) - lamnatos (*Greek*) -- Sean Young (assanges) (*Chinese Traditional*) +- AstroProfundis (*Chinese Simplified*) +- assanges (*Chinese Traditional*) - retiolus (*Catalan, French, Spanish*) - tolstoevsky (*Russian*) -- Ali Demirtaş (alidemirtas) (*Turkish*) -- J. Cam Andrever-Wright (gourmas) (*Cornish*) +- alidemirtas (*Turkish*) +- gourmas (*Cornish*) - coxde (*Chinese Simplified*) - Dremski (*Bulgarian*) - gagik_ (*Armenian*) -- Masoud Abkenar (mabkenar) (*Persian*) +- mabkenar (*Persian*) - arshat (*Kazakh*) -- Ira (seefood) (*Hebrew*) +- seefood (*Hebrew*) - Linerly (*Indonesian*) -- Blak Ouille (BlakOuille16) (*French*) -- e (diveedd) (*Kurmanji (Kurdish)*) -- Em St Cenydd (cancennau) (*Welsh*) -- Tigran (tigransimonyan) (*Armenian*) +- BlakOuille16 (*French*) +- diveedd (*Kurmanji (Kurdish)*) +- cancennau (*Welsh*) +- lisawe (*Norwegian*) +- tigransimonyan (*Armenian*) - Draacoun (*Portuguese, Brazilian*) -- REMOVED_USER (*Turkish*) -- Nurul Azeera Hidayah @ Muhammad Nur Hidayat Yasuyoshi (MNH48.moe) (mnh48) (*Malay*) -- Tagomago (tagomago) (*Spanish, French*) -- Ashun (ashune) (*Croatian*) +- mnh48 (*Malay*) +- tagomago (*French, Spanish*) +- ashune (*Croatian*) - Aditoo17 (*Czech*) - vishnuvaratharajan (*Tamil*) - pulmonarycosignerkindness (*Swedish*) - calypsoopenmail (*French*) - REMOVED_USER (*Kabyle*) - snerk (*Norwegian Nynorsk*) -- Sebastian (SebastianBerlin) (*German*) -- lisawe (*Norwegian*) +- TranslatorDE (*German*) - serratrad (*Catalan*) - Bran_Ruz (*Breton*) -- ViktorOn (*Russian, Danish*) +- ViktorOn (*Danish, Russian*) - Gearguy (*Finnish*) -- Andi Chandler (andibing) (*English, United Kingdom*) -- Tor Egil Hoftun Kvæstad (Taloran) (*Norwegian Nynorsk*) +- andibing (*English, United Kingdom*) +- Taloran (*Norwegian Nynorsk*) - GiorgioHerbie (*Italian*) -- හෙළබස සමූහය (HelaBasa) (*Sinhala*) -- kat (katktv) (*Ukrainian, Russian*) -- Yi-Jyun Pan (pan93412) (*Chinese Traditional*) -- Fjoerfoks (fryskefirefox) (*Frisian, Dutch*) -- Eshagh (eshagh79) (*Persian*) +- HelaBasa (*Sinhala*) +- philip-khor (*English, United Kingdom, Malay*) +- katktv (*Russian, Ukrainian*) +- pan93412 (*Chinese Traditional*) +- fryskefirefox (*Dutch, Frisian*) +- eshagh79 (*Persian*) - regulartranslator (*Portuguese, Brazilian*) - Saederup92 (*Danish*) -- ozzii (Serbian (Cyrillic), French) -- Irfan (Irfan_Radz) (*Malay*) +- ozzii (*French, Serbian (Cyrillic)*) +- Irfan_Radz (*Malay*) - ClearlyClaire (*French, Icelandic*) -- Sokratis Alichanidis (alichani) (*Greek*) -- Jiří Podhorecký (trendspotter) (*Czech*) -- Akarshan Biswas (biswasab) (*Bengali, Sanskrit*) -- Robert Wolniak (Szkodnix) (*Polish*) -- Jan Lindblom (janlindblom) (*Swedish*) -- Dewi (Unkorneg) (*Breton, French*) -- Kristoffer Grundström (Umeaboy) (*Swedish*) -- Rafael H L Moretti (Moretti) (*Portuguese, Brazilian*) +- alichani (*Greek*) +- trendspotter (*Czech*) +- biswasab (*Bengali, Sanskrit*) +- Szkodnix (*Polish*) +- janlindblom (*Swedish*) +- Unkorneg (*Breton, French*) +- Umeaboy (*Swedish*) +- Moretti (*Portuguese, Brazilian*) - d5Ziif3K (*Ukrainian*) -- Nemu (Dormemulo) (*Esperanto, French, Italian, Ido, Afrikaans*) -- Johan Mynhardt (johanmynhardt) (*Afrikaans*) -- Rojdayek (Kurmanji (Kurdish)) +- Dormemulo (*Afrikaans, Esperanto, French, Ido, Italian*) +- johanmynhardt (*Afrikaans*) +- Rojdayek (*Kurmanji (Kurdish)*) - REMOVED_USER (*Portuguese, Brazilian*) - GCardo (*Portuguese, Brazilian*) - christalleras (*Norwegian Nynorsk*) - diorama (*Italian*) -- Jaz-Michael King (jazmichaelking) (*Welsh*) -- Catalina (catalina.st) (*Romanian*) -- Ryo (DrRyo) (*Korean*) -- otrapersona (*Spanish, Mexico, Spanish*) -- Frontier Translation Ltd. (frontier-translation) (*Chinese Simplified*) -- Mauzi (*Swedish, German*) +- jazmichaelking (*Welsh*) +- catalina.st (*Romanian*) +- DrRyo (*Korean*) +- otrapersona (*Spanish, Spanish, Mexico*) +- frontier-translation (*Chinese Simplified*) +- Mauzi (*German, Swedish*) - Clopsy87 (*Italian*) - atarashiako (*Chinese Simplified*) +- 101010pl (*Polish*) - erictapen (*German*) -- zhen liao (az0189re) (*Chinese Simplified*) -- 101010 (101010pl) (*Polish*) +- az0189re (*Chinese Simplified*) - REMOVED_USER (*Norwegian*) - axi (*Finnish*) - silkevicious (*Italian*) -- Floxu (fredrikdim1) (*Norwegian Nynorsk*) -- Nic Dafis (nicdafis) (*Welsh*) -- NadieAishi (*Spanish, Mexico, Spanish*) -- 戸渡生野 (aomyouza2543) (*Thai*) -- Tjipke van der Heide (vancha) (*Frisian*) -- Erik Mogensen (mogsie) (*Norwegian*) +- nicdafis (*Welsh*) +- fredrikdim1 (*Norwegian Nynorsk*) +- NadieAishi (*Spanish, Spanish, Mexico*) +- aomyouza2543 (*Thai*) +- vancha (*Frisian*) +- mogsie (*Norwegian*) - pomoch (*Chinese Traditional, Hong Kong*) -- Alexandre Brito (alexbrito) (*Portuguese, Brazilian*) -- Bertil Hedkvist (Berrahed) (*Swedish*) -- William(ѕ)ⁿ (wmlgr) (*Spanish*) +- alexbrito (*Portuguese, Brazilian*) +- Berrahed (*Swedish*) +- wmlgr (*Spanish*) - LNDDYL (*Chinese Traditional*) - tanketom (*Norwegian Nynorsk*) - norayr (*Armenian*) -- l3ycle (*German*) - strubbl (*German*) -- Satnam S Virdi (pika10singh) (*Punjabi*) -- Tiago Epifânio (tfve) (*Portuguese*) -- Mentor Gashi (mentorgashi.com) (*Albanian*) -- Sid (autinerd1) (*Dutch, German*) +- l3ycle (*German*) +- pika10singh (*Punjabi*) +- tfve (*Portuguese*) +- mentorgashi.com (*Albanian*) +- autinerd1 (*Dutch, German*) - carolinagiorno (*Portuguese, Brazilian*) -- Em_i (emiliencoss) (*French*) -- Liam O (liamoshan) (*Irish*) -- Hayk Khachatryan (brutusromanus123) (*Armenian*) -- Roby Thomas (roby.thomas) (*Malayalam*) +- emiliencoss (*French*) +- liamoshan (*Irish*) +- Gim_Garam (*Korean*) +- brutusromanus123 (*Armenian*) +- roby.thomas (*Malayalam*) - ThonyVezbe (*Breton*) -- Percy (kecrily) (*Chinese Simplified*) -- Bharat Kumar (Marwari) (*Hindi*) -- Austra Muizniece (aus_m) (*Latvian*) -- Urubu Lageano (urubulageano) (*Portuguese, Brazilian*) -- Just Spanish (7_7) (*Spanish, Mexico*) +- kecrily (*Chinese Simplified*) +- Marwari (*Hindi*) +- aus_m (*Latvian*) +- urubulageano (*Portuguese, Brazilian*) +- 7_7 (*Spanish, Mexico*) - v4vachan (*Malayalam*) - bilfri (*Danish*) -- IamHappy (mrmx2013) (*Ukrainian*) +- mrmx2013 (*Ukrainian*) - dkdarshan760 (*Sanskrit*) -- Timur Seber (seber) (*Tatar*) -- Slimane Selyan AMIRI (SelyanKab) (*Kabyle*) +- seber (*Tatar*) +- SelyanKab (*Kabyle*) - VaiTon (*Italian*) - tykayn (*French*) -- Abdulaziz Aljaber (kuwaitna) (*Arabic*) +- kuwaitna (*Arabic*) - taoxvx (*Danish*) -- Hrach Mkrtchyan (hrachmk) (*Armenian*) -- sabri (thetomatoisavegetable) (*Spanish, Spanish, Argentina*) -- CoelacanthusHex (*Chinese Simplified*) -- Rhys Harrison (rhedders) (*Esperanto*) -- syncopams (*Chinese Traditional, Hong Kong, Chinese Traditional, Chinese Simplified*) +- hrachmk (*Armenian*) +- thetomatoisavegetable (*Spanish, Spanish, Argentina*) +- Coelacanthus (*Chinese Simplified*) +- rhedders (*Esperanto*) +- syncopams (*Chinese Simplified, Chinese Traditional, Chinese Traditional, Hong Kong*) - SteinarK (*Norwegian Nynorsk*) +- vagnes (*Norwegian, Norwegian Nynorsk*) - REMOVED_USER (*Standard Moroccan Tamazight*) -- Maxine B. Vågnes (vagnes) (*Norwegian, Norwegian Nynorsk*) -- Rikard Linde (rikardlinde) (*Swedish*) +- rikardlinde (*Swedish*) - ahangarha (*Persian*) -- Lalo Tafolla (lalotafo) (*Spanish, Spanish, Mexico*) -- Larissa Cruz (larissacruz) (*Portuguese, Brazilian*) -- dashersyed (Urdu (Pakistan)) +- lalotafo (*Spanish, Spanish, Mexico*) +- larissacruz (*Portuguese, Brazilian*) +- dashersyed (*Urdu (Pakistan)*) - camerongreer21 (*English, United Kingdom*) - REMOVED_USER (*Ukrainian*) -- Conight Wang (xfddwhh) (*Chinese Simplified*) +- xfddwhh (*Chinese Simplified*) - liffon (*Swedish*) -- Damjan Dimitrioski (gnud) (*Macedonian*) +- gnud (*Macedonian*) - rondnunes (*Portuguese, Brazilian*) - PPNplus (*Thai*) -- Steven Ritchie (Steaph38) (*Scottish Gaelic*) -- 游荡 (MamaShip) (*Chinese Simplified*) -- Edward Navarro (EdwardNavarro) (*Spanish*) +- Steaph38 (*Scottish Gaelic*) +- MamaShip (*Chinese Simplified*) +- EdwardNavarro (*Spanish*) - shioko (*Chinese Simplified*) - gnu-ewm (*Polish*) -- Kahina Mess (K_hina) (*Kabyle*) -- Hexandcube (hexandcube) (*Polish*) -- Scott Starkey (yekrats) (*Esperanto*) +- K_hina (*Kabyle*) +- hexandcube (*Polish*) +- yekrats (*Esperanto*) - ZiriSut (*Kabyle*) - FreddyG (*Esperanto*) -- mynameismonkey (*Welsh*) -- Groosha (groosha) (*Russian*) -- Gwenn (Belvar) (*Breton*) +- jmking (*Welsh*) +- groosha (*Russian*) +- toba (*German*) +- Belvar (*Breton*) - StanleyFrew (*French*) - cathalgarvey (*Irish*) -- Nikita Epifanov (Nikets) (*Russian*) +- Nikets (*Russian*) - REMOVED_USER (*Finnish*) - jaranta (*Finnish*) -- Slobodan Simić (Слободан Симић) (slsimic) (*Serbian (Cyrillic)*) -- iVampireSP (*Chinese Traditional, Chinese Simplified*) -- Felicia Jongleur (midsommar) (*Swedish*) -- Denys (dector) (*Ukrainian*) -- Mo_der Steven (SakuraPuare) (*Chinese Simplified*) +- slsimic (*Serbian (Cyrillic)*) +- iVampireSP (*Chinese Simplified, Chinese Traditional*) +- midsommar (*Swedish*) +- dector (*Ukrainian*) +- SakuraPuare (*Chinese Simplified*) - REMOVED_USER (*German*) -- Kishin Sagume (kishinsagi) (*Chinese Simplified*) +- kishinsagi (*Chinese Simplified*) - bennepharaoh (*Chinese Simplified*) - Vanege (*Esperanto*) -- hibiya inemuri (hibiya) (*Korean*) -- Jess Rafn (therealyez) (*Danish*) -- Stasiek Michalski (hellcp) (*Polish*) +- hibiya (*Korean*) +- therealyez (*Danish*) +- hellcp (*Polish*) - dxwc (*Bengali*) -- Heran Membingung (heranmembingung) (*Indonesian*) - Parodper (*Galician*) +- filbert (*Indonesian*) - rbnval (*Catalan*) +- jmontane (*Catalan*) - Liboide (*Spanish*) - hemnaren (*Norwegian Nynorsk*) -- jmontane (*Catalan*) -- Andy Kleinert (AndyKl) (*German*) -- Chris Kay (chriskarasoulis) (*Greek*) +- AndyKl (*German*) +- Acursen (*German*) +- chriskarasoulis (*Greek*) - CrowdinBRUH (*Vietnamese*) -- Rhoslyn Prys (Rhoslyn) (*Welsh*) -- abidin toumi (Zet24) (*Arabic*) -- Johan Schiff (schyffel) (*Swedish*) -- Rex_sa (rex07) (*Arabic*) +- Zet24 (*Arabic*) +- schyffel (*Swedish*) +- rex07 (*Arabic*) - amedcj (*Kurmanji (Kurdish)*) -- Arunmozhi (tecoholic) (*Tamil*) -- zer0-x (ZER0-X) (*Arabic*) +- tecoholic (*Tamil*) +- zer0-x (*Arabic*) - staticnoisexyz (*Czech*) -- Lauren Liberda (selfisekai) (*Polish*) -- Michael Zeevi (maze88) (*Hebrew*) +- cuu508 (*Latvian*) +- selfisekai (*Polish*) +- maze88 (*Hebrew*) - oti4500 (*Hungarian, Ukrainian*) -- Delta (Delta-Time) (*Japanese*) -- Marc Antoine Thevenet (MATsxm) (*French*) -- AlexKoala (alexkoala) (*Korean*) +- Delta-Time (*Japanese*) +- MATsxm (*French*) +- alexkoala (*Korean*) - SarfarazAhmed (*Urdu (Pakistan)*) -- Ahmad Dakhlallah (MIUIArabia) (*Arabic*) -- Mats Gunnar Ahlqvist (goqbi) (*Swedish*) +- ahmadafef (*Arabic*) +- goqbi (*Swedish*) - diazepan (*Spanish, Spanish, Argentina*) -- Tiger:blank (tsagaanbar) (*Chinese Simplified*) -- REMOVED_USER (*Chinese Simplified*) +- tsagaanbar (*Chinese Simplified*) - marzuquccen (*Kabyle*) +- REMOVED_USER (*Chinese Simplified*) - atriix (*Swedish*) -- Laur (melaur) (*Romanian*) -- VictorCorreia (victorcorreia1984) (*Afrikaans*) -- Remito (remitocat) (*Japanese*) -- Juan José Salvador Piedra (JuanjoSalvador) (*Spanish*) -- REMOVED_USER (*Norwegian*) -- 森の子リスのミーコの大冒険 (Phroneris) (*Japanese*) -- Gim_Garam (*Korean*) +- melaur (*Romanian*) +- victorcorreia1984 (*Afrikaans*) +- remitocat (*Japanese*) +- JuanjoSalvador (*Spanish*) +- Phroneris (*Japanese*) - BurekzFinezt (*Serbian (Cyrillic)*) -- Pēteris Caune (cuu508) (*Latvian*) +- lancet (*Irish*) - asnomgtu (*Hungarian*) - bendigeidfran (*Welsh*) - SHeija (*Finnish*) -- Врабац (Slovorad) (*Serbian (Cyrillic)*) -- Dženan (Dzenan) (*Swedish*) -- Gabriel Beecham (lancet) (*Irish*) +- Dzenan (*Swedish*) +- Slovorad (*Serbian (Cyrillic)*) +- isaac.97_WT (*Spanish*) - antonyho (*Chinese Traditional, Hong Kong*) -- Jack R (isaac.97_WT) (*Spanish*) -- Henrik Mattsson-Mårn (rchk) (*Swedish*) -- Oguzhan Aydin (aoguzhan) (*Turkish*) -- Soran730 (*Chinese Simplified*) -- andruhov (*Ukrainian, Russian*) -- 北䑓如法 (Nyoho) (*Japanese*) +- rchk (*Swedish*) +- aoguzhan (*Turkish*) +- andruhov (*Russian, Ukrainian*) +- Nyoho (*Japanese*) - phena109 (*Chinese Traditional, Hong Kong*) -- Aryamik Sharma (Aryamik) (*Hindi, Swedish*) +- Aryamik (*Hindi, Swedish*) - Unmual (*Spanish*) -- Tobias Bannert (toba) (*German*) -- Adrián Graña (alaris83) (*Spanish*) +- agrana (*Spanish*) - vpei (*Chinese Simplified*) - cruz2020 (*Portuguese*) -- papapep (h9f2ycHh-ktOd6_Y) (*Catalan*) -- Roj (roj1512) (*Sorani (Kurdish), Kurmanji (Kurdish)*) -- るいーね (ruine) (*Japanese*) -- aujawindar (*Norwegian Nynorsk*) +- h9f2ycHh-ktOd6_Y (*Catalan*) +- roj1512 (*Kurmanji (Kurdish), Sorani (Kurdish)*) +- ruine (*Japanese*) - irithys (*Chinese Simplified*) -- Sam Tux (imahbub) (*Bengali*) +- aujawindar (*Norwegian Nynorsk*) +- imahbub (*Bengali*) - igordrozniak (*Polish*) -- Johannes Nilsson (nlssn) (*Swedish*) -- Michał Sidor (michcioperz) (*Polish*) -- Isaac Huang (caasih) (*Chinese Traditional*) -- AW Unad (awcodify) (*Indonesian*) +- nlssn (*Swedish*) +- michcioperz (*Polish*) +- caasih (*Chinese Traditional*) +- stromholm (*Swedish*) +- awcodify (*Indonesian*) - 1Alino (*Slovak*) -- Cutls (cutls) (*Japanese*) -- Goudarz Jafari (GoudarzJafari) (*Persian*) -- Daniel Strömholm (stromholm) (*Swedish*) -- 1 (Ipsumry) (*Spanish*) -- Falling Snowdin (tghgg) (*Vietnamese*) -- Paulino Michelazzo (pmichelazzo) (*Portuguese, Brazilian*) -- Y.Yamashiro (uist1idrju3i) (*Japanese*) -- Rasmus Lindroth (RasmusLindroth) (*Swedish*) -- Gianfranco Fronteddu (gianfro.gianfro) (*Sardinian*) -- Andrea Lo Iacono (niels0n) (*Italian*) +- cutls (*Japanese*) +- GoudarzJafari (*Persian*) +- Ipsumry (*Spanish*) +- tghgg (*Vietnamese*) +- pmichelazzo (*Portuguese, Brazilian*) +- uist1idrju3i (*Japanese*) +- RasmusLindroth (*Swedish*) +- gianfro.gianfro (*Sardinian*) +- niels0n (*Italian*) - fucsia (*Italian*) -- Vedran Serbu (SerenoXGen) (*Croatian*) -- Raphael Das Gupta (das-g) (*Esperanto, German*) +- SerenoXGen (*Croatian*) +- das-g (*Esperanto, German*) - yanchan09 (*Estonian*) - ainmeolai (*Irish*) -- REMOVED_USER (*Norwegian*) +- kinshuksunil (*Hindi*) - mian42 (*Bulgarian*) -- Kinshuk Sunil (kinshuksunil) (*Hindi*) +- ullasjoseph (*Malayalam*) - al_._ (*German, Russian*) -- Ullas Joseph (ullasjoseph) (*Malayalam*) - sanoth (*Swedish*) -- Aftab Alam (iaftabalam) (*Hindi*) +- iaftabalam (*Hindi*) - frumble (*German*) -- juanda097 (juanda-097) (*Spanish*) -- Matthías Páll Gissurarson (icetritlo) (*Icelandic*) -- Russian Retro (retrograde) (*Russian*) +- juanda-097 (*Spanish*) +- icetritlo (*Icelandic*) +- retrograde (*Russian*) +- tedliou (*Chinese Traditional*) - KcKcZi (*Chinese Simplified*) -- Yu-Pai Liu (tedliou) (*Chinese Traditional*) -- Amarin Cemthong (acitmaster) (*Thai*) +- acitmaster (*Thai*) - Etinew (*Hebrew*) - xsml (*Chinese Simplified*) -- S.J. L. (samijuhanilii) (*Finnish*) +- samijuhanilii (*Finnish*) - Anunnakey (*Macedonian*) - erikkemp (*Dutch*) -- Tsl (muun) (*Chinese Simplified*) -- Renato "Lond" Cerqueira (renatolond) (*Portuguese, Brazilian*) -- Úna-Minh Kavanagh (yunitex) (*Irish*) +- renatolond (*Portuguese, Brazilian*) +- muun (*Chinese Simplified*) +- yunitex (*Irish*) - kongk (*Norwegian Nynorsk*) - erikstl (*Esperanto*) - twpenguin (*Chinese Traditional*) +- bobchao (*Chinese Traditional*) - JeremyStarTM (*German*) -- Po-chiang Chao (bobchao) (*Chinese Traditional*) -- Marcus Myge (mygg-priv) (*Norwegian*) -- Esther (esthermations) (*Portuguese*) -- Jiri Grönroos (spammemoreplease) (*Finnish*) +- IetsMooi (*Norwegian*) - MadeInSteak (*Finnish*) +- esthermations (*Portuguese*) +- spammemoreplease (*Finnish*) - witoharmuth (*Swedish*) -- MESHAL45 (*Arabic*) - mcdutchie (*Dutch*) -- Michal Špondr (michalspondr) (*Czech*) +- MESHAL45 (*Arabic*) +- michalspondr (*Czech*) - t_aus_m (*German*) -- kaki7777 (*Japanese, Chinese Traditional*) -- Heimen Stoffels (Vistaus) (*Dutch*) -- serapolis (*Chinese Traditional, Hong Kong, Chinese Traditional, Japanese, Chinese Simplified*) -- Rajarshi Guha (rajarshiguha) (*Bengali*) -- Amir Reza (ElAmir) (*Persian*) -- REMOVED_USER (*Norwegian*) -- MohammadSaleh Kamyab (mskf1383) (*Persian*) +- Vistaus (*Dutch*) +- serapolis (*Chinese Simplified, Chinese Traditional, Chinese Traditional, Hong Kong, Japanese*) +- kaki7777 (*Chinese Traditional, Japanese*) +- rajarshiguha (*Bengali*) +- ElAmir (*Persian*) - REMOVED_USER (*Romanian*) -- Gopal Sharma (gopalvirat) (*Hindi*) -- Вероніка Някшу (pampushkaveronica) (*Russian, Romanian*) -- Linnéa (lesbian_subnet) (*Swedish*) -- Valentin (HDValentin) (*German*) +- mskf1383 (*Persian*) +- gopalvirat (*Hindi*) +- lesbian_subnet (*Swedish*) +- pampushkaveronica (*Romanian, Russian*) +- HDValentin (*German*) - dragnucs2 (*Arabic*) -- Carlos Solís (csolisr) (*Esperanto*) -- Tofiq Abdula (Xwla) (*Sorani (Kurdish)*) +- csolisr (*Esperanto*) +- Xwla (*Sorani (Kurdish)*) - halcek (*Slovak*) -- Tobias Kunze (rixxian) (*German*) -- Parthan S Ramanujam (parthan) (*Tamil*) -- Kasper Nymand (KasperNymand) (*Danish*) -- TS (morte) (*Finnish*) -- REMOVED_USER (*German*) +- parthan (*Tamil*) +- rixxian (*German*) +- KasperNymand (*Danish*) - REMOVED_USER (*Basque*) +- morte (*Finnish*) - subram (*Turkish*) -- Gudwin (*Spanish, Mexico, Spanish*) -- Ptrcmd (ptrcmd) (*Chinese Traditional*) -- shmuelHal (*Hebrew*) +- Gudwin (*Spanish, Spanish, Mexico*) - SensDeViata (*Ukrainian*) +- ptrcmd (*Chinese Traditional*) +- shmuelHal (*Hebrew*) - megaleo (*Portuguese, Brazilian*) -- Acursen (*German*) -- NurKai Kai (nurkaiyttv) (*German*) -- Guttorm (ghveem) (*Norwegian Nynorsk*) +- nurkaiyttv (*German*) - SergioFMiranda (*Portuguese, Brazilian*) -- Danni Lundgren (dannilundgren) (*Danish*) -- Vivek K J (Vivekkj) (*Malayalam*) +- ghveem (*Norwegian Nynorsk*) +- dannilundgren (*Danish*) - hiroTS (*Chinese Traditional*) -- teadesu (*Portuguese, Brazilian*) +- Vivekkj (*Malayalam*) +- fnogcps (*Portuguese, Brazilian*) - petartrajkov (*Macedonian*) -- Ariel Costas (arielcostas3) (*Galician*) -- Ch. (sftblw) (*Korean*) +- arielcostas (*Galician*) +- sftblw (*Korean*) - Rintan (*Japanese*) -- Jair Henrique (jairhenrique) (*Portuguese, Brazilian*) - sorcun (*Turkish*) +- jairhenrique (*Portuguese, Brazilian*) - filippodb (*Italian*) - johne32rus23 (*Russian*) -- OctolinGamer (octolingamer) (*Portuguese, Brazilian*) +- octolingamer (*Portuguese, Brazilian*) - AzureNya (*Chinese Simplified*) -- Ram varma (ram4varma) (*Tamil*) -- REMOVED_USER (Sorani (Kurdish)) -- REMOVED_USER (*Portuguese, Brazilian*) +- ram4varma (*Tamil*) +- REMOVED_USER (*Sorani (Kurdish)*) - seanmhade (*Irish*) - sanser (*Russian*) -- Vijay (vijayatmin) (*Tamil*) +- vijayatmin (*Tamil*) - Anomalion (*German*) -- Pukima (Pukimaa) (*German*) -- Curtis Lee (CansCurtis) (*Chinese Traditional*) -- โบโลน่าไวรัส (nullxyz_) (*Thai*) -- ふぁーらんど (farland1717) (*Japanese*) +- Pukimaa (*German*) +- nullxyz_ (*Thai*) +- CansCurtis (*Chinese Traditional*) +- farland1717 (*Japanese*) - 3wen (*Breton*) +- rahmatullinailzira53 (*Tatar*) - rlafuente (*Portuguese*) -- Ильзира Рахматуллина (rahmatullinailzira53) (*Tatar*) -- Code Man (codemansrc) (*Russian*) -- Philip Gillißen (guerda) (*German*) -- Daniel Dimitrov (daniel.dimitrov) (*Bulgarian*) -- Anton (atjn) (*Danish*) +- codemansrc (*Russian*) +- guerda (*German*) +- daniel.dimitrov (*Bulgarian*) +- atjn (*Danish*) - kekkepikkuni (*Tamil*) - MODcraft (*Chinese Simplified*) - oorsutri (*Tamil*) +- NeoChen1024 (*Chinese Traditional*) - wortfeld (*German*) -- Neo_Chen (NeoChen1024) (*Chinese Traditional*) -- Stereopolex (*Polish*) - NxOne14 (*Bulgarian*) -- Juan Ortiz (Kloido) (*Spanish, Catalan*) -- Nithin V (Nithin896) (*Tamil*) +- Stereopolex (*Polish*) +- Kloido (*Catalan, Spanish*) +- Nithin896 (*Tamil*) - strikeCunny2245 (*Icelandic*) -- Miro Rauhala (mirorauhala) (*Finnish*) -- nicoduesing (duconi) (*German, Esperanto*) -- Gnonthgol (*Norwegian Nynorsk*) -- WKobes (*Dutch*) +- mirorauhala (*Finnish*) +- duconi (*Esperanto, German*) - Oymate (*Bengali*) +- WKobes (*Dutch*) +- Gnonthgol (*Norwegian Nynorsk*) +- EzigboOmenana (*Cornish, Igbo*) - mikwee (*Hebrew*) -- EzigboOmenana (*Igbo, Cornish*) -- yan Wato (janWato) (*Hindi*) +- janWato (*Hindi*) - Papuass (*Latvian*) -- Vincent Orback (vincentorback) (*Swedish*) +- vincentorback (*Swedish*) +- nineteen (*Chinese Simplified*) - chettoy (*Chinese Simplified*) -- 19 (nineteen) (*Chinese Simplified*) -- ಚಿರಾಗ್ ನಟರಾಜ್ (chiraag-nataraj) (*Kannada*) -- Layik Hama (layik) (*Sorani (Kurdish)*) -- Guillaume Turchini (orion78fr) (*French*) -- Andri Yngvason (andryng) (*Icelandic*) -- Aswin C (officialcjunior) (*Malayalam*) -- Yuval Nehemia (yuvalne) (*Hebrew*) -- mawoka-myblock (mawoka) (*German*) -- Ganesh D (auntgd) (*Marathi*) -- Lens0021 (lens0021) (*Korean*) -- An Gafraíoch (angafraioch) (*Irish*) -- Michael Smith (michaelshmitty) (*Dutch*) -- Ryan Ho (koungho) (*Chinese Traditional*) +- chiraag-nataraj (*Kannada*) +- layik (*Sorani (Kurdish)*) +- orion78fr (*French*) +- officialcjunior (*Malayalam*) +- andryng (*Icelandic*) +- auntgd (*Marathi*) +- mawoka (*German*) +- yuvalne (*Hebrew*) +- lens0021 (*Korean*) +- angafraioch (*Irish*) +- koungho (*Chinese Traditional*) +- michaelshmitty (*Dutch*) - tunisiano187 (*French*) -- Peter van Mever (SpacemanSpiff) (*Dutch*) -- Pedro Henrique (exploronauta) (*Portuguese, Brazilian*) +- h_tejas (*Marathi*) +- meskobalazs (*Hungarian*) +- exploronauta (*Portuguese, Brazilian*) - REMOVED_USER (*Esperanto, Italian, Japanese*) -- Tejas Harad (h_tejas) (*Marathi*) -- Balázs Meskó (meskobalazs) (*Hungarian*) -- Vasanthan (vasanthan) (*Tamil*) -- Tatsuto "Laminne" Yamamoto (laminne) (*Japanese*) -- slbtty (shenlebantongying) (*Chinese Simplified*) -- 硫酸鶏 (acid_chicken) (*Japanese*) +- SpacemanSpiff (*Dutch*) +- vasanthan (*Tamil*) +- laminne (*Japanese*) +- shenlebantongying (*Chinese Simplified*) +- acid_chicken (*Japanese*) +- clarminb8 (*Sorani (Kurdish)*) - programizer (*German*) - guessimmaterialgrl (*Chinese Simplified*) -- clarmin b8 (clarminb8) (*Sorani (Kurdish)*) -- Maria Riegler (riegler3m) (*German*) - manukp (*Malayalam*) -- earth dweller (sanethoughtyt) (*Marathi*) +- riegler3m (*German*) +- sanethoughtyt (*Marathi*) - psymyn (*Hebrew*) -- Aaraon Thomas (aaraon) (*Portuguese, Brazilian*) -- Rafael Viana (rafacnec) (*Portuguese, Brazilian*) -- Marek Ľach (marek-lach) (*Slovak*) -- meijerivoi (toilet) (*Finnish*) +- aaraon (*Portuguese, Brazilian*) +- toilet (*Finnish*) +- marek-lach (*Slovak*) +- rafacnec (*Portuguese, Brazilian*) +- GenialMeg (*Spanish*) - essaar (*Tamil*) - serubeena (*Swedish*) - RqndomHax (*French*) - REMOVED_USER (*Polish*) -- ギャラ (gyara) (*Chinese Simplified, Japanese*) -- Khó͘ Tiatlêng (khotiatleng) (*Chinese Traditional, Taigi*) -- revarioba (*Spanish*) -- friedbeans (*Croatian*) -- An (AnTheMaker) (*German*) -- kuchengrab (*German*) -- Hernik (hernik27) (*Czech*) +- gyara (*Chinese Simplified, Japanese*) - valarivan (*Tamil*) -- אדם לוין (adamlevin) (*Hebrew*) -- Vít Horčička (legvita123) (*Czech*) -- Abi Turi (abi123) (*Georgian*) -- Thomas Munkholt (munkholt) (*Danish*) +- khotiatleng (*Chinese Traditional, Taigi*) +- hernik27 (*Czech*) +- kuchengrab (*German*) +- friedbeans (*Croatian*) +- revarioba (*Spanish*) +- AnTheMaker (*German*) +- adamlevin (*Hebrew*) +- abi123 (*Georgian*) +- munkholt (*Danish*) - pparescasellas (*Catalan*) -- Hinaloe (hinaloe) (*Japanese*) +- hinaloe (*Japanese*) +- Selrond (*Slovak*) - Ifnuth (*German*) -- Sebastián Andil (Selrond) (*Slovak*) -- boni777 (*Chinese Simplified*) +- ddgulledge (*Esperanto*) - KEINOS (*Japanese*) -- Asbjørn Olling (a2) (*Danish*) +- a2 (*Danish*) +- boni777 (*Chinese Simplified*) - REMOVED_USER (*Chinese Traditional, Hong Kong*) -- DarkShy Community (ponyfrost.mc) (*Russian*) -- Dennis Reimund (reimunddennis7) (*German*) +- reimunddennis7 (*German*) +- ponyfrost.mc (*Russian*) - jocafeli (*Spanish, Mexico*) -- Wrya ali (John12) (*Sorani (Kurdish)*) -- Bottle (suryasalem2010) (*Tamil*) -- Algustionesa Yoshi (algustionesa) (*Indonesian*) - JzshAC (*Chinese Simplified*) -- Artem Mikhalitsin (artemmikhalitsin) (*Russian*) -- siamano (*Thai, Esperanto*) -- KARARTI44 (kararti44) (*Turkish*) +- suryasalem2010 (*Tamil*) +- John12 (*Sorani (Kurdish)*) +- algustionesa (*Indonesian*) +- artemmikhalitsin (*Russian*) +- mbootsman (*Dutch*) +- siamano (*Esperanto, Thai*) +- kararti44 (*Turkish*) - c0c (*Irish*) -- Stefano S. (Sting1_JP) (*Italian*) +- Sting1_JP (*Italian*) +- sammy8806 (*German*) +- antillion99 (*Spanish*) +- ilis (*Galician*) - tommil (*Finnish*) -- Ignacio Lis (ilis) (*Galician*) -- Steven Tappert (sammy8806) (*German*) -- Antillion (antillion99) (*Spanish*) -- K.B.Dharun Krishna (kbdharun) (*Tamil*) -- Wassim EL BOUHAMIDI (elbouhamidiw) (*Arabic*) - Reg3xp (*Persian*) +- elbouhamidiw (*Arabic*) +- kbdharun (*Tamil*) +- mble (*Polish*) +- Exbu (*Dutch*) - florentVgn (*French*) -- Matt (Exbu) (*Dutch*) -- Maciej Błędkowski (mble) (*Polish*) -- gowthamanb (*Tamil*) - hiphipvargas (*Portuguese*) +- gowthamanb (*Tamil*) - GabuVictor (*Portuguese, Brazilian*) +- REMOVED_USER (*Spanish*) - Pverte (*French*) -- REMOVED_USER (*Spanish*) - Surindaku (*Chinese Simplified*) -- Arttu Ylhävuori (arttu.ylhavuori) (*Finnish*) -- Pabllo Soares (pabllosoarez) (*Portuguese, Brazilian*) -- Jona (88wcJoWl) (*Spanish*) -- Ka2n (kaanmetu) (*Turkish*) +- arttu.ylhavuori (*Finnish*) +- samiti3d (*Thai*) - tctovsli (*Norwegian Nynorsk*) -- Timo Tijhof (Krinkle) (*Dutch*) -- SamitiMed (samiti3d) (*Thai*) -- Mikkel B. Goldschmidt (mikkelbjoern) (*Danish*) -- Odyssey346 (alexader612) (*Norwegian*) -- mecqor labi (mecqorlabi) (*Persian*) -- Cù Huy Phúc Khang (taamee) (*Vietnamese*) -- Oskari Lavinto (olavinto) (*Finnish*) -- Philippe Lemaire (philippe-lemaire) (*Esperanto*) +- Krinkle (*Dutch*) +- mikkelbjoern (*Danish*) +- kaanmetu (*Turkish*) +- pabllosoarez (*Portuguese, Brazilian*) +- mecqorlabi (*Persian*) - vjasiegd (*Polish*) -- Eban (ebanDev) (*Esperanto, French*) -- Nícolas Lavinicki (nclavinicki) (*Portuguese, Brazilian*) -- REMOVED_USER (*Portuguese, Brazilian*) -- Rekan Adl (rekan-adl1) (*Sorani (Kurdish)*) -- VSx86 (*Russian*) +- ebanDev (*Esperanto, French*) +- philippe-lemaire (*Esperanto*) +- olavinto (*Finnish*) +- taamee (*Vietnamese*) +- nclavinicki (*Portuguese, Brazilian*) +- rekan-adl1 (*Sorani (Kurdish)*) - umelard (*Hebrew*) -- Antara2Cinta (Se7enTime) (*Indonesian*) +- Se7enTime (*Indonesian*) +- VSx86 (*Russian*) +- yaitelmouden (*Standard Moroccan Tamazight*) - Lucas_NL (*Dutch*) -- Yassine Aït-El-Mouden (yaitelmouden) (*Standard Moroccan Tamazight*) -- Mathieu Marquer (slasherfun) (*French*) -- Haerul Fuad (Dokuwiki) (*Indonesian*) +- Dokuwiki (*Indonesian*) +- slasherfun (*French*) - parnikkapore (*Thai*) -- Michelle M (MichelleMMM) (*Dutch*) +- MichelleMMM (*Dutch*) +- sherwanothman11 (*Sorani (Kurdish)*) +- lagash (*Esperanto*) - malbona (*Esperanto*) -- Sherwan Othman (sherwanothman11) (*Sorani (Kurdish)*) -- Lagash (lagash) (*Esperanto*) -- Chine Sebastien (chine.sebastien) (*French*) -- bgme (*Chinese Simplified*) -- Rafael V. (Rafaeeel) (*Portuguese, Brazilian*) - SKELET (*Danish*) -- A A (sebastien.chine) (*French*) -- Project Z (projectz.1338) (*German*) -- Fei Yang (Fei1Yang) (*Chinese Traditional*) -- Ğani (freegnu) (*Tatar*) -- musix (*Persian*) -- REMOVED_USER (*German*) -- ALEM FARID (faridatcemlulaqbayli) (*Kabyle*) -- Jean-Pierre MÉRESSE (Jipem) (*French*) +- chine.sebastien (*French*) +- bgme (*Chinese Simplified*) +- Rafaael (*Portuguese, Brazilian*) +- Fei1Yang (*Chinese Traditional*) +- freegnu (*Tatar*) +- sebastien.chine (*French*) +- projectz.1338 (*German*) - enipra (*Armenian*) -- Serhiy Dmytryshyn (dies) (*Ukrainian*) -- Eric Brulatout (ebrulato) (*Esperanto*) -- Hougo (hougo) (*French*) +- faridatcemlulaqbayli (*Kabyle*) +- musix (*Persian*) +- Jipem (*French*) +- hougo (*French*) +- dies (*Ukrainian*) +- djprmf (*Portuguese*) - Sonstwer (*German*) -- Pedro Fernandes (djprmf) (*Portuguese*) -- REMOVED_USER (*Norwegian*) -- Tigran's Tips (tigrank08) (*Armenian*) -- 亜緯丹穂 (ayiniho) (*Japanese*) -- maisui (*Chinese Simplified*) -- Trinsec (*Dutch*) -- Adrián Lattes (haztecaso) (*Spanish*) -- webkinzfrog (*Polish*) +- ebrulato (*Esperanto*) +- haztecaso (*Spanish*) - ybardapurkar (*Marathi*) -- Mordi Sacks (MordiSacks) (*Hebrew*) -- Manuel Tassi (Mannivu) (*Italian*) -- Szabolcs Gál (galszabolcs810624) (*Hungarian*) -- rikrise (*Swedish*) -- when_hurts (*German*) -- Wojciech Bigosinski (wbigos2) (*Polish*) -- Vladislav S (vladislavs) (*Romanian*) -- mikslatvis (*Latvian*) -- MartinAlstad (*Norwegian*) +- MordiSacks (*Hebrew*) +- ayiniho (*Japanese*) +- tigrank08 (*Armenian*) +- Trinsec (*Dutch*) +- webkinzfrog (*Polish*) +- Mannivu (*Italian*) +- maisui (*Chinese Simplified*) - TracyJacks (*Chinese Simplified*) +- galszabolcs810624 (*Hungarian*) +- vladislavs (*Romanian*) +- rikrise (*Swedish*) +- MartinAlstad (*Norwegian*) +- when_hurts (*German*) +- wbigos2 (*Polish*) +- mikslatvis (*Latvian*) - rasheedgm (*Kannada*) -- Cirelli (cirelli94) (*Italian*) - danreznik (*Hebrew*) +- cirelli94 (*Italian*) - iraline (*Portuguese, Brazilian*) -- Seán Mór (seanmor3) (*Irish*) +- seanmor3 (*Irish*) +- sidharastro (*Spanish, Mexico*) - vianaweb (*Portuguese, Brazilian*) -- Siddharastro Doraku (sidharastro) (*Spanish, Mexico*) -- REMOVED_USER (*Spanish*) +- nspeaks (*Hindi*) +- belkacem77 (*Kabyle*) - omquylzu (*Latvian*) -- Arthegor (*French*) -- Navjot Singh (nspeaks) (*Hindi*) - mkljczk (*Polish*) -- Belkacem Mohammed (belkacem77) (*Kabyle*) +- c6ristian (*German*) +- lexxai (*Ukrainian*) - Showfom (*Chinese Simplified*) - xemyst (*Catalan*) -- lexxai (*Ukrainian*) -- c6ristian (*German*) -- svetlozaurus (*Bulgarian*) +- Arthegor (*French*) +- petrosyan (*Armenian*) - Ozai (*German*) +- MetehanOzyurek (*Turkish*) - damascene (*Arabic*) -- Jan Ainali (Ainali) (*Swedish*) -- Sahak Petrosyan (petrosyan) (*Armenian*) -- Metehan Özyürek (MetehanOzyurek) (*Turkish*) -- Сау Рэмсон (sawrams) (*Russian*) +- svetlozaurus (*Bulgarian*) +- Ainali (*Swedish*) +- rapiteanu (*Romanian*) +- sawrams (*Russian*) +- kscanne (*Irish*) +- sebastienserre (*French*) - metehan-arslan (*Turkish*) -- Viorel-Cătălin Răpițeanu (rapiteanu) (*Romanian*) -- Sébastien SERRE (sebastienserre) (*French*) -- Eugen Caruntu (eugencaruntu) (*Romanian*) -- Kevin Scannell (kscanne) (*Irish*) -- Pachara Chantawong (pachara2202) (*Thai*) -- bensch.dev (*German*) +- eugencaruntu (*Romanian*) +- quinoa_biryani (*Bengali*) +- pachara2202 (*Thai*) - LIZH (*French*) -- Siddhartha Sarathi Basu (quinoa_biryani) (*Bengali*) -- Overflow Cat (OverflowCat) (*Chinese Traditional, Chinese Simplified*) -- Stephan Voeth (svoeth) (*German*) -- Zijian Zhao (jobs2512821228) (*Chinese Simplified*) -- bugboy-20 (*Esperanto, Italian*) -- SouthFox (*Chinese Simplified*) -- Noan (SkewRam) (*French*) +- bensch.dev (*German*) +- SkewRam (*French*) +- jobs2512821228 (*Chinese Simplified*) - dbeaver (*German*) +- OverflowCat (*Chinese Simplified, Chinese Traditional*) +- svoeth (*German*) +- SouthFox (*Chinese Simplified*) +- bugboy-20 (*Esperanto, Italian*) +- guruprasath (*Tamil*) - turtle836 (*German*) -- Guru Prasath Anandapadmanaban (guruprasath) (*Tamil*) - zordsdavini (*Lithuanian*) -- Susanna Ånäs (susanna.anas) (*Finnish*) -- Alessandro (alephoto85) (*Italian*) -- Marcepanek_ (thekingmarcepan) (*Polish*) -- Choi Younsoo (usagicore) (*Korean*) -- Yann Aguettaz (yann-a) (*French*) -- zylosophe (*French*) -- Celso Fernandes (Celsof) (*Portuguese, Brazilian*) -- Feruz Oripov (FeruzOripov) (*Russian*) +- susanna.anas (*Finnish*) +- thekingmarcepan (*Polish*) +- alephoto85 (*Italian*) +- FeruzOripov (*Russian*) +- yann-a (*French*) +- usagicore (*Korean*) +- Celsof (*Portuguese, Brazilian*) - REMOVED_USER (*French*) -- Bui Huy Quang (bhuyquang1) (*Vietnamese*) +- zylosophe (*French*) +- bhuyquang1 (*Vietnamese*) - bogomilshopov (*Bulgarian*) +- kaedech (*Japanese*) +- xgc.redes (*Asturian*) - REMOVED_USER (*Burmese*) -- Kaede (kaedech) (*Japanese*) -- Mick Onio (xgc.redes) (*Asturian*) -- Malik Mann (dermalikmann) (*German*) +- dermalikmann (*German*) +- hg6 (*Hindi*) - padulafacundo (*Spanish*) +- tina.zhang040609 (*Chinese Simplified*) - r3dsp1 (*Chinese Traditional, Hong Kong*) - dadosch (*German*) -- Tianqi Zhang (tina.zhang040609) (*Chinese Simplified*) -- HybridGlucose (*Chinese Traditional*) - vmichalak (*French*) -- hg6 (*Hindi*) +- HybridGlucose (*Chinese Traditional*) - marivisales (*Portuguese, Brazilian*) -- Orlando Murcio (Atos20) (*Spanish, Mexico*) +- Atos20 (*Spanish, Mexico*) +- J0hsHH (*Norwegian*) - maa123 (*Japanese*) -- Julian Doser (julian21) (*English, United Kingdom, German*) -- johannes hove-henriksen (J0hsHH) (*Norwegian*) -- Alexander Ivanov (Saiv46) (*Russian*) -- unstable.icu (*Chinese Simplified*) -- Padraic Calpin (padraic-padraic) (*Slovenian*) -- Youngeon Lee (YoungeonLee) (*Korean*) -- LeJun (le-jun) (*French*) -- shdy (*German*) -- REMOVED_USER (*French*) -- Yonjae Lee (yonjlee) (*Korean*) +- julian21 (*English, United Kingdom, German*) - cenegd (*Chinese Simplified*) +- padraic-padraic (*Slovenian*) - piupiupiudiu (*Chinese Simplified*) -- Umi (mtrumi) (*Chinese Traditional, Hong Kong, Chinese Simplified*) -- Yogesh K S (yogi) (*Kannada*) +- shdy (*German*) +- mtrumi (*Chinese Simplified, Chinese Traditional, Hong Kong*) +- YoungeonLee (*Korean*) +- unstable.icu (*Chinese Simplified*) +- yonjlee (*Korean*) +- le-jun (*French*) +- Saiv46 (*Russian*) +- youloveonlymeh (*Chinese Simplified*) +- yogi (*Kannada*) +- adithyak04 (*Malayalam*) +- daijie (*Chinese Simplified*) +- milli.pretili (*Croatian*) - Ulong32 (*Japanese*) -- Adithya K (adithyak04) (*Malayalam*) -- DAI JIE (daijie) (*Chinese Simplified*) -- Mihael Budeč (milli.pretili) (*Croatian*) -- Hugh Liu (youloveonlymeh) (*Chinese Simplified*) +- rakino (*Chinese Simplified*) - ZQYD (*Chinese Simplified*) -- X.M (kimonoki) (*Chinese Simplified*) -- Rakino (rakino) (*Chinese Simplified*) -- paziy Georgi (paziygeorgi4) (*Dutch*) -- Komeil Parseh (mmdbalkhi) (*Persian*) -- Jothipazhani Nagarajan (jothipazhani.n) (*Tamil*) -- tikky9 (*Portuguese, Brazilian*) -- horsm (*Finnish*) -- BenJule (*German*) -- Stanisław Jelnicki (JelNiSlaw) (*Polish*) -- Yananas (wangyanyan.hy) (*Chinese Simplified*) -- Vivamus (elaaksu) (*Turkish*) -- ihealyou (*Italian*) +- kimonoki (*Chinese Simplified*) +- jothipazhani.n (*Tamil*) - AmazighNM (*Kabyle*) -- Miquel Sabaté Solà (mssola) (*Catalan*) +- mssola (*Catalan*) +- JelNiSlaw (*Polish*) +- BenJule (*German*) +- wangyanyan.hy (*Chinese Simplified*) - residuum (*German*) -- nua_kr (*Korean*) -- Andrea Mazzilli (andreamazzilli) (*Italian*) -- Paula SIMON (EncoreEutIlFalluQueJeLeSusse) (*French*) +- mmdbalkhi (*Persian*) +- paziygeorgi4 (*Dutch*) +- tikky9 (*Portuguese, Brazilian*) +- ihealyou (*Italian*) +- elaaksu (*Turkish*) +- horsm (*Finnish*) - hallomaurits (*Dutch*) -- Erfan Kheyrollahi Qaroğlu (ekm507) (*Persian*) - REMOVED_USER (*Galician, Spanish*) -- alnd hezh (alndhezh) (*Sorani (Kurdish)*) -- Clash Clans (KURD12345) (*Sorani (Kurdish)*) +- SolidRhino (*Dutch*) +- KURD12345 (*Sorani (Kurdish)*) +- alndhezh (*Sorani (Kurdish)*) +- nua_kr (*Korean*) +- EncoreEutIlFalluQueJeLeSusse (*French*) +- CloudSet (*Chinese Simplified*) - ruok (*Chinese Simplified*) - Frederik-FJ (*German*) -- CloudSet (*Chinese Simplified*) -- Solid Rhino (SolidRhino) (*Dutch*) +- andreamazzilli (*Italian*) +- ekm507 (*Persian*) +- noellabo (*Japanese*) - hussama (*Portuguese, Brazilian*) -- jazzynico (*French*) -- k_taka (peaceroad) (*Japanese*) -- 林水溶 (shuiRong) (*Chinese Simplified*) -- Peter Lutz (theellutzo) (*German*) -- Sébastien Feugère (smonff) (*French*) -- AnalGoddess770 (*Hebrew*) -- Sven Goller (svengoller) (*German*) -- Ahmet (ahmetlii) (*Turkish*) +- shuiRong (*Chinese Simplified*) +- smonff (*French*) +- peaceroad (*Japanese*) +- hallo_hamza12 (*Sorani (Kurdish)*) +- ahmetlii (*Turkish*) +- theellutzo (*German*) - hosted22 (*German*) -- Hallo Abdullah (hallo_hamza12) (*Sorani (Kurdish)*) -- Karam Hamada (TheKaram) (*Arabic*) -- Takeshi Umeda (noellabo) (*Japanese*) +- svengoller (*German*) +- TheKaram (*Arabic*) +- jazzynico (*French*) +- AnalGoddess770 (*Hebrew*) - SnDer (*Dutch*) -- Robert Yano (throwcalmbobaway) (*Spanish, Mexico*) -- Gustav Lindqvist (Reedyn) (*Swedish*) -- Dagur Ammendrup (dagurp) (*Icelandic*) -- shafouz (*Portuguese, Brazilian*) -- Miguel Branco (mglbranco) (*Galician*) -- Sergey Panteleev (saundefined) (*Russian*) -- Tom_ (*Czech*) -- Zlr- (cZeler) (*French*) -- Ashok314 (ashok314) (*Hindi*) -- PifyZ (*French*) -- Zeyi Fan (fanzeyi) (*Chinese Simplified*) -- OminousCry (*Russian, Ukrainian*) -- Adam Sapiński (Adamos9898) (*Polish*) - eichkat3r (*German*) -- Yasin İsa YILDIRIM (redsfyre) (*Turkish*) -- Tagada (Tagadda) (*French*) +- PifyZ (*French*) +- OminousCry (*Russian, Ukrainian*) +- shafouz (*Portuguese, Brazilian*) +- Tom_ (*Czech*) +- Tagadda (*French*) +- ashok314 (*Hindi*) +- cZeler (*French*) +- Iriep (*Breton*) +- throwcalmbobaway (*Spanish, Mexico*) +- redsfyre (*Turkish*) +- Adamos9898 (*Polish*) +- Reedyn (*Swedish*) +- saundefined (*Russian*) +- fanzeyi (*Chinese Simplified*) +- mglbranco (*Galician*) +- dagurp (*Icelandic*) - gasrios (*Portuguese, Brazilian*) -- 夜楓Yoka (Yoka2627) (*Chinese Simplified*) -- AniCommieDDR (*Russian*) -- Nathaël Noguès (NatNgs) (*French*) -- Daniel M. (daniconil) (*Catalan*) -- César Daniel Cavanzo Quintero (LeinadCQ) (*Esperanto*) -- Noam Tamim (noamtm) (*Hebrew*) +- saccharin23 (*Japanese*) +- tshrinivasan (*Tamil*) +- REMOVED_USER (*Urdu (Pakistan)*) +- kishorkumara3 (*Kannada*) +- swatisani (*Urdu (Pakistan)*) +- daniconil (*Catalan*) +- NatNgs (*French*) +- Yoka2627 (*Chinese Simplified*) - papayaisnotafood (*Chinese Traditional*) -- さっかりんにーさん (saccharin23) (*Japanese*) -- Marcin Wolski (martinwolski) (*Polish*) -- REMOVED_USER (*Chinese Simplified*) -- Kk (kishorkumara3) (*Kannada*) -- Shrinivasan T (tshrinivasan) (*Tamil*) -- REMOVED_USER (Urdu (Pakistan)) -- Kakarico Bra (kakarico20) (*Portuguese, Brazilian*) -- Swati Sani (swatisani) (*Urdu (Pakistan)*) -- 快乐的老鼠宝宝 (LaoShuBaby) (*Chinese Simplified, Chinese Traditional*) -- Mt Front (mtfront) (*Chinese Simplified*) -- SusVersiva (*Catalan*) -- REMOVED_USER (*Portuguese, Brazilian*) -- Avinash Mg (hatman290) (*Malayalam*) -- kruijs (*Dutch*) -- Artem (Artem4ik) (*Russian*) +- LeinadCQ (*Esperanto*) +- kakarico20 (*Portuguese, Brazilian*) +- AniCommieDDR (*Russian*) +- martinwolski (*Polish*) +- noamtm (*Hebrew*) +- tradjincal (*French*) - Zinkokooo (*Basque*) -- 劉昌賢 (twcctz500) (*Chinese Traditional*) - Vikatakavi (*Kannada*) -- Tradjincal (tradjincal) (*French*) -- Robin van der Vliet (RobinvanderVliet) (*Esperanto*) -- Marvin (magicmarvman) (*German*) +- SusVersiva (*Catalan*) +- RobinvanderVliet (*Esperanto*) +- Artem4ik (*Russian*) - pullopen (*Chinese Simplified*) -- Tealk (*German*) -- tibequadorian (*German*) -- Henk Bulder (henkbulder) (*Dutch*) -- Edison Lee (edisonlee55) (*Chinese Traditional*) -- mpdude (*German*) -- Rijk van Geijtenbeek (rvangeijtenbeek) (*Dutch*) -- Entelekheia-ousia (*Chinese Simplified*) -- REMOVED_USER (*Spanish*) -- sergioaraujo1 (*Portuguese, Brazilian*) -- Livingston Samuel (livingston) (*Tamil*) +- magicmarvman (*German*) +- mtfront (*Chinese Simplified*) +- twcctz500 (*Chinese Traditional*) +- LaoShuBaby (*Chinese Simplified, Chinese Traditional*) +- kruijs (*Dutch*) +- hatman290 (*Malayalam*) - mmokhi (*Persian*) +- sergioaraujo1 (*Portuguese, Brazilian*) - tsundoker (*Malayalam*) -- CyberAmoeba (pseudoobscura) (*Chinese Simplified*) - prabhjot (*Hindi*) -- Ikka Putri (ikka240290) (*Indonesian, Danish, English, United Kingdom*) -- Paz Galindo (paz.almendra.g) (*Spanish*) -- Ricardo Colin (rysard) (*Spanish*) -- Pierre Morvan (Iriep) (*Breton*) -- oscfd (*Spanish*) -- Thies Mueller (thies00) (*German*) -- Lyra (teromene) (*French*) -- Kedr (lava20121991) (*Esperanto*) -- mkljczk (mykylyjczyk) (*Polish*) +- livingston (*Tamil*) +- pseudoobscura (*Chinese Simplified*) +- Entelekheia-ousia (*Chinese Simplified*) +- tibequadorian (*German*) +- edisonlee55 (*Chinese Traditional*) +- Tealk (*German*) +- rvangeijtenbeek (*Dutch*) +- henkbulder (*Dutch*) +- mpdude (*German*) - fedot (*Russian*) -- Philipp Fischbeck (PFischbeck) (*German*) -- Hasan Berkay Çağır (berkaycagir) (*Turkish*) -- Silvestri Nicola (nick99silver) (*Italian*) - skaaarrr (*German*) -- Mo Rijndael (mo_rijndael) (*Russian*) -- tsesunnaallun (orezraey) (*Portuguese, Brazilian*) -- Lukas Fülling (lfuelling) (*German*) -- Algo (algovigura) (*Indonesian*) -- REMOVED_USER (*Spanish*) -- setthemfree (*Ukrainian*) -- i fly (ifly3years) (*Chinese Simplified*) -- ralozkolya (*Georgian*) -- Zoé Bőle (zoe1337) (*German*) -- Ville Rantanen (vrntnn) (*Finnish*) +- rysard (*Spanish*) +- paz.almendra.g (*Spanish*) +- mykylyjczyk (*Polish*) +- PFischbeck (*German*) +- berkaycagir (*Turkish*) +- thies00 (*German*) +- lava20121991 (*Esperanto*) +- nick99silver (*Italian*) +- teromene (*French*) +- ikka240290 (*Danish, English, United Kingdom, Indonesian*) +- Merman-Jack (*Chinese Simplified*) +- zoe1337 (*German*) +- lfuelling (*German*) +- REMOVED_USER (*Georgian*) - GaggiX (*Italian*) -- JackXu (Merman-Jack) (*Chinese Simplified*) -- ceonia (*Chinese Traditional, Hong Kong*) -- Emirhan Yavuz (takomlii) (*Turkish*) +- orezraey (*Portuguese, Brazilian*) - teezeh (*German*) -- MevLyshkin (Leinnan) (*Polish*) -- Apple (blackteaovo) (*Chinese Simplified*) -- qwerty287 (*German*) -- Tangcuyu (*Chinese Simplified*) +- takomlii (*Turkish*) +- ceonia (*Chinese Traditional, Hong Kong*) +- mo_rijndael (*Russian*) +- vrntnn (*Finnish*) +- ifly3years (*Chinese Simplified*) +- Leinnan (*Polish*) +- algovigura (*Indonesian*) +- setthemfree (*Ukrainian*) +- anoopp (*Malayalam*) +- samir_t7 (*Kabyle*) +- AymBroussier (*French*) +- albjeremias (*Portuguese*) - Nocta (*French*) -- ru_mactunnag (*Scottish Gaelic*) -- Lilian Nabati (Lilounab49) (*French*) -- lokalisoija (*Finnish*) -- Dennis Reimund (reimund_dennis) (*German*) -- ronee (*Kurmanji (Kurdish)*) -- EricVogt_ (*Spanish*) -- yu miao (metaxx.dev) (*Chinese Simplified*) -- Anoop (anoopp) (*Malayalam*) -- Samir Tighzert (samir_t7) (*Kabyle*) -- sn02 (*German*) -- Yui Karasuma (yui87) (*Japanese*) -- asala4544 (*Basque*) -- Thibaut Rousseau (thiht44) (*French*) -- Jason Gibson (barberpike606) (*Slovenian, Chinese Simplified*) -- Sugar NO (g1024116707) (*Chinese Simplified*) -- Aymeric (AymBroussier) (*French*) - pezcurrel (*Italian*) -- Xurxo Guerra (xguerrap) (*Galician*) -- nicosomb (*French*) -- Albatroz Jeremias (albjeremias) (*Portuguese*) -- María José Vera (mjverap) (*Spanish*) - mashirozx (*Chinese Simplified*) +- blackteaovo (*Chinese Simplified*) +- xguerrap (*Galician*) +- reimund_dennis (*German*) +- asala4544 (*Basque*) +- qwerty287 (*German*) +- ru_mactunnag (*Scottish Gaelic*) +- Lilounab49 (*French*) +- ronee (*Kurmanji (Kurdish)*) +- barberpike606 (*Chinese Simplified, Slovenian*) +- lokalisoija (*Finnish*) +- Tangcuyu (*Chinese Simplified*) - codl (*French*) -- Doug (douglasalvespe) (*Portuguese, Brazilian*) -- Matias Lavik (matiaslavik) (*Norwegian Nynorsk*) -- random_person (*Spanish*) -- whoeta (wh0eta) (*Russian*) -- xpac1985 (xpac) (*German*) -- thisdudeisvegan (braydofficial) (*German*) -- Fleva (*Sardinian*) -- Anonymous (Anonymous666) (*Russian*) -- Mohammad Adnan Mahmood (adnanmig) (*Arabic*) -- ÀŘǾŚ PÀŚĦÀÍ (arospashai) (*Sorani (Kurdish)*) -- mikel (mikelalas) (*Spanish*) -- Trond Boksasp (boksasp) (*Norwegian*) -- asretro (*Chinese Traditional, Hong Kong*) -- Holger Huo (holgerhuo) (*Chinese Simplified*) -- Aman Alam (aalam) (*Punjabi*) -- smedvedev (*Russian*) -- Jay Lonnquist (crowkeep) (*Japanese*) -- mimikun (*Japanese*) -- Mohd Bilal (mdb571) (*Malayalam*) -- veer66 (*Thai*) -- OpenAlgeria (*Arabic*) -- Rave (nayumi-464812844) (*Vietnamese*) -- ReavedNetwork (*German*) -- Michael (Discostu36) (*German*) +- mjverap (*Spanish*) +- metaxx.dev (*Chinese Simplified*) +- g1024116707 (*Chinese Simplified*) +- EricVogt_ (*Spanish*) +- yui87 (*Japanese*) +- sn02 (*German*) +- nicosomb (*French*) +- thiht44 (*French*) - tamaina (*Japanese*) +- OpenAlgeria (*Arabic*) +- Saislakshmanan (*Tamil*) +- amithraj1989 (*Kannada*) +- adnanmig (*Arabic*) +- smedvedev (*Russian*) +- boksasp (*Norwegian*) +- mikelalas (*Spanish*) +- random_person (*Spanish*) +- matiaslavik (*Norwegian Nynorsk*) +- douglasalvespe (*Portuguese, Brazilian*) +- Fleva (*Sardinian*) +- arospashai (*Sorani (Kurdish)*) +- xpac (*German*) +- asretro (*Chinese Traditional, Hong Kong*) +- aalam (*Punjabi*) +- mimikun (*Japanese*) +- holgerhuo (*Chinese Simplified*) +- mdb571 (*Malayalam*) +- braydofficial (*German*) +- rmegg1933 (*Latvian*) +- nayumi-464812844 (*Vietnamese*) +- ReavedNetwork (*German*) +- Discostu36 (*German*) +- veer66 (*Thai*) - sk22 (*German*) -- Ragnars Eggerts (rmegg1933) (*Latvian*) -- Sais Lakshmanan (Saislakshmanan) (*Tamil*) -- Amith Raj Shetty (amithraj1989) (*Kannada*) -- Bartek Fijałkowski (brateq) (*Polish*) -- Asbeltrion (*Spanish*) -- Michael Horstmann (mhrstmnn) (*German*) -- Joffrey Abeilard (Abeilard14) (*French*) -- capiscuas (*Spanish*) +- crowkeep (*Japanese*) +- wh0eta (*Russian*) +- Anonymous666 (*Russian*) - djoerd (*Dutch*) -- REMOVED_USER (*Spanish*) -- NeverMine17 (*Russian*) -- songxianj (songxian_jiang) (*Chinese Simplified*) -- Ács Zoltán (zoli111) (*Hungarian*) -- haaninjo (*Swedish*) - REMOVED_USER (*Esperanto*) -- Philip Molares (DerMolly) (*German*) -- ChalkPE (amato0617) (*Korean*) -- ebrezhoneg (*Breton*) -- 디떱 (diddub) (*Korean*) -- Hans (hansj) (*German*) -- Nithya Mary (nithyamary25) (*Tamil*) -- kavitha129 (*Tamil*) +- Abijeet (*Basque*) +- benjamincobb (*German*) - waweic (*German*) -- Aries (orlea) (*Japanese*) -- おさ (osapon) (*Japanese*) -- Abijeet Patro (Abijeet) (*Basque*) -- centumix (*Japanese*) -- Martin Müller (muellermartin) (*German*) +- kavitha129 (*Tamil*) +- nithyamary25 (*Tamil*) +- ebrezhoneg (*Breton*) +- argxentakato (*Japanese*) - tateisu (*Japanese*) -- Arĝentakato (argxentakato) (*Japanese*) -- Benjamin Cobb (benjamincobb) (*German*) -- deanerschnitzel (*German*) -- Jill H. (kokakiwi) (*French*) -- maksutheam (*Finnish*) -- d0p1 (d0p1s4m4) (*French*) +- osapon (*Japanese*) +- centumix (*Japanese*) +- orlea (*Japanese*) +- NeverMine17 (*Russian*) +- capiscuas (*Spanish*) +- brateq (*Polish*) +- zoli111 (*Hungarian*) +- Jiniux (*Italian*) +- Aniqueper1 (*Chinese Simplified*) +- SamOak (*Portuguese, Brazilian*) +- dobrado (*Portuguese, Brazilian*) +- dcapillae (*Spanish*) +- xissshawww (*Chinese Simplified*) +- kuraking202 (*Sorani (Kurdish)*) +- RanjAhmed (*Sorani (Kurdish)*) +- Salh_haji6 (*Sorani (Kurdish)*) +- dashty (*Sorani (Kurdish)*) +- Kurdish.boy (*Sorani (Kurdish)*) +- herrero.maty (*Spanish*) +- umonaca (*Chinese Simplified*) +- ronchaine (*Finnish*) +- atomicmind (*Slovenian*) +- futchitwo (*Japanese*) +- brodi1 (*Dutch*) +- soheilkhanalipur (*Persian*) +- hud5634j (*Spanish*) +- kvdbve34 (*Russian*) +- jiangshanghan (*Chinese Simplified*) +- patriceboivin58 (*French*) - majorblazr (*Danish*) -- Patrice Boivin (patriceboivin58) (*French*) -- 江尚寒 (jiangshanghan) (*Chinese Simplified*) -- HSD Channel (kvdbve34) (*Russian*) -- alwyn joe (iomedivh200) (*Chinese Simplified*) -- ZHY (sheepzh) (*Chinese Simplified*) -- Bei Li (libei) (*Chinese Simplified*) -- Aluo (Aluo_rbszd) (*Chinese Simplified*) -- clarkzjw (*Chinese Simplified*) -- Noah Luppe (noahlup) (*German*) +- maksutheam (*Finnish*) +- kokakiwi (*French*) - araghunde (*Galician*) +- noahlup (*German*) +- clarkzjw (*Chinese Simplified*) +- Aluo_rbszd (*Chinese Simplified*) +- libei (*Chinese Simplified*) +- sheepzh (*Chinese Simplified*) +- iomedivh200 (*Chinese Simplified*) +- fyuodchiodmoiidiiduh86 (*Chinese Simplified*) - BratishkaErik (*Russian*) - Bunny9568 (*Chinese Simplified*) -- SamOak (*Portuguese, Brazilian*) -- Ranj A Abdulqadir (RanjAhmed) (*Sorani (Kurdish)*) -- Amir Kurdo (kuraking202) (*Sorani (Kurdish)*) -- 于晚霞 (xissshawww) (*Chinese Simplified*) -- Fyuoxyjidyho Moiodyyiodyhi (fyuodchiodmoiidiiduh86) (*Chinese Simplified*) -- RPD0911 (*Hungarian*) -- dcapillae (*Spanish*) -- dobrado (*Portuguese, Brazilian*) -- Hannah (Aniqueper1) (*Chinese Simplified*) -- Azad ahmad (dashty) (*Sorani (Kurdish)*) -- Uri Chachick (urich.404) (*Hebrew*) -- Bnoru (*Portuguese, Brazilian*) -- Jiniux (*Italian*) -- REMOVED_USER (*German*) -- Salh_haji6 (Sorani (Kurdish)) -- Kurdish Translator (*Kurdish.boy) (Sorani (Kurdish)*) -- Beagle (beagleworks) (*Japanese*) -- hud5634j (*Spanish*) -- Kisaragi Hiu (flyingfeather1501) (*Chinese Traditional*) -- Dominik Ziegler (dodomedia) (*German*) -- soheilkhanalipur (*Persian*) -- Brodi (brodi1) (*Dutch*) -- Savarín Electrográfico Marmota Intergalactica (herrero.maty) (*Spanish*) -- Ni Futchi (futchitwo) (*Japanese*) -- Zois Lee (gcnwm) (*Chinese Simplified*) -- Arnold Marko (atomicmind) (*Slovenian*) +- d0p1s4m4 (*French*) +- flyingfeather1501 (*Chinese Traditional*) +- dodomedia (*German*) +- beagleworks (*Japanese*) +- gcnwm (*Chinese Simplified*) - scholzco (*German*) -- Jari Ronkainen (ronchaine) (*Finnish*) -- umonaca (*Chinese Simplified*) +- RPD0911 (*Hungarian*) +- urich.404 (*Hebrew*) +- Bnoru (*Portuguese, Brazilian*) +- deanerschnitzel (*German*) +- haaninjo (*Swedish*) +- Asbeltrion (*Spanish*) +- songxian_jiang (*Chinese Simplified*) +- hansj (*German*) +- amato0617 (*Korean*) +- diddub (*Korean*) +- muellermartin (*German*) +- DerMolly (*German*) +- Abeilard14 (*French*) +- mhrstmnn (*German*) \ No newline at end of file diff --git a/Aptfile b/Aptfile index 8f5bb72a25..5e033f1365 100644 --- a/Aptfile +++ b/Aptfile @@ -1,4 +1,5 @@ ffmpeg +libopenblas0-pthread libpq-dev libxdamage1 libxfixes3 diff --git a/CHANGELOG.md b/CHANGELOG.md index aaedba1138..fab3104bac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,363 @@ -Changelog -========= +# Changelog All notable changes to this project will be documented in this file. +## [4.2.0] - 2023-09-21 + +The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by [@danielmbrasil](https://github.com/danielmbrasil), [@mjankowski](https://github.com/mjankowski), [@nschonni](https://github.com/nschonni), [@renchap](https://github.com/renchap), and [@takayamaki](https://github.com/takayamaki). + +### Added + +- **Add full-text search of opted-in public posts and rework search operators** ([Gargron](https://github.com/mastodon/mastodon/pull/26485), [jsgoldstein](https://github.com/mastodon/mastodon/pull/26344), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26657), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26650), [jsgoldstein](https://github.com/mastodon/mastodon/pull/26659), [Gargron](https://github.com/mastodon/mastodon/pull/26660), [Gargron](https://github.com/mastodon/mastodon/pull/26663), [Gargron](https://github.com/mastodon/mastodon/pull/26688), [Gargron](https://github.com/mastodon/mastodon/pull/26689), [Gargron](https://github.com/mastodon/mastodon/pull/26686), [Gargron](https://github.com/mastodon/mastodon/pull/26687), [Gargron](https://github.com/mastodon/mastodon/pull/26692), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26697), [Gargron](https://github.com/mastodon/mastodon/pull/26699), [Gargron](https://github.com/mastodon/mastodon/pull/26701), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26710), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26739), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26754), [Gargron](https://github.com/mastodon/mastodon/pull/26662), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26755), [Gargron](https://github.com/mastodon/mastodon/pull/26781), [Gargron](https://github.com/mastodon/mastodon/pull/26782), [Gargron](https://github.com/mastodon/mastodon/pull/26760), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26756), [Gargron](https://github.com/mastodon/mastodon/pull/26784), [Gargron](https://github.com/mastodon/mastodon/pull/26807), [Gargron](https://github.com/mastodon/mastodon/pull/26835), [Gargron](https://github.com/mastodon/mastodon/pull/26847), [Gargron](https://github.com/mastodon/mastodon/pull/26834), [arbolitoloco1](https://github.com/mastodon/mastodon/pull/26893), [tribela](https://github.com/mastodon/mastodon/pull/26896), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26927), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26959), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27014)) + This introduces a new `public_statuses` Elasticsearch index for public posts by users who have opted in to their posts being searchable (`toot#indexable` flag). + This also revisits the other indexes to provide more useful indexing, and adds new search operators such as `from:me`, `before:2022-11-01`, `after:2022-11-01`, `during:2022-11-01`, `language:fr`, `has:poll`, or `in:library` (for searching only in posts you have written or interacted with). + Results are now ordered chronologically. +- **Add admin notifications for new Mastodon versions** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26582)) + This is done by querying `https://api.joinmastodon.org/update-check` every 30 minutes in a background job. + That URL can be changed using the `UPDATE_CHECK_URL` environment variable, and the feature outright disabled by setting that variable to an empty string (`UPDATE_CHECK_URL=`). +- **Add “Privacy and reach” tab in profile settings** ([Gargron](https://github.com/mastodon/mastodon/pull/26484), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26508)) + This reorganized scattered privacy and reach settings to a single place, as well as improve their wording. +- **Add display of out-of-band hashtags in the web interface** ([Gargron](https://github.com/mastodon/mastodon/pull/26492), [arbolitoloco1](https://github.com/mastodon/mastodon/pull/26497), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26506), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26525), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26606), [Gargron](https://github.com/mastodon/mastodon/pull/26666), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26960)) +- **Add role badges to the web interface** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25649), [Gargron](https://github.com/mastodon/mastodon/pull/26281)) +- **Add ability to pick domains to forward reports to using the `forward_to_domains` parameter in `POST /api/v1/reports`** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25866), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26636)) + The `forward_to_domains` REST API parameter is a list of strings. If it is empty or omitted, the previous behavior is maintained. + The `forward` parameter still needs to be set for `forward_to_domains` to be taken into account. + The forwarded-to domains can only include that of the original author and people being replied to. +- **Add forwarding of reported replies to servers being replied to** ([Gargron](https://github.com/mastodon/mastodon/pull/25341), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26189)) +- Add `ONE_CLICK_SSO_LOGIN` environment variable to directly link to the Single-Sign On provider if there is only one sign up method available ([CSDUMMI](https://github.com/mastodon/mastodon/pull/26083), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26368), [CSDUMMI](https://github.com/mastodon/mastodon/pull/26857), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26901)) +- **Add webhook templating** ([Gargron](https://github.com/mastodon/mastodon/pull/23289)) +- **Add webhooks for local `status.created`, `status.updated`, `account.updated` and `report.updated`** ([VyrCossont](https://github.com/mastodon/mastodon/pull/24133), [VyrCossont](https://github.com/mastodon/mastodon/pull/24243), [VyrCossont](https://github.com/mastodon/mastodon/pull/24211)) +- **Add exclusive lists** ([dariusk, necropolina](https://github.com/mastodon/mastodon/pull/22048), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25324)) +- **Add a confirmation screen when suspending a domain** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25144), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25603)) +- **Add support for importing lists** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25203), [mgmn](https://github.com/mastodon/mastodon/pull/26120), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26372)) +- **Add optional hCaptcha support** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25019), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25057), [Gargron](https://github.com/mastodon/mastodon/pull/25395), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26388)) +- **Add lines to threads in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24549), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24677), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24696), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24711), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24714), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24713), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24715), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24800), [teeerevor](https://github.com/mastodon/mastodon/pull/25706), [renchap](https://github.com/mastodon/mastodon/pull/25807)) +- **Add new onboarding flow to web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24619), [Gargron](https://github.com/mastodon/mastodon/pull/24646), [Gargron](https://github.com/mastodon/mastodon/pull/24705), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24872), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/24883), [Gargron](https://github.com/mastodon/mastodon/pull/24954), [stevenjlm](https://github.com/mastodon/mastodon/pull/24959), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25010), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25275), [Gargron](https://github.com/mastodon/mastodon/pull/25559), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25561)) +- **Add auto-refresh of accounts we get new messages/edits of** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26510)) +- **Add Elasticsearch cluster health check and indexes mismatch check to dashboard** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26448), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26605), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26658)) +- Add `hide_collections`, `discoverable` and `indexable` attributes to credentials API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26998)) +- Add `S3_ENABLE_CHECKSUM_MODE` environment variable to enable checksum verification on compatible S3-providers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26435)) +- Add admin API for managing tags ([rrgeorge](https://github.com/mastodon/mastodon/pull/26872)) +- Add a link to hashtag timelines from the Trending hashtags moderation interface ([gunchleoc](https://github.com/mastodon/mastodon/pull/26724)) +- Add timezone to datetimes in e-mails ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26822)) +- Add `authorized_fetch` server setting in addition to env var ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26958)) +- Add avatar image to webfinger responses ([tvler](https://github.com/mastodon/mastodon/pull/26558)) +- Add debug logging on signature verification failure ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26637), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26812)) +- Add explicit error messages when DeepL quota is exceeded ([lutoma](https://github.com/mastodon/mastodon/pull/26704)) +- Add Elasticsearch/OpenSearch version to “Software” in admin dashboard ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26652)) +- Add `data-nosnippet` attribute to remote posts and local posts with `noindex` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26648)) +- Add support for federating `memorial` attribute ([rrgeorge](https://github.com/mastodon/mastodon/pull/26583)) +- Add Cherokee and Kalmyk to languages dropdown ([gunchleoc](https://github.com/mastodon/mastodon/pull/26012), [gunchleoc](https://github.com/mastodon/mastodon/pull/26013)) +- Add `DELETE /api/v1/profile/avatar` and `DELETE /api/v1/profile/header` to the REST API ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25124), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26573)) +- Add `ES_PRESET` option to customize numbers of shards and replicas ([Gargron](https://github.com/mastodon/mastodon/pull/26483), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26489)) + This can have a value of `single_node_cluster` (default), `small_cluster` (uses one replica) or `large_cluster` (uses one replica and a higher number of shards). +- Add `CACHE_BUSTER_HTTP_METHOD` environment variable ([renchap](https://github.com/mastodon/mastodon/pull/26528), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26542)) +- Add support for `DB_PASS` when using `DATABASE_URL` ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26295)) +- Add `GET /api/v1/instance/languages` to REST API ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24443)) +- Add primary key to `preview_cards_statuses` join table ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25243), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26384), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26447), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26737), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26979)) +- Add client-side timeout on resend confirmation button ([Gargron](https://github.com/mastodon/mastodon/pull/26300)) +- Add published date and author to news on the explore screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26155)) +- Add `lang` attribute to various UI components ([c960657](https://github.com/mastodon/mastodon/pull/23869), [c960657](https://github.com/mastodon/mastodon/pull/23891), [c960657](https://github.com/mastodon/mastodon/pull/26111), [c960657](https://github.com/mastodon/mastodon/pull/26149)) +- Add stricter protocol fields validation for accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25937)) +- Add support for Azure blob storage ([mistydemeo](https://github.com/mastodon/mastodon/pull/23607), [mistydemeo](https://github.com/mastodon/mastodon/pull/26080)) +- Add toast with option to open post after publishing in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25564), [Signez](https://github.com/mastodon/mastodon/pull/25919), [Gargron](https://github.com/mastodon/mastodon/pull/26664)) +- Add canonical link tags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25715)) +- Add button to see results for polls in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25726)) +- Add at-symbol prepended to mention span title ([forsamori](https://github.com/mastodon/mastodon/pull/25684)) +- Add users index on `unconfirmed_email` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25672), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25702)) +- Add superapp index on `oauth_applications` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25670)) +- Add index to backups on `user_id` column ([mjankowski](https://github.com/mastodon/mastodon/pull/25647)) +- Add onboarding prompt when home feed too slow in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25267), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25556), [Gargron](https://github.com/mastodon/mastodon/pull/25579), [renchap](https://github.com/mastodon/mastodon/pull/25580), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25581), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25617), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25917), [Gargron](https://github.com/mastodon/mastodon/pull/26829), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26935)) +- Add `POST /api/v1/conversations/:id/unread` API endpoint to mark a conversation as unread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25509)) +- Add `translate="no"` to outgoing mentions and links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25524)) +- Add unsubscribe link and headers to e-mails ([Gargron](https://github.com/mastodon/mastodon/pull/25378), [c960657](https://github.com/mastodon/mastodon/pull/26085)) +- Add logging of websocket send errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25280)) +- Add time zone preference ([Gargron](https://github.com/mastodon/mastodon/pull/25342), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26025)) +- Add `legal` as report category ([Gargron](https://github.com/mastodon/mastodon/pull/23941), [renchap](https://github.com/mastodon/mastodon/pull/25400), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26509)) +- Add `data-nosnippet` so Google doesn't use trending posts in snippets for `/` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25279)) +- Add card with who invited you to join when displaying rules on sign-up ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23475)) +- Add missing primary keys to `accounts_tags` and `statuses_tags` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25210)) +- Add support for custom sign-up URLs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25014), [renchap](https://github.com/mastodon/mastodon/pull/25108), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25190), [mgmn](https://github.com/mastodon/mastodon/pull/25531)) + This is set using `SSO_ACCOUNT_SIGN_UP` and reflected in the REST API by adding `registrations.sign_up_url` to the `/api/v2/instance` endpoint. +- Add polling and automatic redirection to `/start` on email confirmation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25013)) +- Add ability to block sign-ups from IP using the CLI ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24870)) +- Add ALT badges to media that has alternative text in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24782), [c960657](https://github.com/mastodon/mastodon/pull/26166) +- Add ability to include accounts with pending follow requests in lists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19727), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24810)) +- Add trend management to admin API ([rrgeorge](https://github.com/mastodon/mastodon/pull/24257)) + - `POST /api/v1/admin/trends/statuses/:id/approve` + - `POST /api/v1/admin/trends/statuses/:id/reject` + - `POST /api/v1/admin/trends/links/:id/approve` + - `POST /api/v1/admin/trends/links/:id/reject` + - `POST /api/v1/admin/trends/tags/:id/approve` + - `POST /api/v1/admin/trends/tags/:id/reject` + - `GET /api/v1/admin/trends/links/publishers` + - `POST /api/v1/admin/trends/links/publishers/:id/approve` + - `POST /api/v1/admin/trends/links/publishers/:id/reject` +- Add user handle to notification mail recipient address ([HeitorMC](https://github.com/mastodon/mastodon/pull/24240)) +- Add progress indicator to sign-up flow ([Gargron](https://github.com/mastodon/mastodon/pull/24545)) +- Add client-side validation for taken username in sign-up form ([Gargron](https://github.com/mastodon/mastodon/pull/24546)) +- Add `--approve` option to `tootctl accounts create` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24533)) +- Add “In Memoriam” banner back to profiles ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23591), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23614)) + This adds the `memorial` attribute to the `Account` REST API entity. +- Add colour to follow button when hashtag is being followed ([c960657](https://github.com/mastodon/mastodon/pull/24361)) +- Add further explanations to the profile link verification instructions ([drzax](https://github.com/mastodon/mastodon/pull/19723)) +- Add a link to Identity provider's account settings from the account settings ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24100), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24628)) +- Add support for streaming server to connect to postgres with self-signed certs through the `sslmode` URL parameter ([ramuuns](https://github.com/mastodon/mastodon/pull/21431)) +- Add support for specifying S3 storage classes through the `S3_STORAGE_CLASS` environment variable ([hyl](https://github.com/mastodon/mastodon/pull/22480)) +- Add support for incoming rich text ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23913)) +- Add support for Ruby 3.2 ([tenderlove](https://github.com/mastodon/mastodon/pull/22928), [casperisfine](https://github.com/mastodon/mastodon/pull/24142), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24202), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26934)) +- Add API parameter to safeguard unexpected mentions in new posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18350)) + +### Changed + +- **Change hashtags to be displayed separately when they are the last line of a post** ([renchap](https://github.com/mastodon/mastodon/pull/26499), [renchap](https://github.com/mastodon/mastodon/pull/26614), [renchap](https://github.com/mastodon/mastodon/pull/26615)) +- **Change reblogs to be excluded from "Posts and replies" tab in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/26302)) +- **Change interaction modal in web interface** ([Gargron, ClearlyClaire](https://github.com/mastodon/mastodon/pull/26075), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26269), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26268), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26267), [mgmn](https://github.com/mastodon/mastodon/pull/26459), [tribela](https://github.com/mastodon/mastodon/pull/26461), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26593), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26795)) +- **Change design of link previews in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/26136), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26151), [Gargron](https://github.com/mastodon/mastodon/pull/26153), [Gargron](https://github.com/mastodon/mastodon/pull/26250), [Gargron](https://github.com/mastodon/mastodon/pull/26287), [Gargron](https://github.com/mastodon/mastodon/pull/26286), [c960657](https://github.com/mastodon/mastodon/pull/26184)) +- **Change "direct message" nomenclature to "private mention" in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24248)) +- **Change translation feature to cover Content Warnings, poll options and media descriptions** ([c960657](https://github.com/mastodon/mastodon/pull/24175), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/25251), [c960657](https://github.com/mastodon/mastodon/pull/26168), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26452)) +- **Change account search to match by text when opted-in** ([jsgoldstein](https://github.com/mastodon/mastodon/pull/25599), [Gargron](https://github.com/mastodon/mastodon/pull/26378)) +- **Change import feature to be clearer, less error-prone and more reliable** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21054), [mgmn](https://github.com/mastodon/mastodon/pull/24874)) +- **Change local and federated timelines to be tabs of a single “Live feeds” column** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25641), [Gargron](https://github.com/mastodon/mastodon/pull/25683), [mgmn](https://github.com/mastodon/mastodon/pull/25694), [Plastikmensch](https://github.com/mastodon/mastodon/pull/26247), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26633)) +- **Change user archive export to be faster and more reliable, and export `.zip` archives instead of `.tar.gz` ones** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23360), [TheEssem](https://github.com/mastodon/mastodon/pull/25034)) +- **Change `mastodon-streaming` systemd unit files to be templated** ([e-nomem](https://github.com/mastodon/mastodon/pull/24751)) +- **Change `statsd` integration to disable sidekiq metrics by default** ([mjankowski](https://github.com/mastodon/mastodon/pull/25265), [mjankowski](https://github.com/mastodon/mastodon/pull/25336), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26310)) + This deprecates `statsd` support and disables the sidekiq integration unless `STATSD_SIDEKIQ` is set to `true`. + This is because the `nsa` gem is unmaintained, and its sidekiq integration is known to add very significant overhead. + Later versions of Mastodon will have other ways to get the same metrics. +- **Change replica support to native Rails adapter** ([krainboltgreene](https://github.com/mastodon/mastodon/pull/25693), [Gargron](https://github.com/mastodon/mastodon/pull/25849), [Gargron](https://github.com/mastodon/mastodon/pull/25874), [Gargron](https://github.com/mastodon/mastodon/pull/25851), [Gargron](https://github.com/mastodon/mastodon/pull/25977), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26074), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26326), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26386), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26856)) + This is a breaking change, dropping `makara` support, and requiring you to update your database configuration if you are using replicas. + To tell Mastodon to use a read replica, you can either set the `REPLICA_DB_NAME` environment variable (along with `REPLICA_DB_USER`, `REPLICA_DB_PASS`, `REPLICA_DB_HOST`, and `REPLICA_DB_PORT`, if they differ from the primary database), or the `REPLICA_DATABASE_URL` environment variable if your configuration is based on `DATABASE_URL`. +- Change DCT method used for JPEG encoding to float ([electroCutie](https://github.com/mastodon/mastodon/pull/26675)) +- Change from `node-redis` to `ioredis` for streaming ([gmemstr](https://github.com/mastodon/mastodon/pull/26581)) +- Change private statuses index to index without crutches ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26713)) +- Change video compression parameters ([Gargron](https://github.com/mastodon/mastodon/pull/26631), [Gargron](https://github.com/mastodon/mastodon/pull/26745), [Gargron](https://github.com/mastodon/mastodon/pull/26766), [Gargron](https://github.com/mastodon/mastodon/pull/26970)) +- Change admin e-mail notification settings to be their own settings group ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26596)) +- Change opacity of the delete icon in the search field to be more visible ([AntoninDelFabbro](https://github.com/mastodon/mastodon/pull/26449)) +- Change Account Search to prioritize username over display name ([jsgoldstein](https://github.com/mastodon/mastodon/pull/26623)) +- Change follow recommendation materialized view to be faster in most cases ([renchap, ClearlyClaire](https://github.com/mastodon/mastodon/pull/26545)) +- Change `robots.txt` to block GPTBot ([Foritus](https://github.com/mastodon/mastodon/pull/26396)) +- Change header of hashtag timelines in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26362), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26416)) +- Change streaming `/metrics` to include additional metrics ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26299), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26945)) +- Change indexing frequency from 5 minutes to 1 minute, add locks to schedulers ([Gargron](https://github.com/mastodon/mastodon/pull/26304)) +- Change column link to add a better keyboard focus indicator ([teeerevor](https://github.com/mastodon/mastodon/pull/26278)) +- Change poll form element colors to fit with the rest of the ui ([teeerevor](https://github.com/mastodon/mastodon/pull/26139), [teeerevor](https://github.com/mastodon/mastodon/pull/26162), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26164)) +- Change 'favourite' to 'favorite' for American English ([marekr](https://github.com/mastodon/mastodon/pull/24667), [gunchleoc](https://github.com/mastodon/mastodon/pull/26009), [nabijaczleweli](https://github.com/mastodon/mastodon/pull/26109)) +- Change ActivityStreams representation of suspended accounts to not use a blank `name` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25276)) +- Change focus UI for keyboard only input ([teeerevor](https://github.com/mastodon/mastodon/pull/25935), [Gargron](https://github.com/mastodon/mastodon/pull/26125), [Gargron](https://github.com/mastodon/mastodon/pull/26767)) +- Change thread view to scroll to the selected post rather than the post being replied to ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24685)) +- Change links in multi-column mode so tabs are open in single-column mode ([Signez](https://github.com/mastodon/mastodon/pull/25893), [Signez](https://github.com/mastodon/mastodon/pull/26070), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25973), [Signez](https://github.com/mastodon/mastodon/pull/26019), [Signez](https://github.com/mastodon/mastodon/pull/26759)) +- Change searching with `#` to include account index ([jsgoldstein](https://github.com/mastodon/mastodon/pull/25638)) +- Change label and design of sensitive and unavailable media in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25712), [Gargron](https://github.com/mastodon/mastodon/pull/26135), [Gargron](https://github.com/mastodon/mastodon/pull/26330)) +- Change button colors to increase hover/focus contrast and consistency ([teeerevor](https://github.com/mastodon/mastodon/pull/25677), [Gargron](https://github.com/mastodon/mastodon/pull/25679)) +- Change dropdown icon above compose form from ellipsis to bars in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25661)) +- Change header backgrounds to use fewer different colors in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25577)) +- Change files to be deleted in batches instead of one-by-one ([Gargron](https://github.com/mastodon/mastodon/pull/23302), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/25586), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25587)) +- Change emoji picker icon ([iparr](https://github.com/mastodon/mastodon/pull/25479)) +- Change edit profile page ([Gargron](https://github.com/mastodon/mastodon/pull/25413), [c960657](https://github.com/mastodon/mastodon/pull/26538)) +- Change "bot" label to "automated" ([Gargron](https://github.com/mastodon/mastodon/pull/25356)) +- Change design of dropdowns in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25107)) +- Change wording of “Content cache retention period” setting to highlight destructive implications ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23261)) +- Change autolinking to allow carets in URL search params ([renchap](https://github.com/mastodon/mastodon/pull/25216)) +- Change share action from being in action bar to being in dropdown in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25105)) +- Change sessions to be ordered from most-recent to least-recently updated ([frankieroberto](https://github.com/mastodon/mastodon/pull/25005)) +- Change vacuum scheduler to also delete expired tokens and unused application records ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24868), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24871)) +- Change "Sign in" to "Login" ([Gargron](https://github.com/mastodon/mastodon/pull/24942)) +- Change domain suspensions to also be checked before trying to fetch unknown remote resources ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24535)) +- Change media components to use aspect-ratio rather than compute height themselves ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24686), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24943), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26801)) +- Change logo version in header based on screen size in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24707)) +- Change label from "For you" to "People" on explore screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24706)) +- Change logged-out WebUI HTML pages to be cached for a few seconds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24708)) +- Change unauthenticated responses to be cached in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/24348), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24662), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24665)) +- Change HTTP caching logic ([Gargron](https://github.com/mastodon/mastodon/pull/24347), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24604)) +- Change hashtags and mentions in bios to open in-app in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24643)) +- Change styling of the recommended accounts to allow bio to be more visible ([chike00](https://github.com/mastodon/mastodon/pull/24480)) +- Change account search in moderation interface to allow searching by username including the leading `@` ([HeitorMC](https://github.com/mastodon/mastodon/pull/24242)) +- Change all components to use the same error page in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24512)) +- Change search pop-out in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24305)) +- Change user settings to be stored in a more optimal way ([Gargron](https://github.com/mastodon/mastodon/pull/23630), [c960657](https://github.com/mastodon/mastodon/pull/24321), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24453), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24460), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24558), [Gargron](https://github.com/mastodon/mastodon/pull/24761), [Gargron](https://github.com/mastodon/mastodon/pull/24783), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25508), [jsgoldstein](https://github.com/mastodon/mastodon/pull/25340), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26884), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27012)) +- Change media upload limits and remove client-side resizing ([Gargron](https://github.com/mastodon/mastodon/pull/23726)) +- Change design of account rows in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24247), [Gargron](https://github.com/mastodon/mastodon/pull/24343), [Gargron](https://github.com/mastodon/mastodon/pull/24956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25131)) +- Change log-out to use Single Logout when using external log-in through OIDC ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24020)) +- Change sidekiq-bulk's batch size from 10,000 to 1,000 jobs in one Redis call ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24034)) +- Change translation to only be offered for supported languages ([c960657](https://github.com/mastodon/mastodon/pull/23879), [c960657](https://github.com/mastodon/mastodon/pull/24037)) + This adds the `/api/v1/instance/translation_languages` REST API endpoint that returns an object with the supported translation language pairs in the form: + ```json + { + "fr": ["en", "de"] + } + ``` + (where `fr` is a supported source language and `en` and `de` or supported output language when translating a `fr` string) +- Change compose form checkbox to native input with `appearance: none` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22949)) +- Change posts' clickable area to be larger ([c960657](https://github.com/mastodon/mastodon/pull/23621)) +- Change `followed_by` link to `location=all` if account is local on /admin/accounts/:id page ([tribela](https://github.com/mastodon/mastodon/pull/23467)) + +### Removed + +- **Remove support for Node.js 14** ([renchap](https://github.com/mastodon/mastodon/pull/25198)) +- **Remove support for Ruby 2.7** ([nschonni](https://github.com/mastodon/mastodon/pull/24237)) +- **Remove clustering from streaming API** ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/24655)) +- **Remove anonymous access to the streaming API** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23989)) +- Remove obfuscation of reply count in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26768)) +- Remove `kmr` from language selection, as it was a duplicate for `ku` ([gunchleoc](https://github.com/mastodon/mastodon/pull/26014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26787)) +- Remove 16:9 cropping from web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26132)) +- Remove back button from bookmarks, favourites and lists screens in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26126)) +- Remove display name input from sign-up form ([Gargron](https://github.com/mastodon/mastodon/pull/24704)) +- Remove `tai` locale ([c960657](https://github.com/mastodon/mastodon/pull/23880)) +- Remove empty Kushubian (csb) local files ([nschonni](https://github.com/mastodon/mastodon/pull/24151)) +- Remove `Permissions-Policy` header from all responses ([Gargron](https://github.com/mastodon/mastodon/pull/24124)) + +### Fixed + +- **Fix filters not being applying in the explore page** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25887)) +- **Fix being unable to load past a full page of filtered posts in Home timeline** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24930)) +- **Fix log-in flow when involving both OAuth and external authentication** ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24073)) +- **Fix broken links in account gallery** ([c960657](https://github.com/mastodon/mastodon/pull/24218)) +- **Fix migration handler not updating lists** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24808)) +- Fix crash when viewing a moderation appeal and the moderator account has been deleted ([xrobau](https://github.com/mastodon/mastodon/pull/25900)) +- Fix error in Web UI when server rules cannot be fetched ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26957)) +- Fix paragraph margins resulting in irregular read-more cut-off in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26828)) +- Fix notification permissions being requested immediately after login ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26472)) +- Fix performances of profile directory ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26840), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26842)) +- Fix mute button and volume slider feeling disconnected in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26827), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26860)) +- Fix “Scoped order is ignored, it's forced to be batch order.” warnings ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26793)) +- Fix blocked domain appearing in account feeds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26823)) +- Fix invalid `Content-Type` header for WebP images ([c960657](https://github.com/mastodon/mastodon/pull/26773)) +- Fix minor inefficiencies in `tootctl search deploy` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26721)) +- Fix filter form in profiles directory overflowing instead of wrapping ([arbolitoloco1](https://github.com/mastodon/mastodon/pull/26682)) +- Fix sign up steps progress layout in right-to-left locales ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26728)) +- Fix bug with “favorited by” and “reblogged by“ view on posts only showing up to 40 items ([timothyjrogers](https://github.com/mastodon/mastodon/pull/26577), [timothyjrogers](https://github.com/mastodon/mastodon/pull/26574)) +- Fix bad search type heuristic ([Gargron](https://github.com/mastodon/mastodon/pull/26673)) +- Fix not being able to negate prefix clauses in search ([Gargron](https://github.com/mastodon/mastodon/pull/26672)) +- Fix timeout on invalid set of exclusionary parameters in `/api/v1/timelines/public` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/26239)) +- Fix adding column with default value taking longer on Postgres >= 11 ([Gargron](https://github.com/mastodon/mastodon/pull/26375)) +- Fix light theme select option for hashtags ([teeerevor](https://github.com/mastodon/mastodon/pull/26311)) +- Fix AVIF attachments ([c960657](https://github.com/mastodon/mastodon/pull/26264)) +- Fix incorrect URL normalization when fetching remote resources ([c960657](https://github.com/mastodon/mastodon/pull/26219), [c960657](https://github.com/mastodon/mastodon/pull/26285)) +- Fix being unable to filter posts for individual Chinese languages ([gunchleoc](https://github.com/mastodon/mastodon/pull/26066)) +- Fix preview card sometimes linking to 4xx error pages ([c960657](https://github.com/mastodon/mastodon/pull/26200)) +- Fix emoji picker button scrolling with textarea content in single-column view ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25304)) +- Fix missing border on error screen in light theme in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26152)) +- Fix UI overlap with the loupe icon in the Explore Tab ([gol-cha](https://github.com/mastodon/mastodon/pull/26113)) +- Fix unexpected redirection to `/explore` after sign-in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26143)) +- Fix `/api/v1/statuses/:id/unfavourite` and `/api/v1/statuses/:id/unreblog` returning non-updated counts ([c960657](https://github.com/mastodon/mastodon/pull/24365)) +- Fix clicking the “Back” button sometimes leading out of Mastodon ([c960657](https://github.com/mastodon/mastodon/pull/23953), [CSFlorin](https://github.com/mastodon/mastodon/pull/24835), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/24867), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25281)) +- Fix processing of `null` ActivityPub activities ([tribela](https://github.com/mastodon/mastodon/pull/26021)) +- Fix hashtag posts not being removed from home feed on hashtag unfollow ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26028)) +- Fix for "follows you" indicator in light web UI not readable ([vmstan](https://github.com/mastodon/mastodon/pull/25993)) +- Fix incorrect line break between icon and number of reposts & favourites ([edent](https://github.com/mastodon/mastodon/pull/26004)) +- Fix sounds not being loaded from assets host ([Signez](https://github.com/mastodon/mastodon/pull/25931)) +- Fix buttons showing inconsistent styles ([teeerevor](https://github.com/mastodon/mastodon/pull/25903), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25965), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26341), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26482)) +- Fix trend calculation working on too many items at a time ([Gargron](https://github.com/mastodon/mastodon/pull/25835)) +- Fix dropdowns being disabled for logged out users in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25714), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25964)) +- Fix explore page being inaccessible when opted-out of trends in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25716)) +- Fix re-activated accounts possibly getting deleted by `AccountDeletionWorker` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25711)) +- Fix `/api/v2/search` not working with following query param ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25681)) +- Fix inefficient query when requesting a new confirmation email from a logged-in account ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25669)) +- Fix unnecessary concurrent calls to `/api/*/instance` in web UI ([mgmn](https://github.com/mastodon/mastodon/pull/25663)) +- Fix resolving local URL for remote content ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25637)) +- Fix search not being easily findable on smaller screens in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25576), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25631)) +- Fix j/k keyboard shortcuts on some status lists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25554)) +- Fix missing validation on `default_privacy` setting ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25513)) +- Fix incorrect pagination headers in `/api/v2/admin/accounts` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25477)) +- Fix non-interactive upload container being given a `button` role and tabIndex ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25462)) +- Fix always redirecting to onboarding in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25396)) +- Fix inconsistent use of middle dot (·) instead of bullet (•) to separate items ([j-f1](https://github.com/mastodon/mastodon/pull/25248)) +- Fix spacing of middle dots in the detailed status meta section ([j-f1](https://github.com/mastodon/mastodon/pull/25247)) +- Fix prev/next buttons color in media viewer ([renchap](https://github.com/mastodon/mastodon/pull/25231)) +- Fix email addresses not being properly updated in `tootctl maintenance fix-duplicates` ([mjankowski](https://github.com/mastodon/mastodon/pull/25118)) +- Fix unicode surrogate pairs sometimes being broken in page title ([eai04191](https://github.com/mastodon/mastodon/pull/25148)) +- Fix various inefficient queries against account domains ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25126)) +- Fix video player offering to expand in a lightbox when it's in an `iframe` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25067)) +- Fix post embed previews ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25071)) +- Fix inadequate error handling in several API controllers when given invalid parameters ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24947), [danielmbrasil](https://github.com/mastodon/mastodon/pull/24958), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25063), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25072), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25386), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25595)) +- Fix uncaught `ActiveRecord::StatementInvalid` in Mastodon::IpBlocksCLI ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24861)) +- Fix various edge cases with local moves ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24812)) +- Fix `tootctl accounts cull` crashing when encountering a domain resolving to a private address ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23378)) +- Fix `tootctl accounts approve --number N` not aproving the N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605)) +- Fix being unable to clear media description when editing posts ([c960657](https://github.com/mastodon/mastodon/pull/24720)) +- Fix unavailable translations not falling back to English ([mgmn](https://github.com/mastodon/mastodon/pull/24727)) +- Fix anonymous visitors getting a session cookie on first visit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24584), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24650), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24664)) +- Fix cutting off first letter of hashtag links sometimes in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24623)) +- Fix crash in `tootctl accounts create --reattach --force` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24557), [danielmbrasil](https://github.com/mastodon/mastodon/pull/24680)) +- Fix characters being emojified even when using Variation Selector 15 (text) ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20949), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24615)) +- Fix uncaught ActiveRecord::StatementInvalid exception in `Mastodon::AccountsCLI#approve` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24590)) +- Fix email confirmation skip option in `tootctl accounts modify USERNAME --email EMAIL --confirm` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24578)) +- Fix tooltip for dates without time ([c960657](https://github.com/mastodon/mastodon/pull/24244)) +- Fix missing loading spinner and loading more on scroll in Private Mentions column ([c960657](https://github.com/mastodon/mastodon/pull/24446)) +- Fix account header image missing from `/settings/profile` on narrow screens ([c960657](https://github.com/mastodon/mastodon/pull/24433)) +- Fix height of announcements not being updated when using reduced animations ([c960657](https://github.com/mastodon/mastodon/pull/24354)) +- Fix inconsistent radius in advanced interface drawer ([thislight](https://github.com/mastodon/mastodon/pull/24407)) +- Fix loading more trending posts on scroll in the advanced interface ([OmmyZhang](https://github.com/mastodon/mastodon/pull/24314)) +- Fix poll ending notification for edited polls ([c960657](https://github.com/mastodon/mastodon/pull/24311)) +- Fix max width of media in `/about` and `/privacy-policy` ([mgmn](https://github.com/mastodon/mastodon/pull/24180)) +- Fix streaming API not being usable without `DATABASE_URL` ([Gargron](https://github.com/mastodon/mastodon/pull/23960)) +- Fix external authentication not running onboarding code for new users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23458)) + +## [4.1.8] - 2023-09-19 + +### Fixed + +- Fix post edits not being forwarded as expected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26936)) +- Fix moderator rights inconsistencies ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26729)) +- Fix crash when encountering invalid URL ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26814)) +- Fix cached posts including stale stats ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26409)) +- Fix uploading of video files for which `ffprobe` reports `0/0` average framerate ([NicolaiSoeborg](https://github.com/mastodon/mastodon/pull/26500)) +- Fix unexpected audio stream transcoding when uploaded video is eligible to passthrough ([yufushiro](https://github.com/mastodon/mastodon/pull/26608)) + +### Security + +- Fix missing HTML sanitization in translation API (CVE-2023-42452, [GHSA-2693-xr3m-jhqr](https://github.com/mastodon/mastodon/security/advisories/GHSA-2693-xr3m-jhqr)) +- Fix incorrect domain name normalization (CVE-2023-42451, [GHSA-v3xf-c9qf-j667](https://github.com/mastodon/mastodon/security/advisories/GHSA-v3xf-c9qf-j667)) + +## [4.1.7] - 2023-09-05 + +### Changed + +- Change remote report processing to accept reports with long comments, but truncate them ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25028)) + +### Fixed + +- **Fix blocking subdomains of an already-blocked domain** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26392)) +- Fix `/api/v1/timelines/tag/:hashtag` allowing for unauthenticated access when public preview is disabled ([danielmbrasil](https://github.com/mastodon/mastodon/pull/26237)) +- Fix inefficiencies in `PlainTextFormatter` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26727)) + +## [4.1.6] - 2023-07-31 + +### Fixed + +- Fix memory leak in streaming server ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26228)) +- Fix wrong filters sometimes applying in streaming ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26159), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26213), [renchap](https://github.com/mastodon/mastodon/pull/26233)) +- Fix incorrect connect timeout in outgoing requests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26116)) + +## [4.1.5] - 2023-07-21 + +### Added + +- Add check preventing Sidekiq workers from running with Makara configured ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25850)) + +### Changed + +- Change request timeout handling to use a longer deadline ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26055)) + +### Fixed + +- Fix moderation interface for remote instances with a .zip TLD ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25885)) +- Fix remote accounts being possibly persisted to database with incomplete protocol values ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25886)) +- Fix trending publishers table not rendering correctly on narrow screens ([vmstan](https://github.com/mastodon/mastodon/pull/25945)) + +### Security + +- Fix CSP headers being unintentionally wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26105)) + +## [4.1.4] - 2023-07-07 + +### Fixed + +- Fix branding:generate_app_icons failing because of disallowed ICO coder ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25794)) +- Fix crash in admin interface when viewing a remote user with verified links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25796)) +- Fix processing of media files with unusual names ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25788)) + ## [4.1.3] - 2023-07-06 ### Added @@ -30,7 +385,7 @@ All notable changes to this project will be documented in this file. - Fix multiple inefficiencies in automatic post cleanup worker ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24607), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24785), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24840)) - Fix performance of streaming by parsing message JSON once ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25278), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25361)) - Fix CSP headers when `S3_ALIAS_HOST` includes a path component ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25273)) -- Fix `tootctl accounts approve --number N` not aproving N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605)) +- Fix `tootctl accounts approve --number N` not approving N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605)) - Fix reports not being closed when performing batch suspensions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24988)) - Fix being able to vote on your own polls ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25015)) - Fix race condition when reblogging a status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25016)) @@ -136,7 +491,7 @@ All notable changes to this project will be documented in this file. - Add instance activity API endpoint toggle back to the admin interface ([dariusk](https://github.com/mastodon/mastodon/pull/22833)) - Add setting for status page URL ([Gargron](https://github.com/mastodon/mastodon/pull/23390), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23499)) - REST API changes: - - Add `configuration.urls.status` attribute to the object returned by `GET /api/v1/instance` + - Add `configuration.urls.status` attribute to the object returned by `GET /api/v2/instance` - Add `account.approved` webhook ([Saiv46](https://github.com/mastodon/mastodon/pull/22938)) - Add 12 hours option to polls ([Pleclown](https://github.com/mastodon/mastodon/pull/21131)) - Add dropdown menu item to open admin interface for remote domains ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21895)) @@ -332,6 +687,7 @@ All notable changes to this project will be documented in this file. - Fix unbounded recursion in post discovery ([ClearlyClaire,nametoolong](https://github.com/mastodon/mastodon/pull/23506)) ## [4.0.2] - 2022-11-15 + ### Fixed - Fix wrong color on mentions hidden behind content warning in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20724)) @@ -339,6 +695,7 @@ All notable changes to this project will be documented in this file. - Fix `unsafe-eval` being used when `wasm-unsafe-eval` is enough in Content Security Policy ([Gargron](https://github.com/mastodon/mastodon/pull/20729), [prplecake](https://github.com/mastodon/mastodon/pull/20606)) ## [4.0.1] - 2022-11-14 + ### Fixed - Fix nodes order being sometimes mangled when rewriting emoji ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20677)) @@ -542,6 +899,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix out-of-bound reads in blurhash transcoder ([delroth](https://github.com/mastodon/mastodon/pull/20388)) ## [3.5.3] - 2022-05-26 + ### Added - **Add language dropdown to compose form in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/18420), [ykzts](https://github.com/mastodon/mastodon/pull/18460)) @@ -589,6 +947,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix confirmation redirect to app without `Location` header ([Gargron](https://github.com/mastodon/mastodon/pull/18523)) ## [3.5.2] - 2022-05-04 + ### Added - Add warning on direct messages screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/18289)) @@ -641,6 +1000,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix error in alias settings page ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18004)) ## [3.5.1] - 2022-04-08 + ### Added - Add pagination for trending statuses in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/17976)) @@ -684,6 +1044,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix error when indexing statuses into Elasticsearch ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17912)) ## [3.5.0] - 2022-03-30 + ### Added - **Add support for incoming edited posts** ([Gargron](https://github.com/mastodon/mastodon/pull/16697), [Gargron](https://github.com/mastodon/mastodon/pull/17727), [Gargron](https://github.com/mastodon/mastodon/pull/17728), [Gargron](https://github.com/mastodon/mastodon/pull/17320), [Gargron](https://github.com/mastodon/mastodon/pull/17404), [Gargron](https://github.com/mastodon/mastodon/pull/17390), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17335), [Gargron](https://github.com/mastodon/mastodon/pull/17696), [Gargron](https://github.com/mastodon/mastodon/pull/17745), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17740), [Gargron](https://github.com/mastodon/mastodon/pull/17697), [Gargron](https://github.com/mastodon/mastodon/pull/17648), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17531), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17499), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17498), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17380), [Gargron](https://github.com/mastodon/mastodon/pull/17373), [Gargron](https://github.com/mastodon/mastodon/pull/17334), [Gargron](https://github.com/mastodon/mastodon/pull/17333), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17699), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17748)) @@ -883,6 +1244,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix being able to bypass e-mail restrictions ([Gargron](https://github.com/mastodon/mastodon/pull/17909)) ## [3.4.6] - 2022-02-03 + ### Fixed - Fix `mastodon:webpush:generate_vapid_key` task requiring a functional environment ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17338)) @@ -897,6 +1259,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Disable legacy XSS filtering ([Wonderfall](https://github.com/mastodon/mastodon/pull/17289)) ## [3.4.5] - 2022-01-31 + ### Added - Add more advanced migration tests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17393)) @@ -911,6 +1274,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix followers synchronization mechanism ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16510)) ## [3.4.4] - 2021-11-26 + ### Fixed - Fix error when suspending user with an already blocked canonical email ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17036)) @@ -928,11 +1292,13 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix handling of recursive toots in WebUI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17041)) ## [3.4.3] - 2021-11-06 + ### Fixed - Fix login being broken due to inaccurately applied backport fix in 3.4.2 ([Gargron](https://github.com/mastodon/mastodon/commit/5c47a18c8df3231aa25c6d1f140a71a7fac9cbf9)) ## [3.4.2] - 2021-11-06 + ### Added - Add `configuration` attribute to `GET /api/v1/instance` ([Gargron](https://github.com/mastodon/mastodon/pull/16485)) @@ -976,6 +1342,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix revoking a specific session not working ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16943)) ## [3.4.1] - 2021-06-03 + ### Added - Add new emoji assets from Twemoji 13.1.0 ([Gargron](https://github.com/mastodon/mastodon/pull/16345)) @@ -995,6 +1362,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix mailer jobs for deleted notifications erroring out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/16294)) ## [3.4.0] - 2021-05-16 + ### Added - **Add follow recommendations for onboarding** ([Gargron](https://github.com/mastodon/mastodon/pull/15945), [Gargron](https://github.com/mastodon/mastodon/pull/16161), [Gargron](https://github.com/mastodon/mastodon/pull/16060), [Gargron](https://github.com/mastodon/mastodon/pull/16077), [Gargron](https://github.com/mastodon/mastodon/pull/16078), [Gargron](https://github.com/mastodon/mastodon/pull/16160), [Gargron](https://github.com/mastodon/mastodon/pull/16079), [noellabo](https://github.com/mastodon/mastodon/pull/16044), [noellabo](https://github.com/mastodon/mastodon/pull/16045), [Gargron](https://github.com/mastodon/mastodon/pull/16152), [Gargron](https://github.com/mastodon/mastodon/pull/16153), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/16082), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/16173), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/16159), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/16189)) @@ -1030,7 +1398,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - This method allows an app through which a user signed-up to request a new confirmation e-mail to be sent, or to change the e-mail of the account before it is confirmed - Add `GET /api/v1/accounts/lookup` to REST API ([Gargron](https://github.com/mastodon/mastodon/pull/15740), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/15750)) - This method allows to quickly convert a username of a known account to an ID that can be used with the REST API, or to check if a username is available - for sign-up + for sign-up - Add `policy` param to `POST /api/v1/push/subscriptions` in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/16040)) - This param allows an app to control from whom notifications should be delivered as push notifications to the app - Add `details` to error response for `POST /api/v1/accounts` in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/15803)) @@ -1140,6 +1508,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix app name, website and redirect URIs not having a maximum length ([Gargron](https://github.com/mastodon/mastodon/pull/16042)) ## [3.3.0] - 2020-12-27 + ### Added - **Add hotkeys for audio/video control in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/15158), [Gargron](https://github.com/mastodon/mastodon/pull/15198)) @@ -1316,6 +1685,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix resolving accounts sometimes creating duplicate records for a given ActivityPub identifier ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/15364)) ## [3.2.2] - 2020-12-19 + ### Added - Add `tootctl maintenance fix-duplicates` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14860), [Gargron](https://github.com/mastodon/mastodon/pull/15223)) @@ -1342,6 +1712,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix resolving accounts sometimes creating duplicate records for a given ActivityPub identifier ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/15364)) ## [3.2.1] - 2020-10-19 + ### Added - Add support for latest HTTP Signatures spec draft ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14556)) @@ -1371,6 +1742,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix files served as `application/octet-stream` being rejected without attempting mime type detection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14452)) ## [3.2.0] - 2020-07-27 + ### Added - Add `SMTP_SSL` environment variable ([OmmyZhang](https://github.com/mastodon/mastodon/pull/14309)) @@ -1506,7 +1878,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix unique username constraint for local users not being enforced in database ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14099)) - Fix unnecessary gap under video modal in web UI ([mfmfuyu](https://github.com/mastodon/mastodon/pull/14098)) - Fix 2FA and sign in token pages not respecting user locale ([mfmfuyu](https://github.com/mastodon/mastodon/pull/14087)) -- Fix unapproved users being able to view profiles when in limited-federation mode *and* requiring approval for sign-ups ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14093)) +- Fix unapproved users being able to view profiles when in limited-federation mode _and_ requiring approval for sign-ups ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14093)) - Fix initial audio volume not corresponding to what's displayed in audio player in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14057)) - Fix timelines sometimes jumping when closing modals in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14019)) - Fix memory usage of downloading remote files ([Gargron](https://github.com/mastodon/mastodon/pull/14184), [Gargron](https://github.com/mastodon/mastodon/pull/14181), [noellabo](https://github.com/mastodon/mastodon/pull/14356)) @@ -1524,6 +1896,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Clear out media attachments in a separate worker (slow) ## [3.1.5] - 2020-07-07 + ### Security - Fix media attachment enumeration ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/14254)) @@ -1531,6 +1904,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix other sessions not being logged out on password change ([Gargron](https://github.com/mastodon/mastodon/pull/14252)) ## [3.1.4] - 2020-05-14 + ### Added - Add `vi` to available locales ([taicv](https://github.com/mastodon/mastodon/pull/13542)) @@ -1569,7 +1943,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix regression in `tootctl media remove-orphans` ([Gargron](https://github.com/mastodon/mastodon/pull/13405)) - Fix old unique jobs digests not having been cleaned up ([Gargron](https://github.com/mastodon/mastodon/pull/13683)) - Fix own following/followers not showing muted users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/13614)) -- Fix list of followed people ignoring sorting on Follows & Followers page ([taras2358](https://github.com/mastodon/mastodon/pull/13676)) +- Fix list of followed people ignoring sorting on Follows & Followers page ([taras2358](https://github.com/mastodon/mastodon/pull/13676)) - Fix wrong pgHero Content-Security-Policy when `CDN_HOST` is set ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/13595)) - Fix needlessly deduplicating usernames on collisions with remote accounts when signing-up through SAML/CAS ([kaiyou](https://github.com/mastodon/mastodon/pull/13581)) - Fix page incorrectly scrolling when bringing up dropdown menus in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/13574)) @@ -1598,6 +1972,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - The issue only affects developers of apps who are shared between multiple users, such as server-side apps like cross-posters ## [3.1.3] - 2020-04-05 + ### Added - Add ability to filter audit log in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/13381)) @@ -1671,6 +2046,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix re-sending of e-mail confirmation not being rate limited ([Gargron](https://github.com/mastodon/mastodon/pull/13360)) ## [v3.1.2] - 2020-02-27 + ### Added - Add `--reset-password` option to `tootctl accounts modify` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/13126)) @@ -1697,11 +2073,13 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix leak of arbitrary statuses through unfavourite action in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/13161)) ## [3.1.1] - 2020-02-10 + ### Fixed - Fix yanked dependency preventing installation ([mayaeh](https://github.com/mastodon/mastodon/pull/13059)) ## [3.1.0] - 2020-02-09 + ### Added - Add bookmarks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/7107), [Gargron](https://github.com/mastodon/mastodon/pull/12494), [Gomasy](https://github.com/mastodon/mastodon/pull/12381)) @@ -1866,6 +2244,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix settings pages being cacheable by the browser ([Gargron](https://github.com/mastodon/mastodon/pull/12714)) ## [3.0.1] - 2019-10-10 + ### Added - Add `tootctl media usage` command ([Gargron](https://github.com/mastodon/mastodon/pull/12115)) @@ -1899,6 +2278,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix `tootctl accounts cull` advertising unused option flag ([Kjwon15](https://github.com/mastodon/mastodon/pull/12074)) ## [3.0.0] - 2019-10-03 + ### Added - Add "not available" label to unloaded media attachments in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/11715), [Gargron](https://github.com/mastodon/mastodon/pull/11745)) @@ -2095,6 +2475,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix performance of GIF re-encoding and always strip EXIF data from videos ([Gargron](https://github.com/mastodon/mastodon/pull/12057)) ## [2.9.3] - 2019-08-10 + ### Added - Add GIF and WebP support for custom emojis ([Gargron](https://github.com/mastodon/mastodon/pull/11519)) @@ -2154,6 +2535,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix blocked domains still being able to fill database with account records ([Gargron](https://github.com/mastodon/mastodon/pull/11219)) ## [2.9.2] - 2019-06-22 + ### Added - Add `short_description` and `approval_required` to `GET /api/v1/instance` ([Gargron](https://github.com/mastodon/mastodon/pull/11146)) @@ -2168,6 +2550,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix audio not being downloaded from remote servers ([Gargron](https://github.com/mastodon/mastodon/pull/11145)) ## [2.9.1] - 2019-06-22 + ### Added - Add moderation API ([Gargron](https://github.com/mastodon/mastodon/pull/9387)) @@ -2193,6 +2576,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix scrolling behaviour in compose form ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/11093)) ## [2.9.0] - 2019-06-13 + ### Added - **Add single-column mode in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/10807), [Gargron](https://github.com/mastodon/mastodon/pull/10848), [Gargron](https://github.com/mastodon/mastodon/pull/11003), [Gargron](https://github.com/mastodon/mastodon/pull/10961), [Hanage999](https://github.com/mastodon/mastodon/pull/10915), [noellabo](https://github.com/mastodon/mastodon/pull/10917), [abcang](https://github.com/mastodon/mastodon/pull/10859), [Gargron](https://github.com/mastodon/mastodon/pull/10820), [Gargron](https://github.com/mastodon/mastodon/pull/10835), [Gargron](https://github.com/mastodon/mastodon/pull/10809), [Gargron](https://github.com/mastodon/mastodon/pull/10963), [noellabo](https://github.com/mastodon/mastodon/pull/10883), [Hanage999](https://github.com/mastodon/mastodon/pull/10839)) @@ -2247,6 +2631,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix login sometimes redirecting to paths that are not pages ([Gargron](https://github.com/mastodon/mastodon/pull/11019)) ## [2.8.4] - 2019-05-24 + ### Fixed - Fix delivery not retrying on some inbox errors that should be retriable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10812)) @@ -2258,6 +2643,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Require specific OAuth scopes for specific endpoints of the streaming API, instead of merely requiring a token for all endpoints, and allow using WebSockets protocol negotiation to specify the access token instead of using a query string ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10818)) ## [2.8.3] - 2019-05-19 + ### Added - Add `og:image:alt` OpenGraph tag ([BenLubar](https://github.com/mastodon/mastodon/pull/10779)) @@ -2280,6 +2666,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix "invited by" not showing up in admin UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10791)) ## [2.8.2] - 2019-05-05 + ### Added - Add `SOURCE_TAG` environment variable ([ushitora-anqou](https://github.com/mastodon/mastodon/pull/10698)) @@ -2292,6 +2679,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix closing video modal scrolling timelines to top ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10695)) ## [2.8.1] - 2019-05-04 + ### Added - Add link to existing domain block when trying to block an already-blocked domain ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10663)) @@ -2331,6 +2719,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix confirmation modals being too narrow for a secondary action button ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10586)) ## [2.8.0] - 2019-04-10 + ### Added - Add polls ([Gargron](https://github.com/mastodon/mastodon/pull/10111), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10155), [Gargron](https://github.com/mastodon/mastodon/pull/10184), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10196), [Gargron](https://github.com/mastodon/mastodon/pull/10248), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10255), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10322), [Gargron](https://github.com/mastodon/mastodon/pull/10138), [Gargron](https://github.com/mastodon/mastodon/pull/10139), [Gargron](https://github.com/mastodon/mastodon/pull/10144), [Gargron](https://github.com/mastodon/mastodon/pull/10145),[Gargron](https://github.com/mastodon/mastodon/pull/10146), [Gargron](https://github.com/mastodon/mastodon/pull/10148), [Gargron](https://github.com/mastodon/mastodon/pull/10151), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10150), [Gargron](https://github.com/mastodon/mastodon/pull/10168), [Gargron](https://github.com/mastodon/mastodon/pull/10165), [Gargron](https://github.com/mastodon/mastodon/pull/10172), [Gargron](https://github.com/mastodon/mastodon/pull/10170), [Gargron](https://github.com/mastodon/mastodon/pull/10171), [Gargron](https://github.com/mastodon/mastodon/pull/10186), [Gargron](https://github.com/mastodon/mastodon/pull/10189), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10200), [rinsuki](https://github.com/mastodon/mastodon/pull/10203), [Gargron](https://github.com/mastodon/mastodon/pull/10213), [Gargron](https://github.com/mastodon/mastodon/pull/10246), [Gargron](https://github.com/mastodon/mastodon/pull/10265), [Gargron](https://github.com/mastodon/mastodon/pull/10261), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10333), [Gargron](https://github.com/mastodon/mastodon/pull/10352), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10140), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10142), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10141), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10162), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10161), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10158), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10156), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10160), [Gargron](https://github.com/mastodon/mastodon/pull/10185), [Gargron](https://github.com/mastodon/mastodon/pull/10188), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10195), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10208), [Gargron](https://github.com/mastodon/mastodon/pull/10187), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10214), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/10209)) @@ -2414,6 +2803,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix `tootctl accounts cull` sometimes removing accounts that are temporarily unreachable ([BenLubar](https://github.com/mastodon/mastodon/pull/10460)) ## [2.7.4] - 2019-03-05 + ### Fixed - Fix web UI not cleaning up notifications after block ([Gargron](https://github.com/mastodon/mastodon/pull/10108)) @@ -2428,6 +2818,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix edit profile page crash for suspended-then-unsuspended users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10178)) ## [2.7.3] - 2019-02-23 + ### Added - Add domain filter to the admin federation page ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/10071)) @@ -2445,6 +2836,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Change custom emojis to randomize stored file name ([hinaloe](https://github.com/mastodon/mastodon/pull/10090)) ## [2.7.2] - 2019-02-17 + ### Added - Add support for IPv6 in e-mail validation ([zoc](https://github.com/mastodon/mastodon/pull/10009)) @@ -2486,6 +2878,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Change error graphic to hover-to-play ([Gargron](https://github.com/mastodon/mastodon/pull/10055)) ## [2.7.1] - 2019-01-28 + ### Fixed - Fix SSO authentication not working due to missing agreement boolean ([Gargron](https://github.com/mastodon/mastodon/pull/9915)) @@ -2500,6 +2893,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix missing strong style for landing page description ([Kjwon15](https://github.com/mastodon/mastodon/pull/9892)) ## [2.7.0] - 2019-01-20 + ### Added - Add link for adding a user to a list from their profile ([namelessGonbai](https://github.com/mastodon/mastodon/pull/9062)) @@ -2629,6 +3023,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Add tombstones for remote statuses to prevent replay attacks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/9830)) ## [2.6.5] - 2018-12-01 + ### Changed - Change lists to display replies to others on the list and list owner ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/9324)) @@ -2638,11 +3033,13 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix failures caused by commonly-used JSON-LD contexts being unavailable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/9412)) ## [2.6.4] - 2018-11-30 + ### Fixed - Fix yarn dependencies not installing due to yanked event-stream package ([Gargron](https://github.com/mastodon/mastodon/pull/9401)) ## [2.6.3] - 2018-11-30 + ### Added - Add hyphen to characters allowed in remote usernames ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/9345)) @@ -2662,6 +3059,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix TLS handshake timeout not being enforced ([Gargron](https://github.com/mastodon/mastodon/pull/9381)) ## [2.6.2] - 2018-11-23 + ### Added - Add Page to whitelisted ActivityPub types ([mbajur](https://github.com/mastodon/mastodon/pull/9188)) @@ -2696,12 +3094,14 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix HTTP connection timeout of 10s not being enforced ([Gargron](https://github.com/mastodon/mastodon/pull/9329)) ## [2.6.1] - 2018-10-30 + ### Fixed - Fix resolving resources by URL not working due to a regression in [valerauko](https://github.com/mastodon/mastodon/pull/9132) ([Gargron](https://github.com/mastodon/mastodon/pull/9171)) - Fix reducer error in web UI when a conversation has no last status ([Gargron](https://github.com/mastodon/mastodon/pull/9173)) ## [2.6.0] - 2018-10-30 + ### Added - Add link ownership verification ([Gargron](https://github.com/mastodon/mastodon/pull/8703)) @@ -2806,11 +3206,13 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix handling of content types with profile ([valerauko](https://github.com/mastodon/mastodon/pull/9132)) ## [2.5.2] - 2018-10-12 + ### Security - Fix XSS vulnerability ([Gargron](https://github.com/mastodon/mastodon/pull/8959)) ## [2.5.1] - 2018-10-07 + ### Fixed - Fix database migrations for PostgreSQL below 9.5 ([Gargron](https://github.com/mastodon/mastodon/pull/8903)) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index ea5f64b0bc..2ee2e538bc 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities @@ -34,7 +34,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe ## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eugen@zeonfederated.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at glitch-abuse@sitedethib.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9963054b39..a232915b6f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,43 @@ -Contributing -============ +# Contributing to Mastodon Glitch Edition + +Thank you for your interest in contributing to the `glitch-soc` project! +Here are some guidelines, and ways you can help. + +> (This document is a bit of a work-in-progress, so please bear with us. +> If you don't see what you're looking for here, please don't hesitate to reach out!) + +## Translations + +You can submit glitch-soc-specific translations via [Crowdin](https://crowdin.com/project/glitch-soc). They are periodically merged into the codebase. + +[![Crowdin](https://badges.crowdin.net/glitch-soc/localized.svg)](https://crowdin.com/project/glitch-soc) + +## Planning + +Right now a lot of the planning for this project takes place in our development Discord, or through GitHub Issues and Projects. +We're working on ways to improve the planning structure and better solicit feedback, and if you feel like you can help in this respect, feel free to give us a holler. + +## Documentation + +The documentation for this repository is available at [`glitch-soc/docs`](https://github.com/glitch-soc/docs) (online at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/)). +Right now, we've mostly focused on the features that make this fork different from upstream in some manner. +Adding screenshots, improving descriptions, and so forth are all ways to help contribute to the project even if you don't know any code. + +## Frontend Development + +Check out [the documentation here](https://glitch-soc.github.io/docs/contributing/frontend/) for more information. + +## Backend Development + +See the guidelines below. + +--- + +You should also try to follow the guidelines set out in the original `CONTRIBUTING.md` from `mastodon/mastodon`, reproduced below. + +
+ +# Contributing Thank you for considering contributing to Mastodon 🐘 @@ -28,9 +66,9 @@ You can submit translations via [Crowdin](https://crowdin.com/project/mastodon). Example: -|Not ideal|Better| -|---|----| -|Fixed NoMethodError in RemovalWorker|Fix nil error when removing statuses caused by race condition| +| Not ideal | Better | +| ------------------------------------ | ------------------------------------------------------------- | +| Fixed NoMethodError in RemovalWorker | Fix nil error when removing statuses caused by race condition | It is not always possible to phrase every change in such a manner, but it is desired. @@ -42,8 +80,8 @@ It is not always possible to phrase every change in such a manner, but it is des - Code style rules (rubocop, eslint) - Normalization of locale files (i18n-tasks) -**Note**: You may need to log in and authorise the GitHub account your fork of this repository belongs to with CircleCI to enable some of the automated checks to run. - ## Documentation The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/documentation](https://github.com/mastodon/documentation). + +
diff --git a/Capfile b/Capfile deleted file mode 100644 index bf3ae7e249..0000000000 --- a/Capfile +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -require 'capistrano/setup' -require 'capistrano/deploy' -require 'capistrano/scm/git' - -install_plugin Capistrano::SCM::Git - -require 'capistrano/rbenv' -require 'capistrano/bundler' -require 'capistrano/yarn' -require 'capistrano/rails/assets' -require 'capistrano/rails/migrations' - -Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } diff --git a/Dockerfile b/Dockerfile index 160efeea4a..8e40091add 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ # syntax=docker/dockerfile:1.4 -# This needs to be bullseye-slim because the Ruby image is built on bullseye-slim -ARG NODE_VERSION="16.18.1-bullseye-slim" +# This needs to be bookworm-slim because the Ruby image is built on bookworm-slim +ARG NODE_VERSION="20.8-bookworm-slim" -FROM ghcr.io/moritzheiber/ruby-jemalloc:3.0.6-slim as ruby +FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.2-slim as ruby FROM node:${NODE_VERSION} as build COPY --link --from=ruby /opt/ruby /opt/ruby @@ -17,11 +17,11 @@ COPY Gemfile* package.json yarn.lock /opt/mastodon/ # hadolint ignore=DL3008 RUN apt-get update && \ + apt-get -yq dist-upgrade && \ apt-get install -y --no-install-recommends build-essential \ - ca-certificates \ git \ libicu-dev \ - libidn11-dev \ + libidn-dev \ libpq-dev \ libjemalloc-dev \ zlib1g-dev \ @@ -37,10 +37,15 @@ RUN apt-get update && \ bundle config set --local without 'development test' && \ bundle config set silence_root_warning true && \ bundle install -j"$(nproc)" && \ - yarn install --pure-lockfile --network-timeout 600000 + yarn install --pure-lockfile --production --network-timeout 600000 && \ + yarn cache clean FROM node:${NODE_VERSION} +# Use those args to specify your own version flags & suffixes +ARG MASTODON_VERSION_PRERELEASE="" +ARG MASTODON_VERSION_METADATA="" + ARG UID="991" ARG GID="991" @@ -51,7 +56,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"] ENV DEBIAN_FRONTEND="noninteractive" \ PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" -# Ignoreing these here since we don't want to pin any versions and the Debian image removes apt-get content after use +# Ignoring these here since we don't want to pin any versions and the Debian image removes apt-get content after use # hadolint ignore=DL3008,DL3009 RUN apt-get update && \ echo "Etc/UTC" > /etc/localtime && \ @@ -60,13 +65,13 @@ RUN apt-get update && \ apt-get -y --no-install-recommends install whois \ wget \ procps \ - libssl1.1 \ + libssl3 \ libpq5 \ imagemagick \ ffmpeg \ libjemalloc2 \ - libicu67 \ - libidn11 \ + libicu72 \ + libidn12 \ libyaml-0-2 \ file \ ca-certificates \ @@ -84,15 +89,16 @@ COPY --chown=mastodon:mastodon --from=build /opt/mastodon /opt/mastodon ENV RAILS_ENV="production" \ NODE_ENV="production" \ RAILS_SERVE_STATIC_FILES="true" \ - BIND="0.0.0.0" + BIND="0.0.0.0" \ + MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \ + MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}" # Set the run user USER mastodon WORKDIR /opt/mastodon # Precompile assets -RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile && \ - yarn cache clean +RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile # Set the work dir and the container entry point ENTRYPOINT ["/usr/bin/tini", "--"] diff --git a/FEDERATION.md b/FEDERATION.md index cd1957cbd1..e3721d7241 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -27,4 +27,5 @@ More information on HTTP Signatures, as well as examples, can be found here: htt - Linked-Data Signatures: https://docs.joinmastodon.org/spec/security/#ld - Bearcaps: https://docs.joinmastodon.org/spec/bearcaps/ -- Followers collection synchronization: https://git.activitypub.dev/ActivityPubDev/Fediverse-Enhancement-Proposals/src/branch/main/feps/fep-8fcf.md +- Followers collection synchronization: https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md +- Search indexing consent for actors: https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md diff --git a/Gemfile b/Gemfile index 6e5292d824..449b0a9203 100644 --- a/Gemfile +++ b/Gemfile @@ -1,27 +1,24 @@ # frozen_string_literal: true source 'https://rubygems.org' -ruby '>= 2.7.0', '< 3.1.0' +ruby '>= 3.0.0' -gem 'pkg-config', '~> 1.5' -gem 'rexml', '~> 3.2' - -gem 'puma', '~> 5.6' -gem 'rails', '~> 6.1.7' +gem 'puma', '~> 6.3' +gem 'rails', '~> 7.0' gem 'sprockets', '~> 3.7.2' gem 'thor', '~> 1.2' -gem 'rack', '~> 2.2.6' +gem 'rack', '~> 2.2.7' -gem 'hamlit-rails', '~> 0.2' -gem 'pg', '~> 1.4' -gem 'makara', '~> 0.5' +gem 'haml-rails', '~>2.0' +gem 'pg', '~> 1.5' gem 'pghero' gem 'dotenv-rails', '~> 2.8' -gem 'aws-sdk-s3', '~> 1.119', require: false +gem 'aws-sdk-s3', '~> 1.123', require: false gem 'fog-core', '<= 2.4.0' gem 'fog-openstack', '~> 0.3', require: false -gem 'kt-paperclip', '~> 7.1' +gem 'kt-paperclip', '~> 7.2' +gem 'md-paperclip-azure', '~> 2.2', require: false gem 'blurhash', '~> 0.1' gem 'active_model_serializers', '~> 0.10' @@ -29,20 +26,23 @@ gem 'addressable', '~> 2.8' gem 'bootsnap', '~> 1.16.0', require: false gem 'browser' gem 'charlock_holmes', '~> 0.7.7' -gem 'chewy', '~> 7.2' -gem 'devise', '~> 4.8' -gem 'devise-two-factor', '~> 4.0' +gem 'chewy', '~> 7.3' +gem 'devise', '~> 4.9' +gem 'devise-two-factor', '~> 4.1' group :pam_authentication, optional: true do gem 'devise_pam_authenticatable2', '~> 9.2' end -gem 'net-ldap', '~> 0.17' -gem 'omniauth-cas', '~> 2.0' -gem 'omniauth-saml', '~> 1.10' -gem 'gitlab-omniauth-openid-connect', '~>0.10.1', require: 'omniauth_openid_connect' -gem 'omniauth', '~> 1.9' -gem 'omniauth-rails_csrf_protection', '~> 0.1' +gem 'net-ldap', '~> 0.18' + +# TODO: Point back at released omniauth-cas gem when PR merged +# https://github.com/dlindahl/omniauth-cas/pull/68 +gem 'omniauth-cas', github: 'stanhu/omniauth-cas', ref: '4211e6d05941b4a981f9a36b49ec166cecd0e271' +gem 'omniauth-saml', '~> 2.0' +gem 'omniauth_openid_connect', '~> 0.6.1' +gem 'omniauth', '~> 2.0' +gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'color_diff', '~> 0.1' gem 'discard', '~> 1.2' @@ -59,10 +59,10 @@ gem 'httplog', '~> 1.6.2' gem 'idn-ruby', require: 'idn' gem 'kaminari', '~> 1.2' gem 'link_header', '~> 0.0' -gem 'mime-types', '~> 3.4.1', require: 'mime/types/columnar' -gem 'nokogiri', '~> 1.14' -gem 'nsa', '~> 0.2' -gem 'oj', '~> 3.13' +gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar' +gem 'nokogiri', '~> 1.15' +gem 'nsa', github: 'jhawthorn/nsa', ref: 'e020fcc3a54d993ab45b7194d89ab720296c111b' +gem 'oj', '~> 3.14' gem 'ox', '~> 2.14' gem 'parslet' gem 'posix-spawn' @@ -70,84 +70,119 @@ gem 'public_suffix', '~> 5.0' gem 'pundit', '~> 2.3' gem 'premailer-rails' gem 'rack-attack', '~> 6.6' -gem 'rack-cors', '~> 1.1', require: 'rack/cors' -gem 'rails-i18n', '~> 6.0' -gem 'rails-settings-cached', '~> 0.6' +gem 'rack-cors', '~> 2.0', require: 'rack/cors' +gem 'rails-i18n', '~> 7.0' +gem 'rails-settings-cached', '~> 0.6', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true' gem 'redcarpet', '~> 3.6' gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis'] gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' -gem 'rqrcode', '~> 2.1' -gem 'ruby-progressbar', '~> 1.11' +gem 'rqrcode', '~> 2.2' +gem 'ruby-progressbar', '~> 1.13' gem 'sanitize', '~> 6.0' gem 'scenic', '~> 1.7' gem 'sidekiq', '~> 6.5' -gem 'sidekiq-scheduler', '~> 4.0' +gem 'sidekiq-scheduler', '~> 5.0' gem 'sidekiq-unique-jobs', '~> 7.1' gem 'sidekiq-bulk', '~> 0.2.0' gem 'simple-navigation', '~> 4.4' gem 'simple_form', '~> 5.2' gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie' gem 'stoplight', '~> 3.0.1' -gem 'strong_migrations', '~> 0.7' +gem 'strong_migrations', '~> 0.8' gem 'tty-prompt', '~> 0.23', require: false gem 'twitter-text', '~> 3.1.0' -gem 'tzinfo-data', '~> 1.2022' +gem 'tzinfo-data', '~> 1.2023' gem 'webpacker', '~> 5.4' gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' -gem 'webauthn', '~> 2.5' +gem 'webauthn', '~> 3.0' gem 'json-ld' gem 'json-ld-preloaded', '~> 3.2' gem 'rdf-normalize', '~> 0.5' -group :development, :test do - gem 'fabrication', '~> 2.30' - gem 'fuubar', '~> 2.5' - gem 'i18n-tasks', '~> 1.0', require: false - gem 'pry-byebug', '~> 3.10' - gem 'pry-rails', '~> 0.3' - gem 'rspec-rails', '~> 5.1' - gem 'rubocop-performance', require: false - gem 'rubocop-rails', require: false - gem 'rubocop-rspec', require: false - gem 'rubocop', require: false -end - -group :production, :test do - gem 'private_address_check', '~> 0.5' -end +gem 'private_address_check', '~> 0.5' group :test do - gem 'capybara', '~> 3.38' + # Used to split testing into chunks in CI + gem 'rspec_chunked', '~> 0.6' + + # RSpec progress bar formatter + gem 'fuubar', '~> 2.5' + + # Extra RSpec extenion methods and helpers for sidekiq + gem 'rspec-sidekiq', '~> 4.0' + + # Browser integration testing + gem 'capybara', '~> 3.39' + gem 'selenium-webdriver' + + # Used to reset the database between system tests + gem 'database_cleaner-active_record' + + # Used to mock environment variables gem 'climate_control', '~> 0.2' - gem 'faker', '~> 3.1' - gem 'json-schema', '~> 3.0' - gem 'rack-test', '~> 2.0' + + # Generating fake data for specs + gem 'faker', '~> 3.2' + + # Generate test objects for specs + gem 'fabrication', '~> 2.30' + + # Add back helpers functions removed in Rails 5.1 gem 'rails-controller-testing', '~> 1.0' - gem 'rspec_junit_formatter', '~> 0.6' - gem 'rspec-sidekiq', '~> 3.1' + + # Validate schemas in specs + gem 'json-schema', '~> 4.0' + + # Test harness fo rack components + gem 'rack-test', '~> 2.1' + + # Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false gem 'simplecov', '~> 0.22', require: false + + # Stub web requests for specs gem 'webmock', '~> 3.18' end group :development do - gem 'active_record_query_trace', '~> 1.8' + # Code linting CLI and plugins + gem 'rubocop', require: false + gem 'rubocop-capybara', require: false + gem 'rubocop-performance', require: false + gem 'rubocop-rails', require: false + gem 'rubocop-rspec', require: false + + # Annotates modules with schema gem 'annotate', '~> 3.2' + + # Enhanced error message pages for development gem 'better_errors', '~> 2.9' gem 'binding_of_caller', '~> 1.0' - gem 'bullet', '~> 7.0' + + # Preview mail in the browser gem 'letter_opener', '~> 1.8' gem 'letter_opener_web', '~> 2.0' - gem 'memory_profiler' - gem 'brakeman', '~> 5.4', require: false + + # Security analysis CLI tools + gem 'brakeman', '~> 6.0', require: false gem 'bundler-audit', '~> 0.9', require: false - gem 'capistrano', '~> 3.17' - gem 'capistrano-rails', '~> 1.6' - gem 'capistrano-rbenv', '~> 2.2' - gem 'capistrano-yarn', '~> 2.0' + # Linter CLI for HAML files + gem 'haml_lint', require: false - gem 'stackprof' + # Validate missing i18n keys + gem 'i18n-tasks', '~> 1.0', require: false +end + +group :development, :test do + # Profiling tools + gem 'memory_profiler', require: false + gem 'ruby-prof', require: false + gem 'stackprof', require: false + gem 'test-prof' + + # RSpec runner for rails + gem 'rspec-rails', '~> 6.0' end group :production do @@ -157,4 +192,10 @@ end gem 'concurrent-ruby', require: false gem 'connection_pool', require: false gem 'xorcist', '~> 1.1' + gem 'cocoon', '~> 1.2' + +gem 'net-http', '~> 0.3.2' +gem 'rubyzip', '~> 2.3' + +gem 'hcaptcha', '~> 7.1' diff --git a/Gemfile.lock b/Gemfile.lock index 23096c3876..affe1bf7f2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,109 +7,150 @@ GIT hkdf (~> 0.2) jwt (~> 2.0) +GIT + remote: https://github.com/jhawthorn/nsa.git + revision: e020fcc3a54d993ab45b7194d89ab720296c111b + ref: e020fcc3a54d993ab45b7194d89ab720296c111b + specs: + nsa (0.2.8) + activesupport (>= 4.2, < 7.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + sidekiq (>= 3.5) + statsd-ruby (~> 1.4, >= 1.4.0) + +GIT + remote: https://github.com/mastodon/rails-settings-cached.git + revision: 86328ef0bd04ce21cc0504ff5e334591e8c2ccab + branch: v0.6.6-aliases-true + specs: + rails-settings-cached (0.6.6) + rails (>= 4.2.0) + +GIT + remote: https://github.com/stanhu/omniauth-cas.git + revision: 4211e6d05941b4a981f9a36b49ec166cecd0e271 + ref: 4211e6d05941b4a981f9a36b49ec166cecd0e271 + specs: + omniauth-cas (2.0.0) + addressable (~> 2.3) + nokogiri (~> 1.5) + omniauth (>= 1.2, < 3) + GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.4) - actionpack (= 6.1.7.4) - activesupport (= 6.1.7.4) + actioncable (7.0.8) + actionpack (= 7.0.8) + activesupport (= 7.0.8) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.4) - actionpack (= 6.1.7.4) - activejob (= 6.1.7.4) - activerecord (= 6.1.7.4) - activestorage (= 6.1.7.4) - activesupport (= 6.1.7.4) + actionmailbox (7.0.8) + actionpack (= 7.0.8) + activejob (= 7.0.8) + activerecord (= 7.0.8) + activestorage (= 7.0.8) + activesupport (= 7.0.8) mail (>= 2.7.1) - actionmailer (6.1.7.4) - actionpack (= 6.1.7.4) - actionview (= 6.1.7.4) - activejob (= 6.1.7.4) - activesupport (= 6.1.7.4) + net-imap + net-pop + net-smtp + actionmailer (7.0.8) + actionpack (= 7.0.8) + actionview (= 7.0.8) + activejob (= 7.0.8) + activesupport (= 7.0.8) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.7.4) - actionview (= 6.1.7.4) - activesupport (= 6.1.7.4) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.8) + actionview (= 7.0.8) + activesupport (= 7.0.8) + rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.4) - actionpack (= 6.1.7.4) - activerecord (= 6.1.7.4) - activestorage (= 6.1.7.4) - activesupport (= 6.1.7.4) + actiontext (7.0.8) + actionpack (= 7.0.8) + activerecord (= 7.0.8) + activestorage (= 7.0.8) + activesupport (= 7.0.8) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.7.4) - activesupport (= 6.1.7.4) + actionview (7.0.8) + activesupport (= 7.0.8) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - active_model_serializers (0.10.13) - actionpack (>= 4.1, < 7.1) - activemodel (>= 4.1, < 7.1) + active_model_serializers (0.10.14) + actionpack (>= 4.1) + activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - active_record_query_trace (1.8) - activejob (6.1.7.4) - activesupport (= 6.1.7.4) + activejob (7.0.8) + activesupport (= 7.0.8) globalid (>= 0.3.6) - activemodel (6.1.7.4) - activesupport (= 6.1.7.4) - activerecord (6.1.7.4) - activemodel (= 6.1.7.4) - activesupport (= 6.1.7.4) - activestorage (6.1.7.4) - actionpack (= 6.1.7.4) - activejob (= 6.1.7.4) - activerecord (= 6.1.7.4) - activesupport (= 6.1.7.4) + activemodel (7.0.8) + activesupport (= 7.0.8) + activerecord (7.0.8) + activemodel (= 7.0.8) + activesupport (= 7.0.8) + activestorage (7.0.8) + actionpack (= 7.0.8) + activejob (= 7.0.8) + activerecord (= 7.0.8) + activesupport (= 7.0.8) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.4) + activesupport (7.0.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) - addressable (2.8.1) + addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) - airbrussh (1.4.1) - sshkit (>= 1.6.1, != 1.7.0) android_key_attestation (0.3.0) annotate (3.2.0) activerecord (>= 3.2, < 8.0) rake (>= 10.4, < 14.0) ast (2.4.2) - attr_encrypted (3.1.0) + attr_encrypted (4.0.0) encryptor (~> 3.0.0) attr_required (1.0.1) awrence (1.2.1) aws-eventstream (1.2.0) - aws-partitions (1.701.0) - aws-sdk-core (3.170.0) + aws-partitions (1.809.0) + aws-sdk-core (3.181.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.62.0) - aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-kms (1.71.0) + aws-sdk-core (~> 3, >= 3.177.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.119.0) - aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-s3 (1.133.0) + aws-sdk-core (~> 3, >= 3.181.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.4) - aws-sigv4 (1.5.2) + aws-sigv4 (~> 1.6) + aws-sigv4 (1.6.0) aws-eventstream (~> 1, >= 1.0.2) - bcrypt (3.1.17) - better_errors (2.9.1) - coderay (>= 1.0.0) + azure-storage-blob (2.0.3) + azure-storage-common (~> 2.0) + nokogiri (~> 1, >= 1.10.8) + azure-storage-common (2.0.4) + faraday (~> 1.0) + faraday_middleware (~> 1.0, >= 1.0.0.rc1) + net-http-persistent (~> 4.0) + nokogiri (~> 1, >= 1.10.8) + base64 (0.1.1) + bcrypt (3.1.18) + better_errors (2.10.1) erubi (>= 1.0.0) rack (>= 0.9.0) + rouge (>= 1.0.0) better_html (2.0.1) actionview (>= 6.0) activesupport (>= 6.0) @@ -117,41 +158,22 @@ GEM erubi (~> 1.4) parser (>= 2.4) smart_properties - bindata (2.4.14) + bindata (2.4.15) binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) blurhash (0.1.7) bootsnap (1.16.0) msgpack (~> 1.2) - brakeman (5.4.0) - browser (4.2.0) + brakeman (6.0.1) + browser (5.3.1) brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) redis (>= 1.0, < 6) builder (3.2.4) - bullet (7.0.7) - activesupport (>= 3.0.0) - uniform_notifier (~> 1.11) bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) - byebug (11.1.3) - capistrano (3.17.1) - airbrussh (>= 1.0.0) - i18n - rake (>= 10.0.0) - sshkit (>= 1.9.0) - capistrano-bundler (2.0.1) - capistrano (~> 3.1) - capistrano-rails (1.6.2) - capistrano (~> 3.1) - capistrano-bundler (>= 1.1, < 3) - capistrano-rbenv (2.2.0) - capistrano (~> 3.1) - sshkit (~> 1.3) - capistrano-yarn (2.0.2) - capistrano (~> 3.0) - capybara (3.38.0) + capybara (3.39.2) addressable matrix mini_mime (>= 0.1.3) @@ -164,36 +186,39 @@ GEM activesupport cbor (0.5.9.6) charlock_holmes (0.7.7) - chewy (7.2.4) + chewy (7.3.4) activesupport (>= 5.2) elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch-dsl chunky_png (1.4.0) climate_control (0.2.0) cocoon (1.2.15) - coderay (1.1.3) color_diff (0.1) concurrent-ruby (1.2.2) - connection_pool (2.3.0) - cose (1.2.1) + connection_pool (2.4.1) + cose (1.3.0) cbor (~> 0.5.9) openssl-signature_algorithm (~> 1.0) crack (0.4.5) rexml crass (1.0.6) - css_parser (1.12.0) + css_parser (1.14.0) addressable + database_cleaner-active_record (2.1.0) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) date (3.3.3) - debug_inspector (1.0.0) - devise (4.8.1) + debug_inspector (1.1.0) + devise (4.9.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-two-factor (4.0.2) + devise-two-factor (4.1.0) activesupport (< 7.1) - attr_encrypted (>= 1.3, < 4, != 2) + attr_encrypted (>= 1.3, < 5, != 2) devise (~> 4.0) railties (< 7.1) rotp (~> 6.0) @@ -226,11 +251,11 @@ GEM erubi (1.12.0) et-orbi (1.2.7) tzinfo - excon (0.95.0) + excon (0.100.0) fabrication (2.30.0) - faker (3.1.1) + faker (3.2.1) i18n (>= 1.8.11, < 2) - faraday (1.9.3) + faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -246,15 +271,17 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) + faraday_middleware (1.2.0) + faraday (~> 1.0) fast_blank (1.0.1) - fastimage (2.2.6) + fastimage (2.2.7) ffi (1.15.5) ffi-compiler (1.0.1) ffi (>= 1.0.0) @@ -272,30 +299,34 @@ GEM fog-json (>= 1.0) ipaddress (>= 0.8) formatador (0.3.0) - fugit (1.7.1) + fugit (1.8.1) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) fuubar (2.5.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) - gitlab-omniauth-openid-connect (0.10.1) - addressable (~> 2.7) - omniauth (>= 1.9, < 3) - openid_connect (~> 1.2) globalid (1.1.0) activesupport (>= 5.0) - hamlit (2.13.0) + haml (6.2.0) temple (>= 0.8.2) thor tilt - hamlit-rails (0.2.3) - actionpack (>= 4.0.1) - activesupport (>= 4.0.1) - hamlit (>= 1.2.0) - railties (>= 4.0.1) + haml-rails (2.1.0) + actionpack (>= 5.1) + activesupport (>= 5.1) + haml (>= 4.0.6) + railties (>= 5.1) + haml_lint (0.51.0) + haml (>= 4.0) + parallel (~> 1.10) + rainbow + rubocop (>= 1.0) + sysexits (~> 1.1) hashdiff (1.0.1) hashie (5.0.0) - highline (2.0.3) + hcaptcha (7.1.0) + json + highline (2.1.0) hiredis (0.6.3) hkdf (0.3.0) htmlentities (4.3.4) @@ -312,7 +343,7 @@ GEM httplog (1.6.2) rack (>= 2.0) rainbow (>= 2.0.0) - i18n (1.12.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) i18n-tasks (1.0.12) activesupport (>= 4.0.2) @@ -329,26 +360,26 @@ GEM ipaddress (0.8.3) jmespath (1.6.2) json (2.6.3) - json-canonicalization (0.3.0) + json-canonicalization (0.3.2) json-jwt (1.15.3) activesupport (>= 4.2) aes_key_wrap bindata httpclient - json-ld (3.2.3) + json-ld (3.2.5) htmlentities (~> 4.3) - json-canonicalization (~> 0.3) + json-canonicalization (~> 0.3, >= 0.3.2) link_header (~> 0.0, >= 0.0.8) multi_json (~> 1.15) - rack (~> 2.2) - rdf (~> 3.2, >= 3.2.9) + rack (>= 2.2, < 4) + rdf (~> 3.2, >= 3.2.10) json-ld-preloaded (3.2.2) json-ld (~> 3.2) rdf (~> 3.2) - json-schema (3.0.0) + json-schema (4.0.0) addressable (>= 2.8) jsonapi-renderer (0.2.2) - jwt (2.5.0) + jwt (2.7.1) kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) @@ -361,14 +392,15 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - kt-paperclip (7.1.1) + kt-paperclip (7.2.1) activemodel (>= 4.2.0) activesupport (>= 4.2.0) marcel (~> 1.0.1) mime-types terrapin (~> 0.6.0) - launchy (2.5.0) - addressable (~> 2.7) + language_server-protocol (3.17.0.3) + launchy (2.5.2) + addressable (~> 2.8) letter_opener (1.8.1) launchy (>= 2.2, < 3) letter_opener_web (2.0.0) @@ -380,72 +412,70 @@ GEM llhttp-ffi (0.4.0) ffi-compiler (~> 1.0) rake (~> 13.0) - lograge (0.12.0) + lograge (0.13.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.19.1) + loofah (2.21.3) crass (~> 1.0.2) - nokogiri (>= 1.5.9) + nokogiri (>= 1.12.0) mail (2.8.1) mini_mime (>= 0.1.1) net-imap net-pop net-smtp - makara (0.5.1) - activerecord (>= 5.2.0) marcel (1.0.2) mario-redis-lock (1.2.1) redis (>= 3.0.5) matrix (0.4.2) + md-paperclip-azure (2.2.0) + addressable (~> 2.5) + azure-storage-blob (~> 2.0.1) + hashie (~> 5.0) memory_profiler (1.0.1) method_source (1.0.0) - mime-types (3.4.1) + mime-types (3.5.1) mime-types-data (~> 3.2015) - mime-types-data (3.2022.0105) - mini_mime (1.1.2) - mini_portile2 (2.8.2) - minitest (5.17.0) - msgpack (1.6.0) + mime-types-data (3.2023.0808) + mini_mime (1.1.5) + mini_portile2 (2.8.4) + minitest (5.19.0) + msgpack (1.7.1) multi_json (1.15.0) - multipart-post (2.1.1) - net-imap (0.3.6) + multipart-post (2.3.0) + net-http (0.3.2) + uri + net-http-persistent (4.0.2) + connection_pool (~> 2.2) + net-imap (0.3.7) date net-protocol - net-ldap (0.17.1) + net-ldap (0.18.0) net-pop (0.1.2) net-protocol net-protocol (0.2.1) timeout - net-scp (4.0.0.rc1) - net-ssh (>= 2.6.5, < 8.0.0) net-smtp (0.3.3) net-protocol - net-ssh (7.0.1) nio4r (2.5.9) - nokogiri (1.14.5) - mini_portile2 (~> 2.8.0) + nokogiri (1.15.4) + mini_portile2 (~> 2.8.2) racc (~> 1.4) - nsa (0.2.8) - activesupport (>= 4.2, < 7) - concurrent-ruby (~> 1.0, >= 1.0.2) - sidekiq (>= 3.5) - statsd-ruby (~> 1.4, >= 1.4.0) - oj (3.13.23) - omniauth (1.9.2) + oj (3.16.1) + omniauth (2.1.1) hashie (>= 3.4.6) - rack (>= 1.6.2, < 3) - omniauth-cas (2.0.0) - addressable (~> 2.3) - nokogiri (~> 1.5) - omniauth (~> 1.2) - omniauth-rails_csrf_protection (0.1.2) + rack (>= 2.2.3) + rack-protection + omniauth-rails_csrf_protection (1.0.1) actionpack (>= 4.2) - omniauth (>= 1.3.1) - omniauth-saml (1.10.3) - omniauth (~> 1.3, >= 1.3.2) - ruby-saml (~> 1.9) + omniauth (~> 2.0) + omniauth-saml (2.1.0) + omniauth (~> 2.0) + ruby-saml (~> 1.12) + omniauth_openid_connect (0.6.1) + omniauth (>= 1.9, < 3) + openid_connect (~> 1.1) openid_connect (1.4.2) activemodel attr_required (>= 1.0.0) @@ -457,23 +487,23 @@ GEM validate_email validate_url webfinger (~> 1.2) - openssl (3.0.0) - openssl-signature_algorithm (1.2.1) - openssl (> 2.0, < 3.1) + openssl (3.1.0) + openssl-signature_algorithm (1.3.0) + openssl (> 2.0) orm_adapter (0.5.0) - ox (2.14.14) - parallel (1.22.1) - parser (3.2.0.0) + ox (2.14.17) + parallel (1.23.0) + parser (3.2.2.3) ast (~> 2.4.1) + racc parslet (2.0.0) pastel (0.8.0) tty-color (~> 0.5) - pg (1.4.5) - pghero (3.1.0) + pg (1.5.4) + pghero (3.3.4) activerecord (>= 6) - pkg-config (1.5.1) posix-spawn (0.3.15) - premailer (1.18.0) + premailer (1.21.0) addressable css_parser (>= 1.12.0) htmlentities (>= 4.0.0) @@ -482,25 +512,17 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) private_address_check (0.5.0) - pry (0.14.1) - coderay (~> 1.1) - method_source (~> 1.0) - pry-byebug (3.10.1) - byebug (~> 11.0) - pry (>= 0.13, < 0.15) - pry-rails (0.3.9) - pry (>= 0.10.4) - public_suffix (5.0.1) - puma (5.6.5) + public_suffix (5.0.3) + puma (6.3.1) nio4r (~> 2.0) pundit (2.3.0) activesupport (>= 3.0.0) raabro (1.4.0) - racc (1.6.2) - rack (2.2.7) - rack-attack (6.6.1) - rack (>= 1.0, < 3) - rack-cors (1.1.1) + racc (1.7.1) + rack (2.2.8) + rack-attack (6.7.0) + rack (>= 1.0, < 4) + rack-cors (2.0.1) rack (>= 2.0.0) rack-oauth2 (1.21.3) activesupport @@ -508,142 +530,156 @@ GEM httpclient json-jwt (>= 1.11.0) rack (>= 2.1.0) + rack-protection (3.0.5) + rack rack-proxy (0.7.6) rack - rack-test (2.0.2) + rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.4) - actioncable (= 6.1.7.4) - actionmailbox (= 6.1.7.4) - actionmailer (= 6.1.7.4) - actionpack (= 6.1.7.4) - actiontext (= 6.1.7.4) - actionview (= 6.1.7.4) - activejob (= 6.1.7.4) - activemodel (= 6.1.7.4) - activerecord (= 6.1.7.4) - activestorage (= 6.1.7.4) - activesupport (= 6.1.7.4) + rails (7.0.8) + actioncable (= 7.0.8) + actionmailbox (= 7.0.8) + actionmailer (= 7.0.8) + actionpack (= 7.0.8) + actiontext (= 7.0.8) + actionview (= 7.0.8) + activejob (= 7.0.8) + activemodel (= 7.0.8) + activerecord (= 7.0.8) + activestorage (= 7.0.8) + activesupport (= 7.0.8) bundler (>= 1.15.0) - railties (= 6.1.7.4) - sprockets-rails (>= 2.0.0) + railties (= 7.0.8) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.0.3) - activesupport (>= 4.2.0) + rails-dom-testing (2.1.1) + activesupport (>= 5.0.0) + minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.5.0) - loofah (~> 2.19, >= 2.19.1) - rails-i18n (6.0.0) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) + rails-i18n (7.0.7) i18n (>= 0.7, < 2) - railties (>= 6.0.0, < 7) - rails-settings-cached (0.6.6) - rails (>= 4.2.0) - railties (6.1.7.4) - actionpack (= 6.1.7.4) - activesupport (= 6.1.7.4) + railties (>= 6.0.0, < 8) + railties (7.0.8) + actionpack (= 7.0.8) + activesupport (= 7.0.8) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rainbow (3.1.1) rake (13.0.6) - rdf (3.2.9) + rdf (3.2.11) link_header (~> 0.0, >= 0.0.8) - rdf-normalize (0.5.1) + rdf-normalize (0.6.1) rdf (~> 3.2) redcarpet (3.6.0) - redis (4.5.1) - redis-namespace (1.10.0) + redis (4.8.1) + redis-namespace (1.11.0) redis (>= 4) redlock (1.3.2) redis (>= 3.0.0, < 6.0) - regexp_parser (2.6.2) + regexp_parser (2.8.1) request_store (1.5.1) rack (>= 1.4) - responders (3.0.1) - actionpack (>= 5.0) - railties (>= 5.0) - rexml (3.2.5) - rotp (6.2.0) + responders (3.1.0) + actionpack (>= 5.2) + railties (>= 5.2) + rexml (3.2.6) + rotp (6.2.2) + rouge (4.1.2) rpam2 (4.0.2) - rqrcode (2.1.2) + rqrcode (2.2.0) chunky_png (~> 1.0) rqrcode_core (~> 1.0) rqrcode_core (1.2.0) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-mocks (3.11.1) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-rails (5.1.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) - rspec-sidekiq (3.1.0) - rspec-core (~> 3.0, >= 3.0.0) - sidekiq (>= 2.4.0) - rspec-support (3.11.1) - rspec_junit_formatter (0.6.0) - rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.44.1) + rspec-support (~> 3.12.0) + rspec-rails (6.0.3) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) + rspec-sidekiq (4.0.1) + rspec-core (~> 3.0) + rspec-expectations (~> 3.0) + rspec-mocks (~> 3.0) + sidekiq (>= 5, < 8) + rspec-support (3.12.1) + rspec_chunked (0.6) + rubocop (1.56.4) + base64 (~> 0.1.1) json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.0.0) + parser (>= 3.2.2.3) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.24.1, < 2.0) + rubocop-ast (>= 1.28.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.24.1) - parser (>= 3.1.1.0) - rubocop-capybara (2.17.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + rubocop-capybara (2.18.0) rubocop (~> 1.41) - rubocop-performance (1.16.0) + rubocop-factory_bot (2.23.1) + rubocop (~> 1.33) + rubocop-performance (1.19.0) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.17.4) + rubocop-rails (2.20.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) - rubocop-rspec (2.18.1) + rubocop-rspec (2.23.2) rubocop (~> 1.33) rubocop-capybara (~> 2.17) - ruby-progressbar (1.11.0) - ruby-saml (1.13.0) - nokogiri (>= 1.10.5) + rubocop-factory_bot (~> 2.22) + ruby-prof (1.6.3) + ruby-progressbar (1.13.0) + ruby-saml (1.15.0) + nokogiri (>= 1.13.10) rexml ruby2_keywords (0.0.5) - rufus-scheduler (3.8.2) + rubyzip (2.3.2) + rufus-scheduler (3.9.1) fugit (~> 1.1, >= 1.1.6) safety_net_attestation (0.4.0) jwt (~> 2.0) - sanitize (6.0.1) + sanitize (6.0.2) crass (~> 1.0.2) nokogiri (>= 1.12.0) scenic (1.7.0) activerecord (>= 4.0.0) railties (>= 4.0.0) + selenium-webdriver (4.13.1) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) semantic_range (3.0.0) - sidekiq (6.5.8) + sidekiq (6.5.11) connection_pool (>= 2.2.5, < 3) rack (~> 2.0) redis (>= 4.5.0, < 5) sidekiq-bulk (0.2.0) sidekiq - sidekiq-scheduler (4.0.3) - redis (>= 4.2.0) + sidekiq-scheduler (5.0.3) rufus-scheduler (~> 3.2) - sidekiq (>= 4, < 7) + sidekiq (>= 6, < 8) tilt (>= 1.4.0) sidekiq-unique-jobs (7.1.29) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) @@ -670,30 +706,29 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - sshkit (1.21.2) - net-scp (>= 1.1.2) - net-ssh (>= 2.8.0) - stackprof (0.2.23) + stackprof (0.2.25) statsd-ruby (1.5.0) - stoplight (3.0.1) + stoplight (3.0.2) redlock (~> 1.0) - strong_migrations (0.7.9) - activerecord (>= 5) + strong_migrations (0.8.0) + activerecord (>= 5.2) swd (1.3.0) activesupport (>= 3) attr_required (>= 0.0.5) httpclient (>= 2.4) - temple (0.8.2) + sysexits (1.2.0) + temple (0.10.2) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) + test-prof (1.2.3) thor (1.2.2) - tilt (2.0.11) - timeout (0.3.2) - tpm-key_attestation (0.11.0) + tilt (2.3.0) + timeout (0.4.0) + tpm-key_attestation (0.12.0) bindata (~> 2.4) - openssl (> 2.0, < 3.1) + openssl (> 2.0) openssl-signature_algorithm (~> 1.0) tty-color (0.6.0) tty-cursor (0.7.1) @@ -710,13 +745,13 @@ GEM unf (~> 0.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2022.7) + tzinfo-data (1.2023.3) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext unf_ext (0.0.8.2) - unicode-display_width (2.4.2) - uniform_notifier (1.16.0) + unicode-display_width (2.5.0) + uri (0.12.2) validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) @@ -725,19 +760,19 @@ GEM public_suffix warden (1.2.9) rack (>= 2.0.9) - webauthn (2.5.2) + webauthn (3.0.0) android_key_attestation (~> 0.3.0) awrence (~> 1.1) bindata (~> 2.4) cbor (~> 0.5.9) cose (~> 1.1) - openssl (>= 2.2, < 3.1) + openssl (>= 2.2) safety_net_attestation (~> 0.4.0) - tpm-key_attestation (~> 0.11.0) + tpm-key_attestation (~> 0.12.0) webfinger (1.2.0) activesupport httpclient (>= 2.4) - webmock (3.18.1) + webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -746,60 +781,57 @@ GEM rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) - websocket-driver (0.7.5) + websocket (1.2.10) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) wisper (2.0.1) xorcist (1.1.3) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.8) + zeitwerk (2.6.11) PLATFORMS ruby DEPENDENCIES active_model_serializers (~> 0.10) - active_record_query_trace (~> 1.8) addressable (~> 2.8) annotate (~> 3.2) - aws-sdk-s3 (~> 1.119) + aws-sdk-s3 (~> 1.123) better_errors (~> 2.9) binding_of_caller (~> 1.0) blurhash (~> 0.1) bootsnap (~> 1.16.0) - brakeman (~> 5.4) + brakeman (~> 6.0) browser - bullet (~> 7.0) bundler-audit (~> 0.9) - capistrano (~> 3.17) - capistrano-rails (~> 1.6) - capistrano-rbenv (~> 2.2) - capistrano-yarn (~> 2.0) - capybara (~> 3.38) + capybara (~> 3.39) charlock_holmes (~> 0.7.7) - chewy (~> 7.2) + chewy (~> 7.3) climate_control (~> 0.2) cocoon (~> 1.2) color_diff (~> 0.1) concurrent-ruby connection_pool - devise (~> 4.8) - devise-two-factor (~> 4.0) + database_cleaner-active_record + devise (~> 4.9) + devise-two-factor (~> 4.1) devise_pam_authenticatable2 (~> 9.2) discard (~> 1.2) doorkeeper (~> 5.6) dotenv-rails (~> 2.8) ed25519 (~> 1.3) fabrication (~> 2.30) - faker (~> 3.1) + faker (~> 3.2) fast_blank (~> 1.0) fastimage fog-core (<= 2.4.0) fog-openstack (~> 0.3) fuubar (~> 2.5) - gitlab-omniauth-openid-connect (~> 0.10.1) - hamlit-rails (~> 0.2) + haml-rails (~> 2.0) + haml_lint + hcaptcha (~> 7.1) hiredis (~> 0.6) htmlentities (~> 4.3) http (~> 5.1) @@ -809,65 +841,67 @@ DEPENDENCIES idn-ruby json-ld json-ld-preloaded (~> 3.2) - json-schema (~> 3.0) + json-schema (~> 4.0) kaminari (~> 1.2) - kt-paperclip (~> 7.1) + kt-paperclip (~> 7.2) letter_opener (~> 1.8) letter_opener_web (~> 2.0) link_header (~> 0.0) lograge (~> 0.12) - makara (~> 0.5) mario-redis-lock (~> 1.2) + md-paperclip-azure (~> 2.2) memory_profiler - mime-types (~> 3.4.1) - net-ldap (~> 0.17) - nokogiri (~> 1.14) - nsa (~> 0.2) - oj (~> 3.13) - omniauth (~> 1.9) - omniauth-cas (~> 2.0) - omniauth-rails_csrf_protection (~> 0.1) - omniauth-saml (~> 1.10) + mime-types (~> 3.5.0) + net-http (~> 0.3.2) + net-ldap (~> 0.18) + nokogiri (~> 1.15) + nsa! + oj (~> 3.14) + omniauth (~> 2.0) + omniauth-cas! + omniauth-rails_csrf_protection (~> 1.0) + omniauth-saml (~> 2.0) + omniauth_openid_connect (~> 0.6.1) ox (~> 2.14) parslet - pg (~> 1.4) + pg (~> 1.5) pghero - pkg-config (~> 1.5) posix-spawn premailer-rails private_address_check (~> 0.5) - pry-byebug (~> 3.10) - pry-rails (~> 0.3) public_suffix (~> 5.0) - puma (~> 5.6) + puma (~> 6.3) pundit (~> 2.3) - rack (~> 2.2.6) + rack (~> 2.2.7) rack-attack (~> 6.6) - rack-cors (~> 1.1) - rack-test (~> 2.0) - rails (~> 6.1.7) + rack-cors (~> 2.0) + rack-test (~> 2.1) + rails (~> 7.0) rails-controller-testing (~> 1.0) - rails-i18n (~> 6.0) - rails-settings-cached (~> 0.6) + rails-i18n (~> 7.0) + rails-settings-cached (~> 0.6)! rdf-normalize (~> 0.5) redcarpet (~> 3.6) redis (~> 4.5) redis-namespace (~> 1.10) - rexml (~> 3.2) - rqrcode (~> 2.1) - rspec-rails (~> 5.1) - rspec-sidekiq (~> 3.1) - rspec_junit_formatter (~> 0.6) + rqrcode (~> 2.2) + rspec-rails (~> 6.0) + rspec-sidekiq (~> 4.0) + rspec_chunked (~> 0.6) rubocop + rubocop-capybara rubocop-performance rubocop-rails rubocop-rspec - ruby-progressbar (~> 1.11) + ruby-prof + ruby-progressbar (~> 1.13) + rubyzip (~> 2.3) sanitize (~> 6.0) scenic (~> 1.7) + selenium-webdriver sidekiq (~> 6.5) sidekiq-bulk (~> 0.2.0) - sidekiq-scheduler (~> 4.0) + sidekiq-scheduler (~> 5.0) sidekiq-unique-jobs (~> 7.1) simple-navigation (~> 4.4) simple_form (~> 5.2) @@ -876,13 +910,20 @@ DEPENDENCIES sprockets-rails (~> 3.4) stackprof stoplight (~> 3.0.1) - strong_migrations (~> 0.7) + strong_migrations (~> 0.8) + test-prof thor (~> 1.2) tty-prompt (~> 0.23) twitter-text (~> 3.1.0) - tzinfo-data (~> 1.2022) - webauthn (~> 2.5) + tzinfo-data (~> 1.2023) + webauthn (~> 3.0) webmock (~> 3.18) webpacker (~> 5.4) webpush! xorcist (~> 1.1) + +RUBY VERSION + ruby 3.2.2p53 + +BUNDLED WITH + 2.4.13 diff --git a/Procfile.dev b/Procfile.dev index ba04fb661b..fbb2c2de23 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,4 +1,4 @@ web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq stream: env PORT=4000 yarn run start -webpack: ./bin/webpack-dev-server --listen-host 0.0.0.0 +webpack: bin/webpack-dev-server diff --git a/README.md b/README.md index abf16d6746..f878752fe3 100644 --- a/README.md +++ b/README.md @@ -1,103 +1,14 @@ -

- - - Mastodon -

+# Mastodon Glitch Edition -[![GitHub release](https://img.shields.io/github/release/mastodon/mastodon.svg)][releases] -[![Build Status](https://img.shields.io/circleci/project/github/mastodon/mastodon.svg)][circleci] -[![Code Climate](https://img.shields.io/codeclimate/maintainability/mastodon/mastodon.svg)][code_climate] -[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin] +> Now with automated deploys! -[releases]: https://github.com/mastodon/mastodon/releases -[circleci]: https://circleci.com/gh/mastodon/mastodon -[code_climate]: https://codeclimate.com/github/mastodon/mastodon -[crowdin]: https://crowdin.com/project/mastodon +[![Build Status](https://img.shields.io/circleci/project/github/glitch-soc/mastodon.svg)][circleci] +[![Code Climate](https://img.shields.io/codeclimate/maintainability/glitch-soc/mastodon.svg)][code_climate] -Mastodon is a **free, open-source social network server** based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub!) +[circleci]: https://circleci.com/gh/glitch-soc/mastodon +[code_climate]: https://codeclimate.com/github/glitch-soc/mastodon -Click below to **learn more** in a video: +So here's the deal: we all work on this code, and anyone who uses that does so absolutely at their own risk. can you dig it? -[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo] - -[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE - -## Navigation - -- [Project homepage 🐘](https://joinmastodon.org) -- [Support the development via Patreon][patreon] -- [View sponsors](https://joinmastodon.org/sponsors) -- [Blog](https://blog.joinmastodon.org) -- [Documentation](https://docs.joinmastodon.org) -- [Official Docker image](https://github.com/mastodon/mastodon/pkgs/container/mastodon) -- [Browse Mastodon servers](https://joinmastodon.org/communities) -- [Browse Mastodon apps](https://joinmastodon.org/apps) - -[patreon]: https://www.patreon.com/mastodon - -## Features - - - -### No vendor lock-in: Fully interoperable with any conforming platform - -It doesn't have to be Mastodon; whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/) - -### Real-time, chronological timeline updates - -Updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well! - -### Media attachments like images and short videos - -Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos loop continuously! - -### Safety and moderation tools - -Mastodon includes private posts, locked accounts, phrase filtering, muting, blocking and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/) - -### OAuth2 and a straightforward REST API - -Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Streaming APIs. This results in a rich app ecosystem with a lot of choices! - -## Deployment - -### Tech stack: - -- **Ruby on Rails** powers the REST API and other web pages -- **React.js** and Redux are used for the dynamic parts of the interface -- **Node.js** powers the streaming API - -### Requirements: - -- **PostgreSQL** 9.5+ -- **Redis** 4+ -- **Ruby** 2.7+ -- **Node.js** 14+ - -The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation. - -A **Vagrant** configuration is included for development purposes. To use it, complete following steps: - -- Install Vagrant and Virtualbox -- Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater` -- Run `vagrant up` -- Run `vagrant ssh -c "cd /vagrant && foreman start"` -- Open `http://mastodon.local` in your browser - -## Contributing - -Mastodon is **free, open-source software** licensed under **AGPLv3**. - -You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository or submit translations using Crowdin. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon). - -**IRC channel**: #mastodon on irc.libera.chat - -## License - -Copyright (C) 2016-2022 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md)) - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License along with this program. If not, see . +- You can view documentation for this project at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/). +- And contributing guidelines are available [here](CONTRIBUTING.md) and [here](https://glitch-soc.github.io/docs/contributing/). diff --git a/Rakefile b/Rakefile index ba6b733dd2..e51cf0e17e 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,8 @@ +# frozen_string_literal: true + # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. -require File.expand_path('../config/application', __FILE__) +require File.expand_path('config/application', __dir__) Rails.application.load_tasks diff --git a/SECURITY.md b/SECURITY.md index ccc7c10346..3e13377db6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,8 +1,11 @@ # Security Policy -If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can reach us at . +If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can either: -You should *not* report such issues on GitHub or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk. +- open a [Github security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new) +- reach us at + +You should _not_ report such issues on public GitHub issues or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk. ## Scope @@ -10,8 +13,10 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through ## Supported Versions -| Version | Supported | -| ------- | ----------| -| 4.0.x | Yes | -| 3.5.x | Yes | -| < 3.5 | No | +| Version | Supported | +| ------- | ---------------- | +| 4.2.x | Yes | +| 4.1.x | Yes | +| 4.0.x | Until 2023-10-31 | +| 3.5.x | Until 2023-12-31 | +| < 3.5 | No | diff --git a/Vagrantfile b/Vagrantfile index 880cc18495..4303f8e067 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -60,6 +60,38 @@ sudo usermod -a -G rvm $USER SCRIPT +$provisionElasticsearch = < + + + + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/config.ru b/config.ru index d7295e4767..afd13e2112 100644 --- a/config.ru +++ b/config.ru @@ -1,5 +1,6 @@ # frozen_string_literal: true + # This file is used by Rack-based servers to start the application. -require ::File.expand_path('config/environment', __dir__) +require File.expand_path('config/environment', __dir__) run Rails.application diff --git a/config/application.rb b/config/application.rb index 55d98ca990..d98e332339 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,17 +1,19 @@ +# frozen_string_literal: true + require_relative 'boot' require 'rails' require 'active_record/railtie' -#require 'active_storage/engine' +# require 'active_storage/engine' require 'action_controller/railtie' require 'action_view/railtie' require 'action_mailer/railtie' require 'active_job/railtie' -#require 'action_cable/engine' -#require 'action_mailbox/engine' -#require 'action_text/engine' -#require 'rails/test_unit/railtie' +# require 'action_cable/engine' +# require 'action_mailbox/engine' +# require 'action_text/engine' +# require 'rails/test_unit/railtie' require 'sprockets/railtie' # Used to be implicitly required in action_mailbox/engine @@ -39,6 +41,8 @@ require_relative '../lib/mastodon/rack_middleware' require_relative '../lib/public_file_server_middleware' require_relative '../lib/devise/two_factor_ldap_authenticatable' require_relative '../lib/devise/two_factor_pam_authenticatable' +require_relative '../lib/chewy/settings_extensions' +require_relative '../lib/chewy/index_extensions' require_relative '../lib/chewy/strategy/mastodon' require_relative '../lib/chewy/strategy/bypass_with_warning' require_relative '../lib/webpacker/manifest_extensions' @@ -47,6 +51,7 @@ require_relative '../lib/rails/engine_extensions' require_relative '../lib/active_record/database_tasks_extensions' require_relative '../lib/active_record/batches' require_relative '../lib/simple_navigation/item_extensions' +require_relative '../lib/http_extensions' Dotenv::Railtie.load @@ -57,7 +62,15 @@ require_relative '../lib/mastodon/redis_config' module Mastodon class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 6.1 + config.load_defaults 7.0 + + # TODO: Release a version which uses the 7.0 defaults as specified above, + # but preserves the 6.1 cache format as set below. In a subsequent change, + # remove this line setting to 6.1 cache format, and then release another version. + # https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format + # https://github.com/mastodon/mastodon/pull/24241#discussion_r1162890242 + config.active_support.cache_format_version = 6.1 + config.add_autoload_paths_to_load_path = false # Settings in config/environments/* take precedence over those specified here. @@ -153,7 +166,6 @@ module Mastodon :sv, :szl, :ta, - :tai, :te, :th, :tr, @@ -182,22 +194,24 @@ module Mastodon # config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] config.active_job.queue_adapter = :sidekiq + config.action_mailer.deliver_later_queue_name = 'mailers' + config.action_mailer.preview_path = Rails.root.join('spec', 'mailers', 'previews') # We use our own middleware for this config.public_file_server.enabled = false - config.middleware.use PublicFileServerMiddleware if Rails.env.development? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true' + config.middleware.use PublicFileServerMiddleware if Rails.env.development? || Rails.env.test? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true' config.middleware.use Rack::Attack config.middleware.use Mastodon::RackMiddleware config.to_prepare do Doorkeeper::AuthorizationsController.layout 'modal' Doorkeeper::AuthorizedApplicationsController.layout 'admin' - Doorkeeper::Application.send :include, ApplicationExtension - Doorkeeper::AccessToken.send :include, AccessTokenExtension - Devise::FailureApp.send :include, AbstractController::Callbacks - Devise::FailureApp.send :include, Localized + Doorkeeper::Application.include ApplicationExtension + Doorkeeper::AccessToken.include AccessTokenExtension + Devise::FailureApp.include AbstractController::Callbacks + Devise::FailureApp.include Localized end end end diff --git a/config/boot.rb b/config/boot.rb index 4e379e7db5..3e44cbe581 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + unless ENV.key?('RAILS_ENV') STDERR.puts 'ERROR: Missing RAILS_ENV environment variable, please set it to "production", "development", or "test".' exit 1 @@ -6,12 +8,4 @@ end ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' # Set up gems listed in the Gemfile. -require 'bootsnap' # Speed up boot time by caching expensive operations. - -Bootsnap.setup( - cache_dir: File.expand_path('../tmp/cache', __dir__), - development_mode: ENV.fetch('RAILS_ENV', 'development') == 'development', - load_path_cache: true, - compile_cache_iseq: false, - compile_cache_yaml: false -) +require 'bootsnap/setup' # Speed up boot time by caching expensive operations. diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 80c5f6d4e5..02ce23a075 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -1,65 +1,5 @@ { "ignored_warnings": [ - { - "warning_type": "SQL Injection", - "warning_code": 0, - "fingerprint": "19df3740b8d02a9fe0eb52c939b4b87d3a2a591162a6adfa8d64e9c26aeebe6d", - "check_name": "SQL", - "message": "Possible SQL injection", - "file": "app/models/status.rb", - "line": 106, - "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", - "code": "result.joins(\"INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}\")", - "render_path": null, - "location": { - "type": "method", - "class": "Status", - "method": null - }, - "user_input": "id", - "confidence": "Weak", - "note": "" - }, - { - "warning_type": "SQL Injection", - "warning_code": 0, - "fingerprint": "30dfe36e87fe1b8f239df9a33d576e44a9863f73b680198d4713be6540ae61d3", - "check_name": "SQL", - "message": "Possible SQL injection", - "file": "app/models/trends/query.rb", - "line": 76, - "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", - "code": "klass.joins(\"join unnest(array[#{ids.join(\",\")}]) with ordinality as x (id, ordering) on #{klass.table_name}.id = x.id\")", - "render_path": null, - "location": { - "type": "method", - "class": "Trends::Query", - "method": "to_arel" - }, - "user_input": "ids.join(\",\")", - "confidence": "Weak", - "note": "" - }, - { - "warning_type": "Redirect", - "warning_code": 18, - "fingerprint": "5fad11cd67f905fab9b1d5739d01384a1748ebe78c5af5ac31518201925265a7", - "check_name": "Redirect", - "message": "Possible unprotected redirect", - "file": "app/controllers/remote_interaction_controller.rb", - "line": 24, - "link": "https://brakemanscanner.org/docs/warning_types/redirect/", - "code": "redirect_to(RemoteFollow.new(resource_params).interact_address_for(Status.find(params[:id])))", - "render_path": null, - "location": { - "type": "method", - "class": "RemoteInteractionController", - "method": "create" - }, - "user_input": "RemoteFollow.new(resource_params).interact_address_for(Status.find(params[:id]))", - "confidence": "High", - "note": "" - }, { "warning_type": "Cross-Site Scripting", "warning_code": 2, @@ -88,106 +28,33 @@ }, "user_input": "(Unresolved Model).new.strike", "confidence": "Weak", + "cwe_id": [ + 79 + ], "note": "" }, { - "warning_type": "SQL Injection", - "warning_code": 0, - "fingerprint": "75fcd147b7611763ab6915faf8c5b0709e612b460f27c05c72d8b9bd0a6a77f8", - "check_name": "SQL", - "message": "Possible SQL injection", - "file": "lib/mastodon/snowflake.rb", - "line": 87, - "link": "https://brakemanscanner.org/docs/warning_types/sql_injection/", - "code": "connection.execute(\"CREATE OR REPLACE FUNCTION timestamp_id(table_name text)\\nRETURNS bigint AS\\n$$\\n DECLARE\\n time_part bigint;\\n sequence_base bigint;\\n tail bigint;\\n BEGIN\\n time_part := (\\n -- Get the time in milliseconds\\n ((date_part('epoch', now()) * 1000))::bigint\\n -- And shift it over two bytes\\n << 16);\\n\\n sequence_base := (\\n 'x' ||\\n -- Take the first two bytes (four hex characters)\\n substr(\\n -- Of the MD5 hash of the data we documented\\n md5(table_name || '#{SecureRandom.hex(16)}' || time_part::text),\\n 1, 4\\n )\\n -- And turn it into a bigint\\n )::bit(16)::bigint;\\n\\n -- Finally, add our sequence number to our base, and chop\\n -- it to the last two bytes\\n tail := (\\n (sequence_base + nextval(table_name || '_id_seq'))\\n & 65535);\\n\\n -- Return the time part and the sequence part. OR appears\\n -- faster here than addition, but they're equivalent:\\n -- time_part has no trailing two bytes, and tail is only\\n -- the last two bytes.\\n RETURN time_part | tail;\\n END\\n$$ LANGUAGE plpgsql VOLATILE;\\n\")", + "warning_type": "Denial of Service", + "warning_code": 76, + "fingerprint": "7b6abba5699755348e7ee82a4694bfbf574b41c7cce2d0db0f7c11ae3f983c72", + "check_name": "RegexDoS", + "message": "Model attribute used in regular expression", + "file": "lib/mastodon/cli/domains.rb", + "line": 128, + "link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/", + "code": "/\\.?(#{DomainBlock.where(:severity => 1).pluck(:domain).map do\n Regexp.escape(domain)\n end.join(\"|\")})$/", "render_path": null, "location": { "type": "method", - "class": "Mastodon::Snowflake", - "method": "define_timestamp_id" + "class": "Mastodon::CLI::Domains", + "method": "crawl" }, - "user_input": "SecureRandom.hex(16)", - "confidence": "Medium", - "note": "" - }, - { - "warning_type": "Mass Assignment", - "warning_code": 105, - "fingerprint": "7631e93d0099506e7c3e5c91ba8d88523b00a41a0834ae30031a5a4e8bb3020a", - "check_name": "PermitAttributes", - "message": "Potentially dangerous key allowed for mass assignment", - "file": "app/controllers/api/v2/search_controller.rb", - "line": 28, - "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", - "code": "params.permit(:type, :offset, :min_id, :max_id, :account_id)", - "render_path": null, - "location": { - "type": "method", - "class": "Api::V2::SearchController", - "method": "search_params" - }, - "user_input": ":account_id", - "confidence": "High", - "note": "" - }, - { - "warning_type": "Mass Assignment", - "warning_code": 105, - "fingerprint": "874be88fedf4c680926845e9a588d3197765a6ccbfdd76466b44cc00151c612e", - "check_name": "PermitAttributes", - "message": "Potentially dangerous key allowed for mass assignment", - "file": "app/controllers/api/v1/admin/reports_controller.rb", - "line": 90, - "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", - "code": "params.permit(:resolved, :account_id, :target_account_id)", - "render_path": null, - "location": { - "type": "method", - "class": "Api::V1::Admin::ReportsController", - "method": "filter_params" - }, - "user_input": ":account_id", - "confidence": "High", - "note": "" - }, - { - "warning_type": "Mass Assignment", - "warning_code": 105, - "fingerprint": "ab5035dd1a9f8c3a8d92fb2c37e8fe86fede4f87c91b71aa32e89c9eede602fc", - "check_name": "PermitAttributes", - "message": "Potentially dangerous key allowed for mass assignment", - "file": "app/controllers/api/v1/notifications_controller.rb", - "line": 81, - "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", - "code": "params.permit(:account_id, :types => ([]), :exclude_types => ([]))", - "render_path": null, - "location": { - "type": "method", - "class": "Api::V1::NotificationsController", - "method": "browserable_params" - }, - "user_input": ":account_id", - "confidence": "High", - "note": "" - }, - { - "warning_type": "Redirect", - "warning_code": 18, - "fingerprint": "ba568ac09683f98740f663f3d850c31785900215992e8c090497d359a2563d50", - "check_name": "Redirect", - "message": "Possible unprotected redirect", - "file": "app/controllers/remote_follow_controller.rb", - "line": 21, - "link": "https://brakemanscanner.org/docs/warning_types/redirect/", - "code": "redirect_to(RemoteFollow.new(resource_params).subscribe_address_for(@account))", - "render_path": null, - "location": { - "type": "method", - "class": "RemoteFollowController", - "method": "create" - }, - "user_input": "RemoteFollow.new(resource_params).subscribe_address_for(@account)", - "confidence": "High", + "user_input": "DomainBlock.where(:severity => 1).pluck(:domain)", + "confidence": "Weak", + "cwe_id": [ + 20, + 185 + ], "note": "" }, { @@ -218,29 +85,12 @@ }, "user_input": "(Unresolved Model).new.url", "confidence": "Weak", - "note": "" - }, - { - "warning_type": "Mass Assignment", - "warning_code": 105, - "fingerprint": "f9de0ca4b04ae4b51b74d98db14dcbb6dae6809e627b58e711019cf9b4a47866", - "check_name": "PermitAttributes", - "message": "Potentially dangerous key allowed for mass assignment", - "file": "app/controllers/api/v1/reports_controller.rb", - "line": 26, - "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", - "code": "params.permit(:account_id, :comment, :category, :forward, :status_ids => ([]), :rule_ids => ([]))", - "render_path": null, - "location": { - "type": "method", - "class": "Api::V1::ReportsController", - "method": "report_params" - }, - "user_input": ":account_id", - "confidence": "High", + "cwe_id": [ + 79 + ], "note": "" } ], - "updated": "2022-03-22 07:48:32 +0100", - "brakeman_version": "5.2.1" + "updated": "2023-07-12 11:20:51 -0400", + "brakeman_version": "6.0.0" } diff --git a/config/brakeman.yml b/config/brakeman.yml new file mode 100644 index 0000000000..95ebc13865 --- /dev/null +++ b/config/brakeman.yml @@ -0,0 +1,3 @@ +--- +:skip_checks: + - CheckPermitAttributes diff --git a/config/database.yml b/config/database.yml index 34acf2f19a..b995f23178 100644 --- a/config/database.yml +++ b/config/database.yml @@ -8,29 +8,57 @@ default: &default application_name: '' development: - <<: *default - database: <%= ENV['DB_NAME'] || 'mastodon_development' %> - username: <%= ENV['DB_USER'] %> - password: <%= (ENV['DB_PASS'] || '').to_json %> - host: <%= ENV['DB_HOST'] %> - port: <%= ENV['DB_PORT'] %> + primary: + <<: *default + database: <%= ENV['DB_NAME'] || 'mastodon_development' %> + username: <%= ENV['DB_USER'] %> + password: <%= (ENV['DB_PASS'] || '').to_json %> + host: <%= ENV['DB_HOST'] %> + port: <%= ENV['DB_PORT'] %> + replica: + <<: *default + database: <%= ENV['DB_NAME'] || 'mastodon_development' %> + username: <%= ENV['DB_USER'] %> + password: <%= (ENV['DB_PASS'] || '').to_json %> + host: <%= ENV['DB_HOST'] %> + port: <%= ENV['DB_PORT'] %> + replica: true # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: - <<: *default - database: <%= ENV['DB_NAME'] || 'mastodon' %>_test<%= ENV['TEST_ENV_NUMBER'] %> - username: <%= ENV['DB_USER'] %> - password: <%= (ENV['DB_PASS'] || '').to_json %> - host: <%= ENV['DB_HOST'] %> - port: <%= ENV['DB_PORT'] %> + primary: + <<: *default + database: <%= ENV['DB_NAME'] || 'mastodon' %>_test<%= ENV['TEST_ENV_NUMBER'] %> + username: <%= ENV['DB_USER'] %> + password: <%= (ENV['DB_PASS'] || '').to_json %> + host: <%= ENV['DB_HOST'] %> + port: <%= ENV['DB_PORT'] %> + replica: + <<: *default + database: <%= ENV['DB_NAME'] || 'mastodon' %>_test<%= ENV['TEST_ENV_NUMBER'] %> + username: <%= ENV['DB_USER'] %> + password: <%= (ENV['DB_PASS'] || '').to_json %> + host: <%= ENV['DB_HOST'] %> + port: <%= ENV['DB_PORT'] %> + replica: true production: - <<: *default - database: <%= ENV['DB_NAME'] || 'mastodon_production' %> - username: <%= ENV['DB_USER'] || 'mastodon' %> - password: <%= (ENV['DB_PASS'] || '').to_json %> - host: <%= ENV['DB_HOST'] || 'localhost' %> - port: <%= ENV['DB_PORT'] || 5432 %> - prepared_statements: <%= ENV['PREPARED_STATEMENTS'] || 'true' %> + primary: + <<: *default + database: <%= ENV['DB_NAME'] || 'mastodon_production' %> + username: <%= ENV['DB_USER'] || 'mastodon' %> + password: <%= (ENV['DB_PASS'] || '').to_json %> + host: <%= ENV['DB_HOST'] || 'localhost' %> + port: <%= ENV['DB_PORT'] || 5432 %> + prepared_statements: <%= ENV['PREPARED_STATEMENTS'] || 'true' %> + replica: + <<: *default + database: <%= ENV['REPLICA_DB_NAME'] ||ENV['DB_NAME'] || 'mastodon_production' %> + username: <%= ENV['REPLICA_DB_USER'] ||ENV['DB_USER'] || 'mastodon' %> + password: <%= (ENV['REPLICA_DB_PASS'] || ENV['DB_PASS'] || '').to_json %> + host: <%= ENV['REPLICA_DB_HOST'] ||ENV['DB_HOST'] || 'localhost' %> + port: <%= ENV['REPLICA_DB_PORT'] ||ENV['DB_PORT'] || 5432 %> + prepared_statements: <%= ENV['PREPARED_STATEMENTS'] || 'true' %> + replica: true diff --git a/config/deploy.rb b/config/deploy.rb index b69a830674..b19567a729 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -lock '3.17.1' +lock '3.17.2' set :repo_url, ENV.fetch('REPO', 'https://github.com/mastodon/mastodon.git') set :branch, ENV.fetch('BRANCH', 'main') @@ -13,9 +13,12 @@ set :migration_role, :app append :linked_files, '.env.production', 'public/robots.txt' append :linked_dirs, 'vendor/bundle', 'node_modules', 'public/system' +SYSTEMD_SERVICES = %i[sidekiq streaming web].freeze +SERVICE_ACTIONS = %i[reload restart status].freeze + namespace :systemd do - %i[sidekiq streaming web].each do |service| - %i[reload restart status].each do |action| + SYSTEMD_SERVICES.each do |service| + SERVICE_ACTIONS.each do |action| desc "Perform a #{action} on #{service} service" task "#{service}:#{action}".to_sym do on roles(:app) do diff --git a/config/environment.rb b/config/environment.rb index caae5f1a0b..637d3829a9 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Load the Rails application. require_relative 'application' diff --git a/config/environments/development.rb b/config/environments/development.rb index c7b4a5d035..916fd5220a 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,37 +1,54 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/integer/time' + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false + config.hosts << 'wobbldev.tarrien.net' + # Do not eager load code on boot. config.eager_load = false # Show full error reports. config.consider_all_requests_local = true + # Enable server timing + config.server_timing = true + # Enable/disable caching. By default caching is disabled. # Run rails dev:cache to toggle caching. - if Rails.root.join('tmp/caching-dev.txt').exist? + if Rails.root.join('tmp', 'caching-dev.txt').exist? config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true + config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{2.days.to_i}", + } else config.action_controller.perform_caching = false config.cache_store = :null_store end + config.action_controller.forgery_protection_origin_check = ENV['DISABLE_FORGERY_REQUEST_PROTECTION'].nil? + ActiveSupport::Logger.new(STDOUT).tap do |logger| logger.formatter = config.log_formatter config.logger = ActiveSupport::TaggedLogging.new(logger) end # Generate random VAPID keys - vapid_key = Webpush.generate_key - config.x.vapid_private_key = vapid_key.private_key - config.x.vapid_public_key = vapid_key.public_key + Webpush.generate_key.tap do |vapid_key| + config.x.vapid_private_key = vapid_key.private_key + config.x.vapid_public_key = vapid_key.public_key + end # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false @@ -41,12 +58,19 @@ Rails.application.configure do # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + # Debug mode disables concatenation and preprocessing of assets. - # This option may cause significant delays in view rendering with a large - # number of complex assets. config.assets.debug = true # Suppress logger output for asset requests. @@ -57,12 +81,14 @@ Rails.application.configure do # Raises helpful error messages. config.assets.raise_runtime_errors = true - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true - # Use an evented file watcher to asynchronously detect changes in source code, - # routes, locales, etc. This feature depends on the listen gem. - # config.file_watcher = ActiveSupport::EventedFileUpdateChecker + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true config.action_mailer.default_options = { from: 'notifications@localhost' } @@ -71,21 +97,9 @@ Rails.application.configure do # Otherwise, use letter_opener, which launches a browser window to view sent mail. config.action_mailer.delivery_method = (ENV['HEROKU'] || ENV['VAGRANT'] || ENV['REMOTE_DEV']) ? :letter_opener_web : :letter_opener - config.after_initialize do - Bullet.enable = true - Bullet.bullet_logger = true - Bullet.rails_logger = false - - Bullet.add_safelist type: :n_plus_one_query, class_name: 'User', association: :account - end - + # We provide a default secret for the development environment here. + # This value should not be used in production environments! config.x.otp_secret = ENV.fetch('OTP_SECRET', '1fc2b87989afa6351912abeebe31ffc5c476ead9bf8b3d74cbc4a302c7b69a45b40b1bbef3506ddad73e942e15ed5ca4b402bf9a66423626051104f4b5f05109') end -ActiveRecordQueryTrace.enabled = ENV['QUERY_TRACE_ENABLED'] == 'true' - -module PrivateAddressCheck - def self.private_address?(*) - false - end -end +Redis.raise_deprecations = true diff --git a/config/environments/production.rb b/config/environments/production.rb index 00d7834775..54fbe2c13f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,3 +1,7 @@ +# frozen_string_literal: true + +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -19,27 +23,33 @@ Rails.application.configure do # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). # config.require_master_key = true - ActiveSupport::Logger.new(STDOUT).tap do |logger| - logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) - end + # Compress CSS using a preprocessor. + # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + # Specifies the header that your server uses for sending files. config.action_dispatch.x_sendfile_header = ENV['SENDFILE_HEADER'] if ENV['SENDFILE_HEADER'].present? + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache + # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX # Allow to specify public IP of reverse proxy if it's needed config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split(/(?:\s*,\s*|\s+)/).map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present? + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true config.ssl_options = { redirect: { - exclude: -> request { request.path.start_with?('/health') || request.headers["Host"].end_with?('.onion') || request.headers["Host"].end_with?('.i2p') } + exclude: ->request { request.path.start_with?('/health') || request.headers["Host"].end_with?('.onion') || request.headers["Host"].end_with?('.i2p') } } } + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). # Use the lowest log level to ensure availability of diagnostic information # when problems arise. config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info').to_sym @@ -50,13 +60,19 @@ Rails.application.configure do # Use a different cache store in production. config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS + # Use a real queuing backend for Active Job (and separate queues per environment). + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "mastodon_production" + + config.action_mailer.perform_caching = false + # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # English when a translation cannot be found). - config.i18n.fallbacks = true + config.i18n.fallbacks = [:en] # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify @@ -73,6 +89,15 @@ Rails.application.configure do end end + # Use a different logger for distributed setups. + # require "syslog/logger" + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") + + ActiveSupport::Logger.new(STDOUT).tap do |logger| + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false @@ -123,12 +148,12 @@ Rails.application.configure do config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym config.action_dispatch.default_headers = { - 'Server' => 'Mastodon', - 'X-Frame-Options' => 'DENY', + 'Server' => 'Mastodon', + 'X-Frame-Options' => 'DENY', 'X-Content-Type-Options' => 'nosniff', - 'X-XSS-Protection' => '0', - 'Permissions-Policy' => 'interest-cohort=()', - 'Referrer-Policy' => 'same-origin', + 'X-XSS-Protection' => '0', + 'X-Clacks-Overhead' => 'GNU Natalie Nguyen', + 'Referrer-Policy' => 'same-origin', } config.x.otp_secret = ENV.fetch('OTP_SECRET') diff --git a/config/environments/test.rb b/config/environments/test.rb index 44786962ae..210329848e 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,25 +1,28 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/integer/time' + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! + # Turn false under Spring and add config.action_view.cache_template_loading = true. config.cache_classes = true - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false + # Eager loading loads your whole application. When running a single test locally, + # this probably isn't necessary. It's a good idea to do in a continuous integration + # system, or in some way before deploying your code. + config.eager_load = ENV['CI'].present? - config.assets.digest = false + config.assets_digest = false # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false - - # The default store, file_store is shared by processes parallelly executed - # and should not be used. config.cache_store = :memory_store # Raise exceptions instead of rendering exception templates. @@ -27,6 +30,7 @@ Rails.application.configure do # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + config.action_mailer.perform_caching = false config.action_mailer.default_options = { from: 'notifications@localhost' } @@ -46,14 +50,32 @@ Rails.application.configure do config.x.vapid_private_key = vapid_key.private_key config.x.vapid_public_key = vapid_key.public_key - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Raise exceptions when a reorder occurs in in_batches + config.active_record.error_on_ignored_order = true + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise config.i18n.default_locale = :en config.i18n.fallbacks = true + + config.to_prepare do + # Force Status to always be SHAPE_TOO_COMPLEX + # Ref: https://github.com/mastodon/mastodon/issues/23644 + 10.times { |i| Status.allocate.instance_variable_set(:"@ivar_#{i}", nil) } + end + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true end -Paperclip::Attachment.default_options[:path] = "#{Rails.root}/spec/test_files/:class/:id_partition/:style.:extension" +Paperclip::Attachment.default_options[:path] = Rails.root.join('spec', 'test_files', ':class', ':id_partition', ':style.:extension') # set fake_data for pam, don't do real calls, just use fake data if ENV['PAM_ENABLED'] == 'true' @@ -68,3 +90,5 @@ end # Catch serialization warnings early Sidekiq.strict_args! + +Redis.raise_deprecations = true diff --git a/config/formatjs-formatter.js b/config/formatjs-formatter.js new file mode 100644 index 0000000000..9be5dd7e26 --- /dev/null +++ b/config/formatjs-formatter.js @@ -0,0 +1,14 @@ +const path = require('path'); + +const upstreamTranslations = require(path.join(__dirname, "../app/javascript/mastodon/locales/en.json")); +const currentTranslations = require(path.join(__dirname, "../app/javascript/flavours/glitch/locales/en.json")); + +exports.format = (msgs) => { + const results = {}; + for (const [id, msg] of Object.entries(msgs)) { + if (!upstreamTranslations[id]) { + results[id] = currentTranslations[id] || msg.defaultMessage; + } + } + return results; +}; diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 46dd3124bf..e5a4eb9a82 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -4,12 +4,19 @@ base_locale: en data: read: - - config/locales/%{locale}.yml - - config/locales/**/*.%{locale}.yml + - config/locales-glitch/%{locale}.yml + - config/locales-glitch/*.%{locale}.yml write: - - ['{devise, simple_form, doorkeeper}.*', 'config/locales/\1.%{locale}.yml'] + - [ + '{devise, simple_form, doorkeeper}.*', + 'config/locales-glitch/\1.%{locale}.yml', + ] + - config/locales-glitch/%{locale}.yml + + external: - config/locales/%{locale}.yml + - config/locales/**/*.%{locale}.yml yaml: write: @@ -50,7 +57,7 @@ ignore_unused: - 'activerecord.errors.*' - '{devise,pagination,doorkeeper}.*' - '{date,datetime,time,number}.*' - - 'simple_form.{yes,no,recommended,not_recommended}' + - 'simple_form.{yes,no,recommended,not_recommended,overridden,glitch_only}' - 'simple_form.{placeholders,hints,labels}.*' - 'simple_form.{error_notification,required}.:' - 'errors.messages.*' @@ -62,8 +69,14 @@ ignore_unused: - 'admin.reports.summary.actions.*' - 'admin_mailer.new_appeal.actions.*' - 'statuses.attached.*' + - 'themes.*' - 'move_handler.carry_{mutes,blocks}_over_text' + - 'admin_mailer.*.subject' - 'notification_mailer.*' + - 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' + - 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' + - 'mail_subscriptions.unsubscribe.emails.*' + - 'preferences.other' # some locales are missing other keys, therefore leading i18n-tasks to detect `preferences` as plural and not finding use ignore_inconsistent_interpolations: - '*.one' diff --git a/config/imagemagick/policy.xml b/config/imagemagick/policy.xml index 1052476b31..e2aa202f27 100644 --- a/config/imagemagick/policy.xml +++ b/config/imagemagick/policy.xml @@ -22,6 +22,6 @@ - + diff --git a/config/initializers/0_duplicate_migrations.rb b/config/initializers/0_duplicate_migrations.rb new file mode 100644 index 0000000000..1b8b590255 --- /dev/null +++ b/config/initializers/0_duplicate_migrations.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# Some migrations have been present in glitch-soc for a long time and have then +# been merged in upstream Mastodon, under a different version number. +# +# This puts us in an uneasy situation in which if we remove upstream's +# migration file, people migrating from upstream will end up having a conflict +# with their already-ran migration. +# +# On the other hand, if we keep upstream's migration and remove our own, +# any current glitch-soc user will have a conflict during migration. +# +# For lack of a better solution, as those migrations are indeed identical, +# we decided monkey-patching Rails' Migrator to completely ignore the duplicate, +# keeping only the one that has run, or an arbitrary one. + +ALLOWED_DUPLICATES = [2018_04_10_220657, 2018_08_31_171112].freeze + +module ActiveRecord + class Migrator + def self.new(direction, migrations, schema_migration, target_version = nil) + migrated = Set.new(Base.connection.migration_context.get_all_versions) + + migrations.group_by(&:name).each do |_name, duplicates| + next unless duplicates.length > 1 && duplicates.all? { |m| ALLOWED_DUPLICATES.include?(m.version) } + + # We have a set of allowed duplicates. Keep the migrated one, if any. + non_migrated = duplicates.reject { |m| migrated.include?(m.version.to_i) } + + migrations = begin + if duplicates.length == non_migrated.length || non_migrated.empty? + # There weren't any migrated one, so we have to pick one “canonical” migration + migrations - duplicates[1..] + else + # Just reject every duplicate which hasn't been migrated yet + migrations - non_migrated + end + end + end + + super(direction, migrations, schema_migration, target_version) + end + end + + class MigrationContext + def needs_migration? + # A set of duplicated migrations is considered migrated if at least one of + # them is migrated. + migrated = get_all_versions + migrations.group_by(&:name).each do |_name, duplicates| + return true unless duplicates.any? { |m| migrated.include?(m.version.to_i) } + end + false + end + end +end diff --git a/config/initializers/0_post_deployment_migrations.rb b/config/initializers/0_post_deployment_migrations.rb index 61121ccd70..8e4d63a2e5 100644 --- a/config/initializers/0_post_deployment_migrations.rb +++ b/config/initializers/0_post_deployment_migrations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Post deployment migrations are included by default. This file must be loaded # before other initializers as Rails may otherwise memoize a list of migrations # excluding the post deployment migrations. diff --git a/config/initializers/2_limited_federation_mode.rb b/config/initializers/2_limited_federation_mode.rb new file mode 100644 index 0000000000..d5f7652d58 --- /dev/null +++ b/config/initializers/2_limited_federation_mode.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +Rails.application.configure do + config.x.limited_federation_mode = (ENV['LIMITED_FEDERATION_MODE'] || ENV['WHITELIST_MODE']) == 'true' + + warn 'WARN: The environment variable WHITELIST_MODE has been replaced with LIMITED_FEDERATION_MODE, you should rename this environment variable in your configuration.' if ENV.key?('WHITELIST_MODE') +end diff --git a/config/initializers/2_whitelist_mode.rb b/config/initializers/2_whitelist_mode.rb deleted file mode 100644 index 1cc6a8e724..0000000000 --- a/config/initializers/2_whitelist_mode.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -Rails.application.configure do - config.x.whitelist_mode = (ENV['LIMITED_FEDERATION_MODE'] || ENV['WHITELIST_MODE']) == 'true' -end diff --git a/config/initializers/omniauth.rb b/config/initializers/3_omniauth.rb similarity index 81% rename from config/initializers/omniauth.rb rename to config/initializers/3_omniauth.rb index f016701467..566e7362a5 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -1,3 +1,9 @@ +# frozen_string_literal: true + +# OmniAuth providers need to be initialized before the CSP initializer +# in `config/initializers/content_security_policy.rb`, which sets the +# `form-action` directive based on them. + Rails.application.config.middleware.use OmniAuth::Builder do # Vanilla omniauth strategies end @@ -70,35 +76,35 @@ Devise.setup do |config| # OpenID Connect Strategy if ENV['OIDC_ENABLED'] == 'true' oidc_options = {} - oidc_options[:display_name] = ENV['OIDC_DISPLAY_NAME'] #OPTIONAL - oidc_options[:issuer] = ENV['OIDC_ISSUER'] if ENV['OIDC_ISSUER'] #NEED - oidc_options[:discovery] = ENV['OIDC_DISCOVERY'] == 'true' if ENV['OIDC_DISCOVERY'] #OPTIONAL (default: false) - oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] #OPTIONAL (default: basic) - scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] #NEED + oidc_options[:display_name] = ENV['OIDC_DISPLAY_NAME'] # OPTIONAL + oidc_options[:issuer] = ENV['OIDC_ISSUER'] if ENV['OIDC_ISSUER'] # NEED + oidc_options[:discovery] = ENV['OIDC_DISCOVERY'] == 'true' if ENV['OIDC_DISCOVERY'] # OPTIONAL (default: false) + oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic) + scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] # NEED scopes = scope_string.split(',') oidc_options[:scope] = scopes.map { |x| x.to_sym } - oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] #OPTIONAL (default: code) - oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] #OPTIONAL (default: query) - oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] #OPTIONAL (default: page) - oidc_options[:prompt] = ENV['OIDC_PROMPT'] if ENV['OIDC_PROMPT'] #OPTIONAL - oidc_options[:send_nonce] = ENV['OIDC_SEND_NONCE'] == 'true' if ENV['OIDC_SEND_NONCE'] #OPTIONAL (default: true) - oidc_options[:send_scope_to_token_endpoint] = ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] == 'true' if ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] #OPTIONAL (default: true) - oidc_options[:post_logout_redirect_uri] = ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] if ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] #OPTIONAL - oidc_options[:uid_field] = ENV['OIDC_UID_FIELD'] if ENV['OIDC_UID_FIELD'] #NEED + oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] # OPTIONAL (default: code) + oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] # OPTIONAL (default: query) + oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] # OPTIONAL (default: page) + oidc_options[:prompt] = ENV['OIDC_PROMPT'] if ENV['OIDC_PROMPT'] # OPTIONAL + oidc_options[:send_nonce] = ENV['OIDC_SEND_NONCE'] == 'true' if ENV['OIDC_SEND_NONCE'] # OPTIONAL (default: true) + oidc_options[:send_scope_to_token_endpoint] = ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] == 'true' if ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] # OPTIONAL (default: true) + oidc_options[:post_logout_redirect_uri] = ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] if ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] # OPTIONAL + oidc_options[:uid_field] = ENV['OIDC_UID_FIELD'] if ENV['OIDC_UID_FIELD'] # NEED oidc_options[:client_options] = {} - oidc_options[:client_options][:identifier] = ENV['OIDC_CLIENT_ID'] if ENV['OIDC_CLIENT_ID'] #NEED - oidc_options[:client_options][:secret] = ENV['OIDC_CLIENT_SECRET'] if ENV['OIDC_CLIENT_SECRET'] #NEED - oidc_options[:client_options][:redirect_uri] = ENV['OIDC_REDIRECT_URI'] if ENV['OIDC_REDIRECT_URI'] #NEED - oidc_options[:client_options][:scheme] = ENV['OIDC_HTTP_SCHEME'] if ENV['OIDC_HTTP_SCHEME'] #OPTIONAL (default: https) - oidc_options[:client_options][:host] = ENV['OIDC_HOST'] if ENV['OIDC_HOST'] #OPTIONAL - oidc_options[:client_options][:port] = ENV['OIDC_PORT'] if ENV['OIDC_PORT'] #OPTIONAL - oidc_options[:client_options][:authorization_endpoint] = ENV['OIDC_AUTH_ENDPOINT'] if ENV['OIDC_AUTH_ENDPOINT'] #NEED when discovery != true - oidc_options[:client_options][:token_endpoint] = ENV['OIDC_TOKEN_ENDPOINT'] if ENV['OIDC_TOKEN_ENDPOINT'] #NEED when discovery != true - oidc_options[:client_options][:userinfo_endpoint] = ENV['OIDC_USER_INFO_ENDPOINT'] if ENV['OIDC_USER_INFO_ENDPOINT'] #NEED when discovery != true - oidc_options[:client_options][:jwks_uri] = ENV['OIDC_JWKS_URI'] if ENV['OIDC_JWKS_URI'] #NEED when discovery != true - oidc_options[:client_options][:end_session_endpoint] = ENV['OIDC_END_SESSION_ENDPOINT'] if ENV['OIDC_END_SESSION_ENDPOINT'] #OPTIONAL + oidc_options[:client_options][:identifier] = ENV['OIDC_CLIENT_ID'] if ENV['OIDC_CLIENT_ID'] # NEED + oidc_options[:client_options][:secret] = ENV['OIDC_CLIENT_SECRET'] if ENV['OIDC_CLIENT_SECRET'] # NEED + oidc_options[:client_options][:redirect_uri] = ENV['OIDC_REDIRECT_URI'] if ENV['OIDC_REDIRECT_URI'] # NEED + oidc_options[:client_options][:scheme] = ENV['OIDC_HTTP_SCHEME'] if ENV['OIDC_HTTP_SCHEME'] # OPTIONAL (default: https) + oidc_options[:client_options][:host] = ENV['OIDC_HOST'] if ENV['OIDC_HOST'] # OPTIONAL + oidc_options[:client_options][:port] = ENV['OIDC_PORT'] if ENV['OIDC_PORT'] # OPTIONAL + oidc_options[:client_options][:authorization_endpoint] = ENV['OIDC_AUTH_ENDPOINT'] if ENV['OIDC_AUTH_ENDPOINT'] # NEED when discovery != true + oidc_options[:client_options][:token_endpoint] = ENV['OIDC_TOKEN_ENDPOINT'] if ENV['OIDC_TOKEN_ENDPOINT'] # NEED when discovery != true + oidc_options[:client_options][:userinfo_endpoint] = ENV['OIDC_USER_INFO_ENDPOINT'] if ENV['OIDC_USER_INFO_ENDPOINT'] # NEED when discovery != true + oidc_options[:client_options][:jwks_uri] = ENV['OIDC_JWKS_URI'] if ENV['OIDC_JWKS_URI'] # NEED when discovery != true + oidc_options[:client_options][:end_session_endpoint] = ENV['OIDC_END_SESSION_ENDPOINT'] if ENV['OIDC_END_SESSION_ENDPOINT'] # OPTIONAL oidc_options[:security] = {} - oidc_options[:security][:assume_email_is_verified] = ENV['OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' #OPTIONAL + oidc_options[:security][:assume_email_is_verified] = ENV['OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' # OPTIONAL config.omniauth :openid_connect, oidc_options end end diff --git a/config/initializers/active_model_serializers.rb b/config/initializers/active_model_serializers.rb index 0e69e1d96c..46f2bb8b98 100644 --- a/config/initializers/active_model_serializers.rb +++ b/config/initializers/active_model_serializers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveModelSerializers.config.tap do |config| config.default_includes = '**' end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index 89d2efab2b..f4556db399 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # ActiveSupport::Reloader.to_prepare do diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 53b39718da..e1fd5f8ced 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -1,13 +1,16 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Version of your assets, change this if you want to expire all your assets. Rails.application.config.assets.version = '1.0' -# Add additional assets to the asset load path -# Rails.application.config.assets.paths << 'node_modules' +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path # Precompile additional assets. -# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -# Rails.application.config.assets.precompile += %w() +# application.js, application.css, and all non-JS/CSS in the app/assets +# folder are already added. +# Rails.application.config.assets.precompile += %w( admin.js admin.css ) Rails.application.config.assets.initialize_on_precompile = true diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index 33699c3091..74f30e8875 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. diff --git a/config/initializers/cache_buster.rb b/config/initializers/cache_buster.rb index 227e450f35..a49fba671b 100644 --- a/config/initializers/cache_buster.rb +++ b/config/initializers/cache_buster.rb @@ -6,5 +6,6 @@ Rails.application.configure do config.x.cache_buster = { secret_header: ENV['CACHE_BUSTER_SECRET_HEADER'], secret: ENV['CACHE_BUSTER_SECRET'], + http_method: ENV['CACHE_BUSTER_HTTP_METHOD'] || 'GET', } end diff --git a/config/initializers/cache_logging.rb b/config/initializers/cache_logging.rb index 08aa807421..4f4b2ebe98 100644 --- a/config/initializers/cache_logging.rb +++ b/config/initializers/cache_logging.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Log cache errors with Rail's logger # This used to be the default in old Rails versions: https://github.com/rails/rails/commit/7fcf8590e788cef8b64cc266f75931c418902ca9#diff-f0748f0be8a653eea13369ebb1cadabcad71ede7cfaf20282447e64329817befL86 Rails.cache.logger = Rails.logger diff --git a/config/initializers/chewy.rb b/config/initializers/chewy.rb index daf4a5f326..66008a0009 100644 --- a/config/initializers/chewy.rb +++ b/config/initializers/chewy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + enabled = ENV['ES_ENABLED'] == 'true' host = ENV.fetch('ES_HOST') { 'localhost' } port = ENV.fetch('ES_PORT') { 9200 } @@ -13,6 +15,9 @@ Chewy.settings = { journal: false, user: user, password: password, + index: { + number_of_replicas: ['single_node_cluster', nil].include?(ENV['ES_PRESET'].presence) ? 0 : 1, + }, } # We use our own async strategy even outside the request-response @@ -23,14 +28,6 @@ Chewy.root_strategy = :bypass_with_warning if Rails.env.production? Chewy.request_strategy = :mastodon Chewy.use_after_commit_callbacks = false -module Chewy - class << self - def enabled? - settings[:enabled] - end - end -end - # Elasticsearch uses Faraday internally. Faraday interprets the # http_proxy env variable by default which leads to issues when # Mastodon is run with hidden services enabled, because diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 1f66155c46..99c6ec023b 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -1,45 +1,72 @@ +# frozen_string_literal: true + # Define an application-wide content security policy # For further information see the following documentation # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy -def host_to_url(str) - "http#{Rails.configuration.x.use_https ? 's' : ''}://#{str}".split('/').first if str.present? +def sso_host + return unless ENV['ONE_CLICK_SSO_LOGIN'] == 'true' + return unless ENV['OMNIAUTH_ONLY'] == 'true' + return unless Devise.omniauth_providers.length == 1 + + provider = Devise.omniauth_configs[Devise.omniauth_providers[0]] + @sso_host ||= begin + case provider.provider + when :cas + provider.cas_url + when :saml + provider.options[:idp_sso_target_url] + when :openid_connect + provider.options.dig(:client_options, :authorization_endpoint) || OpenIDConnect::Discovery::Provider::Config.discover!(provider.options[:issuer]).authorization_endpoint + end + end end -base_host = Rails.configuration.x.web_domain +unless Rails.env.development? + assets_host = Rails.configuration.action_controller.asset_host || "https://#{ENV['WEB_DOMAIN'] || ENV['LOCAL_DOMAIN']}" + data_hosts = [assets_host] -assets_host = Rails.configuration.action_controller.asset_host -assets_host ||= host_to_url(base_host) - -media_host = host_to_url(ENV['S3_ALIAS_HOST']) -media_host ||= host_to_url(ENV['S3_CLOUDFRONT_HOST']) -media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true' -media_host ||= assets_host - -Rails.application.config.content_security_policy do |p| - p.base_uri :none - p.default_src :none - p.frame_ancestors :none - p.font_src :self, assets_host - p.img_src :self, :https, :data, :blob, assets_host - p.style_src :self, assets_host - p.media_src :self, :https, :data, assets_host - p.frame_src :self, :https - p.manifest_src :self, assets_host - p.form_action :self - - if Rails.env.development? - webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{Webpacker.dev_server.host_with_port}" } - - p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls - p.script_src :self, :unsafe_inline, :unsafe_eval, assets_host - p.child_src :self, :blob, assets_host - p.worker_src :self, :blob, assets_host + if ENV['S3_ENABLED'] == 'true' || ENV['AZURE_ENABLED'] == 'true' + attachments_host = "https://#{ENV['S3_ALIAS_HOST'] || ENV['S3_CLOUDFRONT_HOST'] || ENV['AZURE_ALIAS_HOST'] || ENV['S3_HOSTNAME'] || "s3-#{ENV['S3_REGION'] || 'us-east-1'}.amazonaws.com"}" + attachments_host = "https://#{Addressable::URI.parse(attachments_host).host}" + elsif ENV['SWIFT_ENABLED'] == 'true' + attachments_host = ENV['SWIFT_OBJECT_URL'] + attachments_host = "https://#{Addressable::URI.parse(attachments_host).host}" else - p.connect_src :self, :data, :blob, assets_host, media_host, Rails.configuration.x.streaming_api_base_url - p.script_src :self, assets_host, "'wasm-unsafe-eval'" - p.child_src :self, :blob, assets_host - p.worker_src :self, :blob, assets_host + attachments_host = nil + end + + data_hosts << attachments_host unless attachments_host.nil? + + if ENV['PAPERCLIP_ROOT_URL'] + url = Addressable::URI.parse(assets_host) + ENV['PAPERCLIP_ROOT_URL'] + data_hosts << "https://#{url.host}" + end + + data_hosts.concat(ENV['EXTRA_DATA_HOSTS'].split('|')) if ENV['EXTRA_DATA_HOSTS'] + + data_hosts.uniq! + + Rails.application.config.content_security_policy do |p| + p.base_uri :none + p.default_src :none + p.frame_ancestors :none + p.script_src :self, assets_host, "'wasm-unsafe-eval'" + p.font_src :self, assets_host + p.img_src :self, :data, :blob, *data_hosts + p.style_src :self, assets_host + p.media_src :self, :data, *data_hosts + p.frame_src :self, :https + p.child_src :self, :blob, assets_host + p.worker_src :self, :blob, assets_host + p.connect_src :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts + p.manifest_src :self, assets_host + + if sso_host.present? + p.form_action :self, sso_host + else + p.form_action :self + end end end @@ -48,7 +75,7 @@ end # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only # Rails.application.config.content_security_policy_report_only = true -Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } +Rails.application.config.content_security_policy_nonce_generator = ->request { SecureRandom.base64(16) } Rails.application.config.content_security_policy_nonce_directives = %w(style-src) diff --git a/config/initializers/cookie_rotator.rb b/config/initializers/cookie_rotator.rb new file mode 100644 index 0000000000..b829b1a90b --- /dev/null +++ b/config/initializers/cookie_rotator.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# TODO: Remove after 4.2.0 +Rails.application.configure do + config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1 +end + +Rails.application.config.after_initialize do + Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies| + authenticated_encrypted_cookie_salt = Rails.application.config.action_dispatch.authenticated_encrypted_cookie_salt + signed_cookie_salt = Rails.application.config.action_dispatch.signed_cookie_salt + + secret_key_base = Rails.application.secret_key_base + + # TODO: Switch to SHA1 after 4.2.0 + key_generator = ActiveSupport::KeyGenerator.new( + secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256 + ) + key_len = ActiveSupport::MessageEncryptor.key_len + + old_encrypted_secret = key_generator.generate_key(authenticated_encrypted_cookie_salt, key_len) + old_signed_secret = key_generator.generate_key(signed_cookie_salt) + + cookies.rotate :encrypted, old_encrypted_secret + cookies.rotate :signed, old_signed_secret + end +end diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb index 5a6a32d371..ee8dff9c99 100644 --- a/config/initializers/cookies_serializer.rb +++ b/config/initializers/cookies_serializer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Specify a serializer for the signed and encrypted cookie jars. diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb index 55f8c9c919..3d94e38e8e 100644 --- a/config/initializers/cors.rb +++ b/config/initializers/cors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Avoid CORS issues when API is called from the frontend app. @@ -9,26 +11,16 @@ Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '*' - resource '/.well-known/*', - headers: :any, - methods: [:get], - credentials: false - resource '/@:username', - headers: :any, - methods: [:get], - credentials: false - resource '/users/:username', - headers: :any, - methods: [:get], - credentials: false - resource '/api/*', - headers: :any, - methods: [:post, :put, :delete, :get, :patch, :options], - credentials: false, - expose: ['Link', 'X-RateLimit-Reset', 'X-RateLimit-Limit', 'X-RateLimit-Remaining', 'X-Request-Id'] - resource '/oauth/token', - headers: :any, - methods: [:post], - credentials: false + with_options headers: :any, credentials: false do + with_options methods: [:get] do + resource '/.well-known/*' + resource '/@:username' + resource '/users/:username' + end + resource '/api/*', + expose: %w(Link X-RateLimit-Reset X-RateLimit-Limit X-RateLimit-Remaining X-Request-Id), + methods: %i(post put delete get patch options) + resource '/oauth/token', methods: [:post] + end end end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index d7b252c3f2..7bbaff71f0 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'devise/strategies/authenticatable' Warden::Manager.after_set_user except: :fetch do |user, warden| diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 43aac5769f..a78405ace6 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Doorkeeper.configure do # Change the ORM that doorkeeper will use (needs plugins) orm :active_record diff --git a/config/initializers/fast_blank.rb b/config/initializers/fast_blank.rb index f0b7cac78b..349fc023c3 100644 --- a/config/initializers/fast_blank.rb +++ b/config/initializers/fast_blank.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + if String.method_defined?(:blank_as?) class String alias blank? blank_as? diff --git a/config/initializers/ffmpeg.rb b/config/initializers/ffmpeg.rb index 4c0bf779d8..30ea617fcd 100644 --- a/config/initializers/ffmpeg.rb +++ b/config/initializers/ffmpeg.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + if ENV['FFMPEG_BINARY'].present? - FFMPEG.ffmpeg_binary = ENV['FFMPEG_BINARY'] + FFMPEG.ffmpeg_binary = ENV['FFMPEG_BINARY'] end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 06cb15bbb1..ca55f952da 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -1,4 +1,10 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. -# Configure sensitive parameters which will be filtered from the log file. -Rails.application.config.filter_parameters += [:password, :private_key, :public_key, :otp_attempt] +# Configure parameters to be filtered from the log file. Use this to limit dissemination of +# sensitive information. See the ActiveSupport::ParameterFilter documentation for supported +# notations and behaviors. +Rails.application.config.filter_parameters += [ + :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +] diff --git a/config/initializers/http_client_proxy.rb b/config/initializers/http_client_proxy.rb index b29e9edd75..7332ffb53b 100644 --- a/config/initializers/http_client_proxy.rb +++ b/config/initializers/http_client_proxy.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Rails.application.configure do config.x.http_client_proxy = {} diff --git a/config/initializers/httplog.rb b/config/initializers/httplog.rb index 5cfc16a8b5..02fcef4120 100644 --- a/config/initializers/httplog.rb +++ b/config/initializers/httplog.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + HttpLog.configure do |config| config.logger = Rails.logger config.color = { color: :yellow } diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index a361cb0ec3..0dad009b1f 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections @@ -26,6 +28,7 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'URL' inflect.acronym 'ASCII' inflect.acronym 'DeepL' + inflect.acronym 'DSL' inflect.singular 'data', 'data' end diff --git a/config/initializers/locale.rb b/config/initializers/locale.rb new file mode 100644 index 0000000000..4bcb1854cb --- /dev/null +++ b/config/initializers/locale.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +Rails.application.configure do + config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'flavours', '*', 'names.{rb,yml}').to_s] + config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'flavours', '*', 'names', '*.{rb,yml}').to_s] + config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'skins', '*', '*', 'names.{rb,yml}').to_s] + config.i18n.load_path += Dir[Rails.root.join('app', 'javascript', 'skins', '*', '*', 'names', '*.{rb,yml}').to_s] + config.i18n.load_path += Dir[Rails.root.join('config', 'locales-glitch', '*.{rb,yml}').to_s] +end diff --git a/config/initializers/mail_delivery_job.rb b/config/initializers/mail_delivery_job.rb index 3278173966..5c8af84216 100644 --- a/config/initializers/mail_delivery_job.rb +++ b/config/initializers/mail_delivery_job.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActionMailer::MailDeliveryJob.class_eval do discard_on ActiveJob::DeserializationError end diff --git a/config/initializers/makara.rb b/config/initializers/makara.rb deleted file mode 100644 index dc88fa63cd..0000000000 --- a/config/initializers/makara.rb +++ /dev/null @@ -1,2 +0,0 @@ -Makara::Cookie::DEFAULT_OPTIONS[:same_site] = :lax -Makara::Cookie::DEFAULT_OPTIONS[:secure] = Rails.env.production? || ENV['LOCAL_HTTPS'] == 'true' diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 58a6c0063e..dde308cbc1 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -1,4 +1,7 @@ -# Be sure to restart your server when you modify this file. +# frozen_string_literal: true Mime::Type.register 'application/json', :json, %w(text/x-json application/jsonrequest application/jrd+json application/activity+json application/ld+json) Mime::Type.register 'text/xml', :xml, %w(application/xml application/atom+xml application/xrd+xml) + +# WebP is not defined in Rack 2.2. +Rack::Mime::MIME_TYPES['.webp'] = 'image/webp' diff --git a/config/initializers/new_framework_defaults_7_0.rb b/config/initializers/new_framework_defaults_7_0.rb new file mode 100644 index 0000000000..edaf819447 --- /dev/null +++ b/config/initializers/new_framework_defaults_7_0.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# TODO +# The Rails 7.0 framework default here is to set this true. However, we have a +# location in devise that redirects where we don't have an easy ability to +# override a method or set a config option, but where the redirect does not +# provide this option. +# https://github.com/heartcombo/devise/blob/v4.9.2/app/controllers/devise/confirmations_controller.rb#L28 +# Once a solution is found, this line can be removed. +Rails.application.config.action_controller.raise_on_open_redirects = false diff --git a/config/initializers/oj.rb b/config/initializers/oj.rb index de3e17f2eb..9b2d908637 100644 --- a/config/initializers/oj.rb +++ b/config/initializers/oj.rb @@ -1 +1,3 @@ +# frozen_string_literal: true + Oj.default_options = { mode: :compat, time_format: :ruby, use_to_json: true } diff --git a/config/initializers/open_uri_redirection.rb b/config/initializers/open_uri_redirection.rb index 0e57c53c63..cf1f27c5c5 100644 --- a/config/initializers/open_uri_redirection.rb +++ b/config/initializers/open_uri_redirection.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'open-uri' module OpenURI diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index 7ed244e0c0..03e5fdbb8d 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -7,7 +7,7 @@ Paperclip.interpolates :filename do |attachment, style| if style == :original attachment.original_filename else - [basename(attachment, style), extension(attachment, style)].delete_if(&:blank?).join('.') + [basename(attachment, style), extension(attachment, style)].compact_blank!.join('.') end end @@ -61,18 +61,14 @@ if ENV['S3_ENABLED'] == 'true' s3_options: { signature_version: ENV.fetch('S3_SIGNATURE_VERSION') { 'v4' }, - http_open_timeout: ENV.fetch('S3_OPEN_TIMEOUT'){ '5' }.to_i, - http_read_timeout: ENV.fetch('S3_READ_TIMEOUT'){ '5' }.to_i, + http_open_timeout: ENV.fetch('S3_OPEN_TIMEOUT') { '5' }.to_i, + http_read_timeout: ENV.fetch('S3_READ_TIMEOUT') { '5' }.to_i, http_idle_timeout: 5, retry_limit: 0, } ) - - if ENV['S3_PERMISSION'] == '' - Paperclip::Attachment.default_options.merge!( - s3_permissions: ->(*) { nil } - ) - end + + Paperclip::Attachment.default_options[:s3_permissions] = ->(*) { nil } if ENV['S3_PERMISSION'] == '' if ENV.has_key?('S3_ENDPOINT') Paperclip::Attachment.default_options[:s3_options].merge!( @@ -90,25 +86,31 @@ if ENV['S3_ENABLED'] == 'true' ) end + Paperclip::Attachment.default_options[:s3_headers]['X-Amz-Storage-Class'] = ENV['S3_STORAGE_CLASS'] if ENV.has_key?('S3_STORAGE_CLASS') + # Some S3-compatible providers might not actually be compatible with some APIs # used by kt-paperclip, see https://github.com/mastodon/mastodon/issues/16822 - if ENV['S3_FORCE_SINGLE_REQUEST'] == 'true' - module Paperclip - module Storage - module S3Extensions - def copy_to_local_file(style, local_dest_path) - log("copying #{path(style)} to local file #{local_dest_path}") - s3_object(style).download_file(local_dest_path, { mode: 'single_request' }) - rescue Aws::Errors::ServiceError => e - warn("#{e} - cannot copy #{path(style)} to local file #{local_dest_path}") - false - end + # and https://github.com/mastodon/mastodon/issues/26394 + module Paperclip + module Storage + module S3Extensions + def copy_to_local_file(style, local_dest_path) + log("copying #{path(style)} to local file #{local_dest_path}") + + options = {} + options[:mode] = 'single_request' if ENV['S3_FORCE_SINGLE_REQUEST'] == 'true' + options[:checksum_mode] = 'DISABLED' unless ENV['S3_ENABLE_CHECKSUM_MODE'] == 'true' + + s3_object(style).download_file(local_dest_path, options) + rescue Aws::Errors::ServiceError => e + warn("#{e} - cannot copy #{path(style)} to local file #{local_dest_path}") + false end end end - - Paperclip::Storage::S3.prepend(Paperclip::Storage::S3Extensions) end + + Paperclip::Storage::S3.prepend(Paperclip::Storage::S3Extensions) elsif ENV['SWIFT_ENABLED'] == 'true' require 'fog/openstack' @@ -126,13 +128,33 @@ elsif ENV['SWIFT_ENABLED'] == 'true' openstack_cache_ttl: ENV.fetch('SWIFT_CACHE_TTL') { 60 }, openstack_temp_url_key: ENV['SWIFT_TEMP_URL_KEY'], }, - + fog_file: { 'Cache-Control' => 'public, max-age=315576000, immutable' }, fog_directory: ENV['SWIFT_CONTAINER'], fog_host: ENV['SWIFT_OBJECT_URL'], fog_public: true ) +elsif ENV['AZURE_ENABLED'] == 'true' + require 'paperclip-azure' + + Paperclip::Attachment.default_options.merge!( + storage: :azure, + azure_options: { + protocol: 'https', + }, + azure_credentials: { + storage_account_name: ENV['AZURE_STORAGE_ACCOUNT'], + storage_access_key: ENV['AZURE_STORAGE_ACCESS_KEY'], + container: ENV['AZURE_CONTAINER_NAME'], + } + ) + if ENV.has_key?('AZURE_ALIAS_HOST') + Paperclip::Attachment.default_options.merge!( + url: ':azure_alias_url', + azure_host_alias: ENV['AZURE_ALIAS_HOST'] + ) + end else Paperclip::Attachment.default_options.merge!( storage: :filesystem, diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb index 00f64d71b0..50bcf4eade 100644 --- a/config/initializers/permissions_policy.rb +++ b/config/initializers/permissions_policy.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Define an application-wide HTTP permissions policy. For further # information see https://developers.google.com/web/updates/2018/06/feature-policy # diff --git a/config/initializers/pghero.rb b/config/initializers/pghero.rb index 0c77d6d0ff..dc26397b34 100644 --- a/config/initializers/pghero.rb +++ b/config/initializers/pghero.rb @@ -1 +1,3 @@ +# frozen_string_literal: true + PgHero.show_migrations = Rails.env.development? diff --git a/config/initializers/preload_link_headers.rb b/config/initializers/preload_link_headers.rb index 364a7cc1be..168b887811 100644 --- a/config/initializers/preload_link_headers.rb +++ b/config/initializers/preload_link_headers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Since Rails 6.1, ActionView adds preload links for javascript files # in the Links header per default. diff --git a/config/initializers/premailer_rails.rb b/config/initializers/premailer_rails.rb index 31c02dffab..98b2082719 100644 --- a/config/initializers/premailer_rails.rb +++ b/config/initializers/premailer_rails.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../../lib/mastodon/premailer_webpack_strategy' Premailer::Rails.config.merge!(remove_ids: true, diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 3857e30555..429dbd3248 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -5,9 +5,9 @@ require 'doorkeeper/grape/authorization_decorator' class Rack::Attack class Request def authenticated_token - return @token if defined?(@token) + return @authenticated_token if defined?(@authenticated_token) - @token = Doorkeeper::OAuth::Token.authenticate( + @authenticated_token = Doorkeeper::OAuth::Token.authenticate( Doorkeeper::Grape::AuthorizationDecorator.new(self), *Doorkeeper.configuration.access_token_methods ) @@ -79,7 +79,7 @@ class Rack::Attack end throttle('throttle_api_media', limit: 30, period: 30.minutes) do |req| - req.authenticated_user_id if req.post? && req.path.match?(/\A\/api\/v\d+\/media\z/i) + req.authenticated_user_id if req.post? && req.path.match?(%r{\A/api/v\d+/media\z}i) end throttle('throttle_media_proxy', limit: 30, period: 10.minutes) do |req| @@ -98,8 +98,8 @@ class Rack::Attack req.throttleable_remote_ip if req.paging_request? && req.unauthenticated? end - API_DELETE_REBLOG_REGEX = /\A\/api\/v1\/statuses\/[\d]+\/unreblog\z/.freeze - API_DELETE_STATUS_REGEX = /\A\/api\/v1\/statuses\/[\d]+\z/.freeze + API_DELETE_REBLOG_REGEX = %r{\A/api/v1/statuses/\d+/unreblog\z} + API_DELETE_STATUS_REGEX = %r{\A/api/v1/statuses/\d+\z} throttle('throttle_api_delete', limit: 30, period: 30.minutes) do |req| req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX)) @@ -142,10 +142,10 @@ class Rack::Attack match_data = request.env['rack.attack.match_data'] headers = { - 'Content-Type' => 'application/json', - 'X-RateLimit-Limit' => match_data[:limit].to_s, + 'Content-Type' => 'application/json', + 'X-RateLimit-Limit' => match_data[:limit].to_s, 'X-RateLimit-Remaining' => '0', - 'X-RateLimit-Reset' => (now + (match_data[:period] - now.to_i % match_data[:period])).iso8601(6), + 'X-RateLimit-Reset' => (now + (match_data[:period] - (now.to_i % match_data[:period]))).iso8601(6), } [429, headers, [{ error: I18n.t('errors.429') }.to_json]] diff --git a/config/initializers/rack_attack_logging.rb b/config/initializers/rack_attack_logging.rb index ab4822e96b..458bc799f9 100644 --- a/config/initializers/rack_attack_logging.rb +++ b/config/initializers/rack_attack_logging.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveSupport::Notifications.subscribe(/rack_attack/) do |_name, _start, _finish, _request_id, payload| req = payload[:request] diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb new file mode 100644 index 0000000000..8865d85780 --- /dev/null +++ b/config/initializers/redis.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +Redis.sadd_returns_boolean = false diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 210964b1f3..eac23a79b9 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,6 +1,11 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. -Rails.application.config.session_store :cookie_store, - key: '_mastodon_session', - secure: false, # All cookies have their secure flag set by the force_ssl option in production - same_site: :lax +Rails + .application + .config + .session_store :cookie_store, + key: '_mastodon_session', + secure: false, # All cookies have their secure flag set by the force_ssl option in production + same_site: :lax diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index 92cffc5a2a..e7b4f2d458 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Use this setup block to configure all options available in SimpleForm. module AppendComponent @@ -19,8 +21,27 @@ module RecommendedComponent end end +module WarningHintComponent + def warning_hint(_wrapper_options = nil) + @warning_hint ||= begin + options[:warning_hint].to_s.html_safe if options[:warning_hint].present? + end + end +end + +module GlitchOnlyComponent + def glitch_only(_wrapper_options = nil) + return unless options[:glitch_only] + + options[:label_text] = ->(raw_label_text, _required_label_text, _label_present) { safe_join([raw_label_text, ' ', content_tag(:span, I18n.t('simple_form.glitch_only'), class: 'glitch_only')]) } + nil + end +end + SimpleForm.include_component(AppendComponent) SimpleForm.include_component(RecommendedComponent) +SimpleForm.include_component(WarningHintComponent) +SimpleForm.include_component(GlitchOnlyComponent) SimpleForm.setup do |config| # Wrappers are used by the form builder to generate a @@ -78,6 +99,7 @@ SimpleForm.setup do |config| b.wrapper tag: :div, class: :label_input do |ba| ba.optional :recommended + ba.optional :glitch_only ba.use :label ba.wrapper tag: :div, class: :label_input__wrapper do |bb| @@ -86,7 +108,8 @@ SimpleForm.setup do |config| end end - b.use :hint, wrap_with: { tag: :span, class: :hint } + b.use :warning_hint, wrap_with: { tag: :span, class: [:hint, 'warning-hint'] } + b.use :hint, wrap_with: { tag: :span, class: :hint } b.use :error, wrap_with: { tag: :span, class: :error } end @@ -100,6 +123,7 @@ SimpleForm.setup do |config| config.wrappers :with_block_label, class: [:input, :with_block_label], hint_class: :field_with_hint, error_class: :field_with_errors do |b| b.use :html5 b.use :label + b.use :warning_hint, wrap_with: { tag: :span, class: [:hint, 'warning-hint'] } b.use :hint, wrap_with: { tag: :span, class: :hint } b.use :input, wrap_with: { tag: :div, class: :label_input } b.use :error, wrap_with: { tag: :span, class: :error } diff --git a/config/initializers/statsd.rb b/config/initializers/statsd.rb index 93ea1d1e4a..a655c10716 100644 --- a/config/initializers/statsd.rb +++ b/config/initializers/statsd.rb @@ -3,13 +3,13 @@ if ENV['STATSD_ADDR'].present? host, port = ENV['STATSD_ADDR'].split(':') - $statsd = ::Statsd.new(host, port) - $statsd.namespace = ENV.fetch('STATSD_NAMESPACE') { ['Mastodon', Rails.env].join('.') } + statsd = Statsd.new(host, port) + statsd.namespace = ENV.fetch('STATSD_NAMESPACE') { ['Mastodon', Rails.env].join('.') } - ::NSA.inform_statsd($statsd) do |informant| + NSA.inform_statsd(statsd) do |informant| informant.collect(:action_controller, :web) informant.collect(:active_record, :db) informant.collect(:active_support_cache, :cache) - informant.collect(:sidekiq, :sidekiq) + informant.collect(:sidekiq, :sidekiq) if ENV['STATSD_SIDEKIQ'] == 'true' end end diff --git a/config/initializers/stoplight.rb b/config/initializers/stoplight.rb index 8c3c5755ae..72fe40600e 100644 --- a/config/initializers/stoplight.rb +++ b/config/initializers/stoplight.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'stoplight' Rails.application.reloader.to_prepare do diff --git a/config/initializers/strong_migrations.rb b/config/initializers/strong_migrations.rb index 70feb4f113..10b3805db2 100644 --- a/config/initializers/strong_migrations.rb +++ b/config/initializers/strong_migrations.rb @@ -1,3 +1,4 @@ # frozen_string_literal: true -StrongMigrations.start_after = 20170924022025 +StrongMigrations.start_after = 2017_09_24_022025 +StrongMigrations.target_version = 10 diff --git a/config/initializers/trusted_proxies.rb b/config/initializers/trusted_proxies.rb index 3c2afd8cdb..aa2f4510c2 100644 --- a/config/initializers/trusted_proxies.rb +++ b/config/initializers/trusted_proxies.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Rack class Request def trusted_proxy?(ip) diff --git a/config/initializers/twitter_regex.rb b/config/initializers/twitter_regex.rb index e65b05dfde..9ca4eb0da9 100644 --- a/config/initializers/twitter_regex.rb +++ b/config/initializers/twitter_regex.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Twitter::TwitterText class Configuration def emoji_parsing_enabled @@ -6,8 +8,8 @@ module Twitter::TwitterText end class Regex - REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}<>\(\)\?]/iou - REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}\(\)\?!\*"'「」<>;:=\,\.\$%\[\]~&\|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou + REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}<>()?]/iou + REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}()?!*"'「」<>;:=,.$%\[\]~&|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou REGEXEN[:valid_url_balanced_parens] = / \( (?: @@ -24,21 +26,23 @@ module Twitter::TwitterText ) \) /iox + # rubocop:disable Layout/LineLength UCHARS = '\u{A0}-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFEF}\u{10000}-\u{1FFFD}\u{20000}-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}\u{50000}-\u{5FFFD}\u{60000}-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}\u{90000}-\u{9FFFD}\u{A0000}-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}\u{D0000}-\u{DFFFD}\u{E1000}-\u{EFFFD}\u{E000}-\u{F8FF}\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}' - REGEXEN[:valid_url_query_chars] = /[a-z0-9!?\*'\(\);:&=\+\$\/%#\[\]\-_\.,~|@\^#{UCHARS}]/iou - REGEXEN[:valid_url_query_ending_chars] = /[a-z0-9_&=#\/\-#{UCHARS}]/iou - REGEXEN[:valid_url_path] = /(?: + # rubocop:enable Layout/LineLength + REGEXEN[:valid_url_query_chars] = %r{[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|@\^#{UCHARS}]}iou + REGEXEN[:valid_url_query_ending_chars] = %r{[a-z0-9_&=#/\-#{UCHARS}]}iou + REGEXEN[:valid_url_path] = %r{(?: (?: #{REGEXEN[:valid_general_url_path_chars]}* (?:#{REGEXEN[:valid_url_balanced_parens]} #{REGEXEN[:valid_general_url_path_chars]}*)* #{REGEXEN[:valid_url_path_ending_chars]} - )|(?:#{REGEXEN[:valid_general_url_path_chars]}+\/) - )/iox + )|(?:#{REGEXEN[:valid_general_url_path_chars]}+/) + )}iox REGEXEN[:valid_url] = %r{ ( # $1 total match (#{REGEXEN[:valid_url_preceding_chars]}) # $2 Preceding character ( # $3 URL - ((?:https?|dat|dweb|ipfs|ipns|ssb|gopher|gemini):\/\/)? # $4 Protocol (optional) + ((?:https?|dat|dweb|ipfs|ipns|ssb|gopher|gemini)://)? # $4 Protocol (optional) (#{REGEXEN[:valid_domain]}) # $5 Domain(s) (?::(#{REGEXEN[:valid_port_number]}))? # $6 Port number (optional) (/#{REGEXEN[:valid_url_path]}*)? # $7 URL Path and anchor diff --git a/config/initializers/webauthn.rb b/config/initializers/webauthn.rb index a0a5b81537..924ce6d877 100644 --- a/config/initializers/webauthn.rb +++ b/config/initializers/webauthn.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + WebAuthn.configure do |config| # This value needs to match `window.location.origin` evaluated by # the User Agent during registration and authentication ceremonies. - config.origin = "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" + config.origin = "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" # Relying Party name for display purposes config.rp_name = "Mastodon" diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index bbfc3961bf..2f3c0db471 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # This file contains settings for ActionController::ParamsWrapper which diff --git a/config/locales-glitch/af.yml b/config/locales-glitch/af.yml new file mode 100644 index 0000000000..252f9fd5a2 --- /dev/null +++ b/config/locales-glitch/af.yml @@ -0,0 +1 @@ +af: diff --git a/config/locales-glitch/an.yml b/config/locales-glitch/an.yml new file mode 100644 index 0000000000..76cc0689b6 --- /dev/null +++ b/config/locales-glitch/an.yml @@ -0,0 +1 @@ +an: diff --git a/config/locales-glitch/ar.yml b/config/locales-glitch/ar.yml new file mode 100644 index 0000000000..c257bc08a4 --- /dev/null +++ b/config/locales-glitch/ar.yml @@ -0,0 +1 @@ +ar: diff --git a/config/locales-glitch/ast.yml b/config/locales-glitch/ast.yml new file mode 100644 index 0000000000..d762c93994 --- /dev/null +++ b/config/locales-glitch/ast.yml @@ -0,0 +1 @@ +ast: diff --git a/config/locales-glitch/be.yml b/config/locales-glitch/be.yml new file mode 100644 index 0000000000..91ccc2d7e7 --- /dev/null +++ b/config/locales-glitch/be.yml @@ -0,0 +1 @@ +be: diff --git a/config/locales-glitch/bg.yml b/config/locales-glitch/bg.yml new file mode 100644 index 0000000000..d0e375da96 --- /dev/null +++ b/config/locales-glitch/bg.yml @@ -0,0 +1 @@ +bg: diff --git a/config/locales-glitch/bn.yml b/config/locales-glitch/bn.yml new file mode 100644 index 0000000000..152c698290 --- /dev/null +++ b/config/locales-glitch/bn.yml @@ -0,0 +1 @@ +bn: diff --git a/config/locales-glitch/br.yml b/config/locales-glitch/br.yml new file mode 100644 index 0000000000..c7677c850c --- /dev/null +++ b/config/locales-glitch/br.yml @@ -0,0 +1 @@ +br: diff --git a/config/locales-glitch/bs.yml b/config/locales-glitch/bs.yml new file mode 100644 index 0000000000..e9e174462a --- /dev/null +++ b/config/locales-glitch/bs.yml @@ -0,0 +1 @@ +bs: diff --git a/config/locales-glitch/ca.yml b/config/locales-glitch/ca.yml new file mode 100644 index 0000000000..f0c487273d --- /dev/null +++ b/config/locales-glitch/ca.yml @@ -0,0 +1 @@ +ca: diff --git a/config/locales-glitch/ckb.yml b/config/locales-glitch/ckb.yml new file mode 100644 index 0000000000..77d538af77 --- /dev/null +++ b/config/locales-glitch/ckb.yml @@ -0,0 +1 @@ +ckb: diff --git a/config/locales-glitch/co.yml b/config/locales-glitch/co.yml new file mode 100644 index 0000000000..5330938e02 --- /dev/null +++ b/config/locales-glitch/co.yml @@ -0,0 +1 @@ +co: diff --git a/config/locales-glitch/cs.yml b/config/locales-glitch/cs.yml new file mode 100644 index 0000000000..940df937b5 --- /dev/null +++ b/config/locales-glitch/cs.yml @@ -0,0 +1,38 @@ +--- +cs: + admin: + custom_emojis: + batch_copy_error: 'Při kopírování některých emoji došlo k chybě: %{message}' + batch_error: 'Došlo k chybě: %{message}' + settings: + captcha_enabled: + desc_html: Tato funkce používá externí skripty služby hCaptcha, což může být problém z hlediska bezpečí a ochrany dat. Také to může některým (hlavně postiženým) lidem registrační proces výrazně zkomplikovat. Z tohoto důvodu prosím raději zvažte jiné možnosti, jako je schvalování registrací nebo registrace pouze pro zvané.
Uživatelům pozvaným skrze omezenou pozvánku se CAPTCHA nezobrazí. + title: Vyžadovat po nových uživatelích opsání textu z obrázku (CAPTCHA) + flavour_and_skin: + title: Rozhraní a styl + hide_followers_count: + desc_html: Nezobrazovat na uživatelských profilech počet sledujících + title: Schovat počet sledujících + other: + preamble: Různá nastavení glitch-soc, která se nevešla do jiných kategorií. + title: Jiné + outgoing_spoilers: + desc_html: Při federování příspěvků se přidá toto varování o obsahu příspěvkům, které žádné nemají. To může být užitečné, pokud je váš server zaměřen na specifický obsah, pro který by jiné servery mohly varování o obsahu vyžadovat. Připojená média budou označena jako citlivá. + title: Varování o obsahu pro odesílané příspěvky + show_reblogs_in_public_timelines: + desc_html: Veřejné boosty veřejných příspěvků se zobrazí na místní a federované časové ose. + title: Zobrazovat ve veřejných časových osách boosty + show_replies_in_public_timelines: + desc_html: Na místní a federované časové ose se kromě odpovědí autora na vlastní příspěvky (vláken) zobrazí i ostatní veřejné odpovědi. + title: Zobrazovat ve veřejných časových osách odpovědi + trending_status_cw: + desc_html: Zobrazovat v rámci trendů (pokud jsou zapnuté) i příspěvky s varováním o obsahu. Změny tohoto nastavení se neprojeví retroaktivně. + title: Povolit v trendech příspěvky s varováním o obsahu + auth: + captcha_confirmation: + hint_html: Už jen poslední krok! Pro potvrzení svého účtu opište prosím text z obrázku (CAPTCHA). Pokud máte dotazy nebo potřebujete s potvrzením pomoct, můžete kontaktovat administrátora. + title: Ověření uživatele + generic: + use_this: Použít + settings: + flavours: Rozhraní diff --git a/config/locales-glitch/cy.yml b/config/locales-glitch/cy.yml new file mode 100644 index 0000000000..deefc9438f --- /dev/null +++ b/config/locales-glitch/cy.yml @@ -0,0 +1 @@ +cy: diff --git a/config/locales-glitch/da.yml b/config/locales-glitch/da.yml new file mode 100644 index 0000000000..77ec1953ca --- /dev/null +++ b/config/locales-glitch/da.yml @@ -0,0 +1,7 @@ +--- +da: + appearance: + localization: + glitch_guide_link_text: Det gælder også glitch-soc! + settings: + flavours: Varianter diff --git a/config/locales-glitch/de.yml b/config/locales-glitch/de.yml new file mode 100644 index 0000000000..233bf91b38 --- /dev/null +++ b/config/locales-glitch/de.yml @@ -0,0 +1,42 @@ +--- +de: + admin: + custom_emojis: + batch_copy_error: 'Fehler ist beim Kopieren einiger der ausgewählten Emoji aufgetreten: %{message}' + batch_error: 'Ein Fehler ist aufgetreten: %{message}' + settings: + captcha_enabled: + desc_html: Dies beruht auf externen Skripts von hCaptcha, was Sicherheits- und Datenschutz-Bedenken auslösen kann. Zusätzlich kann das den Registrierungsprozess für manche (besonders behinderte) Leute signifikant weniger zugänglich machen. Aus diesen Gründen, bitte ziehe alternative Maßnahmen, wie Zulassungs- oder Einladungs-basierte Registrierung, in Erwägung.
Nutzer, die durch eine Einladung mit eingeschränkter Verwendungsanzahl eingeladen wurden, werden kein CAPTCHA lösen müssen + title: Neue Nutzer sollen ein CAPTCHA lösen müssen, um ihr Konto zu bestätigen + flavour_and_skin: + title: Variante und Skin + hide_followers_count: + desc_html: Follower nicht auf Nutzerprofilen anzeigen + title: Anzahl der Follower verbergen + other: + preamble: Verschiedene glitch-soc-Einstellungen, die nicht in andere Kategorien passen. + title: Sonstiges + outgoing_spoilers: + desc_html: Füge diese Inhaltswarnung bei föderierten Toots hinzu, wenn sie noch keine haben. Nützlich, wenn dein Server auf bestimmte Inhalte spezialisiert ist, die andere Server hinter einer Inhaltswarnung haben wollen. Medien werden auch als empfindlich markiert werden. + title: Inhaltswarnung für ausgehende Toots + show_reblogs_in_public_timelines: + desc_html: Zeige öffentlich geteilte Toots in lokalen und öffentlichen Timelines. + title: Zeige geteilte Toots in öffentlichen Timelines + show_replies_in_public_timelines: + desc_html: Neben öffentlichen Selbst-Antworten (Threads), öffentliche Antworten in lokalen und öffentlichen Timelines anzeigen. + title: Antworten in öffentlichen Timelines anzeigen + trending_status_cw: + desc_html: Erlaube Posts mit Inhaltswarnungen zu trenden, wenn angesagte Beiträge aktiviert sind. Änderungen an dieser Einstellung sind nicht rückwirkend. + title: Erlaube Posts mit Inhaltswarnungen zu trenden + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Und auch für glitch-soc! + auth: + captcha_confirmation: + hint_html: Nur noch ein weiterer Schritt! Um dein Konto zu bestätigen, erfordert dieser Server das Lösen eines CAPTCHA von dir. Bei Fragen oder Problemen mit der Bestätigung kannst du den Server-Administrator kontaktieren. + title: Nutzer-Verifizierung + generic: + use_this: Benutze das + settings: + flavours: Varianten diff --git a/config/locales-glitch/el.yml b/config/locales-glitch/el.yml new file mode 100644 index 0000000000..419ec705c3 --- /dev/null +++ b/config/locales-glitch/el.yml @@ -0,0 +1 @@ +el: diff --git a/config/locales-glitch/en-GB.yml b/config/locales-glitch/en-GB.yml new file mode 100644 index 0000000000..ef03d18104 --- /dev/null +++ b/config/locales-glitch/en-GB.yml @@ -0,0 +1 @@ +en-GB: diff --git a/config/locales-glitch/en.yml b/config/locales-glitch/en.yml new file mode 100644 index 0000000000..1485ee174d --- /dev/null +++ b/config/locales-glitch/en.yml @@ -0,0 +1,42 @@ +--- +en: + admin: + custom_emojis: + batch_copy_error: 'An error occurred when copying some of the selected emoji: %{message}' + batch_error: 'An error occurred: %{message}' + settings: + captcha_enabled: + desc_html: This relies on external scripts from hCaptcha, which may be a security and privacy concern. In addition, this can make the registration process significantly less accessible to some (especially disabled) people. For these reasons, please consider alternative measures such as approval-based or invite-based registration. + title: Require new users to solve a CAPTCHA to confirm their account + flavour_and_skin: + title: Flavour and skin + hide_followers_count: + desc_html: Do not show followers count on user profiles + title: Hide followers count + other: + preamble: Various glitch-soc settings not fitting in other categories. + title: Other + outgoing_spoilers: + desc_html: When federating toots, add this content warning to toots that do not have one. It is useful if your server is specialized in content other servers might want to have under a Content Warning. Media will also be marked as sensitive. + title: Content warning for outgoing toots + show_reblogs_in_public_timelines: + desc_html: Show public boosts of public toots in local and public timelines. + title: Show boosts in public timelines + show_replies_in_public_timelines: + desc_html: In addition to public self-replies (threads), show public replies in local and public timelines. + title: Show replies in public timelines + trending_status_cw: + desc_html: When trending posts are enabled, allow posts with Content Warnings to be eligible. Changes to this setting are not retroactive. + title: Allow posts with Content Warnings to trend + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: And likewise for glitch-soc! + auth: + captcha_confirmation: + hint_html: Just one more step! To confirm your account, this server requires you to solve a CAPTCHA. You can contact the server administrator if you have questions or need assistance with confirming your account. + title: User verification + generic: + use_this: Use this + settings: + flavours: Flavours diff --git a/config/locales-glitch/eo.yml b/config/locales-glitch/eo.yml new file mode 100644 index 0000000000..e7d44a6f67 --- /dev/null +++ b/config/locales-glitch/eo.yml @@ -0,0 +1,17 @@ +--- +eo: + admin: + custom_emojis: + batch_copy_error: 'Eraro okazis dum kopiado de iom da elektitaj emoĝioj: %{message}' + batch_error: 'Eraro okazis: %{message}' + settings: + captcha_enabled: + title: Postuli, ke novaj uzantoj solvi CAPTCHA-on por ke oni konfirmu sian konton + hide_followers_count: + desc_html: Ne montri la kvanton de sekvantoj en profiloj de uzantoj + title: Kaŝi la kvanton de sekvantoj + other: + title: Aliaj + outgoing_spoilers: + desc_html: Elsendante la afiŝoj al aliaj instancoj, aldoni ĉi tiun averton al afiŝoj, kiuj ne havas averton. Ĝi estas utila, se via instanco temas pri enhavo, kiun aliaj instancoj volus kovri per averto. Ambaŭ plurmedioj estos markita kiel tiklaj. + title: Averto por elsenditaj afiŝoj diff --git a/config/locales-glitch/es-AR.yml b/config/locales-glitch/es-AR.yml new file mode 100644 index 0000000000..fb90f56bb2 --- /dev/null +++ b/config/locales-glitch/es-AR.yml @@ -0,0 +1,42 @@ +--- +es-AR: + admin: + custom_emojis: + batch_copy_error: Se produjo un error cuando se copian algunos emojis seleccionados %{message} + batch_error: Ocurrió un error %{message} + settings: + captcha_enabled: + desc_html: Esto depende de scripts externos de hCaptcha, que pueden ser una preocupación de seguridad y privacidad. Además, esto puede hacer el proceso de registro significativamente menos accesible para algunas personas (especialmente personas discapacitadas). Por estas razones, por favor, considerá medidas alternativas como el registro basado en la aprobación o la invitación.
Los usuarios que fueron invitados a través de una invitación de uso limitado no necesitarán resolver una CAPTCHA. + title: Pedir a los usuarios nuevos resolver un CAPTCHA para confirmar su cuenta + flavour_and_skin: + title: Sabor y apariencia + hide_followers_count: + desc_html: No mostrar el conteo de seguidorxs en perfiles de usuarix + title: Ocultar conteo de seguidorxs + other: + preamble: Varias configuraciones de glitch-soc que no encajan en otras categorías. + title: Otro + outgoing_spoilers: + desc_html: Cuando los toots federen, agrega esta etiqueta de contenido a los toots que no tengan. Es útil si tu servidor se especializa en contenido que otros servidores desearían tener con una advertencia de contenido. Los medios también se marcarán como sensibles. + title: Advertencia de contenido para los toots salientes + show_reblogs_in_public_timelines: + desc_html: Mostrar retoots públicos en las línea de tiempo local y pública. + title: Mostrar retoots en líneas de tiempo públicas + show_replies_in_public_timelines: + desc_html: Además de auto-respuestas públicas (hilos), mostrar respuestas públicas en las línea de tiempo local y pública. + title: Mostrar respuestas en líneas de tiempo públicas + trending_status_cw: + desc_html: Cuando las publicaciones en tendencia están habilitadas, permitir que la que contienen Advertencias de Contenido sean elegibles. Los cambios en esta configuración no son retroactivos. + title: Permitir que publicaciones con advertencias de contenido sean tendencia + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Igual para glitch-soc! + auth: + captcha_confirmation: + hint_html: ¡Solo un paso más! Para confirmar tu cuenta, este servidor requiere que resuelvas un CAPTCHA. Puedes contactar con el administrador del servidor si tienes preguntas o necesitas ayuda para confirmar tu cuenta. + title: Verificación de usuario + generic: + use_this: Usar + settings: + flavours: Ediciones diff --git a/config/locales-glitch/es-MX.yml b/config/locales-glitch/es-MX.yml new file mode 100644 index 0000000000..1319dd3e37 --- /dev/null +++ b/config/locales-glitch/es-MX.yml @@ -0,0 +1,42 @@ +--- +es-MX: + admin: + custom_emojis: + batch_copy_error: Se produjo un error cuando se copian algunos emojis seleccionados %{message} + batch_error: Ocurrió un error %{message} + settings: + captcha_enabled: + desc_html: Esto depende de scripts externos de hCaptcha, que pueden ser una preocupación de seguridad y privacidad. Además, esto puede hacer el proceso de registro significativamente menos accesible para algunas personas (especialmente minusválidos). Por estas razones, por favor considera medidas alternativas como el registro basado en la aprobación o la invitación.
Los usuarios que han sido invitados a través de una invitación de uso limitado no necesitarán resolver un CAPTCHA + title: Pedir a los usuarios nuevos resolver un CAPTCHA para confirmar su cuenta + flavour_and_skin: + title: Sabor y apariencia + hide_followers_count: + desc_html: No mostrar el conteo de seguidorxs en perfiles de usuarix + title: Ocultar conteo de seguidorxs + other: + preamble: Varias configuraciones de glitch-soc que no encajan en otras categorías. + title: Otro + outgoing_spoilers: + desc_html: Cuando los toots federen, agrega esta etiqueta de contenido a los toots que no tengan. Es útil si tu servidor se especializa en contenido que otros servidores desearían tener con una advertencia de contenido. Los medios también se marcarán como sensibles. + title: Advertencia de contenido para los toots salientes + show_reblogs_in_public_timelines: + desc_html: Mostrar retoots públicos en las línea de tiempo local y pública. + title: Mostrar retoots en líneas de tiempo públicas + show_replies_in_public_timelines: + desc_html: Además de auto-respuestas públicas (hilos), mostrar respuestas públicas en las línea de tiempo local y pública. + title: Mostrar respuestas en líneas de tiempo públicas + trending_status_cw: + desc_html: Cuando las publicaciones en tendencia están habilitadas, permitir que la que contienen Advertencias de Contenido sean elegibles. Los cambios en esta configuración no son retroactivos. + title: Permitir que publicaciones con advertencias de contenido sean tendencia + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Igual para glitch-soc! + auth: + captcha_confirmation: + hint_html: ¡Solo un paso más! Para confirmar tu cuenta, este servidor requiere que resuelvas un CAPTCHA. Puedes contactar con el administrador del servidor si tienes preguntas o necesitas ayuda para confirmar tu cuenta. + title: Verificación de usuario + generic: + use_this: Usar + settings: + flavours: Ediciones diff --git a/config/locales-glitch/es.yml b/config/locales-glitch/es.yml new file mode 100644 index 0000000000..4e054b056c --- /dev/null +++ b/config/locales-glitch/es.yml @@ -0,0 +1,42 @@ +--- +es: + admin: + custom_emojis: + batch_copy_error: Se produjo un error cuando se copian algunos emojis seleccionados %{message} + batch_error: Ocurrió un error %{message} + settings: + captcha_enabled: + desc_html: Esto depende de scripts externos de hCaptcha, que pueden ser una preocupación de seguridad y privacidad. Además, esto puede hacer el proceso de registro significativamente menos accesible para algunas personas (especialmente minusválidos). Por estas razones, por favor considera medidas alternativas como el registro basado en la aprobación o la invitación.
Los usuarios que han sido invitados a través de una invitación de uso limitado no necesitarán resolver un CAPTCHA + title: Pedir a los usuarios nuevos resolver un CAPTCHA para confirmar su cuenta + flavour_and_skin: + title: Sabor y apariencia + hide_followers_count: + desc_html: No mostrar el conteo de seguidores en los perfiles de usuario + title: Ocultar conteo de seguidorxs + other: + preamble: Varias configuraciones de glitch-soc que no encajan en otras categorías. + title: Otro + outgoing_spoilers: + desc_html: Cuando los toots federen, agrega esta etiqueta de contenido a los toots que no tengan. Es útil si tu servidor se especializa en contenido que otros servidores desearían tener con una advertencia de contenido. Los medios también se marcarán como sensibles. + title: Advertencia de contenido para publicaciones salientes + show_reblogs_in_public_timelines: + desc_html: Mostrar impulsos públicos en las líneas de tiempo local y pública. + title: Mostrar impulsos en líneas de tiempo públicas + show_replies_in_public_timelines: + desc_html: Además de auto-respuestas públicas (hilos), mostrar respuestas públicas en las líneas de tiempo local y pública. + title: Mostrar respuestas en líneas de tiempo públicas + trending_status_cw: + desc_html: Cuando las publicaciones en tendencia están habilitadas, permitir que la que contienen Advertencias de Contenido sean elegibles. Los cambios en esta configuración no son retroactivos. + title: Permitir que publicaciones con advertencias de contenido sean tendencia + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Igual para glitch-soc! + auth: + captcha_confirmation: + hint_html: ¡Solo un paso más! Para confirmar tu cuenta, este servidor requiere que resuelvas un CAPTCHA. Puedes contactar con el administrador del servidor si tienes preguntas o necesitas ayuda para confirmar tu cuenta. + title: Verificación de usuario + generic: + use_this: Usar + settings: + flavours: Ediciones diff --git a/config/locales-glitch/et.yml b/config/locales-glitch/et.yml new file mode 100644 index 0000000000..e020c4ffc4 --- /dev/null +++ b/config/locales-glitch/et.yml @@ -0,0 +1 @@ +et: diff --git a/config/locales-glitch/eu.yml b/config/locales-glitch/eu.yml new file mode 100644 index 0000000000..566e176fc9 --- /dev/null +++ b/config/locales-glitch/eu.yml @@ -0,0 +1 @@ +eu: diff --git a/config/locales-glitch/fa.yml b/config/locales-glitch/fa.yml new file mode 100644 index 0000000000..1c97bc47cc --- /dev/null +++ b/config/locales-glitch/fa.yml @@ -0,0 +1,11 @@ +--- +fa: + admin: + settings: + hide_followers_count: + title: نهفتن تعداد پی‌گیران + other: + title: ديگر + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc diff --git a/config/locales-glitch/fi.yml b/config/locales-glitch/fi.yml new file mode 100644 index 0000000000..23c538b193 --- /dev/null +++ b/config/locales-glitch/fi.yml @@ -0,0 +1 @@ +fi: diff --git a/config/locales-glitch/fo.yml b/config/locales-glitch/fo.yml new file mode 100644 index 0000000000..69f792cca3 --- /dev/null +++ b/config/locales-glitch/fo.yml @@ -0,0 +1 @@ +fo: diff --git a/config/locales-glitch/fr-QC.yml b/config/locales-glitch/fr-QC.yml new file mode 100644 index 0000000000..0cba194f54 --- /dev/null +++ b/config/locales-glitch/fr-QC.yml @@ -0,0 +1,42 @@ +--- +fr-QC: + admin: + custom_emojis: + batch_copy_error: 'Une erreur est survenue lors de la copie de certains des émojis sélectionnés : %{message}' + batch_error: 'Une erreur est survenue : %{message}' + settings: + captcha_enabled: + desc_html: Ceci se base sur des scripts externes venant de hCaptcha, ce qui peut engendrer des soucis de sécurité et de confidentialité. De plus, cela peut rendre l'inscription beaucoup moins accessible pour certaines personnes (comme les personnes handicapées). Pour ces raisons, veuillez préférer des mesures alternatives telles que l'inscription sur acceptation ou invitation.
Les utilisateurs qui ont été invités via une invitation à usage limité n'auront pas à résoudre un CAPTCHA + title: Obliger les nouveaux utilisateurs à résoudre un CAPTCHA pour vérifier leur compte + flavour_and_skin: + title: Apparence et thèmes + hide_followers_count: + desc_html: Ne pas afficher le nombre d'abonné·e·s sur les profils des utilisateurs + title: Cacher le nombre d'abonné·e·s + other: + preamble: Divers autres paramètres de glitch-soc. + title: Autres + outgoing_spoilers: + desc_html: Ajouter un avertissement de contenu à tous les messages lorsqu'ils sont fédérés s'ils n'en possèdent pas déjà. Cela peut être utile si votre serveur est spécialisé dans un type de contenu sur lequel les autres serveurs pourraient vouloir un Avertissement de Contenu. Les médias seront également marqués comme sensibles. + title: Avertissement de contenu pour les messages sortants + show_reblogs_in_public_timelines: + desc_html: Afficher les partages publics de posts publics dans le fil local et global. + title: Afficher les partages dans les fils publics + show_replies_in_public_timelines: + desc_html: En plus des réponses à soi-même (threads), afficher les réponses publiques dans le fil local et global. + title: Afficher les réponses dans les fils publics + trending_status_cw: + desc_html: Quand les posts en tendance sont activés, permettre aux posts avec des avertissements de contenu (CW) d'être éligibles. Les changements effectués sur ce paramètre ne sont pas rétroactifs. + title: Autoriser les posts avec des avertissements de contenu à être en tendances + appearance: + localization: + glitch_guide_link: https://fr.crowdin.com/project/glitch-soc + glitch_guide_link_text: Et c'est pareil avec glitch-soc ! + auth: + captcha_confirmation: + hint_html: Plus qu'une étape ! Pour vérifier votre compte sur ce serveur, vous devez résoudre un CAPTCHA. Vous pouvez contacter l'administrateur·ice du serveur si vous avez des questions ou besoin d'assistance dans la vérification de votre compte. + title: Vérification de l'utilisateur + generic: + use_this: Utiliser ceci + settings: + flavours: Thèmes diff --git a/config/locales-glitch/fr.yml b/config/locales-glitch/fr.yml new file mode 100644 index 0000000000..15c3f8ce52 --- /dev/null +++ b/config/locales-glitch/fr.yml @@ -0,0 +1,42 @@ +--- +fr: + admin: + custom_emojis: + batch_copy_error: 'Une erreur est survenue lors de la copie de certains des émojis sélectionnés : %{message}' + batch_error: 'Une erreur est survenue : %{message}' + settings: + captcha_enabled: + desc_html: Ceci se base sur des scripts externes venant de hCaptcha, ce qui peut engendrer des soucis de sécurité et de confidentialité. De plus, cela peut rendre l'inscription beaucoup moins accessible pour certaines personnes (comme les personnes handicapées). Pour ces raisons, veuillez préférer des mesures alternatives telles que l'inscription sur acceptation ou invitation.
Les utilisateurs qui ont été invités via une invitation à usage limité n'auront pas à résoudre un CAPTCHA + title: Obliger les nouveaux utilisateurs à résoudre un CAPTCHA pour vérifier leur compte + flavour_and_skin: + title: Apparence et thèmes + hide_followers_count: + desc_html: Ne pas afficher le nombre d'abonné·e·s sur les profils des utilisateurs + title: Cacher le nombre d'abonné·e·s + other: + preamble: Divers autres paramètres de glitch-soc. + title: Autres + outgoing_spoilers: + desc_html: Ajouter un avertissement de contenu à tous les messages lorsqu'ils sont fédérés s'ils n'en possèdent pas déjà. Cela peut être utile si votre serveur est spécialisé dans un type de contenu sur lequel les autres serveurs pourraient vouloir un Avertissement de Contenu. Les médias seront également marqués comme sensibles. + title: Avertissement de contenu pour les messages sortants + show_reblogs_in_public_timelines: + desc_html: Afficher les partages publics de posts publics dans le fil local et global. + title: Afficher les partages dans les fils publics + show_replies_in_public_timelines: + desc_html: En plus des réponses à soi-même (threads), afficher les réponses publiques dans le fil local et global. + title: Afficher les réponses dans les fils publics + trending_status_cw: + desc_html: Quand les posts en tendance sont activés, permettre aux posts avec des avertissements de contenu (CW) d'être éligibles. Les changements effectués sur ce paramètre ne sont pas rétroactifs. + title: Autoriser les posts avec des avertissements de contenu à être en tendances + appearance: + localization: + glitch_guide_link: https://fr.crowdin.com/project/glitch-soc + glitch_guide_link_text: Et c'est pareil avec glitch-soc ! + auth: + captcha_confirmation: + hint_html: Plus qu'une étape ! Pour vérifier votre compte sur ce serveur, vous devez résoudre un CAPTCHA. Vous pouvez contacter l'administrateur·ice du serveur si vous avez des questions ou besoin d'assistance dans la vérification de votre compte. + title: Vérification de l'utilisateur + generic: + use_this: Utiliser ceci + settings: + flavours: Thèmes diff --git a/config/locales-glitch/fy.yml b/config/locales-glitch/fy.yml new file mode 100644 index 0000000000..c05849f20d --- /dev/null +++ b/config/locales-glitch/fy.yml @@ -0,0 +1 @@ +fy: diff --git a/config/locales-glitch/ga.yml b/config/locales-glitch/ga.yml new file mode 100644 index 0000000000..20a9da24e9 --- /dev/null +++ b/config/locales-glitch/ga.yml @@ -0,0 +1 @@ +ga: diff --git a/config/locales-glitch/gd.yml b/config/locales-glitch/gd.yml new file mode 100644 index 0000000000..1912f6c6a6 --- /dev/null +++ b/config/locales-glitch/gd.yml @@ -0,0 +1 @@ +gd: diff --git a/config/locales-glitch/gl.yml b/config/locales-glitch/gl.yml new file mode 100644 index 0000000000..8ec5fc81c1 --- /dev/null +++ b/config/locales-glitch/gl.yml @@ -0,0 +1 @@ +gl: diff --git a/config/locales-glitch/he.yml b/config/locales-glitch/he.yml new file mode 100644 index 0000000000..af6fa60a73 --- /dev/null +++ b/config/locales-glitch/he.yml @@ -0,0 +1 @@ +he: diff --git a/config/locales-glitch/hi.yml b/config/locales-glitch/hi.yml new file mode 100644 index 0000000000..d758a5b535 --- /dev/null +++ b/config/locales-glitch/hi.yml @@ -0,0 +1 @@ +hi: diff --git a/config/locales-glitch/hr.yml b/config/locales-glitch/hr.yml new file mode 100644 index 0000000000..f67f33c7e0 --- /dev/null +++ b/config/locales-glitch/hr.yml @@ -0,0 +1 @@ +hr: diff --git a/config/locales-glitch/hu.yml b/config/locales-glitch/hu.yml new file mode 100644 index 0000000000..52314c50c9 --- /dev/null +++ b/config/locales-glitch/hu.yml @@ -0,0 +1 @@ +hu: diff --git a/config/locales-glitch/hy.yml b/config/locales-glitch/hy.yml new file mode 100644 index 0000000000..c406540162 --- /dev/null +++ b/config/locales-glitch/hy.yml @@ -0,0 +1 @@ +hy: diff --git a/config/locales-glitch/id.yml b/config/locales-glitch/id.yml new file mode 100644 index 0000000000..8446cbad90 --- /dev/null +++ b/config/locales-glitch/id.yml @@ -0,0 +1 @@ +id: diff --git a/config/locales-glitch/ig.yml b/config/locales-glitch/ig.yml new file mode 100644 index 0000000000..7c264f0d73 --- /dev/null +++ b/config/locales-glitch/ig.yml @@ -0,0 +1 @@ +ig: diff --git a/config/locales-glitch/io.yml b/config/locales-glitch/io.yml new file mode 100644 index 0000000000..c63dc0e8d9 --- /dev/null +++ b/config/locales-glitch/io.yml @@ -0,0 +1 @@ +io: diff --git a/config/locales-glitch/is.yml b/config/locales-glitch/is.yml new file mode 100644 index 0000000000..337c106df9 --- /dev/null +++ b/config/locales-glitch/is.yml @@ -0,0 +1 @@ +is: diff --git a/config/locales-glitch/it.yml b/config/locales-glitch/it.yml new file mode 100644 index 0000000000..7c14e764bc --- /dev/null +++ b/config/locales-glitch/it.yml @@ -0,0 +1,7 @@ +--- +it: + admin: + settings: + hide_followers_count: + desc_html: Non mostrare il conteggio dei seguaci sui profili utente + title: Nascondi numero di seguaci diff --git a/config/locales-glitch/ja.yml b/config/locales-glitch/ja.yml new file mode 100644 index 0000000000..c8c6da1093 --- /dev/null +++ b/config/locales-glitch/ja.yml @@ -0,0 +1,35 @@ +--- +ja: + admin: + custom_emojis: + batch_copy_error: '選択したいくつかの絵文字のコピー中にエラーが発生しました: %{message}' + batch_error: 'エラーが発生しました: %{message}' + settings: + flavour_and_skin: + title: フレーバーとスキン + hide_followers_count: + desc_html: プロフィールページのフォロワー数を見られないようにします + title: フォロワー数を隠す + other: + preamble: 他のカテゴリに該当しない多様なglitch-socの設定。 + title: その他 + outgoing_spoilers: + desc_html: トゥートが連合される際、閲覧注意としてマークされていないトゥートにこの警告が追加されます。これはあなたのインスタンスが他のインスタンスに警告をして欲しいとされる投稿に特化している場合に便利です。 メディアは閲覧注意にマークされます。 + title: 発信するトゥートへの警告 + show_reblogs_in_public_timelines: + desc_html: ローカルタイムラインと連合タイムラインに公開投稿のブーストを表示します + title: 公開タイムラインにブーストを表示 + show_replies_in_public_timelines: + desc_html: 自分への公開投稿の返信に加えて、すべての公開投稿の返信をローカルタイムラインと連合タイムラインに表示します。 + title: 公開タイムラインに返信を表示 + trending_status_cw: + desc_html: トレンド投稿が有効な場合、コンテンツワーニング付きの投稿がトレンドに掲載されるのを許可します。この設定の変更は遡及的ではありません。 + title: 閲覧注意付きの投稿がトレンドに載るのを許可する + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: そしてglitch-socへも同様に! + generic: + use_this: これを使う + settings: + flavours: フレーバー diff --git a/config/locales-glitch/ka.yml b/config/locales-glitch/ka.yml new file mode 100644 index 0000000000..57a95cb047 --- /dev/null +++ b/config/locales-glitch/ka.yml @@ -0,0 +1 @@ +ka: diff --git a/config/locales-glitch/kab.yml b/config/locales-glitch/kab.yml new file mode 100644 index 0000000000..2109c04b37 --- /dev/null +++ b/config/locales-glitch/kab.yml @@ -0,0 +1 @@ +kab: diff --git a/config/locales-glitch/kk.yml b/config/locales-glitch/kk.yml new file mode 100644 index 0000000000..1dcc9b127c --- /dev/null +++ b/config/locales-glitch/kk.yml @@ -0,0 +1 @@ +kk: diff --git a/config/locales-glitch/kn.yml b/config/locales-glitch/kn.yml new file mode 100644 index 0000000000..d094088d88 --- /dev/null +++ b/config/locales-glitch/kn.yml @@ -0,0 +1 @@ +kn: diff --git a/config/locales-glitch/ko.yml b/config/locales-glitch/ko.yml new file mode 100644 index 0000000000..dd8da37923 --- /dev/null +++ b/config/locales-glitch/ko.yml @@ -0,0 +1,42 @@ +--- +ko: + admin: + custom_emojis: + batch_copy_error: '선택된 에모지를 복사하던 중 오류가 발생했습니다: %{message}' + batch_error: '에러가 발생했습니다: %{message}' + settings: + captcha_enabled: + desc_html: 이것은 hCaptcha의 외부 스크립트에 의존합니다, 이것은 개인정보 보호에 위협을 가할 수도 있습니다. 추가적으로, 이것은 몇몇 사람들(특히나 장애인들)에게 가입 절차의 접근성을 심각하게 떨어트릴 수 있습니다. 이러한 이유로, 대체제로 승인 전용이나 초대제를 통한 가입을 고려해보세요.
한정된 사용만 가능한 초대장을 통한 가입자들은 CAPTCHA를 풀지 않아도 됩니다 + title: 새로운 사용자가 계정 확인을 위해서는 CAPTCHA를 풀어야 하도록 합니다 + flavour_and_skin: + title: 풍미와 스킨 + hide_followers_count: + desc_html: 사용자 프로필에 팔로워 수를 표시하지 않습니다 + title: 팔로워 수 숨기기 + other: + preamble: 다른 곳에 맞지 않는 다양한 글리치 전용 설정들. + title: 기타 + outgoing_spoilers: + desc_html: 툿을 연합할 때 열람주의가 없다면 여기 적힌 열람주의를 추가합니다. 다른 서버에서 열람주의를 설정하기를 요하는 주제에 특화된 서버라면 유용합니다. 미디어 또한 민감함으로 설정됩니다. + title: 나가는 툿에 대한 열람주의 + show_reblogs_in_public_timelines: + desc_html: 공개글의 공개적인 부스트를 로컬과 공개 타임라인에 표시합니다. + title: 부스트를 공개 타임라인에 표시 + show_replies_in_public_timelines: + desc_html: 자기자신에 대한 답글(글타래)와 마찬가지로, 공개적인 답글을 로컬과 공개 타임라인에 표시합니다. + title: 답글을 공개 타임라인에 표시 + trending_status_cw: + desc_html: 유행하는 게시물이 활성화 되었을 때, 열람주의가 설정된 글도 허용합니다. 이 설정의 변경은 소급 적용되지 않습니다. + title: 열람주의를 가진 글이 유행에 오를 수 있도록 허용 + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: 글리치도 마찬가지입니다! + auth: + captcha_confirmation: + hint_html: 한가지 단계가 남았습니다! 계정을 확인하기 위해서는, CAPTCHA를 풀어야 합니다. 질문이 있거나 계정 확인 과정에서 도움을 받고 싶은 경우 서버의 관리자에게 연락해서 해결할 수 있습니다. + title: 사용자 확인 + generic: + use_this: 사용하기 + settings: + flavours: 풍미 diff --git a/config/locales-glitch/ku.yml b/config/locales-glitch/ku.yml new file mode 100644 index 0000000000..b36f7c9883 --- /dev/null +++ b/config/locales-glitch/ku.yml @@ -0,0 +1 @@ +ku: diff --git a/config/locales-glitch/kw.yml b/config/locales-glitch/kw.yml new file mode 100644 index 0000000000..b2cfc12ff1 --- /dev/null +++ b/config/locales-glitch/kw.yml @@ -0,0 +1 @@ +kw: diff --git a/config/locales-glitch/la.yml b/config/locales-glitch/la.yml new file mode 100644 index 0000000000..3a7ba0d445 --- /dev/null +++ b/config/locales-glitch/la.yml @@ -0,0 +1 @@ +la: diff --git a/config/locales-glitch/lt.yml b/config/locales-glitch/lt.yml new file mode 100644 index 0000000000..6c5cb837ac --- /dev/null +++ b/config/locales-glitch/lt.yml @@ -0,0 +1 @@ +lt: diff --git a/config/locales-glitch/lv.yml b/config/locales-glitch/lv.yml new file mode 100644 index 0000000000..1be0eabc09 --- /dev/null +++ b/config/locales-glitch/lv.yml @@ -0,0 +1 @@ +lv: diff --git a/config/locales-glitch/mk.yml b/config/locales-glitch/mk.yml new file mode 100644 index 0000000000..8b9144a988 --- /dev/null +++ b/config/locales-glitch/mk.yml @@ -0,0 +1 @@ +mk: diff --git a/config/locales-glitch/ml.yml b/config/locales-glitch/ml.yml new file mode 100644 index 0000000000..6931a683d1 --- /dev/null +++ b/config/locales-glitch/ml.yml @@ -0,0 +1 @@ +ml: diff --git a/config/locales-glitch/mr.yml b/config/locales-glitch/mr.yml new file mode 100644 index 0000000000..fe1639c6a3 --- /dev/null +++ b/config/locales-glitch/mr.yml @@ -0,0 +1 @@ +mr: diff --git a/config/locales-glitch/ms.yml b/config/locales-glitch/ms.yml new file mode 100644 index 0000000000..2925688a03 --- /dev/null +++ b/config/locales-glitch/ms.yml @@ -0,0 +1 @@ +ms: diff --git a/config/locales-glitch/my.yml b/config/locales-glitch/my.yml new file mode 100644 index 0000000000..5e1fc6bee9 --- /dev/null +++ b/config/locales-glitch/my.yml @@ -0,0 +1 @@ +my: diff --git a/config/locales-glitch/nl.yml b/config/locales-glitch/nl.yml new file mode 100644 index 0000000000..f009eadee5 --- /dev/null +++ b/config/locales-glitch/nl.yml @@ -0,0 +1 @@ +nl: diff --git a/config/locales-glitch/nn.yml b/config/locales-glitch/nn.yml new file mode 100644 index 0000000000..777f4e600f --- /dev/null +++ b/config/locales-glitch/nn.yml @@ -0,0 +1 @@ +nn: diff --git a/config/locales-glitch/no.yml b/config/locales-glitch/no.yml new file mode 100644 index 0000000000..d2a4697e5d --- /dev/null +++ b/config/locales-glitch/no.yml @@ -0,0 +1 @@ +no: diff --git a/config/locales-glitch/oc.yml b/config/locales-glitch/oc.yml new file mode 100644 index 0000000000..325b348894 --- /dev/null +++ b/config/locales-glitch/oc.yml @@ -0,0 +1 @@ +oc: diff --git a/config/locales-glitch/pa.yml b/config/locales-glitch/pa.yml new file mode 100644 index 0000000000..bb8a6c834d --- /dev/null +++ b/config/locales-glitch/pa.yml @@ -0,0 +1 @@ +pa: diff --git a/config/locales-glitch/pl.yml b/config/locales-glitch/pl.yml new file mode 100644 index 0000000000..33f947b897 --- /dev/null +++ b/config/locales-glitch/pl.yml @@ -0,0 +1,42 @@ +--- +pl: + admin: + custom_emojis: + batch_copy_error: 'Podczas kopiowania niektórych zaznaczonych emotikon wystąpił następujący problem: %{message}' + batch_error: 'Wystąpił problem: %{message}' + settings: + captcha_enabled: + desc_html: Wymaga użycia zewnętrznych skryptów hCaptcha, co może negatywnie wpływać na bezpieczeństwo i prywatność. Może również przyczynić się do znaczącego utrudnienia procesu rejestracji niektórym, np. niepełnosprawnym, osobom. Dlatego sugeruje się używanie zaproszeń bądź ręcznie potwierdzanie kont.
Użytkownicy rejestrujący się za pomocą limitowanych zaproszeń nie będą musieli rozwiązywać zadania CHAPTCHA + title: W celu potwierdzenia ich kont wymagaj rozwiązania zadania CAPTCHA przez nowych użytkowników + flavour_and_skin: + title: Odmiana i motyw + hide_followers_count: + desc_html: Nie pokazuj liczby obserwujących w profilach użytkowników. + title: Ukryj liczbę obserwujących + other: + preamble: Ustawienia glitch-soc niepasujące do innych kategorii. + title: Inne + outgoing_spoilers: + desc_html: Podczas wysyłania wpisów do innych serwerów ukryj ich treść za tym ostrzeżeniem a załączniki oznacz jako wrażliwe. Ta opcja jest dedykowana serwerom specjalizującym się w tematyce, która przez innych może traktowana jako wymagająca ostrzeżenia. + title: Ostrzeżenie o zawartości dla wpisów wysyłanych do innych serwerów + show_reblogs_in_public_timelines: + desc_html: Pokaż publiczne podbicia publicznych wpisów w lokalnych i publicznych osiach czasu. + title: Pokaż podbicia w publicznych osiach czasu + show_replies_in_public_timelines: + desc_html: Oprócz odpowiedzi tworzących wątki pokazuj publiczne odpowiedzi w lokalnych i publicznych osiach czasu. + title: Pokaż odpowiedzi w publicznych osiach czasu + trending_status_cw: + desc_html: Pozwól ukrytym za ostrzeżeniem wpisom na włączenie do sekcji „Popularne teraz”, jeżeli jest ona włączona. Zmiana tego ustawienia nie wpłynie na już opublikowane wpisy. + title: Pozwól ukrytym za ostrzeżeniem wpisom na włączenie do sekcji „Popularne teraz” + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Również w wypadku glitch-soc. + auth: + captcha_confirmation: + hint_html: Aby potwierdzić Twoje konto, ten serwer wymaga rozwiązania przez Ciebie zadania CAPTCHA. Możesz skontaktować się z administratorem, jeśli masz jakieś pytania lub potrzebujesz pomocy. + title: Weryfikacja użytkownika + generic: + use_this: Użyj tego + settings: + flavours: Odmiany diff --git a/config/locales-glitch/pt-BR.yml b/config/locales-glitch/pt-BR.yml new file mode 100644 index 0000000000..95c1579bac --- /dev/null +++ b/config/locales-glitch/pt-BR.yml @@ -0,0 +1,42 @@ +--- +pt-BR: + admin: + custom_emojis: + batch_copy_error: 'Ocorreu um erro ao copiar alguns dos emojis selecionados: %{message}' + batch_error: 'Ocorreu um erro: %{message}' + settings: + captcha_enabled: + desc_html: Isto se baseia em scripts externos de hCaptcha, o que pode ser uma preocupação de segurança e privacidade. Além disso, isto pode tornar o processo de registro significativamente menos acessível para algumas pessoas (especialmente deficientes). Por estas razões, favor considerar medidas alternativas como o registro baseado em aprovação ou em convite.
Os usuários que tiverem sido convidados através de um convite de uso limitado não precisarão resolver um CAPTCHA + title: Exigir que novos usuários resolvam um CAPTCHA para confirmar sua conta + flavour_and_skin: + title: Sabor e tema + hide_followers_count: + desc_html: Não mostrar contagem de seguidores em perfis de usuário + title: Ocultar número de seguidores + other: + preamble: Várias configurações de glitch-soc que não se ajustam em outras categorias. + title: Outros + outgoing_spoilers: + desc_html: Ao federar toots, adicione este aviso de conteúdo aos toots que não possuem um. É útil se seu servidor for especializado em conteúdo que outros servidores podem querer ter sob um Aviso de Conteúdo. Os meios de comunicação também serão marcados como sensíveis. + title: Aviso de conteúdo para toots enviados + show_reblogs_in_public_timelines: + desc_html: Mostrar impulsos públicos de toots públicos nas linhas de tempo locais e públicas. + title: Mostrar impulsos em timelines públicas + show_replies_in_public_timelines: + desc_html: Além das auto-respostas públicas (tópicos), mostrar respostas públicas em linhas do tempo locais e públicas. + title: Mostrar respostas em linhas do tempo públicas + trending_status_cw: + desc_html: Quando as mensagens de tendência estiverem habilitadas, permitir que as mensagens com Avisos de Conteúdo sejam elegíveis. As alterações a esta configuração não são retroativas. + title: Permitir que mensagens com Avisos de Conteúdo tornem-se tendência + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: E também para glitch-soc! + auth: + captcha_confirmation: + hint_html: Só mais um passo! Para confirmar a sua conta, este servidor requer que você resolva um CAPTCHA. Você pode entrar em contato com o administrador do servidor se você tiver dúvidas ou precisa de ajuda para confirmar sua conta. + title: Verificação de usuário + generic: + use_this: Use isto + settings: + flavours: Sabores diff --git a/config/locales-glitch/pt-PT.yml b/config/locales-glitch/pt-PT.yml new file mode 100644 index 0000000000..18e41a0564 --- /dev/null +++ b/config/locales-glitch/pt-PT.yml @@ -0,0 +1,42 @@ +--- +pt-PT: + admin: + custom_emojis: + batch_copy_error: 'Houve um erro ao copiar alguns dos emoji selecionados: %{message}' + batch_error: 'Houve um erro: %{message}' + settings: + captcha_enabled: + desc_html: Isto depende de scripts externos da hCaptcha, o que pode ser uma preocupação de segurança e privacidade. Além disso, isto pode tornar o processo de registo menos acessível para algumas pessoas (especialmente as com limitações físicas). Por isto, considera medidas alternativas tais como registo mediante aprovação ou sob convite.
Pessoas que se registam com um convite não precisam de resolver um CAPTCHA + title: Exigir que novas contas resolvam um CAPTCHA para validar o registo + flavour_and_skin: + title: Sabor e tema + hide_followers_count: + desc_html: Não mostrar o número de seguidores nos perfis + title: Esconder o número de seguidores + other: + preamble: Várias opções do glitch-soc que não cabem noutras categorias. + title: Outras opções + outgoing_spoilers: + desc_html: Ao federar toots, juntar este aviso de conteúdo aos toots que não têm aviso. Isto é útil se o teu servidor for especializado em conteúdos que outros servidores podem querer ter sob um Aviso de Conteúdo. Os media também vão ser marcados como sensíveis. + title: Aviso de conteúdo para toots enviados + show_reblogs_in_public_timelines: + desc_html: Mostrar boosts públicos de toots públicos nas linhas de tempo locais e públicas. + title: Mostrar boosts nas timelines públicas + show_replies_in_public_timelines: + desc_html: Além de auto-respostas públicas (fios), mostrar as respostas públicas em linhas de tempo locais e públicas. + title: Mostrar respostas nas linhas de tempo públicas + trending_status_cw: + desc_html: Quando os posts em tendência estão ativados, permitir que posts com Avisos de Conteúdo também possam aparecer. As alterações nesta opção não são retroativas. + title: Permitir que posts com Avisos de Conteúdo possam aparecer nos posts em tendência + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: E também para o glitch-soc! + auth: + captcha_confirmation: + hint_html: Só mais um passo! Para confirmares a tua conta, este servidor exige que resolvas um CAPTCHA. Podes entrar em contacto com o administrador do servidor se tiveres dúvidas ou precisares de ajuda. + title: Verificação + generic: + use_this: Usar isto + settings: + flavours: Sabores diff --git a/config/locales-glitch/ro.yml b/config/locales-glitch/ro.yml new file mode 100644 index 0000000000..79dbaa871c --- /dev/null +++ b/config/locales-glitch/ro.yml @@ -0,0 +1 @@ +ro: diff --git a/config/locales-glitch/ru.yml b/config/locales-glitch/ru.yml new file mode 100644 index 0000000000..ddc9d1e32c --- /dev/null +++ b/config/locales-glitch/ru.yml @@ -0,0 +1 @@ +ru: diff --git a/config/locales-glitch/sa.yml b/config/locales-glitch/sa.yml new file mode 100644 index 0000000000..07ea4372a3 --- /dev/null +++ b/config/locales-glitch/sa.yml @@ -0,0 +1 @@ +sa: diff --git a/config/locales-glitch/sc.yml b/config/locales-glitch/sc.yml new file mode 100644 index 0000000000..91bd6d92f0 --- /dev/null +++ b/config/locales-glitch/sc.yml @@ -0,0 +1 @@ +sc: diff --git a/config/locales-glitch/sco.yml b/config/locales-glitch/sco.yml new file mode 100644 index 0000000000..8165e00a1b --- /dev/null +++ b/config/locales-glitch/sco.yml @@ -0,0 +1 @@ +sco: diff --git a/config/locales-glitch/si.yml b/config/locales-glitch/si.yml new file mode 100644 index 0000000000..b0b50956ed --- /dev/null +++ b/config/locales-glitch/si.yml @@ -0,0 +1 @@ +si: diff --git a/config/locales-glitch/simple_form.af.yml b/config/locales-glitch/simple_form.af.yml new file mode 100644 index 0000000000..252f9fd5a2 --- /dev/null +++ b/config/locales-glitch/simple_form.af.yml @@ -0,0 +1 @@ +af: diff --git a/config/locales-glitch/simple_form.an.yml b/config/locales-glitch/simple_form.an.yml new file mode 100644 index 0000000000..76cc0689b6 --- /dev/null +++ b/config/locales-glitch/simple_form.an.yml @@ -0,0 +1 @@ +an: diff --git a/config/locales-glitch/simple_form.ar.yml b/config/locales-glitch/simple_form.ar.yml new file mode 100644 index 0000000000..c257bc08a4 --- /dev/null +++ b/config/locales-glitch/simple_form.ar.yml @@ -0,0 +1 @@ +ar: diff --git a/config/locales-glitch/simple_form.ast.yml b/config/locales-glitch/simple_form.ast.yml new file mode 100644 index 0000000000..d762c93994 --- /dev/null +++ b/config/locales-glitch/simple_form.ast.yml @@ -0,0 +1 @@ +ast: diff --git a/config/locales-glitch/simple_form.be.yml b/config/locales-glitch/simple_form.be.yml new file mode 100644 index 0000000000..91ccc2d7e7 --- /dev/null +++ b/config/locales-glitch/simple_form.be.yml @@ -0,0 +1 @@ +be: diff --git a/config/locales-glitch/simple_form.bg.yml b/config/locales-glitch/simple_form.bg.yml new file mode 100644 index 0000000000..d0e375da96 --- /dev/null +++ b/config/locales-glitch/simple_form.bg.yml @@ -0,0 +1 @@ +bg: diff --git a/config/locales-glitch/simple_form.bn.yml b/config/locales-glitch/simple_form.bn.yml new file mode 100644 index 0000000000..152c698290 --- /dev/null +++ b/config/locales-glitch/simple_form.bn.yml @@ -0,0 +1 @@ +bn: diff --git a/config/locales-glitch/simple_form.br.yml b/config/locales-glitch/simple_form.br.yml new file mode 100644 index 0000000000..c7677c850c --- /dev/null +++ b/config/locales-glitch/simple_form.br.yml @@ -0,0 +1 @@ +br: diff --git a/config/locales-glitch/simple_form.bs.yml b/config/locales-glitch/simple_form.bs.yml new file mode 100644 index 0000000000..e9e174462a --- /dev/null +++ b/config/locales-glitch/simple_form.bs.yml @@ -0,0 +1 @@ +bs: diff --git a/config/locales-glitch/simple_form.ca.yml b/config/locales-glitch/simple_form.ca.yml new file mode 100644 index 0000000000..f0c487273d --- /dev/null +++ b/config/locales-glitch/simple_form.ca.yml @@ -0,0 +1 @@ +ca: diff --git a/config/locales-glitch/simple_form.ckb.yml b/config/locales-glitch/simple_form.ckb.yml new file mode 100644 index 0000000000..77d538af77 --- /dev/null +++ b/config/locales-glitch/simple_form.ckb.yml @@ -0,0 +1 @@ +ckb: diff --git a/config/locales-glitch/simple_form.co.yml b/config/locales-glitch/simple_form.co.yml new file mode 100644 index 0000000000..5330938e02 --- /dev/null +++ b/config/locales-glitch/simple_form.co.yml @@ -0,0 +1 @@ +co: diff --git a/config/locales-glitch/simple_form.cs.yml b/config/locales-glitch/simple_form.cs.yml new file mode 100644 index 0000000000..ac07d6175f --- /dev/null +++ b/config/locales-glitch/simple_form.cs.yml @@ -0,0 +1,21 @@ +--- +cs: + simple_form: + hints: + defaults: + setting_default_content_type_html: Předpokládat, že nové příspěvky jsou napsané v HTML, pokud není uvedeno jinak + setting_default_content_type_markdown: Předpokládat, že nové příspěvky používají pro formátování Markdown, pokud není uvedeno jinak + setting_default_content_type_plain: Předpokládat, že nové příspěvky nejsou nijak formátované, pokud není uvedeno jinak (standardní chování Mastodonu) + setting_default_language: Jazyk vašich příspěvků lze detekovat automaticky, ale není to vždycky přesné + setting_skin: Aplikuje barevný styl na zvolené rozhraní Mastodonu + labels: + defaults: + setting_default_content_type: Výchozí formát příspěvků + setting_default_content_type_plain: Prostý text + setting_favourite_modal: Před oblíbením příspěvku zobrazit potvrzovací dialog (pouze pro rozhraní Glitch) + setting_skin: Styl + setting_system_emoji_font: Použít výchozí emoji systému (pouze pro rozhraní Glitch) + notification_emails: + trending_link: Nový populární odkaz vyžaduje schválení + trending_status: Nový populární příspěvek vyžaduje schválení + trending_tag: Nový populární hashtag vyžaduje schválení diff --git a/config/locales-glitch/simple_form.cy.yml b/config/locales-glitch/simple_form.cy.yml new file mode 100644 index 0000000000..deefc9438f --- /dev/null +++ b/config/locales-glitch/simple_form.cy.yml @@ -0,0 +1 @@ +cy: diff --git a/config/locales-glitch/simple_form.da.yml b/config/locales-glitch/simple_form.da.yml new file mode 100644 index 0000000000..c05e9c0129 --- /dev/null +++ b/config/locales-glitch/simple_form.da.yml @@ -0,0 +1,15 @@ +--- +da: + simple_form: + hints: + defaults: + setting_show_followers_count: Vis antal følgere på din profil. Hvis du skjuler antallet af følgere, vil det også være skjult for dig selv, og nogle apps kan vise et negativt antal. + labels: + defaults: + setting_default_content_type: Standardformat for indlæg + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Simpel tekst + setting_favourite_modal: Vis bekræftelsesdialog før favoritmarkering (gælder kun for Glitch-varianten) + setting_show_followers_count: Vis antal følgere + setting_system_emoji_font: Brug systemets standardskrifttype til emojis (gælder kun for Glitch-varianten) diff --git a/config/locales-glitch/simple_form.de.yml b/config/locales-glitch/simple_form.de.yml new file mode 100644 index 0000000000..ff4566b852 --- /dev/null +++ b/config/locales-glitch/simple_form.de.yml @@ -0,0 +1,24 @@ +--- +de: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Beim Schreiben von Toots annehmen, dass sie in rohem HTML geschrieben sind, sofern nicht anders angegeben + setting_default_content_type_markdown: Beim Schreiben von Toots annehmen, dass sie in Markdown für Rich-Text-Formatierung geschrieben sind, sofern nicht anders angegeben + setting_default_content_type_plain: Beim Schreiben von Toots annehmen, dass sie in Klartext ohne spezielle Formatierung geschrieben sind, sofern nicht anders angegeben (standardmäßiges Mastodon-Verhalten) + setting_default_language: Die Sprache deiner Toots kann automatisch erkannt werden, aber sie ist nicht immer korrekt + setting_skin: Verändert die ausgewählte Mastodon-Variante + labels: + defaults: + setting_default_content_type: Standardformat für Toots + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Unformatierter Text + setting_favourite_modal: Bestätigungsdialog vor dem Favorisieren anzeigen (gilt nur für Glitch-Variante) + setting_skin: Skin + setting_system_emoji_font: Systemschriftart für Emojis verwenden (nur für Glitch-Variante) + notification_emails: + trending_link: Neuer angesagter Link muss überprüft werden + trending_status: Neuer angesagter Post muss überprüft werden + trending_tag: Neuer angesagter Tag muss überprüft werden diff --git a/config/locales-glitch/simple_form.el.yml b/config/locales-glitch/simple_form.el.yml new file mode 100644 index 0000000000..419ec705c3 --- /dev/null +++ b/config/locales-glitch/simple_form.el.yml @@ -0,0 +1 @@ +el: diff --git a/config/locales-glitch/simple_form.en-GB.yml b/config/locales-glitch/simple_form.en-GB.yml new file mode 100644 index 0000000000..ef03d18104 --- /dev/null +++ b/config/locales-glitch/simple_form.en-GB.yml @@ -0,0 +1 @@ +en-GB: diff --git a/config/locales-glitch/simple_form.en.yml b/config/locales-glitch/simple_form.en.yml new file mode 100644 index 0000000000..9e943133bd --- /dev/null +++ b/config/locales-glitch/simple_form.en.yml @@ -0,0 +1,26 @@ +--- +en: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: When writing toots, assume they are written in raw HTML, unless specified otherwise + setting_default_content_type_markdown: When writing toots, assume they are using Markdown for rich text formatting, unless specified otherwise + setting_default_content_type_plain: When writing toots, assume they are plain text with no special formatting, unless specified otherwise (default Mastodon behavior) + setting_default_language: The language of your toots can be detected automatically, but it's not always accurate + setting_show_followers_count: Show your followers count on your profile. If you hide your followers count, it will be hidden even from yourself, and some applications may display a negative followers count. + setting_skin: Reskins the selected Mastodon flavour + labels: + defaults: + setting_default_content_type: Default format for toots + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Plain text + setting_favourite_modal: Show confirmation dialog before favouriting (applies to Glitch flavour only) + setting_show_followers_count: Show your followers count + setting_skin: Skin + setting_system_emoji_font: Use system's default font for emojis (applies to Glitch flavour only) + notification_emails: + trending_link: New trending link requires review + trending_status: New trending post requires review + trending_tag: New trending tag requires review diff --git a/config/locales-glitch/simple_form.eo.yml b/config/locales-glitch/simple_form.eo.yml new file mode 100644 index 0000000000..7599814048 --- /dev/null +++ b/config/locales-glitch/simple_form.eo.yml @@ -0,0 +1 @@ +eo: diff --git a/config/locales-glitch/simple_form.es-AR.yml b/config/locales-glitch/simple_form.es-AR.yml new file mode 100644 index 0000000000..491ec7ce8c --- /dev/null +++ b/config/locales-glitch/simple_form.es-AR.yml @@ -0,0 +1,26 @@ +--- +es-AR: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Al escribir toots, asume que estás escritos en HTML, a menos que se especifique lo contrario + setting_default_content_type_markdown: Al escribir toots, asume que estás usando Markdown para dar formato de texto enriquecido, a menos que se especifique lo contrario + setting_default_content_type_plain: Al escribir toots, asume que estás usando texto sin formato, a menos que se especifique lo contrario (predeterminado de Mastodon) + setting_default_language: El idioma de tus toots se puede detectar automáticamente, pero no siempre es correcto + setting_show_followers_count: Mostrá el conteo de tus seguidores en tu perfil. Si ocultás el conteo de tus seguidores, se ocultará incluso a vos mismo, y algunas aplicaciones pueden mostrar un recuento negativo de seguidores. + setting_skin: Cambia el diseño de la edición seleccionada de Mastodon + labels: + defaults: + setting_default_content_type: Formato predeterminado de tus toots + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Sin formato + setting_favourite_modal: Mostrar diálogo de confirmación antes de marcar como favorito (sólo aplica a la edición Glich) + setting_show_followers_count: Mostrá el conteo de tus seguidores + setting_skin: Diseño + setting_system_emoji_font: Usar la fuente predeterminada del sistema para emojis (sólo aplica a la edición Glitch) + notification_emails: + trending_link: Un vínculo en tendencia requiere revisión + trending_status: Una publicación en tendencia requiere revisión + trending_tag: Una etiqueta en tendencia requiere revisión diff --git a/config/locales-glitch/simple_form.es-MX.yml b/config/locales-glitch/simple_form.es-MX.yml new file mode 100644 index 0000000000..39a88a3113 --- /dev/null +++ b/config/locales-glitch/simple_form.es-MX.yml @@ -0,0 +1,24 @@ +--- +es-MX: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Al escribir toots, asume que estás escritos en HTML, a menos que se especifique lo contrario + setting_default_content_type_markdown: Al escribir toots, asume que estás usando Markdown para dar formato de texto enriquecido, a menos que se especifique lo contrario + setting_default_content_type_plain: Al escribir toots, asume que estás usando texto sin formato, a menos que se especifique lo contrario (predeterminado de Mastodon) + setting_default_language: El idioma de tus toots se puede detectar automáticamente, pero no siempre es correcto + setting_skin: Cambia el diseño de la edición seleccionada de Mastodon + labels: + defaults: + setting_default_content_type: Formato predeterminado de tus toots + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Sin formato + setting_favourite_modal: Mostrar diálogo de confirmación antes de marcar como favorito (sólo aplica a la edición Glich) + setting_skin: Diseño + setting_system_emoji_font: Usar la fuente predeterminada del sistema para emojis (sólo aplica a la edición Glitch) + notification_emails: + trending_link: Un vínculo en tendencia requiere revisión + trending_status: Una publicación en tendencia requiere revisión + trending_tag: Una etiqueta en tendencia requiere revisión diff --git a/config/locales-glitch/simple_form.es.yml b/config/locales-glitch/simple_form.es.yml new file mode 100644 index 0000000000..d817bc7e57 --- /dev/null +++ b/config/locales-glitch/simple_form.es.yml @@ -0,0 +1,24 @@ +--- +es: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Al escribir toots, asume que estás escritos en HTML, a menos que se especifique lo contrario + setting_default_content_type_markdown: Al escribir toots, asume que estás usando Markdown para dar formato de texto enriquecido, a menos que se especifique lo contrario + setting_default_content_type_plain: Al escribir toots, asume que estás usando texto sin formato, a menos que se especifique lo contrario (predeterminado de Mastodon) + setting_default_language: El idioma de tus toots se puede detectar automáticamente, pero no siempre es correcto + setting_skin: Cambia el diseño de la edición seleccionada de Mastodon + labels: + defaults: + setting_default_content_type: Formato predeterminado de tus toots + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Sin formato + setting_favourite_modal: Mostrar diálogo de confirmación antes de marcar como favorito (sólo aplica a la edición Glich) + setting_skin: Diseño + setting_system_emoji_font: Usar la fuente predeterminada del sistema para emojis (sólo aplica a la edición Glitch) + notification_emails: + trending_link: Un vínculo en tendencia requiere revisión + trending_status: Una publicación en tendencia requiere revisión + trending_tag: Una etiqueta en tendencia requiere revisión diff --git a/config/locales-glitch/simple_form.et.yml b/config/locales-glitch/simple_form.et.yml new file mode 100644 index 0000000000..e020c4ffc4 --- /dev/null +++ b/config/locales-glitch/simple_form.et.yml @@ -0,0 +1 @@ +et: diff --git a/config/locales-glitch/simple_form.eu.yml b/config/locales-glitch/simple_form.eu.yml new file mode 100644 index 0000000000..566e176fc9 --- /dev/null +++ b/config/locales-glitch/simple_form.eu.yml @@ -0,0 +1 @@ +eu: diff --git a/config/locales-glitch/simple_form.fa.yml b/config/locales-glitch/simple_form.fa.yml new file mode 100644 index 0000000000..88215f82cb --- /dev/null +++ b/config/locales-glitch/simple_form.fa.yml @@ -0,0 +1 @@ +fa: diff --git a/config/locales-glitch/simple_form.fi.yml b/config/locales-glitch/simple_form.fi.yml new file mode 100644 index 0000000000..23c538b193 --- /dev/null +++ b/config/locales-glitch/simple_form.fi.yml @@ -0,0 +1 @@ +fi: diff --git a/config/locales-glitch/simple_form.fo.yml b/config/locales-glitch/simple_form.fo.yml new file mode 100644 index 0000000000..69f792cca3 --- /dev/null +++ b/config/locales-glitch/simple_form.fo.yml @@ -0,0 +1 @@ +fo: diff --git a/config/locales-glitch/simple_form.fr-QC.yml b/config/locales-glitch/simple_form.fr-QC.yml new file mode 100644 index 0000000000..dd0d4ba31d --- /dev/null +++ b/config/locales-glitch/simple_form.fr-QC.yml @@ -0,0 +1,26 @@ +--- +fr-QC: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Vos posts sont écrits en HTML brut, sauf indication contraire + setting_default_content_type_markdown: Vos posts utilisent Markdown pour un formatage de texte enrichi, sauf indication contraire + setting_default_content_type_plain: Vos posts sont écrits en texte brut sans formatage spécial, sauf indication contraire (comportement par défaut de Mastodon) + setting_default_language: La langue utilisée pour vos posts peut être automatiquement détectée, cependant cette détection n'est pas toujours fiable + setting_show_followers_count: Montrer votre nombre d'abonné·e·s sur votre profil. Si vous cachez votre nombre d'abonné·e·s, il le sera de vous-même également, et certaines applications pourraient indiquer un compte d'abonné·e·s négatif. + setting_skin: Relooke le mode de Mastodon choisi + labels: + defaults: + setting_default_content_type: Format par défaut pour les posts + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Texte brut + setting_favourite_modal: Afficher une fenêtre de confirmation avant de mettre en favori un post (s'applique uniquement au mode Glitch) + setting_show_followers_count: Cacher votre nombre d'abonné·e·s + setting_skin: Thème + setting_system_emoji_font: Utiliser la police par défaut du système pour les émojis (s'applique uniquement au mode Glitch) + notification_emails: + trending_link: Un nouveau lien en tendances nécessite un examen + trending_status: Un nouveau post en tendances nécessite un examen + trending_tag: Un nouveau tag en tendances nécessite un examen diff --git a/config/locales-glitch/simple_form.fr.yml b/config/locales-glitch/simple_form.fr.yml new file mode 100644 index 0000000000..a01d9a5f0f --- /dev/null +++ b/config/locales-glitch/simple_form.fr.yml @@ -0,0 +1,26 @@ +--- +fr: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Vos posts sont écrits en HTML brut, sauf indication contraire + setting_default_content_type_markdown: Vos posts utilisent Markdown pour un formatage de texte enrichi, sauf indication contraire + setting_default_content_type_plain: Vos posts sont écrits en texte brut sans formatage spécial, sauf indication contraire (comportement par défaut de Mastodon) + setting_default_language: La langue utilisée pour vos posts peut être automatiquement détectée, cependant cette détection n'est pas toujours fiable + setting_show_followers_count: Montrer votre nombre d'abonné·e·s sur votre profil. Si vous cachez votre nombre d'abonné·e·s, il le sera de vous-même également, et certaines applications pourraient indiquer un compte d'abonné·e·s négatif. + setting_skin: Relooke le mode de Mastodon choisi + labels: + defaults: + setting_default_content_type: Format par défaut pour les posts + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Texte brut + setting_favourite_modal: Afficher une fenêtre de confirmation avant de mettre en favori un post (s'applique uniquement au mode Glitch) + setting_show_followers_count: Cacher votre nombre d'abonné·e·s + setting_skin: Thème + setting_system_emoji_font: Utiliser la police par défaut du système pour les émojis (s'applique uniquement au mode Glitch) + notification_emails: + trending_link: Un nouveau lien en tendances nécessite un examen + trending_status: Un nouveau post en tendances nécessite un examen + trending_tag: Un nouveau tag en tendances nécessite un examen diff --git a/config/locales-glitch/simple_form.fy.yml b/config/locales-glitch/simple_form.fy.yml new file mode 100644 index 0000000000..c05849f20d --- /dev/null +++ b/config/locales-glitch/simple_form.fy.yml @@ -0,0 +1 @@ +fy: diff --git a/config/locales-glitch/simple_form.ga.yml b/config/locales-glitch/simple_form.ga.yml new file mode 100644 index 0000000000..20a9da24e9 --- /dev/null +++ b/config/locales-glitch/simple_form.ga.yml @@ -0,0 +1 @@ +ga: diff --git a/config/locales-glitch/simple_form.gd.yml b/config/locales-glitch/simple_form.gd.yml new file mode 100644 index 0000000000..1912f6c6a6 --- /dev/null +++ b/config/locales-glitch/simple_form.gd.yml @@ -0,0 +1 @@ +gd: diff --git a/config/locales-glitch/simple_form.gl.yml b/config/locales-glitch/simple_form.gl.yml new file mode 100644 index 0000000000..8ec5fc81c1 --- /dev/null +++ b/config/locales-glitch/simple_form.gl.yml @@ -0,0 +1 @@ +gl: diff --git a/config/locales-glitch/simple_form.he.yml b/config/locales-glitch/simple_form.he.yml new file mode 100644 index 0000000000..af6fa60a73 --- /dev/null +++ b/config/locales-glitch/simple_form.he.yml @@ -0,0 +1 @@ +he: diff --git a/config/locales-glitch/simple_form.hi.yml b/config/locales-glitch/simple_form.hi.yml new file mode 100644 index 0000000000..d758a5b535 --- /dev/null +++ b/config/locales-glitch/simple_form.hi.yml @@ -0,0 +1 @@ +hi: diff --git a/config/locales-glitch/simple_form.hr.yml b/config/locales-glitch/simple_form.hr.yml new file mode 100644 index 0000000000..f67f33c7e0 --- /dev/null +++ b/config/locales-glitch/simple_form.hr.yml @@ -0,0 +1 @@ +hr: diff --git a/config/locales-glitch/simple_form.hu.yml b/config/locales-glitch/simple_form.hu.yml new file mode 100644 index 0000000000..52314c50c9 --- /dev/null +++ b/config/locales-glitch/simple_form.hu.yml @@ -0,0 +1 @@ +hu: diff --git a/config/locales-glitch/simple_form.hy.yml b/config/locales-glitch/simple_form.hy.yml new file mode 100644 index 0000000000..c406540162 --- /dev/null +++ b/config/locales-glitch/simple_form.hy.yml @@ -0,0 +1 @@ +hy: diff --git a/config/locales-glitch/simple_form.id.yml b/config/locales-glitch/simple_form.id.yml new file mode 100644 index 0000000000..8446cbad90 --- /dev/null +++ b/config/locales-glitch/simple_form.id.yml @@ -0,0 +1 @@ +id: diff --git a/config/locales-glitch/simple_form.ig.yml b/config/locales-glitch/simple_form.ig.yml new file mode 100644 index 0000000000..7c264f0d73 --- /dev/null +++ b/config/locales-glitch/simple_form.ig.yml @@ -0,0 +1 @@ +ig: diff --git a/config/locales-glitch/simple_form.io.yml b/config/locales-glitch/simple_form.io.yml new file mode 100644 index 0000000000..c63dc0e8d9 --- /dev/null +++ b/config/locales-glitch/simple_form.io.yml @@ -0,0 +1 @@ +io: diff --git a/config/locales-glitch/simple_form.is.yml b/config/locales-glitch/simple_form.is.yml new file mode 100644 index 0000000000..337c106df9 --- /dev/null +++ b/config/locales-glitch/simple_form.is.yml @@ -0,0 +1 @@ +is: diff --git a/config/locales-glitch/simple_form.it.yml b/config/locales-glitch/simple_form.it.yml new file mode 100644 index 0000000000..85830635a7 --- /dev/null +++ b/config/locales-glitch/simple_form.it.yml @@ -0,0 +1 @@ +it: diff --git a/config/locales-glitch/simple_form.ja.yml b/config/locales-glitch/simple_form.ja.yml new file mode 100644 index 0000000000..1137420097 --- /dev/null +++ b/config/locales-glitch/simple_form.ja.yml @@ -0,0 +1,24 @@ +--- +ja: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: トゥートを作成するとき特に指定がない限り生のHTMLで書かれているとします + setting_default_content_type_markdown: トゥートを作成するとき特に指定がない限りリッチテキスト形式のマークダウンで書かれているとします + setting_default_content_type_plain: トゥートを作成するとき特に指定がない限りプレーンテキストで書かれているとします(Mastodon既定の動作) + setting_default_language: あなたのトゥートの言語を自動検出しますが必ずしも正確ではありません + setting_skin: 選択したMastodonフレーバーに変更します + labels: + defaults: + setting_default_content_type: 既定のトゥート形式 + setting_default_content_type_html: HTML + setting_default_content_type_markdown: マークダウン + setting_default_content_type_plain: プレーンテキスト + setting_favourite_modal: お気に入りをする前に確認ダイアログを表示する + setting_skin: スキン + setting_system_emoji_font: 絵文字にシステム既定のフォントを使用する(Glitch Edition フレーバーのみに適用されます) + notification_emails: + trending_link: 新しいトレンドリンクのレビューが必要 + trending_status: 新しいトレンド投稿のレビューが必要 + trending_tag: 新しいトレンドタグにはレビューが必要 diff --git a/config/locales-glitch/simple_form.ka.yml b/config/locales-glitch/simple_form.ka.yml new file mode 100644 index 0000000000..57a95cb047 --- /dev/null +++ b/config/locales-glitch/simple_form.ka.yml @@ -0,0 +1 @@ +ka: diff --git a/config/locales-glitch/simple_form.kab.yml b/config/locales-glitch/simple_form.kab.yml new file mode 100644 index 0000000000..2109c04b37 --- /dev/null +++ b/config/locales-glitch/simple_form.kab.yml @@ -0,0 +1 @@ +kab: diff --git a/config/locales-glitch/simple_form.kk.yml b/config/locales-glitch/simple_form.kk.yml new file mode 100644 index 0000000000..1dcc9b127c --- /dev/null +++ b/config/locales-glitch/simple_form.kk.yml @@ -0,0 +1 @@ +kk: diff --git a/config/locales-glitch/simple_form.kn.yml b/config/locales-glitch/simple_form.kn.yml new file mode 100644 index 0000000000..d094088d88 --- /dev/null +++ b/config/locales-glitch/simple_form.kn.yml @@ -0,0 +1 @@ +kn: diff --git a/config/locales-glitch/simple_form.ko.yml b/config/locales-glitch/simple_form.ko.yml new file mode 100644 index 0000000000..f9420f1336 --- /dev/null +++ b/config/locales-glitch/simple_form.ko.yml @@ -0,0 +1,24 @@ +--- +ko: + simple_form: + glitch_only: 글리치 + hints: + defaults: + setting_default_content_type_html: 게시물을 작성할 때, 형식을 지정하지 않았다면, 생 HTML이라고 가정합니다 + setting_default_content_type_markdown: 게시물을 작성할 때, 형식을 지정하지 않았다면, 마크다운이라고 가정합니다 + setting_default_content_type_plain: 게시물을 작성할 때, 형식을 지정하지 않았다면, 일반적인 텍스트라고 가정합니다. (마스토돈의 기본 동작) + setting_default_language: 작성하는 게시물의 언어는 자동으로 설정될 수 있습니다, 하지만 언제나 정확하지는 않습니다 + setting_skin: 선택한 마스토돈 풍미의 스킨을 바꿉니다 + labels: + defaults: + setting_default_content_type: 게시물의 기본 포맷 + setting_default_content_type_html: HTML + setting_default_content_type_markdown: 마크다운 + setting_default_content_type_plain: 일반 텍스트 + setting_favourite_modal: 관심글을 지정할 때 확인 창을 띄웁니다(글리치 풍미에만 적용됨) + setting_skin: 스킨 + setting_system_emoji_font: 에모지에 시스템 기본 폰트 적용하기 (글리치 풍미에만 적용됨) + notification_emails: + trending_link: 새로 유행중인 링크에 대한 리뷰가 필요할 때 + trending_status: 새로 유행중인 게시물에 대한 리뷰가 필요할 때 + trending_tag: 새로 유행중인 해시태그에 대한 리뷰가 필요할 때 diff --git a/config/locales-glitch/simple_form.ku.yml b/config/locales-glitch/simple_form.ku.yml new file mode 100644 index 0000000000..b36f7c9883 --- /dev/null +++ b/config/locales-glitch/simple_form.ku.yml @@ -0,0 +1 @@ +ku: diff --git a/config/locales-glitch/simple_form.kw.yml b/config/locales-glitch/simple_form.kw.yml new file mode 100644 index 0000000000..b2cfc12ff1 --- /dev/null +++ b/config/locales-glitch/simple_form.kw.yml @@ -0,0 +1 @@ +kw: diff --git a/config/locales-glitch/simple_form.la.yml b/config/locales-glitch/simple_form.la.yml new file mode 100644 index 0000000000..3a7ba0d445 --- /dev/null +++ b/config/locales-glitch/simple_form.la.yml @@ -0,0 +1 @@ +la: diff --git a/config/locales-glitch/simple_form.lt.yml b/config/locales-glitch/simple_form.lt.yml new file mode 100644 index 0000000000..6c5cb837ac --- /dev/null +++ b/config/locales-glitch/simple_form.lt.yml @@ -0,0 +1 @@ +lt: diff --git a/config/locales-glitch/simple_form.lv.yml b/config/locales-glitch/simple_form.lv.yml new file mode 100644 index 0000000000..1be0eabc09 --- /dev/null +++ b/config/locales-glitch/simple_form.lv.yml @@ -0,0 +1 @@ +lv: diff --git a/config/locales-glitch/simple_form.mk.yml b/config/locales-glitch/simple_form.mk.yml new file mode 100644 index 0000000000..8b9144a988 --- /dev/null +++ b/config/locales-glitch/simple_form.mk.yml @@ -0,0 +1 @@ +mk: diff --git a/config/locales-glitch/simple_form.ml.yml b/config/locales-glitch/simple_form.ml.yml new file mode 100644 index 0000000000..6931a683d1 --- /dev/null +++ b/config/locales-glitch/simple_form.ml.yml @@ -0,0 +1 @@ +ml: diff --git a/config/locales-glitch/simple_form.mr.yml b/config/locales-glitch/simple_form.mr.yml new file mode 100644 index 0000000000..fe1639c6a3 --- /dev/null +++ b/config/locales-glitch/simple_form.mr.yml @@ -0,0 +1 @@ +mr: diff --git a/config/locales-glitch/simple_form.ms.yml b/config/locales-glitch/simple_form.ms.yml new file mode 100644 index 0000000000..2925688a03 --- /dev/null +++ b/config/locales-glitch/simple_form.ms.yml @@ -0,0 +1 @@ +ms: diff --git a/config/locales-glitch/simple_form.my.yml b/config/locales-glitch/simple_form.my.yml new file mode 100644 index 0000000000..5e1fc6bee9 --- /dev/null +++ b/config/locales-glitch/simple_form.my.yml @@ -0,0 +1 @@ +my: diff --git a/config/locales-glitch/simple_form.nl.yml b/config/locales-glitch/simple_form.nl.yml new file mode 100644 index 0000000000..f009eadee5 --- /dev/null +++ b/config/locales-glitch/simple_form.nl.yml @@ -0,0 +1 @@ +nl: diff --git a/config/locales-glitch/simple_form.nn.yml b/config/locales-glitch/simple_form.nn.yml new file mode 100644 index 0000000000..777f4e600f --- /dev/null +++ b/config/locales-glitch/simple_form.nn.yml @@ -0,0 +1 @@ +nn: diff --git a/config/locales-glitch/simple_form.no.yml b/config/locales-glitch/simple_form.no.yml new file mode 100644 index 0000000000..d2a4697e5d --- /dev/null +++ b/config/locales-glitch/simple_form.no.yml @@ -0,0 +1 @@ +no: diff --git a/config/locales-glitch/simple_form.oc.yml b/config/locales-glitch/simple_form.oc.yml new file mode 100644 index 0000000000..325b348894 --- /dev/null +++ b/config/locales-glitch/simple_form.oc.yml @@ -0,0 +1 @@ +oc: diff --git a/config/locales-glitch/simple_form.pa.yml b/config/locales-glitch/simple_form.pa.yml new file mode 100644 index 0000000000..bb8a6c834d --- /dev/null +++ b/config/locales-glitch/simple_form.pa.yml @@ -0,0 +1 @@ +pa: diff --git a/config/locales-glitch/simple_form.pl.yml b/config/locales-glitch/simple_form.pl.yml new file mode 100644 index 0000000000..bec84b6429 --- /dev/null +++ b/config/locales-glitch/simple_form.pl.yml @@ -0,0 +1,24 @@ +--- +pl: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Jeżeli nie powiedziano inaczej, załóż, że wpisy są pisane w HTML + setting_default_content_type_markdown: Jeżeli nie powiedziano inaczej, załóż, że wpisy są pisane w Markdown + setting_default_content_type_plain: Jeżeli nie powiedziano inaczej, załóż, że wpisy zawierają jedynie czysty tekst (domyślne zachowane Mastodonu) + setting_default_language: Język Twoich wpisów może zostać wykryty automatycznie, aczkolwiek poprawność działania tej fukcji nie jest gwarantowana + setting_skin: Zmienia wygląd używanej odmiany Mastodona + labels: + defaults: + setting_default_content_type: Domyślny format wpisów + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Czysty tekst + setting_favourite_modal: Pytaj o potwierdzenie przed dodaniem do ulubionych + setting_skin: Motyw + setting_system_emoji_font: Użyj systemowej czcionki emotikon (tylko w wypadku odmiany „Glitch”) + notification_emails: + trending_link: Nowy, popularny link wymaga przeglądu + trending_status: Nowy, popularny wpis wymaga przeglądu + trending_tag: Nowy, popularny tag wymaga przeglądu diff --git a/config/locales-glitch/simple_form.pt-BR.yml b/config/locales-glitch/simple_form.pt-BR.yml new file mode 100644 index 0000000000..be3e215f40 --- /dev/null +++ b/config/locales-glitch/simple_form.pt-BR.yml @@ -0,0 +1,24 @@ +--- +pt-BR: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: Ao escrever toots, assume que estão escritos em HTML bruto, a menos que especificado de outra forma + setting_default_content_type_markdown: Ao escrever toots, assume que ele está usando Markdown para formatação de texto, a menos que especificado seja diferente + setting_default_content_type_plain: Ao escrever toots, assume que eles são textos simples sem formatação especial, a menos que esteja especificado de outra forma (comportamento padrão do Mastodon) + setting_default_language: O idioma dos seus toots pode ser detectado automaticamente, mas nem sempre é preciso + setting_skin: Reaplica o sabor Mastodon selecionado + labels: + defaults: + setting_default_content_type: Formato padrão para toots + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Texto sem formatação + setting_favourite_modal: Mostrar diálogo antes de favoritar (aplica-se somente ao sabor Glitch) + setting_skin: Tema + setting_system_emoji_font: Usar fonte padrão do sistema para emojis (aplica-se somente ao sabor Glitch) + notification_emails: + trending_link: Novo link em tendência requer revisão + trending_status: Nova postagem em tendência requer revisão + trending_tag: Nova tag em tendência requer revisão diff --git a/config/locales-glitch/simple_form.pt-PT.yml b/config/locales-glitch/simple_form.pt-PT.yml new file mode 100644 index 0000000000..a1a2dc36b3 --- /dev/null +++ b/config/locales-glitch/simple_form.pt-PT.yml @@ -0,0 +1 @@ +pt-PT: diff --git a/config/locales-glitch/simple_form.ro.yml b/config/locales-glitch/simple_form.ro.yml new file mode 100644 index 0000000000..79dbaa871c --- /dev/null +++ b/config/locales-glitch/simple_form.ro.yml @@ -0,0 +1 @@ +ro: diff --git a/config/locales-glitch/simple_form.ru.yml b/config/locales-glitch/simple_form.ru.yml new file mode 100644 index 0000000000..ddc9d1e32c --- /dev/null +++ b/config/locales-glitch/simple_form.ru.yml @@ -0,0 +1 @@ +ru: diff --git a/config/locales-glitch/simple_form.sa.yml b/config/locales-glitch/simple_form.sa.yml new file mode 100644 index 0000000000..07ea4372a3 --- /dev/null +++ b/config/locales-glitch/simple_form.sa.yml @@ -0,0 +1 @@ +sa: diff --git a/config/locales-glitch/simple_form.sc.yml b/config/locales-glitch/simple_form.sc.yml new file mode 100644 index 0000000000..91bd6d92f0 --- /dev/null +++ b/config/locales-glitch/simple_form.sc.yml @@ -0,0 +1 @@ +sc: diff --git a/config/locales-glitch/simple_form.sco.yml b/config/locales-glitch/simple_form.sco.yml new file mode 100644 index 0000000000..8165e00a1b --- /dev/null +++ b/config/locales-glitch/simple_form.sco.yml @@ -0,0 +1 @@ +sco: diff --git a/config/locales-glitch/simple_form.si.yml b/config/locales-glitch/simple_form.si.yml new file mode 100644 index 0000000000..b0b50956ed --- /dev/null +++ b/config/locales-glitch/simple_form.si.yml @@ -0,0 +1 @@ +si: diff --git a/config/locales-glitch/simple_form.sk.yml b/config/locales-glitch/simple_form.sk.yml new file mode 100644 index 0000000000..f634a02824 --- /dev/null +++ b/config/locales-glitch/simple_form.sk.yml @@ -0,0 +1 @@ +sk: diff --git a/config/locales-glitch/simple_form.sl.yml b/config/locales-glitch/simple_form.sl.yml new file mode 100644 index 0000000000..26c7ce2e31 --- /dev/null +++ b/config/locales-glitch/simple_form.sl.yml @@ -0,0 +1 @@ +sl: diff --git a/config/locales-glitch/simple_form.sq.yml b/config/locales-glitch/simple_form.sq.yml new file mode 100644 index 0000000000..44ddadc95a --- /dev/null +++ b/config/locales-glitch/simple_form.sq.yml @@ -0,0 +1 @@ +sq: diff --git a/config/locales-glitch/simple_form.sr-Latn.yml b/config/locales-glitch/simple_form.sr-Latn.yml new file mode 100644 index 0000000000..c482b5e449 --- /dev/null +++ b/config/locales-glitch/simple_form.sr-Latn.yml @@ -0,0 +1 @@ +sr-Latn: diff --git a/config/locales-glitch/simple_form.sr.yml b/config/locales-glitch/simple_form.sr.yml new file mode 100644 index 0000000000..9e26af8191 --- /dev/null +++ b/config/locales-glitch/simple_form.sr.yml @@ -0,0 +1 @@ +sr: diff --git a/config/locales-glitch/simple_form.sv.yml b/config/locales-glitch/simple_form.sv.yml new file mode 100644 index 0000000000..7e73a972a7 --- /dev/null +++ b/config/locales-glitch/simple_form.sv.yml @@ -0,0 +1 @@ +sv: diff --git a/config/locales-glitch/simple_form.ta.yml b/config/locales-glitch/simple_form.ta.yml new file mode 100644 index 0000000000..4320953ce2 --- /dev/null +++ b/config/locales-glitch/simple_form.ta.yml @@ -0,0 +1 @@ +ta: diff --git a/config/locales-glitch/simple_form.te.yml b/config/locales-glitch/simple_form.te.yml new file mode 100644 index 0000000000..34c54f18f6 --- /dev/null +++ b/config/locales-glitch/simple_form.te.yml @@ -0,0 +1 @@ +te: diff --git a/config/locales-glitch/simple_form.th.yml b/config/locales-glitch/simple_form.th.yml new file mode 100644 index 0000000000..a4431912a8 --- /dev/null +++ b/config/locales-glitch/simple_form.th.yml @@ -0,0 +1 @@ +th: diff --git a/config/locales-glitch/simple_form.tr.yml b/config/locales-glitch/simple_form.tr.yml new file mode 100644 index 0000000000..077d41667a --- /dev/null +++ b/config/locales-glitch/simple_form.tr.yml @@ -0,0 +1 @@ +tr: diff --git a/config/locales-glitch/simple_form.tt.yml b/config/locales-glitch/simple_form.tt.yml new file mode 100644 index 0000000000..5eab4abff9 --- /dev/null +++ b/config/locales-glitch/simple_form.tt.yml @@ -0,0 +1 @@ +tt: diff --git a/config/locales-glitch/simple_form.ug.yml b/config/locales-glitch/simple_form.ug.yml new file mode 100644 index 0000000000..289acf2418 --- /dev/null +++ b/config/locales-glitch/simple_form.ug.yml @@ -0,0 +1 @@ +ug: diff --git a/config/locales-glitch/simple_form.uk.yml b/config/locales-glitch/simple_form.uk.yml new file mode 100644 index 0000000000..dcd932bb17 --- /dev/null +++ b/config/locales-glitch/simple_form.uk.yml @@ -0,0 +1,24 @@ +--- +uk: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: При написанні дмухів, вони записуються в необробленному HTML, якщо це не вказано інакше + setting_default_content_type_markdown: При написанні дмухів вони використовують Markdown для форматування розширеного тексту, якщо не вказано інше + setting_default_content_type_plain: При написанні дмухів , дмух буде звичайним текстом без спеціального форматування, якщо не вказано інше (поведінка Mastodon за замовчуванням). + setting_default_language: Мова ваших дмухів може визначатися автоматично, але не завжди точно + setting_skin: Відновлює звичайну тему Mastodon + labels: + defaults: + setting_default_content_type: Формат дмухів за замовчуванням + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: Звичайний текст + setting_favourite_modal: Показувати діалогове вікно підтвердження перед додаванням до улюблених (стосується лише теми Glitch) + setting_skin: Тема оформлення + setting_system_emoji_font: Використовувати типовий системний шрифт для емодзі (застосовується лише до теми Glitch) + notification_emails: + trending_link: Нове трендове посилання потребує перегляду + trending_status: Новий трендовий допис потребує перегляду + trending_tag: Новий новий теґ потребує перегляду diff --git a/config/locales-glitch/simple_form.ur.yml b/config/locales-glitch/simple_form.ur.yml new file mode 100644 index 0000000000..2cace5883d --- /dev/null +++ b/config/locales-glitch/simple_form.ur.yml @@ -0,0 +1 @@ +ur: diff --git a/config/locales-glitch/simple_form.vi.yml b/config/locales-glitch/simple_form.vi.yml new file mode 100644 index 0000000000..326506f0b1 --- /dev/null +++ b/config/locales-glitch/simple_form.vi.yml @@ -0,0 +1 @@ +vi: diff --git a/config/locales-glitch/simple_form.zh-CN.yml b/config/locales-glitch/simple_form.zh-CN.yml new file mode 100644 index 0000000000..44cb08f5a2 --- /dev/null +++ b/config/locales-glitch/simple_form.zh-CN.yml @@ -0,0 +1,26 @@ +--- +zh-CN: + simple_form: + glitch_only: glitch-soc + hints: + defaults: + setting_default_content_type_html: 在撰写嘟文时,除非另有指定,假定它们使用原始 HTML 语言撰写 + setting_default_content_type_markdown: 在撰写嘟文时,除非另有指定,假定它们使用 Markdown 进行富文本格式化 + setting_default_content_type_plain: 在撰写嘟文时,除非另有指定,假定它们是没有特殊格式的纯文本(默认的 Mastodon 行为) + setting_default_language: 你的嘟文语言可以自动检测,但不一定准确 + setting_show_followers_count: 在您的个人资料页上显示您的粉丝数。如果隐藏了您的粉丝数,即使自己也将无法看到,并且某些应用可能会显示负的粉丝数。 + setting_skin: 更换为所选择的 Mastodon 风格 + labels: + defaults: + setting_default_content_type: 嘟文默认格式 + setting_default_content_type_html: HTML + setting_default_content_type_markdown: Markdown + setting_default_content_type_plain: 纯文本 + setting_favourite_modal: 在点赞嘟文前询问我 (仅限于 Glitch 风格) + setting_show_followers_count: 显示粉丝数 + setting_skin: 皮肤 + setting_system_emoji_font: 使用系统自带表情 (仅限于 Glitch 风格) + notification_emails: + trending_link: 新热门链接需要审核 + trending_status: 新热门嘟文需要审核 + trending_tag: 新热门话题需要审核 diff --git a/config/locales-glitch/simple_form.zh-HK.yml b/config/locales-glitch/simple_form.zh-HK.yml new file mode 100644 index 0000000000..8e51e56487 --- /dev/null +++ b/config/locales-glitch/simple_form.zh-HK.yml @@ -0,0 +1 @@ +zh-HK: diff --git a/config/locales-glitch/simple_form.zh-TW.yml b/config/locales-glitch/simple_form.zh-TW.yml new file mode 100644 index 0000000000..cb82c05261 --- /dev/null +++ b/config/locales-glitch/simple_form.zh-TW.yml @@ -0,0 +1 @@ +zh-TW: diff --git a/config/locales-glitch/sk.yml b/config/locales-glitch/sk.yml new file mode 100644 index 0000000000..f634a02824 --- /dev/null +++ b/config/locales-glitch/sk.yml @@ -0,0 +1 @@ +sk: diff --git a/config/locales-glitch/sl.yml b/config/locales-glitch/sl.yml new file mode 100644 index 0000000000..26c7ce2e31 --- /dev/null +++ b/config/locales-glitch/sl.yml @@ -0,0 +1 @@ +sl: diff --git a/config/locales-glitch/sq.yml b/config/locales-glitch/sq.yml new file mode 100644 index 0000000000..44ddadc95a --- /dev/null +++ b/config/locales-glitch/sq.yml @@ -0,0 +1 @@ +sq: diff --git a/config/locales-glitch/sr-Latn.yml b/config/locales-glitch/sr-Latn.yml new file mode 100644 index 0000000000..c482b5e449 --- /dev/null +++ b/config/locales-glitch/sr-Latn.yml @@ -0,0 +1 @@ +sr-Latn: diff --git a/config/locales-glitch/sr.yml b/config/locales-glitch/sr.yml new file mode 100644 index 0000000000..9e26af8191 --- /dev/null +++ b/config/locales-glitch/sr.yml @@ -0,0 +1 @@ +sr: diff --git a/config/locales-glitch/sv.yml b/config/locales-glitch/sv.yml new file mode 100644 index 0000000000..7e73a972a7 --- /dev/null +++ b/config/locales-glitch/sv.yml @@ -0,0 +1 @@ +sv: diff --git a/config/locales-glitch/ta.yml b/config/locales-glitch/ta.yml new file mode 100644 index 0000000000..4320953ce2 --- /dev/null +++ b/config/locales-glitch/ta.yml @@ -0,0 +1 @@ +ta: diff --git a/config/locales-glitch/te.yml b/config/locales-glitch/te.yml new file mode 100644 index 0000000000..34c54f18f6 --- /dev/null +++ b/config/locales-glitch/te.yml @@ -0,0 +1 @@ +te: diff --git a/config/locales-glitch/th.yml b/config/locales-glitch/th.yml new file mode 100644 index 0000000000..a4431912a8 --- /dev/null +++ b/config/locales-glitch/th.yml @@ -0,0 +1 @@ +th: diff --git a/config/locales-glitch/tr.yml b/config/locales-glitch/tr.yml new file mode 100644 index 0000000000..077d41667a --- /dev/null +++ b/config/locales-glitch/tr.yml @@ -0,0 +1 @@ +tr: diff --git a/config/locales-glitch/tt.yml b/config/locales-glitch/tt.yml new file mode 100644 index 0000000000..5eab4abff9 --- /dev/null +++ b/config/locales-glitch/tt.yml @@ -0,0 +1 @@ +tt: diff --git a/config/locales-glitch/ug.yml b/config/locales-glitch/ug.yml new file mode 100644 index 0000000000..289acf2418 --- /dev/null +++ b/config/locales-glitch/ug.yml @@ -0,0 +1 @@ +ug: diff --git a/config/locales-glitch/uk.yml b/config/locales-glitch/uk.yml new file mode 100644 index 0000000000..05e46c478a --- /dev/null +++ b/config/locales-glitch/uk.yml @@ -0,0 +1,41 @@ +--- +uk: + admin: + custom_emojis: + batch_copy_error: 'Виникла помилка при копіюванні деяких вибраних емодзі: %{message}' + batch_error: 'Сталася помилка: %{message}' + settings: + captcha_enabled: + title: Вимагати нових користувачів проходити CAPTCHA для підтвердження свого облікового запису + flavour_and_skin: + title: Оформлення + hide_followers_count: + desc_html: Не показувати підписників у профілях користувачів + title: Приховати лічильник підписників + other: + preamble: Різні налаштування glitch-soc не вміщуються в інші категорії. + title: Інші + outgoing_spoilers: + desc_html: При федерації дмухів, додавання цього вмісту попередження до дмухів, яких немає. Це корисно, якщо ваш сервер спеціалізується на інших серверах і може захотіти мати під попередженням про вміст. Медіа також буде відзначена як чутливі. + title: Попередження про вміст на вихідні дмухи + show_reblogs_in_public_timelines: + desc_html: Показати публічні поширення дмухів в локальній та публічній стрічці. + title: Показати поширення в публічній стрічці + show_replies_in_public_timelines: + desc_html: На додачу до публічних само-відповідей (потоків), показувати публічні відповіді на локальній та публічній хронологіях. + title: Показати відповіді в публічній стрічці + trending_status_cw: + desc_html: Якщо увімкнено тренди, дозвольте публікаціям з попередженнями про вміст бути прийнятними. Зміни цього параметра не мають зворотної дії. + title: Дозволити дописи з попередженнями про вміст у тренді + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Так само і для неймовірного glitch-soc! + auth: + captcha_confirmation: + hint_html: Ще один крок! Щоб підтвердити свій обліковий запис, інстанс потребує проходження коду CAPTCHA. Ви можете зв'язатися з адміністратором інстансу , якщо у вас є питання або потрібна допомога з підтвердженням вашого облікового запису. + title: Верифікація користувача + generic: + use_this: Використати це + settings: + flavours: Оформлення diff --git a/config/locales-glitch/ur.yml b/config/locales-glitch/ur.yml new file mode 100644 index 0000000000..2cace5883d --- /dev/null +++ b/config/locales-glitch/ur.yml @@ -0,0 +1 @@ +ur: diff --git a/config/locales-glitch/vi.yml b/config/locales-glitch/vi.yml new file mode 100644 index 0000000000..326506f0b1 --- /dev/null +++ b/config/locales-glitch/vi.yml @@ -0,0 +1 @@ +vi: diff --git a/config/locales-glitch/zh-CN.yml b/config/locales-glitch/zh-CN.yml new file mode 100644 index 0000000000..41a153ae10 --- /dev/null +++ b/config/locales-glitch/zh-CN.yml @@ -0,0 +1,42 @@ +--- +zh-CN: + admin: + custom_emojis: + batch_copy_error: '复制部分所选表情时发生错误: %{message}' + batch_error: 发生了一个错误:%{message} + settings: + captcha_enabled: + desc_html: 这依赖于来自hCaptcha的外部脚本,这可能是一个安全和隐私问题。 此外, 这可能使得某些人(尤其是残疾人)的注册简单程度大幅减少。 出于这些原因,请考虑采取其他措施,例如基于审核或邀请的注册。
通过限定邀请链接注册的用户将不需要解决验证码问题 + title: 要求新用户解决验证码以确认他们的账户 + flavour_and_skin: + title: 风格与皮肤 + hide_followers_count: + desc_html: 不要在用户资料中显示粉丝数 + title: 隐藏粉丝数 + other: + preamble: 各种不适合归类到其他类别的glitch-soc设置。 + title: 其它 + outgoing_spoilers: + desc_html: 在交换嘟文的时候,将这个内容警告添加到没有内容警告的嘟文中。如果你的服务器专用于其他服务器可能希望有内容警告的内容,它会很有用。媒体也将被标记为敏感。 + title: 对外添加嘟文内容警告 + show_reblogs_in_public_timelines: + desc_html: 在本站和跨站时间线中显示公开嘟文的转嘟。 + title: 在公共时间线中显示转嘟 + show_replies_in_public_timelines: + desc_html: 除了公开的自我回复(线程模式),在本地和跨站时间轴中显示公开回复。 + title: 在公共时间线中显示回复 + trending_status_cw: + desc_html: 当热门帖子被启用时,允许带有内容警告的帖子获得资格。此设置的更改不具有追溯性。 + title: 允许带有内容警告的帖子进入热门 + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: Glitch-soc也是如此! + auth: + captcha_confirmation: + hint_html: 只需最后一步!为了确认您的账户,本服务器需要您解决一个验证码。如果您有疑问或需要帮助确认您的账户,请联系服务器管理员。 + title: 用户验证 + generic: + use_this: 使用这个 + settings: + flavours: 风格 diff --git a/config/locales-glitch/zh-HK.yml b/config/locales-glitch/zh-HK.yml new file mode 100644 index 0000000000..8e51e56487 --- /dev/null +++ b/config/locales-glitch/zh-HK.yml @@ -0,0 +1 @@ +zh-HK: diff --git a/config/locales-glitch/zh-TW.yml b/config/locales-glitch/zh-TW.yml new file mode 100644 index 0000000000..99af36c9ec --- /dev/null +++ b/config/locales-glitch/zh-TW.yml @@ -0,0 +1,9 @@ +--- +zh-TW: + appearance: + localization: + glitch_guide_link: https://crowdin.com/project/glitch-soc + glitch_guide_link_text: 對於 glitch-soc 來說也是如此! + auth: + captcha_confirmation: + title: 使用者驗證 diff --git a/config/locales/activerecord.ar.yml b/config/locales/activerecord.ar.yml index a30fd9f383..cacbf0714f 100644 --- a/config/locales/activerecord.ar.yml +++ b/config/locales/activerecord.ar.yml @@ -8,12 +8,12 @@ ar: user: agreement: اتفاقية الخدمة email: عنوان البريد الإلكتروني - locale: محلي + locale: اللغة password: كلمة المرور user/account: username: اسم المستخدم user/invite_request: - text: السبب + text: الغرض errors: models: account: @@ -24,11 +24,11 @@ ar: admin/webhook: attributes: url: - invalid: رابط غير صحيح + invalid: رابط تشعبي غير صالح doorkeeper/application: attributes: website: - invalid: رابط غير صحيح + invalid: رابط تشعبي غير صالح import: attributes: data: @@ -41,9 +41,9 @@ ar: attributes: email: blocked: يستخدم مزوّد بريد إلكتروني غير مسموح به - unreachable: يبدو أنه لا وجود + unreachable: يبدو أنه لا وجود له role_id: - elevated: لا يمكن أن يكون أعلى من الدور الحالي + elevated: لا يمكن أن يكون أعلى من دَورِك الحالي user_role: attributes: permissions_as_keys: @@ -53,3 +53,7 @@ ar: position: elevated: لا يمكن أن يكون أعلى من دورك الحالي own_role: لا يمكن تغييرها مع دورك الحالي + webhook: + attributes: + events: + invalid_permissions: لا يمكن إدراج الأحداث التي لا تمتلك حقوقها diff --git a/config/locales/activerecord.be.yml b/config/locales/activerecord.be.yml index 6245ee0903..db6b632dc4 100644 --- a/config/locales/activerecord.be.yml +++ b/config/locales/activerecord.be.yml @@ -53,3 +53,7 @@ be: position: elevated: не можа быць вышэй за вашу бягучую ролю own_role: не можа быць зменены з вашай бягучай роляй + webhook: + attributes: + events: + invalid_permissions: не можа ўключаць у сябе падзеі на якія ў вас няма правоў diff --git a/config/locales/activerecord.bg.yml b/config/locales/activerecord.bg.yml index 2fd0791715..1e19d1effb 100644 --- a/config/locales/activerecord.bg.yml +++ b/config/locales/activerecord.bg.yml @@ -19,7 +19,7 @@ bg: account: attributes: username: - invalid: трябва да е само букви, цифри и долни черти + invalid: трябва да е само буквено-цифрено и долни черти reserved: е запазено admin/webhook: attributes: @@ -41,7 +41,7 @@ bg: attributes: email: blocked: използва се забранен доставчик на услуга за е-поща - unreachable: изглежда, че не съществува + unreachable: изглежда не съществува role_id: elevated: не може да е по-висока от текущата ви роля user_role: @@ -53,3 +53,7 @@ bg: position: elevated: не може да е по-висока от текущата ви роля own_role: не може да се промени с текущата ви роля + webhook: + attributes: + events: + invalid_permissions: не може да включва събития, към които нямате права diff --git a/config/locales/activerecord.bn.yml b/config/locales/activerecord.bn.yml index 0ed3c7eeac..aded2aa7ae 100644 --- a/config/locales/activerecord.bn.yml +++ b/config/locales/activerecord.bn.yml @@ -5,12 +5,20 @@ bn: poll: expires_at: নির্দিষ্ট সময়সীমা options: বিকল্প + user: + locale: ভাষা + password: পাসওয়ার্ড + user/account: + username: ব্যবহারকারীর নাম + user/invite_request: + text: কারণ errors: models: account: attributes: username: invalid: শুধুমাত্র অক্ষর, সংখ্যা এবং _ বেবহার করা যাবে + reserved: সংরক্ষিত status: attributes: reblog: diff --git a/config/locales/activerecord.ca.yml b/config/locales/activerecord.ca.yml index 17d0720d5a..021cc38b4f 100644 --- a/config/locales/activerecord.ca.yml +++ b/config/locales/activerecord.ca.yml @@ -24,11 +24,11 @@ ca: admin/webhook: attributes: url: - invalid: no és una URL vàlida + invalid: no és un enllaç vàlid doorkeeper/application: attributes: website: - invalid: no és una URL vàlida + invalid: no és un enllaç vàlid import: attributes: data: @@ -53,3 +53,7 @@ ca: position: elevated: no pot ser superior al teu rol actual own_role: no es pot canviar amb el teu rol actual + webhook: + attributes: + events: + invalid_permissions: no pots incloure esdeveniments que no en tens permisos diff --git a/config/locales/activerecord.cs.yml b/config/locales/activerecord.cs.yml index def69db1ff..6f4fe86e3f 100644 --- a/config/locales/activerecord.cs.yml +++ b/config/locales/activerecord.cs.yml @@ -8,7 +8,7 @@ cs: user: agreement: Souhlas s podmínkami email: E-mailová adresa - locale: Lokalizace + locale: Jazyk password: Heslo user/account: username: Uživatelské jméno @@ -53,3 +53,7 @@ cs: position: elevated: nemůže být vyšší než vaše aktuální role own_role: nelze změnit s vaší aktuální rolí + webhook: + attributes: + events: + invalid_permissions: nelze zahrnout události, k nimž nemáte práva diff --git a/config/locales/activerecord.csb.yml b/config/locales/activerecord.csb.yml deleted file mode 100644 index 0de706e41f..0000000000 --- a/config/locales/activerecord.csb.yml +++ /dev/null @@ -1 +0,0 @@ -csb: diff --git a/config/locales/activerecord.cy.yml b/config/locales/activerecord.cy.yml index cadc4eee4a..73b54d554e 100644 --- a/config/locales/activerecord.cy.yml +++ b/config/locales/activerecord.cy.yml @@ -8,7 +8,7 @@ cy: user: agreement: Cytundeb gwasanaeth email: Cyfeiriad e-bost - locale: Locale + locale: Lleoliad password: Cyfrinair user/account: username: Enw defnyddiwr @@ -53,3 +53,7 @@ cy: position: elevated: nid yw'n gallu bod yn uwch na'ch rôl cyfredol own_role: nid oes modd ei newid gyda'ch rôl cyfredol + webhook: + attributes: + events: + invalid_permissions: ni ellir cynnwys digwyddiadau nad oes gennych yr hawl iddynt diff --git a/config/locales/activerecord.da.yml b/config/locales/activerecord.da.yml index 35d63da498..fd94a6cf9a 100644 --- a/config/locales/activerecord.da.yml +++ b/config/locales/activerecord.da.yml @@ -3,7 +3,7 @@ da: activerecord: attributes: poll: - expires_at: 截止时间 + expires_at: Tidsfrist options: Valgmuligheder user: agreement: Tjenesteaftale @@ -24,19 +24,19 @@ da: admin/webhook: attributes: url: - invalid: "'er ikke en gyldig URL" + invalid: er ikke en gyldig URL doorkeeper/application: attributes: website: - invalid: "'er ikke en gyldig URL" + invalid: er ikke en gyldig URL import: attributes: data: - malformed: er forkert udformet + malformed: har ugyldigt format status: attributes: reblog: - taken: af allerede eksisterende status + taken: af status findes allerede user: attributes: email: @@ -53,3 +53,7 @@ da: position: elevated: kan ikke være højere end din aktuelle rolle own_role: kan ikke ændres med din aktuelle rolle + webhook: + attributes: + events: + invalid_permissions: kan ikke inkludere begivenheder, du ikke har rettigheder til diff --git a/config/locales/activerecord.de.yml b/config/locales/activerecord.de.yml index 7e49ed1e16..ca590bec7d 100644 --- a/config/locales/activerecord.de.yml +++ b/config/locales/activerecord.de.yml @@ -11,7 +11,7 @@ de: locale: Sprache password: Passwort user/account: - username: Benutzername + username: Profilname user/invite_request: text: Begründung errors: @@ -28,7 +28,7 @@ de: doorkeeper/application: attributes: website: - invalid: ist keine gültige Adresse + invalid: ist keine gültige URL import: attributes: data: @@ -43,13 +43,17 @@ de: blocked: verwendet einen unerlaubten E-Mail-Anbieter unreachable: scheint nicht zu existieren role_id: - elevated: kann nicht höher als Ihre aktuelle Rolle sein + elevated: kann nicht höher als deine derzeitige Rolle sein user_role: attributes: permissions_as_keys: - dangerous: enthält Berechtigungen, welche nicht sicher sind für die Basisrolle - elevated: kann nicht Berechtigungen beinhalten, die deine aktuelle Rolle nicht besitzt - own_role: kann nicht mit deiner aktuellen Rolle geändert werden + dangerous: enthält Berechtigungen, die für die Basisrolle nicht sicher sind + elevated: kann keine Berechtigungen enthalten, die deine aktuelle Rolle nicht besitzt + own_role: kann mit deiner aktuellen Rolle nicht geändert werden position: - elevated: kann nicht höher sein als deine aktuelle Rolle - own_role: kann nicht mit deiner aktuellen Rolle geändert werden + elevated: darf nicht höher als deine derzeitige Rolle sein + own_role: darf nicht mit deiner aktuellen Rolle geändert werden + webhook: + attributes: + events: + invalid_permissions: kann keine Ereignisse einschließen, für die du keine Berechtigung hast diff --git a/config/locales/activerecord.el.yml b/config/locales/activerecord.el.yml index b285e457a1..4eae3b6a00 100644 --- a/config/locales/activerecord.el.yml +++ b/config/locales/activerecord.el.yml @@ -21,6 +21,14 @@ el: username: invalid: μόνο γράμματα, αριθμοί και κάτω παύλες reserved: είναι δεσμευμένο + admin/webhook: + attributes: + url: + invalid: δεν είναι έγκυρο URL + doorkeeper/application: + attributes: + website: + invalid: δεν είναι έγκυρο URL import: attributes: data: @@ -34,9 +42,14 @@ el: email: blocked: χρησιμοποιεί μη επιτρεπόμενο πάροχο e-mail unreachable: δεν φαίνεται να υπάρχει + role_id: + elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας user_role: attributes: permissions_as_keys: + dangerous: προσθήκη δικαιωμάτων που δεν είναι ασφαλή για τον βασικό ρόλο + elevated: δεν είναι δυνατή η προσθήκη δικαιωμάτων που ο τρέχων ρόλος σας δεν κατέχει own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας position: + elevated: δεν μπορεί να είναι μεγαλύτερο από τον τρέχοντα ρόλο σας own_role: δεν μπορεί να αλλάξει με τον τρέχοντα ρόλο σας diff --git a/config/locales/activerecord.en-GB.yml b/config/locales/activerecord.en-GB.yml index e651708c22..2b1cb05a6f 100644 --- a/config/locales/activerecord.en-GB.yml +++ b/config/locales/activerecord.en-GB.yml @@ -53,3 +53,7 @@ en-GB: position: elevated: cannot be higher than your current role own_role: cannot be changed with your current role + webhook: + attributes: + events: + invalid_permissions: cannot include events you don't have the rights to diff --git a/config/locales/activerecord.eo.yml b/config/locales/activerecord.eo.yml index 64af882b4d..99059e3856 100644 --- a/config/locales/activerecord.eo.yml +++ b/config/locales/activerecord.eo.yml @@ -53,3 +53,7 @@ eo: position: elevated: ne povas esti pli altranga ol via aktuala rolo own_role: ne eblas esti ŝanĝita per via aktuala rolo + webhook: + attributes: + events: + invalid_permissions: ne povas inkluzivi eventojn pri kiuj vi ne havas la rajtojn diff --git a/config/locales/activerecord.es-AR.yml b/config/locales/activerecord.es-AR.yml index e00b806962..71b7f9732d 100644 --- a/config/locales/activerecord.es-AR.yml +++ b/config/locales/activerecord.es-AR.yml @@ -53,3 +53,7 @@ es-AR: position: elevated: no puede ser mayor que tu rol actual own_role: no se puede cambiar con tu rol actual + webhook: + attributes: + events: + invalid_permissions: no se pueden incluir eventos para los que no tenés derechos diff --git a/config/locales/activerecord.es-MX.yml b/config/locales/activerecord.es-MX.yml index da76110052..882c40ae8d 100644 --- a/config/locales/activerecord.es-MX.yml +++ b/config/locales/activerecord.es-MX.yml @@ -53,3 +53,7 @@ es-MX: position: elevated: no puede ser mayor que tu rol actual own_role: no se puede cambiar con tu rol actual + webhook: + attributes: + events: + invalid_permissions: no se pueden incluir eventos para los que no tienes permisos diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 450658fa13..186104c702 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -36,7 +36,7 @@ es: status: attributes: reblog: - taken: del estado ya existe + taken: de la publicación ya existe user: attributes: email: @@ -53,3 +53,7 @@ es: position: elevated: no puede ser mayor que tu rol actual own_role: no se puede cambiar con tu rol actual + webhook: + attributes: + events: + invalid_permissions: no se pueden incluir eventos para los que no tienes derechos diff --git a/config/locales/activerecord.et.yml b/config/locales/activerecord.et.yml index d98c6b611a..8cabf0e0fe 100644 --- a/config/locales/activerecord.et.yml +++ b/config/locales/activerecord.et.yml @@ -53,3 +53,7 @@ et: position: elevated: ei saa olla kõrgem, kui sinu praegune roll own_role: ei saa muuta sinu praeguse rolliga + webhook: + attributes: + events: + invalid_permissions: ei tohi sisaldada sündmuseid, mille jaoks pole sul õiguseid diff --git a/config/locales/activerecord.eu.yml b/config/locales/activerecord.eu.yml index 8b83b4ef85..818dab939c 100644 --- a/config/locales/activerecord.eu.yml +++ b/config/locales/activerecord.eu.yml @@ -53,3 +53,7 @@ eu: position: elevated: ezin du zure uneko rola baino goragokoa izan own_role: ezin da aldatu zure uneko rolarekin + webhook: + attributes: + events: + invalid_permissions: ezin duzu gehitu eskubiderik ez duzun gertakaririk diff --git a/config/locales/activerecord.fa.yml b/config/locales/activerecord.fa.yml index 7af0975ff2..3d1e8012bf 100644 --- a/config/locales/activerecord.fa.yml +++ b/config/locales/activerecord.fa.yml @@ -53,3 +53,7 @@ fa: position: elevated: نمی‌تواند بالاتر از نقش کنونیتان باشد own_role: نمی‌تواند با نقش کنونیتان تغییر کند + webhook: + attributes: + events: + invalid_permissions: نمی‌تواند شامل رویدادهایی باشد که حقوقش را ندارید diff --git a/config/locales/activerecord.fi.yml b/config/locales/activerecord.fi.yml index c1dbaff0fe..a06cd399a8 100644 --- a/config/locales/activerecord.fi.yml +++ b/config/locales/activerecord.fi.yml @@ -24,11 +24,11 @@ fi: admin/webhook: attributes: url: - invalid: ei ole kelvollinen URL + invalid: ei ole kelvollinen verkko-osoite doorkeeper/application: attributes: website: - invalid: ei ole kelvollinen URL + invalid: ei ole kelvollinen verkko-osoite import: attributes: data: @@ -53,3 +53,7 @@ fi: position: elevated: ei voi olla korkeampi kuin nykyinen roolisi own_role: ei voi muuttaa nykyisellä roolillasi + webhook: + attributes: + events: + invalid_permissions: ei voi sisältää tapahtumia, joihin sinulla ei ole oikeuksia diff --git a/config/locales/activerecord.fo.yml b/config/locales/activerecord.fo.yml index 4e1a39596f..cf447a9dbc 100644 --- a/config/locales/activerecord.fo.yml +++ b/config/locales/activerecord.fo.yml @@ -53,3 +53,7 @@ fo: position: elevated: loyvi kunnu ikki setast hægri, við verandi rættindum own_role: kann ikki verða broytt við tínum verandi rættindum + webhook: + attributes: + events: + invalid_permissions: kann ikki taka hendingar, sum tú ikki hevur rættindi til, við diff --git a/config/locales/activerecord.fr-QC.yml b/config/locales/activerecord.fr-QC.yml index aed5d290ad..607758add6 100644 --- a/config/locales/activerecord.fr-QC.yml +++ b/config/locales/activerecord.fr-QC.yml @@ -53,3 +53,7 @@ fr-QC: position: elevated: ne peut pas être supérieur à votre rôle actuel own_role: ne peut pas être modifié avec votre rôle actuel + webhook: + attributes: + events: + invalid_permissions: ne peut pas inclure des évènements pour lesquels vous n’avez pas les droits diff --git a/config/locales/activerecord.fr.yml b/config/locales/activerecord.fr.yml index bd34fcbcf1..24bb39502b 100644 --- a/config/locales/activerecord.fr.yml +++ b/config/locales/activerecord.fr.yml @@ -3,7 +3,7 @@ fr: activerecord: attributes: poll: - expires_at: Date butoir + expires_at: Date de fin options: Choix user: agreement: Contrat de service @@ -13,7 +13,7 @@ fr: user/account: username: Nom d’utilisateur·ice user/invite_request: - text: Raison + text: Motif errors: models: account: @@ -53,3 +53,7 @@ fr: position: elevated: ne peut pas être supérieur à votre rôle actuel own_role: ne peut pas être modifié avec votre rôle actuel + webhook: + attributes: + events: + invalid_permissions: ne peut pas inclure des évènements pour lesquels vous n’avez pas les droits diff --git a/config/locales/activerecord.fy.yml b/config/locales/activerecord.fy.yml index cc10d817d5..b571ab60dc 100644 --- a/config/locales/activerecord.fy.yml +++ b/config/locales/activerecord.fy.yml @@ -43,13 +43,17 @@ fy: blocked: brûkt in net tastiene e-mailprovider unreachable: liket net te bestean role_id: - elevated: kin net heger wêze as dyn aktuele rol + elevated: kin net heger wêze as jo aktuele rol user_role: attributes: permissions_as_keys: dangerous: rjochten tafoegje dy’t net feilich binne foar de basisrol - elevated: kin gjin rjochten tafoegje dy’t dyn aktuele rol net besit - own_role: kin net mei dyn aktuele rol wizige wurde + elevated: kin gjin rjochten tafoegje dy’t jo aktuele rol net besit + own_role: kin net mei jo aktuele rol wizige wurde position: - elevated: kin net heger wêze as dyn aktuele rol - own_role: kin net mei dyn aktuele rol wizige wurde + elevated: kin net heger wêze as jo aktuele rol + own_role: kin net mei jo aktuele rol wizige wurde + webhook: + attributes: + events: + invalid_permissions: kin gjin barrens befetsje dêr’t jo gjin rjochten foar hawwe diff --git a/config/locales/activerecord.gd.yml b/config/locales/activerecord.gd.yml index 5e1657d7b7..895f035c03 100644 --- a/config/locales/activerecord.gd.yml +++ b/config/locales/activerecord.gd.yml @@ -53,3 +53,7 @@ gd: position: elevated: chan fhaod seo a bhith nas àirde na an dreuchd a th’ agad an-dràsta own_role: cha ghabh seo atharrachadh leis an dreuchd a th’ agad an-dràsta + webhook: + attributes: + events: + invalid_permissions: chan fhaod thu tachartasan air nach eil ceadan agad a ghabhail a-steach diff --git a/config/locales/activerecord.gl.yml b/config/locales/activerecord.gl.yml index 9393008949..477db570e7 100644 --- a/config/locales/activerecord.gl.yml +++ b/config/locales/activerecord.gl.yml @@ -53,3 +53,7 @@ gl: position: elevated: non pode superar ao teu rol actual own_role: non pode ser modificado co teu rol actual + webhook: + attributes: + events: + invalid_permissions: non podes incluír eventos para os que non tes permiso diff --git a/config/locales/activerecord.he.yml b/config/locales/activerecord.he.yml index 6fe4556787..54d0b0a1cc 100644 --- a/config/locales/activerecord.he.yml +++ b/config/locales/activerecord.he.yml @@ -53,3 +53,7 @@ he: position: elevated: לא יכול להיות גבוה יותר מתפקידך הנוכחי own_role: לא ניתן לשנות באמצעות תפקידך הנוכחי + webhook: + attributes: + events: + invalid_permissions: לא ניתן לכלול ארועים שאין לך הרשאה בשבילם diff --git a/config/locales/activerecord.hi.yml b/config/locales/activerecord.hi.yml index b002ab0933..94368d8e68 100644 --- a/config/locales/activerecord.hi.yml +++ b/config/locales/activerecord.hi.yml @@ -5,12 +5,26 @@ hi: poll: expires_at: समयसीमा options: विकल्प + user: + agreement: सेवा अनुबंध। + email: ई-मेइल पता + locale: स्थानिक + password: कुंजिका + user/account: + username: यूज़रनेम + user/invite_request: + text: कारण errors: models: account: attributes: username: invalid: केवल अक्षर, संख्या और अंडरस्कोर + reserved: आरक्षित है + admin/webhook: + attributes: + url: + invalid: यह मान्य यु.आर.एल. नहिं है status: attributes: reblog: diff --git a/config/locales/activerecord.hr.yml b/config/locales/activerecord.hr.yml index 98ca8155fd..b095244dd6 100644 --- a/config/locales/activerecord.hr.yml +++ b/config/locales/activerecord.hr.yml @@ -5,3 +5,16 @@ hr: poll: expires_at: Krajnji rok options: Opcije + user: + email: E-mail adresa + password: Lozinka + user/account: + username: Korisničko ime + user/invite_request: + text: Razlog + errors: + models: + account: + attributes: + username: + invalid: mora sadržavati samo slova, brojeve i _ diff --git a/config/locales/activerecord.hu.yml b/config/locales/activerecord.hu.yml index 67bad4cb45..e5757ba643 100644 --- a/config/locales/activerecord.hu.yml +++ b/config/locales/activerecord.hu.yml @@ -40,7 +40,7 @@ hu: user: attributes: email: - blocked: egy letiltott e-mail szolgáltatót használ + blocked: egy letiltott email szolgáltatót használ unreachable: úgy tűnik, hogy nem létezik role_id: elevated: nem lehet magasabb, mint a jelenlegi szereped @@ -53,3 +53,7 @@ hu: position: elevated: nem lehet magasabb, mint a jelenlegi szereped own_role: nem megváltoztatható a jelenlegi szerepköröddel + webhook: + attributes: + events: + invalid_permissions: nem lehet olyan eseményeket bevenni, melyekhez nincs jogosultságod diff --git a/config/locales/activerecord.io.yml b/config/locales/activerecord.io.yml index 1adc664cd7..6426defc55 100644 --- a/config/locales/activerecord.io.yml +++ b/config/locales/activerecord.io.yml @@ -53,3 +53,7 @@ io: position: elevated: ne povas divenar plu alta kam vua nuna rolo own_role: ne povas divenesar kun vua nuna rolo + webhook: + attributes: + events: + invalid_permissions: ne povas inkluzar eventi a qui vu ne havas la yuri diff --git a/config/locales/activerecord.is.yml b/config/locales/activerecord.is.yml index fa3406fe33..4423cb6e47 100644 --- a/config/locales/activerecord.is.yml +++ b/config/locales/activerecord.is.yml @@ -53,3 +53,7 @@ is: position: elevated: getur ekki verið veigameiri en núverandi hlutverk þitt own_role: er ekki hægt að breyta með þinu hlutverki + webhook: + attributes: + events: + invalid_permissions: getur ekki innihaldið atburði sem þú hefur ekki réttindi á diff --git a/config/locales/activerecord.it.yml b/config/locales/activerecord.it.yml index 0acbd87478..f23513e34c 100644 --- a/config/locales/activerecord.it.yml +++ b/config/locales/activerecord.it.yml @@ -53,3 +53,7 @@ it: position: elevated: non può essere superiore al tuo ruolo corrente own_role: non può essere modificato con il tuo ruolo corrente + webhook: + attributes: + events: + invalid_permissions: non è possibile includere eventi per i quali non hai i diritti diff --git a/config/locales/activerecord.ja.yml b/config/locales/activerecord.ja.yml index 91fa044925..468df9b12b 100644 --- a/config/locales/activerecord.ja.yml +++ b/config/locales/activerecord.ja.yml @@ -53,3 +53,7 @@ ja: position: elevated: 現在と同じロールには変更できません own_role: 現在と同じロールには変更できません + webhook: + attributes: + events: + invalid_permissions: あなたが権利を持っていないイベントを含めることはできません diff --git a/config/locales/activerecord.ka.yml b/config/locales/activerecord.ka.yml index cdd4f9c4c6..cb8a03702d 100644 --- a/config/locales/activerecord.ka.yml +++ b/config/locales/activerecord.ka.yml @@ -1,13 +1,50 @@ --- ka: activerecord: + attributes: + poll: + expires_at: ბოლო ვადა + options: არჩევანი + user: + agreement: მომსახურების ხელშეკრულება + email: ელ-ფოსტის მისამართი + locale: ლოკალი + password: პაროლი + user/account: + username: მომხმარებლის სახელი + user/invite_request: + text: მიზეზი errors: models: account: attributes: username: invalid: მხოლოდ ასოები, ციფრები და "ქვედა-ტირე" + reserved: რეზერვირებულია + admin/webhook: + attributes: + url: + invalid: არასწორი URL + doorkeeper/application: + attributes: + website: + invalid: არასწორი URL + import: + attributes: + data: + malformed: არასწორად არის ფორმირებული status: attributes: reblog: taken: სტატუსის უკვე არსებობს + user: + attributes: + email: + blocked: იყენებს აკრძალულ ელ-ფოსტის პროვაიდერს + unreachable: როგორც ჩანს, არ არსებობს + role_id: + elevated: არ შეიძლება იყოს თქვენს ამჟამინდელ როლზე მაღალი + user_role: + attributes: + permissions_as_keys: + dangerous: მოიცავს ნებართვებს, რომლებიც არ არის უსაფრთხო საბაზისო როლისთვის diff --git a/config/locales/activerecord.kab.yml b/config/locales/activerecord.kab.yml index 5b3d06634d..909ff68c24 100644 --- a/config/locales/activerecord.kab.yml +++ b/config/locales/activerecord.kab.yml @@ -25,3 +25,7 @@ kab: attributes: reblog: taken: n iddaden yellan yakan + user: + attributes: + email: + unreachable: ur d-ttban ara d akken yella diff --git a/config/locales/activerecord.ko.yml b/config/locales/activerecord.ko.yml index 5d6b6693c1..294d614bca 100644 --- a/config/locales/activerecord.ko.yml +++ b/config/locales/activerecord.ko.yml @@ -53,3 +53,7 @@ ko: position: elevated: 당신의 현재 역할보다 높을 수 없습니다 own_role: 당신의 현재 역할을 변경할 수 없습니다 + webhook: + attributes: + events: + invalid_permissions: 권한이 없는 이벤트를 포함할 수는 없습니다 diff --git a/config/locales/activerecord.lv.yml b/config/locales/activerecord.lv.yml index 097a29621e..5e41f4630e 100644 --- a/config/locales/activerecord.lv.yml +++ b/config/locales/activerecord.lv.yml @@ -53,3 +53,7 @@ lv: position: elevated: nevar būt augstāka par tavu pašreizējo lomu own_role: nevar mainīt pret tavu pašreizējo lomu + webhook: + attributes: + events: + invalid_permissions: nevar ietvert pasākumus, uz kuriem tev nav tiesību diff --git a/config/locales/activerecord.ms.yml b/config/locales/activerecord.ms.yml index 6b84248dec..5f282702f1 100644 --- a/config/locales/activerecord.ms.yml +++ b/config/locales/activerecord.ms.yml @@ -53,3 +53,7 @@ ms: position: elevated: tidak boleh lebih tinggi daripada peranan semasa anda own_role: tidak boleh diubah dengan peranan semasa anda + webhook: + attributes: + events: + invalid_permissions: tidak boleh memasukkan acara yang anda tidak mempunyai hak untuk melakukannya diff --git a/config/locales/activerecord.my.yml b/config/locales/activerecord.my.yml index 6aba9d49b9..f75f9d8e13 100644 --- a/config/locales/activerecord.my.yml +++ b/config/locales/activerecord.my.yml @@ -19,9 +19,41 @@ my: account: attributes: username: - invalid: အက္ခရာစာလုံး၊ ဂဏန်းနံပါတ်နှင့်underscores သာပါရမည် - reserved: အသုံးပြုပြီးဖြစ်သည် + invalid: တွင် အက္ခရာစာလုံး၊ ဂဏန်းနံပါတ်နှင့်underscores သာပါရမည် + reserved: သည် အသုံးပြုပြီးဖြစ်သည် + admin/webhook: + attributes: + url: + invalid: သည် မှန်ကန်သော URL မဟုတ်ပါ + doorkeeper/application: + attributes: + website: + invalid: သည် မှန်ကန်သော URL မဟုတ်ပါ + import: + attributes: + data: + malformed: သည် ပုံမှန်မဟုတ်ပါ + status: + attributes: + reblog: + taken: ပို့စ်တည်ရှိနှင့်ပြီးဖြစ်သည် user: attributes: email: - unreachable: တည်ရှိပုံ မပေါ်ပါ + blocked: တွင် ခွင့်မပြုထားသော အီးမေးလ်ထောက်ပံ့သူပါဝင်နေသည်။ + unreachable: သည် တည်ရှိပုံ မပေါ်ပါ + role_id: + elevated: သင့်လက်ရှိအခန်းကဏ္ဍထက်ပို၍ မမြှင့်တင်နိုင်ပါ + user_role: + attributes: + permissions_as_keys: + dangerous: အခြေခံအခန်းကဏ္ဍအတွက် လုံခြုံမှုမရှိသော ခွင့်ပြုချက်များပါဝင်နေသည် + elevated: သင့်လက်ရှိအခန်းကဏ္ဍမပိုင်ဆိုင်သော ခွင့်ပြုချက်များမပါဝင်ပါ + own_role: သင့်လက်ရှိအခန်းကဏ္ဍဖြင့် ပြောင်းလဲ၍မရနိုင်ပါ + position: + elevated: သင့်လက်ရှိအခန်းကဏ္ဍထက်ပို၍ မမြှင့်တင်နိုင်ပါ + own_role: သင့်လက်ရှိအခန်းကဏ္ဍဖြင့် ပြောင်းလဲ၍မရနိုင်ပါ + webhook: + attributes: + events: + invalid_permissions: ပါဝင်ဖို့ သင့်တွင်အခွင့်မရှိပါ diff --git a/config/locales/activerecord.nl.yml b/config/locales/activerecord.nl.yml index 0e1f824b79..ce2c28a810 100644 --- a/config/locales/activerecord.nl.yml +++ b/config/locales/activerecord.nl.yml @@ -3,7 +3,7 @@ nl: activerecord: attributes: poll: - expires_at: Deadline + expires_at: Vervaldatum options: Keuzes user: agreement: Servicevoorwaarden @@ -53,3 +53,7 @@ nl: position: elevated: kan niet hoger zijn dan jouw huidige rol own_role: kan niet met jouw huidige rol worden gewijzigd + webhook: + attributes: + events: + invalid_permissions: kan geen gebeurtenissen bevatten waar je geen rechten voor hebt diff --git a/config/locales/activerecord.nn.yml b/config/locales/activerecord.nn.yml index 30afb8b079..a303af6247 100644 --- a/config/locales/activerecord.nn.yml +++ b/config/locales/activerecord.nn.yml @@ -53,3 +53,7 @@ nn: position: elevated: kan ikkje vere høgare enn di noverande rolle own_role: kan ikkje endrast med di noverande rolle + webhook: + attributes: + events: + invalid_permissions: kan ikkje inkludere hendingar du ikkje har rettar til diff --git a/config/locales/activerecord.no.yml b/config/locales/activerecord.no.yml index eb1793ca76..5abe3fdc38 100644 --- a/config/locales/activerecord.no.yml +++ b/config/locales/activerecord.no.yml @@ -8,7 +8,7 @@ user: agreement: Tjenesteavtale email: E-postadresse - locale: Landstandard + locale: Språk password: Passord user/account: username: Brukernavn @@ -24,11 +24,11 @@ admin/webhook: attributes: url: - invalid: er ikke en gyldig nettadresse + invalid: er ikke en gyldig lenke doorkeeper/application: attributes: website: - invalid: er ikke en gyldig nettadresse + invalid: er ikke en gyldig lenke import: attributes: data: @@ -53,3 +53,7 @@ position: elevated: kan ikke være høyere enn din nåværende rolle own_role: kan ikke endres med din nåværende rolle + webhook: + attributes: + events: + invalid_permissions: kan ikke inkludere hendelser du ikke har rettigheter til diff --git a/config/locales/activerecord.pl.yml b/config/locales/activerecord.pl.yml index 0d1d9efb19..5ae1d3778a 100644 --- a/config/locales/activerecord.pl.yml +++ b/config/locales/activerecord.pl.yml @@ -53,3 +53,7 @@ pl: position: elevated: nie może być wyższa niż twoja bieżąca rola own_role: nie może być zmieniona z twoją aktualną rolą + webhook: + attributes: + events: + invalid_permissions: nie można uwzględnić wydarzeń, do których nie masz uprawnień diff --git a/config/locales/activerecord.pt-BR.yml b/config/locales/activerecord.pt-BR.yml index 9aa9af62ed..ae78026629 100644 --- a/config/locales/activerecord.pt-BR.yml +++ b/config/locales/activerecord.pt-BR.yml @@ -43,7 +43,7 @@ pt-BR: blocked: usa provedor de e-mail não permitido unreachable: parece não existir role_id: - elevated: não pode ser maior do que seu cargo atual + elevated: não pode ser maior que seu cargo atual user_role: attributes: permissions_as_keys: @@ -53,3 +53,7 @@ pt-BR: position: elevated: não pode ser maior do que seu cargo atual own_role: não pode ser alterado com seu cargo atual + webhook: + attributes: + events: + invalid_permissions: não pode incluir eventos que você não tem permissão para diff --git a/config/locales/activerecord.pt-PT.yml b/config/locales/activerecord.pt-PT.yml index 927c0bffa9..ba738741f8 100644 --- a/config/locales/activerecord.pt-PT.yml +++ b/config/locales/activerecord.pt-PT.yml @@ -53,3 +53,7 @@ pt-PT: position: elevated: não pode ser maior que o da sua função atual own_role: não pode ser alterado com a sua função atual + webhook: + attributes: + events: + invalid_permissions: não pode incluir eventos para os quais não tem permissão diff --git a/config/locales/activerecord.ro.yml b/config/locales/activerecord.ro.yml index 33be0258b8..83c90eda29 100644 --- a/config/locales/activerecord.ro.yml +++ b/config/locales/activerecord.ro.yml @@ -53,3 +53,7 @@ ro: position: elevated: nu poate fi mai mare decât rolul curent own_role: nu poate fi schimbat cu rolul curent + webhook: + attributes: + events: + invalid_permissions: nu poate include evenimente la care nu aveți drepturi diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml index 17b13fc7b4..14f9f61f6c 100644 --- a/config/locales/activerecord.ru.yml +++ b/config/locales/activerecord.ru.yml @@ -53,3 +53,7 @@ ru: position: elevated: не может быть выше, чем ваша текущая роль own_role: невозможно изменить с вашей текущей ролью + webhook: + attributes: + events: + invalid_permissions: нельзя включать события, к которым у вас нет прав diff --git a/config/locales/activerecord.sa.yml b/config/locales/activerecord.sa.yml index 07ea4372a3..b9868c4b85 100644 --- a/config/locales/activerecord.sa.yml +++ b/config/locales/activerecord.sa.yml @@ -1 +1,59 @@ +--- sa: + activerecord: + attributes: + poll: + expires_at: समयसीमा + options: चयनानि + user: + agreement: सेवासम्मतिः + email: ई-पत्रसङ्केतः + locale: स्थलीयम् + password: गुप्तपदम् + user/account: + username: उपभोक्तृनाम + user/invite_request: + text: कारणम् + errors: + models: + account: + attributes: + username: + invalid: केवलमक्षराणि, संख्याः, अन्दर्स्कोरित्येतानि अवश्यानि लभ्येरन्। + reserved: आरक्षितम् + admin/webhook: + attributes: + url: + invalid: वैधं URL नास्ति + doorkeeper/application: + attributes: + website: + invalid: वैधं URL नास्ति + import: + attributes: + data: + malformed: विकृतम् + status: + attributes: + reblog: + taken: प्रेषणस्य पूर्णमेव विद्यते + user: + attributes: + email: + blocked: अस्वीकृतमीपत्रप्रदातारं प्रयोजयति + unreachable: नास्तीति प्रतीयते + role_id: + elevated: तव वर्तमानभूमिकाया उपरि न भवेत् + user_role: + attributes: + permissions_as_keys: + dangerous: आधारभूमिकायै सुरक्षिता न सन्ति इति अनुमतिस्समावेशय + elevated: तव वर्तमानभूमिकायां नास्तीति अनुमतिस्समाविष्टुं न शक्नोति + own_role: तव वर्तमानभूमिकया परिवर्तुं न शक्यते + position: + elevated: तव वर्तमानभूमिकाया उपरि न भवेत् + own_role: तव वर्तमानभूमिकया परिवर्तुं न शक्यते + webhook: + attributes: + events: + invalid_permissions: यस्या घटनाया अधिकारा न सन्ति ताः परिग्रहितुं न शक्यन्ते। diff --git a/config/locales/activerecord.sl.yml b/config/locales/activerecord.sl.yml index be6cea8718..941b847090 100644 --- a/config/locales/activerecord.sl.yml +++ b/config/locales/activerecord.sl.yml @@ -53,3 +53,7 @@ sl: position: elevated: ne more biti višje od vaše trenutne vloge own_role: ni mogoče spremeniti z vašo trenutno vlogo + webhook: + attributes: + events: + invalid_permissions: Dogodkov, do katerih nimate pravic, ni možno vključiti diff --git a/config/locales/activerecord.sq.yml b/config/locales/activerecord.sq.yml index f2ceee70d3..9c548bda04 100644 --- a/config/locales/activerecord.sq.yml +++ b/config/locales/activerecord.sq.yml @@ -53,3 +53,7 @@ sq: position: elevated: s’mund të jetë më i lartë sesa roli juaj i tanishëm own_role: s’mund të ndryshohet me rolin tuaj të tanishëm + webhook: + attributes: + events: + invalid_permissions: s’mund të përfshihen veprimtari mbi të cilat s’keni të drejta diff --git a/config/locales/activerecord.sr-Latn.yml b/config/locales/activerecord.sr-Latn.yml index c6b5e7761e..7f27fc585f 100644 --- a/config/locales/activerecord.sr-Latn.yml +++ b/config/locales/activerecord.sr-Latn.yml @@ -53,3 +53,7 @@ sr-Latn: position: elevated: ne može biti više sa vašom trenutnom ulogom own_role: ne može da se promeni sa vašom trenutnom ulogom + webhook: + attributes: + events: + invalid_permissions: ne mogu se uključiti događaji na koje nemate prava diff --git a/config/locales/activerecord.sr.yml b/config/locales/activerecord.sr.yml index e3fcdd691f..27ee48c9c9 100644 --- a/config/locales/activerecord.sr.yml +++ b/config/locales/activerecord.sr.yml @@ -24,11 +24,11 @@ sr: admin/webhook: attributes: url: - invalid: није важећа УРЛ адреса + invalid: није важећа URL адреса doorkeeper/application: attributes: website: - invalid: није важећа УРЛ адреса + invalid: није важећа URL адреса import: attributes: data: @@ -40,7 +40,7 @@ sr: user: attributes: email: - blocked: користи недозвољени провајдер е-поште + blocked: користи недозвољеног добављача е-поште unreachable: изгледа да не постоји role_id: elevated: не може бити више са вашом тренутном улогом @@ -53,3 +53,7 @@ sr: position: elevated: не може бити више са вашом тренутном улогом own_role: не може да се промени са вашом тренутном улогом + webhook: + attributes: + events: + invalid_permissions: не могу се укључити догађаји на које немате права diff --git a/config/locales/activerecord.sv.yml b/config/locales/activerecord.sv.yml index 5a009becc3..a3a45705ec 100644 --- a/config/locales/activerecord.sv.yml +++ b/config/locales/activerecord.sv.yml @@ -53,3 +53,7 @@ sv: position: elevated: kan inte vara högre än din nuvarande roll own_role: kan inte ändras med din nuvarande roll + webhook: + attributes: + events: + invalid_permissions: kan inte inkludera händelser som du inte har rättigheter till diff --git a/config/locales/activerecord.th.yml b/config/locales/activerecord.th.yml index 45d5565424..3b4b57a236 100644 --- a/config/locales/activerecord.th.yml +++ b/config/locales/activerecord.th.yml @@ -53,3 +53,7 @@ th: position: elevated: ไม่สามารถสูงกว่าบทบาทปัจจุบันของคุณ own_role: ไม่สามารถเปลี่ยนด้วยบทบาทปัจจุบันของคุณ + webhook: + attributes: + events: + invalid_permissions: ไม่สามารถรวมเหตุการณ์ที่คุณไม่มีสิทธิ diff --git a/config/locales/activerecord.tr.yml b/config/locales/activerecord.tr.yml index ffdc68ac87..d2b79d256c 100644 --- a/config/locales/activerecord.tr.yml +++ b/config/locales/activerecord.tr.yml @@ -53,3 +53,7 @@ tr: position: elevated: mevcut rolünüzden yüksek olamaz own_role: mevcut rolünüzle değiştirilemez + webhook: + attributes: + events: + invalid_permissions: erişim hakkınız olmayan olayları içeremez diff --git a/config/locales/activerecord.tt.yml b/config/locales/activerecord.tt.yml index 5f28508d63..e53c2341e4 100644 --- a/config/locales/activerecord.tt.yml +++ b/config/locales/activerecord.tt.yml @@ -2,11 +2,13 @@ tt: activerecord: attributes: + poll: + options: Сайлаулар user: email: Почта адресы locale: Тел - password: Парол + password: Серсүз user/account: username: Кулланучы исеме user/invite_request: - text: Сәбаб + text: Сәбәп diff --git a/config/locales/activerecord.uk.yml b/config/locales/activerecord.uk.yml index f02064283f..f16750acec 100644 --- a/config/locales/activerecord.uk.yml +++ b/config/locales/activerecord.uk.yml @@ -53,3 +53,7 @@ uk: position: elevated: не може бути вищою за поточну роль own_role: не можна змінити у вашій поточній ролі + webhook: + attributes: + events: + invalid_permissions: не можна включати події, на які ви не маєте прав diff --git a/config/locales/activerecord.vi.yml b/config/locales/activerecord.vi.yml index 9dd6b21364..1b4ad0a4d2 100644 --- a/config/locales/activerecord.vi.yml +++ b/config/locales/activerecord.vi.yml @@ -53,3 +53,7 @@ vi: position: elevated: không thể cao hơn vai trò hiện tại của bạn own_role: không thể thay đổi vai trò hiện tại của bạn + webhook: + attributes: + events: + invalid_permissions: không thể bao gồm các sự kiện mà bạn không có quyền diff --git a/config/locales/activerecord.zh-CN.yml b/config/locales/activerecord.zh-CN.yml index e36ea66622..a52e7cff6f 100644 --- a/config/locales/activerecord.zh-CN.yml +++ b/config/locales/activerecord.zh-CN.yml @@ -19,16 +19,16 @@ zh-CN: account: attributes: username: - invalid: 只能包含字母、数字和下划线 + invalid: 只能使用字母、数字和下划线 reserved: 是保留关键字 admin/webhook: attributes: url: - invalid: 非有效网址 + invalid: 网址无效 doorkeeper/application: attributes: website: - invalid: 非有效网址 + invalid: 网址无效 import: attributes: data: @@ -48,8 +48,12 @@ zh-CN: attributes: permissions_as_keys: dangerous: 包含对基本角色不安全的权限 - elevated: 不能包含您当前角色不拥有的权限 + elevated: 不能包含您当前身份未有的权限 own_role: 无法以您当前的身份更改 position: elevated: 不能高于您当前的角色 own_role: 无法以您当前的身份更改 + webhook: + attributes: + events: + invalid_permissions: 不能包含您没有权限的事件 diff --git a/config/locales/activerecord.zh-HK.yml b/config/locales/activerecord.zh-HK.yml index a4ca66386a..c67c2e6d43 100644 --- a/config/locales/activerecord.zh-HK.yml +++ b/config/locales/activerecord.zh-HK.yml @@ -53,3 +53,7 @@ zh-HK: position: elevated: 不可高於你目前的身份 own_role: 無法以你目前的身份更改 + webhook: + attributes: + events: + invalid_permissions: 無法包含你無權使用的事件 diff --git a/config/locales/activerecord.zh-TW.yml b/config/locales/activerecord.zh-TW.yml index 002ca95194..792a9dbb22 100644 --- a/config/locales/activerecord.zh-TW.yml +++ b/config/locales/activerecord.zh-TW.yml @@ -4,7 +4,7 @@ zh-TW: attributes: poll: expires_at: 截止時間 - options: 選擇 + options: 選項 user: agreement: 服務同意書 email: 電子郵件地址 @@ -41,7 +41,7 @@ zh-TW: attributes: email: blocked: 使用不被允許的電子郵件供應商 - unreachable: 似乎不存在 + unreachable: 該電子郵件地址似乎無法使用 role_id: elevated: 不能高於您目前的角色 user_role: @@ -53,3 +53,7 @@ zh-TW: position: elevated: 不能高於您目前的角色 own_role: 無法被您目前的角色更改 + webhook: + attributes: + events: + invalid_permissions: 無法包含您無存取權之事件 diff --git a/config/locales/af.yml b/config/locales/af.yml index ed86619911..1dbf99afe9 100644 --- a/config/locales/af.yml +++ b/config/locales/af.yml @@ -91,13 +91,7 @@ af: approve_appeal: Aanvaar appèl reject_appeal: Verwerp appèl errors: - '400': The request you submitted was invalid or malformed. '403': Jy het nie toestemming om hierdie bladsy te sien nie. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. exports: bookmarks: Boekmerke lists: Lyste diff --git a/config/locales/an.yml b/config/locales/an.yml index 0f2423bfbc..7922ccf585 100644 --- a/config/locales/an.yml +++ b/config/locales/an.yml @@ -124,8 +124,6 @@ an: removed_header_msg: S'ha eliminau con exito la imachen de capitero de %{username} resend_confirmation: already_confirmed: Este usuario ya ye confirmau - send: Reninviar lo correu electronico de confirmación - success: Correu electronico de confirmación ninviau con exito! reset: Reiniciar reset_password: Reiniciar clau resubscribe: Re-suscribir @@ -730,7 +728,6 @@ an: approved: Se requiere aprebación pa rechistrar-se none: Dengún puede rechistrar-se open: Qualsequiera puede rechistrar-se - title: Achustes d'o Servidor site_uploads: delete: Eliminar fichero puyau destroyed_msg: Carga d'o puesto eliminada con exito! @@ -925,7 +922,6 @@ an: guide_link: https://crowdin.com/project/mastodon guide_link_text: Totz pueden contribuyir. sensitive_content: Conteniu sensible - toot_layout: Disenyo d'as publicacions application_mailer: notification_preferences: Cambiar preferencias de correu electronico salutation: "%{name}:" @@ -942,14 +938,12 @@ an: your_token: Lo tuyo token d'acceso auth: apply_for_account: Solicitar una cuenta - change_password: Clau delete_account: Borrar cuenta delete_account_html: Si deseya eliminar la suya cuenta, puede proceder aquí. Será pediu d'una confirmación. description: prefix_invited_by_user: "@%{name} te convida a unir-te a este servidor de Mastodon!" prefix_sign_up: Une-te a Mastodon hue! suffix: Con una cuenta podrás seguir a chent, publicar novedatz y intercambiar mensaches con usuarios de qualsequier servidor de Mastodon y mas! - didnt_get_confirmation: No recibió lo correu de confirmación? dont_have_your_security_key: No tiens la tuya clau de seguranza? forgot_password: Ixuplidés la tuya clau? invalid_reset_password_token: Lo token de reinicio de clau ye invalido u expiró. Per favor pide un nuevo. @@ -967,17 +961,12 @@ an: saml: SAML register: Rechistrar-se registration_closed: "%{instance} no ye acceptando nuevos miembros" - resend_confirmation: Tornar a ninviar lo correu de confirmación reset_password: Restablir clau rules: preamble: Estas son establidas y aplicadas per los moderadors de %{domain}. title: Qualques reglas basicas. security: Cambiar clau set_new_password: Establir nueva clau - setup: - email_below_hint_html: Si l'adreza de correu electronico que amaneixe contino ye incorrecta, se puede cambiar-la aquí y recibir un nuevo correu electronico de confirmación. - email_settings_hint_html: Lo correu electronico de confirmación estió ninviau a %{email}. Si ixa adreza de correu electronico no sía correcta, se puede cambiar-la en a configuración d'a cuenta. - title: Configuración sign_in: preamble_html: Inicia sesión con as tuys credencials %{domain}. Si la tuya cuenta se troba en un servidor diferent, no podrás iniciar aquí una sesión. title: Iniciar sesión en %{domain} @@ -993,18 +982,6 @@ an: view_strikes: Veyer amonestacions pasadas contra la tuya cuenta too_fast: Formulario ninviau masiau rapido, lo intente de nuevo. use_security_key: Usar la clau de seguranza - authorize_follow: - already_following: Ya yes seguindo a esta cuenta - already_requested: Ya has ninviau una solicitut de seguimiento a ixa cuenta - error: Desafortunadament, ha ocurriu una error buscando la cuenta remota - follow: Seguir - follow_request: 'Tiens una solicitut de seguimiento de:' - following: 'Exito! Agora yes seguindo a:' - post_follow: - close: U, puetz simplament zarrar esta finestra. - return: Tornar ta lo perfil de l'usuario - web: Ir ta lo puesto web - title: Seguir a %{acct} challenge: confirm: Continar hint_html: "Tip: No tornaremos a preguntar-te per la clau entre la siguient hora." @@ -1116,8 +1093,6 @@ an: storage: Almagazenamiento featured_tags: add_new: Anyadir nuevo - errors: - limit: Ya has aconseguiu la cantidat maxima de hashtags hint_html: "Qué son las etiquetas destacadas? S'amuestran de forma prominent en o tuyo perfil publico y permiten a los usuarios navegar per las tuyas publicacions publicas especificament baixo ixas etiquetas. Son una gran ferramienta pa fer un seguimiento de treballos creativos u prochectos a largo plazo." filters: contexts: @@ -1161,8 +1136,6 @@ an: index: hint: Este filtro s'aplica a la selección de publicacions individuals independientment d'atros criterios. Puede anyadir mas publicacions a este filtro dende la interficie web. title: Publicacions filtradas - footer: - trending_now: Tendencia agora generic: all: Totz all_items_on_page_selected_html: @@ -1185,8 +1158,6 @@ an: validation_errors: one: Bella cosa no ye bien! Per favor, revisa la error other: Bella cosa no ye bien! Per favor, revise %{count} errors mas abaixo - html_validator: - invalid_markup: 'contiene codigo HTML no valido: %{error}' imports: errors: invalid_csv_file: 'Fichero CSV no valido. Error: %{error}' @@ -1227,9 +1198,6 @@ an: expires_at: Expira uses: Usos title: Convidar a chent - lists: - errors: - limit: Has aconseguiu la cantidat maxima de listas login_activities: authentication_methods: otp: aplicación d'autenticación en dos pasos @@ -1436,7 +1404,6 @@ an: ios: iOS linux: Linux mac: Mac - other: plataforma desconoixida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1507,7 +1474,6 @@ an: show_newer: Amostrar mas recients show_older: Amostrar mas antigos show_thread: Amostrar discusión - sign_in_to_participate: Rechistra-te pa participar en a conversación title: "%{name}: «%{quote}»" visibilities: direct: Directa @@ -1549,12 +1515,9 @@ an: '7889238': 3 meses min_age_label: Branquil de tiempo min_favs: Mantener mensaches con un numero de favoritos mayor que - min_favs_hint: No borra garra d'as publicacions que haigan recibiu mas d'esta cantidat de favoritos. Deixa en blanco pa eliminar publicacions sin importar lo numero de favoritos min_reblogs: Mantener publicacions reblogueadas mas de min_reblogs_hint: No borra garra d'as publicacions que haigan estau reblogueadas mas d'este numero de vegadas. Deixa en blanco pa eliminar publicacions sin importar lo numero de reblogueos stream_entries: - pinned: Publicación fixada - reblogged: retutau sensitive_content: Conteniu sensible strikes: errors: @@ -1654,7 +1617,6 @@ an: seamless_external_login: Has iniciau sesión dende un servicio externo, asinas que los achustes de clau y correu no son disponibles. signed_in_as: 'Sesión iniciada como:' verification: - explanation_html: 'Puetz verificar-te a tu mesmo como lo duenyo d''os links en os metadatos d''o tuyo perfil . Pa ixo, lo puesto vinculau ha de contener un vinclo a lo tuyo perfil de Mastodon. Lo vinclo en o tuyo puesto debe tener un atributo rel="me". Lo texto d''o vinclo no importa. Aquí un eixemplo:' verification: Verificación webauthn_credentials: add: Adhibir nueva clau de seguranza diff --git a/config/locales/ar.yml b/config/locales/ar.yml index ad2797592f..f8c74207de 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -1,24 +1,24 @@ --- ar: about: - about_mastodon_html: 'شبكة التواصل الإجتماعية المستقبَليّة: مِن دون إعلانات ، غير خاضعة لرقابة الشركات ، تصميم أخلاقي ولامركزية! بياناتكم مِلك لكم مع ماستدون!' + about_mastodon_html: 'شبكة التواصل الاجتماعية المستقبَليّة: مِن دون إعلانات، وغير خاضعة لرقابة الشركات، ذات تصميم أخلاقي ولامركزية! بياناتكم مِلك لكم مع ماستدون!' contact_missing: لم يتم تعيينه contact_unavailable: غير متوفر hosted_on: ماستدون مُستضاف على %{domain} title: عن accounts: - follow: اتبع + follow: متابَعة followers: few: متابِعون many: متابِعون - one: متابِع + one: متابِع واحد other: متابِعون - two: متابِعون - zero: متابِعون + two: متابِعان + zero: لا متابِع following: مُتابَع instance_actor_flash: هذا الحساب هو ممثل افتراضي يُستخدم لتمثيل الخادم نفسه ولا يمثل أي مستخدم فردي، يُستخدم لأغراض الاتحاد ولا ينبغي حظره. last_active: آخر نشاط - link_verified_on: تم التحقق مِن مالك هذا الرابط بتاريخ %{date} + link_verified_on: تم التحقق مِن ملكية هذا الرابط بتاريخ %{date} nothing_here: لا يوجد أي شيء هنا! pin_errors: following: يجب أن تكون مِن متابعي حساب الشخص الذي تريد إبرازه @@ -28,7 +28,7 @@ ar: one: منشور واحد other: منشور two: منشورَيْن - zero: منشور + zero: لا منشورات posts_tab_heading: المنشورات admin: account_actions: @@ -39,7 +39,7 @@ ar: created_msg: تم إنشاء ملاحظة الإشراف بنجاح! destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح! accounts: - add_email_domain_block: حظر نطاق بريد إلكتروني + add_email_domain_block: حظر نطاق البريد الإلكتروني هذا approve: صادِق عليه approved_msg: تمت الموافقة على تسجيل %{username} are_you_sure: متأكد ؟ @@ -79,13 +79,13 @@ ar: enabled: مفعَّل enabled_msg: تم إلغاء تجميد حساب %{username} followers: المتابِعون - follows: يتابع + follows: المُتابَعون header: الرأسية inbox_url: رابط صندوق الوارد - invite_request_text: أسباب للانضمام + invite_request_text: غرض الانضمام invited_by: تمت دعوته مِن طرف ip: عنوان الإيبي - joined: انضم + joined: انضم في location: all: الكل local: المحلي @@ -99,6 +99,7 @@ ar: moderation: active: نشِط all: الكل + disabled: مُعطَّل pending: قيد المراجعة silenced: محدود suspended: مُجَمَّد @@ -113,6 +114,13 @@ ar: pending: في انتظار المراجعة perform_full_suspension: تعليق الحساب previous_strikes: العقوبات السابقة + previous_strikes_description_html: + few: لدى هذا الحساب %{count} إنذارات. + many: لدى هذا الحساب %{count} إنذارًا. + one: هذا الحساب لديه %{count}انذار. + other: لدى هذا الحساب %{count} إنذار. + two: لدى هذا الحساب %{count} إنذاران اثنان. + zero: هذا الحساب لديه %{count}انذار. promote: ترقية protocol: البروتوكول public: عمومي @@ -129,8 +137,8 @@ ar: removed_header_msg: تمت إزالة صورة %{username} الرأسية بنجاح resend_confirmation: already_confirmed: هذا المستخدم مؤكد بالفعل - send: أعد إرسال رسالة البريد الإلكتروني الخاصة بالتأكيد - success: تم إرسال رسالة التأكيد بنجاح! + send: إعادة إرسال الرابط الخاص بالتأكيد + success: تم إرسال رابط التأكيد بنجاح! reset: إعادة التعيين reset_password: إعادة ضبط كلمة السر resubscribe: إعادة الاشتراك @@ -138,10 +146,11 @@ ar: search: البحث search_same_email_domain: مستخدمون آخرون لديهم نفس نطاق البريد الإلكتروني search_same_ip: مستخدِمون آخرون بنفس الـ IP + security: الأمان security_measures: only_password: كلمة المرور فقط password_and_2fa: كلمة المرور و 2FA - sensitive: حساس + sensitive: فرضه كحساس sensitized: مُعَين كمنشور حساس shared_inbox_url: رابط الصندوق المُشترَك للبريد الوارد show: @@ -149,7 +158,7 @@ ar: targeted_reports: الشكاوى التي أُنشِأت مِن طرف الآخَرين silence: كتم silenced: تم كتمه - statuses: المنشورات + statuses: منشورات strikes: العقوبات السابقة subscribe: اشترك suspend: علّق الحساب @@ -160,7 +169,7 @@ ar: unblock_email: إلغاء حظر عنوان البريد الإلكتروني unblocked_email_msg: تم إلغاء حظر عنوان البريد الإلكتروني لـ %{username} بنجاح unconfirmed_email: البريد الإلكتروني غير مؤكد - undo_sensitized: التراجع عن حساسية + undo_sensitized: التراجع عن فرضه كحساس undo_silenced: رفع الصمت undo_suspension: إلغاء تعليق الحساب unsilenced_msg: تم فك الحدود من حساب %{username} بنجاح @@ -181,14 +190,14 @@ ar: confirm_user: تأكيد المستخدم create_account_warning: إنشاء تحذير create_announcement: إنشاء إعلان - create_canonical_email_block: إنشاء نطاق للبريد + create_canonical_email_block: إنشاء حظر للبريد create_custom_emoji: إنشاء إيموجي مخصص create_domain_allow: إنشاء نطاق المسموح به - create_domain_block: إنشاء كتلة نطاق + create_domain_block: إنشاء حظر لنطاق create_email_domain_block: إنشاء كتلة نطاق بريد إلكتروني create_ip_block: إنشاء قاعدة IP جديدة create_unavailable_domain: إنشاء نطاق غير متوفر - create_user_role: انشاء رتبه + create_user_role: انشاء دور demote_user: إنزال رتبة المستخدم destroy_announcement: احذف الإعلان destroy_canonical_email_block: حذف نطاق للبريد @@ -229,7 +238,7 @@ ar: update_custom_emoji: تحديث الإيموجي المخصص update_domain_block: تحديث كتلة النطاق update_ip_block: تحديث قاعدة IP - update_status: تحديث الحالة + update_status: تحديث المنشور update_user_role: تحديث الدور actions: approve_appeal_html: وافق %{name} على استئناف قرار الاعتدال من %{target} @@ -312,6 +321,7 @@ ar: unpublish: إلغاء النشر unpublished_msg: تم إلغاء نشر الإعلان بنجاح! updated_msg: تم تحديث الإعلان بنجاح! + critical_update_pending: تحديث حَرِج قيد الانتظار custom_emojis: assign_category: اسند فئة by_domain: النطاق @@ -359,6 +369,27 @@ ar: other: "%{count} تقارير معلقة" two: "%{count} مستخدمين معلقين" zero: "%{count} وسماً معلقاً" + pending_reports_html: + few: "%{count} تقارير قيد الإنتظار" + many: "%{count} تقريرًا قيد الإنتظار" + one: "%{count} تقرير واحد قيد الإنتظار" + other: "%{count} تقرير قيد الانتظار" + two: "%{count} تقريران قيد الانتظار" + zero: "%{count} تقارير قيد الانتظار" + pending_tags_html: + few: "%{count} وسمٍ قيد الانتظار" + many: "%{count} وسماً قيد الانتظار" + one: "وسمٌ واحدٌ قيد الانتظار" + other: "%{count} وسماً قيد الانتظار" + two: "وسمان قيد الانتظار" + zero: "%{count} وسمٍ قيد الانتظار" + pending_users_html: + few: "%{count} مستخدمين قيدَ الانتظار" + many: "%{count} مستخدماً قيدَ الانتظار" + one: "%{count} مستخدم قيدَ الانتظار" + other: "%{count} مستخدماً قيدَ الانتظار" + two: "%{count} مستخدمان قيدَ الانتظار" + zero: "%{count} مستخدمٍ قيدَ الانتظار" resolved_reports: تقارير تم حلها software: البرنامج sources: مصادر التسجيل @@ -380,6 +411,15 @@ ar: undo: إزالة من القائمة البيضاء domain_blocks: add_new: إضافة حجب جديد لنطاق + confirm_suspension: + cancel: إلغاء + confirm: علّق النطاق + permanent_action: لن يستعيد رفع الحظر أي بيانات أو علاقات. + preamble_html: أنت على وشك تعليق %{domain} وجميع نطاقاته الفرعيّة. + remove_all_data: ستُحذف كل المحتوى والوسائط وبيانات حسابات هذا النطاق من خادومك. + stop_communication: سيتوقّف خادومك عن التواصل مع كل هذه الخادومات. + title: تأكيد حظر نطاق %{domain} + undo_relationships: سيتم التراجع عن أي علاقات متابعة ما بين الحسابات على هذه الخوادم وخادمك. created_msg: إنّ حجب النطاق حيز التشغيل destroyed_msg: تم إلغاء الحجب المفروض على النطاق domain: النطاق @@ -413,6 +453,13 @@ ar: view: عرض كتلة النطاق email_domain_blocks: add_new: إضافة + attempts_over_week: + few: "%{count} محاولات تسجيل في آخر أسبوع" + many: "%{count} محاولات تسجيل في آخر أسبوع" + one: "%{count} محاولة تسجيل في آخر أسبوع" + other: "%{count} محاولات تسجيل في آخر أسبوع" + two: "%{count} محاولتا تسجيل في آخر أسبوع" + zero: "%{count} محاولة تسجيل في آخر أسبوع" created_msg: لقد دخل حظر نطاق البريد الإلكتروني حيّز الخدمة delete: حذف dns: @@ -424,6 +471,7 @@ ar: resolve: العثور على عنوان النطاق title: إضافة نطاق بريد جديد إلى اللائحة السوداء no_email_domain_block_selected: لم يطرأ أي تغيير على أي نطاق بريد بما أنه لم يتم اختيار أي نطاق + not_permitted: غير مسموح به resolved_dns_records_hint_html: عنوان النطاق يعود لخوادم البريد (MX) التالية وهو ما يسمح للنطاق باستقبال البريد. حظر خوادم البريد هذه سوف يتسبب في منع أي تسجيل خلال أي نطاق يستخدم هذه الخوادم حتى لو كان اسم النطاق مختلف عن اسماء خوادم البريد.احذر من حظر مزودي البريد العالميين. resolved_through_html: الحصول على العنوان من خلال %{domain} title: القائمة السوداء للبريد الإلكتروني @@ -452,6 +500,13 @@ ar: unsuppress: إستعادة إقتراحات المتابعة instances: availability: + description_html: + few: إذا فشل التسليم إلى النطاق لمدة %{count} أيام دون نجاح، لن تتم أي محاولات أخرى للتسليم إلا إذا تم الاستلام النطاق من. + many: إذا فشل التسليم إلى النطاق لمدة %{count} يوماً دون نجاح، لن تتم أي محاولات أخرى للتسليم إلا إذا تم الاستلام النطاق من. + one: إذا فشل التسليم إلى النطاق لمدة %{count} يومٍ دون نجاح، لن تتم أي محاولات أخرى للتسليم إلا إذا تم الاستلام النطاق من. + other: إذا فشل التسليم إلى النطاق لمدة %{count} يوماً دون نجاح، لن تتم أي محاولات أخرى للتسليم إلا إذا تم الاستلام النطاق من. + two: إذا فشل التسليم إلى النطاق لمدة %{count} يومين دون نجاح، لن تتم أي محاولات أخرى للتسليم إلا إذا تم الاستلام النطاق من. + zero: إذا فشل التسليم إلى النطاق لمدة %{count} يومٍ دون نجاح، لن تتم أي محاولات أخرى للتسليم إلا إذا تم الاستلام النطاق من. failure_threshold_reached: تم الوصول إلى أقصى حد للفشل بتاريخ %{date}. failures_recorded: few: المحاولات الفاشلة في %{count} يومًا. @@ -471,6 +526,7 @@ ar: content_policies: comment: ملاحظة داخلية description_html: يمكنك تحديد سياسات المحتوى التي سيتم تطبيقها على جميع حسابات هذا النطاق وأي من نطاقاته الفرعية. + limited_federation_mode_description_html: يمكنك أن تختار بين السماح أو عدم السماح بالفديرالية مع هذا النطاق. policies: reject_media: رفض الوسائط reject_reports: رفض الشكاوى @@ -481,7 +537,7 @@ ar: title: سياسات المحتوى dashboard: instance_accounts_dimension: الحسابات الأكثر متابعة - instance_accounts_measure: حسابات مخزنة + instance_accounts_measure: حسابات مُخزَّنَة instance_followers_measure: متابعينا هناك instance_follows_measure: متابِعوهم هنا instance_languages_dimension: اللغات الأكثر استخدامًا @@ -582,17 +638,22 @@ ar: mark_as_sensitive_description_html: سيتم تحديد الوسائط في المناشير المبلّغ عنها على أنها محتوى حساس وسيتم تسجيل إنذار لمساعدتك في التعامل المستقبلي مع أي مخالفة جديدة من نفس الحساب. other_description_html: عرض المزيد من الخيارات للتحكم في االحسابات وتخصيص التواصل مع الحسابات المُبلّغ عنها. resolve_description_html: ولن يُتخذ أي إجراء ضد الحساب المبلّغ عنه، ولن تسلَّط عليه أية عقوبة، وسوف يُغلق التقرير. + silence_description_html: الحساب سيظهر فقط لمن يتابعه أو قام بالبحث عنه بشكل مباشر مما يخفض إمكانية رؤيته بشكل شبه كامل. يمكنك دائما التراجع عن هذا الإجراء. تُغلَق كافة الإبلاغات عن هذا الحساب. + suspend_description_html: سيُمنع الوصول إلى الحساب وجميع محتوياته وتُحذف تدريجياً، وسيكون التفاعل معه مستحيلاً. بالإمكان عكس مفعول ذلك في غضون 30 يوماً. يغلق جميع التبليغات ضد الحساب. actions_description_html: تحديد الإجراءات التي يتعين اتخاذها لحل هذا التبليغ. إذا اتخذت إجراء عقابيا ضد الحساب المبلغ عنه، فسيتم إرسال إشعار بالبريد الإلكتروني إليهم، إلا عندما يتم تحديد فئة البريد المزعج. + actions_description_remote_html: حدّد الإجراءات التي يتعين اتخاذها لحل هذا التقرير. هذا سيؤثر فقط على كيفية اتصال خادمك بهذا الحساب البعيد والتعامل مع محتوياته. add_to_report: أضف المزيد إلى التقرير are_you_sure: هل أنت متأكد ؟ assign_to_self: عين لي assigned: تعين رئيس by_target_domain: نطاق الحساب المبلّغ عنه + cancel: إلغاء category: الفئة category_description_html: سيشار إلى سبب الإبلاغ عن هذا الحساب و/أو المحتوى في الاتصال بالحساب المبلغ عنه comment: none: لا شيء comment_description_html: 'لتوفير المزيد من المعلومات، كتب %{name}:' + confirm: تأكيد confirm_action: تأكيد اتخاذ إجراء إشراف على @%{acct} created_at: ذكرت delete_and_resolve: احذف المنشورات @@ -624,10 +685,21 @@ ar: statuses: المحتوى المبلغ عنه statuses_description_html: سيشار إلى المحتوى المخالف في الاتصال بالحساب المبلغ عنه summary: + action_preambles: + delete_html: 'أنت على وشك إزالة بعض منشورات @%{acct}. هذا سوف:' + mark_as_sensitive_html: 'أنت على وشك وسم بعض منشورات @%{acct} على أنها حساسة. هذا سوف:' + silence_html: 'أنت على وشك الحد من الوصول لحساب @%{acct} وهذا سوف:' + suspend_html: 'أنت على وشك تعليق حساب @%{acct}. هذا سوف:' actions: delete_html: إزالة المنشورات المُخالِفة mark_as_sensitive_html: تصنيف وسائط المنشورات المُخالفة كحساسة + silence_html: الحد بشدة من الوصول إلى @%{acct} بجعل ملفهم الشخصي ومحتوياته مرئية فقط لمتابعيهم أو لمن يبحث عنهم يدوياً + suspend_html: تعليق حساب @%{acct}، مما يجعل من غير الممكن الوصول إلى ملفه التعريفي ومحتوياته ويستحيل التفاعل معه close_report: 'تصنيف التقرير #%{id} كإبلاغ تمت معالجته' + close_reports_html: علِّم جميع التبليغات ضد @%{acct} على أنها محلولة + delete_data_html: حذف ملف @%{acct} الشخصي بمحتواه بعد 30 يوماً من الآن ما لم يُلغَ تعليق الحساب + preview_preamble_html: 'سوف يتلقى @%{acct} تحذيرا يحتوي على ما يلي:' + record_strike_html: تسجيل عقوبة ضد @%{acct} لمساعدتك في أخذ إجراءات إضافية في حال انتهاكات مستقبلية من طرف هذا الحساب send_email_html: إرسال بريد إلكتروني تحذيري إلى @%{acct} warning_placeholder: مبررات إضافية اختيارية لإجراء الإشراف. target_origin: مصدر الحساب المبلغ عنه @@ -657,6 +729,13 @@ ar: edit: تعديل رتبة '%{name}' ' everyone: الصلاحيات الافتراضية everyone_full_description_html: هذا هو الدور الأساسي الذي يحمله جميع المستخدمين، حتى أولئك الذين ليس لديهم دور معين. جميع الأدوار الأخرى ترث الأذونات منه. + permissions_count: + few: "%{count} تصريحات" + many: "%{count} تصريحًا" + one: تصريح واحد %{count} + other: "%{count} تصريح" + two: تصريحان %{count} + zero: لا تصريح %{count} privileges: administrator: مدير administrator_description: المستخدمين الذين لديهم هذا التصريح سيتجاوزون جميع التصاريح @@ -716,8 +795,11 @@ ar: preamble: تخصيص واجهة الويب لماستدون. title: المظهر branding: - preamble: العلامة التجارية للخادم الخاص بك تميزه عن الخوادم الأخرى في الشبكة. يمكن عرض هذه المعلومات عبر مجموعة متنوعة من البيئات، مثل واجهة الويب لماستدون, التطبيقات الأصلية، في معاينات الرابط على مواقع الويب الأخرى وداخل تطبيقات الرسائل، وما إلى ذلك. ولهذا السبب، من الأفضل إبقاء هذه المعلومات واضحة وقصيرة وموجزة. + preamble: العلامة التجارية لخادمك الخاص تميزه عن الخوادم الأخرى في الشبكة. يمكن عرض هذه المعلومات عبر مجموعة متنوعة من البيئات، مثل واجهة الويب لماستدون، في التطبيقات الأصلية، في معاينات الروابط على مواقع الويب الأخرى وضمن تطبيقات الرسائل، وما إلى ذلك. ولهذا السبب، من الأفضل إبقاء هذه المعلومات واضحة وقصيرة وموجزة. title: العلامة + captcha_enabled: + desc_html: ويعتمد هذا على نصوص برمجية خارجية من hCaptcha، والتي قد تكون مصدر قلق يتعلق بالأمان والخصوصية. بالإضافة إلى ذلك، قد يؤدي ذلك إلى جعل عملية التسجيل أقل سهولة بالنسبة لبعض الأشخاص (وخاصة المعاقين). لهذه الأسباب، يرجى النظر في تدابير بديلة مثل التسجيل على أساس الموافقة أو على أساس الدعوة. + title: مطالبة المستخدمين الجدد بحل اختبار CAPTCHA لتأكيد حساباتهم content_retention: preamble: التحكم في كيفية تخزين المحتوى الذي ينشئه المستخدم في ماستدون. title: الاحتفاظ بالمحتوى @@ -726,7 +808,7 @@ ar: title: عدم السماح مبدئيا لمحركات البحث بفهرسة الملفات التعريفية للمستخدمين discovery: follow_recommendations: اتبع التوصيات - preamble: تصفح المحتوى المثير للاهتمام أمر مهم في إستقبال المستخدمين الجدد الذين قد لا يعرفون أي شخص ماستدون. التحكم في كيفية عمل ميزات الاكتشاف المختلفة على الخادم الخاص بك. + preamble: يُعد إتاحة رؤية المحتوى المثير للاهتمام أمرًا ضروريًا لجذب مستخدمين جدد قد لا يعرفون أي شخص في Mastodon. تحكم في كيفية عمل ميزات الاكتشاف المختلفة على خادمك الخاص. profile_directory: دليل الصفحات التعريفية public_timelines: الخيوط الزمنية العامة publish_discovered_servers: نشر الخوادم المكتشَفة @@ -745,10 +827,27 @@ ar: approved: طلب الموافقة لازم عند إنشاء حساب none: لا أحد يمكنه إنشاء حساب open: يمكن للجميع إنشاء حساب + security: + authorized_fetch: يتطلّب المصادقة مِن الخوادم الفديرالية + authorized_fetch_hint: إن طلب المصادقة من الخوادم الموحدة يتيح تنفيذًا أكثر صرامة للكتل على مستوى المستخدم وعلى مستوى الخادم. ومع ذلك، يأتي هذا على حساب عقوبة الأداء، ويقلل من مدى وصول ردودك، وقد يؤدي إلى حدوث مشكلات في التوافق مع بعض الخدمات الموحدة. بالإضافة إلى ذلك، لن يمنع هذا الجهات الفاعلة المخصصة من جلب منشوراتك وحساباتك العامة. + authorized_fetch_overridden_hint: لا يُمكِنُكَ تغيير هذا الإعداد لأنه مفروض عبر مُتغيّر في البيئة. + federation_authentication: إنفاذ التوثيق الفديرالي title: إعدادات الخادم site_uploads: delete: احذف الملف الذي تم تحميله destroyed_msg: تم حذف التحميل مِن الموقع بنجاح! + software_updates: + critical_update: حَرِج - يرجى التحديث في أقرب وقت ممكن + description: من المستحسَن إبقاء تثبيت ماستدون الخاص بك محدثا للاستفادة من أحدث التصحيحات والميزات. إضافةً إلى ذلك، فهو مهمّ جدا تحديث ماستدون أحيانًا في الوقت المناسب لتجنب المسائل الأمنية. لهذه الأسباب، يقوم ماستدون بالتحقق من التحديثات كل 30 دقيقة، وسيتم إعلامك وفقا لتفضيلات إشعارات البريد الإلكتروني الخاصة بك. + documentation_link: معرفة المزيد + release_notes: ملخصات الإصدار + title: التحديثات المتوفرة + type: النوع + types: + major: إصدار رئيسي + minor: اصدار بسيط + patch: إصدار تصحيحي - تصحيح للعِلَل وسهل إجراء تطبيق التغييرات + version: الإصدار statuses: account: المؤلف application: التطبيق @@ -785,9 +884,24 @@ ar: suspend: قام %{name} بتعليق حساب %{target} appeal_approved: طُعِن فيه appeal_pending: طعن قيد المراجعة + appeal_rejected: رُفض الطعن system_checks: database_schema_check: message_html: هناك عمليات هجرة معلقة لقواعد البيانات. يرجى تشغيلها لضمان تصرف التطبيق كما هو متوقع + elasticsearch_health_red: + message_html: مجموعة Elasticsearch غير صحية (الحالة الحمراء)، ميزات البحث غير متوفرة + elasticsearch_health_yellow: + message_html: مجموعة Elasticsearch غير صحية (الحالة الصفراء)، قد ترغب في التحقق من السبب + elasticsearch_index_mismatch: + message_html: تعيينات فِهْرِس Elasticsearch قديمة. الرجاء تشغيل tootctl search deploy --only=%{value} + elasticsearch_preset: + action: اطّلع على الدليل + message_html: تحتوي مجموعة Elasticsearch الخاصة بك على أكثر من عقدة واحدة، ولكن Mastodon لم يُعَدّ لاستخدامها. + elasticsearch_preset_single_node: + action: اطّلع على الدليل + message_html: تحتوي مجموعة Elasticsearch الخاصة بك على عقدة واحدة فقط، ويجب تعيين ES_PRESET على single_node_cluster. + elasticsearch_reset_chewy: + message_html: فِهْرِس نظام Elasticsearch الخاص بك قديم بسبب تغيير الإعداد. يرجى تشغيل tootctl search deploy --reset-chewy لتحديثه. elasticsearch_running_check: message_html: تعذر الاتصال بـElasticsearch. الرجاء التحقق من أنه قيد التشغيل، أو تعطيل البحث عن النص الكامل elasticsearch_version_check: @@ -798,6 +912,18 @@ ar: message_html: لم تقم بتحديد أي قواعد خادم. sidekiq_process_check: message_html: لا توجد عملية Sidekiq قيد التشغيل لقائمة الانتظار %{value}. يرجى مراجعة إعدادات Sidekiq الخاصة بك + software_version_critical_check: + action: الاطلاع على التحديثات المتوفرة + message_html: هناك تحديث هام لماستدون، يرجى التحديث في أسرع وقت ممكن. + software_version_patch_check: + action: الاطلاع على التحديثات المتوفرة + message_html: هناك تحديث ماستدون متوفر لتصحيح الأخطاء. + upload_check_privacy_error: + action: تحقق هنا للمزيد من المعلومات + message_html: إعدادات خادم الويب الخاص بكم ليست على ما يرام. خصوصية مستخدميكم في خطر. + upload_check_privacy_error_object_storage: + action: تحقق هنا للمزيد من المعلومات + message_html: "تم تكوين مخزن الكائنات الخاص بك بشكل خاطئ. خصوصية المستخدمين في خطر." tags: review: حالة المراجعة updated_msg: تم تحديث إعدادات الوسوم بنجاح @@ -815,8 +941,16 @@ ar: no_link_selected: لم يطرأ أي تغيير على أي رابط بما أنه لم يتم اختيار أي واحد publishers: no_publisher_selected: لم يطرأ أي تغيير على أي ناشر بما أنه لم يتم اختيار أي واحد + shared_by_over_week: + few: "%{count} أشخاص أعادوا نشره خلال الأسبوع الماضي" + many: "%{count} شخصًا أعادوا نشره خلال الأسبوع الماضي" + one: شخص واحد أعاد نشره خلال الأسبوع الماضي + other: "%{count} شخص أعادوا نشره خلال الأسبوع الماضي" + two: شخصان أعادا نشره خلال الأسبوع الماضي + zero: لا أحد أعاد نشره خلال الأسبوع الماضي title: الروابط المتداولة usage_comparison: تمت مشاركته %{today} مرات اليوم، مقارنة بـ %{yesterday} بالأمس + not_allowed_to_trend: غير مسموح ظهوره في المتداولة only_allowed: من سُمِحَ لهم فقط pending_review: في انتظار المراجعة preview_card_providers: @@ -833,12 +967,19 @@ ar: disallow_account: رفض الناشر no_status_selected: لم يتم تغيير أي منشورات متداوله حيث لم يتم اختيار أي منهم not_discoverable: الكاتب لم يختار أن يكون قابلا للاكتشاف + shared_by: + few: تمت مشاركته وتفضيله %{friendly_count} مرات + many: تمت مشاركته وتفضيله %{friendly_count} مرات + one: تمت مشاركته وتفضيله مرة واحدة + other: تمت مشاركته وتفضيله %{friendly_count} مرات + two: تمت مشاركته وتفضيله مرتين + zero: لم يتم مشاركته أو تفضيله مطلقًا title: المنشورات المتداولة tags: current_score: التقييم الحالي %{score} dashboard: tag_accounts_measure: استخدامات فريدة - tag_languages_dimension: أفضل اللغات + tag_languages_dimension: اللغات الأساسية tag_servers_dimension: الخوادم الأكثر نشاطا tag_servers_measure: خوادم أخرى tag_uses_measure: إجمالي الاستخدامات @@ -854,6 +995,13 @@ ar: trending_rank: 'المتداولة #%{rank}' usable: يمكن استخدامه usage_comparison: تم استخدامه %{today} مرات اليوم، مقارنة بـ %{yesterday} بالأمس + used_by_over_week: + few: مستخدَم من قِبل %{count} أشخاص خلال الأسبوع الماضي + many: مستخدَم من قِبل %{count} شخصا خلال الأسبوع الماضي + one: مستخدَم من قِبل %{count} شخص واحد خلال الأسبوع الماضي + other: مستخدَم من قِبل %{count} شخص خلال الأسبوع الماضي + two: مستخدَم من قِبل %{count} شخصين خلال الأسبوع الماضي + zero: مستخدَم من قِبل %{count} شخص خلال الأسبوع الماضي title: المتداوَلة trending: المتداولة warning_presets: @@ -872,6 +1020,13 @@ ar: empty: ليس لديك أي نقاط نهاية ويب هوك تم تكوينها بعد. enable: تشغيل enabled: نشِط + enabled_events: + few: تم تفعيل %{count} أحداث + many: تم تفعيل %{count} حدثًا + one: تم تفعيل حدث واحد + other: تم تفعيل %{count} حدث + two: تم تفعيل حدثين + zero: لم يتم تفعيل أي حدث events: الأحداث new: رابط ويب جديد rotate_secret: تغيير الرمز @@ -892,6 +1047,9 @@ ar: body: 'قام %{target} بالطعن في قرار %{action_taken_by} بتاريخ %{date} وهو كان %{type}. نص الطعن:' next_steps: يمكنك الموافقة على الطعن وبالتالي التراجع عن قرار المشرف، أو يمكنك تجاهل الطعن. subject: قام %{username} بالطعن بقرار المشرفين بخصوص %{instance} + new_critical_software_updates: + body: تم إصدار إصدارات حرجة جديدة من ماستدون ، قد ترغب في التحديث في أقرب وقت ممكن! + subject: هناك إصدارات ماستدون حَرِجة جديدة متوفرة لـ %{instance}! new_pending_account: body: تفاصيل الحساب الجديد أدناه. يمكنك الموافقة على هذا الطلب أو رفضه. subject: حساب جديد في انتظار مراجعة على %{instance} (%{username}) @@ -899,6 +1057,9 @@ ar: body: قام %{reporter} بالإبلاغ عن %{target} body_remote: أبلغ شخص ما من %{domain} عن %{target} subject: تقرير جديد ل%{instance} (#%{id}) + new_software_updates: + body: لقد تم نشر إصدارات جديدة لماستدون، قد ترغب في التحديث! + subject: هناك إصدارات ماستدون جديدة متوفرة لـ %{instance}! new_trends: body: 'تحتاج العناصر التالية إلى مراجعة قبل أن يمكن عرضها علناً:' new_trending_links: @@ -906,7 +1067,7 @@ ar: new_trending_statuses: title: المنشورات الشائعة new_trending_tags: - no_approved_tags: لا توجد حاليًا هاشات شائعة موافق عليها. + no_approved_tags: لا توجد حاليًا وسوم شائعة موافق عليها. requirements: 'يمكن لأي من هؤلاء المرشحين أن يتجاوز علامة #%{rank} من الوسوم الموافق عليها، وهي حاليا #%{lowest_tag_name} مع نتيجة %{lowest_tag_score}.' title: الوسوم المتداولة subject: تداولات جديدة في انتظار المراجعة على %{instance} @@ -928,33 +1089,37 @@ ar: guide_link: https://crowdin.com/project/mastodon guide_link_text: يمكن للجميع المساهمة. sensitive_content: المحتوى الحساس - toot_layout: شكل المنشور application_mailer: notification_preferences: تعديل تفضيلات البريد الإلكتروني salutation: "%{name}،" settings: 'تغيير تفضيلات البريد الإلكتروني: %{link}' + unsubscribe: إلغاء الاشتراك view: 'اعرض:' view_profile: اعرض الصفحة التعريفية view_status: عرض المنشور applications: created: تم إنشاء التطبيق بنجاح destroyed: تم حذف التطبيق بنجاح + logout: الخروج regenerate_token: إعادة توليد رمز النفاذ token_regenerated: تم إعادة إنشاء الرمز الوصول بنجاح warning: كن حذرا مع هذه البيانات. لا تقم أبدا بمشاركتها مع الآخَرين! your_token: رمز نفاذك auth: apply_for_account: اطلُب حسابًا - change_password: الكلمة السرية + captcha_confirmation: + help_html: إن صادَفتَ مشكلات في حل CAPTCHA ، يمكنك الاتصال بنا بواسطة %{email} ويمكننا مساعدتك. + hint_html: شيء واحد آخر! نحن بحاجة إلى التأكّد من أنك إنسان (حتى نتمكن من تتفادي البريد المزعج!). حل رمز CAPTCHA أدناه وانقر فوق "متابعة". + title: التحقق من الأمان confirmations: wrong_email_hint: إذا كان عنوان البريد الإلكتروني هذا غير صحيح، يمكنك تغييره في إعدادات الحساب. - delete_account: حذف الحساب + delete_account: احذف الحساب delete_account_html: إن كنت ترغب في حذف حسابك يُمكنك المواصلة هنا. سوف يُطلَبُ منك التأكيد قبل الحذف. description: prefix_invited_by_user: يدعوك @%{name} للاتحاق بخادم ماستدون هذا! prefix_sign_up: أنشئ حسابًا على ماستدون اليوم! - suffix: بفضل حساب ، ستكون قادرا على متابعة الأشخاص ونشر تحديثات وتبادل رسائل مع مستخدمين مِن أي خادم Mastodon وأكثر! - didnt_get_confirmation: لم تتلق تعليمات التأكيد ؟ + suffix: بفضل حساب، ستكون قادرا على متابعة أشخاص ونشر تحديثات وتبادل رسائل مع مستخدمين مِن أي خادم Mastodon وأكثر! + didnt_get_confirmation: لم تستلم رابط تأكيد؟ dont_have_your_security_key: ليس لديك مفتاح الأمان الخاص بك؟ forgot_password: نسيت كلمة المرور ؟ invalid_reset_password_token: رمز إعادة تعيين كلمة المرور غير صالح أو منتهي الصلاحية. يرجى طلب واحد جديد. @@ -963,30 +1128,43 @@ ar: log_in_with: الولوج عبر login: تسجيل الدخول logout: خروج - migrate_account: الانتقال إلى حساب آخر + migrate_account: الانتقال إلى حساب مختلف migrate_account_html: إن كنت ترغب في تحويل هذا الحساب نحو حساب آخَر، يُمكِنُك إعداده هنا. or_log_in_with: أو قم بتسجيل الدخول بواسطة privacy_policy_agreement_html: لقد قرأتُ وأوافق على سياسة الخصوصية + progress: + confirm: تأكيد عنوان البريد الإلكتروني + details: تفاصيلك + review: رأيُنا + rules: قبول القواعد providers: cas: CAS saml: SAML register: إنشاء حساب registration_closed: لا يقبل %{instance} استقبال أعضاء جدد - resend_confirmation: إعادة إرسال تعليمات التأكيد + resend_confirmation: إعادة إرسال رابط التأكيد reset_password: إعادة تعيين كلمة المرور rules: + accept: قبول + back: العودة + invited_by: 'يمكنك الانضمام إلى %{domain} بفضل الدعوة التي تلقيتها من:' preamble: يتم تعيين هذه القوانين وفرضها من قبل مشرفي %{domain}. + preamble_invited: قبل المتابعة، يرجى قراءة القواعد الأساسية التي وضعها مشرفو %{domain}. title: بعض القواعد الأساسية. + title_invited: لقد تمت دعوتك. security: الأمان set_new_password: إدخال كلمة مرور جديدة setup: - email_below_hint_html: إذا كان عنوان البريد الإلكتروني التالي غير صحيح، فيمكنك تغييره هنا واستلام بريد إلكتروني جديد للتأكيد. - email_settings_hint_html: لقد تم إرسال رسالة بريد إلكترونية للتأكيد إلى %{email}. إن كان عنوان البريد الإلكتروني غير صحيح ، يمكنك تغييره في إعدادات حسابك. - title: الضبط + email_below_hint_html: قم بفحص مجلد البريد المزعج الخاص بك، أو قم بطلب آخر. يمكنك تصحيح عنوان بريدك الإلكتروني إن كان خاطئا. + email_settings_hint_html: انقر على الرابط الذي أرسلناه لك للتحقق من %{email}. سننتظر هنا. + link_not_received: ألم تحصل على رابط؟ + new_confirmation_instructions_sent: سوف تتلقى رسالة بريد إلكتروني جديدة مع رابط التأكيد في غضون بضع دقائق! + title: تحقَّق من بريدك الوارِد sign_in: - preamble_html: قم بتسجيل الدخول باستخدام بيانات الاعتماد الخاصة بك علي %{domain} إذا تم استضافة حسابك على خادم مختلف، فلن تتمكن من تسجيل الدخول هنا. + preamble_html: قم بتسجيل الدخول باستخدام بيانات الاعتماد الخاصة بك على %{domain}. إن استُضيف حسابك على خادم مختلف عن هذا الخادم، لن تتمكن من الولوج هنا. title: تسجيل الدخول إلى %{domain} sign_up: + manual_review: عمليات التسجيل في %{domain} تمر عبر المراجعة اليدوية من قبل مشرفينا. لمساعدتنا في معالجة إنشاء حسابك، اكتب نَبْذَة عن نفسك ولماذا تريد حسابًا على %{domain}. preamble: مع حساب على خادم ماستدون هذا، ستتمكن من متابعة أي شخص آخر على الشبكة، بغض النظر عن المكان الذي يستضيف فيه حسابهم. title: دعنا نجهّز %{domain}. status: @@ -995,21 +1173,9 @@ ar: functional: حسابك يعمل بشكل كامل. pending: إن طلبك قيد المراجعة من قبل فريقنا. قد يستغرق هذا بعض الوقت. سوف تتلقى بريدا إلكترونيا إذا تمت الموافقة على طلبك. redirecting_to: حسابك غير نشط لأنه تم تحويله حاليا إلى %{acct}. - view_strikes: عرض السجلات السابقة ضد حسابك + view_strikes: عرض العقوبات السابقة المُطَبَّقة ضد حسابك too_fast: تم إرسال النموذج بسرعة كبيرة، حاول مرة أخرى. use_security_key: استخدام مفتاح الأمان - authorize_follow: - already_following: أنت تتابع بالفعل هذا الحساب - already_requested: لقد قُمتَ بإرسال طلب متابَعة إلى هذا الحساب مِن قَبل - error: يا للأسف، وقع هناك خطأ إثر عملية البحث عن الحساب عن بعد - follow: اتبع - follow_request: 'لقد قمت بإرسال طلب متابعة إلى:' - following: 'مرحى! أنت الآن تتبع:' - post_follow: - close: أو يمكنك إغلاق هذه النافذة. - return: اظهر الملف التعريفي للمستخدم - web: واصل إلى الويب - title: إتباع %{acct} challenge: confirm: واصل hint_html: "توصية: لن نطلب منك ثانية كلمتك السرية في غضون الساعة اللاحقة." @@ -1025,7 +1191,7 @@ ar: with_month_name: "%d %B %Y" datetime: distance_in_words: - about_x_hours: "%{count}سا" + about_x_hours: "%{count} سا" about_x_months: "%{count} شهر" about_x_years: "%{count} سنة" almost_x_years: "%{count} سنوات" @@ -1034,9 +1200,9 @@ ar: less_than_x_seconds: الآن over_x_years: "%{count} سنين" x_days: "%{count} أيام" - x_minutes: "%{count}د" - x_months: "%{count} شه" - x_seconds: "%{count}ث" + x_minutes: "%{count} د" + x_months: "%{count} شهر" + x_seconds: "%{count}ثا" deletes: challenge_not_passed: المعلومات التي أدخلتها لم تكن صحيحة confirm_password: قم بإدخال كلمتك السرية الحالية للتحقق من هويتك @@ -1067,7 +1233,7 @@ ar: approve_appeal: الموافقة على الطعن associated_report: التقرير المتربط created_at: بتاريخ - description_html: هذه هي الإجراءات المتخذة ضد حسابك والتحذيرات التي تم إرسالها إليك من قبل موظفي %{instance}. + description_html: هذه هي الإجراءات المتخذة ضد حسابك والتحذيرات التي تم إرسالها إليك من قبل فريق %{instance}. recipient: موجّه إلى reject_appeal: رفض الطعن status: 'المنشور #%{id}' @@ -1086,6 +1252,10 @@ ar: your_appeal_rejected: تم رفض طعنك domain_validator: invalid_domain: ليس بإسم نطاق صالح + edit_profile: + basic_information: معلومات أساسية + hint_html: "قم بتخصيص ما سيراه الناس في ملفك الشخصي العام وبجوار منشوراتك. من المرجح أن يتابعك أشخاص آخرون ويتفاعلون معك إن كان لديك صفحة شخصية مملوء وصورة." + other: أخرى errors: '400': الطلب الذي قدمته غير صالح أو أنّ شكله غير سليم. '403': ليس لك الصلاحيات الكافية لعرض هذه الصفحة. @@ -1122,7 +1292,7 @@ ar: featured_tags: add_new: أضف واحدًا جديدا errors: - limit: لقد قمت بالفعل بعرض الحد الأقصى من الوسوم + limit: لقد قمت بالفعل بعرض الحد الأقصى من عدد الوسوم hint_html: "ما هي الوسوم الرائجة؟ يتم عرضها بشكل بارز على ملفك الشخصي العام وتسمح للناس بتصفح منشوراتك العامة على وجه التحديد تحت تلك الوسوم. وهي أداة رائعة لتتبع الأعمال الإبداعية أو المشاريع الطويلة الأجل." filters: contexts: @@ -1153,6 +1323,20 @@ ar: other: "%{count} كلمة مفتاحية" two: كلمتان مفتاحيتان %{count} zero: "%{count} كلمة مفتاحية" + statuses: + few: "%{count} منشورات" + many: "%{count} منشورًا" + one: "%{count} منشور واحد" + other: "%{count} منشور" + two: "%{count} منشوران اثنان" + zero: "%{count} منشورات" + statuses_long: + few: "%{count} منشورات فردية مخفية" + many: "%{count} منشورًا فرديا مخفيا" + one: منشور فردي مخفي واحد + other: "%{count} منشور فردي مخفي" + two: منشوران فرديان مخفيان + zero: لا منشورات فردية مخفية title: عوامل التصفية new: save: حفظ عامل التصفية الجديد @@ -1164,11 +1348,11 @@ ar: index: hint: ينطبق الفلتر هذا على اختيار المنشورات الفردية بغض النظر عن المعايير الأخرى. يمكنك إضافة المزيد من المنشورات إلى هذا الفلتر من واجهة الويب. title: الرسائل المصفّاة - footer: - trending_now: المتداولة الآن generic: all: الكل + cancel: إلغاء changes_saved_msg: تم حفظ التعديلات بنجاح! + confirm: تأكيد copy: نسخ delete: احذف deselect: إلغاء تحديد الكل @@ -1183,24 +1367,62 @@ ar: other: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه two: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه zero: هناك شيء ما ليس على ما يرام! يُرجى مراجعة الأخطاء الـ %{count} أدناه - html_validator: - invalid_markup: 'يحتوي على علامة HTML غير صالحة: %{error}' imports: errors: + empty: ملف CSV فارغ + incompatible_type: غير متوافق مع نوع الاستيراد المحدد invalid_csv_file: 'ملف CSV غير صالح. خطأ: %{error}' over_rows_processing_limit: يحتوي على أكثر من %{count} صف + too_large: الملف كبير جدًا + failures: فشل + imported: مستورد + mismatched_types_warning: يبدو أنك اخترت نوعًا خاطئًا لهذا الاستيراد، تأكد من فضلك. modes: merge: دمج merge_long: الإبقاء علي التسجيلات الحالية وإضافة الجديدة overwrite: إعادة الكتابة overwrite_long: استبدال التسجيلات الحالية بالجديدة + overwrite_preambles: + blocking_html: أنت على وشك استبدال قائمة الحظر بما يصل إلى %{total_items} من الحسابات من %{filename}. + bookmarks_html: أنت على وشك استبدال إشاراتك المرجعية بما يصل إلى %{total_items} من المشاركات من %{filename}. + domain_blocking_html: أنت على وشك إرشاداتك المرجعية بما يصل إلى %{total_items} من المشاركات من %{filename}. + following_html: أنت على وشك متابعة ما يصل إلى %{total_items} من الحسابات من %{filename} والتوقف عن متابعة أي شخص آخر. + lists_html: إنّك بصدد استبدال قوائمك بمحتوى مِلَفّ %{filename}. ما يُقارِب %{total_items} حسابًا سوف تُضاف إلى قوائم جديدة. + muting_html: أنت على وشك استبدال قائمة الحسابات الصامتة بما يصل إلى %{total_items} من الحسابات من %{filename}. + preambles: + blocking_html: أنت على وشك حظر ما يصل إلى %{total_items} من الحسابات من %{filename}. + bookmarks_html: أنت على وشك إضافة ما يصل إلى %{total_items} من المشاركات من %{filename} إلى إشاراتك المرجعية. + domain_blocking_html: أنت على وشك حظر ما يصل إلى %{total_items} من النطاقات من %{filename}. + following_html: أنت على وشك متابعة ما يصل إلى %{total_items} من الحسابات من %{filename}. + lists_html: أنت على وشك إضافة ما يصل إلى %{total_items} حسابات من %{filename} إلى قوائمك. سيتم إنشاء قوائم جديدة في حالة عدم وجود قائمة للإضافة إليها. + muting_html: أنت على وشك تجاهل ما يصل إلى %{total_items} من الحسابات من %{filename}. preface: بإمكانك استيراد بيانات قد قُمتَ بتصديرها مِن مثيل خادم آخَر، كقوائم المستخدِمين الذين كنتَ تتابِعهم أو قُمتَ بحظرهم. + recent_imports: الاستيرادات الحديثة + states: + finished: تم + in_progress: قيد الإنجاز + scheduled: مُبرمَج + unconfirmed: غير مؤكد + status: منشور success: تم تحميل بياناتك بنجاح وسيتم معالجتها في الوقت المناسب + time_started: بدأ في + titles: + blocking: جارٍ استيراد الحسابات المحظورة + bookmarks: جارٍ استيراد الفواصل المرجعية + domain_blocking: جارٍ استيراد النطاقات المحظورة + following: جارٍ استيراد الحسابات المتابَعة + lists: جارٍ استيراد القوائم + muting: جارٍ استيراد الحسابات المكتومة + type: نوع الاستيراد + type_groups: + constructive: المتابعة والعلامات المرجعية + destructive: الحضر و الكتم types: blocking: قائمة المحظورين bookmarks: الفواصل المرجعية domain_blocking: قائمة النطاقات المحظورة following: قائمة المستخدمين المتبوعين + lists: القوائم muting: قائمة الكتم upload: تحميل invites: @@ -1243,6 +1465,21 @@ ar: failed_sign_in_html: فشل محاولة تسجيل الدخول مع %{method} من %{ip} (%{browser}) successful_sign_in_html: تم تسجيل الدخول بنجاح مع %{method} من %{ip} (%{browser}) title: تاريخ المصادقة + mail_subscriptions: + unsubscribe: + action: نعم، ألغِ الاشتراك + complete: غير مشترك + confirmation_html: هل أنت متأكد أنك تريد إلغاء الاشتراك في تلقي %{type} لـ Mastodon على %{domain} إلى بريدك الإلكتروني على %{email}؟ يمكنك دائمًا إعادة الاشتراك من إعدادات إشعارات البريد الإلكتروني. + emails: + notification_emails: + favourite: إشعارات رسائل البريد الخاصة بالمفضلة + follow: إشعارات رسائل البريد الخاصة بالمتابعة + follow_request: رسائل البريد الإلكترونية الخاصة بطلبات المتابعة + mention: إشعارات رسائل البريد عندما يَذكُرك أحدهم + reblog: رسائل البريد الخاصة بالمنشورات المعاد نشرها + resubscribe_html: إذا قمت بإلغاء الاشتراك عن طريق الخطأ، يمكنك إعادة الاشتراك من إعدادات الإشعارات في بريدك الإلكتروني. + success_html: لن تتلقّ بعد الآن %{type} لماستدون مِن %{domain} على بريدك الإلكتروني %{email}. + title: إلغاء الاشتراك media_attachments: validations: images_and_video: ليس بالإمكان إرفاق فيديو في منشور يحتوي مسبقا على صور @@ -1315,13 +1552,14 @@ ar: subject: انتهى استطلاع %{name} للرأي reblog: body: 'قام %{name} بترقية منشورك:' - subject: قام %{name} بترقية منشورك - title: ترقية جديدة + subject: قام %{name} بإعادة نشر منشورك + title: إعادة نشر جديدة status: subject: "%{name} نشر للتو" update: subject: قام %{name} بتحرير منشور notifications: + administration_emails: إشعارات البريد الإلكتروني الإدارية email_events: الأحداث للإشعارات عبر البريد الإلكتروني email_events_hint: 'اختر الأحداث التي تريد أن تصِلَك اشعارات عنها:' other_settings: إعدادات أخرى للإشعارات @@ -1358,12 +1596,22 @@ ar: expired: لقد انتهى استطلاع الرأي invalid_choice: خيار التصويت الذي قُمتَ يتحديده غير موجود over_character_limit: لا يمكن أن يكون أطول من %{max} حرف لكل واحد + self_vote: لا يمكنك التصويت في استطلاعاتك الخاصة too_few_options: يجب أن يحتوي على أكثر من عنصر واحد too_many_options: لا يمكنه أن يحتوي أكثر مِن %{max} عناصر preferences: other: إعدادات أخرى posting_defaults: التفضيلات الافتراضية للنشر public_timelines: الخيوط الزمنية العامة + privacy: + hint_html: "قم بتخصيص الطريقة التي تريد بها أن يُكتَشَف ملفك الشخصي ومنشوراتك. يمكن لمجموعة متنوعة من الميزات في Mastodon أن تساعدك في الوصول إلى جمهور أوسع عند تفعيلها. خذ بعض الوقت لمراجعة هذه الإعدادات للتأكد من أنها تناسب حالة الاستخدام الخاصة بك." + privacy: الخصوصية + privacy_hint_html: تحكم في مقدار ما ترغب في الكشف عنه لصالح الآخرين. يكتشف الأشخاص الملفات الشخصية المثيرة والتطبيقات الرائعة من خلال تصفح متابعات الأشخاص الآخرين ورؤية التطبيقات التي ينشرونها، ولكن قد تفضل الاحتفاظ بها مخفية. + reach: الوصول + reach_hint_html: تحكم في ما إذا كنت ترغب في أن يكتشفك ويتابعك أشخاص جدد. هل ترغب في أن تظهر منشوراتك على شاشة الاستكشاف؟ هل ترغب في أن يرى الأشخاص الآخرون اقتراحات المتابعة الخاصة بك؟ هل ترغب في قبول جميع المتابعين الجدد تلقائيًا، أم ترغب في التحكّم التفصيلي على كل واحد منهم؟ + search: البحث + search_hint_html: تحكم في كيفية العثور عليك. هل ترغب في أن يجد الناس معلوماتك بناءً على ما نشرته علنيًا؟ هل ترغب في أن يمكن للأشخاص خارج منصة Mastodon العثور على ملفك الشخصي عند البحث على الويب؟ يرجى مراعاة أنه لا يمكن ضمان استبعاد تام من جميع محركات البحث للمعلومات العامة. + title: الخصوصية والوصول إلى الجمهور privacy_policy: title: سياسة الخصوصية reactions: @@ -1376,6 +1624,7 @@ ar: confirm_remove_selected_followers: هل أنت متأكد من أنك تريد إزالة المتابِعين المحددين؟ confirm_remove_selected_follows: هل أنت متيقِّن من أنك تريد إزالة الاشتراكات المحدَّدة؟ dormant: في سبات + follow_failure: تعذرت متابعة بعض الحسابات المختارة. follow_selected_followers: متابَعة المتابِعين المحددين followers: المتابِعون following: يُتابِع @@ -1415,6 +1664,7 @@ ar: electron: إلكترون firefox: فايرفكس generic: متصفح مجهول + huawei_browser: متصفح هواواي ie: إنترنت إكسبلورر micro_messenger: مايكرو ميسنجر nokia: متصفح Nokia S40 Ovi @@ -1424,6 +1674,7 @@ ar: qq: متصفح كيوكيو safari: سفاري uc_browser: متصفح UC Browser + unknown_browser: متصفح غير معروف weibo: وايبو current_session: الجلسة الحالية description: "%{browser} على %{platform}" @@ -1436,9 +1687,10 @@ ar: chrome_os: نظام كروم أواس firefox_os: نظام فايرفكس أواس ios: نظام آي أواس + kai_os: KaiOS linux: لينكس mac: ماك - other: نظام مجهول + unknown_platform: منصة غير معروفة windows: ويندوز windows_mobile: ويندوز موبايل windows_phone: ويندوز فون @@ -1455,7 +1707,7 @@ ar: back: عودة إلى ماستدون delete: حذف الحسابات development: التطوير - edit_profile: عدّل الصفحة التعريفية + edit_profile: تعديل الصفحة التعريفية export: تصدير البيانات featured_tags: الوسوم الشائعة import: استيراد @@ -1512,7 +1764,7 @@ ar: direct: لا يمكن تثبيت المنشورات التي يراها فقط المتسخدمون المشار إليهم limit: لقد بلغت الحد الأقصى للمنشورات المثبتة ownership: لا يمكن تثبيت منشور نشره شخص آخر - reblog: لا يمكن تثبيت ترقية + reblog: لا يمكن تثبيت إعادة نشر poll: total_people: few: "%{count} أشخاص" @@ -1533,36 +1785,35 @@ ar: show_newer: إظهار أحدث show_older: إظهار أقدم show_thread: اعرض خيط المحادثة - sign_in_to_participate: قم بتسجيل الدخول للمشاركة في هذه المحادثة title: '%{name}: "%{quote}"' visibilities: direct: مباشرة private: لمتابِعيك فقط private_long: اعرضه لمتابعيك فقط public: للعامة - public_long: يمكن للجميع رؤيته + public_long: يمكن للجميع رؤية منشوراتك unlisted: غير مُدرَج unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة statuses_cleanup: - enabled: حذف المشاركات القديمة تلقائياً + enabled: حذف المنشورات القديمة تلقائياً enabled_hint: حذف منشوراتك تلقائياً بمجرد أن تصل إلى عتبة عمرية محددة، إلا إذا كانت مطابقة لأحد الاستثناءات أدناه exceptions: الاستثناءات - explanation: لأن حذف المشاركات عملية مكلفة، يتم ذلك ببطء مع مرور الوقت عندما يكون الخادم غير مشغول. لهذا السبب، يمكن حذف مشاركاتك بعد فترة من بلوغها عتبة السن. + explanation: لأن حذف المنشورات عملية مكلفة، يتم ذلك ببطء مع مرور الوقت عندما يكون الخادم غير مشغول. لهذا السبب، عملية حذف مشاركاتك قد تتأخر قليلا بالرغم من تحديدك للمدة. ignore_favs: تجاهل المفضلة - ignore_reblogs: تجاهل المشاركات + ignore_reblogs: تجاهل المعاد نشرها interaction_exceptions: الاستثناءات المبنية على التفاعلات - interaction_exceptions_explanation: لاحظ أنه لا يوجد ضمان لحذف الوظائف إذا كانت أقل من عتبة التعزيز المفضلة بعد أن تكون قد ذهبت إليها. + interaction_exceptions_explanation: لاحظ أنه ليس هناك أي ضمان لحذف المنشورات إن كانت تحت عتبة المفضلة أو عدد إعادات المشاركات بعد تعديها لتلك العتبة. keep_direct: الاحتفاظ بالرسائل المباشرة - keep_direct_hint: لم تقوم بحذف أي من رسائلك المباشرة - keep_media: الاحتفاظ بالمشاركات مع مرفقات الوسائط - keep_media_hint: لم تقوم بحذف أي من المشاركات الخاصة بك التي تحتوي على مرفقات الوسائط - keep_pinned: الاحتفاظ بالمشاركات المثبتة + keep_direct_hint: لن يقوم بحذف أي من رسائلك المباشرة + keep_media: الاحتفاظ بالمنشورات ذات وسائط مرفقة + keep_media_hint: لن تُحذف أي من منشوراتك التي تحتوي على وسائط مرفقة + keep_pinned: الاحتفاظ بالمنشورات المثبتة keep_pinned_hint: لم تقوم بحذف أي من مشاركتك المثبتة keep_polls: الاحتفاظ باستطلاعات الرأي keep_polls_hint: لم تقم بحذف أي من استطلاعاتك - keep_self_bookmark: احتفظ بالمشاركات التي أدرجتها حجزا + keep_self_bookmark: احتفظ بالمنشورات التي أدرجتها في الفواصل المرجعية keep_self_bookmark_hint: لم تقم بحذف مشاركاتك الخاصة إذا قمت بوضع علامة مرجعية عليها - keep_self_fav: احتفظ بالمشاركات التي تفضلها + keep_self_fav: احتفظ بالمنشورات التي أدرجتها في المفضلة keep_self_fav_hint: لم تقم بحذف مشاركاتك الخاصة إذا كنت قد فضلتهم min_age: '1209600': أسبوعان @@ -1570,17 +1821,15 @@ ar: '2629746': شهر واحد '31556952': سنة واحدة '5259492': شهران - '604800': أسبوع + '604800': أسبوع واحد '63113904': سنتان '7889238': 3 أشهر min_age_label: عتبة العمر min_favs: إبقاء المشاركات المفضلة أكثر من - min_favs_hint: لم تقوم بحذف أي من المشاركات الخاصة بك التي حصلت على أكثر من هذه الكمية من المفضلة. اتركه فارغاً لحذف المشاركات بغض النظر عن عدد المفضلات لديها + min_favs_hint: لن تُحذف أي من منشوراتك التي تلقّت على الأقل هذا العدد من المفضلات. اتركه فارغاً لحذف المنشورات مهما كان عدد المفضلات التي تلقتها min_reblogs: إبقاء المشاركات المعززة أكثر من - min_reblogs_hint: لن تُحذف أي من منشوراتك التي أعيد مشاركتها أكثر من هذا العدد من المرات. اتركه فارغاً لحذف المنشورات بغض النظر عن عدد إعادات المشاركة + min_reblogs_hint: لن تُحذف أي من منشوراتك التي أعيد مشاركتها أكثر من هذا العدد من المرات. اتركه فارغاً لحذف المنشورات بغض النظر عن عدد إعادات النشر stream_entries: - pinned: منشور مثبّت - reblogged: شارَكَه sensitive_content: محتوى حساس strikes: errors: @@ -1596,6 +1845,11 @@ ar: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d %Y، %H:%M %Z" + translation: + errors: + quota_exceeded: تم تجاوز حصة استخدام خدمة التَّرْجَمَةً على نطاق الخادم. + too_many_requests: لقد تلقّينا حديثًا عددًا كبيرًا جدا من الطلبات إلى خدمة التَّرْجَمَة. two_factor_authentication: add: إضافة disable: تعطيل @@ -1675,13 +1929,18 @@ ar: title: أهلاً بك، %{name}! users: follow_limit_reached: لا يمكنك متابعة أكثر مِن %{limit} أشخاص + go_to_sso_account_settings: انتقل إلى إعدادات حساب مزود الهوية الخاص بك invalid_otp_token: رمز المصادقة بخطوتين غير صالح otp_lost_help_html: إن فقدتَهُما ، يمكنك الاتصال بـ %{email} seamless_external_login: لقد قمت بتسجيل الدخول عبر خدمة خارجية، إنّ إعدادات الكلمة السرية و البريد الإلكتروني غير متوفرة. signed_in_as: 'تم تسجيل دخولك بصفة:' verification: - explanation_html: 'يمكنك التحقق من نفسك كمالك لروابط البيانات التعريفية على صفحتك الشخصية. لذلك، يجب أن يحتوي الموقع المقترِن على رابط إلى صفحتك التعريفية الشخصية على ماستدون. الرابط الخلفي يجب أن يحتوي على رمز rel="me". محتوى النص في الرابط غير مهم. على سبيل المثال:' + extra_instructions_html: نصيحة: يمكن أن يكون الرابط الموجود على موقع الويب الخاص بك غير مرئي. الجزء المهم هو rel="me" الذي يمنع انتحال الهوية على مواقع الويب ذات المحتوى الذي ينشئه المستخدم. يمكنك أيضًا استخدام علامة link في رأس الصفحة بدلاً من a، ولكن يجب أن يكون HTML قابلاً للوصول دون تنفيذ JavaScript. + here_is_how: إليك كيف ذلك + hint_html: "التحقق من هويتك على Mastodon متاح للجميع. بناءً على معايير الويب المفتوحة، الآن ودائمًا مجانًا. كل ما تحتاجه هو موقع ويب شخصي يتعرف الناس مِن خلاله عليك. عندما تقوم بربط هذا الموقع بملفك الشخصي، سنتحقق من أن الموقع يشير إلى ملفك الشخصي ونعرض عليه علامة بصرية." + instructions_html: قم بنسخ ولصق التعليمة البرمجية أدناه في شفرة HTML لموقعك الخاص على الويب. ثم أضف عنوان موقع الويب الخاص بك إلى أحد الحقول الإضافية في ملفك التعريفي عبر لسان "تعديل الملف التعريفي" ثم احفظ التغييرات. verification: التحقق + verified_links: روابطك التي تم التحقق منها webauthn_credentials: add: إضافة مفتاح أمان جديد create: diff --git a/config/locales/ast.yml b/config/locales/ast.yml index c7d09ddf08..08717c840e 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -6,7 +6,7 @@ ast: hosted_on: 'Mastodon ta agospiáu en: %{domain}' title: Tocante a accounts: - last_active: Última actividá + last_active: última actividá nothing_here: "¡Equí nun hai nada!" posts: one: Artículu @@ -18,11 +18,16 @@ ast: account_moderation_notes: create: Dexar la nota accounts: + add_email_domain_block: Bloquiar el dominiu de corréu electrónicu + approved_msg: Aprobóse correutamente la solicitú de rexistru de «%{username}» + are_you_sure: "¿De xuru que quies facer esta aición?" avatar: Avatar by_domain: Dominiu + confirming: En confirmación disabled: Conxelóse display_name: Nome visible domain: Dominiu + edit: Editar email: Direición de corréu electrónicu followers: Siguidores header: Testera @@ -32,19 +37,22 @@ ast: local: Llocal remote: Remotu title: Llugar + login_status: Estáu del aniciu de la sesión moderation: pending: Pendiente + title: Moderación most_recent_activity: L'actividá más recién most_recent_ip: La IP más recién perform_full_suspension: Suspender protocol: Protocolu + rejected_msg: Refugóse correutamente la solicitú de rexistru de «%{username}» resend_confirmation: already_confirmed: Esti perfil xá ta confirmáu - send: Volver unviar el mensaxe de confirmación role: Rol search: Buscar search_same_email_domain: Otros perfiles col mesmu dominiu de corréu electrónicu search_same_ip: Otros perfiles cola mesma IP + security: Seguranza show: created_reports: Informes fechos statuses: Artículos @@ -60,8 +68,10 @@ ast: confirm_user_html: "%{name} confirmó la direición de corréu electrónicu del perfil %{target}" create_account_warning_html: "%{name} unvió una alvertencia a %{target}" create_announcement_html: "%{name} creó l'anunciu «%{target}»" + create_custom_emoji_html: "%{name} xubió un fustaxe nuevu «%{target}»" create_domain_allow_html: "%{name} permitió la federación col dominiu %{target}" create_domain_block_html: "%{name} bloquió'l dominiu %{target}" + create_unavailable_domain_html: "%{name} paró la entrega al dominiu %{target}" create_user_role_html: "%{name} creó'l rol «%{target}»" destroy_announcement_html: "%{name} desanició l'anunciu «%{target}»" destroy_custom_emoji_html: "%{name} desanició'l fustaxe %{target}" @@ -72,6 +82,9 @@ ast: enable_custom_emoji_html: "%{name} activó'l fustaxe «%{target}»" reject_user_html: "%{name} refugó'l rexistru de: %{target}" remove_avatar_user_html: "%{name} quitó l'avatar de: %{target}" + reopen_report_html: "%{name} volvió abrir l'informe «%{target}»" + resend_user_html: "%{name} volvió unviar el mensaxe de confirmación pa: %{target}" + resolve_report_html: "%{name} resolvió l'informe «%{target}»" unblock_email_account_html: "%{name} desbloquió la direición de corréu electrónicu de: %{target}" update_announcement_html: "%{name} anovó l'anunciu «%{target}»" update_custom_emoji_html: "%{name} anovó'l fustaxe «%{target}»" @@ -138,6 +151,7 @@ ast: space: Usu del espaciu title: Panel top_languages: Les llingües más actives + top_servers: Los sirvidores más activos website: Sitiu web disputes: appeals: @@ -159,6 +173,7 @@ ast: export_domain_allows: no_file: Nun se seleicionó nengún ficheru follow_recommendations: + description_html: "La recomendación de cuentes ayuda a que los perfiles nuevos atopen aína conteníu interesante. Cuando una cuenta nun interactuó abondo con otros perfiles como pa formar recomendaciones personalizaes, estes cuentes van ser les que se recomienden. Recalcúlense caldía a partir d'un mecíu de cuentes con más actividá recién ya mayor númberu de siguidores llocales pa una llingua determinada." language: Pa la llingua status: Estáu title: Recomendación de cuentes @@ -173,13 +188,34 @@ ast: suspend: Suspender policy: Política reason: Motivu públicu + title: Polítiques del conteníu + dashboard: + instance_accounts_dimension: Les cuentes más siguíes + instance_accounts_measure: cuentes atroxaes + instance_followers_measure: siguidores de nueso ellí + instance_follows_measure: siguidores de so equí + instance_languages_dimension: Les llingües más usaes + instance_media_attachments_measure: ficheros multimedia atroxaos + instance_reports_measure: informes d'esa instancia + instance_statuses_measure: artículos atroxaos empty: Nun s'atopó nengún dominiu. known_accounts: one: "%{count} cuenta conocida" other: "%{count} cuentes conocíes" + moderation: + title: Moderación private_comment: Comentariu priváu public_comment: Comentariu públicu title: Federación + total_reported: Informes d'esa instancia + invites: + deactivate_all: Desactivalo too + filter: + all: Too + available: Disponible + expired: Caducó + title: Peñera + title: Invitaciones ip_blocks: expires_in: '1209600': 2 selmanes @@ -192,13 +228,18 @@ ast: title: 'Rellaciones de: %{acct}' relays: status: Estáu + report_notes: + created_msg: "¡La nota del informe creóse correutamente!" reports: account: notes: one: "%{count} nota" other: "%{count} notes" + actions: + silence_description_html: La cuenta va ser visible namás pa quien xá la siguiere o la buscare manualmente, lo que llenda'l so algame. Esta decisión pue desfacese en cualesquier momentu. Si escueyes esta opción, zárrense tolos informes escontra esta cuenta. actions_description_html: Decidi qué aición tomar pa resolver esti informe. Si tomes una aición punitiva escontra la cuenta de la que s'informó, va unviase un avisu per corréu electrónicu a esa cuenta, esceuto cuando se seleiciona la categoría Puxarra. add_to_report: Amestar más al informe + are_you_sure: "¿De xuru que quies facer esta aición?" category: Categoría category_description_html: El motivu pol que s'informó d'esta cuenta y/o conteníu cítase na comunicación cola cuenta de la que s'informó comment_description_html: 'Pa fornir más información, %{name} escribió:' @@ -211,10 +252,13 @@ ast: notes: create: Amestar la nota create_and_resolve: Resolver con una nota + create_and_unresolve: Volver abrir con una nota + delete: Desaniciar title: Notes quick_actions_description_html: 'Toma una aición rápida o baxa pa ver el conteníu del que s''informó:' report: 'Informe #%{id}' reported_by: Perfil qu'informó + resolved: Resolvióse resolved_msg: "¡L'informe resolvióse correutamente!" skip_to_actions: Saltar a les aiciones status: Estáu @@ -233,6 +277,7 @@ ast: administration: Alministración devops: DevOps invites: Invitaciones + moderation: Moderación edit: Edición del rol «%{name}» everyone: Permisos predeterminaos permissions_count: @@ -246,7 +291,7 @@ ast: manage_invites: Xestionar les invitaciones manage_reports: Xestionar los informes manage_roles: Xestionar los roles - manage_rules: Xestionar les regles + manage_rules: Xestionar les normes manage_settings: Xestionar la configuración manage_taxonomies: Xestionar les taxonomíes manage_users: Xestionar los perfiles @@ -255,11 +300,11 @@ ast: view_devops: DevOps title: Roles rules: - add_new: Amestar la regla - title: Regles del sirvidor + add_new: Amestar la norma + title: Normes del sirvidor settings: about: - manage_rules: Xestionar les regles del sirvidor + manage_rules: Xestionar les normes del sirvidor title: Tocante a appearance: preamble: Personaliza la interfaz web de Mastodon. @@ -271,7 +316,12 @@ ast: preamble: Controla cómo s'atroxa'l conteníu xeneráu polos perfiles en Mastodon. title: Retención del conteníu discovery: + follow_recommendations: Recomendación de cuentes + preamble: L'apaición de conteníu interesante ye fundamental p'atrayer persones nueves que nun conozan nada de Mastodon. Controla'l funcionamientu de delles funciones de descubrimientu d'esti sirvidor. + profile_directory: Direutoriu de perfiles public_timelines: Llinies de tiempu públiques + publish_discovered_servers: Espublizamientu de sirvidores descubiertos + publish_statistics: Espublizamientu d'estadístiques title: Descubrimientu trends: Tendencies domain_blocks: @@ -286,44 +336,68 @@ ast: approved: Tol mundu pente una aprobación none: Naide open: Tol mundu - title: Configuración del sirvidor site_uploads: delete: Desaniciar el ficheru xubíu + software_updates: + documentation_link: Saber más + type: Tipu + types: + major: Versión mayor + minor: Versión menor + version: Versión statuses: + back_to_account: Volver a la páxina de la cuenta language: Llingua metadata: Metadatos original_status: Artículu orixinal visibility: Visibilidá + with_media: Con elementos multimedia strikes: actions: delete_statuses: "%{name} desanició l'artículu de: %{target}" + disable: "%{name} conxeló la cuenta de: %{target}" mark_statuses_as_sensitive: "%{name} marcó l'artículu de %{target} como sensible" none: "%{name} unvió una alvertencia a %{target}" sensitive: "%{name} marcó la cuenta de %{target} como sensible" suspend: "%{name} suspendió la cuenta de: %{target}" appeal_approved: Apellóse + appeal_pending: Apellación pendiente system_checks: elasticsearch_running_check: message_html: Nun se pudo conectar con Elasticsearch. Revisa que tea n'execución o desactiva la busca de testos completos title: Alministración trends: + allow: Permitir + disallow: Refugar links: + disallow: Refugar l'enllaz title: Enllaces en tendencia only_allowed: Namás lo permitío pending_review: Revisión pendiente + preview_card_providers: + title: Espublizadores statuses: + allow: Permitir l'artículu + disallow: Refugar l'artículu title: Artículos en tendencia tags: current_score: 'Puntuación total: %{score}' dashboard: tag_accounts_measure: usos únicos + tag_languages_dimension: Les llingües más usaes + tag_servers_dimension: Los sirvidores más destacaos + tag_servers_measure: sirvidores diferentes + tag_uses_measure: usos en total listable: Pue suxerise no_tag_selected: Nun camudó nenguna etiqueta darréu que nun se seleicionó nenguna + not_trendable: Nun apaez nes tendencies not_usable: Nun se pue usar title: Etiquetes en tendencia usable: Pue usase title: Tendencies trending: En tendencia + warning_presets: + title: Xestión d'alvertencies preconfiguraes webhooks: add_new: Amestar un estremu delete: Desaniciar @@ -331,7 +405,7 @@ ast: disable: Desactivar disabled: Desactivóse edit: Editar l'estremu - empty: Entá nun tienes nengún estremu de webhooks configuráu. + empty: Nun tienes nengún estremu de webhooks configuráu. enable: Activar enabled: N'activo enabled_events: @@ -371,34 +445,38 @@ ast: guide_link: https://crowdin.com/project/mastodon guide_link_text: tol mundu pue collaborar. sensitive_content: Conteníu sensible - toot_layout: Distribución de los artículos + application_mailer: + notification_preferences: Camudar les preferencies de los mensaxes de corréu electrónicu applications: created: L'aplicación creóse correutamente + destroyed: L'aplicación desanicióse correutamente regenerate_token: Volver xenerar el pase d'accesu token_regenerated: El pase d'accesu volvió xenerase correutamente warning: Ten munchu curiáu con estos datos, ¡enxamás nun los compartas con naide! your_token: El pase d'accesu auth: - change_password: Contraseña + confirmations: + wrong_email_hint: Si la direición de corréu electrónicu nun ye correuta, pues camudala na configuración de la cuenta. delete_account: Desaniciu de la cuenta delete_account_html: Si quies desaniciar la cuenta, pues facelo equí. Va pidísete que confirmes l'aición. description: prefix_sign_up: "¡Rexístrate güei en Mastodon!" - didnt_get_confirmation: "¿Nun recibiesti les instrucciones de confirmación?" dont_have_your_security_key: "¿Nun tienes una llave de seguranza?" forgot_password: "¿Escaeciesti la contraseña?" login: Aniciar la sesión logout: Zarrar la sesión migrate_account: Cambéu de cuenta + migrate_account_html: Si quies redirixir esta cuenta a otra diferente, pues configurar esta opción equí. privacy_policy_agreement_html: Lleí ya acepto la política de privacidá providers: cas: CAS saml: SAML register: Rexistrase registration_closed: "%{instance} nun acepta cuentes nueves" + rules: + accept: Aceptar + back: Atrás security: Seguranza - setup: - email_settings_hint_html: Unvióse'l mensaxe de confirmación a %{email}. Si la direición de corréu electrónicu nun ye correuta, pues camudala na configuración de la cuenta. sign_in: preamble_html: Anicia la sesión colos tos datos d'accesu en %{domain}. Si la cuenta ta agospiada n'otru sirvidor, nun vas ser a aniciar la sesión equí. title: Aniciu de la sesión en «%{domain}» @@ -410,15 +488,6 @@ ast: functional: La cuenta ta completamente operativa. pending: La to solicitú ta pendiente de que la revise'l nuesu personal ya ye posible que tarde tiempu. Vas recibir un mensaxe si s'aprueba. too_fast: El formulariu xubióse mui rápido, volvi tentalo. - authorize_follow: - already_following: Xá tas siguiendo a esta cuenta - already_requested: Yá unviesti una solicitú de siguimientu a esa cuenta - error: Desafortunadamente, hebo un error al buscar la cuenta remota - follow_request: 'Unviesti una solicitú de siguimientu a:' - post_follow: - close: O pues zarrar esta ventana. - return: Amosar el perfil de la cuenta - web: Dir a la web challenge: confirm: Siguir hint_html: "Conseyu: nun vamos volver pidite la contraseña hasta dientro d'una hora." @@ -444,7 +513,7 @@ ast: challenge_not_passed: La información qu'introduxesti nun yera correuta confirm_password: Introduz la contraseña pa verificar la to identidá warning: - email_contact_html: Si entá nun aportó, pues unviar un mensaxe a %{email} pa consiguir más ayuda + email_contact_html: Si nun aportó, pues unviar un mensaxe a %{email} pa consiguir más ayuda email_reconfirmation_html: Si nun recibiesti'l mensaxe de confirmación, pues volver solicitalu more_details_html: Pa consiguir más detalles, mira la política de privacidá. disputes: @@ -452,13 +521,18 @@ ast: action_taken: Aición tomada appeal: Apellación appeal_rejected: Refugóse l'apellación + appeal_submitted_at: Data de l'apellación + appealed_msg: Unvióse l'apellación. Si s'aprueba, avisámoste. appeals: submit: Unviu d'una apellación approve_appeal: Aprobar l'apellación + associated_report: Informe asociáu created_at: Data + recipient: Dirixóse a reject_appeal: Refugar l'apellación status: 'Artículu #%{id}' status_removed: L'artículu xá se quitó del sistema + your_appeal_approved: Aprobóse la to apellación your_appeal_pending: Unviesti una apellación your_appeal_rejected: Refugóse la to apellación errors: @@ -491,14 +565,15 @@ ast: storage: Almacenamientu multimedia featured_tags: add_new: Amestar - hint_html: "¿Qué son les etiquetes destacaes? Apaecen de forma bien visible nel perfil públicu ya permite que les persones restolen los tos artículos públicos per duana d'eses etiquetes. Son una gran ferramienta pa tener un rexistru de trabayos creativos o de proyeutos a plazu llongu." filters: contexts: account: Perfiles + home: Aniciu ya llistes notifications: Avisos public: Llinies de tiempu públiques thread: Conversaciones edit: + add_keyword: Amestar una pallabra clave keywords: Pallabres clave statuses: Artículos individuales errors: @@ -512,8 +587,8 @@ ast: one: "%{count} artículu" other: "%{count} artículos" title: Peñeres - footer: - trending_now: En tendencia + new: + title: Amestar una peñera generic: all: Too all_items_on_page_selected_html: @@ -522,6 +597,7 @@ ast: all_matching_items_selected_html: one: Seleicionóse %{count} elementu que concasa cola busca. other: Seleicionáronse %{count} elementos que concasen cola busca. + changes_saved_msg: "¡Los cambeos guardáronse correutamente!" copy: Copiar delete: Desaniciar deselect: Deseleicionar too @@ -529,6 +605,8 @@ ast: save_changes: Guardar los cambeos today: güei imports: + errors: + over_rows_processing_limit: contién más de %{count} fileres modes: merge: Mecíu merge_long: Caltién los rexistros esistentes ya amiesta otros nuevos @@ -537,8 +615,11 @@ ast: preface: Pues importar los datos qu'esportares dende otru sirvidor, como la llista de perfiles bloquiaos o que sigas. types: blocking: Llista de perfiles bloquiaos + bookmarks: Marcadores domain_blocking: Llista de dominios bloquiaos following: Llista de siguidores + lists: Llistes + muting: Llista de perfiles colos avisos desactivaos upload: Xubir invites: expired: Caducó @@ -555,15 +636,16 @@ ast: max_uses: one: 1 usu other: "%{count} usos" + prompt: Xenera ya comparti enllaces con otres persones pa conceder l'accesu a esti sirvidor table: expires_at: Data de caducidá - lists: - errors: - limit: Algamesti la cantidá máxima de llistes + uses: Usos + title: Invitación login_activities: authentication_methods: password: contraseña webauthn: llaves de seguranza + successful_sign_in_html: Anicióse correutamente la sesión col métodu «%{method}» dende %{ip} (%{browser}) media_attachments: validations: images_and_video: Nun se pue axuntar nengún videu a un artículu que xá contién imáxenes @@ -572,8 +654,11 @@ ast: errors: missing_also_known_as: nun ye un nomatu d'esta cuenta move_to_self: nun pue ser la cuenta actual + incoming_migrations_html: Pa migrar d'otra cuenta a esta, primero tienes de crear un nomatu de cuenta. warning: followers: Esta aición va mover tolos siguidores de la cuenta actual a la nueva + moderation: + title: Moderación notification_mailer: admin: sign_up: @@ -583,6 +668,7 @@ ast: subject: "%{name} marcó'l to artículu como favoritu" follow: body: "¡Agora %{name} siguete!" + subject: "%{name} ta siguiéndote" follow_request: body: "%{name} solicitó siguite" title: Solicitú de siguimientu nueva @@ -596,6 +682,7 @@ ast: update: subject: "%{name} editó un artículu" notifications: + email_events: Unviu d'avisos per corréu electrónicu email_events_hint: 'Seleiciona los eventos de los que quies recibir avisos:' other_settings: Configuración d'otros avisos number: @@ -614,7 +701,7 @@ ast: instructions_html: "Escania esti códigu QR con Google Authenticator o otra aplicación asemeyada nel móvil. Dende agora, esa aplicación va xenerar los pases que tienes d'introducir cuando anicies la sesión." manual_instructions: 'Si nun pues escaniar el códigu QR ya tienes d''introducilu manualmente, equí tienes el secretu en testu ensin formatu:' setup: Configurar - wrong_code: "¡El códigu introducíu nun yera válidu! ¿La hora del sirvidor y la del preséu son correutes?" + wrong_code: "¡El códigu introducíu nun yera válidu! ¿La hora del sirvidor ya la del preséu son correutes?" pagination: next: Siguiente truncate: "…" @@ -625,6 +712,8 @@ ast: invalid_choice: La opción de votu escoyida nun esiste too_many_options: nun pue contener más de %{max} elementos preferences: + other: Otres preferencies + posting_defaults: Configuración predeterminada del espublizamientu d'artículos public_timelines: Llinies de tiempu públiques privacy_policy: title: Política de privacidá @@ -633,6 +722,8 @@ ast: followers: Siguidores last_active: Última actividá most_recent: Lo más recién + mutual: Mutua + primary: Principal relationship: Rellación remove_selected_follows: Dexar de siguir a los perfiles seleicionaos scheduled_statuses: @@ -648,6 +739,7 @@ ast: electron: Electron firefox: Firefox generic: Restolador desconocíu + huawei_browser: Restolador de Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Restolador Ovi pa S40 de Nokia @@ -657,6 +749,7 @@ ast: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Restolador desconocíu weibo: Weibo current_session: Sesión actual ip: IP @@ -667,9 +760,10 @@ ast: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: GNU/Linux mac: macOS - other: plataforma desconocida + unknown_platform: Plataforma desconocida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -691,7 +785,8 @@ ast: migrate: Migración de la cuenta notifications: Avisos preferences: Preferencies - profile: Perfil + profile: Perfil públicu + relationships: Perfiles que sigues ya te siguen statuses_cleanup: Desaniciu automáticu d'artículos two_factor_authentication: Autenticación en dos pasos webauthn_authentication: Llaves de seguranza @@ -726,14 +821,22 @@ ast: title: "%{name}: «%{quote}»" visibilities: direct: Mensaxe direutu + private: Namás siguidores + private_long: Namás los ven los perfiles siguidores public_long: Tol mundu pue velos unlisted_long: Tol mundu pue velos, mas nun apaecen nes llinies de tiempu públiques statuses_cleanup: exceptions: Esceiciones interaction_exceptions: Esceiciones basaes nes interaiciones keep_direct: Caltener los mensaxes direutos + keep_direct_hint: Nun desanicia nengún mensaxe direutu + keep_media: Caltener los artículos con elementos multimedia + keep_media_hint: Nun desanicia nengún artículu de to que contenta elementos multimedia keep_pinned: Caltener los artículos fixaos keep_polls: Caltener les encuestes + keep_polls_hint: Nun desanicia nenguna encuesta de to + keep_self_bookmark: Caltener los artículos que metieres en Marcadores + keep_self_bookmark_hint: Nun desanicia nengún artículu que metieres en Marcadores min_age: '1209600': 2 selmanes '15778476': 6 meses @@ -766,6 +869,8 @@ ast: appeal_description: Si te paez que ye un error, pues unviar una apellación al personal de %{instance}. explanation: disable: Xá nun pues usar la cuenta mas el perfil ya otros datos siguen intautos. Pues solicitar una copia de seguranza de los datos, camudar la configuración de la cuenta o desaniciar la cuenta. + silence: Pues siguir usando la cuenta mas namás vas ver los artículos de los perfiles que xá siguieres nesti sirvidor ya ye posible que se t'escluya de dalgunes funciones de descubrimientu. Por embargu, otros perfiles entá puen siguite manualmente. + suspend: Xá nun pues usar la cuenta nin se pue acceder a los datos del to perfil. Pues aniciar la sesión pa pidir una copia de seguranza de los tos datos hasta que se desanicien en 30 díes, mas vamos caltener dalgunos datos básicos pa evitar que te saltes la suspensión. reason: 'Motivu:' statuses: 'Artículos citaos:' subject: @@ -777,7 +882,7 @@ ast: suspend: Cuenta suspendida welcome: edit_profile_action: Configurar el perfil - edit_profile_step: Pues personalizar el perfil pente la xuba d'una semeya, el cambéu del nome visible y muncho más. Tamién, si lo prefieres, pues revisar los perfiles nuevos enantes de que puedan siguite. + edit_profile_step: Pues personalizar el perfil pente la xuba d'una semeya, el cambéu del nome visible ya muncho más. Tamién, si lo prefieres, pues revisar los perfiles nuevos enantes de que puedan siguite. explanation: Equí tienes dalgunos conseyos pa que comiences final_action: Comenzar a espublizar subject: Afáyate en Mastodon @@ -788,12 +893,11 @@ ast: seamless_external_login: Aniciesti la sesión pente un serviciu esternu, polo que la configuración de la contraseña ya de la direición de corréu electrónicu nun tán disponibles. signed_in_as: 'Aniciesti la sesión como:' verification: - explanation_html: 'Pues verificate como la persona propietaria de los enllaces nos metadatos del to perfil. Pa ello, el sitiu web enllaciáu ha contener un enllaz al to perfil de Mastodon. Esti enllaz ha tener l''atributu rel="me". El testu del enllaz nun importa. Equí tienes un exemplu:' verification: Verificación webauthn_credentials: create: error: Hebo un problema al amestar la llave de seguranza. Volvi tentalo. invalid_credential: La llave de seguranza nun ye válida - not_enabled: Entá nun activesti la función WebAuthn + not_enabled: Nun activesti la función WebAuthn not_supported: Esti restolador nun ye compatible coles llaves de seguranza otp_required: Pa usar les llaves de seguranza, activa primero l'autenticación en dos pasos. diff --git a/config/locales/be.yml b/config/locales/be.yml index ea5d01764c..4d8ea3df99 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -95,6 +95,7 @@ be: moderation: active: Актыўны all: Усе + disabled: Адключана pending: Чакаюць silenced: Абмежаваны suspended: Прыпынены @@ -130,8 +131,8 @@ be: removed_header_msg: Выява загалоўку %{username} выдаленая resend_confirmation: already_confirmed: Гэты карыстальнік ужо пацверджаны - send: Даслаць пацвярджальны ліст зноў - success: Ліст з пацвярджэннем паспяхова дасланы! + send: Даслаць пацвярджальную спасылку зноў + success: Ліст з пацвярджальнай спасылкай паспяхова дасланы! reset: Скінуць reset_password: Скід паролю resubscribe: Аднавіць падпіску @@ -139,6 +140,7 @@ be: search: Пошук search_same_email_domain: Іншыя карыстальнікі з такім жа даменам эл. пошты search_same_ip: Іншыя карыстальнікі з гэтым IP + security: Бяспека security_measures: only_password: Толькі пароль password_and_2fa: Пароль і 2FA @@ -295,7 +297,7 @@ be: empty: Логі не знойдзены. filter_by_action: Фільтраваць па дзеянню filter_by_user: Адфільтраваць па карыстальніку - title: Правер логі + title: Аўдыт announcements: destroyed_msg: Аб'ява паспяхова выдалена! edit: @@ -313,6 +315,7 @@ be: unpublish: Зняць з публікацыі unpublished_msg: Аб'ява паспяхова схована! updated_msg: Аб'ява паспяхова адноўлена! + critical_update_pending: Чакаецца абнаўленне custom_emojis: assign_category: Прызначыць катэгорыю by_domain: Дамен @@ -394,6 +397,15 @@ be: undo: Забараніць федэрацыю з даменам domain_blocks: add_new: Дадаць новы блок дамену + confirm_suspension: + cancel: Скасаваць + confirm: Прыпыніць + permanent_action: Адмена прыпынення не прывядзе да аднаўлення даных або зносін. + preamble_html: Вы збіраецеся прыпыніць %{domain} і яго паддамены. + remove_all_data: Гэта прывядзе да выдалення ўсяго змесціва, мультымедыя і даных профіляў з вашага сервера для ўліковых запісаў гэтага дамена. + stop_communication: Ваш сервер спыніць сувязь з гэтымі серверамі. + title: Пацвердзіць блакіроўку дамена %{domain} + undo_relationships: Гэта прывядзе да адмены любых падпісак паміж уліковымі запісамі гэтых сервераў і вашым. created_msg: Даменны блок быў апрацаваны destroyed_msg: Даменны блок быў адменены domain: Дамен @@ -443,6 +455,7 @@ be: resolve: Вызначыць дамен title: Заблакіраваць новы дамен эл. пошты no_email_domain_block_selected: Блакіроўкі даменаў эл. пошты не былі змененыя, таму што ні адзін з іх не быў выбраны + not_permitted: Забаронена resolved_dns_records_hint_html: Даменнае імя ператвараецца ў наступныя дамены MX, якія ў канчатковым выніку адказваюць за прыём электроннай пошты. Блакаванне дамена MX заблакуе рэгістрацыю з любога адраса электроннай пошты, які выкарыстоўвае той жа дамен MX, нават калі бачнае імя дамена адрозніваецца. Будзьце асцярожныя, каб не заблакіраваць асноўных пастаўшчыкоў электроннай пошты. resolved_through_html: Вызначына каля %{domain} title: Заблакаваныя паштовыя дамены @@ -493,6 +506,7 @@ be: content_policies: comment: Унутраная нататка description_html: Вы можаце вызначыць палітыку кантэнту, якая будзе прымяняцца да ўсіх уліковых запісаў гэтага дамена і любога з яго субдаменаў. + limited_federation_mode_description_html: Вы можаце выбраць ці дазволіць уваходзіць у федэрацыю з гэтым даменам. policies: reject_media: Адхіліць мультымедыя reject_reports: Адхіліць справаздачы @@ -609,11 +623,13 @@ be: assign_to_self: Прызначыць мне assigned: Прызначаны мадэратар by_target_domain: Дамен уліковага запісу, на які падаецца скарга + cancel: Скасаваць category: Катэгорыя category_description_html: Прычына паведамлення аб гэтым уліковым запісе і/або кантэнце будзе згадана ў сувязі з уліковым запісам, на які пададзена скарга comment: none: Пуста comment_description_html: 'Каб даць больш інфармацыі, %{name} напісаў:' + confirm: Пацвердзіць confirm_action: Пацвердзіць мадэрацыю супраць @%{acct} created_at: Створана delete_and_resolve: Выдаліць допісы @@ -645,14 +661,21 @@ be: statuses: Змесціва, на якое паскардзіліся statuses_description_html: Крыўднае змесціва будзе згадвацца ў зносінах з уліковым запісам, на які пададзена скарга summary: + action_preambles: + delete_html: 'Вы збіраецеся выдаліць некаторыя з допісаў @%{acct}. Гэта будуць:' + mark_as_sensitive_html: 'Вы збіраецеся пазначыць некаторыя з допісаў @%{acct} як уражальныя. Гэта будуць:' + silence_html: 'Вы збіраецеся абмежаваць уліковы запіс @%{acct}. Гэта будзе:' + suspend_html: 'Вы збіраецеся прыпыніць уліковы запіс @%{acct}. Гэта будзе:' actions: delete_html: Выдаліць абразлівы допіс mark_as_sensitive_html: Пазначыць медыя абразлівага допіса як далікатнае + silence_html: Значна абмежаваць ахоп @%{acct}, зрабіўшы профіль і змесціва бачнымі толькі для людзей, якія ўжо падпісаныя, альбо шукае яго ўручную suspend_html: Прыпыніць @%{acct}, зрабіць профіль і змесціва недаступным і не даваць магчымасці ўзаемадзейнічаць з імі close_report: 'Пазначыць скаргу #%{id} як вырашаную' close_reports_html: Адзначыць усе скаргі супраць @%{acct} як вырашаныя delete_data_html: Выдаліць профіль @%{acct} і змесціва праз 30 дзён, калі тым часам гэтае дзеянне не будзе адменена preview_preamble_html: "@%{acct} атрымае папярэджанне наступнага зместу:" + record_strike_html: Зарэгістраваць папярэджанне @%{acct}, каб дапамагчы вам эскаліраваць наступныя парушэнні з боку таго ж уліковага запісу send_email_html: Адправіць @%{acct} папярэджанне па электроннай пошце warning_placeholder: Неабавязковае дадатковае абгрунтаванне мадэрацыі. target_origin: Крыніца уліковага запісу на які пададзена скарга @@ -746,6 +769,9 @@ be: branding: preamble: Брэндынг вашага сервера адрознівае яго ад іншых сервераў у сетцы. Гэтая інфармацыя можа адлюстроўвацца ў розных асяроддзях, напрыклад, у вэб-інтэрфейсе Mastodon, уласных праграмах, у папярэднім праглядзе спасылак на іншых вэб-сайтах і ў праграмах абмену паведамленнямі і гэтак далей. Па гэтай прычыне лепш трымаць гэтую інфармацыю яснай, кароткай і сціслай. title: Брэндынг + captcha_enabled: + desc_html: Гэта функцыянальнасць залежыць ад знешніх скрыптоў hCaptcha, што можа быць праблемай бяспекі і прыватнасці. Акрамя таго, гэта можа зрабіць працэс рэгістрацыі значна менш даступным для некаторых людзей, асабліва інвалідаў. Па гэтых прычынах, калі ласка, разгледзьце альтэрнатыўныя меры, такія як рэгістрацыя на аснове зацвярджэння або запрашэння. + title: Патрабаваць ад новых карыстальнікаў рашэння CAPTCHA для пацверджання іх уліковага запісу content_retention: preamble: Кантралюйце, як створаны карыстальнікамі кантэнт захоўваецца ў Mastodon. title: Утрыманне кантэнту @@ -773,10 +799,27 @@ be: approved: Для рэгістрацыі патрабуецца пацвярджэнне none: Нікому не магчыма зарэгістравацца open: Любому магчыма зарэгістравацца + security: + authorized_fetch: Патрабаваць аўтэнтыфікацыю ад федэратыўных сервераў + authorized_fetch_hint: Патрабаванне аўтэнтыфікацыі ад федэратыўных сервераў дазваляе больш строга выконваць блакіроўкі як на ўзроўні карыстача, так і на ўзроўні сервера. Аднак пры гэтым зніжаецца прадукцыйнасць, памяншаецца ахоп вашых адказаў на допісы і могуць узнікнуць праблемы сумяшчальнасці з некаторымі федэратыўнымі сэрвісамі. Акрамя таго, гэта не перашкодзіць атрымліваць вашыя публічныя допісы і ўліковыя запісы. + authorized_fetch_overridden_hint: Вы не можаце змяніць гэты параметр, паколькі ён перавызначаны зменнай асяроддзя. + federation_authentication: Патрабаванне аўтэнтыфікацыі ад федэратыўных сэрвісаў title: Налады сервера site_uploads: delete: Выдаліць запампаваны файл destroyed_msg: Загрузка сайту паспяхова выдалена! + software_updates: + critical_update: Крытычна - зрабіце абнаўленне як мага хутчэй + description: Рэкамендуецца падтрымліваць усталёўку Mastodon у актуальным стане, каб карыстацца апошнімі выпраўленнямі і магчымасцямі. Акрамя таго, часам вельмі важна своечасова абнаўляць Mastodon, каб пазбегнуць праблем з бяспекай. Па гэтых прычынах Mastodon правярае наяўнасць абнаўленняў кожныя 30 хвілін і паведамляе вам пра гэта ў адпаведнасці з вашымі наладамі апавяшчэнняў па электроннай пошце. + documentation_link: Даведацца больш + release_notes: Журнал змен + title: Даступныя абнаўленні + type: Тып + types: + major: Буйны рэліз + minor: Малы рэліз + patch: Патч-рэліз — выпраўленні памылак і простыя ва ўжыванні змены + version: Версія statuses: account: Аўтар application: Праграма @@ -813,9 +856,24 @@ be: suspend: Уліковы запіс %{target} выключаны %{name} appeal_approved: Абскарджана appeal_pending: Апеляцыя разглядаецца + appeal_rejected: Абскарджанне адхілена system_checks: database_schema_check: message_html: Ёсць незавершаныя міграцыі базы дадзеных. Калі ласка, запусціце іх, каб пераканацца, што дадатак паводзіць сябе належным чынам + elasticsearch_health_red: + message_html: Кластар Elasticsearch нездаровы (чырвоны статус), функцыі пошуку недаступныя + elasticsearch_health_yellow: + message_html: Кластар Elasticsearch нездаровы (жоўты статус), магчыма, неабходна высветліць прычыну + elasticsearch_index_mismatch: + message_html: Супастаўленне індэксаў Elasticsearch састарэла. Калі ласка, выканайце каманду tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Падрабязней у дакументацыі + message_html: Ваш кластар Elasticsearch мае больш за адзін вузел, але Mastodon не наладжаны на іх выкарыстанне. + elasticsearch_preset_single_node: + action: Падрабязней у дакументацыі + message_html: Ваш кластар Elasticsearch мае толькі адзін вузел, ES_PRESET варта ўсталяваць у значэнне single_node_cluster. + elasticsearch_reset_chewy: + message_html: Ваш сістэмны індэкс Elasticsearch састарэлы з-за змены налад. Для яго абнаўлення выканайце каманду tootctl search deploy --reset-chewy. elasticsearch_running_check: message_html: Немагчыма падключыцца да Elasticsearch. Калі ласка, праверце, што ён запушчаны, або адключыце паўнатэкставы пошук elasticsearch_version_check: @@ -826,6 +884,18 @@ be: message_html: Вы не вызначылі ніякіх правілаў сервера. sidekiq_process_check: message_html: Не працуе працэс Sidekiq для %{value} чаргі. Калі ласка праверце вашу канфігурацыю Sidekiq + software_version_critical_check: + action: Прагледзець даступныя абнаўленні + message_html: Даступна крытычнае абнаўленне Mastodon, калі ласка, зрабіце абнаўленне як мага хутчэй. + software_version_patch_check: + action: Прагледзець даступныя абнаўленні + message_html: Даступна абнаўленне Mastodon з выпраўленнем памылак. + upload_check_privacy_error: + action: Для падрабязнасцей націсніце тут + message_html: "Ваш сервер не наладжаны. Прыватнасць карыстальнікаў пад пагрозай." + upload_check_privacy_error_object_storage: + action: Для падрабязнасцей націсніце тут + message_html: "Ваша сховішча не наладжана. Прыватнасць карыстальнікаў пад пагрозай." tags: review: Стан праверкі updated_msg: Налады хэштэгаў паспяхова змененыя @@ -850,6 +920,7 @@ be: other: Абагулілі %{count} чалавек за апошні тыдзень title: Актуальныя спасылкі usage_comparison: Выкарыстоўвалася %{today} разоў сёння, у параўнанні з %{yesterday} учора + not_allowed_to_trend: Забаронена выходзіць у актуальныя only_allowed: Толькі дазволенае pending_review: Чакае праверкі preview_card_providers: @@ -940,6 +1011,9 @@ be: body: "%{target} абскарджвае рашэнне мадэратара %{action_taken_by} ад %{date}, якая была %{type}. Яны напісалі:" next_steps: Вы можаце ўхваліць апеляцыю каб адмяніць рашэнне мадэратараў ці ігнараваць яе. subject: "%{username} абскарджвае рашэнне мадэратараў на %{instance}" + new_critical_software_updates: + body: Выпушчаны новыя крытычныя версіі Mastodon, неабходна абнавіцца як мага хутчэй! + subject: Даступны крытычныя абнаўленні Mastodon для %{instance}! new_pending_account: body: Падрабязнасці новага ўліковага запісу прыведзены ніжэй. Вы можаце зацвердзіць або адхіліць гэтую заяўку. subject: Новы ўліковы запіс для разгляду ў %{instance} (%{username}) @@ -947,6 +1021,9 @@ be: body: "%{reporter} паскардзіўся на %{target}" body_remote: Нехта з %{domain} паскардзіўся на %{target} subject: Новая скарга на %{instance} (#%{id}) + new_software_updates: + body: Выйшлі новыя версіі Mastodon, магчыма, вам варта абнавіцца! + subject: Новыя версіі Mastodon даступныя для %{instance}! new_trends: body: 'Гэтыя элементы трэба праверыць, перш чым публікаваць:' new_trending_links: @@ -976,24 +1053,28 @@ be: guide_link: https://be.crowdin.com/project/mastodon/be guide_link_text: Кожны можа зрабіць унёсак. sensitive_content: Далікатны змест - toot_layout: Макет допісу application_mailer: notification_preferences: Змяніць налады эл. пошты salutation: "%{name}," settings: 'Змяніць налады эл. пошты: %{link}' + unsubscribe: Адпісацца view: 'Паглядзець:' view_profile: Паглядзець профіль view_status: Паглядзець допіс applications: created: Праграма паспяхова створана destroyed: Праграма паспяхова выдалена + logout: Выйсці regenerate_token: Стварыць новы токен доступу token_regenerated: Новы токен доступу паспяхова створаны warning: Будзьце вельмі асцярожныя з гэтымі данымі. Ніколі нікому не паведамляйце іх! your_token: Ваш токен доступу auth: apply_for_account: Пакінуць заяўку - change_password: Пароль + captcha_confirmation: + help_html: Калі ў вас узніклі праблемы з вырашэннем CAPTCHA, вы можаце звязацца з намі праз %{email}, каб мы вам дапамаглі. + hint_html: Засталася яшчэ адна рэч! Каб не дапусціць спаму, нам трэба пацвердзіць, што вы чалавек. Разгадайце CAPTCHA ніжэй і націсніце «Працягнуць». + title: Праверка бяспекі confirmations: wrong_email_hint: Калі гэты адрас электроннай пошты памылковы, вы можаце змяніць яго ў наладах уліковага запісу. delete_account: Выдаліць уліковы запіс @@ -1002,7 +1083,7 @@ be: prefix_invited_by_user: "@%{name} запрашае вас далучыцца да гэтага сервера ў Mastodon!" prefix_sign_up: Зарэгістравацца ў Mastodon сёння! suffix: Маючы ўліковы запіс, вы зможаце падпісвацца на іншых людзей, дзяліцца навінамі і абменьвацца паведамленнямі з карыстальнікамі з любога сервера Mastodon і шмат што яшчэ! - didnt_get_confirmation: Не атрымалі інструкцыю пацвярджэння? + didnt_get_confirmation: Не атрымалі пацвярджальную спасылку? dont_have_your_security_key: Не маеце ключа бяспекі? forgot_password: Забылі свой пароль? invalid_reset_password_token: Токен для скідвання пароля несапраўдны або састарэў. Зрабіце запыт на новы. @@ -1015,26 +1096,39 @@ be: migrate_account_html: Калі вы хочаце перанакіраваць гэты ўліковы запіс на іншы, то можаце наладзіць яго тут. or_log_in_with: Або ўвайсці з дапамогай privacy_policy_agreement_html: Я азнаёміўся і пагаджаюся з палітыкай канфідэнцыйнасці + progress: + confirm: Пацвердзіць email + details: Вашы дадзеныя + review: Наш водгук + rules: Прыняць правілы providers: cas: CAS saml: SAML register: Зарэгістравацца registration_closed: "%{instance} больш не прымае новых удзельнікаў" - resend_confirmation: Адправіць інструкцыю пацвярджэння зноў + resend_confirmation: Даслаць пацвярджальную спасылку зноў reset_password: Скінуць пароль rules: + accept: Прыняць + back: Назад + invited_by: 'Вы можаце далучыцца да %{domain} дзякуючы запрашэнню, якое вы атрымалі ад:' preamble: Правілы вызначаныя мадэратарамі дамена %{domain}. + preamble_invited: Перш чым працягнуць, азнаёмцеся з асноўнымі правіламі, усталяванымі мадэратарамі %{domain}. title: Некалькі базавых правілаў. + title_invited: Вас запрасілі. security: Бяспека set_new_password: Прызначыць новы пароль setup: - email_below_hint_html: Калі прыведзены ніжэй адрас эл. пошты няправільны, вы можаце змяніць яго тут і атрымаць новае пацвярджэнне па эл. пошце. - email_settings_hint_html: Ліст з пацвярджэннем быў адпраўлены на %{email}. Калі гэты адрас эл. пошты няправільны, вы можаце змяніць яго ў наладах уліковага запісу. - title: Налады + email_below_hint_html: Праверце папку са спамам або зрабіце новы запыт. Вы можаце выправіць свой email, калі ён няправільны. + email_settings_hint_html: Націсніце на спасылку, якую мы адправілі, каб спраўдзіць %{email}. Мы вас пачакаем тут. + link_not_received: Не атрымалі спасылку? + new_confirmation_instructions_sent: Праз некалькі хвілін вы атрымаеце новы ліст на email са спасылкай для пацверджання! + title: Праверце вашу пошту sign_in: preamble_html: Уваход з уліковымі дадзенымі %{domain}. Калі ваш уліковы запіс знаходзіцца на іншым серверы, у вас не атрымаецца ўвайсці тут. title: Уваход у %{domain} sign_up: + manual_review: Рэгістрацыі на %{domain} праходзяць ручную праверку нашымі мадэратарамі. Каб дапамагчы нам апрацаваць вашу рэгістрацыю, напішыце крыху пра сябе і чаму вы хочаце мець уліковы запіс на %{domain}. preamble: Маючы ўліковы запіс на гэтым серверы Mastodon, вы будзеце мець магчымасць падпісацца на кожнага чалавека ў сетцы, незалежна ад таго, на якім серверы размешчаны ягоны ўліковы запіс. title: Наладзьма вас на %{domain}. status: @@ -1046,18 +1140,6 @@ be: view_strikes: Праглядзець мінулыя папярэджанні для вашага ўліковага запісу too_fast: Форма адпраўлена занадта хутка, паспрабуйце яшчэ раз. use_security_key: Выкарыстаеце ключ бяспекі - authorize_follow: - already_following: Вы ўжо падпісаныя на гэты ўліковы запіс - already_requested: Вы ўжо адправілі запыт на гэты ўліковы запіс - error: На жаль, падчас пошуку аддаленага ўліковага запісу здарылася памылка - follow: Падпісацца - follow_request: 'Вы адправілі запыт на падпіску:' - following: 'Поспех! Цяпер вы падпісаны на:' - post_follow: - close: Або, вы можаце проста закрыць гэтае акно. - return: Паказаць профіль карыстальніка - web: Перайсці ў вэб-версію - title: Падпісацца на %{acct} challenge: confirm: Працягнуць hint_html: "Парада: Мы не будзем запытваць ваш пароль зноўку на працягу наступнай гадзіны." @@ -1134,6 +1216,10 @@ be: your_appeal_rejected: Ваша абскарджанне было адхілена domain_validator: invalid_domain: не з'яўляецца сапраўдным даменным імем + edit_profile: + basic_information: Асноўная інфармацыя + hint_html: "Наладзьце тое, што людзі будуць бачыць у вашым профілі і побач з вашымі паведамленнямі. Іншыя людзі з большай верагоднасцю будуць сачыць і ўзаемадзейнічаць з вамі, калі ў вас ёсць запоўнены профіль і фота профілю." + other: Іншае errors: '400': Запыт, які вы адправілі, памылковы або няправільны. '403': У вас няма дазволу на прагляд гэтай старонкі. @@ -1220,8 +1306,6 @@ be: index: hint: Гэты фільтр прымяняецца для выбару асобных допісаў незалежна ад іншых крытэрыяў. Вы можаце дадаць больш допісаў у гэты фільтр з вэб-інтэрфейсу. title: Адфільтраваныя допісы - footer: - trending_now: Актуальнае generic: all: Усе all_items_on_page_selected_html: @@ -1234,7 +1318,9 @@ be: many: Абраныя ўсе %{count} элементаў, якія адпавядаюць вашаму пошуку. one: Абраны %{count} элемент, які адпавядае вашаму пошуку. other: Абраныя %{count} элементаў, якія адпавядаюць вашаму пошуку. + cancel: Скасаваць changes_saved_msg: Змены паспяхова захаваны! + confirm: Пацвердзіць copy: Скапіяваць delete: Выдаліць deselect: Зняць вылучэнне з усіх @@ -1252,24 +1338,62 @@ be: many: Штосьці пакуль не зусім правільна! Калі ласка, праглядзіце %{count} памылак ніжэй one: Штосьці пакуль не зусім правільна! Калі ласка, праглядзіце памылку ніжэй other: Штосьці пакуль не зусім правільна! Калі ласка, праглядзіце %{count} памылак ніжэй - html_validator: - invalid_markup: 'змяшчае несапраўдную разметку HTML: %{error}' imports: errors: + empty: Пусты CSV файл + incompatible_type: Несумяшчальны з выбраным тыпам імпарту invalid_csv_file: 'Несапраўдны файл CSV. Памылка: %{error}' over_rows_processing_limit: колькасць радкоў большая за %{count} + too_large: Файл занадта вялікі + failures: Няўдала + imported: Імпартавана + mismatched_types_warning: Здаецца, вы выбралі няправільны тып для гэтага імпарту, праверце яшчэ раз. modes: merge: Аб'яднаць merge_long: Захаваць існуючыя запісы і дадаць новыя overwrite: Перазапісаць overwrite_long: Замяніць бягучыя запісы на новыя + overwrite_preambles: + blocking_html: Вы збіраецеся замяніць свой спіс блакіровак на %{total_items} уліковых запісаў з файла %{filename}. + bookmarks_html: Вы збіраецеся замяніць свае закладкі на %{total_items} допісаў з файла %{filename}. + domain_blocking_html: Вы збіраецеся замяніць свой спіс блакіроўкі даменаў на %{total_items} даменаў з файла %{filename}. + following_html: Вы збіраецеся падпісацца на %{total_items} уліковых запісаў з файла %{filename} і адпісацца ад усіх іншых карыстальнікаў. + lists_html: Вы збіраецеся замяніць свае спісы змесцівам з %{filename}. Да %{total_items} уліковых запісаў будуць дададзены ў новыя спісы. + muting_html: Вы збіраецеся замяніць свой спіс ігнараваных уліковых запісаў на %{total_items} уліковых запісаў з файла %{filename}. + preambles: + blocking_html: Вы збіраецеся заблакіраваць да %{total_items} уліковых запісаў з файла%{filename}. + bookmarks_html: Вы збіраецеся дадаць да %{total_items} паведамленняў з файла %{filename} у вашы закладкі. + domain_blocking_html: Вы збіраецеся заблакіраваць да %{total_items} даменаў з файла %{filename}. + following_html: Вы збіраецеся падпісацца на%{total_items} уліковых запісаў з файла %{filename}. + lists_html: Вы збіраецеся дадаць да %{total_items} уліковых запісаў з %{filename} у вашы спісы. Новыя спісы будуць створаны, калі іх няма. + muting_html: Вы збіраецеся ігнараваць да %{total_items} уліковых запісаў з файла %{filename}. preface: Вы можаце імпартаваць даныя, экспартаваныя вамі з іншага сервера, напрыклад, спіс людзей, на якіх вы падпісаны або якіх блакуеце. + recent_imports: Нядаўнія імпарты + states: + finished: Завершана + in_progress: Выконваецца + scheduled: Запланавана + unconfirmed: Непацверджана + status: Стан success: Вашы даныя паспяхова запампаваныя і будуць неўзабаве апрацаваны + time_started: Пачатак + titles: + blocking: Імпарт заблакіраваных уліковых запісаў + bookmarks: Імпарт закладак + domain_blocking: Імпарт заблакіраваных даменаў + following: Імпарт падпісаных уліковых запісаў + lists: Імпартаванне спісаў + muting: Імпарт ігнараваных уліковых запісаў + type: Тып імпарту + type_groups: + constructive: Падпіскі і закладкі + destructive: Блакіроўкі і ігнараванні types: blocking: Спіс заблакіраваных bookmarks: Закладкі domain_blocking: Спіс заблакіраваных даменаў following: Падпіскі + lists: Спісы muting: Спіс ігнаравання upload: Запампаваць invites: @@ -1310,6 +1434,21 @@ be: failed_sign_in_html: Няўдалая спроба ўваходу праз %{method} з %{ip} (%{browser}) successful_sign_in_html: Паспяховы ўваход праз %{method} з %{ip} (%{browser}) title: Гісторыя ўваходаў + mail_subscriptions: + unsubscribe: + action: Так, адпісацца + complete: Адпісаны + confirmation_html: Вы ўпэўнены, што жадаеце адмовіцца ад %{type} з Mastodon на дамене %{domain} на вашу электронную пошту %{email}? Вы заўсёды можаце паўторна падпісацца у наладах апавяшчэнняў па электроннай пошце. + emails: + notification_emails: + favourite: апавяшчэнні на пошту пра упадабанае + follow: апавяшчэнні на пошту пра падпіскі + follow_request: апавяшчэнні на пошту пра запыты на падпіску + mention: апавяшчэнні на пошту пра згадванні + reblog: апавяшчэнні на пошту пра пашырэнні + resubscribe_html: Калі вы адмовіліся ад падпіскі памылкова, вы можаце зноў падпісацца ў наладах апавяшчэнняў па электроннай пошце. + success_html: Вы больш не будзеце атрымліваць %{type} на сваю электронную пошту %{email} ад Mastodon на дамене %{domain}. + title: Адпісацца media_attachments: validations: images_and_video: Немагчыма прымацаваць відэа да допісу, які ўжо змяшчае выявы @@ -1389,6 +1528,7 @@ be: update: subject: "%{name} адрэдагаваў допіс" notifications: + administration_emails: Апавяшчэнні эл. пошты для адміністратара email_events: Падзеі для апавяшчэнняў эл. пошты email_events_hint: 'Выберыце падзеі, аб якіх вы хочаце атрымліваць апавяшчэнні:' other_settings: Іншыя налады апавяшчэнняў @@ -1425,12 +1565,22 @@ be: expired: Апытанне ўжо скончана invalid_choice: Абраны варыянт апытання не існуе over_character_limit: не можа быць даўжэй за %{max} сімвалаў кожны + self_vote: Вы не можаце галасаваць ва ўласных апытаннях too_few_options: павінна быць болей за адзін варыянт too_many_options: колькасць варыянтаў не можа перавышаць %{max} preferences: other: Іншае posting_defaults: Публікаваць па змаўчанні public_timelines: Публічныя стужкі + privacy: + hint_html: "Наладзьце тое, якім чынам ваш профіль і вашы паведамленні могуць быць знойдзеныя. Розныя функцыі ў Mastodon могуць дапамагчы вам ахапіць шырэйшую аўдыторыю. Удзяліце час гэтым наладам, каб пераканацца, што яны падыходзяць вам." + privacy: Прыватнасць + privacy_hint_html: Кантралюйце, колькі інфармацыі вы хочаце раскрыць для карысці іншых. Людзі адкрываюць для сябе цікавыя профілі і класныя праграмы, праглядаючы допісы іншых людзей і даведваючыся, з якіх праграм яны пішуць, але, магчыма, вы аддаеце перавагу трымаць гэта ў таямніцы. + reach: Дасяжнасць + reach_hint_html: Кантралюйце, ці вы хочаце, каб пра вас даведваліся і на вас падпісваліся новыя людзі. Ці вы хочаце, каб вашы паведамленні з'яўляліся на старонцы "агляд"? Ці вы хочаце, каб іншыя людзі бачылі вас у сваіх рэкамендацыях? Ці вы хочаце аўтаматычна прымаць усіх новых падпісчыкаў або мець магчымасць дэталёва кантраляваць кожнага з іх? + search: Пошук + search_hint_html: Кантралюйце тое, якім чынам вас можна знайсці. Ці хочаце вы, каб людзі знаходзілі вас па тым, пра што вы публічна апублікавалі? Ці вы хочаце, каб людзі за межамі Mastodon знаходзілі ваш профіль пры пошуку ў Інтэрнэце? Трэба памятаць, што поўнае выключэнне з усіх пошукавых сістэм не можа быць гарантавана для публічнай інфармацыі. + title: Прыватнасць і дасяжнасць privacy_policy: title: Палітыка канфідэнцыйнасці reactions: @@ -1443,6 +1593,7 @@ be: confirm_remove_selected_followers: Вы ўпэўнены, што жадаеце выдаліць выбраных падпісчыкаў? confirm_remove_selected_follows: Вы ўпэўнены, што жадаеце выдаліць выбраныя падпіскі? dormant: Занядбаны + follow_failure: Вы не можаце падпісацца на некаторыя акаўнты. follow_selected_followers: Падпісацца на выбраных падпісчыкаў followers: Падпісчыкі following: Падпісаны @@ -1482,6 +1633,7 @@ be: electron: Electron firefox: Firefox generic: Невядомы браўзер + huawei_browser: Браўзер Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1491,6 +1643,7 @@ be: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Невядомы браўзер weibo: Weibo current_session: Бягучая сесія description: "%{browser} на %{platform}" @@ -1503,9 +1656,10 @@ be: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: невядомай платформе + unknown_platform: Невядомая платформа windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1532,7 +1686,7 @@ be: preferences: Налады profile: Профіль relationships: Падпіскі і падпісчыкі - statuses_cleanup: Аўтаматычнае выдаленне допісаў + statuses_cleanup: Аўтавыдаленне допісаў strikes: Папярэджанні мадэратараў two_factor_authentication: Двухфактарная аўтэнтыфікацыя webauthn_authentication: Ключы бяспекі @@ -1588,7 +1742,6 @@ be: show_newer: Паказаць навейшыя show_older: Паказаць старэйшыя show_thread: Паказаць ланцуг - sign_in_to_participate: Зарэгіструйцеся каб удзельнічаць у абмеркаванні title: '%{name}: "%{quote}"' visibilities: direct: Асабіста @@ -1634,8 +1787,6 @@ be: min_reblogs: Захаваць допісы, якія пашырылі хаця б min_reblogs_hint: Не выдаляе вашыя допісы, якія пашырыла прынамсі вызначаная колькасць людзей. Пакіньце гэтае поле пустым, каб допісы выдаляліся незалежна ад гэтай колькасці stream_entries: - pinned: Замацаваны допіс - reblogged: пашыраны sensitive_content: Далікатны змест strikes: errors: @@ -1651,6 +1802,11 @@ be: default: "%d.%m.%Y %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Сервер перавысіў квоту на выкарыстанне службы перакладу. + too_many_requests: Занадта шмат запытаў у сервіс перакладаў. two_factor_authentication: add: Дадаць disable: Адключыць 2FA @@ -1730,13 +1886,18 @@ be: title: Рады вітаць вас, %{name}! users: follow_limit_reached: Вы не можаце падпісацца на большую колькасць людзей чым %{limit} + go_to_sso_account_settings: Перайдзіце ў налады ідэнтыфікацыі вашага ўліковага запісу invalid_otp_token: Няправільны код двухфактарнай аўтэнтыфікацыі otp_lost_help_html: Калі вы страцілі доступ да абодвух, вы можаце скарыстацца %{email} seamless_external_login: Вы ўвайшлі праз знешні сэрвіс, таму налады пароля і эл. пошты недаступныя. signed_in_as: 'Увайшлі як:' verification: - explanation_html: 'Вы можаце пацвердзіць сябе як уладальніка спасылак у метададзеных вашага профілю. Для гэтага спасылка на вэб-сайт павінна ўтрымліваць спасылку на ваш профіль Mastodon. Зваротная спасылка павінна мець атрыбут rel="me". Тэкставы змест спасылкі не мае значэння. Вось прыклад:' + extra_instructions_html: Парада: спасылка на вашым сайце можа быць нябачнай. Важнай часткай з'яўляецца rel="me", якая прадухіляе імперсанацыю на сайтах з карыстальніцкім кантэнтам. Вы нават можаце выкарыстоўваць тэг link у загалоўку старонкі замест a, але HTML павінен быць даступны без выканання JavaScript. + here_is_how: Як гэта зрабіць + hint_html: "Пацвярджэнне асобы на Mastodon даступна кожнаму. Заснавана на адкрытых вэб-стандартах, зараз і заўсёды бясплатна. Усё, што вам трэба, гэта асабісты сайт, па якім людзі вас пазнаюць. Калі вы спасылаецеся на гэты вэб-сайт са свайго профілю, мы правяраем, што вэб-сайт у сваю чаргу спасылаецца на ваш профіль, і паказваем на ім візуальны індыкатар." + instructions_html: Скапіруйце прыведзены ніжэй код і ўстаўце ў HTML вашага сайта. Затым дадайце адрас вашага сайта ў адно з дадатковых палёў вашага профілю на ўкладцы «рэдагаваць профіль» і захавайце змены. verification: Верыфікацыя + verified_links: Вашыя правераныя спасылкі webauthn_credentials: add: Дадаць новы ключ бяспекі create: diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 9127790bc5..b1d91875b3 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -47,7 +47,7 @@ bg: change_role: changed_msg: Успешно променена роля! label: Промяна на ролята - no_role: Няма роля + no_role: Без роля title: Промяна на ролята за %{username} confirm: Потвърждаване confirmed: Потвърдено @@ -61,7 +61,7 @@ bg: disable_sign_in_token_auth: Изключване на удостоверяването с маркер по имейл disable_two_factor_authentication: Изключване на 2факт. удостов. disabled: Замразено - display_name: Показвано име + display_name: Име на показ domain: Домейн edit: Редактиране email: Имейл @@ -91,6 +91,7 @@ bg: moderation: active: Дейно all: Всичко + disabled: Изключено pending: Чака silenced: Ограничено suspended: Спряно @@ -98,13 +99,13 @@ bg: moderation_notes: Бележки за модериране most_recent_activity: Последна дейност most_recent_ip: Последен IP - no_account_selected: Нито един акаунт не е променен, тъй като нито един не е избран + no_account_selected: Нито променени акаунти, тъй като нито един не е бил избран no_limits_imposed: Няма наложени ограничения no_role_assigned: Няма поставена роля not_subscribed: Без абонамент - pending: Изчаква преглед + pending: Чака се преглед perform_full_suspension: Спиране - previous_strikes: Предишни нарушения + previous_strikes: Предишни предупреждения previous_strikes_description_html: one: Този акаунт има едно нарушение. other: Този акунт има %{count} нарушения. @@ -124,8 +125,8 @@ bg: removed_header_msg: Успешно премахнат образ на заглавката на %{username} resend_confirmation: already_confirmed: Потребителят вече е потвърден - send: Повторно изпращане на имейл за потвърждение - success: Успешно изпратено е-писмо за потвърждение! + send: Изпращане пак на връзка за потвърждение + success: Успешно изпратена връзка за потвърждение! reset: Нулиране reset_password: Нулиране на паролата resubscribe: Абониране пак @@ -133,6 +134,7 @@ bg: search: Търсене search_same_email_domain: Други потребители със същия домейн за имейл search_same_ip: Други потребители със същия IP + security: Сигурност security_measures: only_password: Само парола password_and_2fa: Парола и двуфакторно удостоверяване @@ -229,7 +231,7 @@ bg: actions: approve_appeal_html: "%{name} одобри обжалването на решение за модериране от %{target}" approve_user_html: "%{name} одобри регистрирането от %{target}" - assigned_to_self_report_html: "%{name} назначете доклада %{target} на себе си" + assigned_to_self_report_html: "%{name} възложи на себе си доклад %{target}" change_email_user_html: "%{name} промени адреса на имейла на потребителя %{target}" change_role_user_html: "%{name} промени ролята на %{target}" confirm_user_html: "%{name} потвърди адреса на имейла на потребителя %{target}" @@ -307,6 +309,7 @@ bg: unpublish: Без публикуване unpublished_msg: Успешно скрито оповестяване! updated_msg: Успешно осъвременено оповестяване! + critical_update_pending: Чака се критично обновяване custom_emojis: assign_category: Категоризиране by_domain: Домейн @@ -330,7 +333,7 @@ bg: new: title: Добавяне на ново потребителско емоджи no_emoji_selected: Нито едно емоджи не е променено, тъй като нито едно не е избрано - not_permitted: Нямате право да извършвате това действие + not_permitted: Нямате право да извършвате действието overwrite: Презаписване shortcode: Кратък код shortcode_hint: Поне 2 символа, само азбучно-цифрови символи и долни черти @@ -372,14 +375,23 @@ bg: empty: Няма намерени обжалвания. title: Жалби domain_allows: - add_new: Позволявам федерацията с домейна - created_msg: Домейнът е успешно позволен за федерацията + add_new: Позволявам федериране с домейна + created_msg: Успешно позволен домейн за федерацията destroyed_msg: Домейнът е забранен от федерацията export: Износ import: Внос undo: Забрана на федерацията с домейна domain_blocks: add_new: Добавяне на ново блокиране за домейна + confirm_suspension: + cancel: Отказ + confirm: Спиране + permanent_action: Отменянето на спирането няма да възстанови никакви данни или отношения. + preamble_html: На път сте да спрете %{domain} и поддомейните му. + remove_all_data: Това ще премахне всичкото съдържание, мултимедия, и данни на профила за акаунтите на този домейн от сървъра ви. + stop_communication: Вашият сървър ще спре да общува с тези сървъри. + title: Потвърждаване на блокирането на домейна за %{domain} + undo_relationships: Това ще отмени всякакви отношения за последване между акаунтите на тези сървъри и вашия. created_msg: Блокирането на домейна се обработва destroyed_msg: Блокирането на домейна е отменено domain: Домейн @@ -402,7 +414,7 @@ bg: obfuscate: Замъгляване на името на домейна obfuscate_hint: Частично замъгляване на името на домейна в списъка, ако е включено рекламирането на списъка с ограничения на домейни private_comment: Личен коментар - private_comment_hint: Коментирането за това ограничение на домейна за вътрешна употреба от модераторите. + private_comment_hint: Коментирането за това ограничение на домейна е за вътрешна употреба от модераторите. public_comment: Публичен коментар public_comment_hint: Оставяне на коментар за ограничението на домейна за широката публика, ако рекламирането на списъка с ограниченията на домейни е включено. reject_media: Отхвърляне на мултимедийните файлове @@ -427,12 +439,13 @@ bg: resolve: Преобразуване на домейна title: Блокиране на нов домейн на имейл no_email_domain_block_selected: Няма промяна, тъй като няма избрани блокирания на имейл домейн + not_permitted: Няма позволение resolved_dns_records_hint_html: Името на домейна се преобразува към следните MX домейни, които са основно отговорни за получаване на имейл. Блокирането на MX домейн блокира записването от всеки имейл, използващ същия MX домейн, дори видимото име на домейна да е различно. Бъдете внимателни и не блокирайте често-срещани доставчици на имейл resolved_through_html: Преобразувано чрез %{domain} title: Блокирани домейни на имейл export_domain_allows: new: - title: Импортиране на позволенията на домейни + title: Внасяне на позволенията на домейни no_file: Няма избран файл export_domain_blocks: import: @@ -441,6 +454,7 @@ bg: private_comment_description_html: 'За по-лесно проследяване откъде идват внесените блокирания, те ще се създадат със следния личен коментар: %{comment}' private_comment_template: Внесено от %{source} на %{date} title: Внос на блокирания на домейни + invalid_domain_block: 'Едно или повече блокирания на домейн са прескочени поради следнате грешки: %{error}' new: title: Внос на блокирания на домейни no_file: Няма избран файл @@ -472,6 +486,7 @@ bg: content_policies: comment: Вътрешна бележка description_html: Може да определите политиките за съдържание, които ще се приложат към всички акаунти от този домейн и всеки от поддомейните му. + limited_federation_mode_description_html: Може да избирате дали да позволите федарацията с този домейн. policies: reject_media: Отхвърляне на мултимедия reject_reports: Отхвърляне на докладите @@ -584,11 +599,14 @@ bg: assign_to_self: Назначаване на мен assigned: Назначен модератор by_target_domain: Домейн на докладвания акаунт + cancel: Отказ category: Категория category_description_html: Причината, поради която акаунтът и/или съдържанието е докладвано ще се цитира в комуникацията с докладвания акаунт comment: none: Нищо comment_description_html: 'За да предостави повече информация, %{name} написа:' + confirm: Потвърждаване + confirm_action: Потвърждаване на модераторско действие срещу @%{acct} created_at: Докладвано delete_and_resolve: Изтриване на публикациите forwarded: Препратено @@ -605,6 +623,7 @@ bg: placeholder: Опишете какви действия са били предприети или всякакви други свързани нови неща... title: Бележки notes_description_html: Прегледайте и оставете бележки за други модератори и за вас самите след време + processed_msg: Доклад №%{id} успешно обработен quick_actions_description_html: 'Предприемете бързо действие или превъртете надолу, за да видите докладваното съдържание:' remote_user_placeholder: отдалеченият потребител от %{instance} reopen: Отваряне пак на доклад @@ -616,10 +635,29 @@ bg: skip_to_actions: Прескок към действия status: Състояние statuses: Докладвано съдържание - statuses_description_html: Непристойно съдържание ще бъде цитирано в комуникацията с докладвания акаунт + statuses_description_html: Обидно съдържание ще се цитира в общуването с докладвания акаунт + summary: + action_preambles: + delete_html: 'На път сте да премахнете някои от публикациите на @%{acct}. Това ще:' + mark_as_sensitive_html: 'На път сте да означите някои от публикациите на @%{acct} като деликатни. Това ще:' + silence_html: 'На път сте да ограничите акаунта на @%{acct}. Това ще:' + suspend_html: 'На път сте да спрете акаунта на @%{acct}. Това ще:' + actions: + delete_html: Премахване на обидните публикации + mark_as_sensitive_html: Означаване на мултимедийните обидни публикации като деликатни + silence_html: Силно ограничаване достигането на @%{acct}, което прави профилът и съдържанието на това лице видимо само до хората, които са го последвали или ръчно търсещите профила + suspend_html: Спирането на @%{acct} ще направи профилът и съдържанието недостъпни и невъзможни за взаимодействие + close_report: Отбелязване на доклад №%{id} като решен + close_reports_html: Означаване на всички доклади срещу @%{acct} като решени + delete_data_html: Изтриване на профила и съдържанието на @%{acct} за 30 дни от сега, освен ако междувременно не получи спиране + preview_preamble_html: "@%{acct} ще получи предупреждение със следното съдържание:" + record_strike_html: Запис на предупреждение против @%{acct}, за да ви помогне при изострянето на бъдещи нарушения от този акаунт + send_email_html: Изпращане на предупредително е-писмо на @%{acct} + warning_placeholder: Незадължителни допълнителни причини за модераторско действие. target_origin: Произход на докладвания акаунт title: Доклади unassign: Освобождаване + unknown_action_msg: 'Незнайно деяние: %{action}' unresolved: Неразрешено updated_at: Обновено view_profile: Преглед на профила @@ -651,7 +689,7 @@ bg: invite_users_description: Позволява на потребителите да канят нови хора в сървъра manage_announcements: Управляване на оповестяванията manage_announcements_description: Позволява на потребителите да управляват оповестяванията в сървъра - manage_appeals: Управление на обжалванията + manage_appeals: Управление на жалбите manage_appeals_description: Позволява на потребителите да разглеждат обжалвания срещу модераторски действия manage_blocks: Управляване на блокиранията manage_blocks_description: Позволява на потребителите да блокират доставчици на е-поща и IP адреси @@ -690,7 +728,7 @@ bg: description_html: Дори повечето хора да отбелязват, че са прочели и са съгласни с условията на услугата, обикновено хората не ги четат, докато не се сблъскат с проблем. Улеснете четенето на правилата за сървъра си, представяйки ги като списък с точки. Опитайте да се придържате към кратки и прости правила, но не ги разпилявайте в премного точки. edit: Промяна на правило empty: Още няма определени правила на сървъра. - title: Правила на сървъра + title: Сървърни правила settings: about: manage_rules: Управление на правилата на сървъра @@ -703,6 +741,9 @@ bg: branding: preamble: Брандирането на вашия сървър го различава от другите сървъри в мрежата. Тази информация може да се види на различни места, като уеб интерфейса на Mastodon, собствени приложения, в прегледите на линкове от други сайтове и в приложения за съобщения, и т.н. По тази причина е добре тази информация да е кратка и ясна. title: Брандиране + captcha_enabled: + desc_html: Това разчита на външни скриптове от hCaptcha, което може да е проблем за сигурността и поверителността. В допълнение това може да направи процеса на регистриране значимо по-малко достъпно за някои хора (особено с увреждания).. Заради тези причини, то обмислете алтернативни мерки такива като регистрация на базата на одобрение или на покана. + title: Изисква се новите потребители да разгадават капчата, за да потвърдят акаунтите си content_retention: preamble: Управление на това как съдържание, породено от потребители, се съхранява в Mastodon. title: Задържане на съдържание @@ -712,12 +753,12 @@ bg: discovery: follow_recommendations: Препоръки за следване preamble: За потребители, които са нови и не познават никого в Mastodon, показването на интересно съдържание е ключово. Настройте начина, по който различни функции по откриване на съдържание работят на вашия сървър. - profile_directory: Директория на профила + profile_directory: Указател на профила public_timelines: Публични часови оси publish_discovered_servers: Публикуване на откритите сървъри publish_statistics: Публикуване на статистиката title: Откриване - trends: Налагащи се + trends: Изгряващи domain_blocks: all: До всеки disabled: До никого @@ -727,13 +768,30 @@ bg: title: Регистрации registrations_mode: modes: - approved: Нужно е одобрение за записване + approved: Изисква се одобрение за регистриране none: Никой не може да се регистрира - open: Всеки може да се запише + open: Всеки може да се регистрира + security: + authorized_fetch: Изисква се удостоверяване от федеративни сървъри + authorized_fetch_hint: Изискването удостоверяване от феративните сървъри позволява по-строго прилагане на блокирания както на ниво потребител, така и на ниво сървър. Това обаче снижава производителността, намалява обхвата на вашите отговори и може да възникнат проблеми със съвместимостта с някои федеративни услуги. Освен това, то не пречи на посветени участници да извличат вашите обществени публикации и акаунти. + authorized_fetch_overridden_hint: В момента сте неспособни да променяте тази настройка, защото тя се замества от променлива на средата. + federation_authentication: Налагане на удостоверяване на обединени сървъри title: Настройки на сървъра site_uploads: delete: Изтриване на качения файл destroyed_msg: Успешно изтриване на качването на сайта! + software_updates: + critical_update: Критично важно - обновете бързо + description: Препоръчва се да държите осъвременена своята инсталация на Mastodon, за да се възползвате от най-новите поправки и функции. Освен това, понякога е много важно да се осъвременява навреме Mastodon, за да се избегне проблем с безопасността. Заради тези причини Mastodon проверява за обновление на всеки 30 минути и ви известява за това в съответствие с предпочитанията ви за известяване по имейла. + documentation_link: Научете повече + release_notes: Бележки към изданието + title: Налични обновявания + type: Вид + types: + major: Главна версия + minor: Второстепенна версия + patch: Издание на кръпката - оправени бъгове и лесни за прилагане промени + version: Версия statuses: account: Автор application: Приложение @@ -770,9 +828,24 @@ bg: suspend: "%{name} преустанови акаунта на %{target}" appeal_approved: Обжалвано appeal_pending: Чака се обжалването + appeal_rejected: Отхвърлено обжалване system_checks: database_schema_check: message_html: Има миграции на базата данни, които чакат да бъдат изпълнени. Моля, изпълнете ги, за да осигурите изправността на приложението + elasticsearch_health_red: + message_html: Клъстерът Elasticsearch е нездрав (червено състояние), функциите за търсене не са налични + elasticsearch_health_yellow: + message_html: Клъстерът Elasticsearch е нездрав (жълто състояние), може да искате да разследвате причината + elasticsearch_index_mismatch: + message_html: Картографиранията на показатели в Elasticsearch са остарели. Пуснете tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Преглед на документацията + message_html: Вашият клъстер в Elasticsearch има повече от един възел, но Mastodon не е настроен да ги употребява. + elasticsearch_preset_single_node: + action: Преглед на документацията + message_html: Вашият клъстер в Elasticsearch има само един възел, то ES_PRESET би трябвало да се зададе да е single_node_cluster. + elasticsearch_reset_chewy: + message_html: Вашият системен показател в Elasticsearch е остарял поради промяна на настройката. Пуснете tootctl search deploy --reset-chewy, за да го осъвремените. elasticsearch_running_check: message_html: Не можа да се свърже с Elasticsearch. Проверете дали работи или изключете пълнотекстовото търсене elasticsearch_version_check: @@ -783,6 +856,18 @@ bg: message_html: Не сте определили никакви правила на сървъра. sidekiq_process_check: message_html: Не работи процес Sidekiq за %{value} опашка/и. Прегледайте настройките си за Sidekiq + software_version_critical_check: + action: Преглед на наличните обновявания + message_html: Налично e критично обновяване на Mastodon. Обновете възможно най-бързо. + software_version_patch_check: + action: Преглед на наличните обновявания + message_html: Налично е обновяване на Mastodon за оправяне на бъговете. + upload_check_privacy_error: + action: Щракнете тук за повече информация + message_html: "Вашият уеб сървър е погрешно конфигуриран. Поверителността на потребителите ви е изложена на риск." + upload_check_privacy_error_object_storage: + action: Щракнете тук за повече информация + message_html: "Вашето съхранение на предмети е погрешно конфигурирано. Поверителността на потребителите ви е изложена на риск." tags: review: Преглед на състояние updated_msg: Успешно осъвременени настройки на хаштага @@ -794,29 +879,30 @@ bg: links: allow: Позволяване на връзка allow_provider: Позволяване на публикуващия - description_html: Това са линкове, които в момента са често споделяни от акаунти, чиито публикации вашият сървър вижда. Може да помогне на вашите потребители да разберат какво се случва по света. Никой линк няма да се покаже публично, докато не одобрите автора. Можете също и да одобрявате или забранявате отделни линкове. + description_html: Това са връзки, които в момента са много пъти споделяни от акаунти, чиито публикации сървърът ви вижда. Може да помогне на потребителите ви да разберат какво се случва по света. Никоя връзка няма да се показва публично, докато не одобрите публикуващия. Може още и да одобрявате или отхвърляте отделни връзки. disallow: Забранявам връзката disallow_provider: Забраняване на публикуващия - no_link_selected: Няма промяна, тъй като няма избрани линкове + no_link_selected: Няма променени връзки, тъй като нито една не е била избрана publishers: no_publisher_selected: Няма промяна, тъй като няма избрани публикуващи shared_by_over_week: one: Споделено от един човек през последната седмица other: Споделено от %{count} души през последната седмица - title: Нашумели линкове + title: Изгряващи линкове usage_comparison: Споделено %{today} пъти днес, в сравнение с %{yesterday} пъти вчера + not_allowed_to_trend: Не е позволено да са изгряващи only_allowed: Само позволените - pending_review: В очакване на преглед + pending_review: Чака се преглед preview_card_providers: - allowed: Линкове от този публикуващ може да са нашумели + allowed: Линкове от този публикуващ може да са изгряващи description_html: Това са домейни, линковете от които са често споделяни на вашия сървър. Линковете няма да се показват в нашумели, докато домейнът на линка не бъде одобрен. Вашите одобрения (забрани) влияят и на поддомейни. - rejected: Линкове от този автор няма да се включат в нашумели + rejected: Връзки от този публикуващ няма да са изгряващи title: Публикуващи rejected: Отхвърлено statuses: allow: Позволяване на публикацията allow_account: Позволяване на автора - description_html: Това са публикациите, за които вашият сървър знае, че в момента са често споделяни или маркирани като любими. Биха помогнали на вашите нови и завръщащи се потребители да открият повече хора, които да последват. Никоя от публикациите няма да бъде показана публично, докато не одобрите автора и докато авторът не позволи акаунтът му да бъде предложен. Можете също да позволявате и забранявате отделни публикации. + description_html: Има публикации, за които сървърът ви знае, че в момента са често споделяни или означавани като любими. Биха помогнали на вашите нови и завръщащи се потребители да открият повече хора за последване. Никоя от публикациите няма да бъде показана публично, докато не одобрите автора и докато авторът не позволи акаунтът му да бъде предлган на другите. Може още да позволявате или отхвърляте отделни публикации. disallow: Забраняване на публикацията disallow_account: Забрана на автора no_status_selected: Няма промяна, тъй като няма избрана нашумяла публикация @@ -833,14 +919,14 @@ bg: tag_servers_dimension: Водещи сървъри tag_servers_measure: различни сървъри tag_uses_measure: обща употреба - description_html: Това са хаштагове, фигуриращи в момента в много публикации, които вашият сървър вижда. Помага на вашите потребители да виждат за какво говорят другите в момента. Хаштаговете няма да се покажат публично, докато не ги одобрите. + description_html: Има хаштагове, появяващи се в момента в много публикации, които сървърът ви вижда. Помага на вашите потребители да виждат за какво говорят другите в момента. Хаштаговете не се показват публично, докато не ги одобрите. listable: Може да бъде предложено no_tag_selected: Няма промяна, тъй като няма избран таг not_listable: Няма да бъде препоръчан not_trendable: Няма да се появи под налагащи се - not_usable: Не може да се използва + not_usable: Не може да се употребява peaked_on_and_decaying: Връх на актуалността на %{date}, сега е в спад - title: Налагащи се хаштагове + title: Изгряващи хаштагове trendable: Може да се появи под налагащи се trending_rank: 'Налагащи се #%{rank}' usable: Може да се употребява @@ -848,7 +934,7 @@ bg: used_by_over_week: one: Употребено от един човек през последната седмица other: Използвано от %{count} души през последната седмица - title: Налагащи се + title: Изгряващи trending: Изгряващи warning_presets: add_new: Добавяне на ново @@ -889,6 +975,9 @@ bg: body: "%{target} обжалва модераторското решение от %{action_taken_by} на %{date}, което е било %{type}. Жалбата гласи:" next_steps: Можете да одобрите жалбата и да отмените модераторското решение или да я игнорирате. subject: "%{username} обжалва модераторското решение в %{instance}" + new_critical_software_updates: + body: Нови критични версии на Mastodon са издадени и може да искате да обновите възможно най-скоро! + subject: Критични обновявания на Mastodon са налични за %{instance}! new_pending_account: body: Подробностите за новия акаунт са по-долу. Може да одобрите или отхвърлите заявлението. subject: Нов акаунт за преглед на %{instance} (%{username}) @@ -896,6 +985,9 @@ bg: body: "%{reporter} докладва %{target}" body_remote: Някого от %{domain} докладва %{target} subject: Нов доклад за %{instance} (#%{id}) + new_software_updates: + body: Нови версии на Mastodon са издадени и може да искате да осъвремените! + subject: Нови версии на Mastodon са налични за %{instance}! new_trends: body: 'Следните елементи се нуждаят от преглед преди да могат да бъдат показани публично:' new_trending_links: @@ -905,7 +997,7 @@ bg: new_trending_tags: no_approved_tags: Сега няма одобрени налагащи се хаштагове. requirements: 'Всеки от тези кандидати може да надмине #%{rank} одобрен актуален хаштаг, който в момента е #%{lowest_tag_name} с резултат %{lowest_tag_score}.' - title: Нашумели хаштагове + title: Налагащи се хаштагове subject: Нови нашумели, готови за преглед в %{instance} aliases: add_new: Създаване на псевдоним @@ -925,31 +1017,37 @@ bg: guide_link: https://ru.crowdin.com/project/mastodon guide_link_text: Всеки може да участва. sensitive_content: Деликатно съдържание - toot_layout: Оформление на публикацията application_mailer: notification_preferences: Промяна на предпочитанията за имейл salutation: "%{name}," settings: 'Промяна на предпочитанията за имейл: %{link}' + unsubscribe: Стоп на абонамента view: 'Преглед:' view_profile: Преглед на профила view_status: Преглед на публикацията applications: created: Успешно създадено приложение destroyed: Успешно изтрито приложение + logout: Излизане regenerate_token: Регенериране на кода за достъп token_regenerated: Успешно генериране на код за достъп warning: Бъдете внимателни с тези данни. Никога не ги споделяйте с никого! your_token: Вашият код за достъп auth: apply_for_account: Заявка за акаунт - change_password: Парола + captcha_confirmation: + help_html: Ако имате проблем с разгадаването на капчата, то може да се свържете с нас през %{email} и можем да ви помогнем. + hint_html: Просто още едно нещо! Трябва да потвърдим, че сте човек (това е с цел предпазване на нежелани съобщения!). Разгадайте капчата долу и щракнете на "Продължаване". + title: Проверка за сигурност + confirmations: + wrong_email_hint: Ако този адрес на е-поща не е правилен, то може да го промените в настройки на акаунта. delete_account: Изтриване на акаунта delete_account_html: Ако желаете да изтриете акаунта си, може да сторите това тук. Ще ви се поиска потвърждение. description: prefix_invited_by_user: "@%{name} ви покани да се присъедините към този сървър на Mastodon!" prefix_sign_up: Регистрирайте се днес в Mastodon! suffix: Със свой акаунт ще можете да следвате хора, да публикувате актуализации, да обменяте съобщения с потребители от всеки сървър на Mastodon и много повече! - didnt_get_confirmation: Не сте ли получили указания за потвърждение? + didnt_get_confirmation: Не сте ли получили връзка за потвърждение? dont_have_your_security_key: Нямате ли си ключ за сигурност? forgot_password: Забравена парола invalid_reset_password_token: Кодът за възстановяване на паролата е невалиден или с изтекъл срок. Моля, поръчайте нов. @@ -962,26 +1060,39 @@ bg: migrate_account_html: Ако желаете да пренасочите този акаунт към друг, можете да настроите това тук. or_log_in_with: Или влизане с помощта на privacy_policy_agreement_html: Прочетох и има съгласието ми за политиката за поверителност + progress: + confirm: Потвърждаване на имейл + details: Вашите подробности + review: Нашият преглед + rules: Приемане на правилата providers: cas: CAS saml: SAML register: Регистрация registration_closed: "%{instance} не приема нови членуващи" - resend_confirmation: Изпрати отново инструкции за потвърждение + resend_confirmation: Изпращане пак на връзка за потвърждение reset_password: Нулиране на паролата rules: + accept: Приемам + back: Назад + invited_by: 'Може да се присъедините към %{domain} благодарение на поканата, която получихте от:' preamble: Тези са зададени и наложени от модераторите на %{domain}. + preamble_invited: Преди да продължите вземете под внимание основните правила зададени от модераторите на %{domain}. title: Някои основни правила. + title_invited: Поканени сте. security: Сигурност set_new_password: Задаване на нова парола setup: - email_below_hint_html: Ако имейл адресът по-долу е неправилен, можете да го промените тук и да получите ново имейл за потвърждение. - email_settings_hint_html: Имейл за потвърждение беше изпратен до %{email}. Ако този имейл адрес е грешен, можете да го промените в настройките на акаунта. - title: Настройка + email_below_hint_html: Проверете папката си за спам или поискайте друго. Може да поправите адреса на имейла си, ако е грешен. + email_settings_hint_html: Щракнете на връзката за потвърждаване, която ви изпратихме до %{email}. Ще ви почакаме тук. + link_not_received: Не получихте ли връзка? + new_confirmation_instructions_sent: За няколко минути ще получите ново е-писмо с връзка за потвърждение! + title: Проверете входящата си поща sign_in: preamble_html: Влезте с идентификационните данни за %{domain}. Ако вашият акаунт е хостван на различен сървър, няма да можете да влезете в този. title: Влизане в %{domain} sign_up: + manual_review: Регистрирането в %{domain} преминава през ръчен преглед от модераторите ни. Напишете малко за себе си и защо искате акаунт в %{domain}, за да ни помогнете в процеса на регистрацията си. preamble: С акаунт на този съвър в Mastodon ще може да последвате всекиго в мрежата, независимо къде се намира акаунтът му. title: Първоначални настройки за %{domain}. status: @@ -990,21 +1101,9 @@ bg: functional: Вашият акаунт е в изправност. pending: Вашето приложение чака преглед от нашия екип. Това може да отнеме време. Ще получите имейл, ако приложението е одобрено. redirecting_to: Вашият акаунт е бездеен, защото сега се пренасочва към %{acct}. - view_strikes: Преглед на предишните нарушения за вашия акаунт + view_strikes: Преглед на предишните предупреждения против акаунта ви too_fast: Образецът подаден пребързо, опитайте пак. use_security_key: Употреба на ключ за сигурност - authorize_follow: - already_following: Вече следвате този акаунт - already_requested: Вече сте изпратили заявка за последване до този акаунт - error: Възникна грешка, търсейки отдалечения акаунт - follow: Последвай - follow_request: 'Изпратихте следната заявка до:' - following: 'Успешно! Сега сте последвали:' - post_follow: - close: Или просто затворете този прозорец. - return: Показване на профила на потребителя - web: Към мрежата - title: Последвай %{acct} challenge: confirm: Продължаване hint_html: "Съвет: няма да ви питаме пак за паролата през следващия час." @@ -1053,7 +1152,7 @@ bg: strikes: action_taken: Предприето действие appeal: Обжалване - appeal_approved: Това нарушение беше успешно обжалвано и е вече невалидно + appeal_approved: Това предупреждение беше успешно обжалвано и е вече невалидно appeal_rejected: Обжалването е отхвърлено appeal_submitted_at: Подадено обжалване appealed_msg: Вашето обжалване е отхвърлено. Ако е одобрено, то ще бъдете известени. @@ -1081,6 +1180,10 @@ bg: your_appeal_rejected: Вашето обжалване е отхвърлено domain_validator: invalid_domain: не е валидно име на домейн + edit_profile: + basic_information: Основна информация + hint_html: "Персонализирайте какво хората виждат в обществения ви профил и до публикациите ви. Другите хора са по-склонни да ви последват и да взаимодействат с вас, когато имате попълнен профил и снимка на профила." + other: Друго errors: '400': Подадохте невалидна или деформирана заявка. '403': Нямате позволение да разгледате тази страница. @@ -1161,8 +1264,6 @@ bg: index: hint: Този филтър се прилага за избор на отделни публикации, независимо от други критерии. Може да добавите още публикации в този филтър от уебинтерфейса. title: Филтрирани публикации - footer: - trending_now: Налагащи се сега generic: all: Всичко all_items_on_page_selected_html: @@ -1171,7 +1272,9 @@ bg: all_matching_items_selected_html: one: "%{count} елементи, съвпадащи с вашето търсене, са избрани." other: Всички %{count} елементи, съвпадащи с вашето търсене, са избрани. + cancel: Отказ changes_saved_msg: Успешно запазване на промените! + confirm: Потвърждаване copy: Копиране delete: Изтриване deselect: Размаркиране на всичко @@ -1185,24 +1288,62 @@ bg: validation_errors: one: Нещо още не е напълно наред! Прегледайте грешката долу other: Нещо още не е напълно наред! Прегледайте %{count} грешки долу - html_validator: - invalid_markup: 'съдържа невалидно HTML маркиране: %{error}' imports: errors: + empty: Празен файл CSV + incompatible_type: Несъвместимо с избрания вид на внасяне invalid_csv_file: 'Невалиден файл CSV. Грешка: %{error}' over_rows_processing_limit: съдържа повече от %{count} реда + too_large: Преголям файл + failures: Неуспехи + imported: Внесено + mismatched_types_warning: Изглежда сте избрали грешния вид за това внасяне, така че проверете пак. modes: merge: Сливане merge_long: Пази текущите записи и добавя нови overwrite: Презаписване overwrite_long: Заменя текущите записи с новите + overwrite_preambles: + blocking_html: На път сте да замените списъка си с блокирани с до %{total_items} акаунта от %{filename}. + bookmarks_html: На път сте да замените списъка си с отметки с до %{total_items} публикации от %{filename}. + domain_blocking_html: На път сте да замените списъка си с блокирани домейни с до %{total_items} домейна от %{filename}. + following_html: На път сте да последвате до %{total_items} акаунта от %{filename} и да спрете да следвате някой друг. + lists_html: На път сте да замените списъците си със съдържание от %{filename}. До %{total_items} акаунта ще се добавят към новите списъци. + muting_html: На път сте да замените списъка си със заглушени акаунти с до %{total_items} акаунта от %{filename}. + preambles: + blocking_html: На път сте да блокирате до %{total_items} акаунта от %{filename}. + bookmarks_html: На път сте да добавите до %{total_items} публикации от %{filename} в отметките си. + domain_blocking_html: На път сте да блокирате до %{total_items} домейна от %{filename}. + following_html: На път сте да последвате до %{total_items} акаунта от %{filename}. + lists_html: На път сте да добавите до %{total_items} акаунта от %{filename} към вашите списъци. Нови списъци ще се сътворят, ако няма списъци за добавяне. + muting_html: На път сте да заглушите до %{total_items} акаунта от %{filename}. preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция. + recent_imports: Скорошни внасяния + states: + finished: Завършено + in_progress: В ход + scheduled: Планирано + unconfirmed: Непотвърдено + status: Състояние success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие + time_started: Започна в + titles: + blocking: Внасяне на блокираните акаунти + bookmarks: Внасяне на отметките + domain_blocking: Внасяне на блокираните домейни + following: Внасяне на последваните акаунти + lists: Внасяне на списъци + muting: Внасяне на заглушените акаунти + type: Тип на внасяне + type_groups: + constructive: Последвания и отметки + destructive: Блокирания и заглушавания types: blocking: Списък на блокираните bookmarks: Отметки domain_blocking: Списък с блокирания на домейни following: Списък на последователите + lists: Списъци muting: Списък заглушавания upload: Качване invites: @@ -1241,6 +1382,21 @@ bg: failed_sign_in_html: Неуспешен опит за влизане с %{method} от %{ip} (%{browser}) successful_sign_in_html: Успешно влизане с %{method} от %{ip} (%{browser}) title: Историята на удостоверяване + mail_subscriptions: + unsubscribe: + action: Да, да се спре абонамента + complete: Спрян абонамент + confirmation_html: Наистина ли искате да спрете абонамента от получаването на %{type} за Mastodon в %{domain} към имейла си при %{email}? Може винаги пак да се абонирате от своите настройки за известяване по е-поща. + emails: + notification_emails: + favourite: е-писма с любими известия + follow: е-писма с известия за последване + follow_request: е-писма със заявки за следване + mention: е-писма с известия за споменаване + reblog: е-писма с известия за подсилване + resubscribe_html: Ако погрешка сте спрели абонамента, то може пак да се абонирате от своите настройки за известия по е-поща. + success_html: Повече няма да получавате %{type} за Mastodon в %{domain} към имейла си при %{email}. + title: Спиране на абонамента media_attachments: validations: images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения @@ -1320,6 +1476,7 @@ bg: update: subject: "%{name} промени публикация" notifications: + administration_emails: Администраторски известия по имейла email_events: Събития за известия по имейл email_events_hint: 'Изберете събития, за които искате да получавате известия:' other_settings: Настройки за други известия @@ -1356,12 +1513,22 @@ bg: expired: Анкетата вече е приключила invalid_choice: Избраната възможност за гласуване не съществува over_character_limit: не може по-дълго от %{max} символа всяко + self_vote: Не може да гласувате в свои анкети too_few_options: трябва да има повече от един елемент too_many_options: не може да съдържа повече от %{max} елемента preferences: other: Друго posting_defaults: По подразбиране за публикации public_timelines: Публични инфопотоци + privacy: + hint_html: "Персонализирайте как искате профилът ви и публикациите ви да се намират. Разнообразие от функции в Mastodon може да ви помогнат да достигнете по-широка публика, когато е включено. Отделете малко време, за да прегледате тези настройки, за да се уверите, че отговарят на вашия случай на употреба." + privacy: Поверителност + privacy_hint_html: Управлявате колко искате да разкриете в полза на другите. Хората разкриват интересни профили и отлични приложения, разглеждайки последванията на другите и виждайки от кои приложения публикуват, но може да предпочитате да ги държите скрити. + reach: Обхват + reach_hint_html: Управлявайте дали искате да бъдете открити и последвани от нови хора. Искате ли публикациите ви да се появяват в главния екран? Искате ли другите да ви виждат в препоръките им за последване? Желаете ли да приемате автоматично всички нови последователи или да имате подробен контрол върху всеки един? + search: Търсене + search_hint_html: Управлявайте как искате да бъдете открити. Желаете ли хората да ви открият по това, за което сте публикували публично? Искате ли хората извън Mastodon да намират профила ви, търсейки из мрежата? Обърнете внимание, че общото изключване от всички търсачки не може да гарантира за публичната информация. + title: Поверителност и обхват privacy_policy: title: Политика за поверителност reactions: @@ -1374,6 +1541,7 @@ bg: confirm_remove_selected_followers: Наистина ли искате да премахнете избраните последователи? confirm_remove_selected_follows: Наистина ли искате да премахнете избраните последвания? dormant: Неактивен + follow_failure: Не може да се последват някои от избраните акаунти. follow_selected_followers: Последване на избраните последователи followers: Последователи following: Последвани @@ -1413,6 +1581,7 @@ bg: electron: Electron firefox: Firefox generic: Неизвестен браузър + huawei_browser: Браузър Хуауей ie: Internet Explorer micro_messenger: MicroMessenger nokia: Браузър Nokia S40 Ovi @@ -1422,6 +1591,7 @@ bg: qq: Браузър QQ safari: Safari uc_browser: Браузър UC + unknown_browser: Неизвестен браузър weibo: Weibo current_session: Текуща сесия description: "%{browser} на %{platform}" @@ -1434,9 +1604,10 @@ bg: chrome_os: ChromeOS firefox_os: Оп. сист. Firefox ios: iOS + kai_os: KaiOS linux: Линукс mac: macOS - other: неизвестна платформа + unknown_platform: Неизвестна платформа windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1464,7 +1635,7 @@ bg: profile: Профил relationships: Последвания и последователи statuses_cleanup: Автоматично изтриване на публикации - strikes: Нарушения + strikes: Модериране на предупреждения two_factor_authentication: Двустепенно удостоверяване webauthn_authentication: Ключове за сигурност statuses: @@ -1507,7 +1678,6 @@ bg: show_newer: Показване на по-нови show_older: Показване на по-стари show_thread: Показване на нишката - sign_in_to_participate: Влезте, за да участвате в разговора title: "%{name}: „%{quote}“" visibilities: direct: Директно @@ -1519,7 +1689,7 @@ bg: unlisted_long: Всеки ги вижда, но са скрити от публичните инфопотоци statuses_cleanup: enabled: Автоматично изтриване на стари публикации - enabled_hint: Автоматично изтрива публикациите ви, щом достигнат указания възрастов праг, освен ако не съвпаднат с някое от изключенията долу + enabled_hint: От само себе си трие публикациите ви, щом достигнат указания възрастов праг, освен ако не съвпаднат с някое от изключенията долу exceptions: Изключения explanation: Тъй като изтриването на публикации е скъпа операция, това се прави бавно във времето, когато сървърът иначе не е зает. Поради тази причина публикациите ви може да се изтрият известно време след като достигнат възрастовия праг. ignore_favs: Игнориране на харесвания @@ -1549,16 +1719,14 @@ bg: '7889238': 3 месеца min_age_label: Възрастов праг min_favs: Запазване на публикации, маркирани като любими поне - min_favs_hint: Не се изтриват ваши публикации, маркирани като любими поне толкова пъти. Оставете празно, за да изтриете публикациите независимо от броя пъти маркирани като любими + min_favs_hint: Не се изтриват никоя от публикациите ви, маркирани като любими поне толкова пъти. Оставете празно, за да изтриете публикациите независимо от броя маркирания като любими min_reblogs: Запазване на публикации с поне толкова споделяния min_reblogs_hint: Не се изтриват ваши публикации, споделени поне толкова пъти. Оставете празно, за да изтриете публикациите независимо от техния брой споделяния stream_entries: - pinned: Закачена публикация - reblogged: подсилено sensitive_content: Деликатно съдържание strikes: errors: - too_late: Късно е за обжалване на това нарушение + too_late: Твърде късно е за обжалване на това предупреждение tags: does_not_match_previous_name: не съвпада с предишното име themes: @@ -1570,6 +1738,11 @@ bg: default: "%d %b, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Сървърът-широка употреба на квота за услугата за превод е била надвишена. + too_many_requests: Наскоро имаше премного заявки към услугата за превод. two_factor_authentication: add: Добавяне disable: Деактивирай @@ -1649,13 +1822,18 @@ bg: title: Добре дошли на борда, %{name}! users: follow_limit_reached: Не може да последвате повече от %{limit} души + go_to_sso_account_settings: Отидете при настройките на акаунта на своя доставчик на идентичност invalid_otp_token: Невалиден код otp_lost_help_html: Ако загубите достъп до двете, то може да се свържете с %{email} seamless_external_login: Влезли сте чрез външна услуга, така че настройките за парола и имейл не са налични. signed_in_as: 'Влезли като:' verification: - explanation_html: 'Можете да удостоверите самоличността си като собственик на линковете в метаданните на своя профил. За целта сайтът, към който води линк от метаданните, трябва да съдържа линк обратно към вашия профил в Mastodon. Линкът от сайта трябва да съдържа атрибут rel="me". Текстовото съдържание на линка няма значение. Ето пример:' + extra_instructions_html: Съвет:Връзката в уебсайта ви може да е невидима. Важна част е rel="me", която предотврятява имитирането на уебсайтове с породено от потребителите съдържание. Може дори да употребите етикет за връзката в заглавката на странице вместо а, но HTML трябва да достъпен без изпълнение на JavaScript. + here_is_how: Ето как + hint_html: "Потвърждаването на самоличността ви в Mastodon е за всеки. Въз основа на отворени уеб стандарти, сега и завинаги безплатно. Всичко което ви трябва е личен уебсайт, по който хората да ви разпознават. Свързвайки се с този уебсайт от профила си, то ще проверим дали уебсайтът води обратно към профила ви и ще покажем визуален показател в него." + instructions_html: Копипейстнете кода долу в HTML на уебсайта си. Тогава добавете адреса на уебсайта си в едно от допълнителните полета на профила ви от раздела "Редактиране на профила" и запазане на промените. verification: Проверка + verified_links: Вашите потвърдени връзки webauthn_credentials: add: Добавяне на нов ключ за сигурност create: diff --git a/config/locales/bn.yml b/config/locales/bn.yml index 1f2550d298..411339e9a1 100644 --- a/config/locales/bn.yml +++ b/config/locales/bn.yml @@ -5,12 +5,14 @@ bn: contact_missing: নেই contact_unavailable: প্রযোজ্য নয় hosted_on: এই মাস্টাডনটি আছে %{domain} এ + title: পরিচিতি accounts: follow: যুক্ত followers: one: যুক্ত আছে other: যারা যুক্ত হয়েছে following: যুক্ত করা + instance_actor_flash: এই অ্যাকাউন্টটি একটি ভার্চুয়াল সত্তা যা সার্ভারের প্রতিনিধিত্ব করতে ব্যবহৃত হয় এবং কোনও স্বতন্ত্র ব্যবহারকারী নয়। এটি ফেডারেশনের উদ্দেশ্যে ব্যবহার করা হয় এবং স্থগিত করা উচিত নয়. last_active: শেষ সক্রিয় ছিল link_verified_on: এই লিংকের মালিকানা শেষ চেক করা হয় %{date} তারিখে nothing_here: এখানে কিছুই নেই! @@ -31,21 +33,32 @@ bn: accounts: add_email_domain_block: নিষিদ্ধ করা ই-মেইল ডোমেইন approve: অনুমোদন দিন + approved_msg: "%{username}-এর অ্যাকাউন্ট সৃষ্টি আবেদন সফলভাবে অনুমোদিত হয়েছে" are_you_sure: আপনি কি নিশ্চিত ? avatar: অবতার by_domain: ওয়েবসাইট/কার্যক্ষেত্র change_email: + changed_msg: ইমেল সফলভাবে পরিবর্তিত হয়েছে! current_email: এখনকার ইমেইল label: ইমেইল পরিবর্তন new_email: নতুন ইমেইল submit: ইমেইল পরিবর্তন title: "%{username} এর ইমেইল পরিবর্তন" + change_role: + changed_msg: ভূমিকা সফলভাবে পরিবর্তিত! + label: ভূমিকা পরিবর্তন করুন + no_role: কোন ভূমিকা বরাদ্দ করা হয়নি + title: "%{username}-এর ভূমিকা পরিবর্তন করুন" confirm: নিশ্চিত করুন confirmed: নিশ্চিত হয়েছে confirming: নিশ্চিত করা হচ্ছে + custom: বিশেষ + delete: ডেটা মুছুন deleted: মুছে ফেলা হয়েছে demote: নিচের পদে দিন + destroyed_msg: "%{username}-এর ডেটা এখন সারিবদ্ধভাবে মুছে ফেলা হবে" disable: বন্ধ করুন + disable_sign_in_token_auth: ই-মেইল টোকেন প্রমাণীকরণ অক্ষম করুন disable_two_factor_authentication: দুই পদ্ধতির প্রমাণীকরণ(2FA) বন্ধ করুন disabled: বন্ধ করা হয়েছে display_name: দেখানোর জন্য নাম @@ -54,11 +67,14 @@ bn: email: ইমেইল email_status: ইমেইলের অবস্থা enable: চালু করুন + enable_sign_in_token_auth: ই-মেইল টোকেন প্রমাণীকরণ সক্ষম করুন enabled: চালু করুন + enabled_msg: "%{username}-এর অ্যাকাউন্ট সফলভাবে আনফ্রোজ করা হয়েছে" followers: অনুসরকারীরা follows: অনুসরণ করে header: শিরোলেখা inbox_url: চিঠি পাওয়ার বক্স লিংক + invite_request_text: যোগদানের কারণ invited_by: আমন্ত্রণ করেছে ip: আইপি(IP) joined: যোগ দিয়েছে @@ -94,8 +110,6 @@ bn: remove_header: হেডার এর ছবি অপসারণ করুন resend_confirmation: already_confirmed: এই ব্যবহারকারী ইতিমধ্যে নিশ্চিত করা আছে - send: নিশ্চিতকরণ ইমেল পুনরায় পাঠান - success: নিশ্চিতকরণের ইমেল সফলভাবে পাঠানো হয়েছে! reset: পুনরায় সেট করুন reset_password: পাসওয়ার্ড পুনঃস্থাপন করুন resubscribe: পুনরায় সদস্যতা নিন @@ -226,13 +240,5 @@ bn: report_notes: created_msg: রিপোর্ট নোট সফলভাবে তৈরি করা হয়েছে! destroyed_msg: রিপোর্ট নোট সফলভাবে মোছা হয়েছে! - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. verification: verification: সত্যতা নির্ধারণ diff --git a/config/locales/br.yml b/config/locales/br.yml index 6be93d2924..e869374573 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -178,7 +178,6 @@ br: delete: Dilemel expires_in: '1209600': 2 sizhunvezh - '15778476': 6 months '2629746': 1 mizvezh '31556952': 1 bloavezh '86400': 1 devezh @@ -288,25 +287,19 @@ br: view: 'Sellet :' view_status: Gwelet ar c'hannad auth: - change_password: Ger-tremen delete_account: Dilemel ar gont + delete_account_html: Ma fell deoc'h dilemel ho kont e c'hellit klikañ amañ. Goulennet e vo ganeoc'h kadarnaat an obererezh. login: Mont tre logout: Digennaskañ + migrate_account_html: Ma fell deoc'h adkas ar gont-mañ war-zu unan all e c'hellit arventenniñ an dra-se amañ. providers: cas: CAS saml: SAML register: Lakaat ho anv reset_password: Adderaouekaat ar ger-tremen security: Diogelroez - setup: - title: Kefluniañ status: account_status: Statud ar gont - authorize_follow: - follow: Heuliañ - post_follow: - web: Distreiñ d'an etrefas web - title: Heuliañ %{acct} challenge: confirm: Kenderc' hel invalid_password: Ger-tremen diwiriek @@ -336,14 +329,6 @@ br: created_at: Deiziad title_actions: none: Diwall - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. exports: archive_takeout: date: Deiziad @@ -398,6 +383,8 @@ br: table: uses: Implijoù title: Pediñ tud + migrations: + incoming_migrations_html: Evit dilojañ ur gont all da homañ e rankit sevel un alias da gentañ. moderation: title: Habaskadur notification_mailer: @@ -469,7 +456,6 @@ br: ios: iOS linux: Linux mac: macOS - other: savenn dianav windows: Windows revoke: Dizober settings: @@ -499,16 +485,10 @@ br: keep_direct: Mirout ar c'hannadoù eeun min_age: '1209600': 2 sizhunvezh - '15778476': 6 months '2629746': 1 mizvezh '31556952': 1 bloavezh - '5259492': 2 months '604800': 1 sizhunvezh '63113904': 2 vloavezh - '7889238': 3 months - stream_entries: - pinned: Toud spilhennet - reblogged: en·he deus skignet themes: default: Mastodoñ (Teñval) mastodon-light: Mastodoñ (Sklaer) @@ -536,7 +516,6 @@ br: users: signed_in_as: 'Aet-tre evel:' verification: - explanation_html: 'Gallout a rit gwiriañ c''hwi a zo perc''henn. ez liammoù metadata ho profil. Ret eo d''al lec''hienn web staget enderc''hel ul liamm evit mont d''ho profil Mastodon. Ret eo d''al liamm-se enderc''hel un doarenn rel="me". Ne ra forzh an destenn a zo e-barzh al liamm. Setu ur skouer:' verification: Amprouadur webauthn_credentials: add: Ouzphennañ un alc'hwez surentez nevez diff --git a/config/locales/bs.yml b/config/locales/bs.yml index 2709636c9f..e9e174462a 100644 --- a/config/locales/bs.yml +++ b/config/locales/bs.yml @@ -1,10 +1 @@ ---- bs: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 616f8de17f..2cdf87d8fd 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1,7 +1,7 @@ --- ca: about: - about_mastodon_html: 'La xarxa social del futur: sense anuncis, sense vigilància corporativa, disseny ètic i descentralització. Tingues el control de les teves dades amb Mastodon!' + about_mastodon_html: 'La xarxa social del futur: sense anuncis, sense vigilància corporativa, amb un disseny ètic i descentralització. Amb Mastodon controles les teves dades!' contact_missing: No configurat contact_unavailable: N/D hosted_on: Mastodon allotjat a %{domain} @@ -14,7 +14,7 @@ ca: following: Seguint instance_actor_flash: Aquest compte és un actor virtual usat per a representar el mateix servidor i no cap usuari individual. Es fa servir per a federar i no s'hauria d'esborrar. last_active: última activitat - link_verified_on: La propietat d'aquest enllaç s'ha verificat el %{date} + link_verified_on: La propietat d'aquest enllaç va quedar verificada el %{date} nothing_here: No hi ha res aquí! pin_errors: following: Has d'estar seguint la persona que vulguis avalar @@ -31,9 +31,9 @@ ca: created_msg: La nota de moderació s'ha creat correctament! destroyed_msg: Nota de moderació destruïda amb èxit! accounts: - add_email_domain_block: Bloquejar el domini de l'adreça de correu electrònic + add_email_domain_block: Bloca el domini del correu approve: Aprova - approved_msg: L’aplicació del registre de %{username} s’ha aprovat amb èxit + approved_msg: S'ha aprovat la petició de registre de %{username} are_you_sure: N'estàs segur? avatar: Avatar by_domain: Domini @@ -73,7 +73,7 @@ ca: followers: Seguidors follows: Seguits header: Capçalera - inbox_url: URL de la safata d'entrada + inbox_url: Enllaç de la safata d'entrada invite_request_text: Motiu del registre invited_by: Convidat per ip: IP @@ -91,6 +91,7 @@ ca: moderation: active: Actiu all: Tot + disabled: Desactivat pending: Pendent silenced: Limitat suspended: Suspès @@ -115,7 +116,7 @@ ca: redownload: Actualitza el perfil redownloaded_msg: El perfil de %{username} s’ha refrescat des de l’origen amb èxit reject: Rebutja - rejected_msg: L’aplicació de registre de %{username} s’ha rebutjat amb èxit + rejected_msg: S'ha rebutjat la petició de registre de %{username} remote_suspension_irreversible: Les dades d'aquest compte s'han esborrat irreversiblement. remote_suspension_reversible_hint_html: El compte ha estat suspès en el seu servidor i les dades seran totalment suprimides el %{date}. Fins llavors, el servidor remot pot restaurar aquest compte sense efectes negatius. Si vols suprimir immediatament totes les dades del compte, ho pots fer a continuació. remove_avatar: Eliminar avatar @@ -124,8 +125,8 @@ ca: removed_header_msg: S’ha suprimit amb èxit l’imatge de capçalera de %{username} resend_confirmation: already_confirmed: Aquest usuari ja està confirmat - send: Reenviar el correu electrònic de confirmació - success: Correu electrònic de confirmació enviat amb èxit! + send: Reenvia l'enllaç de confirmació + success: Enllaç de confirmació enviat amb èxit! reset: Reinicialitza reset_password: Restableix la contrasenya resubscribe: Torna a subscriure @@ -133,12 +134,13 @@ ca: search: Cerca search_same_email_domain: Altres usuaris amb el mateix domini de correu search_same_ip: Altres usuaris amb la mateixa IP + security: Seguretat security_measures: only_password: Només contrasenya password_and_2fa: Contrasenya i 2FA sensitive: Sensible sensitized: marcar com a sensible - shared_inbox_url: URL de la safata d'entrada compartida + shared_inbox_url: Enllaç de la safata d'entrada compartida show: created_reports: Informes creats targeted_reports: Informes realitzats per altres @@ -170,7 +172,7 @@ ca: action_types: approve_appeal: Aprova l'apel·lació approve_user: Aprova l'usuari - assigned_to_self_report: Assigna l'informe + assigned_to_self_report: Assigna un informe change_email_user: Canvia l'adreça electrònica per l'usuari change_role_user: Canvia el Rol del Usuari confirm_user: Confirma l'usuari @@ -180,7 +182,7 @@ ca: create_custom_emoji: Crea un emoji personalitzat create_domain_allow: Crea un domini permès create_domain_block: Crea un bloqueig de domini - create_email_domain_block: Crea un bloqueig de domini d'adreça de correu + create_email_domain_block: Crea un bloqueig de domini de correu create_ip_block: Crear regla IP create_unavailable_domain: Crea un domini no disponible create_user_role: Crea Rol @@ -188,9 +190,9 @@ ca: destroy_announcement: Esborra l'anunci destroy_canonical_email_block: Esborra el bloqueig de correu electrònic destroy_custom_emoji: Esborra l'emoji personalitzat - destroy_domain_allow: Esborra el domini permès + destroy_domain_allow: Esborra el permís del domini destroy_domain_block: Esborra el bloqueig de domini - destroy_email_domain_block: Esborra el bloqueig de domini de l'adreça de correu + destroy_email_domain_block: Esborra el bloqueig de domini de correu destroy_instance: Purga Domini destroy_ip_block: Eliminar regla IP destroy_status: Elimina la publicació @@ -198,10 +200,10 @@ ca: destroy_user_role: Destrueix Rol disable_2fa_user: Desactiva 2FA disable_custom_emoji: Desactiva l'emoji personalitzat - disable_sign_in_token_auth_user: Desactivar l'autenticació de token per correu per l'usuari + disable_sign_in_token_auth_user: Desactivr l'autenticació de token per correu per a l'usuari disable_user: Deshabilita l'usuari enable_custom_emoji: Activa l'emoji personalitzat - enable_sign_in_token_auth_user: Activar l'autenticació de token per correu pel l'usuari + enable_sign_in_token_auth_user: Activa l'autenticació de token per correu per a l'usuari enable_user: Activa l'usuari memorialize_account: Memoritza el compte promote_user: Promou l'usuari @@ -274,7 +276,7 @@ ca: sensitive_account_html: "%{name} ha marcat els mèdia de %{target} com a sensibles" silence_account_html: "%{name} ha silenciat el compte de %{target}" suspend_account_html: "%{name} ha suspès el compte de %{target}" - unassigned_report_html: "%{name} ha des-assignat l'informe %{target}" + unassigned_report_html: "%{name} ha eliminat l'assignació de l'informe %{target}" unblock_email_account_html: "%{name} ha desbloquejat l'adreça de correu de %{target}" unsensitive_account_html: "%{name} ha desmarcat com sensibles els mèdia de %{target}" unsilence_account_html: "%{name} ha llevat el silenci del compte %{target}" @@ -307,6 +309,7 @@ ca: unpublish: Despublicar unpublished_msg: L’anunci s’ha despublicat amb èxit! updated_msg: L'anunci s'ha actualitzat correctament! + critical_update_pending: Actualització crítica pendent custom_emojis: assign_category: Assigna una categoria by_domain: Domini @@ -372,15 +375,24 @@ ca: empty: No s'ha trobat cap apel·lació. title: Apel·lacions domain_allows: - add_new: Dominis autoritzats - created_msg: El domini ha estat correctament autoritzat - destroyed_msg: S'ha esborrat el domini de la llista blanca + add_new: Permet la federació amb el domini + created_msg: El domini ha estat autoritzat per a la federació + destroyed_msg: El domini ha estat desautoritzat de la federació export: Exporta import: Importa - undo: Treure de la llista blanca + undo: No permetis la federació amb el domini domain_blocks: - add_new: Afegir nou bloqueig de domini - created_msg: El bloqueig de domini ara s'està processant + add_new: Afegeix nou bloqueig de domini + confirm_suspension: + cancel: Cancel·la + confirm: Suspèn + permanent_action: Desfer la suspensió no restaurarà cap dada o relació. + preamble_html: Ets a punt de suspendre %{domain} i els seus sub dominis. + remove_all_data: Això eliminarà tot el contingut, mèdia i dades dels perfils dels comptes d'aquest domini en el teu servidor. + stop_communication: El teu servidor deixarà de comunicar-se amb aquests servidors. + title: Confirma el bloqueig de domini per a %{domain} + undo_relationships: Això desferà qualsevol relació de seguiment entre els comptes d'aquests servidors i el teu. + created_msg: S'està processant el bloqueig de domini destroyed_msg: El bloqueig de domini s'ha desfet domain: Domini edit: Editar el bloqueig del domini @@ -396,7 +408,7 @@ ca: noop: Cap silence: Limitar suspend: Suspensió - title: Bloqueig de domini nou + title: Nou bloqueig de domini no_domain_block_selected: No s'ha canviat cap bloqueig de domini perquè no se n'ha seleccionat cap not_permitted: No tens permís per a realitzar aquesta acció obfuscate: Oculta el nom del domini @@ -427,7 +439,8 @@ ca: resolve: Resol domini title: Nova adreça de correu en la llista negra no_email_domain_block_selected: No s'han canviat els bloquejos de domini perquè cap s'ha seleccionat - resolved_dns_records_hint_html: El nom del domini resol als següents dominis MX, els quals son els responsables finals per a acceptar els correus. Bloquejar un domini MX bloquejarà els registres des de qualsevol adreça de correu que utilitzi el mateix domini MX, encara que el nom visible del domini sigui diferent. Ves amb compte no bloquegis els grans proveïdors de correu electrònic. + not_permitted: No permés + resolved_dns_records_hint_html: El nom del domini resol als següents dominis MX, els quals són els responsables finals per a acceptar els correus. Blocar un domini MX blocarà els registres des de qualsevol adreça de correu que utilitzi el mateix domini MX, encara que el nom visible del domini sigui diferent. Ves amb compte no bloquegis els grans proveïdors de correu electrònic. resolved_through_html: Resolt mitjançant %{domain} title: Llista negra de correus electrònics export_domain_allows: @@ -436,7 +449,7 @@ ca: no_file: No s'ha seleccionat cap fitxer export_domain_blocks: import: - description_html: Estàs a punt d'importar una llista de dominis blocats. Si us plau, revisa aquesta llista amb molta cura, especialment si no l'has creada tu mateix. + description_html: Esteu a punt d'importar una llista de dominis blocats. Reviseu aquesta llista amb molta cura, especialment si no l'heu creada vós mateix. existing_relationships_warning: Relacions de seguiment existents private_comment_description_html: 'Per a ajudar-te a fer un seguiment d''on provenen els bloquejos importats, es crearan amb el següent comentari privat: %{comment}' private_comment_template: Importar des de %{source} el %{date} @@ -446,7 +459,7 @@ ca: title: Importa dominis bloquejats no_file: No s'ha seleccionat cap fitxer follow_recommendations: - description_html: "Seguir les recomanacions ajuda als nous usuaris a trobar ràpidament contingut interessant. Quan un usuari no ha interactuat prou amb d'altres com per a formar a qui seguir personalment, aquests comptes li seran recomanats. Es recalculen a diari a partir d'una barreja de comptes amb els compromisos recents més alts i el nombre més alt de seguidors locals per a un idioma determinat." + description_html: "Seguir les recomanacions ajuda als nous usuaris a trobar ràpidament contingut interessant. Quan un usuari no ha interactuat prou amb altres per a formar a qui seguir personalment, aquests comptes li seran recomanats. Es recalculen diàriament a partir d'una barreja de comptes amb els compromisos recents més alts i el nombre més alt de seguidors locals per a un idioma determinat." language: Per idioma status: Estat suppress: Suprimeix les recomanacions de seguiment @@ -473,6 +486,7 @@ ca: content_policies: comment: Nota interna description_html: Pots definir polítiques de contingut que seran aplicades a tots els comptes d'aquest domini i a qualsevol dels seus subdominis. + limited_federation_mode_description_html: Pots triar si permets la federació amb aquest domini. policies: reject_media: Rebutja mèdia reject_reports: Rebutja informes @@ -554,11 +568,11 @@ ca: enable: Activat enable_hint: Una vegada habilitat, el teu servidor es subscriurà a tots els tuts públics d'aquest relay i començarà a enviar-hi tots els tuts públics d'aquest servidor. enabled: Activat - inbox_url: URL del Relay + inbox_url: Enllaç del Relay pending: S'està esperant l'aprovació del relay save_and_enable: Desa i activa setup: Configura una connexió de relay - signatures_not_enabled: Els relays no treballaran correctament mentre estiguin habilitats el mode segur o llista blanca + signatures_not_enabled: Els relays no funcionaran bé mentre estiguin habilitats els modes segur o de llista blanca status: Estat title: Relays report_notes: @@ -585,11 +599,13 @@ ca: assign_to_self: Assigna'm assigned: Moderador assignat by_target_domain: Domini del compte denunciat + cancel: Cancel·la category: Categoria category_description_html: El motiu pel qual aquest compte o contingut ha estat denunciat se citarà en la comunicació amb el compte denunciat comment: none: Cap comment_description_html: 'Per a donar més informació, %{name} ha escrit:' + confirm: Confirma confirm_action: Confirma l'acció de moderació contra @%{acct} created_at: Denunciat delete_and_resolve: Elimina les publicacions @@ -640,7 +656,7 @@ ca: warning_placeholder: Opcional raó adicional d'aquesta acció de moderació. target_origin: Origen del compte denunciat title: Informes - unassign: Treu l'assignació + unassign: Elimina l'assignació unknown_action_msg: 'Acció desconeguda: %{action}' unresolved: No resolt updated_at: Actualitzat @@ -660,7 +676,7 @@ ca: description_html: Amb rols d'usuari, pots personalitzar quines funcions i àrees de Mastodon els teus usuaris poden accedir. edit: Editar el rol %{name} everyone: Permisos per defecte - everyone_full_description_html: Aquest és el rol base que afecta tots els usuaris, fins i tot els que no en tenen cap d'assignat. Tots els altres rols n'hereten els permisos. + everyone_full_description_html: Aquest és el rol base que afecta tots els usuaris, fins i tot els que no en tenen cap d'assignat. Tots els altres n'hereten els permisos. permissions_count: one: "%{count} permís" other: "%{count} permisos" @@ -686,7 +702,7 @@ ca: manage_reports: Gestiona informes manage_reports_description: Permet als usuaris revisar informes i realitzar accions de moderació contra ells manage_roles: Gestionar rols - manage_roles_description: Permet als usuaris gestionar i assignar rols per sota dels seus + manage_roles_description: Permet als usuaris de gestionar i assignar rols per sota dels seus manage_rules: Gestiona normes manage_rules_description: Permet als usuaris canviar les normes del servidor manage_settings: Gestiona configuració @@ -725,6 +741,9 @@ ca: branding: preamble: La marca del teu servidor el diferencia dels altres servidors de la xarxa. Aquesta informació es pot mostrar en diversos entorns com ara en la interfície web, en les aplicacions natives, en les previsualitzacions dels enllaços en altres webs, dins les aplicacions de missatgeria i d'altres. Per aquesta raó, val més mantenir aquesta informació clara, breu i precisa. title: Marca + captcha_enabled: + desc_html: Això es basa en scripts externs de hCaptcha, que poden ser un problema de privacitat i seguretat. A més, això pot fer que el procés de registre sigui significativament menys accesible per algunes (especialment discapacitades) persones. Per aquestes raons, si us plau considera alternatives com ara registre amb aprovació necessària o basada en invitacions. + title: Demana als nous usuaris que resolguin un CAPTCHA per a confirmar el seu compte content_retention: preamble: Controla com es desa a Mastodon el contingut generat per l'usuari. title: Retenció de contingut @@ -749,13 +768,30 @@ ca: title: Registres registrations_mode: modes: - approved: Es requereix l’aprovació per registrar-se - none: Ningú no pot registrar-se + approved: Cal l’aprovació per a registrar-se + none: No es pot registrar ningú open: Qualsevol pot registrar-se - title: Paràmetres del servidor + security: + authorized_fetch: Requereix autenticació dels servidors federats + authorized_fetch_hint: Requerir l'autenticació dels servidors federats permet una aplicació més estricta dels bloqueigs a nivell d'usuari i a nivell de servidor. Tanmateix, això provoca una penalització del rendiment, redueix l'abast de les seves respostes i pot introduir problemes de compatibilitat amb alguns serveis federats. A més, això no impedirà que els actors dedicats busquin les teves publicacions i comptes públics. + authorized_fetch_overridden_hint: Actualment no pots canviar aquesta configuració perquè està anul·lada per una variable d'entorn. + federation_authentication: Aplicació de l'autenticació de la federació + title: Configuració del servidor site_uploads: delete: Esborra el fitxer pujat destroyed_msg: La càrrega al lloc s'ha suprimit correctament! + software_updates: + critical_update: Crítica - si us plau, actualitza ràpidament + description: Es recomana mantenir actualizada la teva instal·lació de Mastodon per a beneficiar-se de les darreres correccions i característiques. A més, de vegades és fonamental actualitzar Mastodon periòdicament per evitar problemes de seguretat. Per aquestes raons, Mastodon comprova si hi ha actualitzacions cada 30 minuts i et notificarà d'acord amb les teves preferències de notificacions per correu electrònic. + documentation_link: Més informació + release_notes: Notes de llançament + title: Actualitzacions disponibles + type: Tipus + types: + major: Llançament important + minor: Llançament menor + patch: 'Llançament de pedaços: correccions d''errors i canvis fàcils d''aplicar' + version: Versió statuses: account: Autor application: Aplicació @@ -792,11 +828,26 @@ ca: suspend: "%{name} ha suspès el compte de %{target}" appeal_approved: Apel·lat appeal_pending: Apel·lació pendent + appeal_rejected: Apel·lació rebutjada system_checks: database_schema_check: - message_html: Hi ha pendents migracions de la base de dades. Si us plau executa-les per a assegurar que l'aplicació es comporta com s'espera + message_html: Hi ha pendents migracions de la base de dades. Executeu-les per a assegurar que l'aplicació es comporta com s'espera + elasticsearch_health_red: + message_html: El cluster de Elasticsearch no es saludable (estat vermell), les funcions de cerca no estan disponibles + elasticsearch_health_yellow: + message_html: El cluster de Elasticsearch no es saludable (estat groc), és possible que vulguis investigar la raó + elasticsearch_index_mismatch: + message_html: Els mapes de índex de Elasticsearch estan desactualizats. Si us plau executa tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Veure la documentació + message_html: El teu clúster de Elasticsearch té més d'un node però Mastodon no està configurat per a emprar-los. + elasticsearch_preset_single_node: + action: Veure la documentació + message_html: El teu clúster de Elasticsearch té només un node, ES_PRESET hauria de ser configurat com single_node_cluster. + elasticsearch_reset_chewy: + message_html: L'índex del teu sistema Elasticsearch està desactualizat degut a un canvi de configuració. Si us plau executa tootctl search deploy --reset-chewy per a actualitzar-lo. elasticsearch_running_check: - message_html: No s'ha pogut connectar a Elasticsearch. Si us plau verifica que estigui funcionant o desactiva la cerca de text complet + message_html: No s'ha pogut connectar a Elasticsearch. Verifiqueu que funciona o desactiveu la cerca de text complet elasticsearch_version_check: message_html: 'Versió incompatible de Elasticsearch: %{value}' version_comparison: Elasticsearch %{running_version} està funcionant mentre %{required_version} és requerida @@ -804,7 +855,19 @@ ca: action: Gestiona les normes del servidor message_html: No has definit cap norma del servidor. sidekiq_process_check: - message_html: No hi ha cap procés de Sidekiq executant-se per a la cua (o cues) de %{value}. Si us plau revisa la teva configuració de Sidekiq + message_html: No hi ha cap procés de Sidekiq executant-se per a la cua (o cues) de %{value}. Reviseu la configuració de Sidekiq + software_version_critical_check: + action: Veure actualitzacions disponibles + message_html: Hi ha disponible una actualització crítica de Mastodon, si us plau, actualitza-la el més abans possible. + software_version_patch_check: + action: Veure actualitzacions disponibles + message_html: Hi ha disponible una actualització de correcció d'errors de Mastodon. + upload_check_privacy_error: + action: Consulta aquí per a més informació + message_html: "El teu servidor no està ben configurat. La privacitat dels teus usuaris està en risc." + upload_check_privacy_error_object_storage: + action: Consulta aquí per a més informació + message_html: "El teu emagatzamatge d'objectes no està ben configurat. La privacitat dels teus usuaris està en risc." tags: review: Revisar l'estat updated_msg: Ajustaments d'etiquetes actualitzats amb èxit @@ -827,6 +890,7 @@ ca: other: Compartit per %{count} persones en la darrera setmana title: Enllaços en tendència usage_comparison: Compartit %{today} vegades avui, comparat amb %{yesterday} d'ahir + not_allowed_to_trend: No es permet la tendència only_allowed: Només permesos pending_review: Revisió pendent preview_card_providers: @@ -894,7 +958,7 @@ ca: events: Esdeveniments new: Nou webhook rotate_secret: Rota el secret - secret: Signant el secret + secret: Clau de la signatura status: Estat title: Webhooks webhook: Webhook @@ -911,6 +975,9 @@ ca: body: "%{target} està apel·lant una decisió de moderació de %{action_taken_by} el %{date}, del tipus %{type}. Han escrit:" next_steps: Pots aprovar l'apel·lació per a desfer la decisió de moderació o ignorar-la. subject: "%{username} està apel·lant una decisió de moderació a %{instance}" + new_critical_software_updates: + body: S'han alliberat noves versions crítiques de Mastodon, és possible que vulguis actualitzar-les el més aviat possible! + subject: Hi ha disponibles actualitzacions crítiques de Mastodon per a %{instance}! new_pending_account: body: A continuació trobaràs els detalls del compte nou. Pots aprovar o rebutjar aquest registre. subject: Nou compte per a revisar a %{instance} (%{username}) @@ -918,6 +985,9 @@ ca: body: "%{reporter} ha informat de %{target}" body_remote: Algú des del domini %{domain} ha informat sobre %{target} subject: Informe nou per a %{instance} (#%{id}) + new_software_updates: + body: S'han alliberat noves versions de Mastodon, és possible que desitgis actualitzar! + subject: Hi ha disponibles noves versions de Mastodon per a %{instance}! new_trends: body: 'Els següents elements necessiten una revisió abans de que puguin ser mostrats públicament:' new_trending_links: @@ -947,24 +1017,28 @@ ca: guide_link: https://crowdin.com/project/mastodon guide_link_text: Tothom hi pot contribuir. sensitive_content: Contingut sensible - toot_layout: Disseny dels tuts application_mailer: notification_preferences: Canvia les preferències de correu salutation: "%{name}," settings: 'Canvia les preferències de correu: %{link}' + unsubscribe: Cancel·la la subscripció view: 'Visualització:' view_profile: Mostra el perfil view_status: Mostra el tut applications: created: L'aplicació s'ha creat correctament destroyed: L'aplicació s'ha suprimit correctament + logout: Surt regenerate_token: Torna a generar l'identificador d'accés token_regenerated: L'identificador d'accés s'ha generat correctament warning: Aneu amb compte amb aquestes dades. No les compartiu mai amb ningú! your_token: El teu identificador d'accés auth: apply_for_account: Sol·licitar un compte - change_password: Contrasenya + captcha_confirmation: + help_html: Si tens problemes resolguent el CAPTCHA, pots posar-te en contacte amb nosaltres via %{email} i nosaltres podrem ajudar-te. + hint_html: Una cosa més! Necessitem confirmar que ets una persona humana (és així com mantenim a ratlla l'spam). Resolt el CAPTCHA inferior i clica a "Segueix". + title: Revisió de seguretat confirmations: wrong_email_hint: Si aquesta adreça de correu electrònic no és correcte, pots canviar-la en els ajustos del compte. delete_account: Elimina el compte @@ -973,7 +1047,7 @@ ca: prefix_invited_by_user: "@%{name} t'ha invitat a unir-te a aquest servidor de Mastodon!" prefix_sign_up: Registra't avui a Mastodon! suffix: Amb un compte seràs capaç de seguir persones, publicar i intercanviar missatges amb usuaris de qualsevol servidor de Mastodon i més! - didnt_get_confirmation: No has rebut el correu de confirmació? + didnt_get_confirmation: No has rebut l'enllaç de confirmació? dont_have_your_security_key: No tens la teva clau de seguretat? forgot_password: Has oblidat la contrasenya? invalid_reset_password_token: L'enllaç de restabliment de la contrasenya no és vàlid o ha caducat. Torna-ho a provar. @@ -986,28 +1060,41 @@ ca: migrate_account_html: Si vols redirigir aquest compte a un altre diferent, el pots configurar aquí. or_log_in_with: O inicia sessió amb privacy_policy_agreement_html: He llegit i estic d'acord amb la política de privacitat + progress: + confirm: Confirma correu electrònic + details: Els teus detalls + review: La nostra revisió + rules: Accepta les normes providers: cas: CAS saml: SAML register: Registrar-se registration_closed: "%{instance} no accepta nous membres" - resend_confirmation: Torna a enviar el correu de confirmació + resend_confirmation: Reenvia l'enllaç de confirmació reset_password: Restableix la contrasenya rules: + accept: Accepta + back: Enrere + invited_by: 'Pots unir-te a %{domain} gràcies a l''invitació que has rebut de:' preamble: Aquestes regles estan establertes i aplicades per els moderadors de %{domain}. + preamble_invited: Abans de seguir, si us plau considera les normes establertes pels moderadors de %{domain}. title: Algunes regles bàsiques. + title_invited: T'han convidat. security: Seguretat set_new_password: Estableix una contrasenya nova setup: - email_below_hint_html: Si l’adreça de correu electrònic següent és incorrecta, podeu canviar-la aquí i rebre un nou correu electrònic de confirmació. - email_settings_hint_html: El correu electrònic de confirmació es va enviar a %{email}. Si aquesta adreça de correu electrònic no és correcta, la podeu canviar a la configuració del compte. - title: Configuració + email_below_hint_html: Verifica la carpeta fe correu brossa o demana'n un altre. Pots corregir la teva adreça de correu electrònic si no és correcte. + email_settings_hint_html: Toca l'enllaç que t'hem enviat per a verificar %{email}. Esperarem aquí mateix. + link_not_received: No has rebut l'enllaç? + new_confirmation_instructions_sent: Rebràs un nou correu electrònic amb l'enllaç de confirmació en pocs minuts! + title: Comprova la teva safata d'entrada sign_in: - preamble_html: Inicia sessió amb les teves credencials %{domain}. Si el teu compte es troba a un servidor diferent, no podràs iniciar una sessió aquí. + preamble_html: Inicia la sessió amb les teves credencials de %{domain}. Si el teu compte es troba a un servidor diferent, no podràs iniciar sessió aquí. title: Inicia sessió a %{domain} sign_up: - preamble: Amb un compte en aquest servidor Mastodon, podràs seguir qualsevol altre persona de la xarxa, independentment d'on tingui el seu compte. - title: Anem a configurar-te a %{domain}. + manual_review: Els registres a %{domain} passen per una revisió manual dels nostres moderadors. Per ajudar-nos a processar el teu registre, escriu-nos quelcom sobre tu i perquè vols un compte a %{domain}. + preamble: Amb un compte en aquest servidor Mastodon podràs seguir qualsevol altra persona de la xarxa, independentment d'on tingui el compte. + title: Configurem-te a %{domain}. status: account_status: Estat del compte confirming: Esperant que es completi la confirmació del correu electrònic. @@ -1017,18 +1104,6 @@ ca: view_strikes: Veure accions del passat contra el teu compte too_fast: Formulari enviat massa ràpid, torna a provar-ho. use_security_key: Usa clau de seguretat - authorize_follow: - already_following: Ja estàs seguint aquest compte - already_requested: Ja has enviat una sol·licitud de seguiment a aquest usuari - error: Malauradament, ha ocorregut un error cercant el compte remot - follow: Segueix - follow_request: 'Has enviat una sol·licitud de seguiment a:' - following: 'Perfecte! Ara segueixes:' - post_follow: - close: O bé, pots tancar aquesta finestra. - return: Mostra el perfil de l'usuari - web: Vés a la web - title: Segueix %{acct} challenge: confirm: Continua hint_html: "Pista: No et preguntarem un altre cop la teva contrasenya en la pròxima hora." @@ -1063,7 +1138,7 @@ ca: proceed: Elimina el compte success_msg: El compte s'ha eliminat correctament warning: - before: 'Abans de procedir si us plau llegeix amb cura aquestes notes:' + before: 'Abans de procedir, llegiu amb cura aquestes notes:' caches: El contingut que ha estat memoritzat en la memòria cau per altres servidors pot persistir data_removal: Els teus tuts i altres dades seran permanentment eliminades email_change_html: Pots canviar la teva adreça de correu electrònic sense eliminar el teu compte @@ -1105,6 +1180,10 @@ ca: your_appeal_rejected: La teva apel·lació ha estat rebutjada domain_validator: invalid_domain: no es un nom de domini vàlid + edit_profile: + basic_information: Informació bàsica + hint_html: "Personalitza el que la gent veu en el teu perfil públic i a prop dels teus tuts.. És més probable que altres persones et segueixin i interaccionin amb tu quan tens emplenat el teu perfil i amb la teva imatge." + other: Altres errors: '400': La sol·licitud que vas emetre no era vàlida o no era correcta. '403': No tens permís per a veure aquesta pàgina. @@ -1139,7 +1218,7 @@ ca: mutes: Persones silenciades storage: Emmagatzematge featured_tags: - add_new: Afegir nova etiqueta + add_new: Afegeix-ne una de nova errors: limit: Ja has mostrat la quantitat màxima d'etiquetes hint_html: "Què son les etiquetes destacades? Es mostren de manera destacada en el teu perfil públic i permeten a les persones navegar per els teus tuts gràcies a aquestes etiquetes. Són una gran eina per fer un seguiment de treballs creatius o de projectes a llarg termini." @@ -1185,8 +1264,6 @@ ca: index: hint: Aquest filtre aplica als tuts seleccionats independentment d'altres criteris. Pots afegir més tuts a aquest filtre des de la interfície Web. title: Tuts filtrats - footer: - trending_now: En tendència generic: all: Tot all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ ca: all_matching_items_selected_html: one: "%{count} article coincident amb la teva cerca està seleccionat." other: Tots %{count} articles coincidents amb la teva cerca estan seleccionats. + cancel: Cancel·la changes_saved_msg: Els canvis s'han desat correctament! + confirm: Confirma copy: Copiar delete: Elimina deselect: Desfer selecció @@ -1208,25 +1287,63 @@ ca: today: avui validation_errors: one: Alguna cosa no va bé! Si us plau, revisa l'error - other: Alguna cosa no va bé! Si us plau, revisa %{count} errors més a baix - html_validator: - invalid_markup: 'conté HTML markup no vàlid: %{error}' + other: Alguna cosa no va bé! Reviseu els %{count} errors següents imports: errors: + empty: Fitxer CSV buit + incompatible_type: Incompatible amb el tipus d'importació seleccionada invalid_csv_file: 'Fitxer CSV invàlid. Error: %{error}' over_rows_processing_limit: conté més de %{count} files + too_large: El fitxer és massa gran + failures: Fallades + imported: Importat + mismatched_types_warning: Sembla que has seleccionat un tipus erròni per aquesta importació, si ja plau revisa-ho. modes: merge: Fusionar merge_long: Mantenir els registres existents i afegir-ne de nous overwrite: Sobreescriu overwrite_long: Reemplaça els registres actuals amb els nous + overwrite_preambles: + blocking_html: Ets a punt per a reemplaçar la teva llista de bloquejos de fins a %{total_items} comptes des de %{filename}. + bookmarks_html: Ets a punt de reemplaçar els teus marcadors de fins a %{total_items} tuts des de %{filename}. + domain_blocking_html: Ets a punt de reemplaçar la teva llista de dominis bloquejats de fins a %{total_items} dominis des de %{filename}. + following_html: Ets a punt de seguir fins a %{total_items} comptes des de %{filename} i deixar de seguir a la resta. + lists_html: Estàs a punt de reemplaçar les teves llistes amb contactes de %{filename}. S'afegiran fins a %{total_items} comptes a les noves llistes. + muting_html: Ets a punt de reemplaçar la teva llista de comptes silenciats de fins a %{total_items} comptes des de %{filename}. + preambles: + blocking_html: Ets a punt de bloquejar fins a %{total_items} comptes des de %{filename}. + bookmarks_html: Ets a punt d'afegir fins a %{total_items} tuts des de %{filename} als teus marcadors. + domain_blocking_html: Ets a punt de bloquejar fins a %{total_items} dominis des de %{filename}. + following_html: Ets a punt de seguir fins a %{total_items} comptes des de %{filename}. + lists_html: Estàs a punt d'afegir %{total_items} comptes de %{filename} a les teves llistes. Es crearan noves llistes si no hi ha cap llista on afegir-los. + muting_html: Ets a punt de silenciar fins a %{total_items} comptes des de %{filename}. preface: Pots importar algunes les dades que has exportat des d'un altre servidor, com ara el llistat de les persones que estàs seguint o bloquejant. + recent_imports: Importacions recents + states: + finished: Finalitzat + in_progress: En curs + scheduled: Planificat + unconfirmed: Sense confirmar + status: Estat success: Les dades s'han rebut correctament i es processaran en breu + time_started: Va començar el + titles: + blocking: Important comptes bloquejats + bookmarks: Important marcadors + domain_blocking: Important dominis bloquejats + following: Important comptes seguits + lists: Important llistes + muting: Important comptes silenciats + type: Tipus d'importació + type_groups: + constructive: Seguits i Marcadors + destructive: Bloquejos i Silenciats types: blocking: Llista de blocats bookmarks: Marcadors domain_blocking: Llistat de dominis bloquejats following: Llista de seguits + lists: Llistes muting: Llista de silenciats upload: Carrega invites: @@ -1262,9 +1379,24 @@ ca: webauthn: claus de seguretat description_html: Si veus activitat que no reconeixes, considera canviar la teva contrasenya i activar l'autenticació de dos factors. empty: Historial d'autenticació no disponible - failed_sign_in_html: Intent d'inici de sessió errat amb %{method} des-de %{ip} (%{browser}) - successful_sign_in_html: Inici de sessió exitós amb %{method} des-de %{ip} (%{browser}) + failed_sign_in_html: Intent d'inici de sessió errat amb %{method} des de %{ip} (%{browser}) + successful_sign_in_html: Inici de sessió exitós amb %{method} des de %{ip} (%{browser}) title: Historial d'autenticació + mail_subscriptions: + unsubscribe: + action: Sí, canceŀla la subscripció + complete: Subscripció cancel·lada + confirmation_html: Estàs segur que vols donar-te de baixa de rebre %{type} de Mastodon a %{domain} en el teu correu electrònic a %{email}? Sempre pots subscriure't de nou des de la configuració de les notificacions per correu electrònic. + emails: + notification_emails: + favourite: notificacions dels favorits per correu electrònic + follow: notificacions dels seguiments per correu electrònic + follow_request: correus electrònics de peticions de seguiment + mention: correus electrònics de notificacions de mencions + reblog: correus electrònics de notificacions d'impulsos + resubscribe_html: Si ets dones de baixa per error, pots donar-te d'alta des de la configuració de les notificacions per correu electrònic. + success_html: Ja no rebràs %{type} de Mastodon a %{domain} en la teva safata a %{email}. + title: Cancel·la la subscripció media_attachments: validations: images_and_video: No es pot adjuntar un vídeo a una publicació que ja contingui imatges @@ -1277,7 +1409,7 @@ ca: cancelled_msg: Redirecció cancel·lada amb èxit. errors: already_moved: és el mateix compte al que ja t'has mogut - missing_also_known_as: no fa referencia a aquest compte + missing_also_known_as: no fa referència a aquest compte move_to_self: no pot ser el compte actual not_found: podria no ser trobat on_cooldown: Estàs en temps de refredament @@ -1294,7 +1426,7 @@ ca: set_redirect: Ajusta la redirecció warning: backreference_required: El compte nou primer ha de ser configurat per a referenciar aquest - before: 'Abans de procedir si us plau llegeix amb cura aquestes notes:' + before: 'Abans de procedir, llegiu amb cura aquestes notes:' cooldown: Després de moure't hi ha un període de recuperació durant el qual no seràs capaç de moure't un altre cop 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 @@ -1332,7 +1464,7 @@ ca: action: Respon body: "%{name} t'ha mencionat en:" subject: "%{name} t'ha mencionat" - title: Menció nova + title: Nova menció poll: subject: Ha finalitzat l'enquesta de %{name} reblog: @@ -1344,6 +1476,7 @@ ca: update: subject: "%{name} ha editat una publicació" notifications: + administration_emails: Notificacions per correu-e de l'Admin email_events: Esdeveniments per a notificacions de correu electrònic email_events_hint: 'Selecciona els esdeveniments per als quals vols rebre notificacions:' other_settings: Altres opcions de notificació @@ -1380,12 +1513,22 @@ ca: expired: L'enquesta ja ha finalitzat invalid_choice: L’opció de vot escollida no existeix over_character_limit: no pot ser superior a %{max} caràcters cadascun + self_vote: No pots votar en les teves propies enquestes too_few_options: ha de tenir més d'una opció too_many_options: no pot contenir més de %{max} opcions preferences: other: Altre posting_defaults: Valors per defecte de publicació public_timelines: Línies de temps públiques + privacy: + hint_html: "Personalitza com vols que siguin trobats el teu perfil i els teus tuts. Una varietat de característiques de Mastodon et poden ajudar a arribar a una major audiència quan les actives. Dedica una estona a revisar aquests ajustaments per assegurar que son els que necessites." + privacy: Privacitat + privacy_hint_html: Controla quant vols revelar en benefici d'altres. La gent descobreix perfils interessants i aplicacions genials tot navegant per els usuaris seguits d'altres persones i veient des de quines aplicacions publiquen, però pots preferir mantenir-ho amagat. + reach: Arribar a + reach_hint_html: Controla si vols ser descobert i seguit per gent nova. Vols que els teus tuts apareguin en la pantalla de Explora? Vols que altres persones et vegin en les seves recomanacions de seguiment? Vols acceptar automàticament als nous seguidors o tenir un control granular sobre cadascun d'ells? + search: Cerca + search_hint_html: Controla com vols ser trobat. Vols que la gent et trobi per el que publiques? Vols que la gent fora de Mastodon trobi el teu perfil quan cerquin la web? Has de tenir en compte que no es pot garantir la exclusió total de tots els motors de cerca per a la informació pública. + title: Privacitat i arribar privacy_policy: title: Política de Privacitat reactions: @@ -1398,6 +1541,7 @@ ca: confirm_remove_selected_followers: Segur que vols esborrar els seguidors seleccionats? confirm_remove_selected_follows: Segur que vols esborrar els seguits seleccionats? dormant: Inactiu + follow_failure: No es poden seguir alguns dels comptes seleccionats. follow_selected_followers: Segueix als seguidors seleccionats followers: Seguidors following: Seguint @@ -1413,7 +1557,7 @@ ca: remove_selected_follows: Deixa de seguir els usuaris seleccionats status: Estat del compte remote_follow: - missing_resource: No s'ha pogut trobar l'URL de redirecció necessària per al compte + missing_resource: No s'ha pogut trobar l'enllaç de redirecció necessari per al compte reports: errors: invalid_rules: no fa referència a normes vàlides @@ -1437,15 +1581,17 @@ ca: electron: Electron firefox: Firefox generic: Navegador desconegut + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger - nokia: Nokia S40 Ovi Browser + nokia: Navegador Nokia S40 Ovi opera: Opera otter: Otter phantom_js: PhantomJS - qq: QQ Browser + qq: Navegador QQ safari: Safari uc_browser: Navegador UC + unknown_browser: Navegador Desconegut weibo: Weibo current_session: Sessió actual description: "%{browser} de %{platform}" @@ -1458,9 +1604,10 @@ ca: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: plataforma desconeguda + unknown_platform: Plataforma desconeguda windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1531,7 +1678,6 @@ ca: show_newer: Mostra els més nous show_older: Mostra els més vells show_thread: Mostra el fil - sign_in_to_participate: Inicia la sessió per participar a la conversa title: '%{name}: "%{quote}"' visibilities: direct: Directe @@ -1573,12 +1719,10 @@ ca: '7889238': 3 mesos min_age_label: Antiguitat min_favs: Mantenir els tuts afavorits més de - min_favs_hint: No suprimeix cap dels teus tuts que hagin rebut més d'aquesta quantitat de favorits. Deixa-ho en blanc per a suprimir tuts independentment del nombre de favorits que tinguin + min_favs_hint: No suprimeix cap dels teus tuts que hagin rebut més d'aquesta quantitat de favorits. Deixa-ho en blanc per a suprimir tuts independentment del nombre de favorits min_reblogs: Mantenir les publicacions impulsades més de min_reblogs_hint: No suprimeix cap de les teves publicacions que s'hagin impulsat més que aquest nombre de vegades. Deixa-ho en blanc per a suprimir les publicacions independentment del nombre d'impulsos que tinguin. stream_entries: - pinned: Publicació fixada - reblogged: ha impulsat sensitive_content: Contingut sensible strikes: errors: @@ -1594,6 +1738,11 @@ ca: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: S'ha superat la quota d'ús de tot el servidor per el servei de traducció. + too_many_requests: Hi ha hagut massa sol·licituds al servei de traducció recentment. two_factor_authentication: add: Afegeix disable: Desactiva @@ -1625,11 +1774,11 @@ ca: title: Recollida de l'arxiu suspicious_sign_in: change_password: canvia la teva contrasenya - details: 'Aquí estan els detalls del inici de sessió:' - explanation: Hem detectat un inici de sessió del teu compte des d'una nova adreça IP. - further_actions_html: Si no has estat tu, et recomanem %{action} immediatament i activis l'autenticació de dos-factors per a mantenir el teu compte segur. + details: 'Aquest són els detalls de l''inici de sessió:' + explanation: Hem detectat un inici de sessió del teu compte des d'una adreça IP nova. + further_actions_html: Si no has estat tu, %{action} immediatament i activa l'autenticació de dos-factors per a mantenir el teu compte segur. subject: S'ha accedit al teu compte des d'una adreça IP nova - title: Un nou inici de sessió + title: Un inici de sessió nou warning: appeal: Envia una apel·lació appeal_description: Si creus que això és un error, pots enviar una apel·lació a l'equip de %{instance}. @@ -1639,8 +1788,8 @@ ca: explanation: delete_statuses: S'ha trobat que algunes de les teves publicacions violen una o més directrius de la comunitat i, per tant, han estat eliminades pels moderadors de %{instance}. disable: Ja no pots utilitzar el teu compte, però el teu perfil i altres dades encara són intactes. Pots demanar una còpia de les teves dades, canviar els ajustaments del teu compte o esborrar-lo. - mark_statuses_as_sensitive: Algunes de les teves publicacions han estat marcades com a sensibles pels moderadors de %{instance}. Això significa que la gent necessitarà tocar els mèdia en les publicacions perquè la previsualització es mostri. Tu mateix pots marcar els teus mèdia com a sensibles quan publiquis en el futur. - sensitive: A partir d'ara, tots els mèdia pujats seran marcats com a sensibles i ocultats darrere d'un avís. + mark_statuses_as_sensitive: Algunes de les teves publicacions han estat marcades com a sensibles pels moderadors de %{instance}. Això significa que la gent haurà de tocar els mèdia a les publicacions perquè es mostri la previsualització. Pots marcar els teus mateixos mèdia com a sensibles quan publiquis en el futur. + sensitive: A partir d'ara, tots els fitxers pujats seran marcats com a sensibles i ocultats darrere d'un avís. silence: Encara pots fer servir el teu compte però només la gent que ja t'està seguint veuran les teves publicacions en aquest servidor i tu podries ser exclòs de les diverses opcions de descobriment. De totes maneres altres podrien encara seguir-te manualment. suspend: Ja no pots usar el teu compte i el teu perfil i altres dades ja no són accessibles. Encara pots iniciar sessió per a demanar una còpia de les teves dades fins que siguin totalment eliminades al cap de 30 dies, però es mantindran les dades bàsiques per a evitar que esquivis la suspensió. reason: 'Motiu:' @@ -1663,7 +1812,7 @@ ca: suspend: Compte suspès welcome: edit_profile_action: Configura el perfil - edit_profile_step: Pots personalitzar el teu perfil pujant-hi un avatar, canviant el teu nom de visualització i molt més. Si ho prefereixes, pots revisar els seguidors nous abans de que et puguin seguir. + edit_profile_step: Pots personalitzar el teu perfil pujant-hi un avatar, canviant el teu nom de visualització i molt més. Si ho prefereixes, pots revisar els seguidors nous abans que et puguin seguir. explanation: Aquests són alguns consells per a començar final_action: Comença a publicar final_step: 'Comença a publicar! Fins i tot sense seguidors, els altres poden veure els teus missatges públics, per exemple, a la línia de temps local i a les etiquetes. És possible que vulguis presentar-te amb l''etiqueta #introductions.' @@ -1673,13 +1822,18 @@ ca: title: Benvingut a bord, %{name}! users: follow_limit_reached: No pots seguir més de %{limit} persones + go_to_sso_account_settings: Ves a la configuració del compte del teu proveïdor d'identitat invalid_otp_token: El codi de dos factors no és correcte otp_lost_help_html: Si has perdut l'accés a tots dos pots contactar per %{email} seamless_external_login: Has iniciat sessió via un servei extern per tant els ajustos de contrasenya i correu electrònic no estan disponibles. signed_in_as: 'Sessió iniciada com a:' verification: - explanation_html: 'Pots verificar-te com a propietari dels enllaços a les metadades del teu perfil. Per això, el lloc web enllaçat ha de contenir un enllaç al teu perfil de Mastodon. El vincle ha de tenir l''atribut rel="me". El contingut del text de l''enllaç no importa. Aquí tens un exemple:' + extra_instructions_html: Consell: l'enllaç al vostre lloc web pot ser invisible. La part important és rel="me" que evita que us suplantin la identitat a llocs web amb contingut generat pels usuaris. Fins i tot podeu generar una etiqueta link a la capçalera de la pàgina en comptes d'una a, però el codi HTML ha de ser accessible sense requerir executar JavaScript. + here_is_how: Així és com + hint_html: "Verificar la pròpia identitat a Mastodon és per a tothom. Basat en estàndarts webs oberts, ara i per sempre. Només et cat un lloc web personal que la gent reconegui com a teu. Quan hi enllacis des del teu perfil, comprovarem que el web retorna l'enllaç al perfil i hi posarem un indicador visual." + instructions_html: Copieu i enganxeu el següent codi HTML al vostre lloc web. Després, afegiu l'adreça del vostre lloc web dins d'un dels camps extres del vostre perfil i deseu els canvis. verification: Verificació + verified_links: Els teus enllaços verificats webauthn_credentials: add: Afegir nova clau de seguretat create: @@ -1695,5 +1849,5 @@ ca: nickname_hint: Introdueix el sobrenom de la teva clau de seguretat nova not_enabled: Encara no has activat WebAuthn not_supported: Aquest navegador no suporta claus de seguretat - otp_required: Per emprar claus de seguretat si us plau activa primer l'autenticació de dos factors. + otp_required: Per a usar claus de seguretat, activeu primer l'autenticació de dos factors. registered_on: Registrat en %{date} diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index 19e1d50f42..9a974b9ed7 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -119,8 +119,6 @@ ckb: removed_header_msg: بە سەرکەوتوویی وێنەی سەرپەڕەی %{username} لابرا resend_confirmation: already_confirmed: ئەم بەکارهێنەرە پێشتر پشتڕاستکراوەتەوە - send: دووبارە ناردنی ئیمەیڵی دووپاتکردنەوە - success: ئیمەیڵی پشتڕاستکردنەوە بە سەرکەوتوویی نێردرا! reset: ڕێکخستنەوە reset_password: گەڕانەوەی تێپەڕوشە resubscribe: دووبارە ئابونەبوون @@ -573,7 +571,6 @@ ckb: body: ماستۆدۆن لەلایەن خۆبەخشەوە وەردەگێڕێت. guide_link_text: هەموو کەسێک دەتوانێت بەشداری بکات. sensitive_content: ناوەڕۆکی هەستیار - toot_layout: لۆی توت application_mailer: notification_preferences: گۆڕینی پەسەندکراوەکانی ئیمەیڵ salutation: "%{name}," @@ -589,14 +586,12 @@ ckb: warning: زۆر ئاگاداربە لەم داتایە. هەرگیز لەگەڵ کەس دا هاوبەشی مەکە! your_token: کۆدی دەستپێگەیشتنی ئێوە auth: - change_password: تێپەڕوشە delete_account: سڕینەوەی هەژمارە delete_account_html: گەر هەرەکتە هەژمارەکەت بسڕیتەوە، لە لەم قوناغانە بڕۆیتە پێشەوە. داوای پەسەند کردنتان لێدەگیرێت. description: prefix_invited_by_user: "@%{name} بانگت دەکات بۆ پەیوەندیکردن بەم ڕاژەی ماستۆدۆن!" prefix_sign_up: ئەمڕۆ خۆت تۆمار بکە لە ماستۆدۆن! suffix: بە هەژمارەیەک، دەتوانیت شوێن هەژمارەکانی دیکە بکەویت، نوێکردنەوەکان بڵاوبکەوە و نامە لەگەڵ بەکارهێنەران لە هەر ڕاژەیەکی ماستۆدۆن و زیاتر بگۆڕیتەوە! - didnt_get_confirmation: ڕێنماییەکانی دڵنیاکردنەوەت پێنەدرا? dont_have_your_security_key: کلیلی ئاسایشت نیە? forgot_password: تێپەڕوشەکەت لەبیر چووە? invalid_reset_password_token: وشەی نهێنی دووبارە ڕێکبخەوە دروست نیە یان بەسەرچووە. تکایە داوایەکی نوێ بکە. @@ -613,14 +608,9 @@ ckb: saml: SAML register: خۆ تۆمارکردن registration_closed: "%{instance} ئەندامانی نوێ قبووڵ ناکات" - resend_confirmation: دووبارە ناردنی ڕێنماییەکانی دووپاتکردنەوە reset_password: گەڕانەوەی تێپەڕوشە security: ئاسایش set_new_password: سازدانی تێپەڕوشەی نوێ - setup: - email_below_hint_html: ئەگەر ناونیشانی ئیمەیڵی خوارەوە نادروستە، دەتوانیت لێرە بیگۆڕیت و ئیمەیڵێکی پشتڕاستکردنەوەی نوێ وەربگۆڕیت. - email_settings_hint_html: ئیمەیڵی پشتڕاستکردنەوە کە نێردرا بۆ %{email}. ئەگەر ناونیشانی ئیمەیڵ ڕاست نەبوو، دەتوانیت لە ڕێکبەندەکانی هەژمارەکەت بیگۆڕیت. - title: دامەزراندن status: account_status: دۆخی هەژمارە confirming: چاوەڕوانی دڵنیاکردنەوەی ئیمەیڵ بۆ تەواوکردن. @@ -630,18 +620,6 @@ ckb: view_strikes: بینینی لێدانەکانی ڕابردوو لە دژی ئەکاونتەکەت too_fast: فۆڕم زۆر خێرا پێشکەش کراوە، دووبارە هەوڵبدەرەوە. use_security_key: کلیلی ئاسایش بەکاربهێنە - authorize_follow: - already_following: ئێوە ئێستا شوێن کەوتووی ئەم هەژمارەیەی - already_requested: تۆ پێشتر داواکاری بەدواداچوت ناردوە بۆ ئەو هەژمارە - error: بەداخەوە هەڵەیەک هەبوو لە کاتی گەڕان بەدوای ئەو هەژمارەیە - follow: شوێن کەوە - follow_request: 'تۆ داواکاری شوێنکەوتنت ناردووە بۆ:' - following: 'ئەنجام بوو! تۆ ئێستا بەدوای ئەم بەکارهێنەرە دەکەویت:' - post_follow: - close: یان، دەتوانیت ئەم پەنجەرەیە دابخەیت. - return: پرۆفایلی بەکارهێنەر نیشان بدە - web: بڕۆ بۆ وێب - title: دوای %{acct} بکەوە challenge: confirm: بەردەوام بە hint_html: "خاڵ: ئیمە لە کاتژمێری داهاتوو تێپەروشەت لێداوا ناکەین." @@ -726,8 +704,6 @@ ckb: storage: هەمارگەی میدیا featured_tags: add_new: زیادکردنی نوێ - errors: - limit: ئێوە ژمارەی بڕی ڕێگەپێدراوەی هاشتاگت هەیە hint_html: " هاشتاگی تایبەت چییە؟ بە شێوەیەکی دیار نیشان دەدرێت لەسەر پرۆفایلی گشتی و ڕێگە بە خەڵک دەدات بۆ گەڕان لە نووسراوە گشتیەکانت بە تایبەتی لەژێر ئەو هاشتاگە. ئامرازێکی زۆر باشن بۆ پاراستنی کاری داهێنەرانە یان پڕۆژەی درێژخایەنی ئێوە." filters: contexts: @@ -746,8 +722,6 @@ ckb: title: فلتەرەکان new: title: زیادکردنی فلتەری نوێ - footer: - trending_now: هەوادارانی ئێستا generic: all: هەموو changes_saved_msg: گۆڕانکاریەکان بە سەرکەوتوویی هەڵگیرا! @@ -758,8 +732,6 @@ ckb: validation_errors: one: شتێک هێشتا تەواو ڕاست نیە تکایە چاو بە هەڵەکەی خوارەوە بخشێنەوە other: هێشتا تەواو ڕاست نیە تکایە چاو بە هەڵەی %{count} خوارەوە بخشێنەوە - html_validator: - invalid_markup: 'نیشانەی HTML نادروستی تێدایە: %{error}' imports: modes: merge: یەکخستن @@ -797,9 +769,6 @@ ckb: expires_at: بەسەرچووە uses: بەکارهاوردنەکان title: بانگهێشتکردنی خەڵک - lists: - errors: - limit: تۆ گەیشتوویتە زۆرترین ڕێژەی لیستەکان media_attachments: validations: images_and_video: ناتوانرێت لەگەڵ ئەو نووسراوانە کە وێنەی لەگەڵە ،ڤیدیۆ بار بکەی @@ -950,7 +919,6 @@ ckb: firefox_os: سیستەمی کارگێڕی فایەرفۆکس linux: لینۆکس mac: ماک - other: سیستەمیکارگێڕی نەناسراو windows: ویندۆز windows_mobile: ویندۆزموبایل windows_phone: ویندۆزفۆن @@ -1015,7 +983,6 @@ ckb: show_newer: نوێتر پیشان بدە show_older: پیشاندانی کۆنتر show_thread: نیشاندانی ڕشتە - sign_in_to_participate: بچۆ ژوورەوە بۆ بەشداریکردن لە گفتوگۆکەدا visibilities: private: شوێنکەوتوانی تەنها private_long: تەنها بۆ شوێنکەوتوانی پیشان بدە @@ -1024,8 +991,6 @@ ckb: unlisted: پێرست نەبووە unlisted_long: هەموو کەس دەتوانێت بیبینێت، بەڵام لە هێڵی کاتی گشتی دا نەریزراوە stream_entries: - pinned: توتی چەسپکراو - reblogged: بەهێزکردن sensitive_content: ناوەڕۆکی هەستیار tags: does_not_match_previous_name: لەگەڵ ناوی پێشوو یەک ناگرێتەوە @@ -1080,7 +1045,6 @@ ckb: seamless_external_login: تۆ لە ڕێگەی خزمەتگوزاری دەرەکیەوە داخڵ بووی، بۆیە ڕێکبەندەکانی نهێنوشە و ئیمەیل بەردەست نین. signed_in_as: 'چوونە ژوورەوە وەک:' verification: - explanation_html: 'دەتوانیت خۆت بسەلمێنیت وەک خاوەنی لینکەکان لە مێتاداتای پرۆفایلەکەت. بۆ ئەمە، ماڵپەڕە لینککراوەکە پێویستە لینکێکی تێدا بێت بۆ پرۆفایلی ماستۆدۆنەکەت. بەستەری دەبێت هەبێت ="me". ناوەڕۆکی دەقی لینکەکە گرنگ نییە. ئەمە نموونەیەکە:' verification: ساغ کردنەوە webauthn_credentials: add: زیادکردنی کلیلی ئاسایشی نوێ diff --git a/config/locales/co.yml b/config/locales/co.yml index 2ab6c63f96..e613ea7606 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -108,8 +108,6 @@ co: removed_header_msg: U ritrattu di cuprendula di %{username} hè statu toltu resend_confirmation: already_confirmed: St’utilizatore hè digià cunfirmatu - send: Rimandà un’e-mail di cunfirmazione - success: L’e-mail di cunfirmazione hè statu mandatu! reset: Riinizializà reset_password: Riinizializà a chjave d’accessu resubscribe: Riabbunassi @@ -539,7 +537,6 @@ co: guide_link: https://fr.crowdin.com/project/mastodon guide_link_text: Tuttu u mondu pò participà. sensitive_content: Cuntinutu sensibile - toot_layout: Urganizazione application_mailer: notification_preferences: Cambià e priferenze e-mail salutation: "%{name}," @@ -555,14 +552,12 @@ co: warning: Abbadate à quessi dati. Ùn i date à nisunu! your_token: Rigenerà a fiscia d’accessu auth: - change_password: Chjave d’accessu delete_account: Sguassà u contu delete_account_html: S’è voi vulete toglie u vostru contu ghjè quì. Duverete cunfirmà a vostra scelta. description: prefix_invited_by_user: "@%{name} v'invita à raghjunghje stu servore di Mastodon!" prefix_sign_up: Arregistratevi nant'à Mastodon oghji! suffix: Cù un contu, puderete siguità l'altri, pustà statuti è scambià missaghji cù l'utilizatori di tutti i servori Mastodon è ancu di più! - didnt_get_confirmation: Ùn avete micca ricevutu l’istruzione di cunfirmazione? dont_have_your_security_key: Ùn avete micca a chjave di sicurità? forgot_password: Chjave scurdata? invalid_reset_password_token: U ligame di riinizializazione di a chjave d’accessu hè spiratu o ùn hè micca validu. Pudete dumandà un'altru ligame. @@ -578,14 +573,9 @@ co: saml: SAML register: Arregistrassi registration_closed: "%{instance} ùn accetta micca novi socii" - resend_confirmation: Rimandà l’istruzzioni di cunfirmazione reset_password: Cambià a chjave d’accessu security: Sicurità set_new_password: Creà una nova chjave d’accessu - setup: - email_below_hint_html: S'è l'indirizzu e-mail quì sottu ùn hè micca currettu, pudete cambiallu quì è riceve un novu e-mail di cunfirmazione. - email_settings_hint_html: L'e-mail di cunfirmazione hè statu mandatu à l'indirizzu %{email}. S'ellu ùn hè micca currettu, pudete cambiallu in i parametri di u contu. - title: Stallazione status: account_status: Statutu di u contu confirming: In attesa di a cumplezzione di a cunfirmazione di l'e-mail. @@ -593,18 +583,6 @@ co: redirecting_to: U vostru contu hè inattivu perchè riindirizza versu %{acct}. too_fast: Furmulariu mandatu troppu prestu, ripruvate. use_security_key: Utilizà a chjave di sicurità - authorize_follow: - already_following: Site digià abbunatu·a à stu contu - already_requested: Avete digià mandatu una dumanda d'abbunamentu à stu contu - error: Peccatu, c’hè statu un prublemu ricercandu u contu - follow: Siguità - follow_request: 'Avete dumandatu di siguità:' - following: 'Eccu! Avà seguitate:' - post_follow: - close: O pudete ancu chjude sta finestra. - return: Vede u prufile di l’utilizatore - web: Andà à l’interfaccia web - title: Siguità %{acct} challenge: confirm: Cuntinuvà hint_html: "Astuzia: Ùn avemu micca da dumandavvi stu codice per l'ore chì vene." @@ -686,8 +664,6 @@ co: storage: I vostri media featured_tags: add_new: Aghjunghje - errors: - limit: Avete digià messu in mostra u numeru massimale di hashtag hint_html: "Quale sò i hashtag in mostra? Sò messi in vista nant'à u vostru prufile pubblicu è permettenu à a ghjente di vede i vostri statuti ch'annu stu hashtag. Sò una bona manere di mustrà e vostre opere creative o i prughjetti à longu termine." filters: contexts: @@ -706,8 +682,6 @@ co: title: Filtri new: title: Aghjunghje un novu filtru - footer: - trending_now: Tindenze d'avà generic: all: Tuttu changes_saved_msg: Cambiamenti salvati! @@ -718,8 +692,6 @@ co: validation_errors: one: Qualcosa ùn và bè! Verificate u prublemu quì sottu other: Qualcosa ùn và bè! Verificate %{count} prublemi quì sottu - html_validator: - invalid_markup: 'cuntene codice HTML invalidu: %{error}' imports: errors: over_rows_processing_limit: cuntene più di %{count} filari @@ -759,9 +731,6 @@ co: expires_at: Spira uses: Utiliza title: Invità ghjente - lists: - errors: - limit: Ùn pudete più creà altre liste login_activities: authentication_methods: otp: app d'identificazione à dui fattori @@ -937,7 +906,6 @@ co: ios: iOS linux: Linux mac: macOS - other: piattaforma scunnisciuta windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1002,7 +970,6 @@ co: show_newer: Vede i più ricenti show_older: Vede i più anziani show_thread: Vede u filu - sign_in_to_participate: Cunnettatevi per participà à a cunversazione title: '%{name}: "%{quote}"' visibilities: direct: Direttu @@ -1032,17 +999,13 @@ co: '2629746': 1 mese '31556952': 1 annu '5259492': 2 mesi - '604800': 1 week '63113904': 2 anni '7889238': 3 mesi min_age_label: Età minima min_favs: Cunservà i statuti favurizzati più di - min_favs_hint: Ùn sguassa micca i vostri statuti chì anu ricevuti più chì stu numeru di favuriti. Lasciate viotu per sguassà i statuti senza piglià in contu u numaru di favuriti min_reblogs: Cunservà i statuti spartuti più di min_reblogs_hint: Ùn sguassa micca i vostri statuti chì anu ricevuti più chì stu numeru di spartere. Lasciate viotu per sguassà i statuti senza piglià in contu u numaru di spartere stream_entries: - pinned: Statutu puntarulatu - reblogged: hà spartutu sensitive_content: Cuntenutu sensibile tags: does_not_match_previous_name: ùn currisponde micca à l'anzianu nome @@ -1100,7 +1063,6 @@ co: seamless_external_login: Site cunnettatu·a dapoi un serviziu esternu, allora i parametri di chjave d’accessu è d’indirizzu e-mail ùn so micca dispunibili. signed_in_as: 'Cunnettatu·a cum’è:' verification: - explanation_html: 'Pudete verificavi cum''è u pruprietariu di i ligami in i metadati di u vostru prufile. Per quessa, u vostru situ deve avè un ligame versu a vostra pagina Mastodon. U ligame deve avè un''attributu rel="me". U cuntenutu di u testu di u ligame ùn hè micca impurtante. Eccu un''esempiu:' verification: Verificazione webauthn_credentials: add: Aghjunghje una chjave di sicurità diff --git a/config/locales/cs.yml b/config/locales/cs.yml index f96eaae15f..03ec9708d5 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -95,6 +95,7 @@ cs: moderation: active: Aktivní all: Vše + disabled: Deaktivován pending: Čekající silenced: Omezeno suspended: Pozastavené @@ -130,8 +131,8 @@ cs: removed_header_msg: Úspěšně odstraněn obrázek záhlaví uživatele %{username} resend_confirmation: already_confirmed: Tento uživatel je již potvrzen - send: Znovu odeslat potvrzovací e-mail - success: Potvrzovací e-mail byl úspěšně odeslán! + send: Znovu odeslat potvrzovací odkaz + success: Potvrzovací odkaz byl úspěšně odeslán! reset: Obnovit reset_password: Obnovit heslo resubscribe: Znovu odebírat @@ -139,6 +140,7 @@ cs: search: Hledat search_same_email_domain: Ostatní uživatelé se stejnou e-mailovou doménou search_same_ip: Další uživatelé se stejnou IP adresou + security: Zabezpečení security_measures: only_password: Pouze heslo password_and_2fa: Heslo a 2FA @@ -313,6 +315,7 @@ cs: unpublish: Skrýt unpublished_msg: Zveřejněné oznámení bylo úspěšně skryto! updated_msg: Oznámení bylo úspěšně aktualizováno! + critical_update_pending: Čeká se na kritickou aktualizaci custom_emojis: assign_category: Přiřadit kategorii by_domain: Doména @@ -394,6 +397,15 @@ cs: undo: Zakázat federaci s doménou domain_blocks: add_new: Přidat novou blokaci domény + confirm_suspension: + cancel: Zrušit + confirm: Pozastavit + permanent_action: Zrušení pozastavení neobnoví žádná data ani vztah. + preamble_html: Chystáte se pozastavit %{domain} a jeho poddomény. + remove_all_data: Tímto odstraníte z vašeho serveru všechen obsah, média a profilové údaje účtů této domény. + stop_communication: Váš server přestane komunikovat s těmito servery. + title: Potvrďte blokování domény %{domain} + undo_relationships: Toto vrátí jakýkoliv vztah sledování mezi účty na těchto serverech a vaším. created_msg: Blokace domény se právě vyřizuje destroyed_msg: Blokace domény byla odvolána domain: Doména @@ -443,6 +455,7 @@ cs: resolve: Přeložit doménu title: Blokovat novou e-mailovou doménu no_email_domain_block_selected: Žádné blokace e-mailové domény nebyly změněny, protože nebyly žádné vybrány + not_permitted: Nepovoleno resolved_dns_records_hint_html: Doménové jméno vede na následující MX domény, které mají nakonec na starost přijímání e-mailů. Blokování MX domény zablokuje registrace z jakékoliv e-mailové adresy, která používá stejnou MX doménu, i když je viditelné doménové jméno jiné. Dejte si pozor, abyste nezablokovali velké e-mailové poskytovatele. resolved_through_html: Přeložena přes %{domain} title: Blokované e-mailové domény @@ -457,6 +470,7 @@ cs: private_comment_description_html: 'Abychom vám pomohli sledovat, odkud pochází importované bloky, budou tyto importované bloky vytvořeny s následující soukromou poznámkou: %{comment}' private_comment_template: Importováno z %{source} dne %{date} title: Importovat blokované domény + invalid_domain_block: 'Jeden nebo více bloků domén bylo přeskočeno z důvodu chyb(y): %{error}' new: title: Importovat blokované domény no_file: Nebyl vybrán žádný soubor @@ -492,6 +506,7 @@ cs: content_policies: comment: Interní poznámka description_html: Můžete definovat politiky obsahu, které budou aplikovány na všechny účty z této domény i jakoukoliv z jejích subdomén. + limited_federation_mode_description_html: Můžete si vybrat, zda povolit federaci s touto doménou. policies: reject_media: Odmítat média reject_reports: Odmítat hlášení @@ -608,11 +623,14 @@ cs: assign_to_self: Přidělit ke mně assigned: Přiřazený moderátor by_target_domain: Doména nahlášeného účtu + cancel: Zrušit category: Kategorie category_description_html: Důvod nahlášení tohoto účtu a/nebo obsahu bude uveden v komunikaci s nahlášeným účtem comment: none: Žádné comment_description_html: 'Pro upřesnění uživatel %{name} napsal:' + confirm: Potvrdit + confirm_action: Potvrdit moderátorskou akci vůči @%{acct} created_at: Nahlášené delete_and_resolve: Smazat příspěvky forwarded: Přeposláno @@ -629,6 +647,7 @@ cs: placeholder: Popište, jaké akce byly vykonány, nebo jakékoliv jiné související aktuality… title: Poznámky notes_description_html: Zobrazit a zanechat poznámky pro ostatní moderátory i sebe v budoucnu + processed_msg: Nahlášení č.%{id} bylo úspěšně zpracováno quick_actions_description_html: 'Proveďte rychlou akci nebo skrolujte dolů pro nahlášený obsah:' remote_user_placeholder: vzdálený uživatel z %{instance} reopen: Znovu otevřít hlášení @@ -641,6 +660,24 @@ cs: status: Stav statuses: Nahlášený obsah statuses_description_html: Obsah porušující pravidla bude uveden v komunikaci s nahlášeným účtem + summary: + action_preambles: + delete_html: 'Chystáte se odstranit některé z příspěvků uživatele @%{acct}. To znamená:' + mark_as_sensitive_html: 'Chystáte se označit některé z příspěvků @%{acct}jako citlivé. To znamená:' + silence_html: 'Chystáte se omezit účet @%{acct}. To znamená:' + suspend_html: 'Chystáte se pozastavit účet @%{acct}. To znamená:' + actions: + delete_html: Odstranit urážlivé příspěvky + mark_as_sensitive_html: Označit média urážejících příspěvků za citlivá + silence_html: Výrazně omezit dosah @%{acct} tím, že daný profil a jeho obsah bude viditelný pouze těm lidem, kteří ho sledují nebo jej ručně vyhledají + suspend_html: Pozastavit @%{acct}, což daný profil a obsah znepřístupní a neumožní se interakce s ním + close_report: Označit nahlášení č.%{id} za vyřešené + close_reports_html: Označit všechna hlášení proti @%{acct} jako vyřešená + delete_data_html: Odstranit profil a obsah @%{acct} ode dneška po 30 dní, pokud mezitím nebude zrušeno jeho pozastavení + preview_preamble_html: "@%{acct} obdrží varování s následujícím obsahem:" + record_strike_html: Zaznamenat prohřešek @%{acct} pro pomoc s řešením budoucích přestupků z tohoto účtu + send_email_html: Poslat varovný e-mail pro @%{acct} + warning_placeholder: Volitelné další odůvodnění moderační akce. target_origin: Původ nahlášeného účtu title: Hlášení unassign: Odebrat @@ -732,6 +769,9 @@ cs: branding: preamble: Značka vašeho serveru jej odlišuje od ostatních serverů v síti. Tyto informace se mohou zobrazovat v různých prostředích, například ve webovém rozhraní Mastodonu, v nativních aplikacích, v náhledech odkazů na jiných webových stránkách a v aplikacích pro zasílání zpráv atd. Z tohoto důvodu je nejlepší, aby tyto informace byly jasné, krátké a stručné. title: Značka + captcha_enabled: + desc_html: Toto spoléhá na externí skripty z hCaptcha, což může být budit obavy o bezpečnost a soukromí. Navíc to může způsobit, že proces registrace bude pro některé osoby (zejména se zdravotním postižením) hůře přístupný. Z těchto důvodů zvažte alternativní přístup, jako je schvalování registrace nebo pozvánky. + title: Vyžadovat po nových uživatelích, aby vyřešili CAPTCHU pro potvrzení jejich účtu content_retention: preamble: Určuje, jak je obsah generovaný uživatelem uložen v Mastodonu. title: Uchovávání obsahu @@ -759,10 +799,24 @@ cs: approved: Pro registraci je vyžadováno schválení none: Nikdo se nemůže registrovat open: Kdokoliv se může registrovat + security: + authorized_fetch: Vyžadovat autentizaci od federovaných serverů + authorized_fetch_overridden_hint: Momentálně nemůžete změnit toto nastavení, protože je přepsáno proměnnou prostředí. title: Nastavení serveru site_uploads: delete: Odstranit nahraný soubor destroyed_msg: Upload stránky byl úspěšně smazán! + software_updates: + critical_update: Kritické — aktualizujte, prosím, co nejdříve + documentation_link: Zjistit více + release_notes: Poznámky k vydání + title: Dostupné aktualizace + type: Typ + types: + major: Hlavní vydání + minor: Menší vydání + patch: Záplatové vydání — opravy chyb a rychle aplikovatelné změny + version: Verze statuses: account: Autor application: Aplikace @@ -799,9 +853,24 @@ cs: suspend: Uživatel %{name} pozastavil účet %{target} appeal_approved: Podáno odvolání appeal_pending: Čekající odvolání + appeal_rejected: Odvolání zamítnuto system_checks: database_schema_check: message_html: Na spuštění čekají databázové migrace. Nechte je prosím proběhnout pro zajištění očekávaného chování aplikace + elasticsearch_health_red: + message_html: Elasticsearch cluster je nezdravý (červený stav), vyhledávací funkce jsou nedostupné + elasticsearch_health_yellow: + message_html: Elasticsearch cluster je nezdravý (žlutý stav), možná budete chtít prozkoumat důvod + elasticsearch_index_mismatch: + message_html: Mapování indexu Elasticsearch jsou zastaralá. Prosím spusťte tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Prohlédnout dokumentaci + message_html: Váš Elasticsearch cluster má více než jeden node, ale Mastodon není nakonfigurován pro jejich používání. + elasticsearch_preset_single_node: + action: Zobrazit dokumentaci + message_html: Váš Elasticsearch cluster má pouze jeden uzel, ES_PRESET by měl být nastaven na single_node_cluster. + elasticsearch_reset_chewy: + message_html: Váš system index v Elasticsearch je kvůli změně nastavení zastaralý. Pro aktualizaci prosím spusťte tootctl search deploy --reset-chewy. elasticsearch_running_check: message_html: Nelze se připojit k Elasticsearch. Prosím zkontrolujte, že běží, nebo vypněte fulltextové vyhledávání elasticsearch_version_check: @@ -812,6 +881,18 @@ cs: message_html: Nedefinovali jste žádná pravidla serveru. sidekiq_process_check: message_html: Pro %{value} frontu/fronty neběží žádný Sidekiq proces. Zkontrolujte prosím svou Sidekiq konfiguraci + software_version_critical_check: + action: Zobrazit dostupné aktualizace + message_html: K dispozici je kritická aktualizace Mastodonu, prosím aktualizujte co nejrychleji. + software_version_patch_check: + action: Zobrazit dostupné aktualizace + message_html: Je dostupná opravná aktualizace Mastodonu. + upload_check_privacy_error: + action: Pro více informací se podívejte zde + message_html: "Váš webový server je špatně nakonfigurován. Soukromí vašich uživatelů je ohroženo." + upload_check_privacy_error_object_storage: + action: Pro více informací se podívejte zde + message_html: "Váš object storage je špatně nakonfigurován. Soukromí vašich uživatelů je ohroženo." tags: review: Stav posouzení updated_msg: Nastavení hashtagů bylo úspěšně aktualizováno @@ -836,6 +917,7 @@ cs: other: Sdílený %{count} lidmi za poslední týden title: Populární odkazy usage_comparison: Za dnešek %{today} sdílení, oproti %{yesterday} včera + not_allowed_to_trend: Trendování není povoleno only_allowed: Jen povolené pending_review: Čeká na posouzení preview_card_providers: @@ -926,6 +1008,9 @@ cs: body: 'Uživatel %{target} se odvolává proti rozhodnutí moderátora %{action_taken_by} z %{date}, kterým bylo %{type}. Napsal:' next_steps: Můžete schválit odvolání pro vrácení rozhodnutí moderátora, nebo to ignorovat. subject: Uživatel %{username} se odvolává proti rozhodnutí moderátora na %{instance} + new_critical_software_updates: + body: Byly vydány nové kritické verze Mastodonu, možná budete chtít aktualizovat co nejdříve! + subject: Pro %{instance} jsou dostupné kritické aktualizace Mastodonu! new_pending_account: body: Detaily nového účtu jsou uvedeny níže. Tuto žádost můžete schválit nebo zamítnout. subject: Nový účet na serveru %{instance} čekající na posouzení (%{username}) @@ -933,6 +1018,9 @@ cs: body: Uživatel %{reporter} nahlásil uživatele %{target} body_remote: Někdo z domény %{domain} nahlásil uživatele %{target} subject: Nové hlášení pro %{instance} (#%{id}) + new_software_updates: + body: Byly vydány nové verze Mastodonu, možná budete chtít aktualizovat! + subject: Pro %{instance} jsou dostupné nové verze Mastodonu! new_trends: body: 'Následující položky vyžadují posouzení, než mohou být zobrazeny veřejně:' new_trending_links: @@ -962,24 +1050,28 @@ cs: guide_link: https://cs.crowdin.com/project/mastodon guide_link_text: Zapojit se může každý. sensitive_content: Citlivý obsah - toot_layout: Rozložení příspěvků application_mailer: notification_preferences: Změnit předvolby e-mailů salutation: "%{name}," settings: 'Změnit předvolby e-mailů: %{link}' + unsubscribe: Přestat odebírat view: 'Zobrazit:' view_profile: Zobrazit profil view_status: Zobrazit příspěvek applications: created: Aplikace úspěšně vytvořena destroyed: Aplikace úspěšně smazána + logout: Odhlásit se regenerate_token: Znovu vygenerovat přístupový token token_regenerated: Přístupový token byl úspěšně vygenerován warning: Zacházejte s těmito daty opatrně. Nikdy je s nikým nesdílejte! your_token: Váš přístupový token auth: apply_for_account: Požádat o účet - change_password: Heslo + captcha_confirmation: + help_html: Pokud máte problémy s řešením CAPTCHA, můžete se s námi spojit prostřednictvím %{email} a můžeme vám pomoci. + hint_html: Ještě jedna věc! Musíme potvrdit, že jste člověk (to proto, abychom drželi stranou spam!). Vyřešte CAPTCHA níže a klikněte na "Pokračovat". + title: Bezpečnostní kontrola confirmations: wrong_email_hint: Pokud není e-mail správný, můžete si ho změnit v nastavení účtu. delete_account: Odstranit účet @@ -988,7 +1080,7 @@ cs: prefix_invited_by_user: "@%{name} vás zve na tento server Mastodon!" prefix_sign_up: Registrujte se na Mastodonu již dnes! suffix: S účtem budete moci sledovat lidi, psát příspěvky a vyměňovat si zprávy s uživateli z kteréhokoliv serveru Mastodon a dalších služeb! - didnt_get_confirmation: Neobdrželi jste pokyny pro potvrzení? + didnt_get_confirmation: Neobdrželi jste potvrzovací odkaz? dont_have_your_security_key: Nemáte svůj bezpečnostní klíč? forgot_password: Zapomněli jste heslo? invalid_reset_password_token: Token pro obnovení hesla je buď neplatný, nebo vypršel. Vyžádejte si prosím nový. @@ -1001,26 +1093,39 @@ cs: migrate_account_html: Zde můžete nastavit přesměrování tohoto účtu na jiný. or_log_in_with: Nebo se přihlaste pomocí privacy_policy_agreement_html: Četl jsem a souhlasím se zásadami ochrany osobních údajů + progress: + confirm: Confirm e-mail + details: Vaše údaje + review: Naše hodnocení + rules: Přijmout pravidla providers: cas: CAS saml: SAML register: Registrovat registration_closed: "%{instance} nepřijímá nové členy" - resend_confirmation: Znovu odeslat pokyny pro potvrzení + resend_confirmation: Znovu odeslat potvrzovací odkaz reset_password: Obnovit heslo rules: + accept: Přijmout + back: Zpět + invited_by: 'Můžete se připojit k %{domain} díky pozvánce, kterou jste obdrželi od:' preamble: Tohle nastavují a prosazují moderátoři %{domain}. + preamble_invited: Než budete pokračovat, vezměte prosím v úvahu základní pravidla stanovená moderátory %{domain}. title: Některá základní pravidla. + title_invited: Byl/a jsi pozván/a. security: Zabezpečení set_new_password: Nastavit nové heslo setup: - email_below_hint_html: Pokud je níže uvedená e-mailová adresa nesprávná, můžete ji změnit zde a nechat si poslat nový potvrzovací e-mail. - email_settings_hint_html: Potvrzovací e-mail byl odeslán na %{email}. Pokud je tato adresa nesprávná, můžete ji změnit v nastavení účtu. - title: Nastavení + email_below_hint_html: Zkontrolujte složku se spamem, nebo požádejte o jinou. Pokud je to špatné, můžete opravit svou e-mailovou adresu. + email_settings_hint_html: Klikněte na odkaz, který jsme Vám poslali k ověření %{email}. Budeme zde čekat. + link_not_received: Nedostali jste odkaz? + new_confirmation_instructions_sent: Za několik minut obdržíte nový e-mail s potvrzovacím odkazem! + title: Zkontrolujte doručenou poštu sign_in: preamble_html: Přihlaste se se svýma %{domain} údajema. Pokud je váš účet hostován na jiném serveru, nemůžete se zde přihlásit. title: Přihlásit se k %{domain} sign_up: + manual_review: Registrace na %{domain} procházejí manuálním hodnocením od našich moderátorů. Abyste nám pomohli zpracovat Vaši registraci, napište trochu o sobě a proč chcete účet na %{domain}. preamble: S účtem na tomto serveru Mastodon budete moci sledovat jakoukoliv jinou osobu v síti bez ohledu na to, kde je jejich účet hostován. title: Pojďme vás nastavit na %{domain}. status: @@ -1032,18 +1137,6 @@ cs: view_strikes: Zobrazit minulé prohřešky vašeho účtu too_fast: Formulář byl odeslán příliš rychle, zkuste to znovu. use_security_key: Použít bezpečnostní klíč - authorize_follow: - already_following: Tento účet již sledujete - already_requested: Tomuto účtu už jste žádost o sledování zaslali - error: Při hledání vzdáleného účtu bohužel nastala chyba - follow: Sledovat - follow_request: 'Poslali jste žádost o sledování uživateli:' - following: 'Podařilo se! Nyní sledujete uživatele:' - post_follow: - close: Nebo můžete toto okno klidně zavřít. - return: Zobrazit profil uživatele - web: Přejít na web - title: Sledovat %{acct} challenge: confirm: Pokračovat hint_html: "Tip: Po dobu jedné hodiny vás o heslo nebudeme znovu žádat." @@ -1120,6 +1213,10 @@ cs: your_appeal_rejected: Vaše odvolání bylo zamítnuto domain_validator: invalid_domain: není platné doménové jméno + edit_profile: + basic_information: Základní informace + hint_html: "Nastavte si, co lidé uvidí na vašem veřejném profilu a vedle vašich příspěvků. Ostatní lidé vás budou spíše sledovat a komunikovat s vámi, když budete mít vyplněný profil a profilový obrázek." + other: Další errors: '400': Žádost, kterou jste odeslali, byla neplatná nebo poškozená. '403': Nejste oprávněni tuto stránku zobrazit. @@ -1206,8 +1303,6 @@ cs: index: hint: Tento filtr se vztahuje na výběr jednotlivých příspěvků bez ohledu na jiná kritéria. Do tohoto filtru můžete přidat více příspěvků z webového rozhraní. title: Filtrované příspěvky - footer: - trending_now: Právě populární generic: all: Všechny all_items_on_page_selected_html: @@ -1220,7 +1315,9 @@ cs: many: "%{count} položek odpovídající vašemu hledání je vybráno." one: "%{count} položka odpovídající vašemu hledání je vybrána." other: Všech %{count} položek odpovídající vašemu hledání je vybráno. + cancel: Zrušit changes_saved_msg: Změny byly úspěšně uloženy! + confirm: Potvrdit copy: Kopírovat delete: Smazat deselect: Zrušit výběr všeho @@ -1238,24 +1335,44 @@ cs: many: Něco ještě není úplně v pořádku! Zkontrolujte prosím %{count} chyb uvedených níže one: Něco ještě není úplně v pořádku! Zkontrolujte prosím chybu uvedenou níže other: Něco ještě není úplně v pořádku! Zkontrolujte prosím %{count} chyb uvedených níže - html_validator: - invalid_markup: 'obsahuje neplatný HTML kód: %{error}' imports: errors: + empty: Prázdný CSV soubor + incompatible_type: Nekompatibilní s vybraným typem importu invalid_csv_file: 'Neplatný soubor CSV. Chyba: %{error}' over_rows_processing_limit: obsahuje více než %{count} řádků + too_large: Soubor je příliš velký + failures: Chyby + imported: Importováno + mismatched_types_warning: Zdá se, že jste pro tento import vybrali nesprávný typ, zkontrolujte, prosím, znova. modes: merge: Sloučit merge_long: Ponechat existující záznamy a přidat nové overwrite: Přepsat overwrite_long: Nahradit aktuální záznamy novými preface: Můžete importovat data, která jste exportovali z jiného serveru, jako například seznam lidí, které sledujete či blokujete. + recent_imports: Nedávné importy + states: + finished: Dokončeno + in_progress: Probíhá + scheduled: Naplánováno + unconfirmed: Nepotvrzeno + status: Stav success: Vaše data byla úspěšně nahrána a budou zpracována v pravý čas + time_started: Zahájeno v + titles: + blocking: Import blokovaných účtů + bookmarks: Import záložek + domain_blocking: Import blokovaných domén + following: Import sledovaných účtů + muting: Import ztlumených účtů + type: Typ importu types: blocking: Seznam blokovaných bookmarks: Záložky domain_blocking: Seznam blokovaných domén following: Seznam sledovaných + lists: Seznamy muting: Seznam ignorovaných upload: Nahrát invites: @@ -1284,7 +1401,7 @@ cs: title: Pozvat lidi lists: errors: - limit: Dosáhli jste maximálního počtu seznamů + limit: Dosáhl jste maximálního počtu seznamů login_activities: authentication_methods: otp: aplikací pro dvoufaktorové ověření @@ -1411,12 +1528,22 @@ cs: expired: Anketa již skončila invalid_choice: Zvolená možnost hlasování neexistuje over_character_limit: nesmí být žádná delší než %{max} znaků + self_vote: Nemůžete hlasovat ve svých vlastních anketách too_few_options: musí mít více než jednu položku too_many_options: nesmí obsahovat více než %{max} položek preferences: other: Ostatní posting_defaults: Výchozí možnosti psaní public_timelines: Veřejné časové osy + privacy: + hint_html: "Nastavte si, jak chcete, aby šlo váš profil a vaše příspěvky nalézt. Řada funkcí v Mastodonu vám může po zapnutí pomoci získat širší publikum. Věnujte chvíli kontrole těchto nastavení, aby vyhovovala vašim potřebám." + privacy: Soukromí + privacy_hint_html: Nastavte si, kolik toho chcete zveřejnit ve prospěch ostatních. Lidé objevují zajímavé profily a skvělé aplikace procházením sledovaných ostatních lidí i tím, že vidí, z jakých aplikací ostatní posílají příspěvky, vy se však můžete rozhodnout tyto údaje skrýt. + reach: Dosah + reach_hint_html: Nastavte si, zda chcete být objeveni a sledováni novými lidmi. Chcete, aby se vaše příspěvky objevovaly na obrazovce Objevit? Chcete, aby vás další lidé viděli ve svých doporučeních ke sledování? Chcete přijímat všechny nové sledující automaticky nebo mít podrobnou kontrolu nad každým z nich? + search: Vyhledávání + search_hint_html: Mějte pod kontrolou, jak chcete být nalezeni. Chcete, aby vás lidé našli podle toho, o čem jste veřejně psali? Chcete, aby lidé mimo Mastodon mohli nalézt váš profil při prohledávání webu? Mějte na vědomí, že úplné vyřazení ze všech vyhledávačů nelze u veřejných informací garantovat. + title: Soukromí a dosah privacy_policy: title: Zásady ochrany osobních údajů reactions: @@ -1429,6 +1556,7 @@ cs: confirm_remove_selected_followers: Jste si jisti, že chcete odebrat vybrané sledující? confirm_remove_selected_follows: Jste si jisti, že chcete odstranit vybrané sledované? dormant: Nečinné + follow_failure: Nelze sledovat některé z vybraných účtů. follow_selected_followers: Sledovat vybrané sledující followers: Sledující following: Sledovaní @@ -1468,6 +1596,7 @@ cs: electron: Electron firefox: Firefox generic: Neznámý prohlížeč + huawei_browser: Prohlížeč Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1477,6 +1606,7 @@ cs: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Neznámý prohlížeč weibo: Weibo current_session: Aktuální relace description: "%{browser} na systému %{platform}" @@ -1489,9 +1619,10 @@ cs: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: neznámá platforma + unknown_platform: Neznámá platforma windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1574,7 +1705,6 @@ cs: show_newer: Zobrazit novější show_older: Zobrazit starší show_thread: Zobrazit vlákno - sign_in_to_participate: Chcete-li se zúčastnit této konverzace, přihlaste se title: "%{name}: „%{quote}“" visibilities: direct: Přímé @@ -1616,12 +1746,10 @@ cs: '7889238': 3 měsíce min_age_label: Hranice stáří min_favs: Zachovat příspěvky oblíbené alespoň - min_favs_hint: Nesmaže žádný z vašich příspěvků, který obdržel alespoň dané množství oblíbení. Ponechte prázdné pro mazání příspěvků bez ohledu na počet jejich oblíbení + min_favs_hint: Neodstraňuje žádný z vašich příspěvků, které obdržely alespoň tento počet oblíbených. Nechte prázdné pro odstranění příspěvků bez ohledu na jejich počet oblíbených min_reblogs: Zachovat příspěvky boostnuté alespoň min_reblogs_hint: Nesmaže žádný z vašich příspěvků, který byl boostnut alespoň tolikrát. Ponechte prázdné pro mazání příspěvků bez ohledu na počet jejich boostnutí stream_entries: - pinned: Připnutý příspěvek - reblogged: boostnul sensitive_content: Citlivý obsah strikes: errors: @@ -1716,13 +1844,16 @@ cs: title: Vítejte na palubě, %{name}! users: follow_limit_reached: Nemůžete sledovat více než %{limit} lidí + go_to_sso_account_settings: Přejděte do nastavení účtu poskytovatele identity invalid_otp_token: Neplatný kód pro dvoufázové ověřování otp_lost_help_html: Pokud jste ztratili přístup k oběma, spojte se s %{email} seamless_external_login: Jste přihlášeni přes externí službu, nastavení hesla a e-mailu proto nejsou dostupná. signed_in_as: 'Přihlášeni jako:' verification: - explanation_html: 'Můžete se ověřit jako vlastník odkazů v metadatech profilu. Pro tento účel musí stránka v odkazu obsahovat odkaz zpět na váš profil na Mastodonu. Odkaz zpět musí mít atribut rel="me". Na textu odkazu nezáleží. Zde je příklad:' + here_is_how: Jak na to + instructions_html: Zkopírujte a vložte níže uvedený kód do HTML vašeho webu. Poté přidejte adresu vašeho webu do jednoho z extra políček na vašem profilu na záložce "Upravit profil" a uložte změny. verification: Ověření + verified_links: Vaše ověřené odkazy webauthn_credentials: add: Přidat nový bezpečnostní klíč create: diff --git a/config/locales/csb.yml b/config/locales/csb.yml deleted file mode 100644 index e2a6dd4de6..0000000000 --- a/config/locales/csb.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -csb: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 52d1aa2029..a975457cf9 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -17,7 +17,7 @@ cy: zero: Dilynwyr following: Yn dilyn instance_actor_flash: Mae'r cyfrif hwn yn actor rhithwir sy'n cael ei ddefnyddio i gynrychioli'r gweinydd ei hun ac nid unrhyw ddefnyddiwr unigol. Fe'i defnyddir at ddibenion ffederasiwn ac ni ddylid ei atal. - last_active: diweddaraf + last_active: y diweddaraf link_verified_on: Gwiriwyd perchnogaeth y ddolen yma ar %{date} nothing_here: Does dim byd yma! pin_errors: @@ -99,6 +99,7 @@ cy: moderation: active: Yn weithredol all: Popeth + disabled: Analluogwyd pending: Yn aros silenced: Cyfyngedig suspended: Wedi ei atal @@ -136,8 +137,8 @@ cy: removed_header_msg: Llwyddwyd i ddileu delwedd pennyn %{username} resend_confirmation: already_confirmed: Mae'r defnyddiwr hwn wedi ei gadarnhau yn barod - send: Ail anfon e-bost cadarnhad - success: E-bost cadarnhau wedi ei anfon yn llwyddiannus! + send: Ail-anfon dolen cadarnhau + success: Dolen cadarnhau wedi ei anfon yn llwyddiannus! reset: Ailosod reset_password: Ailosod cyfrinair resubscribe: Ail danysgrifio @@ -145,6 +146,7 @@ cy: search: Chwilio search_same_email_domain: Defnyddwyr eraill gyda'r un parth e-bost search_same_ip: Defnyddwyr eraill gyda'r un IP + security: Diogelwch security_measures: only_password: Cyfrinair yn unig password_and_2fa: Cyfrinair a 2FA @@ -189,7 +191,7 @@ cy: create_account_warning: Creu Rhybydd create_announcement: Creu Cyhoeddiad create_canonical_email_block: Creu Bloc E-bost - create_custom_emoji: Creu Emoji Cyfaddas + create_custom_emoji: Creu Emoji Addasedig create_domain_allow: Creu Caniatáu Parth create_domain_block: Creu Gwaharddiad Parth create_email_domain_block: Creu Gwaharddiad Parth E-bost @@ -199,7 +201,7 @@ cy: demote_user: Diraddio Defnyddiwr destroy_announcement: Dileu Cyhoeddiad destroy_canonical_email_block: Dileu Bloc E-bost - destroy_custom_emoji: Dileu Emoji Cyfaddas + destroy_custom_emoji: Dileu Emoji Addasedig destroy_domain_allow: Dileu Caniatáu Parth destroy_domain_block: Dileu Gwaharddiad Parth destroy_email_domain_block: Dileu gwaharddiad parth e-bost @@ -207,12 +209,12 @@ cy: destroy_ip_block: Dileu rheol IP destroy_status: Dileu Postiad destroy_unavailable_domain: Dileu Parth Ddim ar Gael - destroy_user_role: Dinistrio Rôl + destroy_user_role: Dileu Rôl disable_2fa_user: Diffodd 2FA - disable_custom_emoji: Analluogi Emoji Cyfaddas + disable_custom_emoji: Analluogi Emoji Addasedig disable_sign_in_token_auth_user: Analluogi Dilysu Tocyn E-bost ar gyfer Defnyddiwr disable_user: Analluogi Defnyddiwr - enable_custom_emoji: Alluogi Emoji Cyfaddas + enable_custom_emoji: Galluogi Emoji Addasedig enable_sign_in_token_auth_user: Galluogi Dilysu Tocyn E-bost ar gyfer Defnyddiwr enable_user: Galluogi Defnyddiwr memorialize_account: Cofadeilio Cyfrif @@ -233,7 +235,7 @@ cy: unsilence_account: Dad-gyfyngu Cyfrif unsuspend_account: Tynnu Ataliad Cyfrif Dros Dro update_announcement: Diweddaru Cyhoeddiad - update_custom_emoji: Diweddaru Emoji Cyfaddas + update_custom_emoji: Diweddaru Emoji Addasedig update_domain_block: Diweddaru'r Blocio Parth update_ip_block: Diweddaru rheol IP update_status: Diweddaru Postiad @@ -319,6 +321,7 @@ cy: unpublish: Dadgyhoeddi unpublished_msg: Cyhoeddiad wedi'i ddad gyhoeddi'n llwyddiannus! updated_msg: Cyhoeddiad wedi'i ddiweddaru'n llwyddiannus! + critical_update_pending: Diweddariad hanfodol ar ei ffordd custom_emojis: assign_category: Neilltuo categori by_domain: Parth @@ -408,6 +411,15 @@ cy: undo: Gwrthod ffedereiddio gyda pharth domain_blocks: add_new: Ychwanegu bloc parth newydd + confirm_suspension: + cancel: Canslo + confirm: Atal + permanent_action: Ni fydd dadwneud yr atal yn adfer unrhyw ddata neu berthynas. + preamble_html: Rydych ar fin atal %{domain} a'i is-barthau. + remove_all_data: Bydd hyn yn dileu'r holl gynnwys, cyfryngau a data proffil ar gyfer cyfrifon y parth hwn o'ch gweinydd. + stop_communication: Bydd eich gweinydd yn peidio â chyfathrebu â'r gweinyddwyr hyn. + title: Cadarnhewch rwystro parth %{domain} + undo_relationships: Bydd hyn yn dad-wneud unrhyw berthynas dilyn rhwng cyfrifon y gweinyddwyr hyn a'ch un chi. created_msg: Mae'r bloc parth nawr yn cael ei brosesu destroyed_msg: Mae'r bloc parth wedi ei ddadwneud domain: Parth @@ -459,6 +471,7 @@ cy: resolve: Datrys parth title: Rhwystro parth e-bost newydd no_email_domain_block_selected: Heb newid unrhyw flociau parth e-bost gan nad oes un wedi'i ddewis + not_permitted: Dim caniatâd resolved_dns_records_hint_html: Mae'r enw parth yn cyd-fynd â'r parthau MX canlynol, sy'n gyfrifol yn y pen draw am dderbyn e-bost. Bydd rhwystro parth MX yn rhwystro cofrestriadau o unrhyw gyfeiriad e-bost sy'n defnyddio'r un parth MX, hyd yn oed os yw'r enw parth gweladwy yn wahanol. Byddwch yn ofalus i beidio â rhwystro darparwyr e-bost mawr. resolved_through_html: Wedi'i ddatrys trwy %{domain} title: Parthau e-bost wedi'u rhwystro @@ -502,7 +515,7 @@ cy: other: Ymdrechion wedi methu ar %{count} diwrnod gwahanol. two: Ymdrechion wedi methu ar %{count} ddiwrnod gwahanol. zero: Ymdrechion wedi methu ar %{count} o ddyddiau gwahanol. - no_failures_recorded: Dim methiannau wedi'u cofnodi + no_failures_recorded: Dim methiannau wedi'u cofnodi. title: Argaeledd warning: Bu'r ymgais olaf i gysylltu â'r gweinydd hwn yn aflwyddiannus back_to_all: Popeth @@ -513,6 +526,7 @@ cy: content_policies: comment: Nodyn mewnol description_html: Gallwch ddiffinio polisïau cynnwys a fydd yn cael eu cymhwyso i bob cyfrif o'r parth hwn ac unrhyw un o'i is-barthau. + limited_federation_mode_description_html: Gallwch ddewis a ydych am ganiatáu ffedereiddio â'r parth hwn. policies: reject_media: Gwrthod cyfryngau reject_reports: Gwrthod adroddiadau @@ -633,11 +647,13 @@ cy: assign_to_self: Neilltuo i mi assigned: Cymedrolwr wedi'i neilltuo by_target_domain: Parth y cyfrif a adroddwyd + cancel: Canslo category: Categori category_description_html: Bydd y rheswm dros adrodd am y cyfrif a/neu’r cynnwys hwn yn cael ei ddyfynnu wrth gyfathrebu â’r cyfrif a adroddwyd comment: none: Dim comment_description_html: 'I ddarparu rhagor o wybodaeth, ysgrifennodd %{name}:' + confirm: Cadarnhau confirm_action: Cadarnhau gweithred cymedroli yn erbyn @%{acct} created_at: Adroddwyd delete_and_resolve: Dileu postiadau @@ -708,7 +724,7 @@ cy: invites: Gwahoddiadau moderation: Cymedroli special: Arbennig - delete: 'Dileu:' + delete: Dileu description_html: Gyda rolau defnyddwyr, gallwch chi gyfaddasu pa swyddogaethau a meysydd o Mastodon y gall eich defnyddwyr gael mynediad iddyn nhw. edit: Golygu rôl '%{name}' everyone: Caniatâd rhagosodedig @@ -781,6 +797,9 @@ cy: branding: preamble: Mae brandio eich gweinydd yn ei wahaniaethu oddi wrth weinyddion eraill yn y rhwydwaith. Gall y wybodaeth hon gael ei dangos ar draws amrywiaeth o amgylcheddau, megis rhyngwyneb gwe Mastodon, rhaglenni brodorol, mewn rhagolygon cyswllt ar wefannau eraill ac o fewn apiau negeseuon, ac ati. Am y rheswm hwn, mae'n well cadw'r wybodaeth hon yn glir, yn fyr ac yn gryno. title: Brandio + captcha_enabled: + desc_html: Mae hyn yn dibynnu ar sgriptiau allanol gan hCaptcha, a all fod yn bryder diogelwch a phreifatrwydd. Yn ogystal, gall hyn wneud y broses gofrestru yn llawer llai hygyrch i rai pobl (yn enwedig yr anabl). Am y rhesymau hyn, ystyriwch fesurau eraill fel cofrestru ar sail cymeradwyaeth neu ar sail gwahoddiad. + title: Ei gwneud yn ofynnol i ddefnyddwyr newydd ddatrys CAPTCHA i gadarnhau eu cyfrif content_retention: preamble: Rheoli sut mae cynnwys sy'n cael ei gynhyrchu gan ddefnyddwyr yn cael ei storio yn Mastodon. title: Cadw cynnwys @@ -795,7 +814,7 @@ cy: publish_discovered_servers: Cyhoeddi gweinyddion a ddarganfuwyd publish_statistics: Cyhoeddi ystadegau title: Darganfod - trends: Trendiau + trends: Tueddiadau domain_blocks: all: I bawb disabled: I neb @@ -808,10 +827,27 @@ cy: approved: Mae angen cymeradwyaeth i gofrestru none: Nid oes neb yn gallu cofrestru open: Gall unrhyw un cofrestru - title: Gosodiadau Gweinydd + security: + authorized_fetch: Mae angen dilysu gan weinyddion ffederal + authorized_fetch_hint: Mae gofyn am ddilysiad gan weinyddion ffederal yn galluogi gorfodi llymach ar flociau lefel defnyddiwr a lefel gweinydd. Fodd bynnag, daw hyn ar gost perfformiad arafach, mae'n lleihau cyrhaeddiad eich atebion, a gall gyflwyno materion cydnawsedd gyda rhai gwasanaethau ffederal. Yn ogystal, ni fydd hyn yn atal actorion ymroddedig rhag estyn eich postiadau a'ch cyfrifon cyhoeddus. + authorized_fetch_overridden_hint: Nid oes modd i chi newid y gosodiad hwn ar hyn o bryd oherwydd ei fod yn cael ei ddiystyru gan newidyn amgylcheddol. + federation_authentication: Gorfodi dilysu ffederasiwn + title: Gosodiadau gweinydd site_uploads: delete: Dileu ffeil sydd wedi'i llwytho destroyed_msg: Llwytho i fyny i'r wefan wedi'i dileu yn llwyddiannus! + software_updates: + critical_update: Hanfodol - diweddarwch yn fuan + description: Rydym yn argymell eich bod yn cadw'ch gosodiad Mastodon yn gyfredol i elwa o'r atgyweiriadau a'r nodweddion diweddaraf. Hefyd, weithiau mae'n hanfodol diweddaru Mastodon yn amserol er mwyn osgoi materion diogelwch. Am y rhesymau hyn, mae Mastodon yn gwirio am ddiweddariadau bob 30 munud, a bydd yn eich hysbysu yn unol â'ch dewisiadau hysbysu e-bost. + documentation_link: Dysgu rhagor + release_notes: Nodiadau ryddhau + title: Diweddariadau ar gael + type: Math + types: + major: Rhyddhad mawr + minor: Ryddhad llai + patch: Rhyddhad cywiro - cywiriadau gwallau a newidiadau hawdd eu gosod + version: Fersiwn statuses: account: Awdur application: Rhaglen @@ -827,7 +863,7 @@ cy: language: Iaith media: title: Cyfryngau - metadata: Metaddata + metadata: Metadata no_status_selected: Heb newid postiad gan na ddewiswyd dim un open: Agor postiad original_status: Postiad gwreiddiol @@ -848,9 +884,24 @@ cy: suspend: Mae %{name} wedi atal cyfrif %{target} appeal_approved: Apeliwyd appeal_pending: Apêl yn aros + appeal_rejected: Mae'r apêl wedi'i gwrthod system_checks: database_schema_check: message_html: Mae mudo cronfa ddata ar fin digwydd. Rhedwch nhw i sicrhau bod y rhaglen yn ymddwyn yn ôl y disgwyl + elasticsearch_health_red: + message_html: Mae clwstwr Elasticsearch yn afiach (statws coch), nid yw'r nodweddion chwilio ar gael + elasticsearch_health_yellow: + message_html: Mae clwstwr Elasticsearch yn afiach (statws melyn), efallai y byddwch am ymchwilio i'r rheswm + elasticsearch_index_mismatch: + message_html: Mae mapiau mynegai Elasticsearch yn hen ffasiwn. Rhedwch tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Darllenwch y ddogfennaeth + message_html: Mae gan eich clwstwr Elasticsearch fwy nag un nod, ond nid yw Mastodon wedi'i ffurfweddu i'w defnyddio. + elasticsearch_preset_single_node: + action: Darllenwch y ddogfennaeth + message_html: Dim ond un nod sydd gan eich clwstwr Elasticsearch, mae angen gosod ES_PRESET i single_node_cluster . + elasticsearch_reset_chewy: + message_html: Mae eich mynegai system Elasticsearch wedi dyddio oherwydd newid gosodiad. Rhedwch chwiliad tootctl search deploy --reset-chewy i'w ddiweddaru. elasticsearch_running_check: message_html: Methu cysylltu ag Elasticsearch. Gwiriwch ei fod yn rhedeg, neu analluogwch chwiliad testun llawn elasticsearch_version_check: @@ -861,6 +912,18 @@ cy: message_html: Nid ydych wedi diffinio unrhyw reolau gweinydd. sidekiq_process_check: message_html: Does dim proses Sidekiq yn rhedeg ar gyfer y ciw(iau) %{value}. Adolygwch eich ffurfweddiad Sidekiq + software_version_critical_check: + action: Gweld y diweddariadau sydd ar gael + message_html: Mae diweddariad hanfodol Mastodon ar gael, diweddarwch cyn gynted â phosibl. + software_version_patch_check: + action: Gweld y diweddariadau sydd ar gael + message_html: Mae diweddariad cywiro gwal Mastodon ar gael. + upload_check_privacy_error: + action: Ewch yma am fwy o wybodaeth + message_html: "Mae eich gweinydd gwe wedi'i gam ffurfweddu.. Mae preifatrwydd eich defnyddwyr mewn perygl." + upload_check_privacy_error_object_storage: + action: Ewch yma am fwy o wybodaeth + message_html: "Mae eich storfa gwrthrychau wedi'i cham ffurfweddu. Mae preifatrwydd eich defnyddwyr mewn perygl." tags: review: Adolygu statws updated_msg: Gosodiadau hashnodau wedi'i diweddaru'n llwyddiannus @@ -887,6 +950,7 @@ cy: zero: Wedi'i rannu gan %{count} o bobl dros yr wythnos ddiwethaf title: Dolenni sy'n trendio usage_comparison: Wedi'i rannu %{today} gwaith heddiw, o'i gymharu â %{yesterday} ddoe + not_allowed_to_trend: Dim caniatâd i dueddu only_allowed: Derbyniwyd yn unig pending_review: Yn aros am adolygiad preview_card_providers: @@ -983,6 +1047,9 @@ cy: body: 'Mae %{target} yn apelio yn erbyn penderfyniad cymedroli gan %{action_taken_by} ar %{date}, sef %{type}. Mae nhw''n dweud:' next_steps: Gallwch gymeradwyo'r apêl i ddadwneud y penderfyniad cymedroli, neu ei anwybyddu. subject: Mae %{username} yn apelio yn erbyn penderfyniad cymedroli ar %{instance} + new_critical_software_updates: + body: Mae fersiynau hanfodol newydd o Mastodon wedi'u rhyddhau, efallai y byddwch am eu diweddaru cyn gynted â phosibl! + subject: Mae diweddariadau hanfodol Mastodon ar gael ar gyfer %{instance}! new_pending_account: body: Mae manylion y cyfrif newydd yn isod. Gallwch gymeradwyo neu wrthod y cais hwn. subject: Cyfrif newydd i'w adolygu ar %{instance} (%{username}) @@ -990,6 +1057,9 @@ cy: body: Mae %{reporter} wedi adrodd am %{target} body_remote: Mae rhywun o %{domain} wedi adrodd am %{target} subject: Adroddiad newydd am %{instance} (#%{id}) + new_software_updates: + body: Mae fersiynau Mastodon newydd wedi'u rhyddhau, efallai y byddwch am eu diweddaru! + subject: Mae fersiynau Mastodon newydd ar gael ar gyfer %{instance}! new_trends: body: 'Mae angen adolygu''r eitemau canlynol cyn y mae modd eu dangos yn gyhoeddus:' new_trending_links: @@ -1019,24 +1089,28 @@ cy: guide_link: https://crowdin.com/project/mastodon guide_link_text: Gall pawb gyfrannu. sensitive_content: Cynnwys sensitif - toot_layout: Cynllun postiad application_mailer: notification_preferences: Newid gosodiadau e-bost salutation: "%{name}," settings: 'Newid gosodiadau e-bost: %{link}' + unsubscribe: Dad-danysgrifio view: 'Gweld:' view_profile: Gweld proffil view_status: Gweld postiad applications: created: Cais wedi ei greu'n llwyddiannus destroyed: Cais wedi ei ddileu'n llwyddiannus + logout: Allgofnodi regenerate_token: Adfywio tocyn mynediad token_regenerated: Adfywiwyd y tocyn mynediad yn llwyddiannus warning: Byddwch yn ofalus iawn gyda'r data hwn. Peidiwch byth â'i rannu ag unrhyw un! your_token: Eich tocyn mynediad auth: apply_for_account: Gofyn am gyfrif - change_password: Cyfrinair + captcha_confirmation: + help_html: Os oes gennych broblemau yn datrys y CAPTCHA, gallwch gysylltu â ni trwy %{email} a gallwn eich cynorthwyo. + hint_html: Un peth arall! Mae angen i ni gadarnhau eich bod yn ddynol (mae hyn er mwyn i ni allu cadw'r sbam allan!). Datryswch y CAPTCHA isod a chliciwch "Parhau". + title: Gwiriad diogelwch confirmations: wrong_email_hint: Os nad yw'r cyfeiriad e-bost hwnnw'n gywir, gallwch ei newid yng ngosodiadau'r cyfrif. delete_account: Dileu cyfrif @@ -1045,7 +1119,7 @@ cy: prefix_invited_by_user: Mae @%{name} yn eich gwahodd i ymuno â'r gweinydd Mastodon hwn! prefix_sign_up: Cofrestru ar Mastodon heddiw! suffix: Gyda chyfrif, byddwch yn gallu dilyn pobl, postio diweddariadau a chyfnewid negeseuon gyda defnyddwyr o unrhyw weinydd Mastodon, a mwy! - didnt_get_confirmation: Heb dderbyn cyfarwyddiadau cadarnhau? + didnt_get_confirmation: Heb dderbyn dolen cadarnhau? dont_have_your_security_key: Nid oes gennych eich allwedd ddiogelwch? forgot_password: Wedi anghofio'ch cyfrinair? invalid_reset_password_token: Tocyn ailosod cyfrinair yn annilys neu wedi dod i ben. Gwnewch gais am un newydd, os gwelwch yn dda. @@ -1058,26 +1132,39 @@ cy: migrate_account_html: Os hoffech chi ailgyfeirio'r cyfrif hwn at un gwahanol, mae modd ei ffurfweddu yma. or_log_in_with: Neu mewngofnodwch gyda privacy_policy_agreement_html: Rwyf wedi darllen ac yn cytuno i'r polisi preifatrwydd + progress: + confirm: Cadarnhau'r e-bost + details: Eich manylion + review: Ein hadolygiad + rules: Derbyn rheolau providers: cas: CAS saml: SAML register: Cofrestrwch registration_closed: Nid yw %{instance} yn derbyn aelodau newydd - resend_confirmation: Ailanfon cyfarwyddiadau cadarnhau + resend_confirmation: Ail-anfon dolen cadarnhau reset_password: Ailosod cyfrinair rules: + accept: Derbyn + back: Nôl + invited_by: 'Gallwch ymuno â %{domain} diolch i''r gwahoddiad a gawsoch gan:' preamble: Mae'r rhain yn cael eu gosod a'u gorfodi gan y %{domain} cymedrolwyr. + preamble_invited: Cyn i chi barhau, ystyriwch y rheolau sylfaenol a osodwyd gan gymedrolwyr %{domain}. title: Rhai rheolau sylfaenol. + title_invited: Rydych wedi derbyn gwahoddiad. security: Diogelwch set_new_password: Gosod cyfrinair newydd setup: - email_below_hint_html: Os yw'r cyfeiriad e-bost isod yn anghywir, gallwch ei newid yma a derbyn e-bost cadarnhau newydd. - email_settings_hint_html: Anfonwyd yr e-bost cadarnhau at %{email}. Os nad yw'r cyfeiriad e-bost hwnnw'n gywir, gallwch ei newid yng ngosodiadau'r cyfrif. - title: Gosodiad + email_below_hint_html: Gwiriwch eich ffolder sbam, neu gofynnwch am un arall. Gallwch gywiro eich cyfeiriad e-bost os yw'n anghywir. + email_settings_hint_html: Cliciwch ar y ddolen a anfonwyd atoch i wirio %{email}. Byddwn yn aros yma amdanoch. + link_not_received: Heb gael dolen? + new_confirmation_instructions_sent: Byddwch yn derbyn e-bost newydd gyda'r ddolen cadarnhau ymhen ychydig funudau! + title: Gwiriwch eich blwch derbyn sign_in: preamble_html: Mewngofnodwch gyda'ch manylion %{domain}. Os yw eich cyfrif yn cael ei gynnal ar weinydd gwahanol, ni fydd modd i chi fewngofnodi yma. title: Mewngofnodi i %{domain} sign_up: + manual_review: Mae cofrestriadau ar %{domain} yn cael eu hadolygu â llaw gan ein cymedrolwyr. Er mwyn ein helpu i brosesu eich cofrestriad, ysgrifennwch ychydig amdanoch chi'ch hun a pham rydych chi eisiau cyfrif ar %{domain}. preamble: Gyda chyfrif ar y gweinydd Mastodon hwn, byddwch yn gallu dilyn unrhyw berson arall ar y rhwydwaith, lle bynnag mae eu cyfrif yn cael ei gynnal. title: Gadewch i ni eich gosod ar %{domain}. status: @@ -1089,18 +1176,6 @@ cy: view_strikes: Gweld rybuddion y gorffennol yn erbyn eich cyfrif too_fast: Cafodd y ffurflen ei chyflwyno'n rhy gyflym, ceisiwch eto. use_security_key: Defnyddiwch allwedd diogelwch - authorize_follow: - already_following: Rydych yn dilyn y cyfrif hwn yn barod - already_requested: Rydych chi eisoes wedi anfon cais i ddilyn y cyfrif hwnnw - error: Yn anffodus, roedd gwall tra'n edrych am y cyfrif pell - follow: Dilyn - follow_request: 'Rydych wedi anfon cais dilyn at:' - following: 'Llwyddiant! Rydych nawr yn dilyn:' - post_follow: - close: Neu, gallwch gau'r ffenest hon. - return: Dangos proffil y defnyddiwr - web: Ewch i'r we - title: Dilyn %{acct} challenge: confirm: Parhau hint_html: "Awgrym: Fyddwn ni ddim yn gofyn i chi am eich cyfrinair eto am yr awr nesaf." @@ -1177,6 +1252,10 @@ cy: your_appeal_rejected: Mae eich apêl wedi'i gwrthod domain_validator: invalid_domain: ddim yn enw parth dilys + edit_profile: + basic_information: Gwybodaeth Sylfaenol + hint_html: "Addaswch yr hyn y mae pobl yn ei weld ar eich proffil cyhoeddus ac wrth ymyl eich postiadau. Mae pobl eraill yn fwy tebygol o'ch dilyn yn ôl a rhyngweithio â chi pan fydd gennych broffil wedi'i lenwi a llun proffil." + other: Arall errors: '400': Roedd y cais a gyflwynwyd gennych yn annilys neu wedi'i gamffurfio. '403': Nid oes gennych ganiatâd i weld y dudalen hon. @@ -1204,7 +1283,7 @@ cy: request: Gofynn am eich archif size: Maint blocks: Rydych chi'n blocio - bookmarks: Nodau Tudalen + bookmarks: Llyfrnodau csv: CSV domain_blocks: Blociau parth lists: Rhestrau @@ -1213,7 +1292,7 @@ cy: featured_tags: add_new: Ychwanegu errors: - limit: Rydych chi eisoes wedi cynnwys yr uchafswm o hashnodau + limit: Rydych chi eisoes wedi cynnwys y nifer mwyaf o hashnodau hint_html: "Beth yw hashnodau dan sylw? Maen nhw'n cael eu dangos yn amlwg ar eich proffil cyhoeddus ac yn caniatáu i bobl bori'ch postiadau cyhoeddus yn benodol o dan yr hashnodau hynny. Maen nhw'n arf gwych ar gyfer cadw golwg ar weithiau creadigol neu brojectau tymor hir." filters: contexts: @@ -1269,8 +1348,6 @@ cy: index: hint: Mae'r hidlydd hwn yn berthnasol i ddethol postiadau unigol waeth beth fo'r meini prawf eraill. Gallwch ychwanegu mwy o bostiadau at yr hidlydd hwn o'r rhyngwyneb gwe. title: Postiadau wedi'u hidlo - footer: - trending_now: Trendiau generic: all: Popeth all_items_on_page_selected_html: @@ -1287,7 +1364,9 @@ cy: other: Mae pob un o'r %{count} eitem sy'n cyfateb i'ch chwiliad wedi'u dewis. two: Mae pob un o'r %{count} eitem sy'n cyfateb i'ch chwiliad wedi'u dewis. zero: Does %{count} o eitemau sy'n cyfateb i'ch chwiliad wedi'u dewis. + cancel: Canslo changes_saved_msg: Llwyddwyd i gadw'r newidiadau! + confirm: Cadarnhau copy: Copïo delete: Dileu deselect: Dad-ddewis y cwbl @@ -1309,24 +1388,62 @@ cy: other: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod, os gwelwch yn dda two: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} wall isod, os gwelwch yn dda zero: Mae rhywbeth o'i le o hyd! Edrychwch ar y %{count} gwall isod os gwelwch yn dda - html_validator: - invalid_markup: 'yn cynnwys markup HTML annilys: %{error}' imports: errors: + empty: Ffeil CSV wag + incompatible_type: Nid yw'n gydnaws â'r math mewnforio a ddewiswyd invalid_csv_file: 'Ffeil CSV annilys. Gwall: %{error}' over_rows_processing_limit: yn cynnwys mwy na %{count} o resi + too_large: Mae'r ffeil yn rhy fawr + failures: Methiannau + imported: Mewnforwyd + mismatched_types_warning: Mae'n ymddangos eich bod wedi dewis y math anghywir ar gyfer y mewnforiad hwn, edrychwch eto. modes: merge: Cyfuno merge_long: Cadw'r cofnodion presennol ac ychwanegu rhai newydd overwrite: Trosysgrifio overwrite_long: Amnewid y cofnodion cyfredol gyda'r rhai newydd + overwrite_preambles: + blocking_html: Rydych ar fin amnewid eich rhestr rhwystro gyda hyd at %{total_items} o gyfrifon o %{filename} . + bookmarks_html: Rydych ar fin amnewid eich nodau tudalen gyda hyd at %{total_items} o bostiadau gan %{filename} . + domain_blocking_html: Rydych ar fin amnewid eich rhestr rhwystro parth gyda hyd at %{total_items} parth o %{filename} . + following_html: Rydych ar fin dilyn hyd at %{total_items} o gyfrifon o %{filename} a pheidio a ddilyn unrhyw un arall . + lists_html: Rydych ar fin amnewid eich rhestrau gyda chynnwys %{filename} . Bydd hyd at %{total_items} o gyfrifon yn cael eu hychwanegu at restrau newydd. + muting_html: Rydych ar fin amnewid eich rhestr o gyfrifon tawel gyda hyd at %{total_items} o gyfrifon o %{filename} . + preambles: + blocking_html: Rydych ar fin rhwystro hyd at %{total_items} o gyfrifon o %{filename} . + bookmarks_html: Rydych ar fin ychwanegu hyd at %{total_items} o bostiadau o %{filename} at eich nodau tudalen . + domain_blocking_html: Rydych ar fin rhwystro hyd at %{total_items} parth o %{filename} . + following_html: Rydych ar fin dilyn hyd at %{total_items} cyfrif gan %{filename} . + lists_html: Rydych ar fin ychwanegu hyd at %{total_items} o gyfrifon o %{filename} at eich rhestrau . Bydd rhestrau newydd yn cael eu creu os nad oes rhestr i ychwanegu ati. + muting_html: Rydych ar fin tewi hyd at %{total_items} cyfrif o %{filename} . preface: Gallwch fewnforio data rydych chi wedi'i allforio o weinydd arall, fel rhestr o'r bobl rydych chi'n eu dilyn neu'n eu blocio. + recent_imports: Mewnforion diweddar + states: + finished: Wedi gorffen + in_progress: Ar waith + scheduled: Amserlenwyd + unconfirmed: Heb ei gadarnhau + status: Statws success: Llwythwyd eich data yn llwyddiannus a bydd yn cael ei brosesu mewn da bryd + time_started: Cychwynnwyd yn + titles: + blocking: Mewnforio cyfrifon sydd wedi'u rhwystro + bookmarks: Mewnforio nodau tudalen + domain_blocking: Mewnforio parthau sydd wedi'u rhwystro + following: Mewnforio cyfrifon yn cael eu dilyn + lists: Mewnforio rhestrau + muting: Mewnforio cyfrifon wedi'u tewi + type: Math o fewnforion + type_groups: + constructive: Dilyn a Nodau Tudalen + destructive: Rhwystro a Thewi types: blocking: Rhestr blocio - bookmarks: Nodau Tudalen + bookmarks: Llyfrnodau domain_blocking: Rhestr rhwystro parth following: Rhestr ddilynion + lists: Rhestrau muting: Rhestr tewi upload: Llwytho invites: @@ -1357,7 +1474,7 @@ cy: title: Gwahodd pobl lists: errors: - limit: Rydych wedi cyrraedd uchafswm y rhestrau + limit: Rydych chi wedi cyrraedd y nifer mwyaf o restrau login_activities: authentication_methods: otp: ap dilysu dau ffactor @@ -1369,6 +1486,21 @@ cy: failed_sign_in_html: Ymgais mewngofnodi wedi methu gyda %{method} gan %{ip} (%{browser}) successful_sign_in_html: Mewngofnodi llwyddiannus gyda %{method} o %{ip} (%{browser}) title: Hanes dilysu + mail_subscriptions: + unsubscribe: + action: Iawn, dad-danysgrifio + complete: Dad-danysgrifiwyd + confirmation_html: Ydych chi'n siŵr eich bod am ddad-danysgrifo rhag derbyn %{type} Mastodon ar %{domain} i'ch e-bost %{email}? Gallwch bob amser ail-danysgrifio o'ch gosodiadau hysbysiadau e-byst. + emails: + notification_emails: + favourite: hoff e-byst negeseuon hysbysu + follow: dilyn e-byst hysbysu + follow_request: dilyn e-byst ceisiadau + mention: e-byst negeseuon crybwyll + reblog: e-bost hysbysu hybu + resubscribe_html: Os ydych wedi dad-danysgrifio trwy gamgymeriad, gallwch ail-danysgrifio o'ch gosodiadau hysbysiadau e-bost . + success_html: Os nad ydych bellach yn derbyn %{type} Mastodon %{domain} i'ch e-bost %{email}. + title: Dad-danysgrifio media_attachments: validations: images_and_video: Methu atodi fideo i bostiad sydd eisoes yn cynnwys delweddau @@ -1409,7 +1541,7 @@ cy: title: Cymedroil move_handler: carry_blocks_over_text: Symudodd y defnyddiwr hwn o %{acct}, yr oeddech wedi'i rwystro. - carry_mutes_over_text: Symudodd y defnyddiwr hwn o %{acct}, lle roeddech chi wedi'i dewi. + carry_mutes_over_text: Wnaeth y defnyddiwr symud o %{acct}, a oeddech chi wedi'i anwybyddu. copy_account_note_text: 'Symudodd y defnyddiwr hwn o %{acct}, dyma oedd eich nodiadau blaenorol amdanynt:' navigation: toggle_menu: Toglo'r ddewislen @@ -1448,6 +1580,7 @@ cy: update: subject: Golygodd %{name} bostiad notifications: + administration_emails: Hysbysiadau e-bost gweinyddol email_events: Digwyddiadau ar gyfer hysbysiadau e-bost email_events_hint: 'Dewiswch ddigwyddiadau yr ydych am dderbyn hysbysiadau ar eu cyfer:' other_settings: Gosodiadau hysbysiadau arall @@ -1484,12 +1617,22 @@ cy: expired: Mae'r arolwg eisoes wedi dod i ben invalid_choice: Nid yw'r dewis pleidlais hyn yn bodoli over_character_limit: ni all fod yn hwy na %{max} nod yr un + self_vote: Nid oes modd i chi bleidleisio yn eich polau eich hun too_few_options: rhaid cael mwy nag un eitem too_many_options: ni all gynnwys mwy na %{max} eitem preferences: other: Arall posting_defaults: Rhagosodiadau postio public_timelines: Ffrydiau cyhoeddus + privacy: + hint_html: "Cyfaddaswch sut rydych chi am i'ch proffil a'ch postiadau gael eu canfod. Gall amrywiaeth o nodweddion yn Mastodon eich helpu i gyrraedd cynulleidfa ehangach pan fyddwch wedi'ch eu galluogi. Cymerwch eiliad i adolygu'r gosodiadau hyn i sicrhau eu bod yn cyd-fynd â'ch pwrpas defnydd." + privacy: Preifatrwydd + privacy_hint_html: Rheolwch faint rydych chi am ei ddatgelu er budd eraill. Mae pobl yn darganfod proffiliau diddorol ac apiau difyr trwy bori trwy ddilynwyr pobl eraill a gweld o ba apiau maen nhw'n postio, ond efallai y byddai'n well gennych ei gadw'n gudd. + reach: Ymestyn + reach_hint_html: Rheolwch a ydych am gael eich darganfod a'ch dilyn gan bobl newydd. Ydych chi am i'ch postiadau ymddangos ar y sgrin Archwilio? Ydych chi am i bobl eraill eich gweld chi yn eu hargymhellion dilynol? Ydych chi am dderbyn pob dilynwr newydd yn awtomatig, neu gael rheolaeth gronynnog dros bob un? + search: Chwilio + search_hint_html: Rheolwch sut rydych chi am gael eich darganfod. Ydych chi am i bobl ddod o hyd i chi yn ôl yr hyn rydych chi wedi'i bostio'n gyhoeddus amdano? Ydych chi eisiau i bobl y tu allan i Mastodon ddod o hyd i'ch proffil wrth chwilio'r we? Cofiwch nad oes modd gwarantu gwaharddiad llwyr o bob peiriant chwilio ynghylch gwybodaeth gyhoeddus. + title: Preifatrwydd a chyrhaeddiad privacy_policy: title: Polisi preifatrwydd reactions: @@ -1502,6 +1645,7 @@ cy: confirm_remove_selected_followers: Ydych chi'n siŵr eich bod am ddileu'r dilynwyr a ddewiswyd? confirm_remove_selected_follows: Ydych chi'n siŵr eich bod am ddileu'r canlynol? dormant: Segur + follow_failure: Methu dilyn rhai o'r cyfrifon a ddewiswyd. follow_selected_followers: Dilynwch y dilynwyr a ddewiswyd followers: Dilynwyr following: Yn dilyn @@ -1541,15 +1685,17 @@ cy: electron: Electron firefox: Firefox generic: Porwr anhysbys + huawei_browser: Porwr Huawei ie: Nid yw'r rhaglen hon yn gydnaws ag Internet Explorer micro_messenger: MicroMessenger nokia: Porwr Nokia S40 Ovi opera: Opera - otter: dyfrgi + otter: Dyfrgi phantom_js: PhantomJS qq: Porwr QQ safari: Agor yn Safari uc_browser: UC Browser + unknown_browser: Porwr Anhysbys weibo: Weibo current_session: Sesiwn gyfredol description: "%{browser} ar %{platform}" @@ -1562,9 +1708,10 @@ cy: chrome_os: ChromeOS firefox_os: OS Firefox ios: iOS + kai_os: KaiOS linux: Linux - mac: Mac - other: platfform anhysbys + mac: macOS + unknown_platform: Platfform Anhysbys windows: Windows windows_mobile: Windows Mobile windows_phone: Ffôn Windows @@ -1589,7 +1736,7 @@ cy: migrate: Mudo cyfrif notifications: Hysbysiadau preferences: Dewisiadau - profile: Proffil + profile: Proffil cyhoeddus relationships: Yn dilyn a dilynwyr statuses_cleanup: Dileu postiadau'n awtomatig strikes: Rhybuddion cymedroli @@ -1658,8 +1805,7 @@ cy: show_more: Dangos mwy show_newer: Dangos y diweddaraf show_older: Dangos pethau hŷn - show_thread: Dangos trywydd - sign_in_to_participate: Mengofnodwch i gymryd rhan yn y sgwrs + show_thread: Dangos edefyn title: '%{name}: "%{quote}"' visibilities: direct: Uniongyrchol @@ -1686,8 +1832,8 @@ cy: keep_pinned_hint: Nid yw'n dileu unrhyw un o'ch postiadau wedi'u pinio keep_polls: Cadw arolygon keep_polls_hint: Nid yw'n dileu unrhyw un o'ch arolygon - keep_self_bookmark: Cadw y postiadau wedi'u cadw fel nodau tudalen - keep_self_bookmark_hint: Nid yw'n dileu eich postiadau eich hun os ydych wedi rhoi nod tudalen arnyn nhw + keep_self_bookmark: Cadw y postiadau wedi'u cadw fel llyfrnodau + keep_self_bookmark_hint: Nid yw'n dileu eich postiadau eich hun os ydych wedi rhoi llyfrnodau arnyn nhw keep_self_fav: Cadw'r postiadau yr oeddech yn eu ffefrynnu keep_self_fav_hint: Nid yw'n dileu eich postiadau eich hun os ydych wedi eu ffefrynnu min_age: @@ -1701,12 +1847,10 @@ cy: '7889238': 3 mis min_age_label: Trothwy oedran min_favs: Cadw postiadau ffafriwyd am o leiaf - min_favs_hint: Nid yw'n dileu unrhyw un o'ch postiadau sydd wedi derbyn o leiaf y swm hwn o ffefrynnau. Gadewch yn wag i ddileu postiadau waeth beth fo'u ffefrynnau + min_favs_hint: Nid yw'n dileu unrhyw un o'ch postiadau sydd wedi derbyn o leiaf y nifer hwn o ffefrynnau. Gadewch yn wag i ddileu postiadau, beth bynnag yw eu ffefrynnau min_reblogs: Cadw postiadau wedi eu hybu o leiaf min_reblogs_hint: Nid yw'n dileu unrhyw un o'ch postiadau sydd wedi cael eu hybu o leiaf y nifer hwn o weithiau. Gadewch yn wag i ddileu postiadau waeth beth fo'u nifer o hybiadau stream_entries: - pinned: Postiad wedi'i binio - reblogged: hybwyd sensitive_content: Cynnwys sensitif strikes: errors: @@ -1722,6 +1866,11 @@ cy: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Aethpwyd y tu hwnt i gwota defnydd y gweinydd cyfan ar gyfer y gwasanaeth cyfieithu. + too_many_requests: Bu gormod o geisiadau i'r gwasanaeth cyfieithu yn ddiweddar. two_factor_authentication: add: Ychwanegu disable: Analluogi 2FA @@ -1732,7 +1881,7 @@ cy: generate_recovery_codes: Cynhyrchu codau adfer lost_recovery_codes: Mae codau adfer yn caniatáu ichi adennill mynediad i'ch cyfrif os byddwch chi'n colli'ch ffôn. Os ydych chi wedi colli'ch codau adfer, gallwch chi eu hadfywio yma. Bydd eich hen godau adfer yn annilys. methods: Dulliau dau ffactor - otp: Ap dilysu. + otp: Ap dilysu recovery_codes: Creu copi wrth gefn o godau adfer recovery_codes_regenerated: Llwyddwyd i ail greu codau adfer recovery_instructions_html: Os ydych chi'n colli mynediad i'ch ffôn, mae modd i chi ddefnyddio un o'r codau adfer isod i gael mynediad at eich cyfrif. Cadwch y codau adfer yn breifat. Er enghraifft, gallwch chi eu argraffu a'u cadw gyda dogfennau eraill pwysig. @@ -1801,13 +1950,18 @@ cy: title: Croeso, %{name}! users: follow_limit_reached: Nid oes modd i chi ddilyn mwy na %{limit} o bobl + go_to_sso_account_settings: Ewch i osodiadau cyfrif eich darparwr hunaniaeth invalid_otp_token: Côd dau-ffactor annilys otp_lost_help_html: Os colloch chi fynediad i'r ddau, mae modd i chi gysylltu a %{email} seamless_external_login: Yr ydych wedi'ch mewngofnodi drwy wasanaeth allanol, felly nid yw gosodiadau cyfrinair ac e-bost ar gael. signed_in_as: 'Wedi mewngofnodi fel:' verification: - explanation_html: 'Mae modd i chi ddilysu eich hun fel perchenog y dolenni yn metadata eich proffil. Rhaid i''r wefan â dolen iddi gynnwys dolen yn ôl i''ch proffil Mastodon. Rhaid i''r ddolen yn ôl cynnwys y nodwedd rel="me". Does dim ots beth yw cynnwys testun y ddolen. Dyma enghraifft:' + extra_instructions_html: Awgrym: Gall y ddolen ar eich gwefan fod yn anweledig. Y rhan bwysig yw rel="me" sy'n atal dynwarediad ar wefannau gyda chynnwys sy'n cael ei gynyrchu gan ddefnyddwyr. Gallwch hyd yn oed ddefnyddio tag link ym mhennyn y dudalen yn lle a, ond rhaid i'r HTML fod yn hygyrch heb weithredu JavaScript. + here_is_how: Dyma sut + hint_html: "Mae dilysu eich hunaniaeth ar Mastodon ar gyfer pawb. Mae'n seiliedig ar safonau gwe agored, nawr ac am byth, yn rhydd ac am ddim. Y cyfan sydd ei angen arnoch yw gwefan bersonol lle y mae pobl yn eich adnabod chi o'i herwydd. Pan fyddwch yn cysylltu â'r wefan hon o'ch proffil, byddwn yn gwirio bod y wefan yn cysylltu'n ôl â'ch proffil ac yn dangos dangosydd gweledol arni." + instructions_html: Copïwch a gludo'r cod isod i HTML eich gwefan. Yna ychwanegwch gyfeiriad eich gwefan i un o'r meysydd ychwanegol ar eich proffil o'r tab "Golygu proffil" a chadw'r newidiadau. verification: Dilysu + verified_links: Eich dolenni wedi'u dilysu webauthn_credentials: add: Ychwanegu allwedd ddiogelwch newydd create: diff --git a/config/locales/da.yml b/config/locales/da.yml index d89aef9f39..ce53168fb3 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -91,6 +91,7 @@ da: moderation: active: Aktiv all: Alle + disabled: Deaktiveret pending: Afventer silenced: Begrænset suspended: Suspenderet @@ -108,7 +109,7 @@ da: previous_strikes_description_html: one: Denne konto har en anmeldelse. other: Denne konto har %{count} anmeldelser. - promote: Forfrem + promote: Fremhæv protocol: Protokol public: Offentlig push_subscription_expires: PuSH-abonnement udløber @@ -124,8 +125,8 @@ da: removed_header_msg: "%{username}s overskriftsbillede fjernet" resend_confirmation: already_confirmed: Denne bruger er allerede bekræftet - send: Gensend bekræftelses e-mail - success: Bekræftelses e-mail afsendt! + send: Gensend bekræftelseslink + success: Bekræftelseslink afsendt! reset: Nulstil reset_password: Nulstil adgangskode resubscribe: Genabonnér @@ -133,6 +134,7 @@ da: search: Søg search_same_email_domain: Øvrige brugere med samme e-maildomæne search_same_ip: Øvrige brugere med identisk IP + security: Sikkerhed security_measures: only_password: Kun adgangskode password_and_2fa: Adgangskode og 2FA @@ -307,6 +309,7 @@ da: unpublish: Afpublicér unpublished_msg: Bekendtgørelsen er afpubliceret! updated_msg: Bekendtgørelsen er opdateret! + critical_update_pending: Kritisk opdatering afventer custom_emojis: assign_category: Tildel kategori by_domain: Domæne @@ -380,6 +383,15 @@ da: undo: Forbyd federering med domæne domain_blocks: add_new: Tilføj ny domæneblokering + confirm_suspension: + cancel: Annuller + confirm: Suspendér + permanent_action: Fortrydelse af suspensionen vil ikke genoprette nogen data eller sammenhæng. + preamble_html: Du er ved at suspendere %{domain} og dets underdomæner. + remove_all_data: Dette vil fjerne alt indhold, medier og profildata for dette domænes konti fra din server. + stop_communication: Din server vil stoppe kommunikationen med disse servere. + title: Bekræft blokering af domænet %{domain} + undo_relationships: Dette vil fortryde ethvert følgeforhold mellem konti for disse servere og din. created_msg: Domæneblokering under behandling destroyed_msg: Domæneblokering er blevet fjernet domain: Domæne @@ -427,6 +439,7 @@ da: resolve: Opløs domæne title: Blokér nyt e-maildomæne no_email_domain_block_selected: Ingen e-mailblokeringer ændret (ingen var valgt) + not_permitted: Ikke tilladt resolved_dns_records_hint_html: Domænenavnet opløses til flg. MX-domæner, som i sidste ende er ansvarlige for e-mailmodtagelse. Blokering af et MX-domæne blokerer også tilmeldinger fra enhver e-mailadresse på det pågældende MX-domæne, selv hvis det synlige domænenavn er et andet. Pas på ikke ikke at blokere større e-mailudbydere. resolved_through_html: Opløst via %{domain} title: Blokerede e-maildomæner @@ -473,6 +486,7 @@ da: content_policies: comment: Internt notat description_html: Der kan defineres indholdspolitikker, som anvendes på alle konti fra dette domæne samt alle dets underdomæner. + limited_federation_mode_description_html: Man kan vælge, om føderation med dette domæne skal tillades. policies: reject_media: Afvis medier reject_reports: Afvis anmeldelser @@ -576,17 +590,22 @@ da: mark_as_sensitive_description_html: Medierne i det anmeldte indlæg markeres som sensitive, og en advarsel (strike) registreres mhp. eskalering ved evt. fremtidige overtrædelser fra samme konto. other_description_html: Se flere muligheder relateret til at adfærdshåndtering for, samt tilpasning af kommunikation til, den anmeldte konto. resolve_description_html: Ingen foranstaltninger træffes mod den anmeldte konto, ingen advarsel (strike) registreres og anmeldelsen lukkes. + silence_description_html: Kontoen vil kun være synlig for følgerene eller dem, som manuelt slå den op, hvilket markant begrænser dens udbredelse. Kan altid omgøres. Lukker alle indrapporteringer af kontoen. + suspend_description_html: Kontoen inkl. alt indhold utilgængeliggøres og interaktion umuliggøres, og den slettes på et tidspunkt. Kan omgøres inden for 30 dage. Lukker alle indrapporteringer af kontoen. actions_description_html: Afgør, hvilke foranstaltning, der skal træffes for at løse denne anmeldelse. Træffes en straffende foranstaltning mod den anmeldte konto, fremsendes en e-mailnotifikation, undtagen når kategorien Spam er valgt. + actions_description_remote_html: Fastslå en nødvendig handling mhp. at løse denne anmeldelse. Dette vil kun påvirke din servers kommunikation med, og indholdshåndtering for, fjernkontoen. add_to_report: Føj mere til anmeldelse are_you_sure: Sikker? assign_to_self: Tildel til mig assigned: Tildelt moderator by_target_domain: Anmeldte kontos domæne + cancel: Afbryd category: Kategori category_description_html: Årsagen til anmeldelsen af denne konto og/eller indhold refereres i kommunikationen med den anmeldte konto comment: none: Ingen comment_description_html: 'For at give mere information, skrev %{name}:' + confirm: Bekræft confirm_action: Bekræft moderatorhandling for %{acct} created_at: Anmeldt delete_and_resolve: Slet indlæg @@ -722,6 +741,9 @@ da: branding: preamble: Serverens branding adskiller den fra andres i netværket. Oplysningerne kan vises på tværs af div. miljøer, såsom Mastodon-webgrænsefladen, dedikerede applikationer, i-link forhåndsvisninger på andre websteder og i besked-apps mv. Oplysningerne bør derfor være klare og detaljerede, men samtidig kortfattede. title: Branding + captcha_enabled: + desc_html: Dette er afhængig af eksterne scripts fra hCaptcha, som kan være en sikkerhed og privatlivets fred. Derudover kan dette gøre registreringsprocessen betydeligt mindre tilgængelig for nogle (især deaktiveret) personer. Af disse grunde bedes De overveje alternative foranstaltninger såsom godkendelsesbaseret eller inviteret til at blive registreret. + title: Kræv nye brugere for at løse en CAPTCHA for at bekræfte deres konto content_retention: preamble: Styr, hvordan Mastodon gemmer brugergenereret indhold. title: Indholdsopbevaring @@ -733,6 +755,7 @@ da: preamble: At vise interessant indhold er vitalt ifm. at få nye brugere om bord, som måske ikke kender nogen på Mastodon. Styr, hvordan forskellige opdagelsesfunktioner fungerer på serveren. profile_directory: Profiloversigt public_timelines: Offentlige tidslinjer + publish_discovered_servers: Udgiv fundne servere publish_statistics: Udgiv statistik title: Opdagelse trends: Trends @@ -748,10 +771,27 @@ da: approved: Tilmeldingsgodkendelse kræves none: Ingen kan tilmelde sig open: Alle kan tilmelde sig + security: + authorized_fetch: Kræver godkendelse fra fødererede servere + authorized_fetch_hint: Krav om godkendelse fra fødererede servere muliggør strengere håndhævelse af både bruger- og serverniveaublokeringer. Omkostningen er dog en ydelsesreduktion, reduceret udstrækning af dine svar samt potentielle kompatibilitetsproblemer med visse fødererede tjenester. Derudover vil dette ikke hindre målrettede aktører i at hente dine offentlige indlæg og konti. + authorized_fetch_overridden_hint: Da denne indstilling tilsidesættes af en miljøvariabel, kan du p.t. ikke ændre den. + federation_authentication: Håndhævelse af føderationsgodkendelse title: Serverindstillinger site_uploads: delete: Slet uploadet fil destroyed_msg: Websteds-upload blev slettet! + software_updates: + critical_update: Kritisk – opdatér hurtigst muligt + description: Det anbefales at holde Mastodon-installationen opdateret for at drage fordel af de seneste fejlrettelser og funktioner. Undertiden kan det desuden være kritisk at opdatere Mastodon rettidigt for at undgå sikkerhedsproblemer. Mastodon tjekker derfor for opdateringer hvert 30. minut og notificerer dig jf. dine e-mailnotifikationsindstillinger. + documentation_link: Læs mere + release_notes: Udgivelsesnoter + title: Tilgængelige opdateringer + type: Type + types: + major: Større version + minor: Mindre version + patch: Patch-version – fejlrettelser og ukomplicerede ændringer + version: Version statuses: account: Forfatter application: Applikation @@ -788,9 +828,24 @@ da: suspend: "%{name} suspenderede %{target}s konto" appeal_approved: Appelleret appeal_pending: Appel afventer + appeal_rejected: Appel afvist system_checks: database_schema_check: message_html: Databasemigreringer afventer. Kør dem for at sikre den forventede adfærd fra applikationen + elasticsearch_health_red: + message_html: Elasticsearch-klynge er syg (rød status), søgefunktioner er utilgængelige + elasticsearch_health_yellow: + message_html: Elasticsearch klynge er syg (gul status), man ønsker måske at tjekke årsagen + elasticsearch_index_mismatch: + message_html: Elasticsearch-indekseringer er forældede. Kør tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Se dokumentation + message_html: Dit Elasticsearch-cluster har mere end én node, men Mastodon er ikke konfigureret til at bruge dem. + elasticsearch_preset_single_node: + action: Se dokumentation + message_html: Dit Elasticsearch-cluster har kun én node, ES_PRESET skal sættes til single_node_cluster. + elasticsearch_reset_chewy: + message_html: Elasticsearch-systemindekset er forældet grundet en indstillingsændring. Kør tootctl search deploy --reset-chewy for at opdatere det. elasticsearch_running_check: message_html: Kunne ikke oprette forbindelse til Elasticsearch. Tjek, at den kører, eller deaktivér fuldtekstsøgning elasticsearch_version_check: @@ -801,6 +856,18 @@ da: message_html: Ingen serverregler defineret. sidekiq_process_check: message_html: Ingen Sidekiq-proces kører for %{value}-kø(er). Gennemgå Sidekiq-opsætningen + software_version_critical_check: + action: Se tilgængelige opdateringer + message_html: En kritisk Mastodon-opdatering er tilgængelig. Opdatér hurtigst muligt. + software_version_patch_check: + action: Se tilgængelige opdateringer + message_html: En Mastodon-fejlrettelsesopdatering er tilgængelig. + upload_check_privacy_error: + action: Tjek her for flere oplysninger + message_html: "Webserveren er fejlopsat. Brugernes fortrolighed er i fare." + upload_check_privacy_error_object_storage: + action: Tjek her for flere oplysninger + message_html: "Objektlageret er fejlopsat. Brugernes fortrolighed er i fare." tags: review: Revisionsstatus updated_msg: Hashtag-indstillinger opdateret @@ -823,6 +890,7 @@ da: other: Delt af %{count} personer den seneste uge title: Populære links usage_comparison: Delt %{today} gange i dag, sammenlignet med %{yesterday} i går + not_allowed_to_trend: Ikke tilladt at trende only_allowed: Kun tilladte pending_review: Afventer revision preview_card_providers: @@ -907,6 +975,9 @@ da: body: "%{target} appellerer en moderationsbeslutning fra %{action_taken_by} pr. %{date} om at %{type}. Vedkommende skrev:" next_steps: Appellen kan godkendes for at fortryde moderationsbeslutningen eller den ignoreres. subject: "%{username} appellerer en moderationsbeslutning for %{instance}" + new_critical_software_updates: + body: Nye, kritiske Mastodon--versioner er udgivet. Opdatering bør ske hurtigst muligt! + subject: Kritiske Mastodon-opdateringer er tilgængelige til %{instance}! new_pending_account: body: Detaljerne for den nye konto fremgår nedenfor. Du kan godkende eller afvise denne ansøgning. subject: Ny konto til gennemgang på %{instance} (%{username}) @@ -914,6 +985,9 @@ da: body: "%{reporter} har anmeldt %{target}" body_remote: Nogen fra %{domain} har anmeldt %{target} subject: Ny anmeldelse for %{instance} (#%{id}) + new_software_updates: + body: Nye Mastodon-versioner er udgivet. Opgradering bør overvejes! + subject: Nye Mastodon-versioner er tilgængelige til %{instance}! new_trends: body: 'Flg. emner kræver revision, inden de kan vises offentligt:' new_trending_links: @@ -943,33 +1017,37 @@ da: guide_link: https://da.crowdin.com/project/mastodon guide_link_text: Alle kan bidrage. sensitive_content: Sensitivt indhold - toot_layout: Indlægslayout application_mailer: notification_preferences: Skift e-mailpræferencer salutation: "%{name}" settings: 'Skift e-mailpræferencer: %{link}' + unsubscribe: Afmeld notifikationer view: 'Vis:' view_profile: Vis profil view_status: Vis status applications: created: Applikation oprettet destroyed: Applikation slettet + logout: Log af regenerate_token: Regenerér adgangstoken token_regenerated: Adgangstoken regenereret warning: Vær meget påpasselig med disse data. Del dem aldrig med nogen! your_token: Dit adgangstoken auth: apply_for_account: Anmod om en konto - change_password: Adgangskode + captcha_confirmation: + help_html: Hvis du har problemer med at løse CAPTCHA'en, kan du kontakte os via %{email}, så vi kan hjælpe dig. + hint_html: Bare en ting mere! Vi er nødt til at bekræfte, at du er et menneske (dette er for at vi kan holde spam ude!). Løs CAPTCHA'en nedenfor og klik på "Fortsæt". + title: Sikkerhedstjek confirmations: - wrong_email_hint: Er denne e-mail-adresse ikke korrekt, kan den ændres i kontoindstillinger. + wrong_email_hint: Er denne e-mailadresse ikke korrekt, kan den ændres i kontoindstillinger. delete_account: Slet konto delete_account_html: Ønsker du at slette din konto, kan du gøre dette hér. Du vil blive bedt om bekræftelse. description: prefix_invited_by_user: "@%{name} inviterer dig ind på denne Mastodon-server!" prefix_sign_up: Tilmeld dig Mastodon i dag! suffix: Du vil med en konto kunne følge personer, indsende opdateringer og udveksle beskeder med brugere fra enhver Mastodon-server, og meget mere! - didnt_get_confirmation: Ikke modtaget nogle bekræftelsesinstruktioner? + didnt_get_confirmation: Intet bekræftelseslink modtaget? dont_have_your_security_key: Har ikke din sikkerhedsnøgle? forgot_password: Glemt din adgangskode? invalid_reset_password_token: Adgangskodenulstillingstoken ugyldigt eller udløbet. Anmod om et nyt. @@ -981,27 +1059,40 @@ da: migrate_account: Flyt til en anden konto migrate_account_html: Ønsker du at omdirigere denne konto til en anden, kan du opsætte dette hér. or_log_in_with: Eller log ind med - privacy_policy_agreement_html: Jeg accepterer Fortrolighedspolitikken + privacy_policy_agreement_html: Jeg accepterer privatlivspolitikken + progress: + confirm: Bekræft e-mail + details: Dine detaljer + review: Vores gennemgang + rules: Acceptér regler providers: cas: CAS saml: SAML register: Opret dig registration_closed: "%{instance} accepterer ikke nye medlemmer" - resend_confirmation: Gensend bekræftelsesinstruktioner + resend_confirmation: Gensend bekræftelseslink reset_password: Nulstil adgangskode rules: + accept: Acceptér + back: Tilbage + invited_by: 'Du kan tilmelde dig %{domain} takket være den invitation, du har modtaget fra:' preamble: Disse er opsat og håndhæves af %{domain}-moderatorerne. + preamble_invited: Før du fortsætter, bedes du overveje de grundregler, der er fastsat af moderatorerne af %{domain}. title: Nogle grundregler. + title_invited: Du er blevet inviteret. security: Sikkerhed set_new_password: Opsæt ny adgangskode setup: - email_below_hint_html: Er nedenstående e-mailadresse forkert, kan du rette den hér og modtage en ny bekræftelses-e-mail. - email_settings_hint_html: Bekræftelses-e-mailen er sendt til %{email}. Er denne e-mailadresse forkert, kan du rette den via kontoindstillingerne. - title: Opsætning + email_below_hint_html: Tjek Spam-mappen eller anmod om et nyt link. Om nødvendigt kan e-mailadressen rettes. + email_settings_hint_html: Tryk på det tilsendte link for at bekræfte %{email}. + link_not_received: Intet link modtaget? + new_confirmation_instructions_sent: Du bør om få minutter modtage en ny e-mail med bekræftelseslinket! + title: Tjek indbakken sign_in: preamble_html: Log ind med dine %{domain}-legitimationsoplysninger. Hostes kontoen på en anden server, vil der ikke kunne logges ind her. title: Log ind på %{domain} sign_up: + manual_review: Tilmeldinger på %{domain} undergår manuel moderatorgennemgang. For at hjælpe med behandlingen af tilmeldingen, så skriv en smule om dig selv, samt hvorfor du ønsker en konto på %{domain}. preamble: Med en konto på denne Mastodon-server vil man kunne følge enhver anden person på netværket, uanset hvor vedkommendes konto hostes. title: Lad os få dig sat op på %{domain}. status: @@ -1013,18 +1104,6 @@ da: view_strikes: Se tidligere anmeldelser af din konto too_fast: Formularen indsendt for hurtigt, forsøg igen. use_security_key: Brug sikkerhedsnøgle - authorize_follow: - already_following: Du følger allerede denne konto - already_requested: Du har allerede sendt en følgeanmodning til den konto - error: Desværre opstod en fejl under søgning af fjernkontoen - follow: Følg - follow_request: 'Du har sendt en følgeanmodning til:' - following: 'Accepteret! Du følger nu:' - post_follow: - close: Du kan også bare lukke dette vindue. - return: Vis brugerens profil - web: Gå til web - title: Følg %{acct} challenge: confirm: Fortsæt hint_html: "Tip: Du bliver ikke anmodet om din adgangskode igen den næste time." @@ -1036,8 +1115,8 @@ da: invalid_signature: er ikke en gylidig Ed25519-signatur date: formats: - default: "%b %d, %Y" - with_month_name: "%B %d, %Y" + default: "%d. %b %Y" + with_month_name: "%d. %B %Y" datetime: distance_in_words: about_x_hours: "%{count}t" @@ -1066,7 +1145,7 @@ da: email_contact_html: Hvis det stadig ikke ankommer, kan du sende en e-mail til %{email} for hjælp email_reconfirmation_html: Modtager du ikke bekræftelses-e-mailen, kan du anmode om en ny irreversible: Du vil ikke kunne gendanne/genaktivere din konto - more_details_html: For yderligere oplysningerer, tjek fortrolighedspolitikken. + more_details_html: For yderligere oplysningerer, tjek privatlivspolitikken. username_available: Dit brugernavn vil blive tilgængeligt igen username_unavailable: Dit brugernavn vil forblive utilgængeligt disputes: @@ -1101,6 +1180,10 @@ da: your_appeal_rejected: Din appel er afvist domain_validator: invalid_domain: er ikke et gyldigt domænenavn + edit_profile: + basic_information: Oplysninger + hint_html: "Tilpas hvad folk ser på din offentlige profil og ved siden af dine indlæg. Andre personer vil mere sandsynligt følge dig tilbage og interagere med dig, når du har en udfyldt profil og et profilbillede." + other: Andre errors: '400': Din indsendte anmodning er ugyldig eller fejlbehæftet. '403': Du har ikke tilladelse til at se denne side. @@ -1124,7 +1207,7 @@ da: date: Dato download: Download dit arkiv hint_html: Du kan anmode om et arkiv af dine trut og oplagt medie. Den eksporterede data vil være i ActivityPub formattet, læseligt af enhvert kompatibelt program. Du kan anmode om et arkiv én gang om ugen. - in_progress: Kompilerer dit arkiv... + in_progress: Forbereder dit arkiv... request: Anmod om dit arkiv size: Størrelse blocks: Du blokerer @@ -1137,7 +1220,7 @@ da: featured_tags: add_new: Tilføj nyt errors: - limit: Du har allerede fremhævet det maksimale antal hashtags + limit: Det maksimale antal hashtags er allerede fremhævet hint_html: "Hvad er fremhævede hashtags? De vises i en fremtrædende position på din offentlige profil og giver folk mulighed for at gennemse dine offentlige indlæg specifikt under disse hashtags. De er et fantastisk værktøj til at holde styr på kreative værker eller langsigtede projekter." filters: contexts: @@ -1181,8 +1264,6 @@ da: index: hint: Dette filter gælder for udvalgte, individuelle indlæg uanset andre kriterier. Flere indlæg kan føjes til filteret via webfladen. title: Filtrerede indlæg - footer: - trending_now: Trender lige nu generic: all: Alle all_items_on_page_selected_html: @@ -1191,7 +1272,9 @@ da: all_matching_items_selected_html: one: "%{count} emne, der matchede søgningen, er valgt." other: Alle %{count} emner, som matchede søgningen, er valgt. + cancel: Afbryd changes_saved_msg: Ændringerne er gemt! + confirm: Bekræft copy: Kopier delete: Slet deselect: Afmarkér alle @@ -1205,24 +1288,62 @@ da: validation_errors: one: Noget er ikke er helt i vinkel! Tjek fejlen nedenfor other: Noget er ikke er helt i vinkel! Tjek de %{count} fejl nedenfor - html_validator: - invalid_markup: 'indeholder ugyldig HTML-markup: %{error}' imports: errors: + empty: CSV-fil tom + incompatible_type: Inkompatibel med valgte importtype invalid_csv_file: 'Ugyldig CSV-fil. Fejl: %{error}' over_rows_processing_limit: indeholder mere end %{count} rækker + too_large: Filen for stor + failures: Mislykket + imported: Importeret + mismatched_types_warning: Ser ud til, at en forkerte type er valgt til denne import. Dobbelttjek. modes: merge: Sammenflet merge_long: Bibehold eksisterende poster og tilføj nye overwrite: Overskriv overwrite_long: Erstat aktuelle poster med de nye + overwrite_preambles: + blocking_html: Du er ved at erstatte bloklisten med op til %{total_items} konti fra %{filename}. + bookmarks_html: Du er ved at erstatte bogmærkelisten med op til %{total_items} emner fra %{filename}. + domain_blocking_html: Du er ved at erstatte domæneblokeringslisten med op til %{total_items} domæner fra %{filename}. + following_html: Du er ved at følge op til %{total_items} konti fra %{filename} og stoppe med at følge alle andre. + lists_html: Du er ved at erstatte dine lister med indholdet af %{filename}. Op til %{total_items} konti tilføjes nye lister. + muting_html: Du er ved at erstatte listen over tavsgjorte konti med op til %{total_items} konti fra %{filename}. + preambles: + blocking_html: Du er ved at blokere op til %{total_items} konti fra %{filename}. + bookmarks_html: Du er ved at føje op til %{total_items} indlæg fra %{filename} til bogmærkelisten. + domain_blocking_html: Du er ved at blokere op til %{total_items} domæner fra %{filename}. + following_html: Du er ved at følge op til %{total_items} konti fra %{filename}. + lists_html: Du er ved at tilføje op til %{total_items} konti fra %{filename} til dine lister. Nye lister oprettes, hvis der ikke er nogen liste at føje konti til. + muting_html: Du er ved at tavsgøre op til %{total_items} konti fra %{filename}. preface: Du kan importere data, du har eksporteret fra en anden server, såsom en liste over folk du følger eller blokerer. + recent_imports: Seneste importer + states: + finished: Færdig + in_progress: I gang + scheduled: Planlagt + unconfirmed: Ubekræftet + status: Status success: Dine data er uploadet og vil blive behandlet hurtigst muligt + time_started: Startet + titles: + blocking: Importerer blokerede konti + bookmarks: Importerer bogmærker + domain_blocking: Importerer blokerede konti + following: Importerer fulgte konti + lists: Import af lister + muting: Importerer tavsgjorte konti + type: Importtype + type_groups: + constructive: Følger og Bogmærker + destructive: Blokeringer og tavsgjorte types: blocking: Blokeringsliste bookmarks: Bogmærker domain_blocking: Domæneblokeringsliste following: Følgningsliste + lists: Lister muting: Tavsgørelsesliste upload: Upload invites: @@ -1246,7 +1367,7 @@ da: table: expires_at: Udløber uses: Benyttelser - title: Invitere personer + title: Invitér personer lists: errors: limit: Maks. listeantal nået @@ -1261,6 +1382,21 @@ da: failed_sign_in_html: Mislykket indlogning med %{method} fra %{ip} (%{browser}) successful_sign_in_html: Gennemført indlogning med %{method} fra %{ip} (%{browser}) title: Godkendelseshistorik + mail_subscriptions: + unsubscribe: + action: Ja, afmeld + complete: Afmeldt + confirmation_html: Er du sikker på, at du vil afmelde dig fra at modtage %{type} for Mastodon på %{domain} til din e-mail på %{email}? Du kan altid gentilmelde dig dine e-mail-notifikationsindstillinger. + emails: + notification_emails: + favourite: e-mailnotifikationer om favoritmarkeringer + follow: e-mailnotifikationer om nye følgere + follow_request: e-mailnotifikationer om følgeanmodninger + mention: e-mailnotifikationer om omtaler + reblog: e-mailnotifikationer om boosts + resubscribe_html: Hvis du har afmeldt dig ved en fejl, kan du gentilmelde dig under dine e-mail-notifikationsindstillinger. + success_html: Du vil ikke længere modtage %{type} for Mastodon på %{domain} til din e-mail på %{email}. + title: Opsig abonnement media_attachments: validations: images_and_video: En video kan ikke vedhæftes et indlæg med billedindhold @@ -1340,6 +1476,7 @@ da: update: subject: "%{name} redigerede et indlæg" notifications: + administration_emails: Admin e-mailnotifikationer email_events: Begivenheder for e-mailnotifikationer email_events_hint: 'Vælg begivenheder, for hvilke notifikationer skal modtages:' other_settings: Andre notifikationsindstillinger @@ -1357,7 +1494,7 @@ da: code_hint: Angiv koden genereret af godkendelses-appen for at bekræfte description_html: Aktiveres tofaktorgodkendelse vha. af en godkendelses-app, vil man skulle benytte sin mobil, der genererer det token, der skal angives ved indlogning. enable: Aktivér - instructions_html: "Skan denne QR-kode i Google Autehnticator eller en lign. TOTP-app på mobilen. Fremadrettet vil appen generere de tokens, som vil skulle angives ifm. indlogning." + instructions_html: "Skan denne QR-kode i Google Authenticator eller en lign. TOTP-app på mobilen. Fremadrettet vil appen generere de tokens, som vil skulle angives ifm. indlogning." manual_instructions: 'Kan QR-koden ikke skannes, så man er nødt til manuelt at angive den, er her en simplel tekst-hemmelighed:' setup: Opsæt wrong_code: Den angivne kode er ugyldig! Er server- og enhedsklokkeslæt korrekte? @@ -1376,14 +1513,24 @@ da: expired: Afstemningen er allerede afsluttet invalid_choice: Den valgte stemmemulighed findes ikke over_character_limit: må maks. udgøre %{max} tegn hver + self_vote: Du kan ikke stemme i dine egne afstemninger too_few_options: skal have flere end ét valg too_many_options: for mange svar (maks. %{max}) preferences: other: Andet posting_defaults: Standarder for indlæg public_timelines: Offentlige tidslinjer + privacy: + hint_html: "Tilpas hvordan din profil og dine indlæg kan findes. En række funktioner i Mastodon kan hjælpe dig med at nå ud til et bredere publikum, hvis du aktiverer dem. Tjek indstillingerne herunder for at sikre, at de passer til dit brugsscenarie." + privacy: Privatliv + privacy_hint_html: Styr, hvor meget der ønskes synliggjort til gavn for andre. Folk finder interessante profiler og apps ved at tjekke andres følgere ud, samt se hvilke apps de sender fra, men dine præferencer ønskes muligvis ikke synliggjort. + reach: Udbredelse + reach_hint_html: Indstil om du vil blive opdaget og fulgt af nye mennesker. Ønsker du, at dine indlæg skal vises på Udforsk-siden? Ønsker du, at andre skal se dig i deres følg-anbefalinger? Ønsker du at acceptere alle nye følgere automatisk, eller vil du have detaljeret kontrol over hver og en? + search: Søg + search_hint_html: Indstil hvordan du vil findes. Ønsker du, at folk skal finde dig gennem hvad du har skrevet offentligt? Vil du have folk udenfor Mastodon til at finde din profil, når de søger på nettet? Vær opmærksom på, at det ikke kan garanteres at dine offentlige indlæg er udelukket fra alle søgemaskiner. + title: Fortrolighed og udbredelse privacy_policy: - title: Fortrolighedspolitik + title: Privatlivspolitik reactions: errors: limit_reached: Grænse for forskellige reaktioner nået @@ -1392,7 +1539,9 @@ da: activity: Kontoaktivitet confirm_follow_selected_followers: Sikker på, at de valgte følgere skal følges? confirm_remove_selected_followers: Sikker på, at de valgte følgere skal fjernes? + confirm_remove_selected_follows: Sikker på, at de valgte følgere skal fjernes? dormant: I dvale + follow_failure: Kunne ikke følge alle af de valgte konti. follow_selected_followers: Følg valgte følgere followers: Følgere following: Følger @@ -1432,6 +1581,7 @@ da: electron: Electron firefox: Firefox generic: Ukendt browser + huawei_browser: Huawei Browser ie: IE micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1441,6 +1591,7 @@ da: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Ukendt browser weibo: Weibo current_session: Aktuelle session description: "%{browser} på %{platform}" @@ -1453,9 +1604,10 @@ da: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: ukendt platform + unknown_platform: Ukendt platform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1480,7 +1632,7 @@ da: migrate: Kontomigrering notifications: Notifikationer preferences: Præferencer - profile: Profil + profile: Offentlig profil relationships: Følger og følgere statuses_cleanup: Auto-indlægssletning strikes: Moderationsadvarsler @@ -1510,7 +1662,7 @@ da: open_in_web: Åbn i webbrowser over_character_limit: grænsen på %{max} tegn overskredet pin_errors: - direct: Indlæg, som kun kan ses af nævnte brugere, kan ikke fastgøres + direct: Indlæg, som kun kan ses af omtalte brugere, kan ikke fastgøres limit: Maksimalt antal indlæg allerede fastgjort ownership: Andres indlæg kan ikke fastgøres reblog: Et boost kan ikke fastgøres @@ -1526,7 +1678,6 @@ da: show_newer: Vis nyere show_older: Vis ældre show_thread: Vis tråd - sign_in_to_participate: Log ind for at deltage i konversationen title: '%{name}: "%{quote}"' visibilities: direct: Direkte @@ -1568,12 +1719,10 @@ da: '7889238': 3 måneder min_age_label: Alderstærskel min_favs: Behold indlæg favoritmarkeret mindst - min_favs_hint: Sletter ingen egne indlæg, som har modtaget minimum dette antal favoritmarkeringer. Lad stå tomt for at ignorere denne tærskel under sletning + min_favs_hint: Sletter ingen egne indlæg, som har modtaget minimum dette antal favoritmarkeringer. Lad stå tomt for at slette indlæg uanset favoritmarkeringer min_reblogs: Behold indlæg boostet mindst min_reblogs_hint: Sletter ingen egne indlæg, som er boostet flere end dette antal gange. Lad stå tomt for at ignorere denne tærskel under sletning stream_entries: - pinned: Fastgjort indlæg - reblogged: boostet sensitive_content: Sensitivt indhold strikes: errors: @@ -1586,9 +1735,14 @@ da: mastodon-light: Mastodon (lyst) time: formats: - default: "%a %d %b %Y, %H:%M" + default: "%d. %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d. %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Serverens forbrugskvote hos oversættelsestjenesten er opbrugt. + too_many_requests: Oversættelsestjenesten har på det seneste haft for mange forespørgsler. two_factor_authentication: add: Tilføj disable: Deaktivér 2FA @@ -1619,7 +1773,7 @@ da: subject: Dit arkiv er klar til download title: Arkiv download suspicious_sign_in: - change_password: skift din adgangskode + change_password: ændrer din adgangskode details: 'Her er nogle detaljer om login-forsøget:' explanation: Indlogning på din konto fra en ny IP-adresse detekteret. further_actions_html: Hvis dette ikke var dig, anbefaler vi, at du %{action} med det samme og aktiverer to-faktor godkendelse for at holde din konto sikker. @@ -1668,13 +1822,18 @@ da: title: Velkommen ombord, %{name}! users: follow_limit_reached: Du kan maks. følge %{limit} personer + go_to_sso_account_settings: Gå til identitetsudbyderens kontoindstillinger invalid_otp_token: Ugyldig tofaktorkode otp_lost_help_html: Har du mistet adgang til begge, kan du kontakte %{email} seamless_external_login: Du er logget ind via en ekstern tjeneste, så adgangskode- og e-mailindstillinger er utilgængelige. signed_in_as: 'Logget ind som:' verification: - explanation_html: 'Du kan bekræfte dig selv som ejer af linkene i din profilmetadata. For at gøre det, skal det linkede websted indeholde et link pegende tilbage til din Mastodon-profil. Returlinket skal have en rel="me"-attribut. Linkets tekstindhold betyder ikke noget. Her er et eksempel:' + extra_instructions_html: Tip: Linket på din hjemmeside kan være usynligt. Den vigtige del er rel="me" , som forhindrer impersonation på websteder med brugergenereret indhold. Du kan endda bruge et link tag i overskriften på siden i stedet for a, men HTML skal være tilgængelig uden at udføre JavaScript. + here_is_how: Sådan gør du + hint_html: "Bekræftelse af din identitet på Mastodon er for alle. Baseret på åbne webstandarder, nu og for evigt gratis. Alt du behøver er en personlig hjemmeside, som folk genkende dig ved. Når du linker til denne hjemmeside fra din profil, vi vil kontrollere, at hjemmesiden linker tilbage til din profil og vise en visuel indikator på det." + instructions_html: Kopier og indsæt koden nedenfor i HTML på din hjemmeside. Tilføj derefter adressen på din hjemmeside i et af de ekstra felter på din profil på fanen "Redigér profil" og gem ændringer. verification: Bekræftelse + verified_links: Dine bekræftede links webauthn_credentials: add: Tilføj ny sikkerhedsnøgle create: diff --git a/config/locales/de.yml b/config/locales/de.yml index 605eb8e736..d72b0a608f 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1,7 +1,7 @@ --- de: about: - about_mastodon_html: 'Das soziale Netzwerk der Zukunft: Keine Werbung, keine Überwachung, dafür dezentral und mit Anstand! Starte jetzt mit Mastodon!' + about_mastodon_html: 'Das soziale Netzwerk der Zukunft: Keine Werbung, keine Überwachung durch Unternehmen – dafür dezentral und mit Anstand! Beherrsche deine Daten mit Mastodon!' contact_missing: Nicht festgelegt contact_unavailable: Nicht verfügbar hosted_on: Mastodon, gehostet auf %{domain} @@ -10,14 +10,14 @@ de: follow: Folgen followers: one: Follower - other: Folgende + other: Follower following: Folge ich - instance_actor_flash: Dieses Konto ist ein virtueller Akteur, der den Server selbst repräsentiert und nicht ein einzelner Benutzer. Es wird für Föderationszwecke verwendet und sollte nicht gesperrt werden. + instance_actor_flash: Dieses Konto ist ein virtueller Akteur, der den Server selbst repräsentiert, und kein persönliches Profil. Es wird für Föderationszwecke verwendet und sollte daher nicht gesperrt werden. last_active: zuletzt aktiv link_verified_on: Das Profil mit dieser E-Mail-Adresse wurde bereits am %{date} bestätigt nothing_here: Keine Treffer mit dieser Auswahl pin_errors: - following: Du musst dieser Person bereits folgen, um sie empfehlen zu können + following: Du musst dieser Person folgen, um sie empfehlen zu können posts: one: Beitrag other: Beiträge @@ -25,15 +25,15 @@ de: admin: account_actions: action: Aktion ausführen - title: Moderationsaktion auf %{acct} ausführen + title: "@%{acct} moderieren" account_moderation_notes: create: Notiz abspeichern created_msg: Moderationshinweis erfolgreich abgespeichert! - destroyed_msg: Moderationsnotiz erfolgreich gelöscht! + destroyed_msg: Moderationsnotiz erfolgreich entfernt! accounts: add_email_domain_block: E-Mail-Domain sperren approve: Genehmigen - approved_msg: Anmeldeantrag von %{username} erfolgreich genehmigt + approved_msg: Antrag zur Registrierung von %{username} erfolgreich genehmigt are_you_sure: Bist du dir sicher? avatar: Profilbild by_domain: Domain @@ -58,16 +58,16 @@ de: demote: Zurückstufen destroyed_msg: Daten von %{username} wurden zum Löschen in die Warteschlange eingereiht disable: Einfrieren - disable_sign_in_token_auth: Deaktiviere die Zwei-Faktor-Authentisierung (2FA) per E-Mail + disable_sign_in_token_auth: E-Mail-Token-Authentisierung deaktivieren disable_two_factor_authentication: Zwei-Faktor-Authentisierung (2FA) deaktivieren disabled: Eingefroren - display_name: Angezeigter Name + display_name: Anzeigename domain: Domain edit: Bearbeiten - email: E-Mail - email_status: E-Mail-Status + email: E-Mail-Adresse + email_status: Status der E-Mail-Adresse enable: Freischalten - enable_sign_in_token_auth: Aktiviere die Zwei-Faktor-Authentisierung (2FA) per E-Mail + enable_sign_in_token_auth: E-Mail-Token-Authentisierung aktivieren enabled: Freigegeben enabled_msg: Konto von %{username} erfolgreich freigegeben followers: Follower @@ -83,14 +83,15 @@ de: local: Lokal remote: Extern title: Herkunft - login_status: Anmeldestatus - media_attachments: Speicherplatz + login_status: Status + media_attachments: Medienanhänge memorialize: In Gedenkseite umwandeln memorialized: Gedenkseite memorialized_msg: "%{username} wurde erfolgreich in ein Gedenkseiten-Konto umgewandelt" moderation: active: Aktiv all: Alle + disabled: Deaktiviert pending: In Warteschlange silenced: Stummgeschaltet suspended: Gesperrt @@ -104,10 +105,10 @@ de: not_subscribed: Nicht abonniert pending: Überprüfung ausstehend perform_full_suspension: Sperren - previous_strikes: Vorherige Verstöße + previous_strikes: Vorherige Maßnahmen previous_strikes_description_html: - one: Dieses Konto hat einen Verstoß. - other: Dieses Konto hat %{count} Verstöße. + one: Gegen dieses Konto wurde eine Maßnahme verhängt. + other: Gegen dieses Konto wurden %{count} Maßnahmen verhängt. promote: Berechtigungen erweitern protocol: Protokoll public: Öffentlich @@ -117,22 +118,23 @@ de: reject: Ablehnen rejected_msg: Antrag zur Registrierung von %{username} erfolgreich abgelehnt remote_suspension_irreversible: Die Daten dieses Kontos wurden unwiderruflich gelöscht. - remote_suspension_reversible_hint_html: Das Konto wurde auf dem Server gesperrt und sämtliche Daten werden am %{date} entfernt. Bis dahin kann der Server dieses Konto ohne negative Auswirkungen wiederherstellen. Wenn du schon jetzt alle Daten des Kontos unwiderruflich löschen möchtest, kannst du dies nachfolgend tun. + remote_suspension_reversible_hint_html: Das Konto wurde auf dem externen Server gesperrt – und sämtliche Daten werden am %{date} entfernt. Bis dahin kann dieser Server das Konto ohne negative Auswirkungen wiederherstellen. Wenn du schon jetzt alle Daten des Kontos unwiderruflich löschen möchtest, kannst du dies nachfolgend tun. remove_avatar: Profilbild entfernen remove_header: Titelbild entfernen removed_avatar_msg: Profilbild von %{username} erfolgreich entfernt removed_header_msg: Titelbild von %{username} wurde erfolgreich entfernt resend_confirmation: already_confirmed: Dieses Profil wurde bereits bestätigt - send: Bestätigungs-E-Mail erneut senden - success: Bestätigungs-E-Mail erfolgreich gesendet! + send: Bestätigungslink erneut zusenden + success: Bestätigungslink erfolgreich gesendet! reset: Zurücksetzen reset_password: Passwort zurücksetzen - resubscribe: Wieder abonnieren + resubscribe: Erneut abonnieren role: Rolle search: Suchen - search_same_email_domain: Andere Benutzer*innen mit der gleichen E-Mail-Domain - search_same_ip: Andere Benutzer*innen mit derselben IP-Adresse + search_same_email_domain: Andere Konten mit der gleichen E-Mail-Domain + search_same_ip: Andere Konten mit derselben IP-Adresse + security: Sicherheit security_measures: only_password: Nur Passwort password_and_2fa: Passwort und 2FA @@ -145,7 +147,7 @@ de: silence: Stummschalten silenced: Stummgeschaltet statuses: Beiträge - strikes: Vorherige Verstöße + strikes: Vorherige Maßnahmen subscribe: Abonnieren suspend: Sperren suspended: Gesperrt @@ -163,15 +165,15 @@ de: unsuspended_msg: Kontosperre von %{username} erfolgreich aufgehoben username: Profilname view_domain: Übersicht für Domain anzeigen - warn: Warnen + warn: Verwarnen web: Web - whitelisted: Auf der Whitelist + whitelisted: Für Föderation zugelassen action_logs: action_types: - approve_appeal: Einspruch annehmen + approve_appeal: Einspruch zulassen approve_user: Benutzer*in genehmigen - assigned_to_self_report: Bericht zuweisen - change_email_user: E-Mail des Profils ändern + assigned_to_self_report: Meldung zuweisen + change_email_user: E-Mail-Adresse des Kontos ändern change_role_user: Rolle des Profils ändern confirm_user: Benutzer*in bestätigen create_account_warning: Warnung erstellen @@ -193,15 +195,15 @@ de: destroy_email_domain_block: E-Mail-Domain-Sperre löschen destroy_instance: Domain-Daten entfernen destroy_ip_block: IP-Regel löschen - destroy_status: Beitrag löschen + destroy_status: Beitrag entfernen destroy_unavailable_domain: Nicht-verfügbare Domain entfernen destroy_user_role: Rolle entfernen disable_2fa_user: 2FA deaktivieren disable_custom_emoji: Eigenes Emoji deaktivieren - disable_sign_in_token_auth_user: Zwei-Faktor-Authentisierung (2FA) per E-Mail für diesen Account deaktivieren + disable_sign_in_token_auth_user: E-Mail-Token-Authentisierung für dieses Konto deaktivieren disable_user: Benutzer*in deaktivieren enable_custom_emoji: Eigenes Emoji aktivieren - enable_sign_in_token_auth_user: Zwei-Faktor-Authentisierung (2FA) per E-Mail für diesen Account aktivieren + enable_sign_in_token_auth_user: E-Mail-Token-Authentisierung für dieses Konto aktivieren enable_user: Benutzer*in aktivieren memorialize_account: Gedenkkonto promote_user: Benutzer*in hochstufen @@ -211,7 +213,7 @@ de: reopen_report: Meldung wieder eröffnen resend_user: Bestätigungs-E-Mail erneut senden reset_password_user: Passwort zurücksetzen - resolve_report: Bericht lösen + resolve_report: Meldung klären sensitive_account: Konto mit erzwungener Inhaltswarnung silence_account: Konto stummschalten suspend_account: Konto sperren @@ -219,72 +221,72 @@ de: unblock_email_account: E-Mail-Adresse entsperren unsensitive_account: Konto mit erzwungener Inhaltswarnung rückgängig machen unsilence_account: Konto nicht mehr stummschalten - unsuspend_account: Konto nicht mehr sperren + unsuspend_account: Konto entsperren update_announcement: Ankündigung aktualisieren update_custom_emoji: Eigenes Emoji aktualisieren update_domain_block: Domain-Sperre aktualisieren update_ip_block: IP-Regel aktualisieren update_status: Beitrag aktualisieren - update_user_role: Rolle aktualisieren + update_user_role: Rolle bearbeiten actions: - approve_appeal_html: "%{name} genehmigte die Moderationsbeschlüsse von %{target}" + approve_appeal_html: "%{name} hat den Einspruch gegen eine Moderationsentscheidung von %{target} genehmigt" approve_user_html: "%{name} genehmigte die Registrierung von %{target}" - assigned_to_self_report_html: "%{name} hat sich die Meldung %{target} selbst zugewiesen" - change_email_user_html: "%{name} hat die E-Mail-Adresse von %{target} geändert" + assigned_to_self_report_html: "%{name} wies sich die Meldung %{target} selbst zu" + change_email_user_html: "%{name} änderte die E-Mail-Adresse von %{target}" change_role_user_html: "%{name} hat die Rolle von %{target} geändert" - confirm_user_html: "%{name} hat die E-Mail-Adresse von %{target} bestätigt" - create_account_warning_html: "%{name} hat eine Warnung an %{target} gesendet" - create_announcement_html: "%{name} hat die neue Ankündigung erstellt: %{target}" + confirm_user_html: "%{name} bestätigte die E-Mail-Adresse von %{target}" + create_account_warning_html: "%{name} sendete eine Warnung an %{target}" + create_announcement_html: "%{name} erstellte die neue Ankündigung: %{target}" create_canonical_email_block_html: "%{name} hat die E-Mail mit dem Hash %{target} gesperrt" - create_custom_emoji_html: "%{name} hat neues Emoji hochgeladen: %{target}" - create_domain_allow_html: "%{name} hat die Domain %{target} gewhitelistet" - create_domain_block_html: "%{name} hat die Domain %{target} gesperrt" + create_custom_emoji_html: "%{name} lud das neue Emoji %{target} hoch" + create_domain_allow_html: "%{name} erlaubte die Föderation mit der Domain %{target}" + create_domain_block_html: "%{name} sperrte die Domain %{target}" create_email_domain_block_html: "%{name} hat die E-Mail-Domain %{target} gesperrt" - create_ip_block_html: "%{name} hat eine IP-Regel für %{target} erstellt" - create_unavailable_domain_html: "%{name} hat die Lieferung an die Domain %{target} eingestellt" - create_user_role_html: "%{name} hat die Rolle %{target} erstellt" - demote_user_html: "%{name} hat %{target} heruntergestuft" - destroy_announcement_html: "%{name} hat die neue Ankündigung %{target} gelöscht" + create_ip_block_html: "%{name} erstellte eine IP-Regel für %{target}" + create_unavailable_domain_html: "%{name} beendete die Zustellung an die Domain %{target}" + create_user_role_html: "%{name} erstellte die Rolle %{target}" + demote_user_html: "%{name} stufte %{target} herunter" + destroy_announcement_html: "%{name} löschte die Ankündigung %{target}" destroy_canonical_email_block_html: "%{name} hat die E-Mail mit dem Hash %{target} entsperrt" - destroy_custom_emoji_html: "%{name} hat das Emoji gelöscht: %{target}" - destroy_domain_allow_html: "%{name} hat die Domain %{target} von der Whitelist entfernt" - destroy_domain_block_html: "%{name} hat die Domain %{target} entsperrt" + destroy_custom_emoji_html: "%{name} löschte das Emoji %{target}" + destroy_domain_allow_html: "%{name} verwehrte die Föderation mit der Domain %{target}" + destroy_domain_block_html: "%{name} entsperrte die Domain %{target}" destroy_email_domain_block_html: "%{name} hat die E-Mail-Domain %{target} entsperrt" - destroy_instance_html: "%{name} hat die Daten der Domain %{target} entfernt" - destroy_ip_block_html: "%{name} hat eine IP-Regel für %{target} entfernt" - destroy_status_html: "%{name} hat einen Beitrag von %{target} entfernt" - destroy_unavailable_domain_html: "%{name} setzte die Lieferung an die Domain %{target} fort" - destroy_user_role_html: "%{name} hat die Rolle %{target} gelöscht" - disable_2fa_user_html: "%{name} hat die Zwei-Faktor-Authentisierung für %{target} deaktiviert" - disable_custom_emoji_html: "%{name} hat das Emoji deaktiviert: %{target}" - disable_sign_in_token_auth_user_html: "%{name} hat die E-Mail-Token-Authentifizierung für %{target} deaktiviert" - disable_user_html: "%{name} hat den Zugang für %{target} deaktiviert" - enable_custom_emoji_html: "%{name} hat das Emoji aktiviert: %{target}" - enable_sign_in_token_auth_user_html: "%{name} hat die E-Mail-Token-Authentifizierung für %{target} aktiviert" - enable_user_html: "%{name} hat den Zugang für %{target} aktiviert" - memorialize_account_html: "%{name} hat das Konto von %{target} in eine Gedenkseite umgewandelt" - promote_user_html: "%{name} hat %{target} befördert" - reject_appeal_html: "%{name} hat den Moderations-Beschlussantrag von %{target} abgelehnt" + destroy_instance_html: "%{name} entfernte die Daten der Domain %{target} von diesem Server" + destroy_ip_block_html: "%{name} entfernte eine IP-Regel für %{target}" + destroy_status_html: "%{name} entfernte einen Beitrag von %{target}" + destroy_unavailable_domain_html: "%{name} nahm die Zustellung an die Domain %{target} wieder auf" + destroy_user_role_html: "%{name} löschte die Rolle %{target}" + disable_2fa_user_html: "%{name} deaktivierte die Zwei-Faktor-Authentisierung für %{target}" + disable_custom_emoji_html: "%{name} deaktivierte das Emoji %{target}" + disable_sign_in_token_auth_user_html: "%{name} deaktivierte die E-Mail-Token-Authentisierung für %{target}" + disable_user_html: "%{name} deaktivierte den Zugang für %{target}" + enable_custom_emoji_html: "%{name} aktivierte das Emoji %{target}" + enable_sign_in_token_auth_user_html: "%{name} hat die E-Mail-Token-Authentisierung für %{target} aktiviert" + enable_user_html: "%{name} aktivierte den Zugang für %{target}" + memorialize_account_html: "%{name} wandelte das Konto von %{target} in eine Gedenkseite um" + promote_user_html: "%{name} beförderte %{target}" + reject_appeal_html: "%{name} hat den Einspruch gegen eine Moderationsentscheidung von %{target} abgelehnt" reject_user_html: "%{name} hat die Registrierung von %{target} abgelehnt" - remove_avatar_user_html: "%{name} hat das Profilbild von %{target} entfernt" - reopen_report_html: "%{name} hat die Meldung %{target} wieder geöffnet" + remove_avatar_user_html: "%{name} entfernte das Profilbild von %{target}" + reopen_report_html: "%{name} öffnete die Meldung %{target} wieder" resend_user_html: "%{name} hat erneut eine Bestätigungs-E-Mail für %{target} gesendet" - reset_password_user_html: "%{name} hat das Passwort von %{target} zurückgesetzt" - resolve_report_html: "%{name} hat die Meldung %{target} geklärt" - sensitive_account_html: "%{name} hat die Medien von %{target} mit einer Inhaltswarnung versehen" - silence_account_html: "%{name} hat das Konto von %{target} stummgeschaltet" - suspend_account_html: "%{name} hat das Konto von %{target} gesperrt" - unassigned_report_html: "%{name} hat die Zuweisung der Meldung %{target} entfernt" + reset_password_user_html: "%{name} setzte das Passwort von %{target} zurück" + resolve_report_html: "%{name} klärte die Meldung %{target}" + sensitive_account_html: "%{name} versah die Medien von %{target} mit einer Inhaltswarnung" + silence_account_html: "%{name} schaltete das Konto von %{target} stumm" + suspend_account_html: "%{name} sperrte das Konto von %{target}" + unassigned_report_html: "%{name} entfernte die Zuweisung der Meldung %{target}" unblock_email_account_html: "%{name} hat die E-Mail-Adresse von %{target} entsperrt" unsensitive_account_html: "%{name} hat die Inhaltswarnung für Medien von %{target} aufgehoben" - unsilence_account_html: "%{name} hat die Stummschaltung von %{target} aufgehoben" - unsuspend_account_html: "%{name} hat die Kontosperre von %{target} aufgehoben" - update_announcement_html: "%{name} aktualisierte Ankündigung %{target}" - update_custom_emoji_html: "%{name} hat das Emoji geändert: %{target}" - update_domain_block_html: "%{name} hat die Domain-Sperre für %{target} aktualisiert" - update_ip_block_html: "%{name} hat die Regel für IP %{target} geändert" - update_status_html: "%{name} hat einen Beitrag von %{target} aktualisiert" - update_user_role_html: "%{name} hat die Rolle %{target} geändert" + unsilence_account_html: "%{name} hob die Stummschaltung von %{target} auf" + unsuspend_account_html: "%{name} entsperrte das Konto von %{target}" + update_announcement_html: "%{name} überarbeitete die Ankündigung %{target}" + update_custom_emoji_html: "%{name} bearbeitete das Emoji %{target}" + update_domain_block_html: "%{name} aktualisierte die Domain-Sperre für %{target}" + update_ip_block_html: "%{name} änderte die Regel für die IP-Adresse %{target}" + update_status_html: "%{name} überarbeitete einen Beitrag von %{target}" + update_user_role_html: "%{name} änderte die Rolle von %{target}" deleted_account: gelöschtes Konto empty: Protokolle nicht gefunden. filter_by_action: Nach Aktion filtern @@ -307,63 +309,64 @@ de: unpublish: Veröffentlichung rückgängig machen unpublished_msg: Ankündigung erfolgreich unveröffentlicht! updated_msg: Ankündigung erfolgreich aktualisiert! + critical_update_pending: Kritisches Update ausstehend custom_emojis: assign_category: Kategorie zuweisen by_domain: Domain - copied_msg: Lokale Kopie des Emoji erfolgreich erstellt + copied_msg: Lokale Kopie des Emojis erfolgreich erstellt copy: Kopieren - copy_failed_msg: Es konnte keine lokale Kopie des Emojis erstellt werden + copy_failed_msg: Es konnte keine lokale Kopie dieses Emojis auf diesem Server erstellt werden create_new_category: Neue Kategorie erstellen created_msg: Emoji erfolgreich erstellt! delete: Löschen destroyed_msg: Emoji erfolgreich gelöscht! disable: Deaktivieren disabled: Deaktiviert - disabled_msg: Das Emoji wurde erfolgreich deaktiviert + disabled_msg: Dieses Emoji wurde erfolgreich deaktiviert emoji: Emoji enable: Aktivieren enabled: Aktiviert - enabled_msg: Das Emoji wurde erfolgreich aktiviert + enabled_msg: Dieses Emoji wurde erfolgreich aktiviert image_hint: PNG oder GIF bis %{size} - list: Aufführen - listed: Angezeigt + list: Anzeigen + listed: Sichtbar new: title: Eigenes Emoji hinzufügen - no_emoji_selected: Keine Emojis wurden geändert, da keine ausgewählt wurden + no_emoji_selected: Keine Emojis wurden bearbeitet, da keine ausgewählt wurden not_permitted: Du bist für die Durchführung dieses Vorgangs nicht berechtigt overwrite: Überschreiben shortcode: Shortcode shortcode_hint: Mindestens 2 Zeichen, nur Buchstaben, Ziffern und Unterstriche title: Eigene Emojis - uncategorized: Nicht kategorisiert - unlist: Nicht Aufführen - unlisted: Nicht aufgeführt - update_failed_msg: Konnte dieses Emoji nicht aktualisieren - updated_msg: Emoji erfolgreich aktualisiert! + uncategorized: Unkategorisiert + unlist: Nicht anzeigen + unlisted: Nicht sichtbar + update_failed_msg: Konnte dieses Emoji nicht bearbeiten + updated_msg: Emoji erfolgreich bearbeitet! upload: Hochladen dashboard: - active_users: aktive Benutzer*innen + active_users: aktive Profile interactions: Interaktionen media_storage: Medien - new_users: neue Benutzer*innen - opened_reports: Erstellte Meldungen + new_users: neue Profile + opened_reports: eingereichte Meldungen pending_appeals_html: one: "%{count} ausstehender Einspruch" other: "%{count} ausstehende Einsprüche" pending_reports_html: - one: "%{count} ausstehende Meldung" - other: "%{count} ausstehende Meldungen" + one: "%{count} offene Meldung" + other: "%{count} offene Meldungen" pending_tags_html: - one: "%{count} ausstehender Hashtag" - other: "%{count} ausstehende Hashtags" + one: "%{count} ungeprüfter Hashtag" + other: "%{count} ungeprüfte Hashtags" pending_users_html: one: "%{count} unerledigte*r Benutzer*in" other: "%{count} unerledigte Benutzer*innen" - resolved_reports: erledigte Meldungen - software: Software + resolved_reports: geklärte Meldungen + software: Programme sources: Registrierungsort - space: Speicherverbrauch - title: Übersicht + space: Speicherplatz + title: Dashboard top_languages: Häufigste Sprachen top_servers: Aktivste Server website: Website @@ -372,36 +375,45 @@ de: empty: Keine Einsprüche gefunden. title: Einsprüche domain_allows: - add_new: Whitelist-Domain - created_msg: Domain wurde erfolgreich zur Whitelist hinzugefügt - destroyed_msg: Domain wurde von der Whitelist entfernt + add_new: Föderation mit Domain erlauben + created_msg: Domain wurde erfolgreich für die Föderation zugelassen + destroyed_msg: Domain wurde von der Föderation ausgeschlossen export: Exportieren - import: Import - undo: Von der Whitelist entfernen + import: Importieren + undo: Von der Föderation ausschließen domain_blocks: - add_new: Neue Domain-Sperre hinzufügen + add_new: Neue Domain einschränken + confirm_suspension: + cancel: Abbrechen + confirm: Sperren + permanent_action: Das Aufheben der Sperre wird keine Daten oder Beziehungen wiederherstellen. + preamble_html: Du bist dabei, %{domain} und alle Subdomains zu sperren. + remove_all_data: Alle Inhalte, Medien und Profildaten werden für die Konten dieser Domain von deinem Server entfernt. + stop_communication: Dein Server wird nicht länger mit diesen Servern kommunizieren. + title: Sperre für Domain %{domain} bestätigen + undo_relationships: Jede Follower-Beziehung, die zwischen deinem und deren Server besteht, wird aufgelöst. created_msg: Die Domain ist jetzt gesperrt bzw. eingeschränkt - destroyed_msg: Die Domain-Sperre wurde aufgehoben + destroyed_msg: Die Einschränkungen zu dieser Domain wurde entfernt domain: Domain - edit: Domain-Sperre bearbeiten + edit: Einschränkungen bearbeiten existing_domain_block: Du hast %{name} bereits stärker eingeschränkt. existing_domain_block_html: Du hast bereits strengere Beschränkungen für die Domain %{name} verhängt. Du musst diese erst aufheben. export: Exportieren import: Importieren new: - create: Sperre einrichten - hint: Die Domainsperre wird nicht verhindern, dass Konteneinträge in der Datenbank erstellt werden, sondern rückwirkend und automatisch alle Moderationsmethoden auf diese Konten anwenden. + create: Server einschränken + hint: Die Einschränkung einer Domain wird nicht verhindern, dass Konteneinträge in der Datenbank erstellt werden. Es werden aber alle Moderationsmethoden rückwirkend und automatisch auf diese Konten angewendet. severity: - desc_html: "Stummschaltung wird die Beiträge von Konten unter dieser Domain für alle unsichtbar machen, die den Konten nicht folgen. Eine Sperre wird alle Inhalte, Medien und Profildaten für Konten dieser Domain von deinem Server entfernen. Verwende keine, um nur Mediendateien abzulehnen." + desc_html: "Stummschalten wird Beiträge von Konten unter dieser Domain für alle unsichtbar machen, die den Konten nicht folgen. Sperren wird alle Inhalte, Medien und Profildaten für die Konten dieser Domain von deinem Server entfernen. Verwende Kein, wenn du nur Mediendateien ablehnen möchtest." noop: Kein silence: Stummschaltung suspend: Sperren - title: Neue Domain-Sperre + title: Neue Domain einschränken no_domain_block_selected: Keine Domains gesperrt, weil keine ausgewählt wurde(n) - not_permitted: Dir ist es nicht erlaubt, diese Handlung durchzuführen + not_permitted: Du bist nicht berechtigt, diese Aktion durchzuführen obfuscate: Domain-Name verschleiern obfuscate_hint: Den Domain-Namen öffentlich nur teilweise bekannt geben, sofern die Liste der Domain-Beschränkungen aktiviert ist - private_comment: Private bzw. nicht-öffentliche Notiz + private_comment: Interne bzw. nicht-öffentliche Notiz private_comment_hint: Kommentar zu dieser Domain-Beschränkung für die interne Nutzung durch die Moderator*innen. public_comment: Öffentliche Notiz public_comment_hint: Öffentlicher Hinweis zu dieser Domain-Beschränkung, sofern das Veröffentlichen von Sperrlisten grundsätzlich aktiviert ist. @@ -409,7 +421,7 @@ de: reject_media_hint: Entfernt lokal gespeicherte Mediendateien und verhindert deren künftiges Herunterladen. Für Sperren irrelevant reject_reports: Meldungen ablehnen reject_reports_hint: Alle Meldungen von dieser Domain ignorieren. Irrelevant für Sperrungen. - undo: Domain-Sperre aufheben + undo: Einschränkungen aufheben view: Domain-Sperre ansehen email_domain_blocks: add_new: Neue hinzufügen @@ -427,6 +439,7 @@ de: resolve: Domain auflösen title: Neue E-Mail-Domain sperren no_email_domain_block_selected: Keine E-Mail-Domain-Sperren wurden geändert, da keine ausgewählt wurden + not_permitted: Nicht gestattet resolved_dns_records_hint_html: Der Domain-Name wird an die folgenden MX-Domains aufgelöst, die letztendlich für die Annahme von E-Mails zuständig sind. Das Sperren einer MX-Domain sperrt Anmeldungen aller E-Mail-Adressen, die dieselbe MX-Domain verwenden, auch wenn die sichtbare Domain anders lautet. Achte daher darauf, große E-Mail-Anbieter versehentlich nicht auszusperren. resolved_through_html: Durch %{domain} aufgelöst title: Gesperrte E-Mail-Domains @@ -436,32 +449,32 @@ de: no_file: Keine Datei ausgewählt export_domain_blocks: import: - description_html: Du bist dabei, eine Liste von Domain-Sperren zu importieren. Bitte überprüfe diese Liste sehr sorgfältig, insbesondere dann, wenn du sie nicht selbst erstellt hast. - existing_relationships_warning: Bestehende Folgebeziehungen - private_comment_description_html: 'Damit du später nachvollziehen kannst, woher die importierten Sperren stammen, kannst du diesem Eintrag eine private Notiz hinzufügen: %{comment}' + description_html: Du bist dabei, eine Liste von Domains zu importieren, die auf diesem Server gesperrt oder anderweitig eingeschränkt werden. Bitte überprüfe diese Liste sehr sorgfältig, insbesondere dann, wenn du sie nicht selbst erstellt hast. + existing_relationships_warning: Vorhandene Follower-Beziehungen + private_comment_description_html: 'Damit du später nachvollziehen kannst, woher die importierten Sperren stammen, werden sie mit diesem privaten Kommentar erstellt: %{comment}' private_comment_template: Importiert von %{source} am %{date} - title: Domain-Sperren importieren + title: Domains importieren invalid_domain_block: 'Ein oder mehrere Domainsperren wurden wegen folgenden Fehler(n) übersprungen: %{error}' new: - title: Domain-Sperren importieren + title: Domains importieren no_file: Keine Datei ausgewählt follow_recommendations: - description_html: "Folgeempfehlungen helfen neuen Nutzer*innen, interessante Inhalte schnell zu finden. Wenn ein*e Nutzer*in noch nicht genug mit anderen interagiert hat, um personalisierte Folgeempfehlungen zu erhalten, werden stattdessen diese Profile verwendet. Sie werden täglich, basierend auf einer Mischung aus am meisten interagierenden Konten und jenen mit den meisten Followern für eine bestimmte Sprache, neu berechnet." + description_html: "Follower-Empfehlungen helfen neuen Nutzer*innen, interessante Inhalte schnell zu finden. Wenn ein*e Nutzer*in noch nicht genug mit anderen interagiert hat, um personalisierte Follower-Empfehlungen zu erhalten, werden stattdessen diese Profile vorgeschlagen. Sie werden täglich, basierend auf einer Mischung aus am meisten interagierenden Konten und jenen mit den meisten Followern für eine bestimmte Sprache neu berechnet." language: Für Sprache status: Status - suppress: Folgeempfehlungen unterdrücken + suppress: Folgeempfehlung unterbinden suppressed: Unterdrückt title: Folgeempfehlungen - unsuppress: Nicht mehr unterdrücken + unsuppress: Folgeempfehlung nicht mehr unterbinden instances: availability: description_html: - one: Wenn die Zustellung an die Domain seit %{count} Tag erfolglos bleibt, werden keine weiteren Zustellungsversuche unternommen, es sei denn, eine Zustellung von dieser Domain wird empfangen. - other: Wenn die Zustellung an die Domain seit %{count} Tagen erfolglos bleibt, werden keine weiteren Zustellungsversuche unternommen, es sei denn, eine Zustellung von dieser Domain wird empfangen. - failure_threshold_reached: Fehlschlag-Schwelle am %{date} erreicht. + one: Wenn die Zustellung an die Domain %{count} Tag lang erfolglos bleibt, werden keine weiteren Zustellversuche unternommen, bis eine Zustellung von der Domain empfangen wird. + other: Wenn die Zustellung an die Domain an %{count} unterschiedlichen Tagen erfolglos bleibt, werden keine weiteren Zustellversuche unternommen, bis eine Zustellung von der Domain empfangen wird. + failure_threshold_reached: Grenzwert von Fehlschlägen am %{date} überschritten. failures_recorded: - one: Fehlgeschlagener Versuch am %{count}. Tag. - other: Fehlgeschlagener Versuch am %{count}. Tag. + one: Fehlgeschlagener Versuch an %{count} Tag. + other: Fehlgeschlagene Versuche an %{count} unterschiedlichen Tagen. no_failures_recorded: Keine Fehler bei der Aufzeichnung. title: Verfügbarkeit warning: Der letzte Versuch, sich mit diesem Server zu verbinden, war nicht erfolgreich @@ -469,37 +482,38 @@ de: back_to_limited: Stummgeschaltet back_to_warning: Warnung by_domain: Domain - confirm_purge: Bist du dir sicher, dass du die Daten für diese Domain für immer löschen möchtest? + confirm_purge: Möchtest du die Daten von dieser Domain wirklich für immer löschen? content_policies: comment: Interne Notiz description_html: Du kannst Inhaltsrichtlinien definieren, die auf alle Konten dieser Domain und einer ihrer Subdomains angewendet werden. + limited_federation_mode_description_html: Du kannst auswählen, ob du eine Föderation mit dieser Domain erlaubst. policies: reject_media: Medien ablehnen reject_reports: Meldungen ablehnen - silence: Stummschalten + silence: Stummschaltung suspend: Gesperrt - policy: Richtlinie - reason: Öffentlicher Grund + policy: Einschränkung + reason: Öffentliche Begründung title: Inhaltsrichtlinien dashboard: - instance_accounts_dimension: Meiste gefolgte Konten - instance_accounts_measure: gespeicherte Konten - instance_followers_measure: unsere Follower dort + instance_accounts_dimension: Meistgefolgte Konten + instance_accounts_measure: deren Konten hier im Cache + instance_followers_measure: eigene Follower dort instance_follows_measure: deren Follower hier - instance_languages_dimension: Top Sprachen - instance_media_attachments_measure: gespeicherte Medienanhänge - instance_reports_measure: Meldungen über deren Accounts - instance_statuses_measure: gespeicherte Beiträge + instance_languages_dimension: Häufigste Sprachen + instance_media_attachments_measure: deren Medien hier im Cache + instance_reports_measure: Meldungen zu deren Konten + instance_statuses_measure: deren Beiträge hier im Cache delivery: all: Alle clear: Zustellfehler löschen failing: Fehlerhaft - restart: Lieferung neu starten - stop: Lieferung stoppen + restart: Zustellung neu starten + stop: Zustellung beenden unavailable: Nicht verfügbar delivery_available: Zustellung funktioniert - delivery_error_days: Tage seitdem die Zustellung nicht funktioniert - delivery_error_hint: Wenn eine Lieferung für %{count} Tage nicht möglich ist, wird sie automatisch als nicht lieferbar markiert. + delivery_error_days: Tage der fehlerhaften Zustellung + delivery_error_hint: Wenn eine Zustellung %{count} Tage lang nicht möglich ist, wird sie automatisch als unzustellbar markiert. destroyed_msg: Daten von %{domain} sind nun in der Warteschlange für die bevorstehende Löschung. empty: Keine Domains gefunden. known_accounts: @@ -508,11 +522,11 @@ de: moderation: all: Alle limited: Eingeschränkt - title: Moderation + title: Server private_comment: Privater Kommentar public_comment: Öffentlicher Kommentar - purge: Löschen - purge_description_html: Wenn du glaubst, dass diese Domain endgültig offline ist, kannst du alle Account-Datensätze und zugehörigen Daten aus dieser Domain löschen. Das kann eine Weile dauern. + purge: Säubern + purge_description_html: Wenn du glaubst, dass diese Domain endgültig offline ist, dann kannst du alle Kontodatensätze und zugehörigen Daten von diesem Server löschen. Das kann eine Weile dauern. title: Föderation total_blocked_by_us: Von uns gesperrt total_followed_by_them: Gefolgt von denen @@ -547,8 +561,8 @@ de: title: Beziehungen von %{acct} relays: add_new: Neues Relay hinzufügen - delete: Löschen - description_html: Ein Föderierungsrelay ist ein vermittelnder Server, der eine große Anzahl öffentlicher Beiträge zwischen Servern austauscht, die es abonnieren und zu ihm veröffentlichen. Es kann kleinen und mittleren Servern dabei helfen, Inhalte des Fediverse zu entdecken, was andernfalls das manuelle Folgen anderer Leute auf entfernten Servern durch lokale Nutzer erfordern würde. + delete: Entfernen + description_html: Ein Föderierungsrelay ist ein vermittelnder Server, der eine große Anzahl öffentlicher Beiträge zwischen Servern, die das Relay abonnieren und zu ihm veröffentlichen, austauscht. Es kann kleinen und mittleren Servern dabei helfen, Inhalte des Fediverse zu entdecken, was andernfalls das manuelle Folgen anderer Leute auf externen Servern durch lokale Nutzer*innen erfordern würde. disable: Ausschalten disabled: Ausgeschaltet enable: Einschalten @@ -557,69 +571,71 @@ de: inbox_url: Relay-URL pending: Warte auf Zustimmung des Relays save_and_enable: Speichern und aktivieren - setup: Relaisverbindung einrichten - signatures_not_enabled: Relais funktionieren nicht korrekt, während der sichere Modus oder der Whitelist-Modus aktiviert ist + setup: Neues Relay verbinden + signatures_not_enabled: Die Relays funktionieren nicht korrekt, wenn der abgesicherte Modus aktiviert oder die Föderation eingeschränkt ist status: Status - title: Relais + title: Relays report_notes: - created_msg: Meldungs-Kommentar erfolgreich erstellt! - destroyed_msg: Meldungs-Kommentar erfolgreich gelöscht! + created_msg: Notiz zur Meldung erfolgreich erstellt! + destroyed_msg: Notiz zur Meldung erfolgreich entfernt! reports: account: notes: one: "%{count} Notiz" other: "%{count} Notizen" action_log: Protokoll - action_taken_by: Maßnahme ergriffen durch + action_taken_by: Maßnahme ergriffen von actions: - delete_description_html: Der gemeldete Beitrag wird gelöscht und ein Strike wird aufgezeichnet, um dir bei zukünftigen Verstößen des gleichen Accounts zu helfen. - mark_as_sensitive_description_html: Die Medien in den gemeldeten Beiträgen werden mit einer Inhaltswarnung versehen und ein Verstoß wird vermerkt, um bei zukünftigen Verstößen desselben Kontos besser reagieren zu können. + delete_description_html: Der gemeldete Beitrag wird gelöscht und die ergriffene Maßnahme wird aufgezeichnet, um dir bei zukünftigen Verstößen des gleichen Kontos zu helfen. + mark_as_sensitive_description_html: Die Medien in den gemeldeten Beiträgen werden mit einer Inhaltswarnung versehen und der Vorfall wird vermerkt, um bei zukünftigen Verstößen desselben Kontos besser reagieren zu können. other_description_html: Weitere Optionen zur Steuerung des Kontoverhaltens und zur Anpassung der Kommunikation mit dem gemeldeten Konto. - resolve_description_html: Es wird keine Maßnahme gegen das gemeldete Konto ergriffen, es wird kein Strike verzeichnet und die Meldung wird geschlossen. + resolve_description_html: Es wird keine Maßnahme gegen das gemeldete Konto ergriffen und der Vorgang wird nicht aufgezeichnet – die Meldung wird hiermit geschlossen. silence_description_html: Das Konto wird nur für diejenigen sichtbar sein, die dem Konto bereits folgen oder es manuell suchen, was die Reichweite stark einschränkt. Kann jederzeit rückgängig gemacht werden. Alle Meldungen zu diesem Konto werden geschlossen. suspend_description_html: Das Konto und alle Inhalte werden unzugänglich und ggf. gelöscht. Eine Interaktion mit dem Konto wird unmöglich. Dies kann innerhalb von 30 Tagen rückgängig gemacht werden. Alle Meldungen zu diesem Konto werden geschlossen. - actions_description_html: Entscheide, welche Maßnahmen zur Lösung dieses Berichts zu ergreifen sind. Wenn du eine Strafmaßnahme gegen das gemeldete Konto ergreifst, wird eine E-Mail-Benachrichtigung an diese gesendet, außer wenn die Spam-Kategorie ausgewählt ist. - actions_description_remote_html: Entscheide, welche Maßnahmen du zur Lösung dieser Meldungen ergreifen möchtest. Dies wirkt sich lediglich darauf aus, wie dein Server mit diesem externen Konto kommuniziert und dessen Inhalt handhabt. - add_to_report: Mehr zur Meldung hinzufügen + actions_description_html: Entscheide, welche Maßnahmen du zum Klären dieser Meldung ergreifen möchtest. Wenn du eine Strafmaßnahme gegen das gemeldete Konto ergreifst, wird eine E-Mail-Benachrichtigung an dieses gesendet, außer wenn die Spam-Kategorie ausgewählt ist. + actions_description_remote_html: Entscheide, welche Maßnahmen du zum Klären dieser Meldung ergreifen möchtest. Dies wirkt sich lediglich darauf aus, wie dein Server mit diesem externen Konto kommuniziert und dessen Inhalt handhabt. + add_to_report: Meldung ergänzen are_you_sure: Bist du dir sicher? assign_to_self: Mir zuweisen assigned: Zugewiesene*r Moderator*in by_target_domain: Domain des gemeldeten Kontos + cancel: Abbrechen category: Kategorie - category_description_html: Der Grund, warum dieses Konto und/oder der Inhalt gemeldet wurden, wird in der Kommunikation mit dem gemeldeten Konto zitiert + category_description_html: Der Grund, weshalb dieses Konto und/oder der Inhalt gemeldet worden ist, wird in der Kommunikation mit dem gemeldeten Konto erwähnt comment: none: Kein - comment_description_html: 'Um weitere Informationen bereitzustellen, schrieb %{name} Folgendes:' - confirm_action: Moderationsaktion gegen @%{acct} bestätigen + comment_description_html: "%{name} ergänzte die Meldung um folgende Hinweis:" + confirm: Bestätigen + confirm_action: Maßnahme gegen @%{acct} bestätigen created_at: Gemeldet delete_and_resolve: Beiträge löschen forwarded: Weitergeleitet forwarded_to: Weitergeleitet an %{domain} - mark_as_resolved: Als gelöst markieren + mark_as_resolved: Als geklärt markieren mark_as_sensitive: Mit einer Inhaltswarnung versehen - mark_as_unresolved: Als ungelöst markieren + mark_as_unresolved: Als ungeklärt markieren no_one_assigned: Niemand notes: - create: Kommentar hinzufügen - create_and_resolve: Mit Kommentar lösen - create_and_unresolve: Mit Kommentar wieder öffnen + create: Notiz hinzufügen + create_and_resolve: Mit Notiz als geklärt markieren + create_and_unresolve: Mit Notiz wieder öffnen delete: Löschen placeholder: Bitte beschreibe, welche Maßnahmen bzw. Sanktionen ergriffen worden sind, und führe alles auf, was es Erwähnenswertes zu diesem Profil zu berichten gibt … title: Notizen notes_description_html: Notiz an dich und andere Moderator*innen hinterlassen - processed_msg: 'Meldung #%{id} erfolgreich bearbeitet' - quick_actions_description_html: 'Eine schnelle Aktion ausführen oder nach unten rolle, um gemeldete Inhalte zu sehen:' + processed_msg: Meldung Nr. %{id} erfolgreich bearbeitet + quick_actions_description_html: 'Führe eine schnelle Aktion aus oder scrolle nach unten, um gemeldete Inhalte zu sehen:' remote_user_placeholder: das externe Profil von %{instance} reopen: Meldung wieder eröffnen - report: 'Meldung #%{id}' + report: "%{id}. Meldung" reported_account: Gemeldetes Konto reported_by: Gemeldet von - resolved: Gelöst - resolved_msg: Meldung erfolgreich gelöst! - skip_to_actions: Zu Aktionen springen + resolved: Geklärt + resolved_msg: Meldung erfolgreich geklärt! + skip_to_actions: Zur Maßnahme springen status: Status statuses: Gemeldeter Inhalt - statuses_description_html: Störende Inhalte werden in der Kommunikation mit dem gemeldeten Konto zitiert + statuses_description_html: Beanstandete Inhalte werden in der Kommunikation mit dem gemeldeten Konto erwähnt summary: action_preambles: delete_html: 'Du bist dabei, einige Beiträge von @%{acct} zu entfernen. Dies wird:' @@ -627,22 +643,22 @@ de: silence_html: 'Du bist dabei, das Konto von @%{acct} einzuschränken. Dies wird:' suspend_html: 'Du bist dabei, das Konto von @%{acct} zu sperren. Dies wird:' actions: - delete_html: Die anstößigen Beiträge entfernen - mark_as_sensitive_html: Medien der anstößigen Beiträge mit einer Inhaltswarnung versehen + delete_html: Die beanstandeten Beiträge entfernen + mark_as_sensitive_html: Medien der beanstandeten Beiträge mit einer Inhaltswarnung versehen silence_html: Schränkt die Reichweite von @%{acct} stark ein, indem das Profil und dessen Inhalte nur für Personen sichtbar sind, die dem Profil bereits folgen oder es manuell aufrufen suspend_html: "@%{acct} sperren, sodass das Profil und dessen Inhalte nicht mehr zugänglich sind und keine Interaktion mehr möglich ist" - close_report: 'Meldung #%{id} als erledigt markieren' - close_reports_html: "Alle Meldungen gegen @%{acct} als erledigt markieren" - delete_data_html: Das Profil und die Inhalte von @%{acct} werden in 30 Tagen gelöscht, es sei denn, sie werden in der Zwischenzeit entsperrt + close_report: Meldung Nr. %{id} als geklärt markieren + close_reports_html: "Alle Meldungen gegen @%{acct} als geklärt markieren" + delete_data_html: Das Profil und die Inhalte von @%{acct} in 30 Tagen löschen, es sei denn, das Konto wird in der Zwischenzeit entsperrt preview_preamble_html: "@%{acct} wird eine Warnung mit folgenden Inhalten erhalten:" - record_strike_html: Einen Verstoß gegen @%{acct} eintragen, um bei zukünftigen Verstößen desselben Kontos besser reagieren zu können + record_strike_html: Einen Verstoß gegen @%{acct} vermerken, um bei zukünftigen Verstößen desselben Kontos besser reagieren zu können send_email_html: "@%{acct} eine Warnung per E-Mail senden" - warning_placeholder: Optional zusätzliche Begründung für die Moderationsmaßnahme. + warning_placeholder: "(Optional) Zusätzliche Begründung für die Moderationsaktion." target_origin: Domain des gemeldeten Kontos title: Meldungen - unassign: Zuweisung entfernen + unassign: Zuweisung aufheben unknown_action_msg: 'Unbekannte Aktion: %{action}' - unresolved: Ungelöst + unresolved: Ungeklärt updated_at: Aktualisiert view_profile: Profil anzeigen roles: @@ -655,11 +671,11 @@ de: devops: DevOps invites: Einladungen moderation: Moderation - special: Spezial - delete: Löschen - description_html: Mit Benutzer*inn-Rollen kannst du die Funktionen und Bereiche von Mastodon anpassen, auf die deine Benutzer*innen zugreifen können. + special: Besonderheit + delete: Entfernen + description_html: Mit Rollen kannst du die Funktionen und Bereiche von Mastodon anpassen, auf die deine Benutzer*innen zugreifen können. edit: Rolle „%{name}“ bearbeiten - everyone: Standardberechtigungen + everyone: Standard everyone_full_description_html: Das ist die Basis-Rolle, die für alle Benutzer*innen gilt – auch für diejenigen ohne zugewiesene Rolle. Alle anderen Rollen erben Berechtigungen davon. permissions_count: one: "%{count} Berechtigung" @@ -667,12 +683,12 @@ de: privileges: administrator: Administrator*in administrator_description: Benutzer*innen mit dieser Berechtigung werden alle Beschränkungen umgehen - delete_user_data: Profildaten löschen + delete_user_data: Kontodaten löschen delete_user_data_description: Erlaubt Benutzer*innen, die Daten anderer Benutzer*innen sofort zu löschen - invite_users: Benutzer*innen einladen + invite_users: Leute einladen invite_users_description: Erlaubt bereits registrierten Benutzer*innen, neue Leute zum Server einzuladen manage_announcements: Ankündigungen verwalten - manage_announcements_description: Erlaubt Benutzer*innen, Ankündigungen auf dem Server zu verwalten + manage_announcements_description: Erlaubt Profilen, Ankündigungen auf dem Server zu verwalten manage_appeals: Einsprüche verwalten manage_appeals_description: Erlaubt es Benutzer*innen, Entscheidungen der Moderator*innen zu widersprechen manage_blocks: Sperrungen verwalten @@ -680,7 +696,7 @@ de: manage_custom_emojis: Eigene Emojis verwalten manage_custom_emojis_description: Erlaubt es Benutzer*innen, eigene Emojis auf dem Server zu verwalten manage_federation: Föderation verwalten - manage_federation_description: Erlaubt Nutzer*innen, Domains anderer Mastodon-Server zu sperren oder zuzulassen – und die Zustellbarkeit zu steuern + manage_federation_description: Erlaubt Benutzer*innen, Domains anderer Mastodon-Server zu sperren oder zuzulassen – und die Zustellbarkeit zu steuern manage_invites: Einladungen verwalten manage_invites_description: Erlaubt es Benutzer*innen, Einladungslinks zu durchsuchen und zu deaktivieren manage_reports: Meldungen verwalten @@ -691,11 +707,11 @@ de: manage_rules_description: Erlaubt es Benutzer*innen, Serverregeln zu ändern manage_settings: Einstellungen verwalten manage_settings_description: Erlaubt Nutzer*innen, Einstellungen dieses Servers zu ändern - manage_taxonomies: Taxonomien verwalten + manage_taxonomies: Hashtags verwalten manage_taxonomies_description: Ermöglicht Benutzer*innen, die Trends zu überprüfen und die Hashtag-Einstellungen zu aktualisieren - manage_user_access: Benutzer*in-Zugriff verwalten + manage_user_access: Kontozugriff verwalten manage_user_access_description: Erlaubt es Benutzer*innen, die Zwei-Faktor-Authentisierung (2FA) anderer zu deaktivieren, ihre E-Mail-Adresse zu ändern und ihr Passwort zurückzusetzen - manage_users: Benutzer*innen verwalten + manage_users: Konten verwalten manage_users_description: Erlaubt es Benutzer*innen, die Details anderer Profile einzusehen und diese Accounts zu moderieren manage_webhooks: Webhooks verwalten manage_webhooks_description: Erlaubt es Benutzer*innen, Webhooks für administrative Vorkommnisse einzurichten @@ -720,23 +736,26 @@ de: rules_hint: Es gibt einen eigenen Bereich für Regeln, die deine Benutzer*innen einhalten müssen. title: Über appearance: - preamble: Die Oberfläche von Mastodon anpassen. + preamble: Passe das Webinterface von Mastodon an. title: Design branding: preamble: Das Branding deines Servers unterscheidet ihn von anderen Servern im Netzwerk. Diese Informationen können in einer Vielzahl von Umgebungen angezeigt werden, z. B. in der Weboberfläche von Mastodon, in nativen Anwendungen, in Linkvorschauen auf anderen Websites und in Messaging-Apps und so weiter. Aus diesem Grund ist es am besten, diese Informationen klar, kurz und prägnant zu halten. title: Branding + captcha_enabled: + desc_html: Dies beruht auf externen Skripten von hCaptcha, die ein Sicherheits- und Datenschutzproblem darstellen könnten. Darüber hinaus kann das den Registrierungsprozess für manche Menschen (insbesondere für Menschen mit Behinderung) erheblich erschweren. Aus diesen Gründen solltest du alternative Maßnahmen in Betracht ziehen, z. B. eine Registrierung basierend auf einer Einladung oder auf Genehmigungen. + title: Neue Nutzer*innen müssen ein CAPTCHA lösen, um das Konto zu bestätigen content_retention: - preamble: Lege fest, wie lange nutzergenerierte Inhalte auf deiner Mastodon-Instanz gespeichert werden. - title: Cache & Archive + preamble: Lege fest, wie lange Inhalte von Nutzer*innen auf deinem Mastodon-Server gespeichert bleiben. + title: Aufbewahrung von Inhalten default_noindex: - desc_html: Betrifft alle Benutzer, die diese Einstellung nicht selbst geändert haben - title: Benutzer standardmäßig von der Suchmaschinen-Indizierung ausnehmen + desc_html: Betrifft alle Profile, die diese Einstellung bei sich nicht geändert haben + title: Profile standardmäßig von der Suchmaschinen-Indizierung ausnehmen discovery: - follow_recommendations: Folgeempfehlungen + follow_recommendations: Follower-Empfehlungen preamble: Das Auffinden interessanter Inhalte ist wichtig, um neue Nutzer einzubinden, die Mastodon noch nicht kennen. Bestimme, wie verschiedene Suchfunktionen auf deinem Server funktionieren. profile_directory: Profilverzeichnis public_timelines: Öffentliche Timeline - publish_discovered_servers: Veröffentliche bekannte Server + publish_discovered_servers: Entdeckte Server offenlegen publish_statistics: Statistiken veröffentlichen title: Entdecken trends: Trends @@ -745,17 +764,34 @@ de: disabled: Niemandem users: Für angemeldete lokale Benutzer*innen registrations: - preamble: Lege fest, wer auf Deinem Server ein Konto erstellen darf. + preamble: Lege fest, wer auf deinem Server ein Konto erstellen darf. title: Registrierungen registrations_mode: modes: approved: Registrierung muss genehmigt werden - none: Niemand kann sich registrieren + none: Niemand darf sich registrieren open: Alle können sich registrieren - title: Server-Einstellungen + security: + authorized_fetch: Authentisierung von föderierten Servern erforderlich machen + authorized_fetch_hint: Das Anfordern einer Authentisierung von föderierten Servern ermöglicht ein strengeres Durchsetzen von Sperren sowohl auf Ebene der Benutzer*innen als auch des Servers. Allerdings ist das mit Leistungseinbußen verbunden, reduziert die Reichweite deiner Antworten und kann zu Kompatibilitätsproblemen mit einigen föderierten Diensten führen. Darüber hinaus wird das Abrufen deiner öffentlichen Beiträge und Konten durch spezialisierte Akteur*innen nicht verhindert. + authorized_fetch_overridden_hint: Diese Einstellung wird derzeit von einer Umgebungsvariable überschrieben und kann daher nicht geändert werden. + federation_authentication: Authentisierung von föderierten Servern durchsetzen + title: Servereinstellungen site_uploads: delete: Hochgeladene Datei löschen destroyed_msg: Upload erfolgreich gelöscht! + software_updates: + critical_update: Kritisch — bitte zügig aktualisieren + description: Es wird empfohlen, deine Mastodon-Installation auf dem aktuellen Stand zu halten, um von den neuesten Fehlerbehebungen und Funktionen zu profitieren. Darüber hinaus ist es wichtig, Mastodon zeitnah zu aktualisieren, um Sicherheitslücken zu schließen. Aus diesen Gründen prüft Mastodon alle 30 Minuten auf Updates und du wirst entsprechend deiner Einstellungen per E-Mail informiert. + documentation_link: Mehr erfahren + release_notes: Versionshinweise + title: Verfügbare Updates + type: Art + types: + major: Hauptversion + minor: Nebenversion + patch: Revision — Fehlerbehebungen und einfach zu implementierende Änderungen + version: Version statuses: account: Autor*in application: Anwendung @@ -783,18 +819,33 @@ de: with_media: Mit Medien strikes: actions: - delete_statuses: "%{name} hat die Beiträge von %{target} entfernt" - disable: "%{name} hat das Konto von %{target} eingefroren" + delete_statuses: "%{name} entfernte die Beiträge von %{target}" + disable: "%{name} fror das Konto von %{target} ein" mark_statuses_as_sensitive: "%{name} hat die Beiträge von %{target} mit einer Inhaltswarnung versehen" none: "%{name} hat eine Warnung an %{target} gesendet" - sensitive: "%{name} hat das Profil von %{target} mit einer Inhaltswarnung versehen" - silence: "%{name} hat das Konto von %{target} stummgeschaltet" - suspend: "%{name} hat das Konto von %{target} gesperrt" + sensitive: "%{name} versah das Konto von %{target} mit einer Inhaltswarnung" + silence: "%{name} schaltete das Konto von %{target} stumm" + suspend: "%{name} sperrte das Konto von %{target}" appeal_approved: Einspruch angenommen appeal_pending: Einspruch ausstehend + appeal_rejected: Einspruch abgelehnt system_checks: database_schema_check: message_html: Es gibt ausstehende Datenbankmigrationen. Bitte führe sie aus, um sicherzustellen, dass sich die Anwendung wie erwartet verhält + elasticsearch_health_red: + message_html: Elasticsearch-Cluster ist fehlerhaft (roter Status) – Suchfunktionen sind nicht verfügbar + elasticsearch_health_yellow: + message_html: Elasticsearch-Cluster ist fehlerhaft (gelber Status) – du solltest den Grund dafür untersuchen + elasticsearch_index_mismatch: + message_html: 'Elasticsearch-Index-Mappings sind veraltet. Bitte führe Folgendes aus: tootctl search deploy --only=%{value}' + elasticsearch_preset: + action: Dokumentation ansehen + message_html: Elasticsearch-Cluster besitzt mehr als einen Knoten, aber Mastodon ist nicht für die Verwendung dieser Knoten konfiguriert. + elasticsearch_preset_single_node: + action: Dokumentation ansehen + message_html: Elasticsearch-Cluster besitzt nur einen Knoten. ES_PRESET sollte auf single_node_cluster gesetzt werden. + elasticsearch_reset_chewy: + message_html: 'Elasticsearch-Systemindex ist aufgrund einer Einstellungsänderung veraltet. Bitte führe Folgendes zum Aktualisieren aus: tootctl search deploy --reset-chewy' elasticsearch_running_check: message_html: Verbindung mit Elasticsearch konnte nicht hergestellt werden. Bitte prüfe, ob Elasticsearch läuft, oder deaktiviere die Volltextsuche elasticsearch_version_check: @@ -802,12 +853,24 @@ de: version_comparison: Elasticsearch %{running_version} läuft, aber %{required_version} wird benötigt rules_check: action: Serverregeln verwalten - message_html: Du hast keine Serverregeln definiert. + message_html: Du hast keine Serverregeln festgelegt. sidekiq_process_check: message_html: Kein Sidekiq-Prozess läuft für die %{value} Warteschlange(n). Bitte überprüfe deine Sidekiq-Konfiguration + software_version_critical_check: + action: Verfügbare Updates ansehen + message_html: Ein kritisches Mastodon-Update ist verfügbar – bitte aktualisiere so schnell wie möglich. + software_version_patch_check: + action: Verfügbare Updates ansehen + message_html: Ein Mastodon-Update für Fehlerbehebungen ist verfügbar. + upload_check_privacy_error: + action: Für weitere Informationen hier klicken + message_html: "Die Konfiguration deines Servers ist fehlerhaft. Die Privatsphäre deiner Benutzer*innen ist gefährdet." + upload_check_privacy_error_object_storage: + action: Für weitere Informationen hier klicken + message_html: "Die Konfiguration deines Objektspeichers ist fehlerhaft. Die Privatsphäre deiner Benutzer*innen ist gefährdet." tags: review: Prüfstatus - updated_msg: Hashtageinstellungen wurden erfolgreich aktualisiert + updated_msg: Hashtag-Einstellungen erfolgreich aktualisiert title: Administration trends: allow: Erlauben @@ -816,68 +879,69 @@ de: links: allow: Link erlauben allow_provider: Herausgeber*in erlauben - description_html: Dies sind Links, die derzeit von zahlreichen Accounts geteilt werden und die deinem Server aufgefallen sind. Die Benutzer*innen können darüber herausfinden, was in der Welt vor sich geht. Die Links werden allerdings erst dann öffentlich vorgeschlagen, wenn du die Herausgeber*innen genehmigt hast. Du kannst alternativ aber auch nur einzelne URLs zulassen oder ablehnen. + description_html: Dies sind Links, die derzeit von zahlreichen Konten geteilt werden und die deinem Server aufgefallen sind. Die Benutzer*innen können darüber herausfinden, was in der Welt vor sich geht. Die Links werden allerdings erst dann öffentlich vorgeschlagen, wenn du die Herausgeber*innen genehmigt hast. Du kannst alternativ aber auch nur einzelne URLs zulassen oder ablehnen. disallow: Link verbieten disallow_provider: Herausgeber*in verbieten no_link_selected: Keine Links wurden geändert, da keine ausgewählt wurden publishers: - no_publisher_selected: Keine Herausgeber wurden geändert, da keine ausgewählt wurden + no_publisher_selected: Keine Herausgeber*innen wurden geändert, da keine ausgewählt wurden shared_by_over_week: - one: In der letzten Woche von einer Person geteilt - other: In der letzten Woche von %{count} Personen geteilt + one: In den vergangenen 7 Tagen von einem Profil geteilt + other: In den vergangenen 7 Tagen von %{count} Profilen geteilt title: Angesagte Links - usage_comparison: Heute %{today} Mal geteilt, gestern %{yesterday} Mal + usage_comparison: Heute %{today}-mal und gestern %{yesterday}-mal geteilt + not_allowed_to_trend: Darf nicht trenden only_allowed: Nur Genehmigte pending_review: Überprüfung ausstehend preview_card_providers: - allowed: Links von diesem Herausgeber können angesagt sein + allowed: Links von diesem/dieser Herausgeber*in können im Trend liegen description_html: Dies sind Domains, von denen Links oft auf deinem Server geteilt werden. Links werden nicht öffentlich trenden, es sei denn, die Domain des Links wird genehmigt. Deine Zustimmung (oder Ablehnung) erstreckt sich auf Subdomains. - rejected: Links von diesem Herausgeber können nicht angesagt sein + rejected: Links von diesem/dieser Herausgeber*in werden nicht im Trend liegen title: Herausgeber rejected: Abgelehnt statuses: allow: Beitrag erlauben - allow_account: Autor*in erlauben + allow_account: Profil erlauben description_html: Dies sind Beiträge, von denen dein Server weiß, dass sie derzeit viel geteilt und favorisiert werden. Dies kann neuen und wiederkehrenden Personen helfen, weitere Profile zu finden, denen sie folgen können. Die Beiträge werden erst dann öffentlich angezeigt, wenn du die Person genehmigst und sie es zulässt, dass ihr Profil anderen vorgeschlagen wird. Du kannst auch einzelne Beiträge zulassen oder ablehnen. disallow: Beitrag verbieten - disallow_account: Autor*in verweigern - no_status_selected: Keine angesagten Beiträge wurden geändert, da keine ausgewählt wurden + disallow_account: Profil verweigern + no_status_selected: Die im Trend liegenden Beiträge wurden nicht geändert, da keine ausgewählt wurden not_discoverable: Autor*in hat sich dafür entschieden, nicht entdeckt zu werden shared_by: one: Einmal geteilt oder favorisiert other: "%{friendly_count}-mal geteilt oder favorisiert" title: Angesagte Beiträge tags: - current_score: Aktuelle Punktzahl %{score} + current_score: 'Aktueller Score: %{score}' dashboard: - tag_accounts_measure: eindeutige Verwendungen - tag_languages_dimension: Top Sprachen - tag_servers_dimension: Top Server - tag_servers_measure: verschiedene Server - tag_uses_measure: Gesamtnutzungen + tag_accounts_measure: Profile + tag_languages_dimension: Häufigste Sprachen + tag_servers_dimension: Aktivste Server + tag_servers_measure: Server + tag_uses_measure: insgesamt description_html: Diese Hashtags werden derzeit in vielen Beiträgen verwendet, die dein Server sieht. Dies kann deinen Nutzer*innen helfen, herauszufinden, worüber die Leute im Moment am meisten schreiben. Hashtags werden erst dann öffentlich angezeigt, wenn du sie genehmigst. listable: Kann vorgeschlagen werden - no_tag_selected: Keine Tags wurden geändert, da keine ausgewählt wurden + no_tag_selected: Keine Hashtags wurden geändert, da keine ausgewählt wurden not_listable: Wird nicht vorgeschlagen - not_trendable: Wird nicht unter Trends angezeigt + not_trendable: Wird in den Trends nicht angezeigt not_usable: Kann nicht verwendet werden peaked_on_and_decaying: In den Trends am %{date}, jetzt absteigend title: Angesagte Hashtags - trendable: Darf unter Trends erscheinen - trending_rank: 'Trend #%{rank}' - usable: Kann verwendet werden - usage_comparison: Heute %{today} Mal genutzt, gestern %{yesterday} Mal + trendable: Darf in den Trends erscheinen + trending_rank: Platz %{rank} + usable: Darf verwendet werden + usage_comparison: Heute %{today}-mal und gestern %{yesterday}-mal verwendet used_by_over_week: - one: In der letzten Woche von einer Person genutzt - other: In der letzten Woche von %{count} Personen genutzt + one: In den vergangenen 7 Tagen von einem Profil verwendet + other: In den vergangenen 7 Tagen von %{count} Profilen verwendet title: Trends - trending: Häufig diskutiert + trending: Angesagt warning_presets: add_new: Neu hinzufügen delete: Löschen - edit_preset: Warnungsvorlage bearbeiten - empty: Du hast noch keine Warnungsvorlagen hinzugefügt. - title: Warnungsvorlagen verwalten + edit_preset: Warnvorlage bearbeiten + empty: Du hast noch keine Warnvorlagen hinzugefügt. + title: Warnvorlagen verwalten webhooks: add_new: Endpunkt hinzufügen delete: Löschen @@ -903,21 +967,27 @@ de: actions: delete_statuses: das Löschen der Beiträge disable: das Einfrieren der Konten - mark_statuses_as_sensitive: das Markieren der Beiträge mit einer Inhaltswarnung + mark_statuses_as_sensitive: um die Beiträge des Profils mit einer Inhaltswarnung zu versehen none: eine Warnung - sensitive: das Markieren des Profils mit einer Inhaltswarnung + sensitive: das Markieren des Kontos mit einer Inhaltswarnung silence: das Beschränken des Kontos suspend: um deren Konto zu sperren - body: "%{target} hat etwas gegen eine Moderationsentscheidung von %{action_taken_by} vom %{date}, die %{type} war. Die Person schrieb:" - next_steps: Du kannst dem Einspruch zustimmen und die Moderationsentscheidung rückgängig machen oder ignorieren. - subject: "%{username} hat Einspruch gegen eine Moderationsentscheidung von %{instance} eingelegt" + body: "%{target} erhebt Einspruch gegen eine Moderationsentscheidung von %{action_taken_by} vom %{date} (%{type}). Folgendes wurde geschrieben:" + next_steps: Du kannst dem Einspruch zustimmen, um die Moderationsentscheidung rückgängig zu machen, oder ihn ignorieren. + subject: "%{username} hat Einspruch gegen eine Moderationsentscheidung auf %{instance} erhoben" + new_critical_software_updates: + body: Kritische Updates wurden für Mastodon veröffentlicht – du solltest so schnell wie möglich aktualisieren! + subject: Kritische Mastodon-Updates sind für %{instance} verfügbar! new_pending_account: body: Die Details von diesem neuem Konto sind unten. Du kannst die Anfrage akzeptieren oder ablehnen. - subject: Neues Konto zur Überprüfung auf %{instance} verfügbar (%{username}) + subject: Neues Konto zum Überprüfen auf %{instance} verfügbar (%{username}) new_report: body: "%{reporter} hat %{target} gemeldet" body_remote: Jemand von %{domain} hat %{target} gemeldet - subject: Neue Meldung auf %{instance} (#%{id}) + subject: Neue Meldung auf %{instance} (Nr. %{id}) + new_software_updates: + body: Neue Mastodon-Versionen wurden veröffentlicht – du solltest aktualisieren! + subject: Neue Mastodon-Versionen sind für %{instance} verfügbar! new_trends: body: 'Die folgenden Einträge müssen überprüft werden, bevor sie öffentlich angezeigt werden können:' new_trending_links: @@ -925,89 +995,106 @@ de: new_trending_statuses: title: Angesagte Beiträge new_trending_tags: - no_approved_tags: Derzeit gibt es keine genehmigten trendenen Hashtags. + no_approved_tags: Es gibt keine genehmigten Hashtags, die gerade im Trend liegen. requirements: 'Jeder dieser Kandidaten könnte den #%{rank} genehmigten angesagten Hashtag übertreffen, der derzeit #%{lowest_tag_name} mit einer Punktzahl von %{lowest_tag_score} ist.' title: Angesagte Hashtags subject: Neue Trends zur Überprüfung auf %{instance} aliases: add_new: Alias erstellen - created_msg: Ein neuer Alias wurde erfolgreich erstellt. Du kannst nun den Wechsel vom alten Konto starten. + created_msg: Neuer Alias erfolgreich erstellt. Du kannst nun den Umzug vom alten zum neuen Konto starten. deleted_msg: Der Alias wurde erfolgreich entfernt. Aus jenem Konto zu diesem zu verschieben, ist nicht mehr möglich. - empty: Du hast keine Aliase. - hint_html: Wenn du von einem Konto zu einem anderen Konto wechseln möchtest, dann kannst du einen Alias erstellen, welcher benötigt wird, bevor du deine Follower vom alten Account zu diesen migrierst. Die Aktion allein ist harmlos und wi­der­ruf­lich. Die Kontenmigration wird vom alten Konto aus eingeleitet. - remove: Alle Aliase aufheben + empty: Du hast keine Aliasse. + hint_html: Wenn du von einem anderen Konto auf dieses umziehen möchtest, dann kannst du hier einen Alias erstellen, der erforderlich ist, um deine Follower vom alten Konto auf dieses zu migrieren. Diese Aktion ist harmlos und wi­der­ruf­lich. Der Kontoumzug wird vom alten Konto aus eingeleitet. + remove: Alle Aliasse aufheben appearance: advanced_web_interface: Erweitertes Webinterface - advanced_web_interface_hint: Wenn du mehr aus deiner Bildschirmbreite herausholen möchtest, kannst du mit dem erweiterten Webinterface weitere Spalten hinzufügen und dadurch mehr Informationen auf einmal sehen, z. B. deine Startseite, die Mitteilungen, die föderierte Timeline sowie beliebig viele deiner Listen und Hashtags. + advanced_web_interface_hint: Wenn du mehr aus deiner Bildschirmbreite herausholen möchtest, kannst du mit dem erweiterten Webinterface weitere Spalten hinzufügen und dadurch mehr Informationen auf einmal sehen, z. B. deine Startseite, die Benachrichtigungen, die föderierte Timeline sowie beliebig viele deiner Listen und Hashtags. animations_and_accessibility: Animationen und Barrierefreiheit confirmation_dialogs: Bestätigungsdialoge discovery: Entdecken localization: body: Mastodon wird von Freiwilligen übersetzt. - guide_link: https://de.crowdin.com/project/mastodon + guide_link: https://de.crowdin.com/project/mastodon/de guide_link_text: Alle können mitmachen und etwas dazu beitragen. sensitive_content: Inhaltswarnung - toot_layout: Timeline-Layout application_mailer: notification_preferences: E-Mail-Einstellungen ändern salutation: "%{name}," settings: 'E-Mail-Einstellungen ändern: %{link}' - view: 'Ansehen:' + unsubscribe: Abbestellen + view: 'Hier überprüfen:' view_profile: Profil anzeigen - view_status: Beitrag öffnen + view_status: Beitrag anschauen applications: created: Anwendung erfolgreich erstellt destroyed: Anwendung erfolgreich gelöscht - regenerate_token: Zugangs-Token neu erstellen + logout: Abmelden + regenerate_token: Zugriffstoken neu erstellen token_regenerated: Zugriffstoken erfolgreich neu erstellt warning: Sei mit diesen Daten sehr vorsichtig. Teile sie mit niemandem! - your_token: Dein Zugangs-Token + your_token: Dein Zugriffstoken auth: apply_for_account: Konto beantragen - change_password: Passwort + captcha_confirmation: + help_html: Falls du Probleme beim Lösen des CAPTCHA hast, dann kannst uns über %{email} kontaktieren und wir werden versuchen, dir zu helfen. + hint_html: Fast geschafft! Wir müssen uns vergewissern, dass du ein Mensch bist (damit wir Spam verhindern können!). Bitte löse das CAPTCHA und klicke auf „Weiter“. + title: Sicherheitsüberprüfung confirmations: - wrong_email_hint: Wenn diese E-Mail-Adresse nicht korrekt ist, kann sie in den Kontoeinstellungen geändert werden. + wrong_email_hint: Sollte diese E-Mail-Adresse nicht korrekt sein, kannst du sie in den Kontoeinstellungen ändern. delete_account: Konto löschen delete_account_html: Falls du dein Konto endgültig löschen möchtest, kannst du das hier vornehmen. Du musst dies zusätzlich bestätigen. description: - prefix_invited_by_user: "@%{name} lädt dich ein, diesem Server von Mastodon beizutreten!" + prefix_invited_by_user: "@%{name} lädt dich ein, diesem Mastodon-Server beizutreten!" prefix_sign_up: Registriere dich noch heute bei Mastodon! suffix: Mit einem Konto kannst du Profilen folgen, neue Beiträge veröffentlichen, Nachrichten mit Personen von jedem Mastodon-Server austauschen und vieles mehr! - didnt_get_confirmation: Keine Bestätigungsanweisungen erhalten? - dont_have_your_security_key: Hast du keinen Sicherheitsschlüssel? + didnt_get_confirmation: Keinen Bestätigungslink erhalten? + dont_have_your_security_key: Du hast keinen Sicherheitsschlüssel? forgot_password: Passwort vergessen? invalid_reset_password_token: Das Token zum Zurücksetzen des Passworts ist ungültig oder abgelaufen. Bitte fordere ein neues an. - link_to_otp: Gib einen Zwei-Faktor-Code von deinem Handy oder einen Wiederherstellungscode ein - link_to_webauth: Verwende dein Sicherheitsschlüsselgerät + link_to_otp: Gib einen Zwei-Faktor-Code von deinem Smartphone oder einen Wiederherstellungscode ein + link_to_webauth: Verwende deinen Sicherheitsschlüssel log_in_with: Anmelden mit login: Anmelden logout: Abmelden migrate_account: Zu einem anderen Konto umziehen - migrate_account_html: Wenn du dieses Konto auf ein anderes umleiten möchtest, kannst du es hier konfigurieren. + migrate_account_html: Wenn du dieses Konto auf ein anderes weiterleiten möchtest, kannst du es hier konfigurieren. or_log_in_with: Oder anmelden mit privacy_policy_agreement_html: Ich habe die Datenschutzerklärung gelesen und stimme ihr zu + progress: + confirm: E-Mail-Adresse bestätigen + details: Deine Daten + review: Unsere Überprüfung + rules: Regeln akzeptieren providers: cas: CAS saml: SAML register: Registrieren registration_closed: "%{instance} akzeptiert keine neuen Mitglieder" - resend_confirmation: Bestätigungsanweisungen erneut senden + resend_confirmation: Bestätigungslink erneut zusenden reset_password: Passwort zurücksetzen rules: - preamble: Diese werden von den %{domain}-Moderator*innen festgelegt und erzwungen. + accept: Akzeptieren + back: Zurück + invited_by: 'Du kannst %{domain} beitreten – dank der Einladung von:' + preamble: Diese werden von den Moderator*innen von %{domain} festgelegt und durchgesetzt. + preamble_invited: Bevor du fortfährst, beachte bitte die Grundregeln der Moderator*innen von %{domain}. title: Einige Grundregeln. + title_invited: Du wurdest eingeladen. security: Sicherheit - set_new_password: Neues Passwort setzen + set_new_password: Neues Passwort einrichten setup: - email_below_hint_html: Wenn die unten stehende E-Mail-Adresse falsch ist, kannst du sie hier ändern und eine neue Bestätigungs-E-Mail erhalten. - email_settings_hint_html: Die Bestätigungs-E-Mail wurde an %{email} gesendet. Wenn diese E-Mail-Adresse nicht korrekt ist, kannst du sie in den Einstellungen ändern. - title: Konfiguration + email_below_hint_html: Überprüfe deinen Spam-Ordner oder lass dir den Bestätigungslink erneut zusenden. Falls die angegebene E-Mail-Adresse falsch ist, kannst du sie auch korrigieren. + email_settings_hint_html: Klicke auf den Bestätigungslink, den wir an %{email} gesendet haben, um die Adresse zu verifizieren. Wir warten hier solange auf dich. + link_not_received: Keinen Bestätigungslink erhalten? + new_confirmation_instructions_sent: In wenigen Minuten wirst du eine neue E-Mail mit dem Bestätigungslink erhalten! + title: Überprüfe dein E-Mail-Postfach sign_in: preamble_html: Melde dich mit deinen Zugangsdaten für %{domain} an. Solltest du dein Konto auf einem anderen Server registriert haben, ist eine Anmeldung hier nicht möglich. title: Bei %{domain} anmelden sign_up: - preamble: Mit einem Account auf diesem Mastodon-Server kannst du jeder anderen Person im Netzwerk folgen, unabhängig davon, wo ihr Account gehostet wird. - title: Okay, lass uns mit %{domain} anfangen. + manual_review: Registrierungen für den Server %{domain} werden manuell durch unsere Moderator*innen überprüft. Um uns dabei zu unterstützen, schreibe etwas über dich und sage uns, weshalb du ein Konto auf %{domain} anlegen möchtest. + preamble: Mit einem Konto auf diesem Mastodon-Server kannst du jeder anderen Person im Netzwerk folgen, unabhängig davon, wo ihr Konto registriert ist. + title: Lass uns dein Konto auf %{domain} einrichten. status: account_status: Kontostatus confirming: Auf die Bestätigung deiner E-Mail-Adresse wird gewartet. @@ -1015,25 +1102,13 @@ de: pending: Die Prüfung deiner Bewerbung steht noch aus. Dies kann einige Zeit in Anspruch nehmen. Sobald deine Bewerbung genehmigt wurde, erhältst du eine E-Mail. redirecting_to: Dein Konto ist inaktiv, weil es zu %{acct} umgezogen ist. view_strikes: Vorherige Verstöße deines Kontos ansehen - too_fast: Formular zu schnell gesendet, versuche es erneut. + too_fast: Formular zu schnell übermittelt. Bitte versuche es erneut. use_security_key: Sicherheitsschlüssel verwenden - authorize_follow: - already_following: Du folgst diesem Konto bereits - already_requested: Du hast bereits eine Anfrage zum Folgen diesen Accounts versendet - error: Das Remote-Konto konnte nicht geladen werden - follow: Folgen - follow_request: 'Du hast eine Folgeanfrage gesendet an:' - following: 'Erfolg! Du folgst nun:' - post_follow: - close: Oder du schließt einfach dieses Fenster. - return: Benutzerprofil anzeigen - web: In der Benutzeroberfläche öffnen - title: "%{acct} folgen" challenge: confirm: Fortfahren hint_html: "Hinweis: Wir werden dich für die nächste Stunde nicht erneut nach deinem Passwort fragen." invalid_password: Ungültiges Passwort - prompt: Gib dein Passwort ein, um fortzufahren + prompt: Bestätige mit deinem Passwort, um fortzufahren crypto: errors: invalid_key: ist kein gültiger Ed25519- oder Curve25519-Schlüssel @@ -1041,21 +1116,21 @@ de: date: formats: default: "%d. %b %Y" - with_month_name: "%B %d, %Y" + with_month_name: "%d. %B %Y" datetime: distance_in_words: - about_x_hours: "%{count}h" - about_x_months: "%{count}mo" - about_x_years: "%{count}y" - almost_x_years: "%{count}y" + about_x_hours: "%{count} Std." + about_x_months: "%{count} Mon." + about_x_years: "%{count} J." + almost_x_years: "%{count} J." half_a_minute: Gerade eben - less_than_x_minutes: "%{count}m" + less_than_x_minutes: "%{count} Min." less_than_x_seconds: Gerade eben - over_x_years: "%{count}J" - x_days: "%{count}T" - x_minutes: "%{count}m" - x_months: "%{count}mo" - x_seconds: "%{count}s" + over_x_years: "%{count} J." + x_days: "%{count} T." + x_minutes: "%{count} Min." + x_months: "%{count} Mon." + x_seconds: "%{count} Sek." deletes: challenge_not_passed: Die eingegebenen Informationen waren nicht korrekt confirm_password: Gib dein derzeitiges Passwort ein, um deine Identität zu bestätigen @@ -1063,19 +1138,19 @@ de: proceed: Konto löschen success_msg: Dein Konto wurde erfolgreich gelöscht warning: - before: 'Bevor du fortfährst, lies bitte diese Punkte sorgfältig durch:' - caches: Inhalte, die von anderen Servern zwischengespeichert wurden, können weiterhin bestehen + before: 'Bevor du fortfährst, lies bitte diese Hinweise sorgfältig durch:' + caches: Inhalte, die von anderen Servern zwischengespeichert wurden, können fortbestehen data_removal: Deine Beiträge und alle anderen Daten werden für immer entfernt email_change_html: Du kannst deine E-Mail-Adresse ändern, ohne dein Konto zu löschen - email_contact_html: Wenn die Bestätigungs-E-Mail immer noch nicht ankam, kannst du eine E-Mail an %{email} senden, um weitere Hilfe zu erhalten + email_contact_html: Sollte sie noch immer nicht angekommen sein, kannst du eine E-Mail an %{email} senden, um weitere Hilfe zu erhalten email_reconfirmation_html: Wenn du die Bestätigungs-E-Mail nicht erhalten hast, kannst du sie erneut anfordern - irreversible: Du kannst dein Konto nicht mehr wiederherstellen oder reaktivieren + irreversible: Du wirst dein Konto nicht mehr wiederherstellen oder reaktivieren können more_details_html: Weitere Details findest du in der Datenschutzerklärung. username_available: Dein Profilname wird wieder verfügbar sein username_unavailable: Dein Profilname wird auch nach dem Löschen für andere nicht zugänglich sein disputes: strikes: - action_taken: Maßnahme ergriffen + action_taken: Maßnahme appeal: Einspruch appeal_approved: Dieser Verstoß wurde erfolgreich angefochten und ist nicht mehr gültig appeal_rejected: Der Einspruch wurde abgelehnt @@ -1084,80 +1159,84 @@ de: appeals: submit: Einspruch erheben approve_appeal: Einspruch annehmen - associated_report: Zugehöriger Bericht + associated_report: Zugehörige Meldung created_at: Datum - description_html: Dies sind Aktionen gegen dein Konto und Warnungen, die von den Mitarbeitern von %{instance} an dich gesendet wurden. + description_html: Dies sind Maßnahmen, die gegen dein Konto ergriffen worden sind, und Warnungen, die dir die Mitarbeiter*innen von %{instance} gesendet haben. recipient: Adressiert an reject_appeal: Einspruch ablehnen - status: 'Beitrag #%{id}' + status: "%{id}. Beitrag" status_removed: Beitrag bereits vom System entfernt title: "%{action} vom %{date}" title_actions: delete_statuses: Beitragsentfernung - disable: Einfrieren des Kontos + disable: Konto einfrieren mark_statuses_as_sensitive: Beiträge mit einer Inhaltswarnung versehen none: Warnung sensitive: Profil mit einer Inhaltswarnung versehen silence: Kontobeschränkung suspend: Kontosperre your_appeal_approved: Dein Einspruch wurde angenommen - your_appeal_pending: Du hast Einspruch eingelegt + your_appeal_pending: Du hast Einspruch erhoben your_appeal_rejected: Dein Einspruch wurde abgelehnt domain_validator: - invalid_domain: ist kein gültiger Domain-Name + invalid_domain: ist keine gültige Domain + edit_profile: + basic_information: Allgemeine Informationen + hint_html: "Bestimme, was andere auf deinem öffentlichen Profil und neben deinen Beiträgen sehen können. Wenn du ein Profilbild festlegst und dein Profil vervollständigst, werden andere eher mit dir interagieren und dir folgen." + other: Andere errors: - '400': Die Anfrage, die du gesendet hast, war ungültig oder fehlerhaft. - '403': Dir fehlt die Befugnis, diese Seite sehen zu können. + '400': Die Anfrage, die du gestellt hast, war ungültig oder fehlerhaft. + '403': Dir fehlt die Berechtigung, diese Seite aufzurufen. '404': Die Seite, nach der du gesucht hast, wurde nicht gefunden. '406': Diese Seite ist im gewünschten Format nicht verfügbar. '410': Die Seite, nach der du gesucht hast, existiert hier nicht mehr. '422': - content: Sicherheitsüberprüfung fehlgeschlagen. Sperrst du Cookies aus? + content: Sicherheitsüberprüfung fehlgeschlagen. Blockierst du Cookies? title: Sicherheitsüberprüfung fehlgeschlagen - '429': Du wurdest gedrosselt + '429': Zu viele Anfragen '500': - content: Bitte verzeih', etwas ist bei uns schiefgegangen. - title: Diese Seite ist kaputt + content: Wir bitten um Verzeihung, aber etwas ist bei uns schiefgegangen. + title: Diese Seite enthält einen Fehler '503': Die Seite konnte wegen eines temporären Serverfehlers nicht angezeigt werden. - noscript_html: Bitte aktiviere JavaScript, um die Mastodon-Web-Anwendung zu verwenden. Alternativ kannst du auch eine der nativen Mastodon-Anwendungen für deine Plattform probieren. + noscript_html: Bitte aktiviere JavaScript, um das Webinterface von Mastodon zu verwenden. Alternativ kannst du auch eine der nativen Apps für Mastodon verwenden. existing_username_validator: - not_found: kann lokale*n Benutzer*in mit diesem Profilnamen nicht finden - not_found_multiple: "%{usernames} können nicht gefunden werden" + not_found: kann lokale Konten mit diesem Profilnamen nicht finden + not_found_multiple: "%{usernames} konnten nicht gefunden werden" exports: archive_takeout: date: Datum download: Archiv jetzt herunterladen hint_html: Du kannst ein Archiv deiner Beiträge, Listen, hochgeladenen Medien usw. anfordern. Die exportierten Daten werden im ActivityPub-Format gespeichert und können mit geeigneter Software ausgewertet und angezeigt werden. Du kannst alle 7 Tage ein Archiv erstellen lassen. - in_progress: Persönliches Archiv wird erstellt … + in_progress: Persönliches Archiv wird erstellt … request: Dein Archiv anfordern - size: Größe - blocks: Gesperrte Accounts + size: Dateigröße + blocks: Blockierte Profile bookmarks: Lesezeichen csv: CSV - domain_blocks: Gesperrte Domains + domain_blocks: Blockierte Domains lists: Listen - mutes: Stummgeschaltete Accounts + mutes: Stummgeschaltete Profile storage: Medienspeicher featured_tags: - add_new: Neu hinzufügen + add_new: Neuen hinzufügen errors: - limit: Du hast bereits die maximale Anzahl an empfohlenen Hashtags erreicht - hint_html: "Was sind empfohlene Hashtags? Sie werden in deinem öffentlichen Profil hervorgehoben und ermöglichen es den Menschen, deine öffentlichen Beiträge speziell unter diesen Hashtags zu durchsuchen. Sie sind ein großartiges Werkzeug, um kreative Werke oder langfristige Projekte zu verfolgen." + limit: Du hast bereits die maximale Anzahl an Hashtags erreicht + hint_html: "Präsentiere deine wichtigsten Hashtags auf deinem Profil. Vorgestellte Hashtags verschaffen einen Überblick über deine kreativen Werke und langfristigen Projekte. Sie werden gut sichtbar auf deinem Profil angezeigt und ermöglichen einen schnellen Zugriff auf deine eigenen Beiträge." filters: contexts: account: Profile - home: Startseite - notifications: Mitteilungen + home: Startseite und Listen + notifications: Benachrichtigungen public: Öffentliche Timelines thread: Unterhaltungen edit: - add_keyword: Stichwort hinzufügen - keywords: Stichwörter + add_keyword: Schlagwort hinzufügen + keywords: Schlagwörter statuses: Individuelle Beiträge - statuses_hint_html: Dieser Filter gilt für die Auswahl einzelner Beiträge, unabhängig davon, ob sie mit den unten stehenden Schlüsselwörtern übereinstimmen. Beiträge im Filter ansehen oder entfernen.. + statuses_hint_html: Dieser Filter gilt für die Auswahl einzelner Beiträge, unabhängig davon, ob sie mit den unten aufgeführten Schlagwörtern übereinstimmen. Beiträge überprüfen oder aus dem Filter entfernen. title: Filter bearbeiten errors: - deprecated_api_multiple_keywords: Diese Parameter können von dieser Anwendung nicht geändert werden, da sie auf mehr als ein Filterschlüsselwort angewendet werden. Verwende eine neuere Anwendung oder das Webinterface. + deprecated_api_multiple_keywords: Diese Parameter können von dieser Anwendung nicht geändert werden, da sie für mehr als ein Filterschlagwort gelten. Verwende eine aktuellere Anwendung oder das Webinterface. invalid_context: Ungültiger oder fehlender Kontext übergeben index: contexts: Filter in %{contexts} @@ -1166,8 +1245,8 @@ de: expires_in: Läuft ab in %{distance} expires_on: Läuft am %{date} ab keywords: - one: "%{count} Stichwort" - other: "%{count} Stichwörter" + one: "%{count} Schlagwort" + other: "%{count} Schlagwörter" statuses: one: "%{count} Beitrag" other: "%{count} Beiträge" @@ -1179,56 +1258,94 @@ de: save: Neuen Filter speichern title: Neuen Filter hinzufügen statuses: - back_to_filter: Zurück zum Filter + back_to_filter: Zurück zu den Filtern batch: remove: Filter entfernen index: hint: Dieser Filter wird verwendet, um einzelne Beiträge unabhängig von anderen Kriterien auszuwählen. Du kannst mehr Beiträge zu diesem Filter über das Webinterface hinzufügen. title: Gefilterte Beiträge - footer: - trending_now: In den Trends generic: all: Alle all_items_on_page_selected_html: one: "%{count} Element auf dieser Seite ausgewählt." other: Alle %{count} Elemente auf dieser Seite ausgewählt. all_matching_items_selected_html: - one: "%{count} Element trifft auf ihre Suche zu." - other: Alle %{count} Elemente, die Ihrer Suche entsprechen, werden ausgewählt. - changes_saved_msg: Änderungen gespeichert! + one: "%{count} Element, das den Suchkriterien entspricht, ist ausgewählt." + other: Alle %{count} Elemente, die den Suchkriterien entsprechen, sind ausgewählt. + cancel: Abbrechen + changes_saved_msg: Änderungen erfolgreich gespeichert! + confirm: Bestätigen copy: Kopieren delete: Löschen - deselect: Auswahl für alle aufheben + deselect: Alle abwählen none: Keine order_by: Sortieren nach save_changes: Änderungen speichern select_all_matching_items: - one: Wähle %{count} Element, das deiner Suche entspricht. - other: Wählen Sie alle %{count} Elemente, die Ihrer Suche entsprechen. + one: Wähle %{count} Element, das deinen Suchkriterien entspricht. + other: Wähle alle %{count} Elemente, die deinen Suchkriterien entsprechen. today: heute validation_errors: one: Etwas ist noch nicht ganz richtig! Bitte korrigiere den Fehler other: Etwas ist noch nicht ganz richtig! Bitte korrigiere %{count} Fehler - html_validator: - invalid_markup: 'enthält ungültiges HTML-Markup: %{error}' imports: errors: + empty: Leere CSV-Datei + incompatible_type: Inkompatibel mit dem ausgewählten Importtyp invalid_csv_file: 'Ungültige CSV-Datei. Fehler: %{error}' over_rows_processing_limit: enthält mehr als %{count} Zeilen + too_large: Datei ist zu groß + failures: Fehler + imported: Importiert + mismatched_types_warning: Möglicherweise hast du den falschen Typ für diesen Import ausgewählt. Bitte überprüfe alles noch einmal. modes: merge: Zusammenführen - merge_long: Behalte existierende Datensätze und füge neue hinzu + merge_long: Bestehende Datensätze beibehalten und neue hinzufügen overwrite: Überschreiben - overwrite_long: Ersetze aktuelle Datensätze mit neuen - preface: Daten, die du von einem anderen Server exportiert hast, kannst du hierher importieren. Das betrifft beispielsweise die Listen von Profilen, denen du folgst oder die du gesperrt hast. + overwrite_long: Bestehende Datensätze durch neue ersetzen + overwrite_preambles: + blocking_html: Du bist dabei, deine Liste blockierter Konten durch bis zu %{total_items} Konten aus %{filename} zu ersetzen. + bookmarks_html: Du bist dabei, deine Lesezeichen durch bis zu %{total_items} Beiträge aus %{filename} zu ersetzen. + domain_blocking_html: Du bist dabei, deine Liste blockierter Domains durch bis zu %{total_items} Domains aus %{filename} zu ersetzen. + following_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} zu folgen und niemand anderes zu folgen. + lists_html: Du bist dabei, deine Listen durch den Inhalt aus %{filename} zu ersetzen. Es werden bis zu %{total_items} Konten zu neuen Listen hinzugefügt. + muting_html: Du bist dabei, deine Liste stummgeschalteter Konten durch bis zu %{total_items} Konten aus %{filename} zu ersetzen. + preambles: + blocking_html: Du bist dabei, bis zu %{total_items}%{total_items} Konten aus %{filename} zu blockieren. + bookmarks_html: Du bist dabei, bis zu %{total_items} Beiträge aus %{filename} zu deinen Lesezeichen hinzuzufügen. + domain_blocking_html: Du bist dabei, bis zu %{total_items} Domains aus %{filename} zu blockieren. + following_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} zu folgen. + lists_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} zu deinen Listen hinzuzufügen. Wenn es keine Liste gibt, zu der etwas hinzugefügt werden kann, dann werden neue Listen erstellt. + muting_html: Du bist dabei, bis zu %{total_items} Konten aus %{filename} stummzuschalten. + preface: Daten, die du von einem Mastodon-Server exportiert hast, kannst du hierher importieren. Das betrifft beispielsweise die Listen von Profilen, denen du folgst oder die du blockiert hast. + recent_imports: Zuletzt importiert + states: + finished: Fertig + in_progress: In Bearbeitung + scheduled: Geplant + unconfirmed: Unbestätigt + status: Status success: Deine Daten wurden erfolgreich hochgeladen und werden in Kürze verarbeitet + time_started: Gestartet am + titles: + blocking: Blockierte Konten importieren + bookmarks: Lesezeichen importieren + domain_blocking: Blockierte Domains importieren + following: Gefolgte Konten importieren + lists: Listen importieren + muting: Stummgeschaltete Konten importieren + type: Importtyp + type_groups: + constructive: Folge ich & Lesezeichen + destructive: Blockierte & Stummgeschaltete types: - blocking: Sperrliste + blocking: Blockierte Profile bookmarks: Lesezeichen - domain_blocking: Domain-Sperrliste - following: Folgeliste - muting: Stummschaltungsliste - upload: Liste importieren + domain_blocking: Blockierte Domains + following: Folge ich + lists: Listen + muting: Stummgeschaltete Profile + upload: Datei importieren invites: delete: Deaktivieren expired: Abgelaufen @@ -1243,14 +1360,14 @@ de: generate: Einladungslink erstellen invited_by: 'Du wurdest eingeladen von:' max_uses: - one: 1 mal verwendet - other: "%{count} mal verwendet" + one: Eine Verwendung + other: "%{count} Verwendungen" max_uses_prompt: Keine Einschränkung prompt: Erstelle Einladungen und teile die dazugehörigen Links, um anderen einen Zugang zu diesem Server zu gewähren table: expires_at: Läuft ab - uses: Verwendet - title: Leute einladen + uses: Verwendungen + title: Einladungen lists: errors: limit: Du hast die maximale Anzahl an Listen erreicht @@ -1261,50 +1378,65 @@ de: sign_in_token: E-Mail-Sicherheitscode webauthn: Sicherheitsschlüssel description_html: Wenn du verdächtige Aktivitäten bemerkst, die du nicht verstehst oder zuordnen kannst, solltest du dringend dein Passwort ändern und ungeachtet dessen die Zwei-Faktor-Authentisierung (2FA) aktivieren. - empty: Kein Authentifizierungsverlauf verfügbar - failed_sign_in_html: Fehler beim Anmeldeversuch mit %{method} von %{ip} (%{browser}) - successful_sign_in_html: Erfolgreiche Anmeldung mit %{method} von %{ip} (%{browser}) - title: Authentifizierungsverlauf + empty: Kein Anmeldeverlauf verfügbar + failed_sign_in_html: Fehlgeschlagener Anmeldeversuch mit %{method} von %{ip} (%{browser}) + successful_sign_in_html: Erfolgreiches Anmelden mit %{method} von %{ip} (%{browser}) + title: Anmeldeverlauf + mail_subscriptions: + unsubscribe: + action: Ja, abbestellen + complete: Abbestellt + confirmation_html: Möchtest du %{type} für Mastodon auf %{domain} an deine E-Mail-Adresse %{email} wirklich abbestellen? Du kannst dies später in den Einstellungen Benachrichtigungen per E-Mail rückgängig machen. + emails: + notification_emails: + favourite: E-Mail-Benachrichtigungen für Favoriten + follow: E-Mail-Benachrichtigungen für Follower + follow_request: E-Mail-Benachrichtigungen für Follower-Anfragen + mention: E-Mail-Benachrichtigungen für Erwähnungen + reblog: E-Mail-Benachrichtigungen für geteilte Beiträge + resubscribe_html: Falls du etwas irrtümlich abbestellt hast, kannst du das in den Einstellungen Benachrichtigungen per E-Mail rückgängig machen. + success_html: Du wirst nicht länger %{type} für Mastodon auf %{domain} an deine E-Mail-Adresse %{email} erhalten. + title: Abbestellen media_attachments: validations: - images_and_video: Es kann kein Video an einen Beitrag, der bereits Bilder enthält, angehängt werden - not_ready: Dateien, die noch nicht bearbeitet wurden, können nicht angehängt werden. Versuche es gleich noch einmal! - too_many: Es können nicht mehr als 4 Dateien angehängt werden + images_and_video: Es kann kein Video an einen Beitrag angehängt werden, der bereits Bilder enthält + not_ready: Dateien, die noch nicht verarbeitet wurden, können nicht angehängt werden. Versuche es gleich noch einmal! + too_many: Mehr als vier Dateien können nicht angehängt werden migrations: acct: umgezogen nach - cancel: Umleitung abbrechen - cancel_explanation: Das Abbrechen der Umleitung wird dein aktuelles Konto erneut aktivieren, aber keine Follower, die auf dieses Konto verschoben wurden, zurückholen. - cancelled_msg: Die Umleitung wurde erfolgreich abgebrochen. + cancel: Weiterleitung beenden + cancel_explanation: Das Abbrechen der Weiterleitung wird dein aktuelles Konto erneut aktivieren, aber keine Follower zurückholen, die auf dieses Konto verschoben wurden. + cancelled_msg: Die Weiterleitung wurde erfolgreich beendet. errors: already_moved: ist das gleiche Konto, zu dem du bereits umgezogen bist - missing_also_known_as: referenziert nicht zurück auf dieses Konto + missing_also_known_as: ist kein Alias für dieses Konto move_to_self: darf nicht das aktuelles Konto sein - not_found: kann nicht gefunden werden + not_found: konnte nicht gefunden werden on_cooldown: Die Abklingzeit läuft gerade - followers_count: Anzahl der Follower zum Zeitpunkt der Migration des Accounts + followers_count: Anzahl der Follower zum Zeitpunkt des Umzugs incoming_migrations: Von einem anderen Konto umziehen - incoming_migrations_html: Um von einem anderen Konto zu diesem zu wechseln, musst du zuerst einen Kontoalias erstellen. - moved_msg: Dein altes Profil wird jetzt zum neuen Account %{acct} weitergeleitet und deine Follower werden übertragen. + incoming_migrations_html: Um von einem anderen Konto zu diesem umzuziehen, musst du zuerst ein Konto-Alias erstellen. + moved_msg: Dein Konto wird jetzt auf %{acct} weitergeleitet und deine Follower werden übertragen. not_redirecting: Dein Konto wird derzeit nicht auf ein anderes Konto weitergeleitet. - on_cooldown: Du hast dein Konto vor kurzem migriert. Diese Funktion wird in %{count} Tagen wieder verfügbar sein. - past_migrations: Vorherige Migrationen + on_cooldown: Du bist mit deinem Konto erst vor Kurzem umgezogen. Diese Funktion wird in %{count} Tagen wieder verfügbar sein. + past_migrations: Vorherige Umzüge proceed_with_move: Follower übertragen redirected_msg: Dein Konto wird nun zu %{acct} weitergeleitet. redirecting_to: Dein Konto wird zu %{acct} weitergeleitet. - set_redirect: Umleitung einrichten + set_redirect: Weiterleitung einrichten warning: - backreference_required: Das neue Konto muss zuerst so konfiguriert werden, dass es auf das alte Konto referenziert + backreference_required: Das neue Konto muss zuerst auf das alte Konto verweisen before: 'Bevor du fortfährst, lies bitte diese Hinweise sorgfältig durch:' - cooldown: Nach dem Migrieren wird es eine Abklingzeit geben, in der du das Konto nicht noch einmal migrieren kannst - disabled_account: Dein aktuelles Konto wird nachher nicht vollständig nutzbar sein. Du hast jedoch Zugriff auf den Datenexport sowie die Reaktivierung. - followers: Alle Follower werden vom aktuellen zum neuen Konto übertragen - only_redirect_html: Alternativ kannst du nur eine Weiterleitung auf dein Profil erstellen. - other_data: Keine anderen Daten werden automatisch verschoben - redirect: Das Profil deines aktuellen Kontos wird mit einer Weiterleitungsnachricht versehen und von Suchanfragen ausgeschlossen + cooldown: Nach dem Umzug wird es eine Weile dauern, bis du erneut umziehen darfst + disabled_account: Dein altes Konto ist nur noch eingeschränkt nutzbar. 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 Profil einrichten, ohne die Follower zu übertragen. + other_data: Keine anderen Daten werden automatisch zum neuen Konto übertragen + redirect: Dein altes Konto wird einen Hinweis erhalten, dass du umgezogen bist. Außerdem wird das Profil von Suchanfragen ausgeschlossen moderation: title: Moderation move_handler: - carry_blocks_over_text: Dieses Konto ist von %{acct}, das du gesperrt hast, umgezogen. + carry_blocks_over_text: Dieses Konto ist von %{acct}, das du blockiert hast, umgezogen. carry_mutes_over_text: Dieses Konto ist von %{acct}, das du stummgeschaltet hast, umgezogen. copy_account_note_text: 'Dieses Konto ist von %{acct} umgezogen. Hier deine damals verfassten Notizen zum Profil:' navigation: @@ -1317,54 +1449,55 @@ de: subject: "%{name} registrierte sich" favourite: body: 'Dein Beitrag wurde von %{name} favorisiert:' - subject: "%{name} hat deinen Beitrag favorisiert" + subject: "%{name} favorisierte deinen Beitrag" title: Neue Favorisierung follow: body: "%{name} folgt dir jetzt!" subject: "%{name} folgt dir jetzt" title: Neuer Follower follow_request: - action: Verwalte Folge-Anfragen + action: Follower-Anfragen verwalten body: "%{name} möchte dir folgen" - subject: 'Ausstehender Follower: %{name}' - title: Neue Folge-Anfrage + subject: 'Ausstehende Folgeanfragen: %{name}' + title: Neue Follower-Anfrage mention: action: Antworten - body: "%{name} hat dich erwähnt:" - subject: "%{name} hat dich erwähnt" + body: 'Du wurdest von %{name} erwähnt:' + subject: "%{name} erwähnte dich" title: Neue Erwähnung poll: subject: Eine Umfrage von %{name} ist beendet reblog: - body: 'Deinen Beitrag hat %{name} geteilt:' - subject: "%{name} hat deinen Beitrag geteilt" + body: 'Dein Beitrag wurde von %{name} geteilt:' + subject: "%{name} teilte deinen Beitrag" title: Dein Beitrag wurde geteilt status: - subject: "%{name} hat gerade etwas gepostet" + subject: "%{name} veröffentlichte gerade einen Beitrag" update: subject: "%{name} bearbeitete einen Beitrag" notifications: + administration_emails: Admin-E-Mail-Benachrichtigungen email_events: Benachrichtigungen per E-Mail - email_events_hint: 'Bitte die Ereignisse auswählen, für die du Benachrichtigungen erhalten möchtest:' - other_settings: Weitere Einstellungen + email_events_hint: 'Bitte die Ereignisse auswählen, für die du Benachrichtigungen per E-Mail erhalten möchtest:' + other_settings: Weitere Benachrichtigungseinstellungen number: human: decimal_units: - format: "%n%u" + format: "%n %u" units: - billion: B - million: M - quadrillion: Q - thousand: K - trillion: T + billion: Mrd. + million: Mio. + quadrillion: Brd. + thousand: Tsd. + trillion: Bio. otp_authentication: code_hint: Gib den Code ein, den deine 2FA- bzw. TOTP-App generiert hat, um den Vorgang zu bestätigen description_html: Wenn du die Zwei-Faktor-Authentisierung (2FA) mit einer Authentifizierungs-App deines Smartphones aktivierst, benötigst du neben dem regulären Passwort zusätzlich auch den zeitbasierten Code der 2FA-App, um dich anmelden zu können. enable: Aktivieren - instructions_html: "Scanne diesen QR-Code mit einer TOTP-App (wie dem Google Authenticator). Die 2FA-App generiert dann zeitbasierte Codes, die du beim Login zusätzlich zum regulären Passwort eingeben musst." + instructions_html: "Scanne diesen QR-Code mit einer beliebigen Authentisierungs-App (TOTP). Diese App generiert dann zeitbasierte Codes, die du beim Anmelden zusätzlich zum regulären Passwort eingeben musst." manual_instructions: Wenn du den QR-Code nicht einscannen kannst, sondern die Zahlenfolge manuell eingeben musst, ist hier der geheime Token für deine 2FA-App. setup: Einrichten - wrong_code: Der eingegebene Code war ungültig! Sind die Serverzeit und die Gerätezeit korrekt? + wrong_code: Der eingegebene Code ist ungültig! Laufen Serverzeit und Gerätezeit synchron? pagination: newer: Neuer next: Weiter @@ -1373,58 +1506,69 @@ de: truncate: "…" polls: errors: - already_voted: Du hast bereits für diese Umfrage abgestimmt + already_voted: An dieser Umfrage hast du bereits teilgenommen duplicate_options: enthält doppelte Einträge - duration_too_long: ist zu weit in der Zukunft + duration_too_long: liegt zu weit in der Zukunft duration_too_short: ist zu früh - expired: Die Umfrage ist bereits vorbei - invalid_choice: Die gewählte Abstimmoption existiert nicht - over_character_limit: kann nicht länger als jeweils %{max} Zeichen sein - too_few_options: muss mindestens einen Eintrag haben - too_many_options: kann nicht mehr als %{max} Einträge beinhalten + expired: Diese Umfrage ist bereits beendet + invalid_choice: Diese Auswahl existiert nicht + over_character_limit: darf nicht länger als %{max} Zeichen sein + self_vote: Du kannst an deinen eigenen Umfragen nicht selbst teilnehmen + too_few_options: muss mehr als ein Auswahlfeld enthalten + too_many_options: darf nicht mehr als %{max} Auswahlfelder enthalten preferences: other: Erweitert posting_defaults: Standardeinstellungen für Beiträge public_timelines: Öffentliche Timelines + privacy: + hint_html: "Bestimme, wie dein Profil und deine Beiträge gefunden werden sollen. Eine Vielzahl von Funktionen in Mastodon können dir helfen, eine größere Reichweite zu erlangen, wenn sie aktiviert sind. Nimm dir einen Moment Zeit, um diese Einstellungen zu überprüfen und sicherzustellen, dass sie für deinen Anwendungsfall geeignet sind." + privacy: Datenschutz + privacy_hint_html: Bestimme, wie viele Informationen du für andere preisgeben möchtest. Viele Menschen entdecken interessante Profile und coole Apps, indem sie die Follower anderer Profile durchstöbern und die Apps sehen, über die Beiträge veröffentlicht wurden – möglicherweise möchtest du diese Informationen ausblenden. + reach: Reichweite + reach_hint_html: Bestimme, ob Profile dich entdecken und dir folgen dürfen. Möchtest du, dass deine Beiträge unter „Entdecken“ erscheinen? Möchtest du, dass andere dich in ihren Follower-Empfehlungen sehen? Möchtest du alle neuen Follower automatisch akzeptieren oder jeden einzelnen genehmigen? + search: Suche + search_hint_html: Bestimme, wie du entdeckt werden möchtest. Möchtest du, dass die Leute dich anhand deiner öffentlichen Beiträge finden können? Möchtest du, dass Menschen außerhalb von Mastodon dein Profil finden, wenn sie im Internet suchen? Bitte beachte, dass ein vollständiger Ausschluss aus allen Suchmaschinen für öffentlich zugängliche Informationen nicht garantiert werden kann. + title: Datenschutz und Reichweite privacy_policy: title: Datenschutzerklärung reactions: errors: limit_reached: Limit für verschiedene Reaktionen erreicht - unrecognized_emoji: ist kein anerkanntes Emoji + unrecognized_emoji: ist ein unbekanntes Emoji relationships: activity: Kontoaktivität - confirm_follow_selected_followers: Bist du dir sicher, dass du den ausgewählten Followern folgen möchtest? - confirm_remove_selected_followers: Bist du sicher, dass du den ausgewählten Konten entfolgen möchtest? - confirm_remove_selected_follows: Bist du sicher, dass du den ausgewählten Konten entfolgen möchtest? + confirm_follow_selected_followers: Möchtest du den ausgewählten Followern folgen? + confirm_remove_selected_followers: Möchtest du die ausgewählten Follower wirklich entfernen? + confirm_remove_selected_follows: Möchtest du den ausgewählten Konten wirklich entfolgen? dormant: Inaktiv + follow_failure: Einigen der ausgewählten Konten konnte nicht gefolgt werden. follow_selected_followers: Ausgewählten Followern folgen followers: Follower following: Folge ich invited: Eingeladen last_active: Zuletzt aktiv - most_recent: Neuste + most_recent: Neueste moved: Umgezogen mutual: Gegenseitig primary: Primär relationship: Beziehung - remove_selected_domains: Entferne alle Follower von den ausgewählten Domains - remove_selected_followers: Entferne ausgewählte Follower - remove_selected_follows: Ausgewählten Benutzer*innen entfolgen + remove_selected_domains: Alle Follower von den ausgewählten Domains entfernen + remove_selected_followers: Ausgewählten Followern entfolgen + remove_selected_follows: Ausgewählten Profilen entfolgen status: Kontostatus remote_follow: missing_resource: Die erforderliche Weiterleitungs-URL für dein Konto konnte nicht gefunden werden reports: errors: - invalid_rules: verweist nicht auf gültige Regeln + invalid_rules: verweist nicht auf gültige Serverregeln rss: content_warning: 'Inhaltswarnung:' descriptions: account: Öffentliche Beiträge von @%{acct} - tag: 'Öffentliche Beiträge mit dem Tag #%{hashtag}' + tag: 'Öffentliche Beiträge mit dem Hashtag #%{hashtag}' scheduled_statuses: - over_daily_limit: Du hast das Limit für geplante Beiträge, welches %{limit} beträgt, für heute erreicht - over_total_limit: Du hast das Limit für geplante Beiträge, welches %{limit} beträgt, erreicht + over_daily_limit: Du hast das Limit von %{limit} geplanten Beiträgen für heute erreicht + over_total_limit: Du hast das Limit für geplante Beiträge, das %{limit} beträgt, erreicht too_soon: Das geplante Datum muss in der Zukunft liegen sessions: activity: Letzte Aktivität @@ -1433,10 +1577,11 @@ de: alipay: Alipay blackberry: BlackBerry chrome: Chrome - edge: Microsoft Edge + edge: Edge electron: Electron firefox: Firefox generic: Unbekannter Browser + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1591,7 @@ de: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Unbekannter Browser weibo: Weibo current_session: Aktuelle Sitzung description: "%{browser} auf %{platform}" @@ -1458,37 +1604,38 @@ de: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux - mac: Mac - other: unbekanntes Betriebssystem + mac: macOS + unknown_platform: Unbekannte Plattform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone revoke: Widerrufen - revoke_success: Sitzung erfolgreich geschlossen + revoke_success: Sitzung erfolgreich widerrufen title: Sitzungen - view_authentication_history: Authentifizierungsverlauf deines Kontos anzeigen + view_authentication_history: Anmeldeverlauf deines Kontos anzeigen settings: account: Konto account_settings: Kontoeinstellungen - aliases: Kontoaliase + aliases: Konto-Aliasse appearance: Design - authorized_apps: Genehmigte Apps + authorized_apps: Autorisierte Anwendungen back: Zurück zu Mastodon - delete: Konto löschen + delete: Kontolöschung development: Entwicklung edit_profile: Profil bearbeiten export: Exportieren - featured_tags: Empfohlene Hashtags + featured_tags: Vorgestellte Hashtags import: Importieren import_and_export: Importieren und exportieren - migrate: Konto-Umzug + migrate: Kontoumzug notifications: Benachrichtigungen preferences: Einstellungen - profile: Profil - relationships: Folge ich und Follower + profile: Öffentliches Profil + relationships: Follower und Folge ich statuses_cleanup: Automatische Löschung - strikes: Moderieren von Verstößen + strikes: Maßnahmen two_factor_authentication: Zwei-Faktor-Authentisierung (2FA) webauthn_authentication: Sicherheitsschlüssel statuses: @@ -1507,13 +1654,13 @@ de: content_warning: 'Inhaltswarnung: %{warning}' default_language: Wie die Sprache des Webinterface disallowed_hashtags: - one: 'enthält einen verbotenen Hashtag: %{tags}' - other: 'enthält verbotene Hashtags: %{tags}' - edited_at_html: Bearbeitet %{date} + one: 'enthält einen nicht-erlaubten Hashtag: %{tags}' + other: 'enthält nicht-erlaubte Hashtags: %{tags}' + edited_at_html: 'Bearbeitet: %{date}' errors: in_reply_not_found: Der Beitrag, auf den du antworten möchtest, scheint nicht zu existieren. - open_in_web: Im Web öffnen - over_character_limit: Zeichenlimit von %{max} überschritten + open_in_web: Im Webinterface öffnen + 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 limit: Du hast bereits die maximale Anzahl an Beiträgen angeheftet @@ -1531,37 +1678,36 @@ de: show_newer: Neuere anzeigen show_older: Ältere anzeigen show_thread: Thread anzeigen - sign_in_to_participate: Melde dich an, um an der Unterhaltung teilzunehmen - title: '%{name}: "%{quote}"' + title: "%{name}: „%{quote}“" visibilities: direct: Direktnachricht - private: Nur eigene Follower - private_long: Nur für deine eigenen Follower sichtbar + private: Nur Follower + private_long: Nur für deine Follower sichtbar public: Öffentlich public_long: Für alle sichtbar unlisted: Nicht gelistet - unlisted_long: Für alle sichtbar, aber in öffentlichen Timelines nicht aufgelistet + unlisted_long: Für alle sichtbar (mit Ausnahme von öffentlichen Timelines) statuses_cleanup: - enabled: Automatisch alte Beiträge löschen + enabled: Alte Beiträge automatisch entfernen enabled_hint: Löscht automatisch deine Beiträge, sobald sie die angegebene Altersgrenze erreicht haben, es sei denn, sie entsprechen einer der unten angegebenen Ausnahmen exceptions: Ausnahmen explanation: Damit Mastodon nicht durch das Löschen von Beiträgen ausgebremst wird, wartet der Server damit, bis wenig los ist. Aus diesem Grund werden deine Beiträge ggf. erst einige Zeit nach Erreichen der Altersgrenze gelöscht. ignore_favs: Favoriten ignorieren ignore_reblogs: Geteilte Beiträge ignorieren interaction_exceptions: Ausnahmen basierend auf Interaktionen - interaction_exceptions_explanation: Beachte, dass Beiträge nicht gelöscht werden, sobald deine Grenzwerte für Favoriten oder geteilte Beiträge einmal überschritten worden sind – auch dann nicht, wenn diese Schwellenwerte mittlerweile nicht mehr erreicht werden. - keep_direct: Direktnachrichten behalten - keep_direct_hint: Löscht keine deiner privaten Nachrichten - keep_media: Beiträge mit angehängten Medien-Dateien behalten - keep_media_hint: Löscht keinen deiner Beiträge mit angehängten Medien-Dateien + interaction_exceptions_explanation: Beachte, dass Beiträge nicht gelöscht werden, sobald deine Grenzwerte für Favoriten oder geteilte Beiträge einmal überschritten wurden – auch dann nicht, wenn diese Schwellenwerte mittlerweile nicht mehr erreicht werden. + keep_direct: Private Nachrichten behalten + keep_direct_hint: Löscht keinen deiner Beiträge, die nur für erwähnte Profile sichtbar sind + keep_media: Beiträge mit Medien behalten + keep_media_hint: Löscht keinen deiner Beiträge mit Medienanhängen keep_pinned: Angeheftete Beiträge behalten - keep_pinned_hint: Löscht keinen deiner angehefteten Beiträge im Profil + keep_pinned_hint: Löscht keinen deiner angehefteten Beiträge keep_polls: Umfragen behalten keep_polls_hint: Löscht keine deiner Umfragen keep_self_bookmark: Als Lesezeichen markierte Beiträge behalten keep_self_bookmark_hint: Löscht keinen deiner Beiträge, die du als Lesezeichen gesetzt hast - keep_self_fav: Behalte favorisierte Beiträge - keep_self_fav_hint: Löscht keinen deiner Beiträge, die du favorisiert hast + keep_self_fav: Favorisierte Beiträge behalten + keep_self_fav_hint: Löscht keinen deiner eigenen Beiträge, die du favorisiert hast min_age: '1209600': 2 Wochen '15778476': 6 Monate @@ -1574,15 +1720,13 @@ de: min_age_label: Altersgrenze min_favs: Behalte Beiträge, die häufiger favorisiert wurden als … min_favs_hint: Löscht keine Beiträge, die mindestens so oft favorisiert worden sind. Lass das Feld leer, um alle Beiträge – unabhängig der Anzahl an Favoriten – zu löschen - min_reblogs: Behalte Beiträge, die öfter geteilt wurden als + min_reblogs: Behalte Beiträge, die häufiger geteilt wurden als … min_reblogs_hint: Löscht keine Beiträge, die mindestens so oft geteilt worden sind. Lass das Feld leer, um alle Beiträge – unabhängig der Anzahl an geteilten Beiträgen – zu löschen stream_entries: - pinned: Angehefteter Beitrag - reblogged: teilte sensitive_content: Inhaltswarnung strikes: errors: - too_late: Es ist zu spät, um gegen diesen Verstoß Einspruch zu erheben + too_late: Es ist zu spät, um gegen diese Maßnahme Einspruch zu erheben tags: does_not_match_previous_name: entspricht nicht dem vorherigen Namen themes: @@ -1591,9 +1735,14 @@ de: mastodon-light: Mastodon (Hell) time: formats: - default: "%d.%m.%Y %H:%M" + default: "%d. %b %Y, %H:%M Uhr" month: "%b %Y" - time: "%H:%M" + time: "%H:%M Uhr" + with_time_zone: "%d. %b %Y, %H:%M Uhr %Z" + translation: + errors: + quota_exceeded: Das Kontingent, das dem Server zur Verfügung steht, wurde für den Übersetzungsdienst überschritten. + too_many_requests: Der Übersetzungsdienst hat kürzlich zu viele Anfragen erhalten. two_factor_authentication: add: Hinzufügen disable: Zwei-Faktor-Authentisierung (2FA) deaktivieren @@ -1602,16 +1751,16 @@ de: enabled: Zwei-Faktor-Authentisierung (2FA) ist aktiviert enabled_success: Zwei-Faktor-Authentisierung (2FA) erfolgreich aktiviert generate_recovery_codes: Wiederherstellungscodes erstellen - lost_recovery_codes: Wiederherstellungscodes erlauben es dir, wieder Zugang zu deinem Konto zu erlangen, falls du keinen Zugriff mehr auf die Zwei-Faktor-Authentisierung (2FA) oder den Sicherheitsschlüssel hast. Solltest Du diese Wiederherstellungscodes verloren haben, kannst du sie hier neu generieren. Deine alten, bereits erstellten Wiederherstellungscodes werden dadurch ungültig. + lost_recovery_codes: Wiederherstellungscodes ermöglichen es dir, wieder Zugang zu deinem Konto zu erlangen, falls du keinen Zugriff mehr auf die Zwei-Faktor-Authentisierung (2FA) oder den Sicherheitsschlüssel hast. Solltest du diese Wiederherstellungscodes verloren haben, kannst du sie hier neu generieren. Deine alten, bereits erstellten Wiederherstellungscodes werden dadurch ungültig. methods: Methoden der Zwei-Faktor-Authentisierung (2FA) - otp: Authentifizierungs-App + otp: Authentisierungs-App recovery_codes: Wiederherstellungscodes sichern recovery_codes_regenerated: Wiederherstellungscodes erfolgreich neu erstellt - recovery_instructions_html: Wenn du den Zugang zu deinem Telefon verlieren solltest, kannst du einen untenstehenden Wiederherstellungscode benutzen, um wieder auf dein Konto zugreifen zu können. Bewahre die Wiederherstellungscodes gut auf. Du könntest sie beispielsweise ausdrucken und bei deinen restlichen wichtigen Dokumenten aufbewahren. + recovery_instructions_html: Falls du jemals den Zugang zu deinem Smartphone verlierst, kannst du einen der unten aufgeführten Wiederherstellungscodes verwenden, um wieder Zugang zu deinem Konto zu erhalten. Bewahre die Wiederherstellungscodes sicher auf. Du kannst sie zum Beispiel ausdrucken und zusammen mit anderen wichtigen Dokumenten aufbewahren. webauthn: Sicherheitsschlüssel user_mailer: appeal_approved: - action: Gehe zu deinem Konto + action: Dein Konto aufrufen explanation: Der Einspruch gegen deinen Verstoß vom %{strike_date}, den du am %{appeal_date} eingereicht hast, wurde genehmigt. Dein Konto ist wieder in gutem Zustand. subject: Dein Einspruch vom %{date} wurde angenommen title: Einspruch angenommen @@ -1622,31 +1771,31 @@ de: backup_ready: explanation: Du hast eine vollständige Sicherung deines Mastodon-Kontos angefordert. Das Backup kann jetzt heruntergeladen werden! subject: Dein persönliches Archiv kann heruntergeladen werden - title: Archivmitnahme + title: Archiv-Download suspicious_sign_in: - change_password: dein Passwort zu ändern - details: 'Hier sind die Details des Versuchs:' + change_password: dein Passwort ändern + details: 'Hier sind die Details zu den Anmeldeversuchen:' explanation: Wir haben eine Anmeldung zu deinem Konto von einer neuen IP-Adresse festgestellt. further_actions_html: Wenn du das nicht warst, empfehlen wir dir schnellstmöglich, %{action} und die Zwei-Faktor-Authentisierung (2FA) für dein Konto zu aktivieren, um es abzusichern. subject: Es wurde auf dein Konto von einer neuen IP-Adresse zugegriffen title: Eine neue Anmeldung warning: - appeal: Einspruch einsenden + appeal: Einspruch erheben appeal_description: Wenn du glaubst, dass es sich um einen Fehler handelt, kannst du einen Einspruch an die Administration von %{instance} senden. categories: spam: Spam - violation: Inhalt verstößt gegen die folgenden Gemeinschaftsrichtlinien + violation: Inhalt verstößt gegen die folgenden Serverregeln explanation: - delete_statuses: Einige deiner Beiträge wurden als Verstoß gegen eine oder mehrere Gemeinschaftsrichtlinien erkannt und von den Moderator*innen von %{instance} entfernt. - disable: Du kannst dein Konto nicht mehr verwenden, aber dein Profil und andere Daten bleiben unversehrt. Du kannst eine Sicherung deiner Daten anfordern, die Kontoeinstellungen ändern oder dein Konto löschen. - mark_statuses_as_sensitive: Ein oder mehrere deiner Beiträge wurden von den Moderator*innen von %{instance} mit einer Inhaltswarnung versehen. Das bedeutet, dass Besucher*innen diese Medien in den Beiträgen zunächst antippen müssen, um die Vorschau anzuzeigen. Beim Verfassen der nächsten Beiträge kannst du auch selbst eine Inhaltswarnung für hochgeladene Medien festlegen. + delete_statuses: Einige deiner Beiträge haben gegen eine oder mehrere Serverregeln verstoßen und wurden daher von den Moderator*innen von %{instance} entfernt. + disable: Du kannst dein Konto nicht mehr verwenden, aber dein Profil und deine anderen Daten bleiben erhalten. Du kannst eine Sicherung deiner Daten anfordern, die Kontoeinstellungen ändern oder dein Konto löschen. + mark_statuses_as_sensitive: Ein oder mehrere deiner Beiträge wurden von den Moderator*innen von %{instance} mit einer Inhaltswarnung versehen. Das bedeutet, dass die Medien in den Beiträgen erst angeklickt werden müssen, bevor sie angezeigt werden. Beim Verfassen der nächsten Beiträge kannst du auch selbst eine Inhaltswarnung für hochgeladene Medien festlegen. sensitive: Von nun an werden alle deine hochgeladenen Mediendateien mit einer Inhaltswarnung versehen und hinter einer Warnung versteckt. - silence: Solange dein Konto limitiert ist, können nur die Leute, die dir bereits folgen, deine Beiträge auf dem Server sehen, und es könnte sein, dass du von verschiedenen öffentlichen Listungen ausgeschlossen wirst. Andererseits können andere dir manuell folgen. + silence: Du kannst dein Konto weiterhin verwenden, aber nur Personen, die dir bereits folgen, sehen deine Beiträge auf diesem Server. Ebenso kannst du aus verschiedenen Suchfunktionen ausgeschlossen werden. Andere können dir jedoch weiterhin manuell folgen. suspend: Du kannst dein Konto nicht mehr verwenden und dein Profil und andere Daten sind nicht mehr verfügbar. Du kannst dich immer noch anmelden, um eine Sicherung deiner Daten anzufordern, bis die Daten innerhalb von 30 Tagen vollständig gelöscht wurden. Allerdings werden wir einige Daten speichern, um zu verhindern, dass du die Sperrung umgehst. - reason: 'Grund:' - statuses: 'Zitierte Beiträge:' + reason: 'Begründung:' + statuses: 'Betroffene Beiträge:' subject: - delete_statuses: Deine Beiträge auf %{acct} wurden entfernt + delete_statuses: Deine Beiträge von %{acct} sind entfernt worden disable: Dein Konto %{acct} wurde eingefroren mark_statuses_as_sensitive: Deine Beiträge von %{acct} wurden mit einer Inhaltswarnung versehen none: Warnung für %{acct} @@ -1665,32 +1814,37 @@ de: edit_profile_action: Profil einrichten edit_profile_step: Du kannst dein Profil anpassen, indem du ein Profilbild hochlädst, deinen Anzeigenamen änderst und vieles mehr. Du kannst dich dafür entscheiden, neue Follower zu überprüfen, bevor sie dir folgen dürfen. explanation: Hier sind ein paar Tipps, um loszulegen - final_action: Fang an zu posten + final_action: Mit erstem Beitrag starten final_step: 'Fang jetzt an zu posten! Selbst ohne Follower werden deine öffentlichen Beiträge von anderen gesehen, zum Beispiel in der lokalen Timeline oder über die Hashtags. Möglicherweise möchtest du dich allen mit dem Hashtag #neuhier vorstellen.' full_handle: Dein vollständiger Profilname - full_handle_hint: Dies ist, was du deinen Freunden sagen kannst, damit sie dich anschreiben oder dir von einem anderen Server folgen können. - subject: Willkommen bei Mastodon + full_handle_hint: Deinen vollständigen Profilnamen kannst du deinen Freund*innen mitteilen, damit sie dich anschreiben oder dir von einem anderen Server folgen können. + subject: Willkommen bei Mastodon! title: Willkommen an Bord, %{name}! users: - follow_limit_reached: Du kannst nicht mehr als %{limit} Leuten folgen + follow_limit_reached: Du kannst nicht mehr als %{limit} Profilen folgen + go_to_sso_account_settings: Kontoeinstellungen des Identitätsanbieters aufrufen invalid_otp_token: Ungültiger Code der Zwei-Faktor-Authentisierung (2FA) otp_lost_help_html: Wenn du beides nicht mehr weißt, melde dich bitte bei uns unter der E-Mail-Adresse %{email} seamless_external_login: Du bist über einen externen Dienst angemeldet, daher sind Passwort- und E-Mail-Einstellungen nicht verfügbar. signed_in_as: 'Angemeldet als:' verification: - explanation_html: 'Du kannst bestätigen, dass die Links in deinen Profil-Metadaten dir gehören. Dafür muss die verlinkte Website einen Link zurück auf dein Mastodon-Profil enthalten. Dieser Link muss ein rel="me"-Attribut enthalten. Der Linktext ist dabei egal. Hier ist ein Beispiel:' + extra_instructions_html: Hinweis: Der Link auf deiner Website kann unsichtbar sein. Der wichtige Teil ist rel="me", wodurch das Nachahmen von Personen auf Websites mit nutzergenerierten Inhalten verhindert wird. Du kannst auch ein link-Tag statt a im Header auf der Seite verwenden, jedoch muss der HTML-Code ohne das Ausführen von JavaScript zugänglich sein. + here_is_how: So funktioniert’s + hint_html: "Alle können ihre Identität auf Mastodon verifizieren. Basierend auf offenen Standards – jetzt und für immer kostenlos. Alles, was du brauchst, ist eine eigene Website. Wenn du von deinem Profil auf diese Website verlinkst, überprüfen wir, ob die Website zu deinem Profil zurückverlinkt, und zeigen einen visuellen Hinweis an." + instructions_html: Kopiere den unten stehenden Code und füge ihn in das HTML deiner Website ein. Trage anschließend die Adresse deiner Website in ein Zusatzfeld auf deinem Profil ein und speichere die Änderungen. Die Zusatzfelder befinden sich im Reiter „Profil bearbeiten“. verification: Verifizierung + verified_links: Deine verifizierten Links webauthn_credentials: add: Sicherheitsschlüssel hinzufügen create: error: Beim Hinzufügen des Sicherheitsschlüssels ist ein Fehler aufgetreten. Bitte versuche es erneut. success: Dein Sicherheitsschlüssel wurde erfolgreich hinzugefügt. - delete: Löschen - delete_confirmation: Bist du sicher, dass du diesen Sicherheitsschlüssel löschen möchtest? - description_html: Wenn du die Authentifizierung mit Sicherheitsschlüssel aktivierst, musst du einen deiner Sicherheitsschlüssel verwenden, um dich anmelden zu können. + delete: Entfernen + delete_confirmation: Möchtest du diesen Sicherheitsschlüssel wirklich entfernen? + description_html: Wenn du die Authentisierung mit Sicherheitsschlüssel aktivierst, musst du dich mit einem deiner Sicherheitsschlüssel anmelden. destroy: - error: Es gab ein Problem beim Löschen deines Sicherheitsschlüssels. Bitte versuche es erneut. - success: Dein Sicherheitsschlüssel wurde erfolgreich gelöscht. + error: Beim Entfernen des Sicherheitsschlüssels ist ein Fehler aufgetreten. Bitte versuche es erneut. + success: Dein Sicherheitsschlüssel wurde erfolgreich entfernt. invalid_credential: Ungültiger Sicherheitsschlüssel nickname_hint: Gib den Spitznamen deines neuen Sicherheitsschlüssels ein not_enabled: Du hast WebAuthn noch nicht aktiviert diff --git a/config/locales/devise.ar.yml b/config/locales/devise.ar.yml index 7b88207713..97d1710edf 100644 --- a/config/locales/devise.ar.yml +++ b/config/locales/devise.ar.yml @@ -2,7 +2,7 @@ ar: devise: confirmations: - confirmed: تم تأكيد عنوان بريدك الإلكتروني. + confirmed: تم تأكيد عنوان بريدك الإلكتروني بنجاح. send_instructions: سوف تتلقى بعد بضع دقائق رسالةً إلكترونيةً تضم تعليمات التأكيد. إن لم تتلق الرسالة، الرجاء التحقق من إنها ليست ضمن ملف الرسائل غير المرغوب فيها. send_paranoid_instructions: إن كان عنوان بريدك الإلكتروني موجودا في قاعدة بياناتنا سوف تتلقّى الإرشادات اللازمة لتأكيده خلال بضع دقائق. يُرجى الإطلاع على الرسائل المتلقاة في البريد غير المرغوب فيه أيضا للتحقق من تلقي الرسالة. failure: @@ -13,7 +13,7 @@ ar: locked: إن حسابك مقفل. not_found_in_database: "%{authentication_keys} أو كلمة سر خاطئة." pending: إنّ حسابك في انتظار مراجعة. - timeout: لقد انتهت مدة صلاحية جلستك. قم بتسجيل الدخول من جديد للمواصلة. + timeout: لقد انتهت مدة صَلاحِيَة جلستك. قم بتسجيل الدخول من جديد للمواصلة. unauthenticated: يجب عليك تسجيل الدخول أو إنشاء حساب قبل المواصلة. unconfirmed: يجب عليك تأكيد عنوان بريدك الإلكتروني قبل المواصلة. mailer: @@ -37,8 +37,8 @@ ar: title: تم تغيير كلمة السر reconfirmation_instructions: explanation: ندعوك لتأكيد العنوان الجديد قصد تعديله في بريدك. - extra: إن لم تكن صاحب هذا الطلب ، يُرجى عدم إعارة الاهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله. - subject: 'ماستدون: تأكيد كلمة السر الخاصة بـ %{instance}' + extra: إن لم تكن صاحب هذا الطلب، يُرجى عدم إعارة الاهتمام لهذه الرسالة. فعنوان البريد الإلكتروني المتعلق بحساب ماستدون سوف يبقى هو مِن غير أي تعديل إلّا و فقط إن قمت بالنقر على الرابط أعلاه قصد تعديله. + subject: 'ماستدون: تأكيد عنوان البريد الإلكتروني الخاص بـ %{instance}' title: التحقق من عنوان البريد الإلكتروني reset_password_instructions: action: تغيير كلمة السر @@ -100,7 +100,7 @@ ar: signed_in: تم تسجيل دخولك بنجاح. signed_out: تم تسجيل خروجك بنجاح. unlocks: - send_instructions: سوف تتلقى خلال بضع دقائق رسالة إلكترونية تحتوي على التعليمات اللازمة لفك القفل عن حسابك. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج. + send_instructions: سوف تتلقى خلال بضع دقائق رسالة إلكترونية تحتوي على التعليمات اللازمة لفك القُفْل عن حسابك. إن لم تتلق تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج. send_paranoid_instructions: إن كان حسابك موجود فعليًا فسوف تتلقى في غضون دقائق رسالة إلكترونية تحتوي على تعليمات تدُلُّك على كيفية فك القفل عن حسابك. إن لم تتلقى تلك الرسالة ، ندعوك إلى تفقُّد مجلد البريد المزعج. unlocked: لقد تمت عملية إلغاء تجميد حسابك بنجاح. للمواصلة ، يُرجى تسجيل الدخول. errors: @@ -108,8 +108,8 @@ ar: already_confirmed: قمت بتأكيده من قبل ، يرجى إعادة محاولة تسجيل الدخول confirmation_period_expired: يجب التأكد منه قبل انقضاء مدة %{period}، يرجى إعادة طلب جديد expired: انتهت مدة صلاحيته، الرجاء طلب واحد جديد - not_found: لا يوجد - not_locked: ليس مقفلاً + not_found: تَعَذَّرَ العُثُورُ عليه + not_locked: لم يكن مقفَلاً not_saved: few: "%{count} أخطاء منعت هذا %{resource} من الحفظ:" many: "%{count} أخطاء منعت هذا %{resource} من الحفظ:" diff --git a/config/locales/devise.ast.yml b/config/locales/devise.ast.yml index f48c70e2d4..a4378dee92 100644 --- a/config/locales/devise.ast.yml +++ b/config/locales/devise.ast.yml @@ -10,15 +10,17 @@ ast: last_attempt: Quédate un intentu más enantes de bloquiar la cuenta. locked: La cuenta ta bloquiada. pending: La cuenta sigue en revisión. - timeout: La sesión caducó. Volvi aniciala pa siguir. + timeout: La sesión caduco. Volvi aniciar la sesión pa siguir. unauthenticated: Tienes d'aniciar la sesión o rexistrate enantes de siguir. unconfirmed: Tienes de confirmar la direición de corréu electrónicu enantes de siguir. mailer: confirmation_instructions: + action: Verificar la direición de corréu electrónicu explanation: Creesti una cuenta en %{host} con esta direición de corréu electrónicu ya tas a un calcu d'activala. Si nun fixesti esta aición, inora esti mensaxe. explanation_when_pending: Solicitesti una invitación a %{host} con esta direición de corréu electrónicu. Namás que confirmes la direición de corréu electrónicu, vamos revisar la solicitú. Entrín ya non, pues aniciar la sesión pa camudar los detalles o desaniciar la cuenta, mas nun pues acceder a la mayoría de funciones hasta que la cuenta nun tea aprobada. Si se refuga la solicitú, nun ye necesario que faigas nada más o si, per otra parte, tu nun fixesti esta aición, inora esti mensaxe. - extra_html: Revisa tamién les regles del sirvidor ya los nuesos términos del serviciu. + extra_html: Revisa tamién les normes del sirvidor ya los nuesos términos del serviciu. subject: 'Mastodon: instrucciones de confirmación de «%{instance}»' + title: Verificación de la direición de corréu electrónicu email_changed: explanation: 'La direición de corréu electrónicu de la cuenta camudó a:' extra: Si nun camudesti la direición de corréu electrónicu, ye probable que daquién accediere a la cuenta. Camuda la contraseña agora mesmo o ponte en contautu cola alministración del sirvidor si nun yes a acceder a la cuenta. diff --git a/config/locales/devise.bg.yml b/config/locales/devise.bg.yml index 5ce0157045..5046771340 100644 --- a/config/locales/devise.bg.yml +++ b/config/locales/devise.bg.yml @@ -15,7 +15,7 @@ bg: pending: Вашият акаунт все още е в процес на проверка. timeout: Заседанието ви изтече. Влезте пак, за да продължите. unauthenticated: Преди да продължите, трябва да влезете или да се регистрирате. - unconfirmed: Преди да продължите, трябва да потвърдите имейл адреса си. + unconfirmed: Преди да продължите, трябва да потвърдите адреса на имейла си. mailer: confirmation_instructions: action: Потвърдете адреса на имейла @@ -37,11 +37,11 @@ bg: title: Паролата е променена reconfirmation_instructions: explanation: Потвърдете новия адрес, за да промените имейла си. - extra: Ако тази промяна не е инициирана от вас, то игнорирайте този имейл. Адресът на имейл за акаунта в Mastodon няма да се промени, докато не влезете в горната връзка. + extra: Ако тази промяна не е започната от вас, то пренебрегнете този имейл. Адресът на имейла за акаунта в Mastodon няма да се промени, докато не влезете в горната връзка. subject: 'Mastodon: Потвърдете имейла за %{instance}' title: Потвърдете своя имейл адрес reset_password_instructions: - action: Промяна на парола + action: Промяна на паролата explanation: Поискахте нова парола за акаунта си. extra: Ако не сте заявили това, то игнорирайте това е-писмо. Паролата ви няма да се променя, докато не влезете от връзката по-горе и не създадете нова. subject: 'Mastodon: Указания за задаване на нова парола' @@ -76,7 +76,7 @@ bg: webauthn_enabled: explanation: Удостоверяването с ключ за сигурност е активирано за вашия акаунт. Вашият ключ за сигурност вече може да се използва за вход. subject: 'Mastodon: Включено удостоверяване с ключ за сигурност' - title: Ключовете за сигурност са активирани + title: Включени ключове за сигурност omniauth_callbacks: failure: Не успяхме да ви упълномощим от %{kind}, защото "%{reason}". success: Успешно упълномощаване от акаунт на %{kind}. @@ -93,10 +93,10 @@ bg: signed_up_but_locked: Регистрирахте се успешно. Въпреки това, не можете да влезете, тъй като акаунтът ви е заключен. signed_up_but_pending: Изпратено е съобщение до адреса на имейла ви с връзка за потвърждение. След като щракнете върху линка, ние ще прегледаме заявлението ви. Ще бъдете уведомени при одобрение. signed_up_but_unconfirmed: Е-писмо с връзка за потвърждение е изпратено до имейла ви. Последвайте връзката, за да задействате акаунта си. Проверете папката си за спам, ако не сте получили това е-писмо. - update_needs_confirmation: Успешно обновихте акаунта си, но трябва да потвърдим вашия нов имейл адрес. Проверете електронната си поща и отворете отворете линка за потвърждение на новия си имейл адрес. Проверете спам папката си, ако не сте получили имейл за потвърждение. + update_needs_confirmation: Успешно осъвременихте акаунта си, но трябва да потвърдим новия ви адрес на имейл. Проверете имейла си и отворете връзката за потвърждаване на новия имейл адрес. Проверете папката си за спам, ако не сте получили това е-писмо. updated: Акаунтът ви е успешно осъвременен. sessions: - already_signed_out: Успешно излизане от профила. + already_signed_out: Успешно излизане. signed_in: Успешно влизане. signed_out: Успешно излизане. unlocks: diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml index b19a046197..6ebdafb9ec 100644 --- a/config/locales/devise.ca.yml +++ b/config/locales/devise.ca.yml @@ -8,15 +8,15 @@ ca: Si l'adreça de correu-e ja existeix a la nostra base de dades rebràs un correu amb instruccions sobre com confirmar-la. Si us plau, verifica la carpeta de la brossa si no l'has rebut. failure: - already_authenticated: Ja estàs registrat. + already_authenticated: Ja t'has registrat. 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. locked: El teu compte s'ha blocat. not_found_in_database: "%{authentication_keys} o contrasenya no són vàlids." pending: El teu compte encara està en revisió. - timeout: La sessió ha expirat. Torna a iniciar-la per a continuar. - unauthenticated: Cal iniciar sessió o registrar-se abans de continuar. + timeout: La teva sessió ha expirat. Torna a iniciar-la per a continuar. + unauthenticated: Necessites iniciar sessió o registrar-te abans de continuar. unconfirmed: Has de confirmar l'adreça-e abans de continuar. mailer: confirmation_instructions: @@ -24,7 +24,7 @@ ca: action_with_app: Confirma i torna a %{app} explanation: Has creat un compte a %{host} amb aquesta adreça de correu electrònic. Estàs a un sol clic d'activar-lo. Si no ho has fet tu, ignora aquest correu electrònic. explanation_when_pending: Has sol·licitat una invitació a %{host} amb aquesta adreça-e. Revisarem la sol·licitud quan la confirmis. Pots iniciar la sessió per canviar els detalls o eliminar el compte, però no pots accedir a la majoria de les funcions fins que s'hagi aprovat. Si es rebutja la sol·licitud, les teves dades s’eliminaran, de manera que no se t’exigirà cap acció més. Si tu no has fet aquesta sol·licitud, ignora aquest correu-e. - extra_html: Si us plau, consulta també a les regles del servidor i a les nostres condicions de servei. + extra_html: Consulteu també a les regles del servidor i a les nostres condicions de servei. subject: 'Mastodon: Instruccions de confirmació de %{instance}' title: Verifica l'adreça-e email_changed: @@ -86,15 +86,15 @@ ca: no_token: Només pots accedir a aquesta pàgina a través de l'enllaç de restabliment de la contrasenya. Si vens d'un correu electrònic com aquest, assegura't que has introduït l'adreça completa proporcionada. send_instructions: Si el teu correu electrònic existeix en la nostra base de dades, rebràs en pocs minuts un enllaç de restabliment de contrasenya en l'adreça de correu. Si us plau verifica la teva carpeta de correu brossa si no has rebut aquest correu. send_paranoid_instructions: Si el teu correu electrònic existeix en la nostra base de dades, rebràs un enllaç de restabliment de contrasenya en l'adreça de correu en pocs minuts. Si us plau verifica la carpeta de correu brossa si no reps aquest correu. - updated: La contrasenya s'ha canviat correctament. Ara ja estàs registrat. + updated: La contrasenya s'ha pogut canviar. Ara ja has iniciat la sessió. updated_not_active: La contrasenya s'ha canviat correctament. registrations: destroyed: Adéu! el compte s'ha cancel·lat amb èxit. Desitgem veure't de nou ben aviat. - signed_up: Benvingut! T'has registrat amb èxit. - signed_up_but_inactive: T´has registrat amb èxit. No obstant, no podem iniciar la teva sessió perquè el teu compte encara no s'ha activat. - signed_up_but_locked: T'has registrat amb èxit. Això no obstant, no podem iniciar la sessió perquè el teu compte està blocat. + signed_up: Benvingut! T'has registrat. + signed_up_but_inactive: T'has registrat. Tanmateix, no podem iniciar la teva sessió perquè el compte encara no s'ha activat. + signed_up_but_locked: T'has registrat. Tanmateix, no podem iniciar la sessió perquè el compte està blocat. signed_up_but_pending: S'ha enviat un missatge amb un enllaç de confirmació a la teva adreça de correu electrònic. Després que hagis fet clic a l'enllaç, revisarem la sol·licitud. Se't notificarà si s'aprova. - signed_up_but_unconfirmed: S'ha enviat per correu electrònic un missatge amb un enllaç de confirmació. Fes clic a l'enllaç per a activar el compte. Si us plau verifica la teva carpeta de correu brossa si no reps aquest correu. + signed_up_but_unconfirmed: S'ha enviat per correu electrònic un missatge amb un enllaç de confirmació. Fes clic a l'enllaç per a activar el compte. Si us plau, verifica la teva carpeta de correu brossa si no el reps. update_needs_confirmation: Has actualitzat el teu compte amb èxit, però necessitem verificar la teva nova adreça de correu. Si us plau comprova el correu i segueixi l'enllaç per confirmar la nova adreça de correu. Si us plau verifica la teva carpeta de correu brossa si no reps aquest correu. updated: El teu compte ha estat actualitzat amb èxit. sessions: @@ -104,10 +104,10 @@ ca: unlocks: send_instructions: En pocs minuts rebràs un correu electrònic amb instruccions sobre com desbloquejar el teu compte. Si us plau verifica la teva carpeta de correu brossa si no has rebut aquest correu. send_paranoid_instructions: Si el teu compte existeix, rebràs en pocs minuts un correu electrònic amb instruccions sobre com desbloquejar-lo. Verifica la carpeta de correu brossa si no has rebut aquest correu. - unlocked: El compte s'ha desbloquejat correctament. Inicia sessió per a continuar. + unlocked: El teu compte s'ha desbloquejat correctament. Inicia la sessió per a continuar. errors: messages: - already_confirmed: ja està confirmat. Intenta iniciar sessió + already_confirmed: ja està confirmat, intenta iniciar sessió confirmation_period_expired: cal fer la confirmació dins de %{period}, si us plau sol·licita-ho de nou expired: ha expirat, si us plau demana'n una altra not_found: no s'ha trobat diff --git a/config/locales/devise.csb.yml b/config/locales/devise.csb.yml deleted file mode 100644 index 0de706e41f..0000000000 --- a/config/locales/devise.csb.yml +++ /dev/null @@ -1 +0,0 @@ -csb: diff --git a/config/locales/devise.da.yml b/config/locales/devise.da.yml index 18aa431622..17593be3fd 100644 --- a/config/locales/devise.da.yml +++ b/config/locales/devise.da.yml @@ -14,7 +14,7 @@ da: not_found_in_database: Ugyldig %{authentication_keys} eller adgangskode. pending: Din konto er stadig under revision. timeout: Session udløbet. Log ind igen for at fortsætte. - unauthenticated: Log ind eller tilmelde dig for at fortsætte. + unauthenticated: Log ind eller tilmeld dig for at fortsætte. unconfirmed: Bekræft din e-mailadresse for at fortsætte. mailer: confirmation_instructions: @@ -22,7 +22,7 @@ da: action_with_app: Bekræft og returnér til %{app} explanation: Du har oprettet en konto på %{host} med denne e-mailadresse og er nu ét klik fra at aktivere den. Har du ikke oprettet dig, så ignorér blot denne e-mail. explanation_when_pending: Du har ansøgt om en invitation til %{host} med denne e-mailadresse. Når du har bekræftet adressen, gennemgås din ansøgning. Du kan logge ind for at ændre oplysninger eller slette kontoen, men hovedparten af funktionerne kan ikke tilgås, før kontoen er godkendt. Afvises ansøgningen, fjernes dine data, så ingen yderligere handling fra dig er nødvendig. Har du ikke ansøgt, så ignorér blot denne e-mail. - extra_html: Tjek også reglerne for serveren samt gældende Tjenestevilkår. + extra_html: Tjek også reglerne for serveren samt vores tjenestevilkår. subject: 'Mastodon: Bekræftelsesinstrukser for %{instance}' title: Bekræft e-mailadresse email_changed: @@ -31,7 +31,7 @@ da: subject: 'Mastodon: E-mail skiftet' title: Ny e-mailadresse password_change: - explanation: Din kontoadgangskode er skiftet. + explanation: Din adgangskode er skiftet. extra: Har du ikke selv skiftet din adgangskode, har nogen sandsynligvis opnået adgang til din konto. Skift derfor straks din adgangskode eller kontakt serveradministratoren, hvis du er låst ude af kontoen. subject: 'Mastodon: Adgangskode skiftet' title: Adgangskode skiftet @@ -42,7 +42,7 @@ da: title: Bekræft e-mailadresse reset_password_instructions: action: Skift adgangskode - explanation: Du har anmodet om en ny kontoadgangskode. + explanation: Du har anmodet om en ny adgangskode. extra: Har du ikke anmodet om dette, så ignorér denne e-mail. Din adgangskode skiftes først, når en ny er oprettet vha. linket ovenfor. subject: 'Mastodon: Instruktioner til adgangskodenulstilling' title: Adgangskodenulstilling diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml index e5ce87ebec..a77240dabe 100644 --- a/config/locales/devise.de.yml +++ b/config/locales/devise.de.yml @@ -2,107 +2,107 @@ de: devise: confirmations: - confirmed: Deine E-Mail-Adresse wurde bestätigt. + confirmed: Deine E-Mail-Adresse wurde erfolgreich bestätigt. send_instructions: Du wirst in wenigen Minuten eine E-Mail erhalten. Darin wird erklärt, wie du deine E-Mail-Adresse bestätigen kannst. Schau bitte auch in deinem Spam-Ordner nach, wenn du diese E-Mail nicht erhalten hast. send_paranoid_instructions: Falls deine E-Mail-Adresse in unserer Datenbank hinterlegt ist, wirst du in wenigen Minuten eine E-Mail erhalten. Darin wird erklärt, wie du deine E-Mail-Adresse bestätigen kannst. Schau bitte auch in deinem Spam-Ordner nach, wenn du diese E-Mail nicht erhalten hast. failure: already_authenticated: Du bist bereits angemeldet. inactive: Dein Konto wurde noch nicht aktiviert. invalid: "%{authentication_keys} oder Passwort ungültig." - last_attempt: Du hast noch einen Versuch, bevor dein Konto gesperrt wird. + last_attempt: Du hast nur noch einen Versuch, bevor dein Zugang gesperrt wird. locked: Dein Konto ist gesperrt. not_found_in_database: "%{authentication_keys} oder Passwort ungültig." - pending: Dein Konto wird immer noch überprüft. + pending: Dein Konto wird weiterhin überprüft. timeout: Deine Sitzung ist abgelaufen. Bitte melde dich erneut an, um fortzufahren. unauthenticated: Du musst dich anmelden oder registrieren, bevor du fortfahren kannst. unconfirmed: Du musst deine E-Mail-Adresse bestätigen, bevor du fortfahren kannst. mailer: confirmation_instructions: action: E-Mail-Adresse verifizieren - action_with_app: Bestätigen und zu %{app} zurückkehren - explanation: Du hast auf %{host} mit dieser E-Mail-Adresse ein Konto erstellt. Du bist nur noch einen Klick von der Aktivierung entfernt. Wenn du das nicht warst, kannst du diese E-Mail ignorieren. - explanation_when_pending: Du hast dich für eine Einladung bei %{host} mit dieser E-Mailadresse beworben. Sobald du deine E-Mailadresse bestätigst hast, werden wir deine Anfrage überprüfen. Du kannst dich in dieser Zeit nicht anmelden. Wenn deine Anfrage abgelehnt wird, werden deine Daten entfernt, also wird keine weitere Handlung benötigt. Wenn du das nicht warst, kannst du diese E-Mail ignorieren. - extra_html: Bitte lies auch die Regeln des Servers und unsere Nutzungsbedingungen. - subject: 'Mastodon: Bestätigung deines Kontos bei %{instance}' - title: E-Mail-Adresse verifizieren + action_with_app: Bestätigen – und dann zur App %{app} zurückkehren + explanation: Du hast mit dieser E-Mail-Adresse ein Konto auf %{host} erstellt. Du bist nur noch einen Klick von der Aktivierung entfernt. Wenn du das nicht warst, dann kannst du diese E-Mail ignorieren. + explanation_when_pending: Du hast dich für eine Einladung bei %{host} mit dieser E-Mail-Adresse beworben. Sobald du deine E-Mail-Adresse bestätigt hast, werden wir deine Anfrage überprüfen. Du kannst dich in dieser Zeit nicht anmelden. Wenn deine Anfrage abgelehnt wird, werden deine Daten entfernt – von dir ist keine weitere Handlung notwendig. Wenn du das nicht warst, dann kannst du diese E-Mail ignorieren. + extra_html: Bitte beachte auch die Serverregeln und unsere Datenschutzerklärung. + subject: 'Mastodon: Anleitung zum Bestätigen deines Kontos auf %{instance}' + title: Verifiziere E-Mail-Adresse email_changed: - explanation: 'Die E-Mail-Adresse deines Accounts wird geändert zu:' - extra: Wenn du deine E-Mail-Adresse nicht geändert hast, dann wird es vermutlich so sein, dass jemand Zugriff zu deinem Account erhalten hat. Bitte ändere sofort dein Passwort oder kontaktiere den Administrator des Servers, wenn du dich ausgesperrt hast. + explanation: 'Die E-Mail-Adresse deines Kontos wird geändert zu:' + extra: Wenn du deine E-Mail-Adresse nicht geändert hast, ist es wahrscheinlich, dass sich jemand Zugang zu deinem Konto verschafft hat. Bitte ändere sofort dein Passwort oder kontaktiere die Serververwaltung, wenn du aus deinem Konto ausgesperrt bist. subject: 'Mastodon: E-Mail-Adresse geändert' title: Neue E-Mail-Adresse password_change: - explanation: Das Passwort für deinen Account wurde geändert. - extra: Wenn du dein Passwort nicht geändert hast, dann wird es vermutlich so sein, dass jemand Zugriff auf deinem Account erlangt hat. Bitte ändere sofort dein Passwort oder kontaktiere den Administrator des Servers, wenn du dich ausgesperrt hast. + explanation: Das Passwort für dein Konto wurde geändert. + extra: Wenn du dein Passwort nicht geändert hast, ist es wahrscheinlich, dass sich jemand Zugang zu deinem Konto verschafft hat. Bitte ändere sofort dein Passwort oder kontaktiere die Serververwaltung, wenn du aus deinem Konto ausgesperrt bist. subject: 'Mastodon: Passwort geändert' title: Passwort geändert reconfirmation_instructions: explanation: Bestätige deine neue E-Mail-Adresse, um sie zu ändern. - extra: Wenn diese Änderung nicht von dir ausgeführt wurde, dann solltest du diese E-Mail ignorieren. Die E-Mail-Adresse für deinen Mastodon-Account wird sich nicht ändern, bis du den obigen Link anklickst. - subject: 'Mastodon: Bestätige E-Mail-Adresse für %{instance}' + extra: Wenn diese Änderung nicht von dir ausgeführt wurde, dann kannst du diese E-Mail ignorieren. Die E-Mail-Adresse für dein Mastodon-Konto wird sich erst ändern, wenn du den obigen Link anklickst. + subject: 'Mastodon: E-Mail-Adresse für %{instance} bestätigen' title: E-Mail-Adresse verifizieren reset_password_instructions: - action: Ändere Passwort - explanation: Du hast ein neues Passwort für deinen Account angefragt. - extra: Wenn du diese Anfrage nicht gestellt hast, solltest du diese E-Mail ignorieren. Dein Passwort wird sich nicht ändern, solange du den obigen Link anklickst und ein neues erstellst. - subject: 'Mastodon: Passwort zurücksetzen' + action: Passwort ändern + explanation: Du hast ein neues Passwort für dein Konto angefordert. + extra: Wenn du diese Anfrage nicht gestellt hast, dann kannst du diese E-Mail ignorieren. Dein Passwort wird sich erst ändern, wenn du den obigen Link anklickst und ein neues Passwort erstellst. + subject: 'Mastodon: Anleitung zum Zurücksetzen deines Passworts' title: Passwort zurücksetzen two_factor_disabled: - explanation: Zwei-Faktor-Authentifizierung für dein Konto wurde deaktiviert. Login ist jetzt nur mit E-Mail-Adresse und Passwort möglich. - subject: 'Mastodon: Zwei‐Faktor‐Authentifizierung deaktiviert' + explanation: Zwei-Faktor-Authentisierung (2FA) für dein Konto wurde deaktiviert. Eine Anmeldung ist jetzt nur noch mit E-Mail-Adresse und Passwort möglich. + subject: 'Mastodon: Zwei‐Faktor‐Authentisierung (2FA) deaktiviert' title: 2FA deaktiviert two_factor_enabled: - explanation: Zwei-Faktor-Authentifizierung wurde für dein Konto aktiviert. Ein Token, das von der verbundenen TOTP-App generiert wird, wird für den Login benötigt. - subject: 'Mastodon: Zwei‐Faktor‐Authentifizierung aktiviert' + explanation: Die Zwei-Faktor-Authentisierung (2FA) wurde für dein Konto aktiviert. Das zeitbasierte Einmalpasswort, das von deiner TOTP-App generiert wird, muss bei jeder Anmeldung zusätzlich eingegeben werden. + subject: 'Mastodon: Zwei‐Faktor‐Authentisierung (2FA) aktiviert' title: 2FA aktiviert two_factor_recovery_codes_changed: explanation: Die vorherigen Wiederherstellungscodes wurden ungültig gemacht und es wurden neue erstellt. subject: 'Mastodon: Zwei-Faktor-Wiederherstellungscodes neu erstellt' title: 2FA-Wiederherstellungscodes geändert unlock_instructions: - subject: 'Mastodon: Konto entsperren' + subject: 'Mastodon: Anleitung zum Entsperren deines Kontos' webauthn_credential: added: explanation: Der folgende Sicherheitsschlüssel wurde zu deinem Konto hinzugefügt subject: 'Mastodon: Neuer Sicherheitsschlüssel' title: Ein neuer Sicherheitsschlüssel wurde hinzugefügt deleted: - explanation: Der folgende Sicherheitsschlüssel wurde aus deinem Konto gelöscht - subject: 'Mastodon: Sicherheitsschlüssel gelöscht' - title: Einer deiner Sicherheitsschlüssel wurde gelöscht + explanation: Der folgende Sicherheitsschlüssel wurde von deinem Konto entfernt + subject: 'Mastodon: Sicherheitsschlüssel entfernt' + title: Einer deiner Sicherheitsschlüssel wurde entfernt webauthn_disabled: - explanation: Die Authentifizierung mit Sicherheitsschlüssel wurde für dein Konto deaktiviert. Der Login ist nun nur mit dem Token möglich, der von der eingerichteten TOTP-App generiert wird. - subject: 'Mastodon: Authentifizierung mit Sicherheitsschlüssel deaktiviert' + explanation: Das Authentisieren mit Sicherheitsschlüsseln wurde für dein Konto deaktiviert. Die Anmeldung ist jetzt nur noch mit dem zeitbasierten Einmalpasswort möglich, das von deiner TOTP-App generiert wird. + subject: 'Mastodon: Authentisierung mit Sicherheitsschlüsseln deaktiviert' title: Sicherheitsschlüssel deaktiviert webauthn_enabled: - explanation: Die Authentifizierung mit einem Sicherheitsschlüssel wurde für dein Konto aktiviert. Dein Sicherheitsschlüssel kann nun für die Anmeldung verwendet werden. - subject: 'Mastodon: Authentifizierung mit Sicherheitsschlüssel aktiviert' + explanation: Die Authentisierung mit Sicherheitsschlüssel wurde für dein Konto aktiviert. Dein Sicherheitsschlüssel kann nun für die Anmeldung verwendet werden. + subject: 'Mastodon: Authentisierung mit Sicherheitsschlüssel aktiviert' title: Sicherheitsschlüssel aktiviert omniauth_callbacks: failure: Du konntest nicht mit deinem %{kind}-Konto angemeldet werden, weil „%{reason}“. - success: Du hast dich erfolgreich mit deinem %{kind}-Konto angemeldet. + success: Du hast dich erfolgreich mit deinem Konto %{kind} angemeldet. passwords: no_token: Du kannst diese Seite nur über den Link aus der E-Mail zum Zurücksetzen des Passworts aufrufen. Wenn du einen solchen Link aufgerufen hast, vergewissere dich bitte, dass du die vollständige Adresse aufrufst. - send_instructions: Du erhältst in wenigen Minuten eine E-Mail. Darin wird erklärt, wie du dein Passwort zurücksetzen kannst. - send_paranoid_instructions: Falls deine E-Mail-Adresse in unserer Datenbank hinterlegt ist, erhältst du in wenigen Minuten eine E-Mail. Darin wird erklärt, wie du dein Passwort zurücksetzen kannst. - updated: Ihr Passwort wurde erfolgreich geändert. Du bist jetzt angemeldet. + send_instructions: Du erhältst in wenigen Minuten eine E-Mail, sofern deine Adresse unserer Datenbank bekannt ist. In dieser Nachricht befindet sich ein Link. Wenn du diesen aufrufst, kannst du dein Passwort zurücksetzen. Sollte die E-Mail nicht im Posteingangsordner landen, überprüfe auch deinen Spam-/Junk-Ordner. + send_paranoid_instructions: Du erhältst in wenigen Minuten eine E-Mail, sofern deine Adresse unserer Datenbank bekannt ist. In dieser Nachricht befindet sich ein Link. Wenn du diesen aufrufst, kannst du dein Passwort zurücksetzen. Sollte die E-Mail nicht im Posteingangsordner landen, überprüfe auch deinen Spam-/Junk-Ordner. + updated: Dein Passwort wurde erfolgreich geändert. Du bist jetzt angemeldet. updated_not_active: Dein Passwort wurde erfolgreich geändert. registrations: - destroyed: Dein Konto wurde gelöscht. - signed_up: Willkommen! Du hast dich erfolgreich registriert. + destroyed: Tschüss! Dein Konto wurde erfolgreich gelöscht. Wir hoffen, dich bald wiederzusehen. + signed_up: Herzlich willkommen! Du hast dich erfolgreich registriert. signed_up_but_inactive: Du hast dich erfolgreich registriert. Allerdings ist dein Konto noch nicht aktiviert und du kannst dich daher noch nicht anmelden. signed_up_but_locked: Du hast dich erfolgreich registriert. Allerdings ist dein Konto gesperrt und du kannst dich daher nicht anmelden. - signed_up_but_pending: Eine Nachricht mit einem Bestätigungslink wurde an dich per E-Mail geschickt. Nachdem du diesen Link angeklickt hast, werden wir deine Anfrage überprüfen. Du wirst benachrichtigt werden, falls die Anfrage angenommen wurde. + signed_up_but_pending: Eine Nachricht mit einem Bestätigungslink wurde an deine E-Mail-Adresse gesendet. Nachdem du diesen Link angeklickt hast, werden wir deine Bewerbung überprüfen. Sobald sie genehmigt wurde, wirst du benachrichtigt. signed_up_but_unconfirmed: Du hast dich erfolgreich registriert. Wir konnten dich noch nicht anmelden, da dein Konto noch nicht bestätigt ist. Du erhältst in Kürze eine E-Mail. Darin wird erklärt, wie du dein Konto freischalten kannst. update_needs_confirmation: Deine Daten wurden aktualisiert, aber du musst deine neue E-Mail-Adresse bestätigen. Du erhältst in wenigen Minuten eine E-Mail. Darin ist erklärt, wie du die Änderung deiner E-Mail-Adresse abschließen kannst. - updated: Ihr Konto wurde erfolgreich aktualisiert. + updated: Dein Konto wurde erfolgreich aktualisiert. sessions: already_signed_out: Erfolgreich abgemeldet. signed_in: Erfolgreich angemeldet. signed_out: Erfolgreich abgemeldet. unlocks: - send_instructions: Du erhältst in wenigen Minuten eine E-Mail. Darin wird erklärt, wie du dein Konto entsperren kannst. - send_paranoid_instructions: Falls deine E-Mail-Adresse in unserer Datenbank hinterlegt ist, erhältst du in wenigen Minuten eine E-Mail. Darin wird erklärt, wie du dein Konto entsperren kannst. - unlocked: Dein Konto wurde entsperrt. Du bist jetzt angemeldet. + send_instructions: Du erhältst in wenigen Minuten eine E-Mail. Darin wird erklärt, wie du dein Konto entsperren kannst. Sollte die E-Mail nicht im Posteingangsordner landen, überprüfe auch deinen Spam-/Junk-Ordner. + send_paranoid_instructions: Falls deine E-Mail-Adresse in unserer Datenbank hinterlegt ist, erhältst du in wenigen Minuten eine E-Mail. Darin wird erklärt, wie du dein Konto entsperren kannst. Sollte die E-Mail nicht im Posteingangsordner landen, überprüfe auch deinen Spam-/Junk-Ordner. + unlocked: Dein Konto wurde erfolgreich entsperrt. Bitte melde dich an, um fortzufahren. errors: messages: already_confirmed: wurde bereits bestätigt, bitte versuche dich anzumelden @@ -111,5 +111,5 @@ de: not_found: nicht gefunden not_locked: ist nicht gesperrt not_saved: - one: '1 Fehler hat verhindert, dass %{resource} gespeichert wurde:' - other: "%{count} Fehler haben verhindert, dass %{resource} gespeichert wurde:" + one: '1 Fehler verhinderte, dass %{resource} gespeichert wurde:' + other: "%{count} Fehler verhinderten, dass %{resource} gespeichert wurde:" diff --git a/config/locales/devise.en-GB.yml b/config/locales/devise.en-GB.yml index 9a51d07576..e7ab9462dc 100644 --- a/config/locales/devise.en-GB.yml +++ b/config/locales/devise.en-GB.yml @@ -6,22 +6,22 @@ en-GB: send_instructions: You will receive an email with instructions for how to confirm your email address in a few minutes. Please check your spam folder if you didn't receive this email. send_paranoid_instructions: If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes. Please check your spam folder if you didn't receive this email. failure: - already_authenticated: You are already signed in. + already_authenticated: You are already logged in. inactive: Your account is not activated yet. invalid: Invalid %{authentication_keys} or password. last_attempt: You have one more attempt before your account is locked. locked: Your account is locked. not_found_in_database: Invalid %{authentication_keys} or password. pending: Your account is still under review. - timeout: Your session expired. Please sign in again to continue. - unauthenticated: You need to sign in or sign up before continuing. + timeout: Your session expired. Please log in again to continue. + unauthenticated: You need to log in or sign up before continuing. unconfirmed: You have to confirm your email address before continuing. mailer: confirmation_instructions: action: Verify email address action_with_app: Confirm and return to %{app} explanation: You have created an account on %{host} with this email address. You are one click away from activating it. If this wasn't you, please ignore this email. - explanation_when_pending: You applied for an invite to %{host} with this email address. Once you confirm your e-mail address, we will review your application. You can login to change your details or delete your account, but you cannot access most of the functions until your account is approved. If your application is rejected, your data will be removed, so no further action will be required from you. If this wasn't you, please ignore this email. + explanation_when_pending: You applied for an invite to %{host} with this email address. Once you confirm your e-mail address, we will review your application. You can log in to change your details or delete your account, but you cannot access most of the functions until your account is approved. If your application is rejected, your data will be removed, so no further action will be required from you. If this wasn't you, please ignore this email. extra_html: Please also check out the rules of the server and our terms of service. subject: 'Mastodon: Confirmation instructions for %{instance}' title: Verify email address @@ -84,28 +84,28 @@ en-GB: no_token: You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided. send_instructions: If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. Please check your spam folder if you didn't receive this email. send_paranoid_instructions: If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. Please check your spam folder if you didn't receive this email. - updated: Your password has been changed successfully. You are now signed in. + updated: Your password has been changed successfully. You are now logged in. updated_not_active: Your password has been changed successfully. registrations: destroyed: Bye! Your account has been successfully cancelled. We hope to see you again soon. signed_up: Welcome! You have signed up successfully. - signed_up_but_inactive: You have signed up successfully. However, we could not sign you in because your account is not yet activated. - signed_up_but_locked: You have signed up successfully. However, we could not sign you in because your account is locked. + signed_up_but_inactive: You have signed up successfully. However, we could not log you in because your account is not yet activated. + signed_up_but_locked: You have signed up successfully. However, we could not log you in because your account is locked. signed_up_but_pending: A message with a confirmation link has been sent to your email address. After you click the link, we will review your application. You will be notified if it is approved. signed_up_but_unconfirmed: A message with a confirmation link has been sent to your email address. Please follow the link to activate your account. Please check your spam folder if you didn't receive this email. update_needs_confirmation: You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address. Please check your spam folder if you didn't receive this email. updated: Your account has been updated successfully. sessions: - already_signed_out: Signed out successfully. - signed_in: Signed in successfully. - signed_out: Signed out successfully. + already_signed_out: Logged out successfully. + signed_in: Logged in successfully. + signed_out: Logged out successfully. unlocks: send_instructions: You will receive an email with instructions for how to unlock your account in a few minutes. Please check your spam folder if you didn't receive this email. send_paranoid_instructions: If your account exists, you will receive an email with instructions for how to unlock it in a few minutes. Please check your spam folder if you didn't receive this email. - unlocked: Your account has been unlocked successfully. Please sign in to continue. + unlocked: Your account has been unlocked successfully. Please log in to continue. errors: messages: - already_confirmed: was already confirmed, please try signing in + already_confirmed: was already confirmed, please try logging in confirmation_period_expired: needs to be confirmed within %{period}, please request a new one expired: has expired, please request a new one not_found: not found diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 458fa6d759..eef8214817 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -13,8 +13,8 @@ en: locked: Your account is locked. not_found_in_database: Invalid %{authentication_keys} or password. pending: Your account is still under review. - timeout: Your session expired. Please sign in again to continue. - unauthenticated: You need to sign in or sign up before continuing. + timeout: Your session expired. Please login again to continue. + unauthenticated: You need to login or sign up before continuing. unconfirmed: You have to confirm your email address before continuing. mailer: confirmation_instructions: @@ -102,7 +102,7 @@ en: unlocks: send_instructions: You will receive an email with instructions for how to unlock your account in a few minutes. Please check your spam folder if you didn't receive this email. send_paranoid_instructions: If your account exists, you will receive an email with instructions for how to unlock it in a few minutes. Please check your spam folder if you didn't receive this email. - unlocked: Your account has been unlocked successfully. Please sign in to continue. + unlocked: Your account has been unlocked successfully. Please login to continue. errors: messages: already_confirmed: was already confirmed, please try signing in diff --git a/config/locales/devise.es-AR.yml b/config/locales/devise.es-AR.yml index d4dc4b7a74..d9c922ed86 100644 --- a/config/locales/devise.es-AR.yml +++ b/config/locales/devise.es-AR.yml @@ -102,7 +102,7 @@ es-AR: unlocks: send_instructions: En unos minutos, vas a recibir un correo electrónico con instrucciones sobre cómo desbloquear tu cuenta. Si pasa el tiempo y no recibiste ningún mensaje, por favor, revisá tu carpeta de correo basura / no deseado / spam. send_paranoid_instructions: Si tu cuenta existe en nuestra base de datos, en unos minutos vas a recibir un correo electrónico con instrucciones sobre cómo desbloquear tu cuenta. Si pasa el tiempo y no recibiste ningún mensaje, por favor, revisá tu carpeta de correo basura / no deseado / spam. - unlocked: Se desbloqueó tu cuenta exitosamente. Por favor, iniciá sesión para continuar. + unlocked: Tu cuenta fue desbloqueada exitosamente. Por favor, iniciá sesión para continuar. errors: messages: already_confirmed: ya se confirmó; por favor, intentá iniciar sesión diff --git a/config/locales/devise.es.yml b/config/locales/devise.es.yml index 7cfae2da6b..ef6a70ee4f 100644 --- a/config/locales/devise.es.yml +++ b/config/locales/devise.es.yml @@ -13,8 +13,8 @@ es: locked: Tu cuenta está bloqueada. not_found_in_database: Incorrecto %{authentication_keys} o contraseña. pending: Su cuenta aun se encuentra bajo revisión. - timeout: Su sesión ha expirado. Por favor inicie sesión de nuevo para continuar. - unauthenticated: Necesita iniciar sesión o registrarse antes de continuar. + timeout: Tu sesión expiró. Por favor, inicia sesión nuevamente para continuar. + unauthenticated: Necesitas iniciar sesión o registrarte antes de continuar. unconfirmed: Tiene que confirmar su dirección de correo electrónico antes de continuar. mailer: confirmation_instructions: diff --git a/config/locales/devise.et.yml b/config/locales/devise.et.yml index 9fd54d1422..da1cc989d2 100644 --- a/config/locales/devise.et.yml +++ b/config/locales/devise.et.yml @@ -48,15 +48,15 @@ et: title: Salasõna lähtestamine two_factor_disabled: explanation: Kontol on kaheastmeline autentimine välja lülitatud. Sisenemine on võimalik ainult kasutades e-postiaadressi ja salasõna. - subject: 'Mastodon: Kahe-etapine autentimine välja lülitatud' + subject: 'Mastodon: Kaheastmeline autentimine välja lülitatud' title: 2FA keelatud two_factor_enabled: explanation: Kontol on sisse lülitatud kaheastmeline autentimine. Sisenemiseks on vajalik ühekordne aeguv võti TOTP-rakenduse poolt. - subject: 'Mastodon: Kahe-etapine autentimine sisse lülitatud' + subject: 'Mastodon: kaheastmeline autentimine sisse lülitatud' title: 2FA lubatud two_factor_recovery_codes_changed: explanation: Eelmised taastekoodid on nüüd kehtetud ning loodud uued. - subject: 'Mastodon: Kahe-etapise autentimise taastuskoodid taasloodud' + subject: 'Mastodon: Kaheastmelise autentimise taastuskoodid taasloodud' title: 2FA taastekoodid muudetud unlock_instructions: subject: 'Mastodon: Lahti lukustamis juhendid' @@ -78,7 +78,7 @@ et: subject: 'Mastodon: turvavõtme autentimine sisse lülitatud' title: Turvavõtmed on sisse lülitatud omniauth_callbacks: - failure: Ei saanud teid tuvastada %{kind} kaudu, kuna "%{reason}". + failure: Ei saanud sind tuvastada %{kind} kaudu, kuna "%{reason}". success: Tuvastamine %{kind} konto järgi õnnestus. passwords: no_token: Sellele leheküljele ei pääse tulemata salasõna lähtestamise e-kirjast. Kui tuled salasõna lähtestamise e-kirjast, palun veendu, et kasutasid tervet saadetud URLi. @@ -87,7 +87,7 @@ et: updated: Salasõna muutmine õnnestus. Oled nüüd sisse logitud. updated_not_active: Sinu salasõna muutmine õnnestus. registrations: - destroyed: Nägemist! sinu konto sulgemine õnnestus. Me loodame sind varsti taas näha. + destroyed: Nägemist! Sinu konto sulgemine õnnestus. Me loodame sind varsti taas näha. signed_up: Tere tulemast! Sinu konto loomine õnnestus. signed_up_but_inactive: Sinu konto loodi edukalt, kuid me ei saanud sind sisse logida, kuna konto pole veel aktiveeritud. signed_up_but_locked: Sinu konto loodi edukalt, kuid me ei saanud sind sisse logida, kuna konto on lukustatud. diff --git a/config/locales/devise.eu.yml b/config/locales/devise.eu.yml index 1e71181d1e..eb23e06d4a 100644 --- a/config/locales/devise.eu.yml +++ b/config/locales/devise.eu.yml @@ -2,9 +2,9 @@ eu: devise: confirmations: - confirmed: Zure e-mail helbidea ongi baieztatu da. - send_instructions: E-mail mezu bat jasoko duzu minutu batzuk barru zure e-mail helbidea baieztatzeko argibideekin. Egiaztatu zure spam karpeta ez baduzu e-mail hau jasotzen. - send_paranoid_instructions: Zure e-mail helbidea aurretik gure datu-basean bazegoen, e-mail mezu bat jasoko duzu minutu batzuk barru zure e-mail helbidea baieztatzeko argibideekin. Egiaztatu zure spam karpeta ez baduzu e-mail hau jasotzen. + confirmed: Zure eposta helbidea ongi baieztatu da. + send_instructions: Eposta mezu bat jasoko duzu minutu gutxi barru zure eposta helbidea berresteko argibideekin. Begiratu zure spam karpetan ez baduzu mezua jaso. + 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. inactive: Zure kontua ez dago oraindik aktibo. @@ -15,35 +15,35 @@ eu: pending: Zure kontua oraindik berrikusteke dago. timeout: Zure saioa iraungitu da. Hasi saioa berriro jarraitzeko. unauthenticated: Saioa hasi edo izena eman behar duzu jarraitu aurretik. - unconfirmed: Zure e-mail helbidea baieztatu behar duzu jarraitu aurretik. + unconfirmed: Zure eposta helbidea berretsi behar duzu jarraitu aurretik. mailer: confirmation_instructions: - action: Baieztatu e-mail helbidea + action: Egiaztatu eposta helbidea action_with_app: Berretsi eta itzuli %{app} aplikaziora - explanation: Kontu bat sortu duzu %{host} ostalarian e-mail helbide honekin. Aktibatzeko klik bat falta zaizu. Ez baduzu zuk sortu, ez egin ezer e-mail honekin. - explanation_when_pending: "%{host} instantziara gonbidatua izatea eskatu duzu e-mail helbide honekin. Behin zure e-mail helbidea berresten duzula, zure eskaera berrikusiko da. Ezin duzu aurretik saioa hasi. Zure eskaera ukatuko balitz, zure datuak ezabatuko lirateke, eta ez zenuke beste ezer egiteko beharrik. Hau ez bazara zu izan, ezikusi e-mail hau." + explanation: Kontu bat sortu duzu %{host} ostalarian eposta helbide honekin. Klik bat baino ez zaizu falta kontua aktibatzeko. Ez baduzu zuk sortu, ez egin ezer mezu honekin. + explanation_when_pending: "%{host} instantziara gonbidatzeko eskatu duzu eposta helbide honekin. Behin zure eposta helbidea berresten duzula, zure eskaera berrikusiko da. Ezin duzu aurretik saioa hasi. Zure eskaera ukatuko balitz, zure datuak ezabatuko lirateke, eta ez zenuke beste ezer egiteko beharrik. Ez baduzu zuk eskatu gonbidapena, ez egin ezer mezu honekin." extra_html: Egiaztatu zerbitzariaren arauak eta zerbitzuaren erabilera baldintzak. subject: 'Mastodon: %{instance} instantziaren argibideak baieztapenerako' - title: Baieztatu e-mail helbidea + title: Egiaztatu eposta helbidea email_changed: - explanation: 'Zure kontuaren e-mail helbidea honetara aldatuko da:' - extra: Ez baduzu e-mail helbidea aldatu, agian baten bat zure kontura sartzea lortu du. Aldatu zure pasahitza berehala edo jarri zerbitzariko administratzailearekin kontaktuan zure kontura sartzerik ez baduzu. - subject: 'Mastodon: E-mail helbidea aldatuta' - title: E-mail helbide berria + explanation: 'Zure kontuaren eposta helbidea hau izango da aurrerantzean:' + extra: Ez baduzu eposta helbidea aldatu, agian baten bat zure kontuan sartu da. Aldatu zure pasahitza berehala edo jarri zerbitzariko administratzailearekin harremanetan zure kontura sartzerik ez baduzu. + subject: 'Mastodon: Aldatu da eposta helbidea' + title: Eposta helbide berria password_change: explanation: Zure kontuaren pasahitza aldatu da. extra: Ez baduzu pasahitza aldatu, agian baten bat zure kontura sartzea lortu du. Aldatu zure pasahitza berehala edo jarri zerbitzariko administratzailearekin kontaktuan zure kontura sartzerik ez baduzu. subject: 'Mastodon: Pasahitza aldatuta' title: Pasahitza aldatuta reconfirmation_instructions: - explanation: Baieztatu helbide berria zure e-maila aldatzeko. - extra: Aldaketa hau ez baduzu zuk eskatu, ezikusi e-mail hau. Mastodon kontuaren e-mail helbidea ez da aldatuko goiko estekan sartzen ez bazara. - subject: 'Mastodon: Baieztatu %{instance} instantziarako e-mail helbidea' - title: Baieztatu e-mail helbidea + explanation: Berretsi helbide berria zure eposta aldatzeko. + extra: Aldaketa hau ez baduzu zuk eskatu, ez egin ezer mezu honekin. Mastodon kontuaren eposta helbidea ez da aldatuko goiko estekan sartzen ez bazara. + subject: 'Mastodon: Berretsi %{instance} instantziarako eposta helbidea' + title: Egiaztatu eposta helbidea reset_password_instructions: action: Aldatu pasahitza explanation: Pasahitza berria eskatu duzu zure konturako. - extra: Ez baduzu hau eskatu, mesedez ezikusi e-mail hau. Zure pasahitza ez da aldatuko goiko estekara sartu eta berri bat sortzen ez baduzu. + extra: Hori ez baduzu zuk eskatu, ez egin ezer mezu honekin. Zure pasahitza ez da aldatuko goiko estekara sartu eta berri bat sortzen ez baduzu. subject: 'Mastodon: Pasahitza berrezartzeko argibideak' title: Pasahitza berrezartzea two_factor_disabled: @@ -81,9 +81,9 @@ eu: failure: Ezin izan zaizu %{kind} motatik autentifikatu arrazoia "%{reason}" dela. success: Ongi egin da autentifikazioa %{kind} kontuarekin. passwords: - no_token: Ezin zara orri honetara sartu ez bazatoz pasahitza aldatzeko e-mail batetik. Pasahitza aldatzeko e-mail batetik bazatoz egiaztatu emandako URL osoa erabiltzen duzula mesedez. - send_instructions: Zure e-mail helbidea gure datu-basean badago, pasahitza berreskuratzeko esteka bat duen e-mail bat jasoko duzu minutu gutxi barru. Egiaztatu spam karpeta e-mail hau jasotzen ez baduzu. - send_paranoid_instructions: Zure e-mail helbidea gure datu-basean badago, pasahitza berreskuratzeko esteka bat duen e-mail bat jasoko duzu minutu gutxi barru. Egiaztatu spam karpeta e-mail hau jasotzen ez baduzu. + no_token: Ezin zara orri honetara sartu ez bazatoz pasahitza aldatzeko eposta mezu batetik. Pasahitza aldatzeko mezu batetik bazatoz, egiaztatu emandako URL osoa erabiltzen duzula. + send_instructions: Zure eposta helbidea gure datu-basean badago, pasahitza berreskuratzeko esteka bat duen eposta bat jasoko duzu minutu gutxi barru. Begiratu zure spam karpetan ez baduzu mezua jaso. + send_paranoid_instructions: Zure eposta helbidea gure datu-basean badago, pasahitza berreskuratzeko esteka bat duen mezu bat jasoko duzu minutu gutxi barru. Begiratu zure spam karpetan ez baduzu mezua jaso. updated: Zure pasahitza ongi aldatu da. Saioa hasi duzu. updated_not_active: Zure pasahitza ongi aldatu da. registrations: @@ -91,17 +91,17 @@ eu: signed_up: Ongi etorri! Ongi hasi duzu saioa. signed_up_but_inactive: Ongi eman duzu izena. Hala ere, ezin duzu saioa hasi zure kontua oraindik ez dagoelako aktibatuta. signed_up_but_locked: Ongi eman duzu izena. Hala ere, ezin duzu saioa hasi zure kontua giltzapetuta dagoelako. - signed_up_but_pending: Berrespen esteka bat duen mezu bat bidali da zure e-mail helbidera. Behin esteka sakatzen duzula, zure eskaera berrikusiko da. Onartzen bada jakinaraziko zaizu. - signed_up_but_unconfirmed: Baieztapen esteka bat duen e-mail bidali zaizu. Jarraitu esteka zure kontua aktibatzeko. Egiaztatu spam karpeta ez baduzu e-mail hau jaso. - update_needs_confirmation: Zure kontua ongi eguneratu duzu, baina zure email helbide berria egiaztatu behar dugu. Baieztapen esteka bat duen e-mail bidali zaizu, jarraitu esteka zure e-mal helbide berria baieztatzeko. Egiaztatu spam karpeta ez baduzu e-mail hau jaso. + signed_up_but_pending: Berrespen esteka bat duen mezu bat bidali dizugu zure eposta helbidera. Behin esteka sakatzen duzula, zure eskaera berrikusiko da. Onartzen bada, jakinarazpena jasoko duzu. + signed_up_but_unconfirmed: Baieztapen esteka bat duen eposta bat bidali dizugu. Jarraitu esteka zure kontua aktibatzeko. Begiratu zure spam karpetan ez baduzu mezua jaso. + update_needs_confirmation: Zure kontua ongi eguneratu duzu, baina zure eposta helbide berria egiaztatu behar dugu. Berrespen esteka bat duen mezua bidali dizugu, sartu estekan zure eposta helbide berria berresteko. Begiratu zure spam karpetan ez baduzu mezua jaso. updated: Zure kontua ongi eguneratu da. sessions: already_signed_out: Ongi amaitu duzu saioa. signed_in: Ongi hasi duzu saioa. signed_out: Ongi amaitu duzu saioa. unlocks: - send_instructions: Kontua desblokeatzeko argibideak dituen e-mail jasoko duzu minutu gutxi barru. Egiaztatu spam karpeta ez baduzu e-mail hau jaso. - send_paranoid_instructions: Zure kontua existitzen bada, hau desblokeatzeko argibideak dituen e-mail bat jasoko duzu minutu gutxi barru. Egiaztatu spam karpeta ez baduzu mezu hau jasotzen. + send_instructions: Kontua desblokeatzeko argibideak dituen eposta jasoko duzu minutu gutxi barru. Begiratu zure spam karpetan ez baduzu mezua jaso. + send_paranoid_instructions: Zure kontua existitzen bada, hau desblokeatzeko argibideak dituen eposta bat jasoko duzu minutu gutxi barru. Begiratu zure spam karpetan ez baduzu mezua jaso. unlocked: Zure kontua ongi desblokeatu da. Hasi saioa jarraitzeko. errors: messages: diff --git a/config/locales/devise.fa.yml b/config/locales/devise.fa.yml index bb71347315..07db5395da 100644 --- a/config/locales/devise.fa.yml +++ b/config/locales/devise.fa.yml @@ -8,10 +8,10 @@ fa: failure: already_authenticated: همین الآن هم وارد شده‌اید. inactive: حساب شما هنوز فعال نشده است. - invalid: "%{authentication_keys} یا رمز نامعتبر." + invalid: "%{authentication_keys} یا گذرواژه نامعتبر." last_attempt: پیش از آن که حساب شما قفل شود، یک فرصت دیگر دارید. locked: حساب شما قفل شده است. - not_found_in_database: "%{authentication_keys} یا رمز نامعتبر." + not_found_in_database: "%{authentication_keys} یا گذرواژه نامعتبر." pending: حساب شما همچنان در دست بررسی است. timeout: مهلت این ورود شما به سر رسید. برای ادامه، دوباره وارد شوید. unauthenticated: برای ادامه باید وارد شوید یا ثبت نام کنید. @@ -27,27 +27,27 @@ fa: title: تأیید نشانی ایمیل email_changed: explanation: 'نشانی ایمیل حساب شما تغییر می‌کند به:' - extra: اگر شما ایمیل خود را عوض نکردید، شاید کسی به حساب شما دسترسی پیدا کرده است. در این صورت لطفاً هر چه زودتر رمز حسابتان را عوض کنید. اگر رمزتان دیگر کار نمی‌کند، لطفاً با مدیر سرور تماس بگیرید. + extra: اگر شما ایمیل خود را عوض نکردید، شاید کسی به حساب شما دسترسی پیدا کرده است. در این صورت لطفاً هر چه زودتر گذرواژه حسابتان را عوض کنید. اگر گذرواژه‌تان دیگر کار نمی‌کند، لطفاً با مدیر سرور تماس بگیرید. subject: 'ماستودون: نشانی ایمیل عوض شد' title: نشانی ایمیل تازه password_change: - explanation: رمز حساب شما تغییر کرد. - extra: اگر شما رمز حسابتان را تغییر ندادید، شاید کسی به حساب شما دسترسی پیدا کرده است. در این صورت لطفاً هر چه زودتر رمز حسابتان را عوض کنید. اگر رمزتان دیگر کار نمی‌کند، لطفاً با مدیر سرور تماس بگیرید. - subject: 'ماستودون: رمزتان عوض شد' - title: رمزتان عوض شد + explanation: گذرواژه حساب شما تغییر کرد. + extra: اگر شما گذرواژه حسابتان را تغییر ندادید، شاید کسی به حساب شما دسترسی پیدا کرده است. در این صورت لطفاً هر چه زودتر گذرواژه حسابتان را عوض کنید. اگر گذرواژه‌تان دیگر کار نمی‌کند، لطفاً با مدیر سرور تماس بگیرید. + subject: 'ماستودون: گذرواژه‌تان عوض شد' + title: گذرواژه‌تان عوض شد reconfirmation_instructions: explanation: نشانی تازه را تأیید کنید تا ایمیل‌تان عوض شود. extra: اگر شما باعث این تغییر نبودید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید، نشانی ایمیل مربوط به حساب شما عوض نخواهد شد. subject: 'ماستودون: تأیید رایانامه برای %{instance}' title: تأیید نشانی ایمیل reset_password_instructions: - action: تغییر رمز - explanation: شما رمز تازه‌ای برای حسابتان درخواست کردید. - extra: اگر شما چنین درخواستی نکردید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید و رمز تازه‌ای نسازید، رمز شما عوض نخواهد شد. - subject: 'ماستودون: راهنمایی برای بازنشانی رمز' - title: بازنشانی رمز + action: تغییر گذرواژه + explanation: شما گذرواژه تازه‌ای برای حسابتان درخواست کردید. + extra: اگر شما چنین درخواستی نکردید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید و گذرواژه تازه‌ای نسازید، گذرواژه شما عوض نخواهد شد. + subject: 'ماستودون: راهنمایی برای بازنشانی گذرواژه' + title: بازنشانی گذرواژه two_factor_disabled: - explanation: ورود دومرحله‌ای برای حساب شما غیرفعال شده است. از الان می‌توانید تنها با نشانی ایمیل و رمز وارد حساب خود شوید. + explanation: ورود دومرحله‌ای برای حساب شما غیرفعال شده است. از الان می‌توانید تنها با نشانی ایمیل و گذرواژه وارد حساب خود شوید. subject: 'ماستودون: تأیید هویت دو مرحله‌ای از کار افتاد' title: ورود دومرحله‌ای غیرفعال two_factor_enabled: @@ -81,11 +81,11 @@ fa: failure: تآیید هویتتان از %{kind} نتوانست انجام شود چرا که «%{reason}». success: تأیید هویت از حساب %{kind} با موفقیت انجام شد. passwords: - no_token: این صفحه را تنها از راه یک ایمیل بازنشانی رمز می‌شود دید. اگر از چنین ایمیلی می‌آیید، لطفاً مطمئن شوید که نشانی موجود در ایمیل را کامل به کار برده‌اید. - send_instructions: اگر ایمیل شما در پایگاه دادهٔ ما موجود باشد، تا دقایقی دیگر یک ایمیل بازیابی رمز دریافت خواهید کرد. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. - send_paranoid_instructions: اگر ایمیل شما در پایگاه دادهٔ ما موجود باشد، تا دقایقی دیگر یک ایمیل بازیابی رمز دریافت خواهید کرد. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. - updated: رمز شما با موفقیت تغییر کرد. شما الان وارد سیستم هستید. - updated_not_active: رمز شما با موفقیت تغییر کرد. + no_token: این صفحه را تنها از راه یک ایمیل بازنشانی گذرواژه می‌شود دید. اگر از چنین ایمیلی می‌آیید، لطفاً مطمئن شوید که نشانی موجود در ایمیل را کامل به کار برده‌اید. + send_instructions: اگر ایمیل شما در پایگاه دادهٔ ما موجود باشد، تا دقایقی دیگر یک ایمیل بازیابی گذرواژه دریافت خواهید کرد. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. + send_paranoid_instructions: اگر ایمیل شما در پایگاه دادهٔ ما موجود باشد، تا دقایقی دیگر یک ایمیل بازیابی گذرواژه دریافت خواهید کرد. اگر این ایمیل نیامد، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. + updated: گذرواژه شما با موفقیت تغییر کرد. شما الان وارد سیستم هستید. + updated_not_active: گذرواژه شما با موفقیت تغییر کرد. registrations: destroyed: بدرود! حساب شما با موفقیت لغو شد. امیدواریم دوباره شما را ببینیم. signed_up: خوش آمدید! شما با موفقیت ثبت نام کردید. diff --git a/config/locales/devise.fi.yml b/config/locales/devise.fi.yml index ce5a35efde..8bbcb071e3 100644 --- a/config/locales/devise.fi.yml +++ b/config/locales/devise.fi.yml @@ -2,79 +2,79 @@ fi: devise: confirmations: - confirmed: Sähköpostiosoitteesi on vahvistettu onnistuneesti. + confirmed: Sähköpostiosoitteesi on vahvistettu. send_instructions: Saat pian sähköpostitse ohjeet sähköpostiosoitteesi vahvistamiseen. Jos et saanut viestiä, tarkista roskapostikansiosi. - send_paranoid_instructions: Jos sähköpostiosoitteesi on tietokannassamme, saat pian ohjeet osoitteesi vahvistamiseen. Jos et saanut viestiä, tarkista roskapostikansiosi. + send_paranoid_instructions: Jos sähköpostiosoitteesi on tiedossammme, saat pian sähköpostiisi ohjeet sen vahvistamiseen. Jos et saanut viestiä, tarkista roskapostikansiosi. failure: already_authenticated: Olet jo kirjautunut sisään. inactive: Tiliäsi ei ole vielä aktivoitu. invalid: Virheellinen %{authentication_keys} tai salasana. - last_attempt: Sinulla on vielä yksi yritys ennen kuin tunnuksesi lukitaan. + last_attempt: Sinulla on vielä yksi yritys ennen kuin tilisi lukitaan. locked: Tilisi on lukittu. not_found_in_database: Virheellinen %{authentication_keys} tai salasana. - pending: Tämä tili on vielä tarkistamatta. + pending: Tilisi on vielä tarkistamatta. timeout: Istuntosi on umpeutunut. Jatka kirjautumalla uudelleen sisään. - unauthenticated: Sinun pitää kirjautua sisään tai rekisteröityä ennen kuin voit jatkaa. + unauthenticated: Sinun on kirjauduttava tai rekisteröidyttävä ennen kuin voit jatkaa. unconfirmed: Vahvista sähköpostiosoitteesi, ennen kuin jatkat. mailer: confirmation_instructions: - action: Vahvista sähköpostiosoitteesi + action: Vahvista sähköpostiosoite action_with_app: Vahvista ja palaa %{app} - explanation: Olet luonut tilin palvelimelle %{host} käyttäen tätä sähköpostiosoitetta. Aktivoi tili yhdellä klikkauksella. Jos et luonut tiliä itse, voit jättää tämän viestin huomiotta. + explanation: Olet luonut tilin palvelimelle %{host} käyttäen tätä sähköpostiosoitetta. Olet painalluksen päässä tilin aktivoinnista. Jos et luonut tiliä itse, voit jättää tämän viestin huomiotta. explanation_when_pending: Teit hakemuksen kutsusta palvelimelle %{host} tällä sähköpostiosoitteella. Kun olet vahvistanut sähköpostiosoitteesi, tarkistamme hakemuksesi. Voit kirjautua sisään muuttaaksesi hakemuksen sisältöä tai poistaaksesi tilin, mutta et voi käyttää suurinta osaa toiminnallisuudesta ennen kuin hakemuksesi on hyväksytty. Jos hakemuksesi hylätään, tietosi poistetaan eikä sinulta tarvita enempää toimia. Jos sinä et tehnyt hakemusta, voit jättää tämän viestin huomiotta. - extra_html: Katso myös palvelimen säännöt ja käyttöehdot. + extra_html: Tutustu myös palvelimen sääntöihin ja palveluehtoihimme. subject: 'Mastodon: Vahvistusohjeet instanssille %{instance}' - title: Vahvista sähköpostiosoitteesi + title: Vahvista sähköpostiosoite email_changed: explanation: 'Tilin sähköpostiosoitteeksi vaihdetaan:' - extra: Jos et vaihtanut sähköpostiosoitettasi, joku muu on todennäköisesti päässyt käyttämään tiliäsi. Vaihda salasanasi viipymättä. Jos et pääse kirjautumaan tilillesi, ota yhteyttä instanssin ylläpitäjään. + extra: Jos et vaihtanut sähköpostiosoitettasi, joku muu on todennäköisesti päässyt käyttämään tiliäsi. Vaihda salasanasi viipymättä, tai ota yhteyttä palvelimen ylläpitäjään, jos et pääse kirjautumaan tilillesi. subject: 'Mastodon: Sähköpostiosoite vaihdettu' title: Uusi sähköpostiosoite password_change: explanation: Tilisi salasana on vaihdettu. - extra: Jos et vaihtanut salasanaasi, joku muu on todennäköisesti päässyt käyttämään tiliäsi. Vaihda salasanasi viipymättä. Jos et pääse kirjautumaan tilillesi, ota yhteyttä instanssin ylläpitäjään. - subject: 'Mastodon: Salasana vaihdettu' + extra: Jos et vaihtanut salasanaasi, joku muu on todennäköisesti päässyt käyttämään tiliäsi. Vaihda salasanasi viipymättä, tai ota yhteyttä palvelimen ylläpitäjään, jos et pääse kirjautumaan tilillesi. + subject: 'Mastodon: salasana vaihdettu' title: Salasana vaihdettu reconfirmation_instructions: explanation: Vahvista uusi sähköpostiosoite, niin muutos astuu voimaan. extra: Jos et tehnyt muutosta itse, voit jättää tämän viestin huomiotta. Mastodon-tilin sähköpostiosoitetta ei vaihdeta, ennen kuin klikkaat yllä olevaa linkkiä. - subject: 'Mastodon: Vahvista sähköpostiosoite instanssille %{instance}' + subject: 'Mastodon: vahvista sähköpostiosoite: %{instance}' title: Vahvista sähköpostiosoite reset_password_instructions: action: Vaihda salasana explanation: Pyysit tilillesi uuden salasanan. extra: Jos et tehnyt pyyntöä itse, voit jättää tämän viestin huomiotta. Salasanaasi ei vaihdeta, ennen kuin klikkaat yllä olevaa linkkiä ja luot uuden salasanan. - subject: 'Mastodon: Ohjeet salasanan vaihtoon' + subject: 'Mastodon: ohjeet salasanan vaihtoon' title: Salasanan vaihto two_factor_disabled: - explanation: Kaksivaiheinen tunnistus tilillesi on otettu pois käytöstä. Kirjautuminen onnistuu nyt pelkällä sähköpostiosoitteella ja salasanalla. - subject: 'Mastodon: Kaksivaiheinen tunnistut otettu pois käytöstä' - title: 2FA poistettu käytöstä + explanation: Tilisi kaksivaiheinen todennus poistettiin käytöstä. Kirjautuminen onnistuu nyt pelkällä sähköpostiosoitella ja salasanalla. + subject: 'Mastodon: kaksivaiheinen todennus poistettu käytöstä' + title: 2-vaiheinen todennus pois käytöstä two_factor_enabled: - explanation: Kaksivaiheinen tunnistus on otettu käyttöön tilillesi. Koodi kaksivaiheisen tunnistuksen sovelluksesta tarvitaan kirjautumiseen. - subject: 'Mastodon: Kaksivaiheinen tunnistus otettu käyttöön' - title: 2FA käytössä + explanation: Kaksivaiheinen todennus on otettu käyttöön tilillesi. Kirjautumiseen tarvitaan kaksivaiheisen todennuksen sovelluksesta saatu koodi. + subject: 'Mastodon: kaksivaiheinen todennus otettu käyttöön' + title: 2-vaiheinen todennus käytössä two_factor_recovery_codes_changed: - explanation: Aiemmat palautuskoodi on poistettu käytöstä ja uudet on luotu. - subject: 'Mastodon: Kaksivaiheisen tunnistuksen palautuskoodit uudelleenluotu' - title: 2FA palautuskoodit vaihdettu + explanation: Uudet palautuskoodit on nyt luotu ja vanhat on mitätöity. + subject: 'Mastodon: kaksivaiheisen todennuksen palautuskoodit luotiin uudelleen' + title: 2-vaiheisen todennuksen palautuskoodit vaihdettiin unlock_instructions: - subject: 'Mastodon: Ohjeet lukituksen poistoon' + subject: 'Mastodon: lukituksen poistamisen ohjeet' webauthn_credential: added: explanation: Seuraava suojausavain on lisätty tilillesi - subject: 'Mastodon: Uusi suojausavain' + subject: 'Mastodon: uusi suojausavain' title: Uusi suojausavain on lisätty deleted: explanation: Seuraava suojausavain on poistettu tililtäsi - subject: 'Mastodon: Suojausavain poistettu' + subject: 'Mastodon: suojausavain poistettu' title: Yksi suojausavaimistasi on poistettu webauthn_disabled: - explanation: Suojausavaimilla todennus on poistettu käytöstä tililtäsi. Kirjautuminen on nyt mahdollista käyttämällä vain paritetun TOTP-sovelluksen luomaa tokenia. - subject: 'Mastodon: Todennus suoja-avaimilla poistettu käytöstä' + explanation: Suojausavaimilla todennus on poistettu käytöstä tililtäsi. Kirjautuminen on nyt mahdollista vain paritetun TOTP-sovelluksen luomaa koodia käyttämällä. + subject: 'Mastodon: Todennus suojausavaimilla poistettu käytöstä' title: Suojausavaimet poistettu käytöstä webauthn_enabled: - explanation: Todennus suojausavaimella on otettu käyttöön tililläsi. Suojausavaintasi voidaan nyt käyttää kirjautumiseen. + explanation: Todennus suojausavaimella on otettu käyttöön tilillesi. Suojausavaintasi voidaan nyt käyttää kirjautumiseen. subject: 'Mastodon: Todennus suojausavaimella on otettu käyttöön' title: Suojausavaimet käytössä omniauth_callbacks: @@ -102,7 +102,7 @@ fi: unlocks: send_instructions: Saat pian sähköpostitse ohjeet tilin lukituksen poistoon. Jos et saanut viestiä, tarkista roskapostikansio. send_paranoid_instructions: Jos tili on olemassa, saat pian sähköpostitse ohjeet tilin lukituksen poistoon. Jos et saanut viestiä, tarkista roskapostikansio. - unlocked: Tilin lukituksen poisto onnistui. Jatka kirjautumalla sisään. + unlocked: Tilisi lukituksen poisto onnistui. Jatka kirjautumalla sisään. errors: messages: already_confirmed: on jo vahvistettu. Yritä kirjautua sisään @@ -111,5 +111,5 @@ fi: not_found: ei löydy not_locked: ei ollut lukittu not_saved: - one: '1 virhe esti kohteen %{resource} tallennuksen:' + one: 'Yksi virhe esti kohteen %{resource} tallennuksen:' other: "%{count} virhettä esti kohteen %{resource} tallennuksen:" diff --git a/config/locales/devise.fy.yml b/config/locales/devise.fy.yml index 3a7ead83e3..9e93d2c19f 100644 --- a/config/locales/devise.fy.yml +++ b/config/locales/devise.fy.yml @@ -2,26 +2,26 @@ fy: devise: confirmations: - confirmed: Dyn account is befêstige. - send_instructions: Do ûntfangst fia in e-mailberjocht ynstruksjes hoe’tsto dyn account befêstigje kinst. Sjoch yn de map net-winske wannear’t neat ûntfongen waard. - send_paranoid_instructions: As dyn e-mailadres yn de database stiet, ûntfangsto fia in e-mailberjocht ynstruksjes hoe’tsto dyn account befêstigje kinst. Sjoch yn de map net-winske wannear’t neat ûntfongen waard. + confirmed: Jo account is befêstige. + send_instructions: Jo ûntfange fia in e-mailberjocht ynstruksjes hoe’t jo jo account befêstigje kinne. Sjoch yn de map net-winske wannear’t neat ûntfongen waard. + send_paranoid_instructions: As jo e-mailadres yn de database stiet, ûntfange jo fia in e-mailberjocht ynstruksjes hoe’t jo jo account befêstigje kinne. Sjoch yn de map net-winske wannear’t neat ûntfongen waard. failure: - already_authenticated: Do bist al oanmeld. + already_authenticated: Jo binne al oanmeld. inactive: Jo account is noch net aktivearre. invalid: "%{authentication_keys} of wachtwurd ûnjildich." - last_attempt: Do hast noch ien besykjen oer eardat dyn account blokkearre wurdt. - locked: Dyn account is blokkearre. + last_attempt: Jo hawwe noch ien besykjen oer eardat jo account blokkearre wurdt. + locked: Jo account is blokkearre. not_found_in_database: "%{authentication_keys} of wachtwurd ûnjildich." - pending: Dyn account moat noch hieltyd beoardiele wurde. + pending: Jo account moat noch hieltyd beoardiele wurde. timeout: Dyn sesje is ferrûn, meld dy opnij oan. unauthenticated: Jo moatte oanmelde of registrearje. - unconfirmed: Do moatst earst dyn account befêstigje. + unconfirmed: Jo moatte earst jo account befêstigje. mailer: confirmation_instructions: action: E-mailadres ferifiearje action_with_app: Befêstigje en nei %{app} tebekgean - explanation: Do hast in account op %{host} oanmakke en mei ien klik kinsto dizze aktivearje. Wannear’tsto dit account net oanmakke hast, meisto dit e-mailberjocht negearje. - explanation_when_pending: Do fregest mei dit e-mailadres in útnûging oan foar %{host}. Neidatsto dyn e-mailadres befêstige hast, beoardielje wy dyn oanfraach. Do kinst oant dan noch net oanmelde. Wannear’t dyn oanfraach ôfwêzen wurdt, wurde dyn gegevens fuortsmiten en hoechsto dêrnei fierder neat mear te dwaan. Wannear’tsto dit net wiest, kinsto dit e-mailberjocht negearje. + explanation: Jo hawwe in account op %{host} oanmakke en mei ien klik kinne jo dizze aktivearje. Wannear’t jo dizze account net oanmakke hawwe, meie jo dit e-mailberjocht negearje. + explanation_when_pending: Jo freegje mei dit e-mailadres in útnûging oan foar %{host}. Neidat jo jo e-mailadres befêstige hawwe, beoardielje wy jo oanfraach. Jo kinne oant dan noch net oanmelde. Wannear’t jo oanfraach ôfwêzen wurdt, wurde jo gegevens fuortsmiten en hoege jo dêrnei fierder neat mear te dwaan. Wannear’t jo dit net wiene, kinne jo dit e-mailberjocht negearje. extra_html: |- 128 / 5.000 Kontrolearje ek de regels fan de server en ús tsjinstbetingsten. diff --git a/config/locales/devise.gl.yml b/config/locales/devise.gl.yml index 96ebb68c3c..b392f4642c 100644 --- a/config/locales/devise.gl.yml +++ b/config/locales/devise.gl.yml @@ -13,8 +13,8 @@ gl: locked: A túa conta está bloqueada. not_found_in_database: "%{authentication_keys} ou contrasinal non válidos." pending: A túa conta aínda está baixo revisión. - timeout: A túa sesión expirou. Por favor, entra de novo para continuares. - unauthenticated: Precisas de entrar na túa conta ou rexistrarte antes de continuar. + timeout: A túa sesión caducou. Accede outra vez para continuar. + unauthenticated: Precisas iniciar sesión ou rexistrarte antes de continuar. unconfirmed: Tes que confirmar o teu enderezo de email antes de continuar. mailer: confirmation_instructions: diff --git a/config/locales/devise.hi.yml b/config/locales/devise.hi.yml index 423d69fd03..c61f25027f 100644 --- a/config/locales/devise.hi.yml +++ b/config/locales/devise.hi.yml @@ -4,8 +4,20 @@ hi: confirmations: confirmed: आपका ईमेल पता का सफलतापूर्वक पुष्टि कर लिया गया था failure: + already_authenticated: आप पहले से ही प्रवेशित है| inactive: आपका खाता सक्रिय नहीं है! locked: आपके अकाउंट को ब्लॉक किया गया है। + pending: आपका खाता अभी भीं समीक्षा मे है। mailer: + confirmation_instructions: + action: ईमेल पता सत्यापित करें email_changed: title: नया ईमेल पता + two_factor_enabled: + title: 2FA सक्षम हुआ + webauthn_credential: + added: + title: एक नइ सुरक्षा कुंजी जोडी गई + deleted: + subject: 'मस्टाडोन: सुरक्षा कुंजी निकाली गई' + title: आपकी कोई एक सुरक्षा कुंजी निकाली गई diff --git a/config/locales/devise.hu.yml b/config/locales/devise.hu.yml index ddadd17894..bbf6a6399b 100644 --- a/config/locales/devise.hu.yml +++ b/config/locales/devise.hu.yml @@ -7,43 +7,43 @@ hu: send_paranoid_instructions: Ha az e-mail címed már szerepel az adatbázisunkban, néhány percen belül kapsz egy levelet az e-mail cím megerősítésére vonatkozó utasításokkal. Kérjük, ellenőrizd a spam mappád, ha nem látod az e-mailt. failure: already_authenticated: Már bejelentkeztél. - inactive: A fiókod még nincs aktiválva. + inactive: Fiókodat még nem aktiválták. invalid: Helytelen %{authentication_keys} vagy jelszó. last_attempt: Már csak egy próbálkozásod maradt, mielőtt a fiókodat zároljuk. locked: A fiókodat zároltuk. not_found_in_database: Helytelen %{authentication_keys} vagy jelszó. pending: A fiókod még engedélyezésre vár. - timeout: A munkameneted lejárt. Kérjük, a folytatáshoz jelentkezz be újra. + timeout: A munkameneted lejárt. A folytatáshoz jelentkezz be újra. unauthenticated: A folytatás előtt be kell jelentkezned vagy regisztrálnod kell. - unconfirmed: A folytatás előtt meg kell erősítened az e-mail címed. + unconfirmed: A folytatás előtt meg kell erősítened az emailcímedet. mailer: confirmation_instructions: - action: Erősítsd meg az e-mail címedet - action_with_app: Megerősítés majd vissza ide %{app} - explanation: Ezzel az e-mail címmel kezdeményeztek regisztrációt a(z) %{host} oldalon. Csak egy kattintás, és a felhasználói fiókodat aktiváljuk. Ha a regisztrációt nem te kezdeményezted, kérjük tekintsd ezt az e-mailt tárgytalannak. - explanation_when_pending: Ezzel az e-mail címmel meghívást kértél a(z) %{host} oldalon. Ahogy megerősíted az e-mail címed, átnézzük a jelentkezésedet. Ennek ideje alatt nem tudsz belépni. Ha a jelentkezésed elutasítjuk, az adataidat töröljük, más teendőd nincs. Ha a kérelmet nem te kezdeményezted, kérjük tekintsd ezt az e-mailt tárgytalannak. + action: Emailcím ellenőrzése + action_with_app: 'Megerősítés majd visszatérés: %{app}' + explanation: Ezzel az emailcímmel kezdeményeztél egy regisztrációt a %{host} kiszolgálón. Csak egy kattintásra vagy az aktiválástól. Ha a regisztrációt nem te indítottad, tekintsd ezt az emailt tárgytalannak. + explanation_when_pending: Ezzel az email címmel meghívást kértél a %{host} kiszolgálóra. Amint az emailcímedet megerősítetted, áttekintjük a jelentkezésedet. Ennek ideje alatt bejelentkezhetsz az adataid módosításához vagy a fiókod törléséhez, de a funkciók többségét nem használhatod a fiókod jóváhagyásáig. Ha a jelentkezésed elutasításra kerül, az adataid törlésre kerülnek, így nincs más teendőd. Ha nem te kezdeményezted ezt, tekintsd ezt az emailt tárgytalannak. extra_html: Tekintsd át a a kiszolgáló szabályait és a felhasználási feltételeket. - subject: 'Mastodon: Megerősítési lépések ehhez az instancehez: %{instance}' - title: E-mail cím megerősítése + subject: 'Mastodon: Megerősítési utasítások: %{instance}' + title: Emailcím megerősítése email_changed: explanation: 'A fiókodhoz tartozó e-mail cím a következőre változik:' extra: Ha nem változtattad meg az e-mail címed, akkor valószínű, hogy valaki hozzáférhetett a fiókodhoz. Kérjük, azonnal változtasd meg a jelszavadat, vagy lépj kapcsolatba a szerver adminisztrátorával, ha ki vagy zárva a fiókodból. - subject: 'Mastodon: a fiókodhoz tartozó e-mail címet megváltoztattuk' - title: Új e-mail cím + subject: 'Mastodon: Email megváltozott' + title: Új emailcím password_change: explanation: A fiókodhoz tartozó jelszót megváltoztattuk. extra: Ha nem te kérted a fiókod jelszavának módosítását, akkor valaki hozzáférhetett a fiókodhoz. Legjobb, ha azonnal megváltoztatod a jelszavadat; ha nem férsz hozzá a fiókodhoz, vedd fel a kapcsolatot a kiszolgálód adminisztrátorával. - subject: 'Mastodon: Jelszavad megváltoztattuk' - title: Sikeres jelszómódosítás + subject: 'Mastodon: A jelszó megváltoztatásra került' + title: A jelszó megváltoztatásra került reconfirmation_instructions: - explanation: Az e-mail cím megváltoztatásához meg kell erősítened az új címet. - extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az e-mailt tárgytalannak. A Mastodon fiókodhoz tartozó e-mail címed változatlan marad mindaddig, amíg rá nem kattintasz a fenti linkre. - subject: 'Mastodon: erősítsd meg a(z) %{instance} szerverhez tartozó e-mail címed' - title: E-mail cím megerősítése + explanation: Az emailcím megváltoztatásához meg kell erősítened az új címet. + extra: Amennyiben nem te kezdeményezted ezt a módosítást, kérjük tekintsd ezt az emailt tárgytalannak. A Mastodon fiókodhoz tartozó emailcímed változatlan marad mindaddig, amíg rá nem kattintasz a fenti linkre. + subject: 'Mastodon: Email cím megerősítése: %{instance}' + title: Emailcím megerősítése reset_password_instructions: action: Jelszó módosítása explanation: A fiókodhoz tartozó jelszó módosítását kezdeményezted. - extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az e-mailt tárgytalannak. A Mastodon fiókodhoz tartozó jelszavad változatlan marad mindaddig, amíg újat nem hozol létre a fenti linkre kattintva. + extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az emailt tárgytalannak. A jelszavad változatlan marad mindaddig, amíg újat nem hozol létre a fenti linkre kattintva. subject: 'Mastodon: Jelszó visszaállítási lépések' title: Jelszó visszaállítása two_factor_disabled: @@ -55,37 +55,37 @@ hu: subject: Kétlépcsős azonosítás engedélyezve title: Kétlépcsős hitelesítés engedélyezve two_factor_recovery_codes_changed: - explanation: A korábbi helyreállítási kódokat letiltottuk, és újakat generáltunk. + explanation: A korábbi helyreállítási kódok letiltásra és újragenerálásra kerültek. subject: Kétlépcsős helyreállítási kódok újra létrejöttek - title: A kétlépcsős kódok megváltozott + title: A kétlépcsős kódok megváltoztak unlock_instructions: subject: 'Mastodon: Feloldási lépések' webauthn_credential: added: explanation: A következő biztonsági kulcsot hozzáadtuk a fiókodhoz subject: 'Mastodon: Új biztonsági kulcs' - title: Új biztonsági kulcsot vettünk fel + title: Új biztonsági kulcs lett hozzáadva deleted: explanation: A következő biztonsági kulcsot töröltük a fiókodból - subject: 'Mastodon: Biztonsági kulcs törölve' + subject: 'Mastodon: A biztonsági kulcs törlésre került' title: Az egyik biztonsági kulcsodat törölték webauthn_disabled: explanation: A biztonsági kulccsal történő hitelesítést letiltottuk a fiókodon. Bejelentkezni csak a párosított TOTP app által generált tokennel lehet. - subject: 'Mastodon: Biztonsági kulccsal történő hitelesítés letiltva' - title: Biztonsági kulcsok letiltva + subject: 'Mastodon: A biztonsági kulccsal történő hitelesítés letiltásra került' + title: A biztonsági kulcsok letiltásra kerültek webauthn_enabled: explanation: A biztonsági kulccsal történő hitelesítést engedélyeztük a fiókodon. A biztonsági kulcsodat mostantól használhatod bejelentkezésre. - subject: 'Mastodon: Biztonsági kulcsos hitelesítés engedélyezve' - title: Biztonsági kulcsok engedélyezve + subject: 'Mastodon: A biztonsági kulcsos hitelesítés engedélyezésre került' + title: A biztonsági kulcsok engedélyezésre kerültek omniauth_callbacks: failure: Sikertelen hitelesítés %{kind} fiókról, mert "%{reason}". success: Sikeres hitelesítés %{kind} fiókról. passwords: - no_token: Nem férhetsz hozzá ehhez az oldalhoz jelszó visszaállító e-mail nélkül. Ha egy jelszó visszaállító e-mail hozott ide, ellenőrizd, hogy a megadott teljes URL-t használd. - send_instructions: Pár percen belül kapni fogsz egy e-mailt arról, hogy hogyan tudod visszaállítani a jelszavadat. Kérlek ellenőrizd a levélszemét mappádat, ha nem kaptál ilyen e-mailt. - send_paranoid_instructions: Ha létezik az e-mail cím, pár percen belül kapni fogsz egy e-mailt arról, hogy hogyan tudod visszaállítani a jelszavadat. Kérlek ellenőrizd a levélszemét mappádat, ha nem kaptál ilyen e-mailt. - updated: Jelszavad sikeresen frissült. Bejelentkeztél. - updated_not_active: Jelszavad sikeresen megváltoztattuk. + no_token: Nem férhetsz hozzá ehhez az oldalhoz jelszó-visszaállító email nélkül. Ha egy jelszó-visszaállító email hozott ide, ellenőrizd, hogy a teljes megadott URL-t használtad-e. + send_instructions: Ha az emailcímed létezik az adatbázisunkban, néhány percen belül kapsz egy jelszó-helyreállítási hivatkozást az emailcímedre. Ellenőrizd a spam mappádat, ha nem kaptad meg ezt az emailt. + send_paranoid_instructions: Ha az emailcímed létezik az adatbázisunkban, néhány percen belül kapsz egy jelszó-helyreállítási hivatkozást az emailcímedre. Ellenőrizd a spam mappádat, ha nem kaptad meg ezt az emailt. + updated: A jelszavad sikeresen megváltozott. Megtörtént a bejelentkezés. + updated_not_active: A jelszavad sikeresen megváltoztatásra került. registrations: destroyed: Viszlát! A fiókodat sikeresen töröltük. Reméljük hamarosan viszontláthatunk. signed_up: Üdvözlünk! Sikeresen regisztráltál. @@ -94,15 +94,15 @@ hu: signed_up_but_pending: Egy megerősítési hivatkozással ellátott üzenetet kiküldtünk az e-mail címedre. Ha kattintasz a hivatkozásra, átnézzük a kérelmedet. Értesítünk, ha jóváhagytuk. signed_up_but_unconfirmed: Egy megerősítési hivatkozással ellátott üzenetet kiküldtünk az e-mail címedre. Kérjük használd a hivatkozást a fiókod aktiválásához. Ellenőrizd a spam mappádat, ha nem kaptad meg ezt a levelet. update_needs_confirmation: Sikeresen frissítetted a fiókodat, de szükségünk van az e-mail címed megerősítésére. Kérlek ellenőrizd az e-mailedet és kövesd a levélben szereplő megerősítési linket az e-mail címed megerősítéséhez. Ellenőrizd a levélszemét mappád, ha nem kaptál volna ilyen levelet. - updated: Fiókod frissítése sikeres. + updated: A fiókod sikeresen frissítésre került. sessions: - already_signed_out: Sikeres kijelentkezés. - signed_in: Sikeres bejelentkezés. - signed_out: Sikeres kijelentkezés. + already_signed_out: A kijelentkezés sikeres volt. + signed_in: A bejelentkezés sikeres volt. + signed_out: A kijelentkezés sikeres volt. unlocks: send_instructions: Pár percen belül egy e-mailt fogsz kapni a feloldáshoz szükséges lépésekkel. Ellenőrizd a levélszemét mappád, ha nem kaptál volna ilyen levelet. send_paranoid_instructions: Ha a fiókod létezik, pár percen belül egy e-mailt fogsz kapni a feloldáshoz szükséges lépésekkel. Ellenőrizd a levélszemét mappád, ha nem kaptál volna ilyen levelet. - unlocked: A fiókodat sikeresen feloldottuk. Jelentkezz be a folytatáshoz. + unlocked: A fiókod sikeresen feloldásra került. Jelentkezz be a folytatáshoz. errors: messages: already_confirmed: már meg lett erősítve, kérjük jelentkezz be diff --git a/config/locales/devise.is.yml b/config/locales/devise.is.yml index e595f77afd..3b7cf10987 100644 --- a/config/locales/devise.is.yml +++ b/config/locales/devise.is.yml @@ -88,7 +88,7 @@ is: updated_not_active: Það tókst að breyta lykilorðinu þínu. registrations: destroyed: Bless! Hætt hefur verið við notandaaðganginn þinn. Við vonumst samt eftir að sjá þig fljótt aftur. - signed_up: Velkonin/n! Það tókst að nýskrá þig. + signed_up: Velkomin/n! Það tókst að nýskrá þig. signed_up_but_inactive: Þér hefur tekist að nýskrá þig. Hinsvegar gátum við ekki skráð þig inn því notandaaðgangurinn þinn hefur ekki enn verið virkjaður. signed_up_but_locked: Þér hefur tekist að nýskrá þig. Hinsvegar gátum við ekki skráð þig inn því notandaaðgangurinn þinn er læstur. signed_up_but_pending: Skilaboð með staðfestingartengli hafa verið send á tölvupóstfangið þitt. Þegar þú smellir á þennan tengil munum við yfirfara og staðfesta umsóknina þína. Þú færð svo að vita hvort hún verður samþykkt. diff --git a/config/locales/devise.ko.yml b/config/locales/devise.ko.yml index 9dc9f2167b..3ab7c11a5c 100644 --- a/config/locales/devise.ko.yml +++ b/config/locales/devise.ko.yml @@ -4,7 +4,7 @@ ko: confirmations: confirmed: 이메일이 성공적으로 승인 되었습니다. send_instructions: 몇 분 이내로 확인 이메일이 발송 됩니다. 이메일을 받지 못 한 경우, 스팸 폴더를 확인하세요. - send_paranoid_instructions: 당신의 이메일이 우리의 DB에 있을 경우 몇 분 이내로 확인 메일이 발송 됩니다. 이메일을 받지 못 한 경우, 스팸 폴더를 확인하세요. + send_paranoid_instructions: 이메일 주소가 저희 데이터베이스에 있는 경우, 몇 분 내에 이메일 주소를 확인하는 방법에 대한 안내가 포함된 이메일을 받을 수 있습니다. 이 이메일을 받지 못했다면 스팸 폴더를 확인해 주세요. failure: already_authenticated: 이미 로그인 된 상태입니다. inactive: 계정이 아직 활성화 되지 않았습니다. @@ -13,7 +13,7 @@ ko: locked: 계정이 잠겼습니다. not_found_in_database: 올바르지 않은 %{authentication_keys} 혹은 암호입니다. pending: 이 계정은 아직 검토 중입니다. - timeout: 세션이 만료 되었습니다. 다시 로그인 해 주세요. + timeout: 세션이 만료되었습니다. 다시 로그인 하세요. unauthenticated: 계속 하려면 로그인을 해야 합니다. unconfirmed: 계속 하려면 이메일을 확인 받아야 합니다. mailer: @@ -82,8 +82,8 @@ ko: success: "%{kind} 계정을 성공적으로 인증했습니다." passwords: no_token: 이 페이지는 암호 재설정 이메일을 거쳐야 접근할 수 있습니다. 만약 암호 재설정 이메일 거치지 않았다면 입력한 URL이 맞는지 확인 바랍니다. - send_instructions: 당신의 이메일 주소가 우리의 DB에 있다면 패스워드 복구 링크가 몇 분 이내에 메일로 발송 됩니다. 만약 메일을 받지 못 하신 경우 스팸 폴더를 확인해 주세요. - send_paranoid_instructions: 당신의 이메일 주소가 우리의 DB에 있다면 패스워드 복구 링크가 몇 분 이내에 메일로 발송 됩니다. 만약 메일을 받지 못 하신 경우 스팸 폴더를 확인해 주세요. + send_instructions: 이메일 주소가 저희 데이터베이스에 있는 경우, 몇 분 내에 이메일 주소로 비밀번호 복구 링크를 받을 수 있습니다. 이 이메일을 받지 못했다면 스팸 폴더를 확인해 주세요. + send_paranoid_instructions: 이메일 주소가 저희 데이터베이스에 있는 경우, 몇 분 내에 이메일 주소로 비밀번호 복구 링크를 받을 수 있습니다. 이 이메일을 받지 못했다면 스팸 폴더를 확인해 주세요. updated: 암호를 잘 바꾸었습니다. 현재 로그인 상태입니다. updated_not_active: 암호를 잘 변경하였습니다. registrations: diff --git a/config/locales/devise.ms.yml b/config/locales/devise.ms.yml index c1165e47da..30eceb239d 100644 --- a/config/locales/devise.ms.yml +++ b/config/locales/devise.ms.yml @@ -81,17 +81,39 @@ ms: failure: Tidak dapat mengesahkan anda daripada %{kind} disebabkan oleh “%{reason}”. success: Berjaya disahkan daripada akaun %{kind}. passwords: + no_token: Anda tidak boleh mengakses halaman ini tanpa datang daripada e-mel tetapan semula kata laluan. Jika anda datang daripada e-mel tetapan semula kata laluan, sila pastikan anda menggunakan URL penuh yang disediakan. + send_instructions: Jika alamat e-mel anda wujud dalam pangkalan data kami, anda akan menerima pautan pemulihan kata laluan di alamat e-mel anda dalam beberapa minit. Sila semak folder spam anda jika anda tidak menerima e-mel ini. + send_paranoid_instructions: Jika alamat e-mel anda wujud dalam pangkalan data kami, anda akan menerima pautan pemulihan kata laluan di alamat e-mel anda dalam beberapa minit. Sila semak folder spam anda jika anda tidak menerima e-mel ini. updated: Kata laluan anda telah berjaya ditukar. Anda telah didaftar masuk. updated_not_active: Kata laluan anda telah berjaya ditukar. registrations: destroyed: Selamat tinggal! Akaun anda telah berjaya dibatalkan. Kami harap berjumpa lagi. signed_up: Selamat datang! Anda telah berjaya mendaftar. signed_up_but_inactive: Anda telah berjaya mendaftar. Namun, kami tidak dapat mendaftar masuk anda kerana akaun anda belum diaktifkan. + signed_up_but_locked: Anda telah berjaya mendaftar. Walau bagaimanapun, kami tidak dapat melog masuk anda kerana akaun anda dikunci. + signed_up_but_pending: Mesej dengan pautan pengesahan telah dihantar ke alamat e-mel anda. Selepas anda mengklik pautan, kami akan menyemak permohonan anda. Anda akan dimaklumkan jika ia diluluskan. + signed_up_but_unconfirmed: Mesej dengan pautan pengesahan telah dihantar ke alamat e-mel anda. Sila ikuti pautan untuk mengaktifkan akaun anda. Sila semak folder spam anda jika anda tidak menerima e-mel ini. + update_needs_confirmation: Anda berjaya mengemas kini akaun anda, tetapi kami perlu mengesahkan alamat e-mel baharu anda. Sila semak e-mel anda dan ikuti pautan pengesahan untuk mengesahkan alamat e-mel baharu anda. Sila semak folder spam anda jika anda tidak menerima e-mel ini. + updated: Akaun anda telah berjaya dikemas kini. sessions: already_signed_out: Daftar keluar berjaya. signed_in: Daftar masuk berjaya. signed_out: Daftar keluar berjaya. + unlocks: + send_instructions: Anda akan menerima e-mel dengan arahan tentang cara membuka kunci akaun anda dalam beberapa minit. Sila semak folder spam anda jika anda tidak menerima e-mel ini. + send_paranoid_instructions: Jika akaun anda wujud, anda akan menerima e-mel dengan arahan cara membuka kuncinya dalam beberapa minit. Sila semak folder spam anda jika anda tidak menerima e-mel ini. + unlocked: Akaun anda telah berjaya dibuka. Sila log masuk untuk meneruskan. errors: messages: already_confirmed: sudah disahkan, sila cuba mendaftar masuk + confirmation_period_expired: perlu disahkan dalam %{period}, sila minta yang baharu + expired: telah tamat tempoh, sila minta yang baharu not_found: tidak dijumpai + not_locked: tidak dikunci + not_saved: + other: |- + satu + 1 ralat melarang %{resource} ini daripada disimpan: + + Lain-lain + %{count} ralat melarang %{resource} ini daripada disimpan: diff --git a/config/locales/devise.my.yml b/config/locales/devise.my.yml index 5e1fc6bee9..04d744cf2b 100644 --- a/config/locales/devise.my.yml +++ b/config/locales/devise.my.yml @@ -1 +1,114 @@ +--- my: + devise: + confirmations: + confirmed: သင်၏ အီးမေးလ်လိပ်စာ အောင်မြင်စွာအတည်ပြုပြီးပါပြီ။ + send_instructions: မိနစ်အနည်းငယ်အတွင်း သင့်အီးမေးလ်လိပ်စာကို အတည်ပြုရန်အတွက် ညွှန်ကြားချက်များပါရှိသည့် အီးမေးလ်တစ်စောင်ကို သင်ရရှိမည်ဖြစ်ပါသည်။ ဤအီးမေးလ်ကို လက်ခံမရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + send_paranoid_instructions: အကယ်၍ သင့်အီးမေးလ်လိပ်စာသည် ကျွန်ုပ်တို့၏ဒေတာဘေ့စ်တွင် ရှိနေပါက မိနစ်အနည်းငယ်အတွင်း သင့်အီးမေးလ်လိပ်စာကို အတည်ပြုရန်အတွက် ညွှန်ကြားချက်များပါရှိသည့် အီးမေးလ်တစ်စောင်ကို သင်ရရှိမည်ဖြစ်ပါသည်။ ဤအီးမေးလ်ကို လက်ခံမရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + failure: + already_authenticated: သင်ဝင်ရောက်ပြီးဖြစ်သည်။ + inactive: သင်၏အကောင့်သည်အသက်မဝင်သေးပါ + invalid: မှားယွင်းသော %{authentication_keys} သို့မဟုတ် စကားဝှက် ဖြစ်ပါသည်။ + last_attempt: သင့်အကောင့်ကို လော့ခ်မချမီ နောက်ထပ်ကြိုးစားမှုတစ်ခု ရှိသေးသည်။ + locked: သင့်အကောင့်ကို လော့ခ်ချထားသည်။ + not_found_in_database: မှားယွင်းသော %{authentication_keys} သို့မဟုတ် စကားဝှက် ဖြစ်ပါသည်။ + pending: သင့်အကောင့်အား စိစစ်ဆဲဖြစ်သည်။ + timeout: သင့် Session သက်တမ်းကုန်သွားပါပြီ။ ရှေ့ဆက်ရန်အတွက် ကျေးဇူးပြုပြီး ထပ်မံဝင်ရောက်ပါ။ + unauthenticated: ဆက်မလုပ်မီ သင်သည် အကောင့်ဝင်ရန် သို့မဟုတ် အကောင့်ဖွင့်ရန် လိုအပ်သည်။ + unconfirmed: ဆက်မလုပ်မီ သင့်အီးမေးလ်လိပ်စာကို အတည်ပြုရပါမည်။ + mailer: + confirmation_instructions: + action: အီးမေးလ်လိပ်စာကို အတည်ပြုပါ + action_with_app: အတည်ပြုပြီး %{app} သို့ပြန်သွားပါ + explanation: "%{host} တွင် ဤအီးမေးလ်လိပ်စာဖြင့် သင် အကောင့်တစ်ခု ဖန်တီးထားပြီးဖြစ်သည်။ သင် ကလစ်တစ်ချက်နှိပ်ရုံဖြင့် အကောင့်အား အသက်ဝင်စေနိုင်သည်။ အကယ်၍ သင်ဖန်တီးထားခြင်းမဟုတ်ခဲ့လျှင် ယခုအီးမေးလ်အား ကျေးဇူးပြု၍ လျစ်လျူရှုပါ။" + explanation_when_pending: "%{host} သို့ ဖိတ်ခေါ်မှုတစ်ခုကို ဤအီးမေးလ်လိပ်စာဖြင့် သင်တောင်းဆိုခဲ့သည်။ အီးမေးလ်လိပ်စာကို သင်အတည်ပြုပြီးပါက ကျွန်ုပ်တို့အနေဖြင့် သင့်တောင်းဆိုမှုအား စိစစ်မည်ဖြစ်သည်။ သင့်အနေဖြင့် မိမိအကောင့်အတွင်း ဝင်ရောက်၍ အသေးစိတ်အချက်အလက်များအား ပြုပြင်နိုင်သည် (သို့) မိမိအကောင့်အား ဖျက်နိုင်သည်။ သို့သော် သင့်အကောင့်ကို အတည်ပြုမပြီးမချင်း သင့်အနေဖြင့် လုပ်ငန်းဆောင်တာအများစုအား ဆောင်ရွက်နိုင်မည် မဟုတ်ပေ။ သင်၏ အကောင့်တောင်းဆိုမှု ငြင်းဆန်ခံရပါက သင့်အချက်အလက်များအား ဖယ်ရှားပေးမည်ဖြစ်သည်။ သင့်အနေဖြင့် တခြားအရေးယူဆောင်ရွက်ရန် မလိုအပ်ပါ။ အကယ်၍ ယခုတောင်းဆိုမှုအား သင်ပြုလုပ်ထားခြင်းမဟုတ်ခဲ့လျှင် ယခုအီးမေးလ်အား ကျေးဇူးပြု၍ လျစ်လျူရှုပါ။" + extra_html: ကျေးဇူးပြု၍ ဆာဗာစည်းမျဉ်းများ နှင့် ကျွန်ုပ်တို့၏ဝန်ဆောင်မှုစည်းမျဉ်းများကိုလည်း စစ်ဆေးကြည့်ပါ။ + subject: Mastodon - %{instance} အတွက် အတည်ပြုချက် ညွှန်ကြားချက်များ + title: အီးမေးလ်လိပ်စာကို အတည်ပြုပါ + email_changed: + explanation: သင့်အကောင့်အတွက် အီးမေးလ်လိပ်စာကို ပြောင်းလဲနေပါသည် - + extra: သင့်အီးမေးလ်လိပ်စာ မပြောင်းထားပါက တစ်စုံတစ်ဦးသည် သင့်အကောင့်သို့ ဝင်ရောက်ခွင့်ရရှိသွားနိုင်ပါသည်။ သင့်အကောင့် လော့ခ်ကျသွားပါက သင့်စကားဝှက်ကို ချက်ချင်းပြောင်းပါ သို့မဟုတ် ဆာဗာစီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။ + subject: 'Mastodon: အီးမေးလ်ပြောင်းလဲသွားပြီ' + title: အီးမေးလ်လိပ်စာအသစ် + password_change: + explanation: သင့်အကောင့်အတွက် စကားဝှက်ကို ပြောင်းလဲလိုက်ပါပြီ။ + extra: သင့်စကားဝှက် မပြောင်းထားပါက တစ်စုံတစ်ဦးသည် သင့်အကောင့်သို့ ဝင်ရောက်ခွင့်ရရှိသွားနိုင်ပါသည်။ သင့်အကောင့် လော့ခ်ကျသွားပါက သင့်စကားဝှက်ကို ချက်ချင်းပြောင်းပါ သို့မဟုတ် ဆာဗာစီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။ + subject: 'Mastodon: စကားဝှက်ပြောင်းလဲသွားပြီ' + title: စကားဝှက်ပြောင်းလဲသွားပြီ + reconfirmation_instructions: + explanation: သင်၏အီးမေးလ်လိပ်စာပြောင်းရန် လိပ်စာအသစ်အတည်ပြုပါ။ + extra: တစ်ကယ်လို့ ပြောင်းလဲမှုကို သင်တောင်းဆိုတာမဟုတ်ဘူးဆိုရင် ဤအီးမေးလ်ကို လျစ်လျူရှုလိုက်ပါ။ အပေါ်မှ လင့်ခ်ကိုမဝင်မချင်း သင့်အီးမေးလ်ပြောင်းသွားမည်မဟုတ်ပါ + subject: 'Mastodon: %{instance} အတွက်အီးမေးလ်အတည်ပြုပါ' + title: အီးမေးလ်လိပ်စာစစ်ဆေးပါ + reset_password_instructions: + action: စကားဝှက်ပြောင်းမည် + explanation: သင့်အကောင့်အတွက် စကားဝှက်အသစ်တစ်ခု တောင်းဆိုခဲ့သည်။ + extra: သင်မတောင်းဆိုထားပါက ဤအီးမေးလ်ကို လျစ်လျူရှုလိုက်ပါ။ အထက်ဖော်ပြပါလင့်ခ်ကို သင်ဝင်ရောက်ပြီး အသစ်တစ်ခုမဖန်တီးမချင်း သင့်စကားဝှက်သည် ပြောင်းလဲမည်မဟုတ်ပါ။ + subject: 'Mastodon: စကားဝှက်ညွှန်ကြားချက် ပြန်လည်သတ်မှတ်မည်' + title: စကားဝှက်ပြန်လည်သတ်မှတ်မည် + two_factor_disabled: + explanation: သင့်အကောင့်အတွက် နှစ်ဆင့်ခံလုံခြုံရေးစနစ်အထောက်အထားပြခြင်းကို ပိတ်ထားသည်။ အီးမေးလ်လိပ်စာနှင့် စကားဝှက်ကိုသာ အသုံးပြု၍ အကောင့်ဝင်ရောက်နိုင်ပါသည်။ + subject: 'Mastodon: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ပိတ်ထားသည်' + title: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ပိတ်ထားသည် + two_factor_enabled: + explanation: သင့်အကောင့်အတွက် နှစ်ဆင့်ခံလုံခြုံရေးစနစ်အထောက်အထားပြခြင်းကို ဖွင့်ထားသည်။ TOTP အက်ပ်မှ ထုတ်ပေးသည့် တိုကင်တစ်ခုမှာ အကောင့်ဝင်ရန်အတွက် လိုအပ်ပါသည်။ + subject: 'Mastodon: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ဖွင့်ထားသည်' + title: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ဖွင့်ထားသည် + two_factor_recovery_codes_changed: + explanation: ယခင်ပြန်လည်ရယူသည့်ကုဒ်များမှာ မမှန်ကန်သောကြောင့် အသစ်များကို ထုတ်ပေးခဲ့သည်။ + subject: Mastodon - နှစ်ဆင့်ခံလုံခြုံရေး ပြန်လည်ရယူသည့်ကုဒ်များကို ပြန်လည်ထုတ်ပေးခြင်း + title: နှစ်ဆင့်ခံလုံခြုံရေးစနစ် ပြန်လည်ရယူသည့်ကုဒ်နံပါတ်များ ပြောင်းလဲခဲ့သည် + unlock_instructions: + subject: Mastodon - ညွှန်ကြားချက်များကို လော့ခ်ဖွင့်ပါ + webauthn_credential: + added: + explanation: ဖော်ပြပါလုံခြုံရေးသော့ချက်အား သင့်အကောင့်ထဲသို့ထည့်ပြီးပါပြီ + subject: 'Mastodon: လုံခြုံရေးသော့ချက်အသစ်' + title: လုံခြုံရေးသော့ချက်အသစ် ထည့်လိုက်ပါပြီ + deleted: + explanation: ဖော်ပြပါလုံခြုံရေးသော့ချက်အား သင့်အကောင့်ထဲမှဖျက်လိုက်ပါပြီ + subject: 'Mastodon: လုံခြုံရေးသော့ချက် ဖျက်လိုက်ပါပြီ' + title: လုံခြုံရေးသော့ချက်များထဲမှတစ်ခု ဖျက်လိုက်ပါပြီ + webauthn_disabled: + explanation: သင့်အကောင့်အတွက် လုံခြုံရေးကီးများဖြင့် အထောက်အထားပြခြင်းကို ပိတ်ထားသည်။ TOTP အက်ပ်မှထုတ်ပေးသည့် တိုကင်ကိုသာ အသုံးပြု၍ အကောင့်ဝင်ရောက်နိုင်ပါသည်။ + subject: Mastodon - လုံခြုံရေးကီးများဖြင့် အထောက်အထားစိစစ်ခြင်းကို ပိတ်ထားသည် + title: လုံခြုံရေးသော့ချက်များ ပိတ်ပြီးပါပြီ + webauthn_enabled: + explanation: သင့်အကောင့်အတွက် လုံခြုံရေးကီး အထောက်အထားစိစစ်ခြင်းကို ဖွင့်ထားသည်။ အကောင့်ဝင်ရန်အတွက် သင်၏လုံခြုံရေးကီးကို ယခုအသုံးပြုနိုင်ပါပြီ။ + subject: Mastodon - လုံခြုံရေးကီး အထောက်အထားစိစစ်ခြင်းကို ဖွင့်ထားသည် + title: လုံခြုံရေးသော့ချက်များ ဖွင့်ပြီးပါပြီ + omniauth_callbacks: + failure: "“%{reason}” ကြောင့် %{kind} မှ သင့်ကို စစ်မှန်ကြောင်း အထောက်အထား မပြနိုင်ပါ။" + success: "%{kind} အကောင့်မှ အထောက်အထားပြပြီးပါပြီ။" + passwords: + no_token: စကားဝှက်ပြန်လည်သတ်မှတ်ခြင်းအီးမေးလ်မှ မလာပါက ဤစာမျက်နှာကို သင်ဝင်ရောက်၍မရနိုင်ပါ။ အကယ်၍ ၎င်းမှလာပါက ပေးထားသော URL အပြည့်အစုံကို အသုံးပြုရပါမည်။ + send_instructions: အကယ်၍ သင့်အီးမေးလ်လိပ်စာသည် ကျွန်ုပ်တို့၏ဒေတာဘေ့စ်တွင် ရှိနေပါက မိနစ်အနည်းငယ်အတွင်း သင့်အီးမေးလ်လိပ်စာတွင် စကားဝှက်ပြန်လည်ရယူရေးလင့်ခ် ရရှိမည်ဖြစ်ပါသည်။ ဤအီးမေးလ်ကို လက်ခံမရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + send_paranoid_instructions: အကယ်၍ သင့်အီးမေးလ်လိပ်စာသည် ကျွန်ုပ်တို့၏ဒေတာဘေ့စ်တွင် ရှိနေပါက မိနစ်အနည်းငယ်အတွင်း သင့်အီးမေးလ်လိပ်စာတွင် စကားဝှက်ပြန်လည်ရယူရေးလင့်ခ် ရရှိမည်ဖြစ်ပါသည်။ ဤအီးမေးလ်ကို လက်ခံမရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + updated: သင့်စကားဝှက်ကို အောင်မြင်စွာ ပြောင်းလဲပြီးပါပြီ။ သင်သည် ယခု အကောင့်ဝင်ထားပြီးဖြစ်ပါသည်။ + updated_not_active: သင့်စကားဝှက်ကို အောင်မြင်စွာ ပြောင်းလဲပြီးပါပြီ။ + registrations: + destroyed: တာ့တာ၊ သင့်အကောင့်ကို ပယ်ဖျက်လိုက်ပါပြီ။ မကြာခင် ပြန်တွေ့နိုင်ရန်မျှော်လင့်မိပါသည်။ + signed_up: ကြိုဆိုပါသည်။ သင်သည် အောင်မြင်စွာ စာရင်းသွင်းပြီးပါပြီ။ + signed_up_but_inactive: သင်သည် အောင်မြင်စွာ အကောင့်ဖွင့်ပြီးပါပြီ။ သို့သော်လည်း သင့်အကောင့် အတည်မပြုရသေးသောကြောင့် ဝင်၍မရနိုင်ပါ။ + signed_up_but_locked: သင်သည် အောင်မြင်စွာ အကောင့်ဖွင့်ပြီးပါပြီ။ သို့သော်လည်း သင့်အကောင့်လော့ခ်ချထားသောကြောင့် လက်မှတ်ထိုးဝင်၍မရနိုင်ပါ။ + signed_up_but_pending: အတည်ပြုချက်လင့်ခ်ပါရှိသော စာတိုတစ်စောင်ကို သင့်အီးမေးလ်လိပ်စာသို့ ပေးပို့လိုက်ပါပြီ။ လင့်ခ်ကို နှိပ်ပြီးနောက် သင့်အက်ပလီကေးရှင်းကို ကျွန်ုပ်တို့ ပြန်လည်စစ်ဆေးပါမည်။ အတည်ပြုပြီးပါက သင့်ထံ အကြောင်းကြားပါမည်။ + signed_up_but_unconfirmed: အကောင့်ဖွင့်ရန်အတွက် လင့်ခ်တစ်ခုကို ထောက်ခံချက်အီးမေးလ််နှင့်အတူပို့ပေးလိုက်ပါပြီ။ သင့်အကောင့်ဖွင့်နိုင်ရန် လင့်ခ်ကိုဝင်ရောက်ပေးပါ။ အီးမေးလ်မတွေ့ပါက စပမ်းဖိုင်တွဲထဲတွင်စစ်ကြည့်ပါ။ + update_needs_confirmation: သင့်အကောင့်ကို မွမ်းမံပြင်ဆင်ထားသော်လည်း သင့်အီးမေးလ်လိပ်စာအသစ်ကို အတည်ပြုရန် လိုအပ်ပါသည်။ ကျေးဇူးပြု၍ သင့်အီးမေးလ်ကို စစ်ဆေးပြီး သင့်အီးမေးလ်လိပ်စာအသစ်ကို အတည်ပြုရန်အတွက် အတည်ပြုလင့်ခ်အား နှိပ်ပါ။ ဤအီးမေးလ်ကို မရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + updated: သင့်အကောင့်အားအောင်မြင်စွာ ပြင်ဆင်ပြီးပါပြီ။ + sessions: + already_signed_out: အောင်မြင်စွာအကောင့်မှထွက်ပြီးပါပြီ။ + signed_in: အောင်မြင်စွာအကောင့်ဝင်ပြီးပါပြီ။ + signed_out: အောင်မြင်စွာအကောင့်မှထွက်ပြီးပါပြီ။ + unlocks: + send_instructions: မိနစ်အနည်းငယ်အတွင်း သင့်အကောင့်လော့ခ်ဖွင့်နည်းအတွက် ညွှန်ကြားချက်များပါရှိသည့် အီးမေးလ်တစ်စောင်ကို သင်လက်ခံရရှိမည်ဖြစ်သည်။ ဤအီးမေးလ်ကို မရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + send_paranoid_instructions: အကယ်၍ သင့်တွင် အကောင့်ရှိပါက မိနစ်အနည်းငယ်အတွင်း လော့ခ်ဖွင့်နည်းအတွက် ညွှန်ကြားချက်များပါရှိသည့် အီးမေးလ်တစ်စောင်ကို သင်ရရှိမည်ဖြစ်သည်။ ဤအီးမေးလ်ကို လက်ခံမရရှိပါက သင်၏ Spam ဖိုင်ကို စစ်ဆေးပါ။ + unlocked: သင့်အကောင့်ကို လော့ခ်ဖွင့်ပြီးပါပြီ။ ရှေ့ဆက်ရန်အတွက် အကောင့်ဝင်ပါ။ + errors: + messages: + already_confirmed: အတည်ပြုပြီးဖြစ်သည်။ ကျေးဇူးပြု၍ အကောင့်ဝင်ကြည့်ပါ။ + confirmation_period_expired: "%{period} အတွင်း အတည်ပြုရန် လိုအပ်ပြီး အသစ်တစ်ခု တောင်းဆိုပါ" + expired: သည် သက်တမ်းကျော်လွန်သွားပြီ။ ကျေးဇူးပြု၍အသစ်တစ်ခု တောင်းဆိုပါ + not_found: ရှာမတွေ့ပါ + not_locked: လော့ခ် မချထားပါ + not_saved: + other: "%{count} အမှားသည် ဤ %{resource} အား သိမ်းဆည်းခြင်းမှ တားမြစ်ထားသည်-" diff --git a/config/locales/devise.nl.yml b/config/locales/devise.nl.yml index 477c7d41f1..1b5081fe8c 100644 --- a/config/locales/devise.nl.yml +++ b/config/locales/devise.nl.yml @@ -2,7 +2,7 @@ nl: devise: confirmations: - confirmed: Jouw account is bevestigd. + confirmed: Jouw e-mailadres is succesvol bevestigd. send_instructions: Je ontvangt via e-mail instructies hoe je jouw account kunt bevestigen. Kijk tussen je spam wanneer niks werd ontvangen. send_paranoid_instructions: Als jouw e-mailadres in de database staat, ontvang je via e-mail instructies hoe je jouw account kunt bevestigen. Kijk tussen je spam wanneer niks werd ontvangen. failure: diff --git a/config/locales/devise.pt-BR.yml b/config/locales/devise.pt-BR.yml index ae64d165e2..6345a103b8 100644 --- a/config/locales/devise.pt-BR.yml +++ b/config/locales/devise.pt-BR.yml @@ -13,7 +13,7 @@ pt-BR: locked: Sua conta está bloqueada. not_found_in_database: "%{authentication_keys} ou senha inválida." pending: Sua conta está sendo revisada. - timeout: Você saiu de sua conta. Entre novamente para continuar. + timeout: Sua sessão expirou. Por favor, entre novamente para continuar. unauthenticated: Você precisa entrar ou criar uma conta antes de continuar. unconfirmed: Você precisa confirmar o seu endereço de e-mail antes de continuar. mailer: diff --git a/config/locales/devise.si.yml b/config/locales/devise.si.yml index a20057cef9..362f97b8a9 100644 --- a/config/locales/devise.si.yml +++ b/config/locales/devise.si.yml @@ -23,7 +23,6 @@ si: explanation: ඔබ මෙම ඊමේල් ලිපිනය සමඟ %{host} හි ගිණුමක් සාදා ඇත. ඔබ එය සක්‍රිය කිරීමට එක ක්ලික් කිරීමක් ඇත. මේ ඔබ නොවේ නම්, කරුණාකර මෙම විද්‍යුත් තැපෑල නොසලකා හරින්න. explanation_when_pending: ඔබ මෙම විද්‍යුත් තැපැල් ලිපිනය සමඟ %{host} වෙත ආරාධනාවක් සඳහා ඉල්ලුම් කළා. ඔබ ඔබගේ විද්‍යුත් තැපැල් ලිපිනය තහවුරු කළ පසු, අපි ඔබගේ අයදුම්පත සමාලෝචනය කරන්නෙමු. ඔබගේ විස්තර වෙනස් කිරීමට හෝ ඔබගේ ගිණුම මකා දැමීමට ඔබට පුරනය විය හැක, නමුත් ඔබගේ ගිණුම අනුමත වන තුරු ඔබට බොහෝ කාර්යයන් වෙත ප්‍රවේශ විය නොහැක. ඔබගේ අයදුම්පත ප්‍රතික්ෂේප කළහොත්, ඔබගේ දත්ත ඉවත් කරනු ඇත, එබැවින් ඔබෙන් වැඩිදුර ක්‍රියාමාර්ග අවශ්‍ය නොවනු ඇත. මේ ඔබ නොවේ නම්, කරුණාකර මෙම විද්‍යුත් තැපෑල නොසලකා හරින්න. extra_html: කරුණාකර සේවාදායකයේ නීති සහ අපගේ සේවා කොන්දේසිද පරීක්ෂා කරන්න. - subject: 'Mastodon: %{instance}සඳහා තහවුරු කිරීමේ උපදෙස්' title: වි. තැපෑල තහවුරු කරන්න email_changed: explanation: 'ඔබගේ ගිණුම සඳහා ඊමේල් ලිපිනය වෙනස් වෙමින් පවතී:' @@ -33,30 +32,26 @@ si: password_change: explanation: ඔබගේ ගිණුම සඳහා මුරපදය වෙනස් කර ඇත. extra: ඔබ ඔබගේ මුරපදය වෙනස් නොකළේ නම්, යමෙකු ඔබගේ ගිණුමට ප්‍රවේශය ලබා ගෙන ඇති බව පෙනෙන්නට තිබේ. ඔබගේ ගිණුමෙන් අගුලු දමා ඇත්නම් කරුණාකර ඔබගේ මුරපදය වහාම වෙනස් කරන්න හෝ සේවාදායක පරිපාලක අමතන්න. - subject: 'Mastodon: මුරපදය වෙනස් විය' + subject: 'මාස්ටඩන්: මුරපදය වෙනස් විය' title: මුරපදය වෙනස් විය reconfirmation_instructions: explanation: ඔබගේ ඊමේල් වෙනස් කිරීමට නව ලිපිනය තහවුරු කරන්න. - extra: මෙම වෙනස ඔබ විසින් ආරම්භ කරන ලද්දක් නොවේ නම්, කරුණාකර මෙම විද්‍යුත් තැපෑල නොසලකා හරින්න. ඔබ ඉහත සබැඳියට ප්‍රවේශ වන තෙක් Mastodon ගිණුම සඳහා ඊමේල් ලිපිනය වෙනස් නොවේ. - subject: 'Mastodon: %{instance}සඳහා විද්‍යුත් තැපෑල තහවුරු කරන්න' title: වි-තැපෑල තහවුරු කරන්න reset_password_instructions: action: මුරපදය වෙනස් කරන්න explanation: ඔබ ඔබගේ ගිණුම සඳහා නව මුරපදයක් ඉල්ලා ඇත. extra: ඔබ මෙය ඉල්ලා නොසිටියේ නම්, කරුණාකර මෙම විද්‍යුත් තැපෑල නොසලකා හරින්න. ඔබ ඉහත සබැඳියට ප්‍රවේශ වී අලුත් එකක් සාදන තෙක් ඔබේ මුරපදය වෙනස් නොවනු ඇත. - subject: 'Mastodon: මුරපද උපදෙස් යළි පිහිටුවන්න' + subject: 'මාස්ටඩන්: මුරපදය යළි සැකසීමේ උපදෙස්' title: මුරපදය යළි සැකසීම two_factor_disabled: explanation: ඔබගේ ගිණුම සඳහා ද්වි-සාධක සත්‍යාපනය අබල කර ඇත. විද්‍යුත් තැපැල් ලිපිනය සහ මුරපදය පමණක් භාවිතයෙන් දැන් පුරනය විය හැක. - subject: 'Mastodon: ද්වි සාධක සත්‍යාපනය අක්‍රීය කර ඇත' title: ද්විපියවර අබලයි two_factor_enabled: explanation: ඔබගේ ගිණුම සඳහා ද්වි-සාධක සත්‍යාපනය සක්‍රීය කර ඇත. යුගල කළ TOTP යෙදුම මගින් ජනනය කරන ලද ටෝකනයක් පුරනය වීමට අවශ්‍ය වනු ඇත. - subject: 'Mastodon: ද්වි සාධක සත්‍යාපනය සක්‍රීය කර ඇත' title: ද්විපියවර සබලයි two_factor_recovery_codes_changed: explanation: පෙර ප්‍රතිසාධන කේත අවලංගු කර නව ඒවා උත්පාදනය කර ඇත. - subject: 'Mastodon: ද්වි-සාධක ප්‍රතිසාධන කේත නැවත උත්පාදනය කරන ලදී' + subject: 'මාස්ටඩන්: ද්වි-සාධක ප්‍රතිසාධන කේත නැවත උත්පාදනය කෙරිණි' title: ද්විපියවර ප්‍රතිසාධන කේත වෙනස් විය unlock_instructions: subject: 'මාස්ටඩන්: අගුළු හැරීමේ උපදේශ' @@ -67,15 +62,13 @@ si: title: ආරක්‍ෂණ යතුරක් එකතු කර ඇත deleted: explanation: පහත ආරක්ෂක යතුර ඔබගේ ගිණුමෙන් මකා ඇත - subject: 'Mastodon: ආරක්ෂක යතුර මකා ඇත' + subject: 'මාස්ටඩන්: ආරක්‍ෂණ යතුර මකා ඇත' title: ඔබගේ ආරක්ෂක යතුරු වලින් එකක් මකා ඇත webauthn_disabled: explanation: ඔබගේ ගිණුම සඳහා ආරක්ෂක යතුරු සමඟ සත්‍යාපනය අබල කර ඇත. යුගල කළ TOTP යෙදුම මගින් ජනනය කරන ලද ටෝකනය පමණක් භාවිතයෙන් දැන් පුරනය විය හැක. - subject: 'Mastodon: ආරක්ෂක යතුරු සමඟ සත්‍යාපනය අක්‍රිය කර ඇත' title: ආරක්‍ෂණ යතුරු අබල කර ඇත webauthn_enabled: explanation: ඔබගේ ගිණුම සඳහා ආරක්ෂක යතුරු සත්‍යාපනය සක්‍රීය කර ඇත. ඔබගේ ආරක්ෂක යතුර දැන් පුරනය වීම සඳහා භාවිතා කළ හැක. - subject: 'Mastodon: ආරක්ෂක යතුරු සත්‍යාපනය සක්‍රීය කර ඇත' title: ආරක්‍ෂණ යතුරු සබල කර ඇත omniauth_callbacks: failure: '"%{reason}" නිසා %{kind} සිට ඔබව සත්‍යාපනය කළ නොහැක.' @@ -93,7 +86,7 @@ si: signed_up_but_locked: ඔබ සාර්ථකව ලියාපදිංචි වී ඇත. කෙසේ වෙතත්, ඔබගේ ගිණුම අගුලු දමා ඇති නිසා අපට ඔබව පුරනය කිරීමට නොහැකි විය. signed_up_but_pending: තහවුරු කිරීමේ සබැඳියක් සහිත පණිවිඩයක් ඔබගේ විද්‍යුත් තැපැල් ලිපිනයට යවා ඇත. ඔබ සබැඳිය ක්ලික් කළ පසු, අපි ඔබගේ අයදුම්පත සමාලෝචනය කරන්නෙමු. එය අනුමත වුවහොත් ඔබට දැනුම් දෙනු ලැබේ. signed_up_but_unconfirmed: තහවුරු කිරීමේ සබැඳියක් සහිත පණිවිඩයක් ඔබගේ විද්‍යුත් තැපැල් ලිපිනයට යවා ඇත. ඔබගේ ගිණුම සක්‍රිය කිරීමට කරුණාකර සබැඳිය අනුගමනය කරන්න. ඔබට මෙම විද්‍යුත් තැපෑල නොලැබුනේ නම් කරුණාකර ඔබගේ අයාචිත තැපැල් ෆෝල්ඩරය පරීක්ෂා කරන්න. - update_needs_confirmation: ඔබගේ ගිණුම සාර්ථකව යාවත්කාලීන වුවද අපට නව වි-තැපැල් ලිපිනය තහවුරු කර ගැනීමට වුවමනා කෙරේ. කරුණාකර ඔබගේ වි-තැපෑල පරීක්‍ෂා කර ඊට අදාළ සබැඳිය අනුගමනය කර ඔබගේ නව වි-තැපැල් ලිපිනය තහවුරු කරන්න. ඔබට මෙම වි-තැපෑල නොලැබුණේ නම් කරුණාකර අයාචිත තැපැල් බහාලුම බලන්න. + update_needs_confirmation: ඔබගේ ගිණුම සාර්ථකව යාවත්කාලීන වුවද අපට නව වි-තැපැල් ලිපිනය සත්‍යාපනය කර ගැනීමට වුවමනා කෙරේ. කරුණාකර ඔබගේ වි-තැපෑල පරීක්‍ෂා කර ඊට අදාළ සබැඳිය අනුගමනය කර ඔබගේ නව වි-තැපැල් ලිපිනය තහවුරු කරන්න. ඔබට මෙම වි-තැපෑල නොලැබුණේ නම් කරුණාකර අයාචිත තැපැල් බහාලුම බලන්න. updated: ඔබගේ ගිණුම සාර්ථකව යාවත්කාලීන කර ඇත. sessions: already_signed_out: සාර්ථකව නික්මිණි. @@ -108,8 +101,7 @@ si: already_confirmed: දැනටමත් තහවුරු කර ඇත, කරුණාකර පුරනය වීමට උත්සාහ කරන්න confirmation_period_expired: "%{period}තුළ තහවුරු කළ යුතුය, කරුණාකර අලුත් එකක් ඉල්ලන්න" expired: කල් ඉකුත් වී ඇත, කරුණාකර අලුත් එකක් ඉල්ලන්න - not_found: හමු වුණේ නැහැ - not_locked: අගුලු දමා නොතිබුණි + not_found: හමු නොවිණි not_saved: one: '1 දෝෂයක් මෙම %{resource} සුරැකීම තහනම් කර ඇත:' other: 'දෝෂ %{count} කින් මෙම %{resource} සුරැකීම තහනම් කර ඇත:' diff --git a/config/locales/devise.sr-Latn.yml b/config/locales/devise.sr-Latn.yml index 836f83a9a5..6b4a5801c6 100644 --- a/config/locales/devise.sr-Latn.yml +++ b/config/locales/devise.sr-Latn.yml @@ -18,13 +18,13 @@ sr-Latn: unconfirmed: Pre nastavka morate potvrditi svoj nalog. mailer: confirmation_instructions: - action: Potvrdite adresu e-pošte + action: Verifikujte adresu e-pošte action_with_app: Potvrdi i vrati se na %{app} explanation: Napravili ste nalog na %{host} sa adresom ove e-pošte. Na jedan klik ste udaljeni od aktiviranja. Ako ovo niste vi, molimo ignorišite ovu e-poštu. explanation_when_pending: Prijavili ste se za poziv %{host} sa ovim imejlom. Kada potvrdite svoj imejl, pregledaćemo vašu prijavu. Možete se prijaviti da biste promenili detalje ili izbrisali nalog, ali ne možete pristupiti većini funkcija dok vam nalog ne bude odobren. Ako vaša prijava bude odbijena, vaši podaci će biti uklonjeni, tako da od vas neće biti potrebne dalje radnje. Ako ovo niste bili vi, zanemarite ovaj imejl. extra_html: Molimo da takođe proverite pravila ove instance i naše uslove korišćenja. subject: 'Mastodont: Uputstvo za potvrdu korisničkog naloga na instanci %{instance}' - title: Potvrdite adresu e-pošte + title: Verifikujte adresu e-pošte email_changed: explanation: 'Adresa ove e-pošte za vaš nalog će biti promenjena u:' extra: Ako niste promenili vašu e-poštu, sasvim je moguće da je neko drugi dobio pristup vašem nalogu. Molimo promenite lozinku odmah ili kontaktirajte administratora instance ako ste zaključani izvan vašeg naloga. @@ -39,7 +39,7 @@ sr-Latn: explanation: Potvrdite novu adresu da biste promenili e-poštu. extra: Ako ova promena nije inicirana sa vaše strane, molimo ignorišite ovu e-poštu. Adresa e-pošta za ovaj Mastodon nalog neće biti promenjena dok ne pristupite poveznici/linku iznad. subject: 'Mastodon: Potvrdite e-poštu za %{instance}' - title: Potvrdite adresu e-pošte + title: Verifikujte adresu e-pošte reset_password_instructions: action: Lozinka promenjena explanation: Zatražili ste novu lozinku za vaš nalog. @@ -93,7 +93,7 @@ sr-Latn: signed_up_but_locked: Uspešno ste se registrovali. Nažalost ne možete se prijaviti zato što je Vaš nalog zaključan. signed_up_but_pending: Na vaš imejl poslata je poruka sa vezom za potvrdu. Nakon što kliknete na vezu, pregledaćemo vašu prijavu. Bićete obavešteni ako bude odobreno. signed_up_but_unconfirmed: Poruka za potvrdu Vašeg naloga je poslata na Vašu imejl adresu. Kliknite na vezu u imejlu da potvrdite svoj nalog. Molimo proverite i spam fasciklu ako niste primili poruku. - update_needs_confirmation: Uspešno ste ažurirali svoj nalog, ali treba da potvrdimo novu adresu Vaše e-pošte. Molimo Vas da proverite e-poštu i pratite link za potvrdu nove adrese Vaše e-pošte. + update_needs_confirmation: Uspešno ste ažurirali svoj nalog, ali moramo da verifikujemo vašu novu adresu e-pošte. Proverite svoju e-poštu i pratite vezu za potvrdu da biste potvrdili novu adresu e-pošte. Proverite svoju fasciklu neželjene pošte ako niste primili ovu e-poštu. updated: Vaš nalog je uspešno ažuriran. sessions: already_signed_out: Uspešno ste se odjavili. diff --git a/config/locales/devise.sr.yml b/config/locales/devise.sr.yml index 12c5869c62..d55cf7a268 100644 --- a/config/locales/devise.sr.yml +++ b/config/locales/devise.sr.yml @@ -12,39 +12,39 @@ sr: last_attempt: Имате још један покушај пре него што Ваш налог буде закључан. locked: Ваш налог је закључан. not_found_in_database: Неисправна %{authentication_keys} или лозинка. - pending: Ваш рачун је још увек у прегледу. - timeout: Време трајања Ваше сесије је истекло. За наставак пријавите се поново. - unauthenticated: За наставак се морате пријавити или регистровати. + pending: Ваш налог се још увек прегледа. + timeout: Ваша сесија је истекла. Пријавите се поново да бисте наставили. + unauthenticated: Морате да се пријавите или региструјете пре него што наставите. unconfirmed: Пре наставка морате потврдити свој налог. mailer: confirmation_instructions: - action: Потврдите адресу е-поште + action: Верификујте адресу е-поште action_with_app: Потврди и врати се на %{app} explanation: Направили сте налог на %{host} са адресом ове е-поште. На један клик сте удаљени од активирања. Ако ово нисте ви, молимо игноришите ову е-пошту. explanation_when_pending: Пријавили сте се за позив %{host} са овим имејлом. Када потврдите свој имејл, прегледаћемо вашу пријаву. Можете се пријавити да бисте променили детаље или избрисали налог, али не можете приступити већини функција док вам налог не буде одобрен. Ако ваша пријава буде одбијена, ваши подаци ће бити уклоњени, тако да од вас неће бити потребне даље радње. Ако ово нисте били ви, занемарите овај имејл. extra_html: Молимо да такође проверите правила ове инстанце и наше услове коришћења. - subject: 'Мастодонт: Упутство за потврду корисничког налога на инстанци %{instance}' - title: Потврдите адресу е-поште + subject: 'Mastodon: Упутство за потврду корисничког налога на инстанци %{instance}' + title: Верификујте адресу е-поште email_changed: explanation: 'Адреса ове е-поште за ваш налог ће бити промењена у:' extra: Ако нисте променили вашу е-пошту, сасвим је могуће да је неко други добио приступ вашем налогу. Молимо промените лозинку одмах или контактирајте администратора инстанце ако сте закључани изван вашег налога. - subject: 'Мастодон: Е-пошта промењена' + subject: 'Mastodon: Е-пошта промењена' title: Нова адреса е-поште password_change: explanation: Лозинка вашег налога је промењена. extra: Ако нисте променили вашу е-пошту, сасвим је могуће да је неко други добио приступ вашем налогу. Молимо промените лозинку одмах или контактирајте администратора инстанце ако сте закључани изван вашег налога. - subject: 'Мастодонт: Лозинка промењена' + subject: 'Mastodon: Лозинка промењена' title: Лозинка промењена reconfirmation_instructions: explanation: Потврдите нову адресу да бисте променили е-пошту. - extra: Ако ова промена није иницирана са ваше стране, молимо игноришите ову е-пошту. Адреса е-пошта за овај Мастодон налог неће бити промењена док не приступите повезници/линку изнад. - subject: 'Мастодон: Потврдите е-пошту за %{instance}' - title: Потврдите адресу е-поште + extra: Ако ова промена није иницирана са ваше стране, молимо игноришите ову е-пошту. Адреса е-поште за овај Mastodon налог неће бити промењена док не приступите вези изнад. + subject: 'Mastodon: Потврдите е-пошту за %{instance}' + title: Верификујте адресу е-поште reset_password_instructions: action: Лозинка промењена explanation: Затражили сте нову лозинку за ваш налог. extra: Ако нисте затражили ово, молимо игноришите ову е-пошту. Ваша лозинка неће бити промењена док не приступите повезници/вези изнад и не направите нову. - subject: 'Мастодонт: Упутство за ресетовање лозинке' + subject: 'Mastodon: Упутство за ресетовање лозинке' title: Лозинка ресетована two_factor_disabled: explanation: Двофакторска аутентификација за ваш налог је онемогућена. Пријава је сада могућа само помоћу имејла и лозинке. @@ -59,7 +59,7 @@ sr: subject: 'Mastodon: Поново су генерисани кодови за опоравак' title: 2FA кодови опоравка промењени unlock_instructions: - subject: 'Мастодонт: Упутство за откључавање корисничког налога' + subject: 'Mastodon: Упутство за откључавање корисничког налога' webauthn_credential: added: explanation: Следећи безбедносни кључ је додат на ваш налог @@ -93,7 +93,7 @@ sr: signed_up_but_locked: Успешно сте се регистровали. Нажалост не можете се пријавити зато што је Ваш налог закључан. signed_up_but_pending: На ваш имејл послата је порука са везом за потврду. Након што кликнете на везу, прегледаћемо вашу пријаву. Бићете обавештени ако буде одобрено. signed_up_but_unconfirmed: Порука за потврду Вашег налога је послата на Вашу имејл адресу. Кликните на везу у имејлу да потврдите свој налог. Молимо проверите и спам фасциклу ако нисте примили поруку. - update_needs_confirmation: Uспешно сте ажурирали свој налог, али треба да потврдимо нову адресу Ваше е-поште. Молимо Вас да проверите е-пошту и пратите линк за потврду нове адресе Ваше е-поште. + update_needs_confirmation: Успешно сте ажурирали свој налог, али морамо да верификујемо вашу нову адресу е-поште. Проверите своју е-пошту и пратите везу за потврду да бисте потврдили нову адресу е-поште. Проверите своју фасциклу нежељене поште ако нисте примили ову е-пошту. updated: Ваш налог је успешно ажуриран. sessions: already_signed_out: Успешно сте се одјавили. @@ -102,7 +102,7 @@ sr: unlocks: send_instructions: У року од неколико минута примићете имејл са упутством за откључавање Вашег налога. Молимо проверите и спам фасциклу ако нисте примили поруку. send_paranoid_instructions: колико се адреса Ваше е-поште налази у нашој бази, у року од неколико минута примићете поруку са упутством како да откључате Ваш налог. Молимо проверите и спам фасциклу ако нисте примили поруку. - unlocked: Ваш налог је успешно откључан. Молимо Вас да се пријавите да бисте наставили. + unlocked: Ваш налог је успешно откључан. Пријавите се да бисте наставили. errors: messages: already_confirmed: је већ потврђен, молимо Вас да се пријавите diff --git a/config/locales/devise.th.yml b/config/locales/devise.th.yml index 6717019a0b..dce498525f 100644 --- a/config/locales/devise.th.yml +++ b/config/locales/devise.th.yml @@ -9,12 +9,12 @@ th: already_authenticated: คุณได้ลงชื่อเข้าอยู่แล้ว inactive: ยังไม่ได้เปิดใช้งานบัญชีของคุณ invalid: "%{authentication_keys} หรือรหัสผ่านไม่ถูกต้อง" - last_attempt: คุณลองได้อีกหนึ่งครั้งก่อนที่บัญชีของคุณจะถูกล็อค - locked: บัญชีของคุณถูกล็อค + last_attempt: คุณลองได้อีกหนึ่งครั้งก่อนที่จะมีการล็อคบัญชีของคุณ + locked: มีการล็อคบัญชีของคุณอยู่ not_found_in_database: "%{authentication_keys} หรือรหัสผ่านไม่ถูกต้อง" pending: บัญชีของคุณยังคงอยู่ระหว่างการตรวจทาน - timeout: เซสชันของคุณหมดอายุแล้ว โปรดลงชื่อเข้าอีกครั้งเพื่อดำเนินการต่อ - unauthenticated: คุณจำเป็นต้องลงชื่อเข้าหรือลงทะเบียนก่อนดำเนินการต่อ + timeout: เซสชันของคุณหมดอายุแล้ว โปรดเข้าสู่ระบบอีกครั้งเพื่อดำเนินการต่อ + unauthenticated: คุณจำเป็นต้องเข้าสู่ระบบหรือลงทะเบียนก่อนดำเนินการต่อ unconfirmed: คุณต้องยืนยันที่อยู่อีเมลของคุณก่อนดำเนินการต่อ mailer: confirmation_instructions: @@ -27,12 +27,12 @@ th: title: ยืนยันที่อยู่อีเมล email_changed: explanation: 'กำลังเปลี่ยนที่อยู่อีเมลสำหรับบัญชีของคุณเป็น:' - extra: หากคุณไม่ได้เปลี่ยนอีเมลของคุณ อาจเป็นไปได้ว่ามีใครสักคนได้รับสิทธิเข้าถึงบัญชีของคุณ โปรดเปลี่ยนรหัสผ่านของคุณทันทีหรือติดต่อผู้ดูแลเซิร์ฟเวอร์หากคุณถูกล็อคออกจากบัญชีของคุณ + extra: หากคุณไม่ได้เปลี่ยนอีเมลของคุณ มีแนวโน้มว่าใครสักคนได้รับสิทธิเข้าถึงบัญชีของคุณ โปรดเปลี่ยนรหัสผ่านของคุณทันทีหรือติดต่อผู้ดูแลเซิร์ฟเวอร์หากมีการล็อคคุณออกจากบัญชีของคุณ subject: 'Mastodon: เปลี่ยนอีเมลแล้ว' title: ที่อยู่อีเมลใหม่ password_change: explanation: เปลี่ยนรหัสผ่านสำหรับบัญชีของคุณแล้ว - extra: หากคุณไม่ได้เปลี่ยนรหัสผ่านของคุณ อาจเป็นไปได้ว่ามีใครสักคนได้รับสิทธิเข้าถึงบัญชีของคุณ โปรดเปลี่ยนรหัสผ่านของคุณทันทีหรือติดต่อผู้ดูแลเซิร์ฟเวอร์หากคุณถูกล็อคออกจากบัญชีของคุณ + extra: หากคุณไม่ได้เปลี่ยนรหัสผ่านของคุณ มีแนวโน้มว่าใครสักคนได้รับสิทธิเข้าถึงบัญชีของคุณ โปรดเปลี่ยนรหัสผ่านของคุณทันทีหรือติดต่อผู้ดูแลเซิร์ฟเวอร์หากมีการล็อคคุณออกจากบัญชีของคุณ subject: 'Mastodon: เปลี่ยนรหัสผ่านแล้ว' title: เปลี่ยนรหัสผ่านแล้ว reconfirmation_instructions: @@ -70,7 +70,7 @@ th: subject: 'Mastodon: ลบกุญแจความปลอดภัยแล้ว' title: ลบหนึ่งในกุญแจความปลอดภัยของคุณแล้ว webauthn_disabled: - explanation: ปิดใช้งานการรับรองความถูกต้องด้วยกุญแจความปลอดภัยสำหรับบัญชีของคุณแล้ว ตอนนี้สามารถเข้าสู่ระบบได้โดยใช้โทเคนที่สร้างโดยแอป TOTP ที่จับคู่เท่านั้น + explanation: ปิดใช้งานการรับรองความถูกต้องด้วยกุญแจความปลอดภัยสำหรับบัญชีของคุณแล้ว ตอนนี้สามารถเข้าสู่ระบบได้โดยใช้เพียงโทเคนที่สร้างโดยแอป TOTP ที่จับคู่เท่านั้น subject: 'Mastodon: ปิดใช้งานการรับรองความถูกต้องด้วยกุญแจความปลอดภัยแล้ว' title: ปิดใช้งานกุญแจความปลอดภัยแล้ว webauthn_enabled: @@ -91,9 +91,9 @@ th: signed_up: ยินดีต้อนรับ! คุณได้ลงทะเบียนสำเร็จ signed_up_but_inactive: คุณได้ลงทะเบียนสำเร็จ อย่างไรก็ตาม เราไม่สามารถลงชื่อคุณเข้าได้เนื่องจากยังไม่ได้เปิดใช้งานบัญชีของคุณ signed_up_but_locked: คุณได้ลงทะเบียนสำเร็จ อย่างไรก็ตาม เราไม่สามารถลงชื่อคุณเข้าได้เนื่องจากมีการล็อคบัญชีของคุณอยู่ - signed_up_but_pending: ส่งข้อความพร้อมลิงก์ยืนยันไปยังที่อยู่อีเมลของคุณแล้ว หลังจากคุณคลิกลิงก์ เราจะตรวจทานใบสมัครของคุณ คุณจะได้รับการแจ้งเตือนหากมีการอนุมัติใบสมัคร - signed_up_but_unconfirmed: ส่งข้อความพร้อมลิงก์ยืนยันไปยังที่อยู่อีเมลของคุณแล้ว โปรดไปตามลิงก์เพื่อเปิดใช้งานบัญชีของคุณ โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ - update_needs_confirmation: คุณได้อัปเดตบัญชีของคุณสำเร็จ แต่เราจำเป็นต้องยืนยันที่อยู่อีเมลใหม่ของคุณ โปรดตรวจสอบอีเมลของคุณแล้วไปตามลิงก์ยืนยันเพื่อยืนยันที่อยู่อีเมลใหม่ของคุณ โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ + signed_up_but_pending: ส่งข้อความพร้อมลิงก์การยืนยันไปยังที่อยู่อีเมลของคุณแล้ว หลังจากคุณคลิกลิงก์ เราจะตรวจทานใบสมัครของคุณ คุณจะได้รับการแจ้งเตือนหากมีการอนุมัติใบสมัคร + signed_up_but_unconfirmed: ส่งข้อความพร้อมลิงก์การยืนยันไปยังที่อยู่อีเมลของคุณแล้ว โปรดไปตามลิงก์เพื่อเปิดใช้งานบัญชีของคุณ โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ + update_needs_confirmation: คุณได้อัปเดตบัญชีของคุณสำเร็จ แต่เราจำเป็นต้องยืนยันที่อยู่อีเมลใหม่ของคุณ โปรดตรวจสอบอีเมลของคุณและไปตามลิงก์การยืนยันเพื่อยืนยันที่อยู่อีเมลใหม่ของคุณ โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ updated: อัปเดตบัญชีของคุณสำเร็จ sessions: already_signed_out: ลงชื่อออกสำเร็จ @@ -102,7 +102,7 @@ th: unlocks: send_instructions: คุณจะได้รับอีเมลพร้อมคำแนะนำวิธีการปลดล็อคบัญชีของคุณในไม่กี่นาที โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ send_paranoid_instructions: หากมีบัญชีของคุณอยู่ คุณจะได้รับอีเมลพร้อมคำแนะนำวิธีการปลดล็อคบัญชีในไม่กี่นาที โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ - unlocked: ปลดล็อคบัญชีของคุณสำเร็จ โปรดลงชื่อเข้าเพื่อดำเนินการต่อ + unlocked: ปลดล็อคบัญชีของคุณสำเร็จ โปรดเข้าสู่ระบบเพื่อดำเนินการต่อ errors: messages: already_confirmed: ได้รับการยืนยันไปแล้ว โปรดลองลงชื่อเข้า diff --git a/config/locales/devise.tt.yml b/config/locales/devise.tt.yml index 3b73d0fab9..8757bcc033 100644 --- a/config/locales/devise.tt.yml +++ b/config/locales/devise.tt.yml @@ -7,9 +7,21 @@ tt: reset_password_instructions: action: Серсүзне үзгәртү title: Серсүзне алыштыру + two_factor_enabled: + title: 2FA кабызылды webauthn_credential: deleted: subject: 'Mastodon: Иминлек ачкычы бетерелгән' + passwords: + updated: Серсүзегез уңышлы үзгәртелде. Сез хәзер кердегез. + updated_not_active: Серсүзегез уңышлы үзгәртелде. + registrations: + signed_up: Рәхим итегез! Сез уңышлы теркәлдегез. + updated: Хисабыгыз уңышлы яңартылды. + sessions: + already_signed_out: Уңышлы чыккансыз. + signed_in: Уңышлы кердегез. + signed_out: Уңышлы чыккансыз. errors: messages: not_found: табылмады diff --git a/config/locales/devise.uk.yml b/config/locales/devise.uk.yml index 50e592a96c..bb81a2a1b8 100644 --- a/config/locales/devise.uk.yml +++ b/config/locales/devise.uk.yml @@ -13,8 +13,8 @@ uk: locked: Ваш обліковий запис заблоковано. not_found_in_database: Неправильний %{authentication_keys} або пароль. pending: Ваш обліковий запис ще перебуває на розгляді. - timeout: Ваша сесія вичерпана. Будь ласка, зайдіть знову, щоб продовжити. - unauthenticated: Для продовження Вам потрібно увійти або зареєструватися. + timeout: Час сеансу минув. Будь ласка, увійдіть знову, щоб продовжити. + unauthenticated: Щоб продовжити, увійдіть або зареєструйтеся. unconfirmed: Для продовження Вам потрібно підтвердити Вашу поштову скриньку. mailer: confirmation_instructions: diff --git a/config/locales/devise.vi.yml b/config/locales/devise.vi.yml index 2139daca75..904cc51fe9 100644 --- a/config/locales/devise.vi.yml +++ b/config/locales/devise.vi.yml @@ -14,7 +14,7 @@ vi: not_found_in_database: "%{authentication_keys} không có trong dữ liệu." pending: Tài khoản của bạn vẫn đang được xem xét. timeout: Phiên của bạn đã hết hạn. Vui lòng đăng nhập lại để tiếp tục. - unauthenticated: Bạn cần đăng nhập hoặc đăng ký trước khi tiếp tục. + unauthenticated: Bạn cần đăng nhập để tiếp tục. unconfirmed: Bạn phải xác minh địa chỉ email trước khi tiếp tục. mailer: confirmation_instructions: diff --git a/config/locales/devise.zh-CN.yml b/config/locales/devise.zh-CN.yml index 4a47dddec4..5a3dbff7e4 100644 --- a/config/locales/devise.zh-CN.yml +++ b/config/locales/devise.zh-CN.yml @@ -44,20 +44,20 @@ zh-CN: action: 更改密码 explanation: 点击下面的链接来更改账户的密码。 extra: 如果你并没有请求本次变更,请忽略此邮件。你的密码只有在你点击上面的链接并输入新密码后才会更改。 - subject: Mastodon:重置密码信息 + subject: Mastodon:重置密码说明 title: 重置密码 two_factor_disabled: - explanation: 账号的双重认证已禁用。现在仅使用邮箱和密码即可登录。 - subject: Mastodon:双重认证已禁用。 - title: 双重认证已禁用 + explanation: 账号的双因素认证已禁用。现在仅使用邮箱和密码即可登录。 + subject: Mastodon:双因素认证已禁用 + title: 双因素认证已停用 two_factor_enabled: - explanation: 账号双重认证已启用。登录时将需要来自已配对的 TOTP 应用生成的验证码。 - subject: Mastodon:双重验证已开启 - title: 已启用双重认证 + explanation: 账号双因素认证已启用。登录时将需要来自已配对的 TOTP 应用生成的验证码。 + subject: Mastodon:双因素认证已启用 + title: 双因素认证已启用 two_factor_recovery_codes_changed: explanation: 新恢复码已生成,同时旧恢复码已失效。 - subject: Mastodon:重新生成双重认证的恢复码 - title: 双重认证的恢复码已更改 + subject: Mastodon:双因素认证恢复码已重新生成 + title: 双因素认证恢复码已更改 unlock_instructions: subject: Mastodon:账户解锁信息 webauthn_credential: @@ -96,9 +96,9 @@ zh-CN: update_needs_confirmation: 账号信息更新成功,但我们需要验证你的新电子邮件地址,请点击邮件中的链接以确认。如果没有收到邮件,请检查你的垃圾邮箱。 updated: 账户资料更新成功。 sessions: - already_signed_out: 已成功登出。 + already_signed_out: 已成功退出登录。 signed_in: 已成功登录。 - signed_out: 已成功登出。 + signed_out: 已成功退出登录。 unlocks: send_instructions: 几分钟后,你将收到一封解锁账户的邮件。如果没有,请检查你的垃圾邮箱。 send_paranoid_instructions: 如果你的账号存在,你将会在几分钟内收到一封指引你如何解锁账号的邮件。如果你没有收到这封邮件,请检查你邮箱的垃圾箱。 diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml index e500e1d9e8..ea1813e413 100644 --- a/config/locales/devise.zh-TW.yml +++ b/config/locales/devise.zh-TW.yml @@ -21,7 +21,7 @@ zh-TW: action: 驗證電子郵件地址 action_with_app: 確認並返回 %{app} explanation: 您已經在 %{host} 上以此電子郵件地址建立了一支帳號。您距離啟用它只剩一點之遙了。若這不是您,請忽略此信件。 - explanation_when_pending: 您使用此電子郵件地址申請了 %{host} 的邀請。當您確認電子郵件信箱後我們將審核您的申請。您可以登入以改變您的細節或刪除您的帳號,但直到您的帳號被核准之前,您無法操作大部分的功能。若您的申請遭拒絕,您的資料將被移除而不必做後續動作。如果這不是您,請忽略此信件。 + explanation_when_pending: 您使用此電子郵件地址申請了 %{host} 的邀請。當您確認電子郵件地址後我們將審核您的申請。您可以在登入後變更詳細資訊或刪除您的帳號,但直到您的帳號被核准之前,您無法操作大部分的功能。若您的申請遭拒絕,您的資料將被移除而不必做後續動作。如果這不是您本人,請忽略此郵件。 extra_html: 同時也請看看伺服器規則服務條款。 subject: Mastodon:%{instance} 確認說明 title: 驗證電子郵件地址 @@ -49,15 +49,15 @@ zh-TW: two_factor_disabled: explanation: 您帳號的兩階段驗證已停用。現在只使用電子郵件及密碼登入。 subject: Mastodon:已停用兩階段驗證 - title: 已停用 2FA + title: 已停用兩階段驗證 two_factor_enabled: explanation: 已對您的帳號啟用兩階段驗證。登入時將需要已配對的 TOTP 應用程式所產生之 Token。 subject: Mastodon:已啟用兩階段驗證 - title: 已啟用 2FA + title: 已啟用兩階段驗證 two_factor_recovery_codes_changed: explanation: 之前的備用驗證碼已經失效,且已產生新的。 subject: Mastodon:兩階段驗證備用驗證碼已經重新產生 - title: 2FA 備用驗證碼已變更 + title: 兩階段驗證備用驗證碼已變更 unlock_instructions: subject: Mastodon:解鎖指引 webauthn_credential: @@ -82,8 +82,8 @@ zh-TW: success: 成功透過 %{kind} 帳號登入。 passwords: no_token: 您必須透過密碼重設信件才能存取此頁面。若確實如此,請確定輸入的網址是完整的。 - send_instructions: 若電子郵件地址存在於我們的資料庫,幾分鐘後您將在信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 - send_paranoid_instructions: 若電子郵件地址存在於我們的資料庫,幾分鐘後您將在信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 + send_instructions: 若電子郵件地址存在於我們的資料庫,幾分鐘後您將於信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 + send_paranoid_instructions: 若電子郵件地址存在於我們的資料庫,幾分鐘後您將於信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 updated: 您的密碼已成功變更,現在已經登入。 updated_not_active: 您的密碼已成功變更。 registrations: @@ -101,8 +101,8 @@ zh-TW: signed_out: 已成功登出。 unlocks: send_instructions: 幾分鐘後您將收到解鎖帳號的指引信件。若未收到請檢查垃圾郵件資料夾。 - send_paranoid_instructions: 若此帳號存在,您將在幾分鐘後收到解鎖指引信件。若未收到請檢查垃圾郵件資料夾。 - unlocked: 已解鎖您的帳號,請登入繼續。 + send_paranoid_instructions: 若此帳號存在,您將於幾分鐘後收到解鎖指引信件。若未收到請檢查垃圾郵件資料夾。 + unlocked: 已解鎖您的帳號,請登入以繼續。 errors: messages: already_confirmed: 已經確認,請嘗試登入 diff --git a/config/locales/doorkeeper.af.yml b/config/locales/doorkeeper.af.yml index a513a6a450..504c7f507e 100644 --- a/config/locales/doorkeeper.af.yml +++ b/config/locales/doorkeeper.af.yml @@ -107,7 +107,6 @@ af: bookmarks: Boekmerke conversations: Gesprekke crypto: End-tot-end-enkripsie - favourites: Gunstelinge filters: Filters lists: Lyste media: Media-aanhegsels @@ -138,7 +137,6 @@ af: read:accounts: sien rekeninginligting read:blocks: sien jou blokkerings read:bookmarks: sien jou boekmerke - read:favourites: sien jou gunstelinge read:filters: sien jou filters read:lists: sien jou lyste read:mutes: sien jou uitdowings @@ -151,7 +149,6 @@ af: write:blocks: blokkeer rekeninge en domeine write:bookmarks: laat ’n boekmerk by plasings write:conversations: doof en wis gesprekke uit - write:favourites: merk gunstelingplasings write:filters: skep filters write:follows: volg mense write:lists: skep lyste diff --git a/config/locales/doorkeeper.an.yml b/config/locales/doorkeeper.an.yml index 127366d1c6..1096d8c8dc 100644 --- a/config/locales/doorkeeper.an.yml +++ b/config/locales/doorkeeper.an.yml @@ -127,7 +127,6 @@ an: bookmarks: Marcadors conversations: Conversacions crypto: Zifrau de cabo a cabo - favourites: Favoritos filters: Filtros follow: Seguius, silenciaus y blocaus follows: Seguius @@ -170,7 +169,6 @@ an: read:accounts: veyer información de cuentas read:blocks: veyer a quí has blocau read:bookmarks: veyer los tuyos marcadors - read:favourites: veyer los tuyos favoritos read:filters: veyer los tuyos filtros read:follows: veyer a quí sigues read:lists: veyer las tuyas listas @@ -184,7 +182,6 @@ an: write:blocks: blocar cuentas y dominios write:bookmarks: alzar estaus como marcadors write:conversations: silenciar y eliminar conversacions - write:favourites: publicacions favoritas write:filters: creyar filtros write:follows: seguir usuarios write:lists: creyar listas diff --git a/config/locales/doorkeeper.ar.yml b/config/locales/doorkeeper.ar.yml index 861a63eb4d..889c182a3f 100644 --- a/config/locales/doorkeeper.ar.yml +++ b/config/locales/doorkeeper.ar.yml @@ -3,10 +3,10 @@ ar: activerecord: attributes: doorkeeper/application: - name: التسمية + name: اسم التطبيق redirect_uri: عنوان التحويل scopes: المجالات - website: تطبيق الويب + website: موقع ويب التطبيق errors: models: doorkeeper/application: @@ -19,30 +19,30 @@ ar: doorkeeper: applications: buttons: - authorize: ترخيص + authorize: تخويل cancel: إلغاء destroy: إبطال edit: تعديل submit: إرسال confirmations: - destroy: متأكد ؟ + destroy: هل أنت متأكد؟ edit: title: تعديل التطبيق form: - error: عفوا! تحقق من خُلوّ الاستمارة من الأخطاء من فضلك + error: عفوا! تحقق من خُلوّ الاستمارة من أخطاء مُحتمَلة من فضلك help: native_redirect_uri: إستخدم %{native_redirect_uri} للاختبار و التجريب محليا redirect_uri: إستخدم خطا واحدا لكل رابط scopes: تقسيم المجالات بمسافات بيضاء. بدون تحديد قيمة يعني ذلك استخدام المجالات الإفتراضية. index: application: تطبيق - callback_url: رابط رد النداء + callback_url: الرابط التشعبي لرد النداء delete: حذف empty: ليس لديك أية تطبيقات. name: التسمية new: تطبيق جديد - scopes: المجالات - show: عرض + scopes: النطاقات + show: إظهار title: تطبيقاتك new: title: تطبيق جديد @@ -122,6 +122,7 @@ ar: admin/accounts: إدارة الحسابات admin/all: جميع المهام الإدارية admin/reports: إدارة التقارير + all: وصول كامل إلى حساب ماستدون الخاص بك blocks: تم حجبها bookmarks: الفواصل المرجعية conversations: المحادثات @@ -176,14 +177,14 @@ ar: read:mutes: رؤية الحسابات التي كَتمتَها read:notifications: رؤية إشعاراتك الخاصة read:reports: رؤية إبلاغاتك - read:search: البحث مكانك + read:search: البحث نيابةً عنك read:statuses: رؤية كافة المنشورات write: تغيير كافة بيانات حسابك write:accounts: تعديل صفحتك التعريفية write:blocks: حجب الحسابات و النطاقات write:bookmarks: الإحتفاظ بالمنشورات في الفواصل المرجعية write:conversations: كتم وحذف المحادثات - write:favourites: الإعجاب بمنشورات + write:favourites: إضافة المنشورات إلى المفضلة write:filters: إنشاء عوامل تصفية write:follows: متابَعة الأشخاص write:lists: إنشاء القوائم diff --git a/config/locales/doorkeeper.ast.yml b/config/locales/doorkeeper.ast.yml index 695f9e4b04..0564e49dac 100644 --- a/config/locales/doorkeeper.ast.yml +++ b/config/locales/doorkeeper.ast.yml @@ -14,6 +14,8 @@ ast: destroy: Destruyir edit: Editar submit: Unviar + confirmations: + destroy: "¿De xuru que quies facer esta aición?" form: error: "¡Meca! Revisa los errores posibles del formulariu" help: @@ -23,6 +25,7 @@ ast: name: Nome new: Aplicación nueva scopes: Ámbitos + title: Les tos aplicaciones new: title: Aplicación nueva show: @@ -45,6 +48,8 @@ ast: authorized_applications: buttons: revoke: Revocar + confirmations: + revoke: "¿De xuru que quies facer esta aición?" index: description_html: Estes son les aplicaciones que puen acceder a la cuenta cola API. Si equí hai aplicaciones que nun conoces o hai dalguna aplicación que nun funciona correutamente, pues revocar el so accesu. never_used: Enxamás s'usó @@ -66,11 +71,21 @@ ast: write: Accesu de namás escritura title: accounts: Cuentes + admin/accounts: Alministración de cuentes admin/all: Toles funciones alministratives + admin/reports: Alministración d'informes + all: Accesu completu a la cuenta de Mastodon + bookmarks: Marcadores conversations: Conversaciones crypto: Cifráu de puntu a puntu filters: Peñeres + lists: Llistes + media: Elementos multimedia + mutes: Perfiles colos avisos desativaos notifications: Avisos + reports: Informes + search: Busca + statuses: Artículos layouts: admin: nav: @@ -82,7 +97,7 @@ ast: admin:write: modifica tolos datos del sirvidor crypto: usa'l cifráu de puntu a puntu follow: modifica les rellaciones de les cuentes - push: receición d'avisos push + push: recibe avisos push read: llee tolos datos de les cuentes read:accounts: mira la información de les cuentes read:blocks: mira les cuentes bloquiaes @@ -97,12 +112,13 @@ ast: write: modifica los datos de les cuentes write:accounts: modifica los perfiles write:blocks: bloquia cuentes ya dominios - write:favourites: artículos favoritos + write:bookmarks: meter artículos en Marcadores + write:conversations: desaniciar ya desactivar los avisos de conversaciones write:filters: crea peñeres write:follows: sigue a perfiles write:lists: crea llistes write:media: xube ficheros multimedia write:mutes: desactiva los avisos de perfiles ya de conversaciones write:notifications: borra los avisos - write:reports: informa d'otres perfiles + write:reports: informa d'otros perfiles write:statuses: espubliza artículos diff --git a/config/locales/doorkeeper.be.yml b/config/locales/doorkeeper.be.yml index 1d0ffda4b2..4524dd707e 100644 --- a/config/locales/doorkeeper.be.yml +++ b/config/locales/doorkeeper.be.yml @@ -127,7 +127,7 @@ be: bookmarks: Закладкі conversations: Размовы crypto: Скразное шыфраванне - favourites: Абраныя + favourites: Упадабанае filters: Фільтры follow: Падпіскі, ігнараванне і блакіроўка follows: Падпіскі @@ -170,7 +170,7 @@ be: read:accounts: бачыць інфармацыю аб уліковых запісах read:blocks: бачыць свае блакіроўкі read:bookmarks: бачыць свае закладкі - read:favourites: Бачыць сваё абранае + read:favourites: бачыць сваё упадабанае read:filters: бачыць свае фільтры read:follows: бачыць свае падпіскі read:lists: бачыць свае спісы @@ -184,7 +184,7 @@ be: write:blocks: блакіраваць уліковыя запісы і дамены write:bookmarks: закладкі допісаў write:conversations: ігнараваць і выдаляць размовы - write:favourites: дадаваць допісы ва ўпадабанае + write:favourites: упадабаныя допісы write:filters: ствараць фільтры write:follows: Сачыць за людзьмі write:lists: ствараць спiсы diff --git a/config/locales/doorkeeper.bg.yml b/config/locales/doorkeeper.bg.yml index ec1f351ee0..8e026794ee 100644 --- a/config/locales/doorkeeper.bg.yml +++ b/config/locales/doorkeeper.bg.yml @@ -164,13 +164,13 @@ bg: admin:write:ip_blocks: извършване на действия за модериране на IP адреси блокирано admin:write:reports: извършване на действия за модериране на докладвания crypto: употреба на цялостно шифроване - follow: промяна на взаимоотношенията с други акаунти + follow: промяна на взаимоотношенията на акаунта push: получаване на вашите изскачащи известия read: четене на всички данни от акаунта ви read:accounts: преглед на информация за акаунти read:blocks: преглед на вашите блокирания read:bookmarks: преглед на вашите отметки - read:favourites: преглед на вашите любими + read:favourites: прегледайте любимите си read:filters: преглед на вашите филтри read:follows: преглед на вашите последвания read:lists: преглед на вашите списъци diff --git a/config/locales/doorkeeper.br.yml b/config/locales/doorkeeper.br.yml index 0a81e03bbe..3de6230d4c 100644 --- a/config/locales/doorkeeper.br.yml +++ b/config/locales/doorkeeper.br.yml @@ -125,7 +125,6 @@ br: read:accounts: gwelout titouroù ar c'hontoù read:blocks: gwelout ar pezh a zo stanket ganeoc'h read:bookmarks: gwelout ho sinedoù - read:favourites: gwelout ho muiañ-karet read:filters: gwelout ho siloù read:follows: gwelout ar pezh a zo heuliet ganeoc'h read:lists: gwelout ho listennoù @@ -137,7 +136,6 @@ br: write:accounts: kemmañ ho profil write:blocks: berzañ kontoù ha domanioù write:bookmarks: toudoù enrollet evel sinedoù - write:favourites: merkañ toudoù evel muiañ-karet write:filters: krouiñ siloù write:follows: heuliañ an dud write:lists: krouiñ listennoù diff --git a/config/locales/doorkeeper.ca.yml b/config/locales/doorkeeper.ca.yml index 93fb071b31..9706f3db70 100644 --- a/config/locales/doorkeeper.ca.yml +++ b/config/locales/doorkeeper.ca.yml @@ -127,7 +127,7 @@ ca: bookmarks: Marcadors conversations: Converses crypto: Xifrat d'extrem a extrem - favourites: Preferits + favourites: Favorits filters: Filtres follow: Seguits, Silenciats i Blocats follows: Seguits @@ -150,11 +150,11 @@ ca: admin:read: llegeix totes les dades en el servidor admin:read:accounts: llegir informació confidencial de tots els comptes admin:read:canonical_email_blocks: llegeix informació sensible de tots els blocs canònics de correu-e - admin:read:domain_allows: llegeix informació sensible de tots els dominis permesos - admin:read:domain_blocks: llegeix informació sensible de tots els blocs de domini - admin:read:email_domain_blocks: llegeix informació sensible de tots els blocs de domini de correu-e - admin:read:ip_blocks: llegeix informació sensible de tots els blocs d'IP - admin:read:reports: llegir informació confidencial de tots els informes i comptes reportats + admin:read:domain_allows: llegeix informació confidencial de tots els dominis permesos + admin:read:domain_blocks: llegeix informació confidencial de tots els blocs de domini + admin:read:email_domain_blocks: llegeix informació confidencial de tots els blocs de domini de correu-e + admin:read:ip_blocks: llegeix informació confidencial de tots els blocs d'IP + admin:read:reports: llegeix informació confidencial de tots els informes i comptes reportats admin:write: modificar totes les dades en el servidor admin:write:accounts: fer l'acció de moderació en els comptes admin:write:canonical_email_blocks: executa accions de moderació en blocs canònics de correu-e @@ -170,7 +170,7 @@ ca: read:accounts: mira informació dels comptes read:blocks: mira els teus bloqueigs read:bookmarks: mira els teus marcadors - read:favourites: mira els teus preferits + read:favourites: mira els teus favorits read:filters: mira els teus filtres read:follows: mira els teus seguiments read:lists: mira les teves llistes @@ -184,7 +184,7 @@ ca: write:blocks: bloca comptes i dominis write:bookmarks: marca tuts write:conversations: silencia i esborra converses - write:favourites: afavoreix tuts + write:favourites: tuts favorits write:filters: crea filtres write:follows: segueix gent write:lists: crea llistes diff --git a/config/locales/doorkeeper.ckb.yml b/config/locales/doorkeeper.ckb.yml index 39b9f65f62..f952b6eca9 100644 --- a/config/locales/doorkeeper.ckb.yml +++ b/config/locales/doorkeeper.ckb.yml @@ -126,7 +126,6 @@ ckb: bookmarks: نیشانەکان conversations: گفتوگۆکان crypto: کۆدکردنی کۆتایی بۆ کۆتایی - favourites: دڵخوازەکان filters: پاڵێوراوەکان follows: بەدواداچووان lists: پێرستەکان @@ -158,7 +157,6 @@ ckb: read:accounts: بینینی زانیاری هەژمارەکان read:blocks: بینینی بلۆکەکانت read:bookmarks: نیشانەکان ببینە - read:favourites: بینینی دڵخوازەکانت read:filters: بینینی پاڵافتنەکانت read:follows: سەیری شوێنکەوتەکانت بکە read:lists: بینینی لیستەکانت @@ -172,7 +170,6 @@ ckb: write:blocks: بلۆک کردنی هەژمارەکەی دۆمەینەکان write:bookmarks: بارەکانی نیشانکەر write:conversations: بێدەنگکردن و سڕینەوەی گفتوگۆکان - write:favourites: دۆخی دڵخوازەکان write:filters: پاڵێوەر دروست بکە write:follows: دوای خەڵک بکەوە write:lists: دروستکردنی لیستەکان diff --git a/config/locales/doorkeeper.co.yml b/config/locales/doorkeeper.co.yml index 78c86d0db9..ae89344abd 100644 --- a/config/locales/doorkeeper.co.yml +++ b/config/locales/doorkeeper.co.yml @@ -124,7 +124,6 @@ co: read:accounts: vede l'infurmazione di i conti read:blocks: vede i vostri blucchimi read:bookmarks: vede i vostri segnalibri - read:favourites: vede i vostri favuriti read:filters: vede i vostri filtri read:follows: vede i vostri abbunamenti read:lists: vede e vostre liste @@ -137,7 +136,6 @@ co: write:accounts: mudificà u prufile write:blocks: bluccà conti è dumini write:bookmarks: segnà statuti - write:favourites: aghjustà statuti à i favuriti write:filters: creà filtri write:follows: siguità conti write:lists: creà liste diff --git a/config/locales/doorkeeper.cs.yml b/config/locales/doorkeeper.cs.yml index b8bb6b8540..ba2100edfd 100644 --- a/config/locales/doorkeeper.cs.yml +++ b/config/locales/doorkeeper.cs.yml @@ -127,7 +127,7 @@ cs: bookmarks: Záložky conversations: Konverzace crypto: End-to-end šifrování - favourites: Oblíbení + favourites: Oblíbené filters: Filtry follow: Sledování, ztlumení a blokování follows: Sledovaní @@ -170,7 +170,7 @@ cs: read:accounts: vidět informace o účtech read:blocks: vidět vaše blokace read:bookmarks: vidět vaše záložky - read:favourites: vidět vaše oblíbené příspěvky + read:favourites: zobrazit vaše oblíbené read:filters: vidět vaše filtry read:follows: vidět vaše sledování read:lists: vidět vaše seznamy @@ -184,7 +184,7 @@ cs: write:blocks: blokovat účty a domény write:bookmarks: přidávat příspěvky do záložek write:conversations: skrývat a mazat konverzace - write:favourites: oblibovat si příspěvky + write:favourites: oblíbené příspěvky write:filters: vytvářet filtry write:follows: sledovat lidi write:lists: vytvářet seznamy diff --git a/config/locales/doorkeeper.csb.yml b/config/locales/doorkeeper.csb.yml deleted file mode 100644 index 0de706e41f..0000000000 --- a/config/locales/doorkeeper.csb.yml +++ /dev/null @@ -1 +0,0 @@ -csb: diff --git a/config/locales/doorkeeper.cy.yml b/config/locales/doorkeeper.cy.yml index f3da378cf3..e79aa0359f 100644 --- a/config/locales/doorkeeper.cy.yml +++ b/config/locales/doorkeeper.cy.yml @@ -124,12 +124,12 @@ cy: admin/reports: Gweinyddu adroddiadau all: Mynediad llawn i'ch cyfrif Mastodon blocks: Blociau - bookmarks: Nodau Tudalen + bookmarks: Llyfrnodau conversations: Sgyrsiau crypto: Amgryptio o ben i ben favourites: Ffefrynnau filters: Hidlyddion - follow: Yn dilyn, Wedi Tewi a Blociau + follow: Dilynion, Anwybyddiadau a Blociau follows: Yn dilyn lists: Rhestrau media: Atodiadau cyfryngau @@ -169,7 +169,7 @@ cy: read: darllen holl ddata eich cyfrif read:accounts: gweld gwybodaeth y cyfrif read:blocks: gweld eich blociau - read:bookmarks: gweld eich nodau tudalen + read:bookmarks: gweld eich llyfrnodau read:favourites: gweld eich ffefrynnau read:filters: gweld eich hidlwyr read:follows: gweld eich dilynwyr @@ -182,7 +182,7 @@ cy: write: addasu holl ddata eich cyfrif write:accounts: addasu eich proffil write:blocks: blocio cyfrifon a parthau - write:bookmarks: gosod nod tudalen postiadau + write:bookmarks: llyfrnodi postiadau write:conversations: anwybyddu a dileu sgyrsiau write:favourites: hoff bostiadau write:filters: creu hidlwyr diff --git a/config/locales/doorkeeper.de.yml b/config/locales/doorkeeper.de.yml index 21f508d90d..cc7b88a282 100644 --- a/config/locales/doorkeeper.de.yml +++ b/config/locales/doorkeeper.de.yml @@ -3,7 +3,7 @@ de: activerecord: attributes: doorkeeper/application: - name: Name der Anwendung + name: Anwendungsname redirect_uri: Weiterleitungs-URI scopes: Befugnisse website: Website der Anwendung @@ -25,14 +25,14 @@ de: edit: Bearbeiten submit: Speichern confirmations: - destroy: Bist du sicher? + destroy: Bist du dir sicher? edit: title: Anwendung bearbeiten form: - error: Hoppla! Bitte überprüfe das Formular auf mögliche Fehler + error: Ups! Bitte überprüfe das Formular auf mögliche Fehler help: - native_redirect_uri: Benutze %{native_redirect_uri} für lokale Tests - redirect_uri: Benutze eine Zeile pro URI + native_redirect_uri: Verwende %{native_redirect_uri} für lokale Tests + redirect_uri: Verwende eine Zeile pro URI scopes: Bitte die Befugnisse mit Leerzeichen trennen. Zur Verwendung der Standardwerte freilassen. index: application: Anwendung @@ -42,7 +42,7 @@ de: name: Name new: Neue Anwendung scopes: Befugnisse - show: Zeigen + show: Anzeigen title: Deine Anwendungen new: title: Neue Anwendung @@ -60,8 +60,8 @@ de: error: title: Ein Fehler ist aufgetreten new: - prompt_html: "%{client_name} möchte auf dein Konto zugreifen. Es ist eine Anwendung von Drittanbietern. Wenn du ihr nicht vertraust, dann solltest du sie nicht autorisieren." - review_permissions: Rechte überprüfen + prompt_html: "%{client_name} möchte auf dein Konto zugreifen. Es handelt sich um eine Software von Dritten. Wenn du der Anwendung nicht vertraust, solltest du ihr keinen Zugriff auf dein Konto geben." + review_permissions: Berechtigungen überprüfen title: Autorisierung erforderlich show: title: Kopiere diesen Autorisierungs-Code und füge ihn in die Anwendung ein. @@ -69,7 +69,7 @@ de: buttons: revoke: Widerrufen confirmations: - revoke: Bist du sicher? + revoke: Bist du dir sicher? index: authorized_at: Autorisiert am %{date} description_html: Dies sind Anwendungen, die über die Programmierschnittstelle (API) auf dein Konto zugreifen können. Wenn es Anwendungen gibt, die du hier nicht zuordnen kannst oder wenn sich eine Anwendung verdächtig verhält, kannst du den Zugriff widerrufen. @@ -77,12 +77,12 @@ de: never_used: Nie verwendet scopes: Berechtigungen superapp: Intern - title: Deine genehmigten Apps + title: Deine autorisierten Anwendungen errors: messages: - access_denied: Die Anfrage wurde durch Benutzer_in oder Autorisierungs-Server verweigert. + access_denied: Diese Anfrage wurde von den Inhaber*innen oder durch den Autorisierungsserver abgelehnt. credential_flow_not_configured: Das Konto konnte nicht gefunden werden, da Doorkeeper.configure.resource_owner_from_credentials nicht konfiguriert ist. - invalid_client: 'Client-Authentifizierung ist fehlgeschlagen: Client unbekannt, keine Authentisierung mitgeliefert oder Authentisierungsmethode wird nicht unterstützt.' + invalid_client: 'Client-Authentisierung ist fehlgeschlagen: Client unbekannt, keine Authentisierung mitgeliefert oder Authentisierungsmethode wird nicht unterstützt.' invalid_grant: Die beigefügte Autorisierung ist ungültig, abgelaufen, wurde widerrufen oder einem anderen Client ausgestellt, oder der Weiterleitungs-URI stimmt nicht mit der Autorisierungs-Anfrage überein. invalid_redirect_uri: Der beigefügte Weiterleitungs-URI ist ungültig. invalid_request: @@ -92,9 +92,9 @@ de: invalid_resource_owner: Die angegebenen Zugangsdaten für das Konto sind ungültig, oder das Konto kann nicht gefunden werden invalid_scope: Die angeforderte Befugnis ist ungültig, unbekannt oder fehlerhaft. invalid_token: - expired: Der Zugriffs-Token ist abgelaufen - revoked: Der Zugriffs-Token wurde widerrufen - unknown: Der Zugriffs-Token ist ungültig + expired: Der Zugriffstoken ist abgelaufen + revoked: Der Zugriffstoken wurde widerrufen + unknown: Der Zugriffstoken ist ungültig resource_owner_authenticator_not_configured: Das Konto konnte nicht gefunden werden, da Doorkeeper.configure.resource_owner_authenticator nicht konfiguriert ist. server_error: Der Autorisierungs-Server hat ein unerwartetes Problem festgestellt und konnte die Anfrage nicht bearbeiten. temporarily_unavailable: Der Autorisierungs-Server ist aufgrund von zwischenzeitlicher Überlastung oder Wartungsarbeiten derzeit nicht in der Lage, die Anfrage zu bearbeiten. @@ -114,14 +114,14 @@ de: notice: Anwendung widerrufen. grouped_scopes: access: - read: Nur-Lese-Zugriff + read: Nur Lesezugriff read/write: Lese- und Schreibzugriff - write: Schreibzugriff + write: Nur Schreibzugriff title: accounts: Konten - admin/accounts: Verwaltung der Konten + admin/accounts: Kontenverwaltung admin/all: Alle administrativen Funktionen - admin/reports: Verwaltung der Berichte + admin/reports: Meldungen verwalten all: Voller Zugriff auf dein Mastodon-Konto blocks: Blockierungen bookmarks: Lesezeichen @@ -167,11 +167,11 @@ de: follow: Kontenbeziehungen verändern push: deine Push-Benachrichtigungen erhalten read: all deine Daten lesen - read:accounts: deine Konteninformationen einsehen - read:blocks: deine Blockaden einsehen + read:accounts: deine Kontoinformationen einsehen + read:blocks: deine Blockierungen einsehen read:bookmarks: deine Lesezeichen lesen - read:favourites: deine Favoriten ansehen - read:filters: deine Filter ansehen + read:favourites: deine Favoriten einsehen + read:filters: deine Filter einsehen read:follows: sehen, wem du folgst read:lists: deine Listen sehen read:mutes: deine Stummschaltungen einsehen @@ -179,17 +179,17 @@ de: read:reports: deine Meldungen sehen read:search: in deinem Namen suchen read:statuses: alle Beiträge sehen - write: all deine Benutzerdaten verändern + write: all deine Kontodaten verändern write:accounts: dein Profil bearbeiten write:blocks: Domains und Konten blockieren write:bookmarks: Lesezeichen hinzufügen write:conversations: Unterhaltungen stummschalten und löschen write:favourites: Beiträge favorisieren write:filters: Filter erstellen - write:follows: Leuten folgen + write:follows: Profilen folgen write:lists: Listen erstellen write:media: Mediendateien hochladen write:mutes: Profile und Unterhaltungen stummschalten - write:notifications: deine Benachrichtigungen leeren - write:reports: andere Leute melden + write:notifications: deine Benachrichtigungen löschen + write:reports: andere Profile melden write:statuses: Beiträge veröffentlichen diff --git a/config/locales/doorkeeper.el.yml b/config/locales/doorkeeper.el.yml index 8084bb5b3c..b275af3365 100644 --- a/config/locales/doorkeeper.el.yml +++ b/config/locales/doorkeeper.el.yml @@ -60,6 +60,8 @@ el: error: title: Εμφανίστηκε σφάλμα new: + prompt_html: Ο/Η %{client_name} θα ήθελε άδεια πρόσβασης στο λογαριασμό σας. Είναι μια εφαρμογή από τρίτους. Αν δεν το εμπιστεύεστε, τότε δεν πρέπει να το εξουσιοδοτήσετε. + review_permissions: Αναθεώρηση δικαιωμάτων title: Απαιτείται έγκριση show: title: Αντέγραψε αυτό τον κωδικό έγκρισης στην εφαρμογή. @@ -69,8 +71,12 @@ el: confirmations: revoke: Σίγουρα; index: + authorized_at: Εξουσιοδοτήθηκε στις %{date} + description_html: Αυτές είναι εφαρμογές που μπορούν να έχουν πρόσβαση στο λογαριασμό σας χρησιμοποιώντας το API. Αν υπάρχουν εφαρμογές που δεν αναγνωρίζετε εδώ ή μια εφαρμογή δεν συμπεριφέρεται σωστά, μπορείτε να ανακαλέσετε την πρόσβασή της. + last_used_at: Τελευταία χρήση στις %{date} never_used: Ποτέ σε χρήση scopes: Δικαιώματα + superapp: Εσωτερική title: Οι εφαρμογές που έχεις εγκρίνει errors: messages: @@ -117,11 +123,13 @@ el: admin/all: Όλες οι λειτουργίες διαχείρησης admin/reports: Διαχείριση αναφορών all: Πλήρης πρόσβαση στο λογαριασμό σας στο Mastodon + blocks: Αποκλεισμοί bookmarks: Σελιδοδείκτες conversations: Συνομιλίες crypto: Κρυπτογράφηση από άκρο σε άκρο - favourites: Αγαπημένα filters: Φίλτρα + follow: Ακολουθείτε, σε Σίγαση και Αποκλεισμοί + follows: Ακολουθείτε lists: Λίστες media: Συνημμένα πολυμέσα mutes: Αποσιωπήσεις @@ -140,9 +148,19 @@ el: scopes: admin:read: ανάγνωση δεδομένων στον διακομιστή admin:read:accounts: ανάγνωση ευαίσθητων πληροφοριών όλων των λογαριασμών + admin:read:canonical_email_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων email + admin:read:domain_allows: ανάγνωση ευαίσθητων πληροφοριών όλων των επιτρεπόμενων τομέων + admin:read:domain_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων τομέων + admin:read:email_domain_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων τομέων email + admin:read:ip_blocks: ανάγνωση ευαίσθητων πληροφοριών όλων των αποκλεισμένων IP admin:read:reports: ανάγνωση ευαίσθητων πληροφοριών όλων των καταγγελιών και των καταγγελλομένων λογαριασμών admin:write: αλλαγή δεδομένων στον διακομιστή admin:write:accounts: εκτέλεση διαχειριστικών ενεργειών σε λογαριασμούς + admin:write:canonical_email_blocks: εκτέλεση ενεργειών διαχείρισης σε αποκλεισμένα email + admin:write:domain_allows: εκτέλεση ενεργειών διαχείρισης σε επιτρεπτούς τομείς + admin:write:domain_blocks: εκτέλεση ενεργειών διαχείρισης σε αποκλεισμένους τομείς + admin:write:email_domain_blocks: εκτελέστε ενέργειες διαχείρισης σε αποκλεισμένους τομείς email + admin:write:ip_blocks: εκτέλεση ενεργειών διαχείρισης σε αποκλεισμένες IP admin:write:reports: εκτέλεση διαχειριστικών ενεργειών σε καταγγελίες crypto: χρήση κρυπτογράφησης από άκρο σε άκρο follow: να αλλάζει τις σχέσεις με λογαριασμούς @@ -151,7 +169,6 @@ el: read:accounts: να βλέπει τα στοιχεία λογαριασμών read:blocks: να βλέπει τους αποκλεισμένους σου read:bookmarks: εμφάνιση των σελιδοδεικτών σας - read:favourites: να βλέπει τα αγαπημένα σου read:filters: να βλέπει τα φίλτρα σου read:follows: να βλέπει ποιους ακολουθείς read:lists: να βλέπει τις λίστες σου @@ -165,7 +182,6 @@ el: write:blocks: να μπλοκάρει λογαριασμούς και τομείς write:bookmarks: προσθήκη σελιδοδεικτών write:conversations: σίγαση και διαγραφή συνομιλιών - write:favourites: να σημειώνει δημοσιεύσεις ως αγαπημένες write:filters: να δημιουργεί φίλτρα write:follows: να ακολουθεί ανθρώπους write:lists: να δημιουργεί λίστες diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml index a28f91c0e0..0432a5e3fb 100644 --- a/config/locales/doorkeeper.en.yml +++ b/config/locales/doorkeeper.en.yml @@ -127,7 +127,7 @@ en: bookmarks: Bookmarks conversations: Conversations crypto: End-to-end encryption - favourites: Favourites + favourites: Favorites filters: Filters follow: Follows, Mutes and Blocks follows: Follows @@ -170,7 +170,7 @@ en: read:accounts: see accounts information read:blocks: see your blocks read:bookmarks: see your bookmarks - read:favourites: see your favourites + read:favourites: see your favorites read:filters: see your filters read:follows: see your follows read:lists: see your lists @@ -184,7 +184,7 @@ en: write:blocks: block accounts and domains write:bookmarks: bookmark posts write:conversations: mute and delete conversations - write:favourites: favourite posts + write:favourites: favorite posts write:filters: create filters write:follows: follow people write:lists: create lists diff --git a/config/locales/doorkeeper.eo.yml b/config/locales/doorkeeper.eo.yml index 18005fc3ab..8bb61c7a49 100644 --- a/config/locales/doorkeeper.eo.yml +++ b/config/locales/doorkeeper.eo.yml @@ -60,7 +60,7 @@ eo: error: title: Eraro okazis new: - prompt_html: "%{client_name} volas permeso por aliri vian konton. Se vi ne konfidu ĝin, ne rajtigu ĝin." + prompt_html: "%{client_name} petas permeson por aliri vian konton. Se vi ne fidas ĝin, ne rajtigu ĝin." review_permissions: Revizu permesojn title: Rajtigo bezonata show: @@ -127,7 +127,7 @@ eo: bookmarks: Legosignoj conversations: Konversacioj crypto: Fin-al-fina ĉifrado - favourites: Preferaĵoj + favourites: Preferatoj filters: Filtriloj follow: Abonadoj, silentigitaj kontoj kaj blokitaj kontoj follows: Sekvas @@ -170,7 +170,7 @@ eo: read:accounts: vidi la informojn de la kontoj read:blocks: vidi viajn blokadojn read:bookmarks: vidi viajn legosignojn - read:favourites: vidi viajn stelumojn + read:favourites: vidi viajn preferatojn read:filters: vidi viajn filtrilojn read:follows: vidi viajn sekvatojn read:lists: vidi viajn listojn @@ -184,7 +184,7 @@ eo: write:blocks: bloki kontojn kaj domajnojn write:bookmarks: aldoni mesaĝojn al la legosignoj write:conversations: mallautigi kaj forigi babiladojn - write:favourites: stelumi mesaĝojn + write:favourites: preferataj afiŝaj write:filters: krei filtrilojn write:follows: sekvi homojn write:lists: krei listojn diff --git a/config/locales/doorkeeper.es-MX.yml b/config/locales/doorkeeper.es-MX.yml index f6b5e4c5dd..082d656bc5 100644 --- a/config/locales/doorkeeper.es-MX.yml +++ b/config/locales/doorkeeper.es-MX.yml @@ -184,7 +184,7 @@ es-MX: write:blocks: bloquear cuentas y dominios write:bookmarks: guardar estados como marcadores write:conversations: silenciar y eliminar conversaciones - write:favourites: toots favoritos + write:favourites: publicaciones favoritas write:filters: crear filtros write:follows: seguir usuarios write:lists: crear listas diff --git a/config/locales/doorkeeper.es.yml b/config/locales/doorkeeper.es.yml index e8d9d8e93f..002f813b32 100644 --- a/config/locales/doorkeeper.es.yml +++ b/config/locales/doorkeeper.es.yml @@ -129,7 +129,7 @@ es: crypto: Cifrado de extremo a extremo favourites: Favoritos filters: Filtros - follow: Seguimientos, silenciad@s y bloqueos + follow: Seguimientos, silenciados y bloqueos follows: Seguidos lists: Listas media: Adjuntos multimedia @@ -178,13 +178,13 @@ es: read:notifications: ver tus notificaciones read:reports: ver tus informes read:search: buscar en su nombre - read:statuses: ver todos los estados + read:statuses: ver todas las publicaciones write: publicar en tu nombre write:accounts: modifica tu perfil write:blocks: bloquear cuentas y dominios - write:bookmarks: guardar estados como marcadores + write:bookmarks: guardar publicaciones como marcadores write:conversations: silenciar y eliminar conversaciones - write:favourites: publicaciones favoritas + write:favourites: marcar publicaciones como favoritas write:filters: crear filtros write:follows: seguir usuarios write:lists: crear listas @@ -192,4 +192,4 @@ es: write:mutes: silenciar usuarios y conversaciones write:notifications: limpia tus notificaciones write:reports: reportar a otras personas - write:statuses: publicar estados + write:statuses: publicar mensajes diff --git a/config/locales/doorkeeper.et.yml b/config/locales/doorkeeper.et.yml index 0f8ddd2776..1843031706 100644 --- a/config/locales/doorkeeper.et.yml +++ b/config/locales/doorkeeper.et.yml @@ -170,7 +170,7 @@ et: read:accounts: näha konto informatsiooni read:blocks: näha su blokeeringuid read:bookmarks: näha järjehoidjaid - read:favourites: näha Teie lemmikuid + read:favourites: näha sinu lemmikuid read:filters: näha su filtreid read:follows: näha su jälgimisi read:lists: näha su nimekirju diff --git a/config/locales/doorkeeper.eu.yml b/config/locales/doorkeeper.eu.yml index 8d2a9f3b67..9886e034b0 100644 --- a/config/locales/doorkeeper.eu.yml +++ b/config/locales/doorkeeper.eu.yml @@ -80,10 +80,10 @@ eu: title: Zuk baimendutako aplikazioak errors: messages: - access_denied: Baliabidearen jabeak edo baimenaren zerbitzariak eskaria ukatu du. + access_denied: Baliabidearen jabeak edo baimenaren zerbitzariak eskaera ukatu du. credential_flow_not_configured: Baliabidearen jabearen pasahitza kredentzialen fluxuak huts egin du Doorkeeper.configure.resource_owner_from_credentials konfiguratu gabe dagoelako. invalid_client: Bezeroaren autentifikazioak huts egin du bezero ezezaguna delako, ez delako bezero autentifikazioa txertatu, edo autentifikazio metodoa ez delako onartzen. - invalid_grant: Emandako autorizatzea baliogabea da, iraungitu da, indargabetu da. ez dator bat autorizatze eskarian erabilitako URI-arekin, edo beste bezero batek sortu du. + invalid_grant: Emandako baimena baliogabea da, iraungi edo indargabetu da, ez dator bat baimen-eskaeran erabilitako birbideratze URI-arekin edo beste bezero batek sortu du. invalid_redirect_uri: Sartutako birbideratze URI-a baliogabea da. invalid_request: missing_param: 'Beharrezko parametroa falta da: %{value}.' @@ -184,7 +184,7 @@ eu: write:blocks: kontuak eta domeinuak blokeatzea write:bookmarks: mezuen laster-marka write:conversations: mututu eta ezabatu elkarrizketak - write:favourites: gogoko mezuak + write:favourites: gogoko bidalketak write:filters: sortu iragazkiak write:follows: jarraitu jendea write:lists: sortu zerrendak diff --git a/config/locales/doorkeeper.fa.yml b/config/locales/doorkeeper.fa.yml index 36c2ead4a8..c56e76e346 100644 --- a/config/locales/doorkeeper.fa.yml +++ b/config/locales/doorkeeper.fa.yml @@ -64,7 +64,7 @@ fa: review_permissions: بازبینی اجازه‌ها title: نیاز به اجازه دادن show: - title: این کد مجوز را کپی کرده و در برنامه وارد کنید. + title: این کد تأیید را رونوشت کرده و در برنامه بگذارید. authorized_applications: buttons: revoke: فسخ @@ -127,7 +127,7 @@ fa: bookmarks: نشانک‌ها conversations: گفت‌وگوها crypto: رمزگذاری سرتاسری - favourites: پسندیده‌ها + favourites: برگزیده‌ها filters: پالایه‌ها follow: پی‌گیری، خموشی و مسدودی‌ها follows: پی‌گرفتگان @@ -149,9 +149,19 @@ fa: scopes: admin:read: خواندن تمام داده‌ها روی کارساز admin:read:accounts: خواندن اطّلاعات حساس از همهٔ حساب‌ها + admin:read:canonical_email_blocks: خواندن اطّلاعات حسّاس از همهٔ انسدادهای رایانامهٔ متعارف + admin:read:domain_allows: خواندن اطّلاعات حساس از همهٔ دامنه ها اجازه داده شد + admin:read:domain_blocks: خواندن اطّلاعات حساس از همهٔ دامنه های مسدودشده + admin:read:email_domain_blocks: خواندن اطّلاعات حساس از همهٔ دامنه های رایانامه های مسدودشده + admin:read:ip_blocks: خواندن اطّلاعات حساس از همهٔ IPهای مسدودشده admin:read:reports: خواندن اطّلاعات حساس از همهٔ گزارش‌ها و حساب‌های گزارش‌شده admin:write: تغییر تمام داده‌ها روی کارساز admin:write:accounts: انجام کنش مدیریتی روی حساب‌ها + admin:write:canonical_email_blocks: انجام کنش‌های نظارتی روی همهٔ انسدادهای رایانامهٔ متعارف + admin:write:domain_allows: انجام کنش مدیریتی روی اجازه‌های دامنه + admin:write:domain_blocks: انجام کنش مدیریتی روی انسدادهای دامنه + admin:write:email_domain_blocks: انجام کنش مدیریتی روی انسدادهای دامنهٔ رایانامه + admin:write:ip_blocks: انجام کنش مدیریتی روی مسدودسازی های IP admin:write:reports: انجام کنش مدیریتی روی گزارش‌ها crypto: از رمزگذاری سرتاسر استفاده کنید follow: پیگیری، مسدودسازی، لغو مسدودسازی، و لغو پیگیری حساب‌ها @@ -174,7 +184,7 @@ fa: write:blocks: انسداد حساب‌ها و دامنه‌ها write:bookmarks: نشانک‌گذاری وضعیت‌ها write:conversations: مکالمات را بی‌صدا و حذف کنید - write:favourites: برگزیدن وضعیت‌ها + write:favourites: فرسته‌های برگزیده write:filters: ایحاد پالایش‌ها write:follows: پی‌گیری افراد write:lists: ایجاد سیاهه‌ها diff --git a/config/locales/doorkeeper.fi.yml b/config/locales/doorkeeper.fi.yml index e2a81b4e9f..0f263b00d5 100644 --- a/config/locales/doorkeeper.fi.yml +++ b/config/locales/doorkeeper.fi.yml @@ -6,7 +6,7 @@ fi: name: Sovelluksen nimi redirect_uri: Uudelleenohjauksen URI scopes: Oikeudet - website: Sovelluksen verkkosivu + website: Sovelluksen verkkosivusto errors: models: doorkeeper/application: @@ -14,14 +14,14 @@ fi: redirect_uri: fragment_present: ei voi sisältää osia. invalid_uri: on oltava kelvollinen URI. - relative_uri: on oltava täydellinen URI. + relative_uri: on oltava täysi URI. secured_uri: on oltava HTTPS/SSL-URI. doorkeeper: applications: buttons: authorize: Valtuuta cancel: Peruuta - destroy: Tuhoa + destroy: Poista edit: Muokkaa submit: Lähetä confirmations: @@ -29,11 +29,11 @@ fi: edit: title: Muokkaa sovellusta form: - error: Hups! Tarkista, että lomakkeessa ei ole virheitä + error: Hupsis! Tarkista, ettei lomakkeessasi ole virheitä help: native_redirect_uri: Käytä %{native_redirect_uri} paikallisiin testeihin redirect_uri: Lisää jokainen URI omalle rivilleen - scopes: Erota oikeudet välilyönnein. Jos kenttä jätetään tyhjäksi, käytetään oletusoikeuksia. + scopes: Erota oikeudet välilyönneillä. Jätä kenttä tyhjäksi, jos haluat käyttää oletusoikeuksia. index: application: Sovellus callback_url: Takaisinkutsu-URL @@ -48,32 +48,32 @@ fi: title: Uusi sovellus show: actions: Toiminnot - application_id: Asiakasohjelman tunnus + application_id: Ohjelman tunnus callback_urls: Takaisinkutsu-URL:t scopes: Oikeudet - secret: Asiakasohjelman salainen avain + secret: Ohjelman salaisuus title: 'Sovellus: %{name}' authorizations: buttons: authorize: Valtuuta - deny: Evää + deny: Estä error: title: Tapahtui virhe new: - prompt_html: "%{client_name} pyytää lupaa käyttää tiliäsi. Se on kolmannen osapuolen sovellus. Jos et luota siihen, sinun ei pitäisi sallia sitä." + prompt_html: "%{client_name} pyytää lupaa käyttää tiliäsi. Se on kolmannen osapuolen sovellus. Jos et luota siihen, älä valtuuta sitä." review_permissions: Tarkista käyttöoikeudet title: Valtuutus vaaditaan show: title: Kopioi tämä valtuutuskoodi ja liitä se sovellukseen. authorized_applications: buttons: - revoke: Peru + revoke: Hylkää confirmations: revoke: Oletko varma? index: authorized_at: Valtuutettu %{date} - description_html: Nämä ovat sovelluksia, jotka voivat käyttää tiliäsi käyttäen API. Jos et tunnista sitä tai sovellus toimii väärin, voit peruuttaa sen käyttöoikeuden. - last_used_at: Viimeksi käytetty %{date} + description_html: Nämä sovellukset voivat käyttää tiliäsi ohjelmointirajapinnan kautta. Jos tässä on sovelluksia, joita et tunnista, tai sovellus toimii väärin, voit peruuttaa sen käyttöoikeuden. + last_used_at: Käytetty viimeksi %{date} never_used: Ei käytetty scopes: Oikeudet superapp: Sisäinen @@ -81,7 +81,7 @@ fi: errors: messages: access_denied: Resurssin omistaja tai valtuutuspalvelin hylkäsi pyynnön. - credential_flow_not_configured: Resurssin omistajan salasana epäonnistui, koska asetusta Doorkeeper.configure.resource_owner_from_credentials ei ole konfiguroitu. + credential_flow_not_configured: Resurssin omistajan salasanatietojen luku epäonnistui, koska asetusta Doorkeeper.configure.resource_owner_from_credentials ei ole konfiguroitu. invalid_client: Asiakasohjelman valtuutus epäonnistui, koska asiakas on tuntematon, asiakkaan valtuutus ei ollut mukana tai valtuutustapaa ei tueta. invalid_grant: Valtuutuslupa on virheellinen, umpeutunut, peruttu, valtuutuspyynnössä käytettyä uudelleenohjaus-URI:tä vastaamaton tai myönnetty toiselle asiakkaalle. invalid_redirect_uri: Uudelleenohjaus-URI on virheellinen. @@ -111,12 +111,12 @@ fi: notice: Sovellus päivitetty. authorized_applications: destroy: - notice: Sovellus peruttu. + notice: Sovellus poistettu. grouped_scopes: access: - read: Vain luku + read: Vain lukuoikeus read/write: Luku- ja kirjoitusoikeudet - write: Vain kirjoitus + write: Vain kirjoitusoikeus title: accounts: Tilit admin/accounts: Tilien hallinta @@ -135,7 +135,7 @@ fi: media: Medialiitteet mutes: Mykistykset notifications: Ilmoitukset - push: Push-ilmoitukset + push: Puskuilmoitukset reports: Raportit search: Hae statuses: Viestit @@ -147,49 +147,49 @@ fi: application: title: OAuth-valtuutus tarvitaan scopes: - admin:read: lukea kaikkia tietoja palvelimelta - admin:read:accounts: lue arkaluontoinen sisältö kaikilta tileiltä - admin:read:canonical_email_blocks: lue arkaluonteisia tietoja kaikista kanonisesti sallituista sähköpostiosoitteista + admin:read: lue kaikkia palvelimen tietoja + admin:read:accounts: lue arkaluonteisia tietoja kaikista tileistä + admin:read:canonical_email_blocks: lue arkaluonteisia tietoja kaikista estetyistä kanonisista sähköpostiosoitteista admin:read:domain_allows: lue arkaluonteisia tietoja kaikista sallituista verkkotunnuksista admin:read:domain_blocks: lue arkaluonteisia tietoja kaikista estetyistä verkkotunnuksista admin:read:email_domain_blocks: lue arkaluonteisia tietoja kaikista estetyistä sähköpostiverkkotunnuksista admin:read:ip_blocks: lue arkaluonteisia tietoja kaikista estetyistä IP-osoitteista - admin:read:reports: lue arkaluonteiset tiedot kaikista raporteista ja raportoiduista tileistä - admin:write: muokata kaikkia tietoja palvelimella - admin:write:accounts: suorita moderointitoiminnot tileillä - admin:write:canonical_email_blocks: toteuta moderointitoimenpiteitä kanonisille sähköpostiosoite-estoille - admin:write:domain_allows: toteuta moderointitoimenpiteitä sallituille verkkotunnuksille - admin:write:domain_blocks: toteuta moderointitoimenpiteitä estetyille verkkotunnuksille - admin:write:email_domain_blocks: toteuta moderointitoimenpiteitä estetyille sähköpostiverkkotunnuksille - admin:write:ip_blocks: toteuta moderointitoimenpiteitä estetyille IP-osoitteille - admin:write:reports: suorita moderointitoiminnot raporteissa - crypto: käytä päästä päähän salausta - follow: seurata, estää, perua eston ja lopettaa tilien seuraaminen - push: vastaanottaa push-ilmoituksesi - read: lukea tilin tietoja - read:accounts: nähdä tilin tiedot - read:blocks: katso lohkosi - read:bookmarks: katso kirjanmerkkisi - read:favourites: katso suosikkisi - read:filters: katso suodattimesi - read:follows: katso ketä seuraat - read:lists: katso listasi - read:mutes: katso mykistyksesi - read:notifications: katso ilmoitukset - read:reports: katso raporttisi - read:search: haku sinun puolesta - read:statuses: katso kaikki viestit - write: julkaista puolestasi - write:accounts: muokata profiiliasi - write:blocks: estää tilit ja palvelimet - write:bookmarks: kirjanmerkki viestit - write:conversations: mykistä ja poistaa keskustelut - write:favourites: suosikki viestit - write:filters: luoda suodattimia - write:follows: seurata ihmisiä - write:lists: luoda listoja - write:media: lähettää mediatiedostoja - write:mutes: mykistää ihmisiä ja keskusteluja - write:notifications: tyhjentää ilmoituksesi - write:reports: raportoi muille ihmisille - write:statuses: julkaise viestejä + admin:read:reports: lue arkaluonteisia tietoja kaikista raporteista ja raportoiduista tileistä + admin:write: muokkaa kaikkia palvelimen tietoja + admin:write:accounts: suorita valvontatoimia tileille + admin:write:canonical_email_blocks: suorita valvontatoimia estetyille kanonisille sähköpostiosoitteille + admin:write:domain_allows: suorita valvontatoimia sallituille verkkotunnuksille + admin:write:domain_blocks: suorita valvontatoimia estetyille verkkotunnuksille + admin:write:email_domain_blocks: suorita valvontatoimia estetyille sähköpostiverkkotunnuksille + admin:write:ip_blocks: suorita valvontatoimia estetyille IP-osoitteille + admin:write:reports: suorita valvontatoimia raporteille + crypto: käytä päästä päähän -salausta + follow: muokkaa tilin suhteita + push: vastaanota puskuilmoituksiasi + read: lue kaikkia tilin tietoja + read:accounts: katso tilien tietoja + read:blocks: katso estojasi + read:bookmarks: katso kirjanmerkkejäsi + read:favourites: katso suosikkejasi + read:filters: katso suodattimiasi + read:follows: katso seurattujasi + read:lists: katso listojasi + read:mutes: katso mykistyksiäsi + read:notifications: katso ilmoituksiasi + read:reports: katso raporttejasi + read:search: hae puolestasi + read:statuses: katso kaikkia julkaisujasi + write: muokkaa kaikkia tilisi tietoja + write:accounts: muokkaa profiiliasi + write:blocks: estä tilejä ja verkkotunnuksia + write:bookmarks: lisää julkaisuja kirjanmerkkeihin + write:conversations: mykistä ja poista keskusteluja + write:favourites: suosikkijulkaisut + write:filters: luo suodattimia + write:follows: seuraa käyttäjiä + write:lists: luo listoja + write:media: lähetä mediatiedostoja + write:mutes: mykistä käyttäjiä ja keskusteluja + write:notifications: tyhjennä ilmoituksesi + write:reports: raportoi muita käyttäjiä + write:statuses: julkaise julkaisuja diff --git a/config/locales/doorkeeper.fo.yml b/config/locales/doorkeeper.fo.yml index e4c1a8b8a6..78f8701ae9 100644 --- a/config/locales/doorkeeper.fo.yml +++ b/config/locales/doorkeeper.fo.yml @@ -127,7 +127,7 @@ fo: bookmarks: Bókamerki conversations: Samrøður crypto: Enda-til-enda bronglan - favourites: Yndispostar + favourites: Dámdir postar filters: Filtur follow: Fylgingar, doyvingar og blokeringar follows: Fylgir @@ -170,7 +170,7 @@ fo: read:accounts: vís kontuupplýsingar read:blocks: síggja tínar blokeringar read:bookmarks: síggja tíni bókamerki - read:favourites: síggja tínar yndispostar + read:favourites: sí tínar dámdu postar read:filters: síggja tíni filtur read:follows: síggja hvørji tú fylgir read:lists: síggja tínar listar @@ -184,7 +184,7 @@ fo: write:blocks: blokera kontur og domenir write:bookmarks: bókamerkja postar write:conversations: doyva og strika samrøður - write:favourites: yndismerkja postar + write:favourites: dáma postar write:filters: gera filtur write:follows: fylgja fólki write:lists: gera listar diff --git a/config/locales/doorkeeper.fr-QC.yml b/config/locales/doorkeeper.fr-QC.yml index f8a5b64846..043b4a6cda 100644 --- a/config/locales/doorkeeper.fr-QC.yml +++ b/config/locales/doorkeeper.fr-QC.yml @@ -122,12 +122,14 @@ fr-QC: admin/accounts: Gestion des comptes admin/all: Toutes les fonctionnalités d'administration admin/reports: Gestion des rapports + all: Accès complet à votre compte Mastodon blocks: Bloqués bookmarks: Marque-pages conversations: Conversations crypto: Chiffrement de bout-en-bout favourites: Favoris filters: Filtres + follow: Abonnements, comptes masqués et comptes bloqués follows: Abonnements lists: Listes media: Fichiers médias @@ -147,18 +149,18 @@ fr-QC: scopes: admin:read: lire toutes les données du serveur admin:read:accounts: lire les informations sensibles de tous les comptes - admin:read:canonical_email_blocks: lire les informations sensibles de tous les bloqueurs d'e-mails canoniques + admin:read:canonical_email_blocks: lire les informations sensibles de tous les bloqueurs de courriels canoniques admin:read:domain_allows: lire les informations sensibles de tous les domaines autorisés - admin:read:domain_blocks: lire les informations sensibles de tous les blocqueurs de domaines - admin:read:email_domain_blocks: lire les informations sensibles de tous les blocqueurs d'e-mails de domaines + admin:read:domain_blocks: lire les informations sensibles de tous les bloqueurs de domaines + admin:read:email_domain_blocks: lire les informations sensibles de tous les bloqueurs de domaines de courriel admin:read:ip_blocks: lire les informations sensibles de tous les blocqueurs d'IP admin:read:reports: lire les informations sensibles de tous les signalements et des comptes signalés admin:write: modifier toutes les données sur le serveur admin:write:accounts: effectuer des actions de modération sur les comptes - admin:write:canonical_email_blocks: effectuer des actions de modération sur les bloqueurs d'e-mails canoniques + admin:write:canonical_email_blocks: effectuer des actions de modération sur les bloqueurs de courriels canoniques admin:write:domain_allows: effectuer des actions de modération sur les autorisations de domaines admin:write:domain_blocks: effectuer des actions de modération sur des bloqueurs de domaines - admin:write:email_domain_blocks: effectuer des actions de modération sur des bloqueurs d'e-mails de domaines + admin:write:email_domain_blocks: effectuer des actions de modération sur des bloqueurs de domaines de courriel admin:write:ip_blocks: effectuer des actions de modération sur des bloqueurs d'IP admin:write:reports: effectuer des actions de modération sur les signalements crypto: utiliser le chiffrement de bout-en-bout @@ -182,7 +184,7 @@ fr-QC: write:blocks: bloquer des comptes et des domaines write:bookmarks: mettre des messages en marque-pages write:conversations: masquer et effacer les conversations - write:favourites: mettre des messages en favori + write:favourites: publications favorites write:filters: créer des filtres write:follows: suivre des personnes write:lists: créer des listes diff --git a/config/locales/doorkeeper.fr.yml b/config/locales/doorkeeper.fr.yml index d777c925a3..2c37b651a7 100644 --- a/config/locales/doorkeeper.fr.yml +++ b/config/locales/doorkeeper.fr.yml @@ -184,7 +184,7 @@ fr: write:blocks: bloquer des comptes et des domaines write:bookmarks: mettre des messages en marque-pages write:conversations: masquer et effacer les conversations - write:favourites: mettre des messages en favori + write:favourites: messages favoris write:filters: créer des filtres write:follows: suivre des personnes write:lists: créer des listes diff --git a/config/locales/doorkeeper.fy.yml b/config/locales/doorkeeper.fy.yml index 3617b65c12..8acf7ea9b8 100644 --- a/config/locales/doorkeeper.fy.yml +++ b/config/locales/doorkeeper.fy.yml @@ -38,7 +38,7 @@ fy: application: Tapassing callback_url: Callback-URL delete: Fuortsmite - empty: Do hast gjin tapassingen konfigurearre. + empty: Jo hawwe gjin tapassingen konfigurearre. name: Namme new: Nije tapassing scopes: Tastimmingen @@ -184,7 +184,7 @@ fy: write:blocks: accounts en domeinen blokkearje write:bookmarks: berjochten oan blêdwizers tafoegje write:conversations: petearen negearre en fuortsmite - write:favourites: berjochten as favoryt markearje + write:favourites: favorite berjochten write:filters: filters oanmeitsje write:follows: minsken folgje write:lists: listen oanmeitsje diff --git a/config/locales/doorkeeper.ga.yml b/config/locales/doorkeeper.ga.yml index 9bd0d29128..a263a6b15d 100644 --- a/config/locales/doorkeeper.ga.yml +++ b/config/locales/doorkeeper.ga.yml @@ -40,7 +40,6 @@ ga: accounts: Cuntais bookmarks: Leabharmharcanna conversations: Comhráite - favourites: Toghanna filters: Scagairí follows: Cuntais leanta lists: Liostaí diff --git a/config/locales/doorkeeper.gd.yml b/config/locales/doorkeeper.gd.yml index 84621d3009..4db4497b4e 100644 --- a/config/locales/doorkeeper.gd.yml +++ b/config/locales/doorkeeper.gd.yml @@ -122,12 +122,14 @@ gd: admin/accounts: Rianachd nan cunntas admin/all: Gach gleus na rianachd admin/reports: Rianachd nan gearan + all: Làn-inntrigeadh dhan chunntas Mastodon agad blocks: Bacaidhean bookmarks: Comharran-lìn conversations: Còmhraidhean crypto: Crioptachadh o cheann gu ceann favourites: Annsachdan filters: Criathragan + follow: Leantainn, mùchaidhean is bacaidhean follows: Leantainn lists: Liostaichean media: Ceanglachain mheadhanan @@ -145,39 +147,49 @@ gd: application: title: Tha feum air ùghdarrachadh OAuth scopes: - admin:read: dàta sam bith a leughadh air an fhrithealaiche - admin:read:accounts: fiosrachadh dìomhair air a h-uile cunntas a leughadh - admin:read:reports: fiosrachadh dìomhair air a h-uile gearan is cunntasan a chaidh a ghearan mun dèidhinn a leughadh - admin:write: dàta sam bith atharrachadh air an fhrithealaiche - admin:write:accounts: gnìomhan na maorsainneachd a ghabhail air cunntasan - admin:write:reports: gnìomhan na maorsainneachd a ghabhail air gearanan - crypto: crioptachadh o cheann gu ceann a chleachdadh - follow: dàimhean chunntasan atharrachadh - push: na brathan putaidh agad fhaighinn - read: dàta sam bith a’ cunntais agad a leughadh - read:accounts: fiosrachadh nan cunntasan fhaicinn - read:blocks: na bacaidhean agad fhaicinn - read:bookmarks: na comharran-lìn agad fhaicinn - read:favourites: na h-annsachdan agad fhaicinn - read:filters: na criathragan agad fhaicinn - read:follows: faicinn cò a tha thu a’ leantainn - read:lists: na liostaichean agad fhaicinn - read:mutes: na mùchaidhean agad fhaicinn - read:notifications: na brathan agad faicinn - read:reports: na gearanan agad fhaicinn - read:search: lorg a dhèanamh às do leth - read:statuses: na postaichean uile fhaicinn - write: dàta sam bith a’ cunntais agad atharrachadh - write:accounts: a’ phròifil agad atharrachadh - write:blocks: cunntasan is àrainnean a bhacadh - write:bookmarks: comharran-lìn a dhèanamh de phostaichean - write:conversations: còmhraidhean a mhùchadh is a sguabadh às - write:favourites: postaichean a chur ris na h-annsachdan - write:filters: criathragan a chruthachadh + admin:read: leughadh dàta sam bith air an fhrithealaiche + admin:read:accounts: leughadh fiosrachaidh dhìomhair air a h-uile cunntas + admin:read:canonical_email_blocks: leughadh fiosrachaidh dhìomhair air a h-uile bacadh puist-d gnàthach + admin:read:domain_allows: leughadh fiosrachaidh dhìomhair air a h-uile cead àrainne + admin:read:domain_blocks: leughadh fiosrachaidh dhìomhair air a h-uile bacadh àrainne + admin:read:email_domain_blocks: leughadh fiosrachaidh dhìomhair air a h-uile bacadh àrainn puist-d + admin:read:ip_blocks: leughadh fiosrachaidh dhìomhair air a h-uile bacadh IP + admin:read:reports: leughadh fiosrachaidh dhìomhair air a h-uile gearan is cunntasan a chaidh a ghearan mun dèidhinn + admin:write: atharrachadh dàta sam bith air an fhrithealaiche + admin:write:accounts: gnìomhan na maorsainneachd air cunntasan + admin:write:canonical_email_blocks: gnìomhan na maorsainneachd air bacaidhean puist-d gnàthach + admin:write:domain_allows: gnìomhan na maorsainneachd air ceadan àrainn + admin:write:domain_blocks: gnìomhan na maorsainneachd air bacaidhean àrainne + admin:write:email_domain_blocks: gnìomhan na maorsainneachd air bacaidhean àrainn puist-d + admin:write:ip_blocks: gnìomhan na maorsainneachd air bacaidhean IP + admin:write:reports: gnìomhan na maorsainneachd air gearanan + crypto: cleachdadh crioptachaidh o cheann gu ceann + follow: atharrachadh dàimhean chunntasan + push: faighinn nam brathan putaidh agad + read: leughadh dàta sam bith a’ cunntais agad + read:accounts: sealltainn fiosrachadh nan cunntasan + read:blocks: sealltainn nam bacaidhean agad + read:bookmarks: sealltainn nan comharran-lìn agad + read:favourites: sealltainn nan annsachdan agad + read:filters: sealltainn nan criathragan agad + read:follows: sealltainn cò a tha thu a’ leantainn + read:lists: sealltainn nan liostaichean agad + read:mutes: sealltainn nam mùchaidhean agad + read:notifications: sealltainn nam brathan agad + read:reports: sealltainn nan gearanan agad + read:search: lorg às do leth + read:statuses: sealltainn nam postaichean uile + write: atharrachadh dàta sam bith a’ cunntais agad + write:accounts: atharrachadh na pròifile agad + write:blocks: bacadh chunntasan is àrainnean + write:bookmarks: cruthachadh chomharran-lìn de phostaichean + write:conversations: mùchadh is sguabadh às chòmhraidhean + write:favourites: cur phostaichean ris na h-annsachdan + write:filters: cruthachadh chriathragan write:follows: leantainn dhaoine - write:lists: liostaichean a chruthachadh - write:media: faidhlichean meadhain a luchdadh suas - write:mutes: daoine is còmhraidhean a mhùchadh - write:notifications: na brathan agad fhalamhachadh - write:reports: gearan a dhèanamh mu chàch - write:statuses: postaichean fhoillseachadh + write:lists: cruthachadh liostaichean + write:media: luchdadh suas fhaidhlichean meadhain + write:mutes: mùchadh dhaoine is chòmhraidhean + write:notifications: falamhachadh nam brathan agad + write:reports: gearan mu chàch + write:statuses: foillseachadh phostaichean diff --git a/config/locales/doorkeeper.gl.yml b/config/locales/doorkeeper.gl.yml index 622fcfe768..c7f21d1ba8 100644 --- a/config/locales/doorkeeper.gl.yml +++ b/config/locales/doorkeeper.gl.yml @@ -120,7 +120,7 @@ gl: title: accounts: Contas admin/accounts: Administración das contas - admin/all: Tódalas funcións administrativas + admin/all: Todas as funcións administrativas admin/reports: Administración das denuncias all: Acceso completo á túa conta de Mastodon blocks: Bloqueos @@ -129,7 +129,7 @@ gl: crypto: Cifrado extremo-a-extremo favourites: Favoritas filters: Filtros - follow: Seguidas, Silenciadas e Bloqueadas + follow: Seguidas, Acaladas e Bloqueadas follows: Seguimentos lists: Listas media: Anexos multimedia @@ -150,7 +150,7 @@ gl: admin:read: ler todos os datos no servidor admin:read:accounts: ler información sensible de todas as contas admin:read:canonical_email_blocks: ler a información sensíbel de tódolos bloqueos de correos electrónicos canónicos - admin:read:domain_allows: ler a información sensible de tódolos dominios permitidos + admin:read:domain_allows: ler a información sensible de todos os dominios permitidos admin:read:domain_blocks: ler a información sensible de tódolos bloqueos de dominio admin:read:email_domain_blocks: ler a información sensible de tódolos dominios de correo electrónico admin:read:ip_blocks: ler a información sensible de tódolos bloqueos de IP diff --git a/config/locales/doorkeeper.hu.yml b/config/locales/doorkeeper.hu.yml index 51f42405a6..4559dcbd31 100644 --- a/config/locales/doorkeeper.hu.yml +++ b/config/locales/doorkeeper.hu.yml @@ -5,7 +5,7 @@ hu: doorkeeper/application: name: Alkalmazás neve redirect_uri: Átirányító URI - scopes: Hatáskör + scopes: Hatókör website: Az alkalmazás weboldala errors: models: @@ -19,7 +19,7 @@ hu: doorkeeper: applications: buttons: - authorize: Engedélyezés + authorize: Hitelesítés cancel: Mégsem destroy: Törlés edit: Szerkesztés @@ -31,38 +31,38 @@ hu: form: error: Hoppá! Ellenőrizd az űrlapot az esetleges hibák miatt help: - native_redirect_uri: Használj %{native_redirect_uri} a helyi tesztekhez + native_redirect_uri: "%{native_redirect_uri} használata a helyi tesztekhez" redirect_uri: Egy sor URI-nként - scopes: A hatásköröket szóközzel válaszd el. Hagyd üresen az alapértelmezett hatáskörökhöz. + scopes: A hatóköröket szóközzel válaszd el. Hagyd üresen az alapértelmezett hatókörök használatához. index: application: Alkalmazás callback_url: Visszahívási URL delete: Eltávolítás - empty: Nincsenek alkalmazásaid. + empty: Nincsenek saját alkalmazások. name: Név new: Új alkalmazás - scopes: Hatáskör - show: Mutat + scopes: Hatókörök + show: Megjelenítés title: Alkalmazásaid new: title: Új alkalmazás show: actions: Műveletek - application_id: Alkalmazás azonosító - callback_urls: Callback URL-ek + application_id: Ügyfélkulcs + callback_urls: Visszahívási URL-ek scopes: Hatáskörök - secret: Titok + secret: Ügyfél titkos kulcs title: 'Alkalmazás: %{name}' authorizations: buttons: - authorize: Engedélyezés + authorize: Hitelesítés deny: Tiltás error: title: Hiba történt new: prompt_html: "%{client_name} szeretné elérni a fiókodat. Ez egy harmadik féltől származó alkalmazás. Ha nem bízol meg benne, ne addj felhatalmazást neki." - review_permissions: Engedélyek áttekintése - title: Engedély szükséges + review_permissions: Jogosultságok áttekintése + title: Hitelesítés szükséges show: title: Másold le ezt az engedélyező kódot és írd be az alkalmazásba. authorized_applications: @@ -71,13 +71,13 @@ hu: confirmations: revoke: Biztos vagy benne? index: - authorized_at: 'Felhatalmazva ekkor: %{date}' + authorized_at: 'Hitelesítés: %{date}' description_html: Ezek olyan alkalmazások, melyek API-n keresztül érhetik el a fiókodat. Ha vannak itt olyanok, melyeket nem ismersz fel, vagy valamelyik alkalmazás rosszul működik, visszavonhatod az engedélyét. - last_used_at: 'Utoljára ekkor használva: %{date}' + last_used_at: 'Utolsó használat: %{date}' never_used: Soha sem volt használva - scopes: Engedélyek + scopes: Jogosultságok superapp: Belső - title: Engedélyezett alkalmazásaid + title: Hitelesített alkalmazásaid errors: messages: access_denied: Az erőforrás tulajdonosa vagy az engedélyező kiszolgáló elutasította a kérést. @@ -92,10 +92,10 @@ hu: invalid_resource_owner: A biztosított erőforrás tulajdonosának hitelesítő adatai nem valósak, vagy az erőforrás tulajdonosa nem található. invalid_scope: A kért nézet érvénytelen, ismeretlen, vagy hibás. invalid_token: - expired: Hozzáférési kulcs lejárt - revoked: Hozzáférési kulcsot visszavonták - unknown: Hozzáférési kulcs érvénytelen - resource_owner_authenticator_not_configured: Erőforrás tulajdonos keresés megszakadt, ugyanis a Doorkeeper.configure.resource_owner_authenticator beállítatlan. + expired: A hozzáférési kulcs lejárt + revoked: A hozzáférési kulcsot visszavonták + unknown: A hozzáférési kulcs érvénytelen + resource_owner_authenticator_not_configured: Az erőforrás-tulajdonos keresése megszakadt, ugyanis a Doorkeeper.configure.resource_owner_authenticator nem lett beállítva. server_error: Az engedélyező kiszolgáló váratlan körülménybe ütközött, ami megakadályozta, hogy teljesítse a kérést. temporarily_unavailable: Az engedélyezési kiszolgáló jelenleg nem tudja kezelni a kérelmet a kiszolgáló ideiglenes túlterhelése vagy karbantartása miatt. unauthorized_client: A kliens nincs feljogosítva erre a kérésre. @@ -104,14 +104,14 @@ hu: flash: applications: create: - notice: Alkalmazás létrehozva. + notice: Az alkalmazás létrehozva. destroy: - notice: Alkalmazás törölve. + notice: Az alkalmazás törlésre került. update: notice: Alkalmazás frissítve. authorized_applications: destroy: - notice: Alkalmazás visszavonva. + notice: Az alkalmazás visszavonásra került. grouped_scopes: access: read: Csak olvasási elérés @@ -164,9 +164,9 @@ hu: admin:write:ip_blocks: moderáció végrehajtása IP-blokkokon admin:write:reports: moderációs műveletek végzése bejelentéseken crypto: végpontok közti titkosítás használata - follow: fiókok követése, letiltása, tiltás feloldása és követés abbahagyása + follow: fiókkapcsolatok módosítása push: push értesítések fogadása - read: fiókod adatainak olvasása + read: saját fiók adatainak olvasása read:accounts: fiók adatainak megtekintése read:blocks: letiltások megtekintése read:bookmarks: könyvjelzőid megtekintése @@ -177,10 +177,10 @@ hu: read:mutes: némítások megtekintése read:notifications: értesítések megtekintése read:reports: bejelentések megtekintése - read:search: nevedben keresés + read:search: keresés a saját nevedben read:statuses: bejegyzések megtekintése write: fiókod adatainak megváltoztatása - write:accounts: profilod megváltoztatása + write:accounts: saját profilod megváltoztatása write:blocks: fiókok és domainek letiltása write:bookmarks: bejegyzések könyvjelzőzése write:conversations: beszélgetések némítása és törlése diff --git a/config/locales/doorkeeper.hy.yml b/config/locales/doorkeeper.hy.yml index 6548d1e5e9..39ffc9898c 100644 --- a/config/locales/doorkeeper.hy.yml +++ b/config/locales/doorkeeper.hy.yml @@ -145,7 +145,7 @@ hy: read:accounts: տեսնել հաշիւների ինֆորմացիան read:blocks: տեսնել արգելափակումները read:bookmarks: տեսնել էջանիշները - read:favourites: տեսնել հաւանումները + read:favourites: տես քո հաւանածները read:filters: տեսնել ֆիլտրերը read:follows: տեսնել հետեւորդներին read:lists: տեսնել ցանկերը @@ -158,7 +158,6 @@ hy: write:accounts: փոփոխել հաշիւը write:blocks: արգելափակել հաշիւները եւ դոմէյնները write:bookmarks: էջանշել գրառումները - write:favourites: հաւանել գրառումները write:filters: "'ստեղծել ֆիլտրեր" write:follows: հետեւել մարդկանց write:lists: ստեղծել ցանկեր diff --git a/config/locales/doorkeeper.id.yml b/config/locales/doorkeeper.id.yml index 55bda04fec..3f9a409c21 100644 --- a/config/locales/doorkeeper.id.yml +++ b/config/locales/doorkeeper.id.yml @@ -126,7 +126,6 @@ id: bookmarks: Markah conversations: Percakapan crypto: Enkripsi end-to-end - favourites: Favorit filters: Saringan follows: Mengikuti lists: Daftar @@ -165,7 +164,6 @@ id: read:accounts: lihat informasi akun read:blocks: lihat blokiran Anda read:bookmarks: lihat markah Anda - read:favourites: lihat favorit Anda read:filters: lihat saringan Anda read:follows: lihat yang Anda ikuti read:lists: lihat daftar Anda @@ -179,7 +177,6 @@ id: write:blocks: blokir akun dan domain write:bookmarks: status markah write:conversations: bisukan dan hapus percakapan - write:favourites: status favorit write:filters: buat saringan write:follows: ikuti orang write:lists: buat daftar diff --git a/config/locales/doorkeeper.io.yml b/config/locales/doorkeeper.io.yml index df56335f84..e2418e4c77 100644 --- a/config/locales/doorkeeper.io.yml +++ b/config/locales/doorkeeper.io.yml @@ -126,7 +126,7 @@ io: bookmarks: Libromarki conversations: Konversi crypto: Intersequanta chifro - favourites: Favorati + favourites: Favoriziti filters: Filtrili follows: Sequati lists: Listi @@ -158,7 +158,7 @@ io: read:accounts: videz kontinformo read:blocks: videz restrikti read:bookmarks: videz vua libromarki - read:favourites: videz vua favorati + read:favourites: videz vua favoriziti read:filters: videz vua filtrili read:follows: videz vua sequinti read:lists: videz vua listi @@ -172,7 +172,7 @@ io: write:blocks: restriktez konti e domeni write:bookmarks: libromarkez posti write:conversations: silencigez e efacez konversi - write:favourites: favorata posti + write:favourites: favorizita posti write:filters: kreez filtrili write:follows: sequez personi write:lists: kreez listi diff --git a/config/locales/doorkeeper.it.yml b/config/locales/doorkeeper.it.yml index 31e09a6af3..3fd998fc4a 100644 --- a/config/locales/doorkeeper.it.yml +++ b/config/locales/doorkeeper.it.yml @@ -170,7 +170,7 @@ it: read:accounts: visualizzare le informazioni sui profili read:blocks: visualizzare i tuoi blocchi read:bookmarks: visualizzare i tuoi segnalibri - read:favourites: visualizzare i tuoi preferiti + read:favourites: vedi i tuoi preferiti read:filters: visualizzare i tuoi filtri read:follows: visualizzare i tuoi seguiti read:lists: visualizzare i tuoi elenchi @@ -184,7 +184,7 @@ it: write:blocks: bloccare profili e domini write:bookmarks: aggiungere post tra i segnalibri write:conversations: silenziare ed eliminare conversazioni - write:favourites: salvare post tra i preferiti + write:favourites: post preferiti write:filters: creare filtri write:follows: seguire persone write:lists: creare elenchi diff --git a/config/locales/doorkeeper.ja.yml b/config/locales/doorkeeper.ja.yml index 0e52e1f09d..62f2a3eb0a 100644 --- a/config/locales/doorkeeper.ja.yml +++ b/config/locales/doorkeeper.ja.yml @@ -184,7 +184,7 @@ ja: write:blocks: ユーザーのブロックやドメインの非表示 write:bookmarks: 投稿のブックマーク登録 write:conversations: 会話のミュートと削除 - write:favourites: 投稿のお気に入り登録 + write:favourites: お気に入りの投稿 write:filters: フィルターの変更 write:follows: あなたの代わりにフォロー、アンフォロー write:lists: リストの変更 diff --git a/config/locales/doorkeeper.ka.yml b/config/locales/doorkeeper.ka.yml index 36df811f1f..4c692cf517 100644 --- a/config/locales/doorkeeper.ka.yml +++ b/config/locales/doorkeeper.ka.yml @@ -112,7 +112,6 @@ ka: read: წაიკითხოს მთელი თქვენი ანგარიშის მონაცემები read:accounts: იხილოს ანგარიშის ინფორმაცია read:blocks: იხილოს თქვენი ბლოკები - read:favourites: იხილოს თქვენი ფავორიტები read:filters: იხილოს თქვენი ფილრები read:follows: იხილოს თქვენი მიდევნებები read:lists: იხილოს თქვენი სიები @@ -124,7 +123,6 @@ ka: write: შეცვალოს მთელი თქვენი ანგარიშის მონაცემები write:accounts: შეცვალოს თქვენი პროფილი write:blocks: დაბლოკოს ანგარიშები და დომენები - write:favourites: ფავორიტი სტატუსები write:filters: შექმნას ფილტრები write:follows: გაყვეს ხალხს write:lists: შექმნას სიები diff --git a/config/locales/doorkeeper.kab.yml b/config/locales/doorkeeper.kab.yml index ba1d7057a1..fe1a8d9c50 100644 --- a/config/locales/doorkeeper.kab.yml +++ b/config/locales/doorkeeper.kab.yml @@ -84,7 +84,6 @@ kab: accounts: Imiḍanen admin/accounts: Tadbelt n imiḍan crypto: Awgelhen seg yixef ɣer yixef - favourites: Ismenyifen filters: Imzizdigen lists: Tibdarin notifications: Tilɣa @@ -107,7 +106,6 @@ kab: read:accounts: ẓer isallen n yimiḍanen read:blocks: ẓer imiḍanen i tesḥebseḍ read:bookmarks: ẓer ticraḍ-ik - read:favourites: ẓer ismenyifen-ik read:filters: ẓer imsizedgen-ik read:follows: ẓer imeḍfaṛen-ik read:lists: ẓer tibdarin-ik·im diff --git a/config/locales/doorkeeper.kk.yml b/config/locales/doorkeeper.kk.yml index daaa3a9ebf..a9668180c0 100644 --- a/config/locales/doorkeeper.kk.yml +++ b/config/locales/doorkeeper.kk.yml @@ -120,7 +120,6 @@ kk: read:accounts: see accounts infоrmation read:blocks: see your blоcks read:bookmarks: белгілегендерді қарау - read:favourites: see your favоurites read:filters: see yоur filters read:follows: see your follоws read:lists: see yоur lists @@ -133,7 +132,6 @@ kk: write:accounts: modify your prоfile write:blocks: block accounts and dоmains write:bookmarks: белгілер статусы - write:favourites: favourite stаtuses write:filters: creаte filters write:follows: follow peоple write:lists: creatе lists diff --git a/config/locales/doorkeeper.ko.yml b/config/locales/doorkeeper.ko.yml index 504fefd281..8e6e4b8aaa 100644 --- a/config/locales/doorkeeper.ko.yml +++ b/config/locales/doorkeeper.ko.yml @@ -4,7 +4,7 @@ ko: attributes: doorkeeper/application: name: 애플리케이션 이름 - redirect_uri: 리다이렉트 URI + redirect_uri: 리디렉트 URI scopes: 범위 website: 애플리케이션 웹사이트 errors: @@ -15,7 +15,7 @@ ko: fragment_present: fragment를 포함할 수 없습니다 invalid_uri: 올바른 URI 이어야 합니다. relative_uri: 절대경로 URI 이어야 합니다 - secured_uri: " HTTPS/SSL URI 이어야 합니다." + secured_uri: HTTPS/SSL URI 이어야 합니다. doorkeeper: applications: buttons: @@ -25,13 +25,13 @@ ko: edit: 편집 submit: 제출 confirmations: - destroy: 정말로 실행하시겠습니까? + destroy: 확실합니까? edit: title: 애플리케이션 수정 form: error: 이런! 오류를 확인하세요 help: - native_redirect_uri: "%{native_redirect_uri} 을/를 이용해 로컬 테스트를 할 수 있습니다" + native_redirect_uri: "%{native_redirect_uri}에서 로컬 테스트를 할 수 있습니다." redirect_uri: 한 줄에 하나의 URI를 작성하세요 scopes: 스페이스로 범위를 구분하세요. 빈 칸으로 놔두면 기본 범위를 사용합니다. index: @@ -40,12 +40,12 @@ ko: delete: 삭제 empty: 애플리케이션이 없습니다. name: 이름 - new: 새 애플리케이션 + new: 새로운 애플리케이션 scopes: 범위 show: 표시 title: 내 응용프로그램 new: - title: 새 애플리케이션 + title: 새로운 애플리케이션 show: actions: 동작 application_id: 클라이언트 키 @@ -60,7 +60,7 @@ ko: error: title: 오류가 발생하였습니다 new: - prompt_html: "%{client_name}이 당신의 계정에 대한 접근 권한을 요청합니다. 이것은 제3자의 응용프로그램입니다. 이것을 신뢰하지 않는다면, 권한을 승인하지 말아야 합니다." + prompt_html: "%{client_name} 제3자 애플리케이션이 귀하의 계정에 접근하기 위한 권한을 요청하고 있습니다. 이 애플리케이션을 신뢰할 수 없다면 이 요청을 승인하지 마십시오." review_permissions: 권한 검토 title: 승인 필요 show: @@ -72,7 +72,7 @@ ko: revoke: 확실합니까? index: authorized_at: "%{date}에 승인됨" - description_html: 당신의 계정에 API를 통해 접근 가능한 응용프로그램의 목록입니다. 알 수 없는 응용프로그램, 혹은 잘못된 행동을 하고 있는 응용프로그램이 있다면, 권한을 취소할 수 있습니다. + description_html: API를 통해 이 계정에 접근 가능한 애플리케이션의 목록입니다. 알 수 없는 애플리케이션이나 잘못된 행위를 하는 애플리케이션이 있다면 권한을 취소할 수 있습니다. last_used_at: "%{date}에 마지막으로 사용됨" never_used: 사용되지 않음 scopes: 권한 @@ -82,7 +82,7 @@ ko: messages: access_denied: 리소스 소유자 또는 인증 서버가 요청을 거부했습니다. credential_flow_not_configured: Doorkeeper.configure.resource_owner_from_credentials의 설정이 되어있지 않아 리소스 소유자 암호 자격증명이 실패하였습니다. - invalid_client: 알 수 없는 클라이언트이기 때문에 클라이언트 인증이 실패하였습니다, 클라이언트 자격증명이 포함되지 않았거나, 지원 되지 않는 메소드입니다. + invalid_client: 클라이언트를 확인할 수 없기 때문에 인증이 실패하였습니다. 클라이언트 자격 증명이 포함되지 않았거나 지원되지 않는 메소드입니다. invalid_grant: 제공된 권한 부여가 잘못되거나, 만료되었거나, 취소되었거나, 권한 부여 요청에 사용된 리디렉션 URI가 일치하지 않거나, 다른 클라이언트에 지정되었습니다. invalid_redirect_uri: 리디렉션 URI가 올바르지 않습니다 invalid_request: @@ -104,11 +104,11 @@ ko: flash: applications: create: - notice: 애플리케이션이 생성 되었습니다. + notice: 애플리케이션을 만들었습니다. destroy: - notice: 애플리케이션이 삭제 되었습니다. + notice: 애플리케이션을 삭제하였습니다. update: - notice: 애플리케이션이 갱신 되었습니다. + notice: 애플리케이션을 갱신했습니다. authorized_applications: destroy: notice: 애플리케이션이 삭제되었습니다. @@ -164,27 +164,27 @@ ko: admin:write:ip_blocks: IP 차단에 모더레이션 조치 취하기 admin:write:reports: 신고에 모더레이션 조치 취하기 crypto: 종단간 암호화 사용 - follow: 계정의 관계를 수정 - push: 푸시 알림을 받기 - read: 계정의 모든 데이터를 읽기 - read:accounts: 계정의 정보를 보기 - read:blocks: 차단을 보기 + follow: 계정 관계 수정 + push: 푸시 알림 받기 + read: 계정의 모든 데이터 읽기 + read:accounts: 계정 정보 보기 + read:blocks: 차단 보기 read:bookmarks: 내 북마크 보기 - read:favourites: 관심글을 보기 - read:filters: 필터를 보기 - read:follows: 팔로우를 보기 - read:lists: 리스트를 보기 - read:mutes: 뮤트를 보기 + read:favourites: 좋아요 보기 + read:filters: 필터 보기 + read:follows: 팔로우 보기 + read:lists: 리스트 보기 + read:mutes: 뮤트 보기 read:notifications: 알림 보기 read:reports: 신고 보기 read:search: 당신의 권한으로 검색 - read:statuses: 게시물 모두 보기 + read:statuses: 모든 게시물 보기 write: 계정 정보 수정 write:accounts: 프로필 수정 - write:blocks: 계정이나 도메인 차단 + write:blocks: 계정 및 도메인 차단 write:bookmarks: 게시물을 북마크에 넣기 - write:conversations: 뮤트와 대화 삭제 - write:favourites: 관심글 지정 + write:conversations: 뮤트 및 대화 삭제 + write:favourites: 게시물 좋아요 write:filters: 필터 만들기 write:follows: 사람을 팔로우 write:lists: 리스트 만들기 diff --git a/config/locales/doorkeeper.ku.yml b/config/locales/doorkeeper.ku.yml index 3f8d7d068f..e3438eb5de 100644 --- a/config/locales/doorkeeper.ku.yml +++ b/config/locales/doorkeeper.ku.yml @@ -122,12 +122,13 @@ ku: admin/accounts: Rêveberiya ajimêran admin/all: Hemû fonksiyonên reveberî admin/reports: Rêveberiya ragihandinan + all: Gihîştina tevahî ya ajimêra te ya Mastodon blocks: Astengkirin bookmarks: Şûnpel conversations: Axaftin crypto: Dawî bi dawî şifrekirî - favourites: Bijarte filters: Parzûn + follow: Şopîner, bêdengkirin û astengkirin follows: Dişopîne lists: Lîste media: Pêvekên medya @@ -147,9 +148,19 @@ ku: scopes: admin:read: hemû daneyên li ser rajekar bixwîne admin:read:accounts: zanyariyên hestiyar yên hemû ajimêran li ser rajekar bixwîne + admin:read:canonical_email_blocks: zaniyarên hestyar ên hemû astengkerên e-nameya bixwîne + admin:read:domain_allows: zaniyarên hestyar ên hemû mafdayînên navpar bixwîne + admin:read:domain_blocks: zaniyarên hestyar ên hemû astengkirinên navpar bixwîne + admin:read:email_domain_blocks: zaniyarên hestyar ên hemû astengkirinên navpar ên e-nameyê bixwîne + admin:read:ip_blocks: zaniyarên hestyar ên hemû astengkirinên IP bixwîne admin:read:reports: zanyariyên hestiyar yên hemû ragihandinan û ajimêrên ragihandî li ser rajekar bixwîne admin:write: hemû daneyên li ser rajekar biguherîne admin:write:accounts: di ajimêrê de çalakiyên li hev kirî pêk bîne + admin:write:canonical_email_blocks: li ser astengkirinên e-nameyê çalakiyên çavdêriyê pêk bîne + admin:write:domain_allows: li ser mafdayînên navpar çalakiyên çavdêriyê pêk bîne + admin:write:domain_blocks: li ser astengkirinên navpar çalakiyên çavdêriyê pêk bîne + admin:write:email_domain_blocks: li ser astengkirinên e-nameya navpar çalakiyên çavdêriyê pêk bîne + admin:write:ip_blocks: li ser astengkirinên IP çalakiyên çavdêriyê pêk bîne admin:write:reports: di ragihandinê de çalakiyên li hev kirî pêk bîne crypto: dawî bi dawî şifrekirî bi kar bîne follow: têkiliyên ajimêrê biguherîne @@ -158,7 +169,6 @@ ku: read:accounts: zanyariyên ajimêran bibîne read:blocks: ajimêran ku te astenkiriye bibîne read:bookmarks: şûnpelên xwe bibîne - read:favourites: bijarteyên xwe bibîne read:filters: parzûnûn xwe bibîne read:follows: ên tu dişopînî bibîne read:lists: lîsteyên xwe bibîne @@ -172,7 +182,6 @@ ku: write:blocks: ajimêr û navperan asteng bike write:bookmarks: şandiyan di şûnpelê de tomar bike write:conversations: bêdengkirin û jêbirina axaftinan - write:favourites: şandiyên bijarte write:filters: parzûnan çê bike write:follows: kesan bişopîne write:lists: lîsteyan biafirîne diff --git a/config/locales/doorkeeper.lv.yml b/config/locales/doorkeeper.lv.yml index 08d7a0d644..0356c22ecb 100644 --- a/config/locales/doorkeeper.lv.yml +++ b/config/locales/doorkeeper.lv.yml @@ -127,7 +127,7 @@ lv: bookmarks: Grāmatzīmes conversations: Sarunas crypto: Pilnīga šifrēšana - favourites: Izlases + favourites: Izlase filters: Filtri follow: Seko, Izslēdz un Bloķē follows: Seko @@ -170,7 +170,7 @@ lv: read:accounts: apskatīt kontu informāciju read:blocks: apskatīt savus blokus read:bookmarks: apskatīt savas grāmatzīmes - read:favourites: apskatīt savu izlasi + read:favourites: skatīt tavu izlasi read:filters: apskatīt savus filtrus read:follows: apskatīt savus sekotājus read:lists: apskatīt savus sarakstus diff --git a/config/locales/doorkeeper.ms.yml b/config/locales/doorkeeper.ms.yml index b84bde805f..32fb0044bb 100644 --- a/config/locales/doorkeeper.ms.yml +++ b/config/locales/doorkeeper.ms.yml @@ -4,21 +4,103 @@ ms: attributes: doorkeeper/application: name: Nama aplikasi + redirect_uri: Ubah hala URI + scopes: Skop + website: Laman web permohonan + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: tidak boleh mengandungi serpihan. + invalid_uri: mestilah URI yang sah. + relative_uri: mestilah URI mutlak. + secured_uri: mestilah URI HTTPS/SSL. doorkeeper: applications: buttons: + authorize: Benarkan cancel: Batal + destroy: Musnah edit: Sunting submit: Hantar confirmations: destroy: Anda pasti? + edit: + title: Mengedit permohonan + form: + error: Alamak! Semak borang anda untuk kemungkinan kesilapan + help: + native_redirect_uri: Gunakan %{native_redirect_uri} untuk ujian tempatan + redirect_uri: Gunakan satu barisan setiap URI + scopes: Asingkan skop dengan ruang. Biarkan kosong untuk menggunakan skop lalai. index: + application: Aplikasi + callback_url: URL callback delete: Padam + empty: Anda tidak mempunyai aplikasi. name: Nama + new: Aplikasi baru + scopes: Skop show: Paparkan + title: Aplikasi anda + new: + title: Aplikasi baru + show: + actions: Tindakan + application_id: Kunci klien + callback_urls: URLs Callback + scopes: Skop + secret: Rahsia klien + title: 'Aplikasi: %{name}' + authorizations: + buttons: + authorize: Benarkan + deny: Nafikan + error: + title: Ralat telah berlaku + new: + prompt_html: "%{client_name} ingin mendapatkan kebenaran untuk mengakses akaun anda. Ia adalah aplikasi pihak ketiga. Jika anda tidak mempercayainya, maka anda tidak seharusnya membenarkannya." + review_permissions: Semak kebenaran + title: Kebenaran diperlukan + show: + title: Salin kod kebenaran ini dan tampalkannya pada aplikasi. authorized_applications: + buttons: + revoke: Batalkan + confirmations: + revoke: Adakah anda pasti? index: + authorized_at: Dibenarkan on %{date} + description_html: Ini adalah aplikasi yang boleh mengakses akaun lalui kegunaan API. Jika terdapat aplikasi yang anda tidak kenali di sini, atau aplikasi tidak berfungsi, anda boleh membatalkan aksesnya. + last_used_at: Terakhir digunakan pada %{date} + never_used: Tidak pernah digunakan + scopes: Kebenaran superapp: Dalaman + title: Aplikasi anda your dibenarkan + errors: + messages: + access_denied: Pemilik sumber atau server kebenaran menolak permintaan. + credential_flow_not_configured: Carian Pemilik Sumber gagal kerana Doorkeeper.configure.resource_owner_authenticator tidak dikonfigurasikan. + invalid_client: Pengesahan pelanggan gagal disebabkan oleh pelanggan yang tidak diketahui, tiada pengesahan pelanggan disertakan atau kaedah pengesahan yang tidak disokong. + invalid_grant: Pemberian kebenaran yang diberikan adalah tidak sah, tamat tempoh, dibatalkan, tidak sepadan dengan URI pengalihan yang digunakan dalam permintaan kebenaran atau telah dikeluarkan kepada klien lain. + invalid_redirect_uri: Uri ubah hala yang disertakan tidak sah. + invalid_request: + missing_param: 'Parameter yang diperlukan hilang: %{value}.' + request_not_authorized: Permintaan perlu dibenarkan. Parameter yang diperlukan untuk membenarkan permintaan tiada atau tidak sah. + unknown: Permintaan itu tidak mempunyai parameter yang diperlukan, termasuk nilai parameter yang tidak disokong, atau sebaliknya salah bentuk. + invalid_resource_owner: Bukti kelayakan pemilik sumber yang diberikan tidak sah atau pemilik sumber tidak dapat ditemui + invalid_scope: Skop yang diminta tidak sah, tidak diketahui atau salah bentuk. + invalid_token: + expired: Token akses telah tamat tempoh + revoked: Token akses telah dibatalkan + unknown: Token akses tidak sah + resource_owner_authenticator_not_configured: Carian Pemilik Sumber gagal kerana Doorkeeper.configure.resource_owner_authenticator tidak dikonfigurasikan. + server_error: Server kebenaran mengalami keadaan yang tidak dijangka yang menghalangnya daripada memenuhi permintaan. + temporarily_unavailable: Server kebenaran pada masa ini tidak dapat mengendalikan permintaan kerana beban berlebihan sementara atau penyelenggaraan server. + unauthorized_client: Klien tidak dibenarkan untuk melaksanakan permintaan ini menggunakan kaedah ini. + unsupported_grant_type: Jenis pemberian kebenaran tidak disokong oleh server kebenaran. + unsupported_response_type: Server kebenaran tidak menyokong jenis respons ini. flash: applications: create: @@ -27,26 +109,87 @@ ms: notice: Aplikasi dipadamkan. update: notice: Aplikasi dikemaskini. + authorized_applications: + destroy: + notice: Aplikasi dipadamkan. grouped_scopes: + access: + read: Akses baca sahaja + read/write: Akses baca dan tulis + write: Akses tulis sahaja title: accounts: Akaun admin/accounts: Pengurusan akaun admin/all: Semua fungsi pengurusan admin/reports: Pengurusan laporan + all: Akses penuh ke akaun Mastodon anda + blocks: Blok + bookmarks: Penanda buku conversations: Perbualan + crypto: Penyulitan hujung ke hujung + favourites: Kegemaran + filters: Penapis + follow: Ikut, Senyap dan Blok follows: Ikutan + lists: Senarai media: Lampiran media + mutes: Senyapkan notifications: Pemberitahuan push: Pemberitahuan segera reports: Laporan search: Cari statuses: Hantaran + layouts: + admin: + nav: + applications: Aplikasi + oauth2_provider: Pembekal OAuth2 + application: + title: Keizinan OAuth diperlukan scopes: admin:read: baca semua data pada pelayan admin:read:accounts: baca maklumat sensitif untuk semua akaun + admin:read:canonical_email_blocks: baca maklumat sensitif semua blok e-mel kanonik + admin:read:domain_allows: baca maklumat sensitif semua domain yang dibenarkan + admin:read:domain_blocks: baca maklumat sensitif semua blok domain + admin:read:email_domain_blocks: baca maklumat sensitif semua blok domain e-mel + admin:read:ip_blocks: baca maklumat sensitif semua blok IP admin:read:reports: baca maklumat sensitif untuk semua laporan dan akaun-akaun yang dilaporkan admin:write: mengubah semua data pada pelayan + admin:write:accounts: melakukan tindakan penyederhanaan pada akaun + admin:write:canonical_email_blocks: melakukan tindakan penyederhanaan pada blok e-mel kanonik + admin:write:domain_allows: melakukan tindakan penyederhanaan pada domain yang dibenarkan + admin:write:domain_blocks: melakukan tindakan penyederhanaan pada blok domain + admin:write:email_domain_blocks: melakukan tindakan penyederhanaan pada blok domain e-mel + admin:write:ip_blocks: melakukan tindakan penyederhanaan pada blok IP + admin:write:reports: melakukan tindakan penyederhanaan ke atas laporan + crypto: gunakan penyulitan hujung ke hujung + follow: mengubah suai perhubungan akaun + push: terima pemberitahuan tolak anda + read: baca semua data akaun anda + read:accounts: lihat maklumat akaun + read:blocks: lihat blok anda + read:bookmarks: lihat penanda halaman anda + read:favourites: lihat kegemaran anda + read:filters: lihat penapis anda + read:follows: lihat senarai yang anda ikuti + read:lists: lihat senarai anda + read:mutes: lihat senarai yang anda senyapkan + read:notifications: lihat notifikasi anda + read:reports: lihat laporan anda + read:search: cari bagi pihak anda read:statuses: lihat semua hantaran + write: ubahsuai semua data akaun anda + write:accounts: ubaisuai profail anda + write:blocks: domain dan akaun blok write:bookmarks: menandabuku hantaran - write:favourites: hantaran kegemaran + write:conversations: senyapkan dan padamkan perbualan + write:favourites: pos kesukaan + write:filters: cipta penapis + write:follows: ikut orang + write:lists: cipta senarai + write:media: memuat naik fail media + write:mutes: membisukan orang dan perbualan + write:notifications: kosongkan pemberitahuan anda + write:reports: melaporkan orang lain write:statuses: terbitkan hantaran diff --git a/config/locales/doorkeeper.my.yml b/config/locales/doorkeeper.my.yml index 5e1fc6bee9..bce6039eae 100644 --- a/config/locales/doorkeeper.my.yml +++ b/config/locales/doorkeeper.my.yml @@ -1 +1,195 @@ +--- my: + activerecord: + attributes: + doorkeeper/application: + name: အက်ပလီကေးရှင်းအမည် + redirect_uri: URI ကို ပြန်ညွှန်းရန် + scopes: နယ်ပယ်များ + website: အက်ပလီကေးရှင်းဝဘ်ဆိုဒ် + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: အပိုင်းတစ်ပိုင်း မပါဝင်နိုင်ပါ။ + invalid_uri: သည် မှန်ကန်သော URI ဖြစ်ရမည်။ + relative_uri: URI ဖြစ်ရမည်။ + secured_uri: သည် HTTPS/SSL URI ဖြစ်ရမည်။ + doorkeeper: + applications: + buttons: + authorize: လုပ်ပိုင်ခွင့် + cancel: ပယ်ဖျက်မည် + destroy: ဖျက်ဆီးမည် + edit: ပြင်မည် + submit: တင်သွင်းမည် + confirmations: + destroy: သေချာပါသလား? + edit: + title: အက်ပလီကေးရှင်းကို ပြင်ဆင်ရန် + form: + error: အိုး၊ သင့်ဖောင်မှာ အမှားအယွင်းများရှိနိုင်သောကြောင့် စစ်ဆေးပါ + help: + native_redirect_uri: ဒေသတွင်းစမ်းသပ်မှုများအတွက် %{native_redirect_uri} ကို အသုံးပြုပါ + redirect_uri: URI တစ်ခုစီအတွက် လိုင်းတစ်ကြောင်းသုံးပါ + scopes: နယ်ပယ်များကို နေရာလွတ်များဖြင့် ခွဲခြားပါ။ မူလသတ်မှတ်ထားသည့်နယ်ပယ်များ အသုံးပြုရန်အတွက် အလွတ် ချန်ထားပါ။ + index: + application: အက်ပလီကေးရှင်း + callback_url: URL ပြန်ခေါ်ရန် + delete: ဖျက်မည် + empty: သင့်တွင် အက်ပလီကေးရှင်းများ မရှိပါ။ + name: အမည် + new: အက်ပလီကေးရှင်းအသစ် + scopes: နယ်ပယ်များ + show: ပြရန် + title: သင့်အက်ပလီကေးရှင်းများ + new: + title: အက်ပလီကေးရှင်းအသစ် + show: + actions: လုပ်ဆောင်ချက်များ + application_id: Client ကီး + callback_urls: URLs ပြန်ခေါ်ရန် + scopes: နယ်ပယ်များ + secret: Client လျှို့ဝှက်ချက် + title: အက်ပလီကေးရှင်း - %{name} + authorizations: + buttons: + authorize: လုပ်ပိုင်ခွင့် + deny: ငြင်းရန် + error: + title: အမှားအယွင်းတစ်ခု ဖြစ်ပေါ်ခဲ့သည် + new: + prompt_html: "%{client_name} က သင့်အကောင့်သို့ ဝင်ရောက်ရန် ခွင့်ပြုချက်ရယူလိုပါသည်။ ၎င်းမှာ ပြင်ပကြားခံအက်ပလီကေးရှင်းတစ်ခုဖြစ်သည်။ သင် မယုံကြည်ပါက ၎င်းကိုခွင့်မပြုသင့်ပါ။" + review_permissions: ခွင့်ပြုချက်များကို ပြန်လည်သုံးသပ်ပါ + title: ခွင့်ပြုချက် လိုအပ်သည် + show: + title: ဤခွင့်ပြုချက်ကုဒ်ကို ကူးယူပြီး အက်ပလီကေးရှင်းသို့ ကူးထည့်ပါ။ + authorized_applications: + buttons: + revoke: ပြန်ရုပ်သိမ်းရန် + confirmations: + revoke: သေချာပါသလား။ + index: + authorized_at: "%{date} တွင် ခွင့်ပြုခဲ့သည်" + description_html: "၎င်းတို့မှာ API အသုံးပြု၍ သင့်အကောင့်ကို ဝင်ရောက်ကြည့်ရှုနိုင်သော အက်ပလီကေးရှင်းများဖြစ်သည်။ ဤနေရာတွင် သင်မသိသော အက်ပလီကေးရှင်းများ ရှိပါက သို့မဟုတ် အက်ပလီကေးရှင်းတစ်ခုသည် လွဲမှားစွာ လုပ်ဆောင်နေပါက ၎င်း၏ ဝင်ရောက်ခွင့်ကို သင် ပြန်လည်ရုပ်သိမ်းနိုင်သည်။" + last_used_at: "%{date} တွင် နောက်ဆုံးအသုံးပြုခဲ့သည်" + never_used: မသုံးဖူးပါ + scopes: ခွင့်ပြုချက်များ + superapp: အတွင်းပိုင်း + title: ခွင့်ပြုထားသော အက်ပလီကေးရှင်းများ + errors: + messages: + access_denied: မူလပိုင်ရှင် သို့မဟုတ် ခွင့်ပြုချက်ရှိသောဆာဗာမှ တောင်းဆိုချက်ကို ငြင်းပယ်ခဲ့သည်။ + credential_flow_not_configured: Doorkeeper.configure.resource_owner_from_credentials ကို သတ်မှတ်မထားသည့်အတွက် မူလပိုင်ရှင် စကားဝှက် အထောက်အထားများထည့်သွင်းခြင်းမှာ မအောင်မြင်တော့ပါ။ + invalid_client: Client အထောက်အထားစိစစ်မှု မအောင်မြင်ခြင်းမှာ အမည်မသိ Client ဖြစ်ခြင်း၊ Client စစ်မှန်ကြောင်းအထောက်အထားမပါဝင်ခြင်း သို့မဟုတ် ပံ့ပိုးမထားသည့် အထောက်အထားဖြစ်နေခြင်းကြောင့် ဖြစ်ပါသည်။ + invalid_grant: ပံ့ပိုးပေးထားသည့် ခွင့်ပြုချက်ပေးသည် မမှန်ကန်ပါ၊ သက်တမ်းကုန်၊ ရုပ်သိမ်းလိုက်သည်၊ ခွင့်ပြုချက်တောင်းခံမှုတွင် အသုံးပြုထားသော ပြန်ညွှန်း URI နှင့် မကိုက်ညီပါ သို့မဟုတ် အခြားအသုံးပြုသူထံသို့ ထုတ်ပေးထားသည်။ + invalid_redirect_uri: ပြန်ညွှန်းထားခြင်းတွင် ပါဝင်သော URI မှာ မမှန်ကန်ပါ။ + invalid_request: + missing_param: ပျောက်နေသည့် လိုအပ်သောအရာ - %{value}။ + request_not_authorized: ခွင့်ပြုချက်တောင်းခံရန် လိုအပ်ပါသည်။ တောင်းဆိုမှုခွင့်ပြုချက်အတွက် လိုအပ်သောအရာမှာ ပျောက်ဆုံးနေခြင်း သို့မဟုတ် မမှန်ကန်ခြင်း ကြောင့်ဖြစ်ပါသည်။ + unknown: တောင်းဆိုချက်တွင် ပံ့ပိုးမထားသော တန်ဖိုးတစ်ခုပါဝင်သည့် လိုအပ်သောအချက်အလက်တစ်ခု ပျောက်ဆုံးနေပါသည် သို့မဟုတ် ပုံစံမှားယွင်းနေပါသည်။ + invalid_resource_owner: ပံ့ပိုးပေးထားသည့် မူလပိုင်ရှင်အထောက်အထားများမှာ မမှန်ကန်ပါ သို့မဟုတ် မူလပိုင်ရှင်ကို ရှာမတွေ့ပါ။ + invalid_scope: တောင်းဆိုထားသော နယ်ပယ်မှာ မမှန်ကန်ခြင်း၊ မသိခြင်း သို့မဟုတ် ပုံစံမမှန်ကန်ခြင်းတို့ကြောင့် ဖြစ်ပါသည်။ + invalid_token: + expired: အသုံးပြုခွင့် တိုကင် သက်တမ်းကုန်သွားပါပြီ + revoked: အသုံးပြုခွင့်တိုကင်ကို ရုပ်သိမ်းခဲ့သည် + unknown: အသုံးပြုခွင့်တိုကင်မှာ မမှန်ကန်ပါ + resource_owner_authenticator_not_configured: Doorkeeper.configure.resource_owner_authenticator ကို ပြုပြင်မွမ်းမံမှုအားဖယ်ရှားထားခြင်းကြောင့် မူလပိုင်ရှင်ရှာဖွေခြင်းမှာ မအောင်မြင်ပါ။ + server_error: ခွင့်ပြုထားသောဆာဗာသည် တောင်းဆိုချက်ကို မဖြည့်ဆည်းပေးနိုင်သည့် မမျှော်လင့်ထားသော အခြေအနေတစ်ခုကို ကြုံတွေ့ခဲ့ရသည်။ + temporarily_unavailable: ဆာဗာမှာ ယာယီအလုပ်များပိုလုပ်နေရခြင်း သို့မဟုတ် ဆာဗာပြုပြင်ထိန်းသိမ်းမှုတို့ကြောင့် တောင်းဆိုချက်ကို လောလောဆယ်တွင် ကိုင်တွယ်နိုင်ခြင်းမရှိသေးပါ။ + unauthorized_client: ဤနည်းလမ်းကို အသုံးပြု၍ Client မှ ဤတောင်းဆိုမှုကို ဆောင်ရွက်ခွင့်မရှိပါ။ + unsupported_grant_type: တရားဝင်ခွင့်ပြုချက်အမျိုးအစားကို ခွင့်ပြုချက်ဆာဗာမှ မပံ့ပိုးထားပါ။ + unsupported_response_type: ခွင့်ပြုထားသောဆာဗာသည် ဤတုံ့ပြန်မှုအမျိုးအစားကို မပံ့ပိုးပါ။ + flash: + applications: + create: + notice: အက်ပလီကေးရှင်းကို ဖန်တီးခဲ့သည်။ + destroy: + notice: အက်ပလီကေးရှင်းကို ဖျက်ခဲ့သည်။ + update: + notice: အက်ပလီကေးရှင်းကို ပြင်ဆင်ခဲ့သည်။ + authorized_applications: + destroy: + notice: အက်ပလီကေးရှင်းကို ပြန်ရုပ်သိမ်းခဲ့သည်။ + grouped_scopes: + access: + read: ဖတ်ခွင့်သာရှိသည် + read/write: ဖတ်ပြီးပြင်ဆင်ခွင့်ရှိသည် + write: ပြင်ခွင့်သာရှိသည် + title: + accounts: အကောင့်များ + admin/accounts: အကောင့်စီမံခန့်ခွဲမှု + admin/all: စီမံခွင့်ဆိုင်ရာ လုပ်ငန်းဆောင်တာအားလုံး + admin/reports: မှတ်တမ်းများ စီမံခန့်ခွဲခြင်း + all: သင်၏ Mastodon အကောင့်သို့ အပြည့်အဝ ဝင်ရောက်ခွင့် + blocks: ပိတ်ပင်ထားမှုများ + bookmarks: မှတ်ထားသည်များ + conversations: စကားဝိုင်းများ + crypto: ပေးပို့သူနှင့် ရရှိသူများသာသိနိုင်သော လုံခြုံမှုနည်းလမ်း + favourites: Favorites + filters: စစ်ထုတ်ထားခြင်းများ + follow: စောင့်ကြည့်ခြင်း၊ အသံပိတ်ခြင်းနှင့် ပိတ်ပင်ခြင်းများ + follows: စောင့်ကြည့်မယ် + lists: စာရင်းများ + media: မီဒီယာ ပူးတွဲချက်များ + mutes: အသံပိတ်ထားရန် + notifications: အသိပေးချက်များ + push: အသိပေးချက်များအား ရအောင်ပို့ခြင်း + reports: မှတ်တမ်းများ + search: ရှာရန် + statuses: ပို့စ်များ + layouts: + admin: + nav: + applications: အက်ပလီကေးရှင်းများ + oauth2_provider: OAuth2 ပံ့ပိုးပေးသူ + application: + title: OAuth ခွင့်ပြုချက် လိုအပ်ပါသည် + scopes: + admin:read: ဆာဗာရှိ အချက်အလက်အားလုံးကို ဖတ်ပါ + admin:read:accounts: အကောင့်အားလုံး၏ အရေးကြီးသော သတင်းအချက်အလက်များကို ဖတ်ပါ + admin:read:canonical_email_blocks: ပိတ်ပင်ထားသော Canonical Email အားလုံး၏ အရေးကြီးသောသတင်းအချက်အလက်များကို ဖတ်ပါ + admin:read:domain_allows: ခွင့်ပြုထားသော ဒိုမိန်းအားလုံး၏ အရေးကြီးသော သတင်းအချက်အလက်များကို ဖတ်ပါ + admin:read:domain_blocks: ပိတ်ပင်ထားသော ဒိုမိန်းအားလုံး၏ အရေးကြီးသော သတင်းအချက်အလက်များကို ဖတ်ပါ + admin:read:email_domain_blocks: ပိတ်ပင်ထားသော အီးမေးလ်ဒိုမိန်းအားလုံး၏ အရေးကြီးသောသတင်းအချက်အလက်များကို ဖတ်ပါ + admin:read:ip_blocks: ပိတ်ပင်ထားသော IP အားလုံး၏ အရေးကြီးသောသတင်းအချက်အလက်များကို ဖတ်ပါ + admin:read:reports: မှတ်တမ်းများနှင့် တိုင်ကြားထားသောအကောင့်များအားလုံး၏ အရေးကြီးသော အချက်အလက်ကို ဖတ်ပါ။ + admin:write: ဆာဗာပေါ်ရှိ အချက်အလက်အားလုံးကို ပြင်ဆင်ပါ + admin:write:accounts: အကောင့်များအား စိစစ်လုပ်ဆောင်မှုများ ဆောင်ရွက်ပါ + admin:write:canonical_email_blocks: Canonical Email ပိတ်ပင်ထားမှုများအား စိစစ်လုပ်ဆောင်မှုများ ဆောင်ရွက်ပါ + admin:write:domain_allows: ခွင့်ပြုထားသောဒိုမိန်းပေါ်တွင် စိစစ်လုပ်ဆောင်ချက်များ ဆောင်ရွက်ပါ + admin:write:domain_blocks: ပိတ်ပင်ထားသောဒိုမိန်းပေါ်တွင် စိစစ်လုပ်ဆောင်ချက်များ ဆောင်ရွက်ပါ + admin:write:email_domain_blocks: ပိတ်ပင်ထားသော အီးမေးလ်ဒိုမိန်းပေါ်တွင် စိစစ်လုပ်ဆောင်ချက်များ ဆောင်ရွက်ပါ + admin:write:ip_blocks: IP ပိတ်ပင်ခြင်းများအတွက် စိစစ်လုပ်ဆောင်မှုများ ဆောင်ရွက်ပါ + admin:write:reports: အစီရင်ခံစာများပေါ်တွင် စိစစ်လုပ်ဆောင်ချက်များ ဆောင်ရွက်ပါ + crypto: ပေးပို့သူနှင့် ရရှိသူများသာသိနိုင်သော လုံခြုံမှုနည်းလမ်းကို အသုံးပြုပါ + follow: အကောင့်ဆက်ဆံရေးများကို ပြင်ဆင်ပါ + push: သင်ရရှိအောင်ပေးပို့ထားသည့် အသိပေးချက်များကို လက်ခံပါ + read: သင့်အကောင့်အချက်အလက်အားလုံးကို ဖတ်ပါ + read:accounts: အကောင့်အချက်အလက်များကို ကြည့်ပါ + read:blocks: သင် ပိတ်ပင်ထားသည်များကို ကြည့်ပါ + read:bookmarks: သင် မှတ်ထားသည်များကို ကြည့်ပါ + read:favourites: favorites များကို ကြည့်ပါ + read:filters: သင် စစ်ထုတ်ထားမှုများကို ကြည့်ပါ + read:follows: သင့်အားစောင့်ကြည့်နေသူများကို ကြည့်ပါ + read:lists: သင့်စာရင်းများကို ကြည့်ပါ + read:mutes: သင်အသံပိတ်ထားမှုများကို ကြည့်ပါ + read:notifications: သင့်အသိပေးချက်များကို ကြည့်ပါ + read:reports: သင့်မှတ်တမ်းများကို ကြည့်ပါ + read:search: သင့်ကိုယ်စား ရှာဖွေပါ + read:statuses: ပို့စ်အားလုံးကို ကြည့်ပါ + write: သင့်အကောင့်၏ အချက်အလက်အားလုံးကို ပြင်ဆင်ပါ + write:accounts: သင့်ပရိုဖိုင်ကို ပြင်ဆင်ပါ + write:blocks: အကောင့်များနှင့် ဒိုမိန်းများကို ပိတ်ပင်ပါ + write:bookmarks: မှတ်ထားသောပို့စ်များ + write:conversations: စကားဝိုင်းများကို အသံပိတ်ပြီး ဖျက်ပါ + write:favourites: favorite ပို့စ်များ + write:filters: စစ်ထုတ်ခြင်းအား ဖန်တီးပါ + write:follows: စောင့်ကြည့်ရန် + write:lists: စာရင်းများ ဖန်တီးရန် + write:media: မီဒီယာဖိုင်များကို အင်တာနက်ပေါ်တင်ပါ + write:mutes: လူများနှင့် စကားဝိုင်းများကို ပိတ်ထားပါ + write:notifications: သင့်အအသိပေးချက်များကို ရှင်းလင်းပါ + write:reports: အခြားလူများကို သတင်းပို့မည် + write:statuses: ပို့စ်များအား ရအောင်ပို့ခြင်း diff --git a/config/locales/doorkeeper.nl.yml b/config/locales/doorkeeper.nl.yml index f9e90e7957..65e2bfcb7a 100644 --- a/config/locales/doorkeeper.nl.yml +++ b/config/locales/doorkeeper.nl.yml @@ -170,7 +170,7 @@ nl: read:accounts: informatie accounts bekijken read:blocks: jouw geblokkeerde gebruikers bekijken read:bookmarks: jouw bladwijzers bekijken - read:favourites: jouw favorieten bekijken + read:favourites: je favorieten tonen read:filters: jouw filters bekijken read:follows: de accounts die jij volgt bekijken read:lists: jouw lijsten bekijken @@ -184,7 +184,7 @@ nl: write:blocks: accounts en domeinen blokkeren write:bookmarks: berichten aan bladwijzers toevoegen write:conversations: gespreken negeren en verwijderen - write:favourites: berichten als favoriet markeren + write:favourites: favoriete berichten write:filters: filters aanmaken write:follows: mensen volgen write:lists: lijsten aanmaken diff --git a/config/locales/doorkeeper.nn.yml b/config/locales/doorkeeper.nn.yml index 0582b53f8a..66dd0f9093 100644 --- a/config/locales/doorkeeper.nn.yml +++ b/config/locales/doorkeeper.nn.yml @@ -184,7 +184,7 @@ nn: write:blocks: blokker kontoar og domene write:bookmarks: bokmerk innlegg write:conversations: målbind og slett samtalar - write:favourites: merk innlegg som favoritt + write:favourites: favorittmarker innlegg write:filters: lag filter write:follows: fylg folk write:lists: lag lister diff --git a/config/locales/doorkeeper.oc.yml b/config/locales/doorkeeper.oc.yml index 84935d49ba..64bc3a43e2 100644 --- a/config/locales/doorkeeper.oc.yml +++ b/config/locales/doorkeeper.oc.yml @@ -127,7 +127,6 @@ oc: bookmarks: Marcadors conversations: Conversacions crypto: Chiframent del cap a la fin - favourites: Favorits filters: Filtres follow: Seguidors, Silenciats e blocats follows: Abonaments @@ -165,7 +164,6 @@ oc: read:accounts: veire las informacions del compte read:blocks: veire vòstres blocatges read:bookmarks: veire vòstres marcadors - read:favourites: veire vòstres favorits read:filters: veire vòstres filtres read:follows: veire vòstres abonaments read:lists: veire vòstras listas @@ -179,7 +177,6 @@ oc: write:blocks: blocar de comptes e de domenis write:bookmarks: ajustar als marcadors write:conversations: amudir e suprimir las conversacions - write:favourites: metre en favorit write:filters: crear de filtres write:follows: sègre de mond write:lists: crear de listas diff --git a/config/locales/doorkeeper.pl.yml b/config/locales/doorkeeper.pl.yml index 1891ada150..226c0d403c 100644 --- a/config/locales/doorkeeper.pl.yml +++ b/config/locales/doorkeeper.pl.yml @@ -184,7 +184,7 @@ pl: write:blocks: możliwość blokowania domen i użytkowników write:bookmarks: możliwość dodawania wpisów do zakładek write:conversations: wycisz i usuń konwersacje - write:favourites: możliwość dodawnia wpisów do ulubionych + write:favourites: polubianie wpisów write:filters: możliwość tworzenia filtrów write:follows: możliwość obserwowania ludzi write:lists: możliwość tworzenia list diff --git a/config/locales/doorkeeper.pt-BR.yml b/config/locales/doorkeeper.pt-BR.yml index 6b64badf7a..d7e9353b59 100644 --- a/config/locales/doorkeeper.pt-BR.yml +++ b/config/locales/doorkeeper.pt-BR.yml @@ -127,7 +127,7 @@ pt-BR: bookmarks: Salvos conversations: Conversas crypto: Criptografia de ponta a ponta - favourites: Favoritos + favourites: Favoritas filters: Filtros follow: Seguidores, Silenciados e Bloqueados follows: Seguidores @@ -170,7 +170,7 @@ pt-BR: read:accounts: ver informações das contas read:blocks: ver seus bloqueados read:bookmarks: ver seus salvos - read:favourites: ver seus favoritos + read:favourites: veja suas favoritas read:filters: ver seus filtros read:follows: ver quem você segue read:lists: ver suas listas @@ -184,7 +184,7 @@ pt-BR: write:blocks: bloquear contas e domínios write:bookmarks: salvar toots write:conversations: silenciar e excluir conversas - write:favourites: favoritar toots + write:favourites: publicações favoritas write:filters: criar filtros write:follows: seguir pessoas write:lists: criar listas diff --git a/config/locales/doorkeeper.pt-PT.yml b/config/locales/doorkeeper.pt-PT.yml index 2dee34bd9a..31f6e46278 100644 --- a/config/locales/doorkeeper.pt-PT.yml +++ b/config/locales/doorkeeper.pt-PT.yml @@ -184,7 +184,7 @@ pt-PT: write:blocks: bloquear contas e domínios write:bookmarks: estado dos favoritos write:conversations: silenciar e eliminar conversas - write:favourites: estado dos favoritos + write:favourites: assinalar como favoritas write:filters: criar filtros write:follows: seguir pessoas write:lists: criar listas diff --git a/config/locales/doorkeeper.ro.yml b/config/locales/doorkeeper.ro.yml index 59e67aeb24..fa28373521 100644 --- a/config/locales/doorkeeper.ro.yml +++ b/config/locales/doorkeeper.ro.yml @@ -122,12 +122,14 @@ ro: admin/accounts: Administrarea conturilor admin/all: Toate funcțiile administrative admin/reports: Administrarea rapoartelor + all: Acces deplin la contul tău Mastodon blocks: Blocuri bookmarks: Marcaje conversations: Conversații crypto: Criptare în ambele părți favourites: Favorite filters: Filtre + follow: Urmăriți, Ignorați și Blocați follows: Urmăriri lists: Liste media: Atașamente media @@ -158,7 +160,7 @@ ro: read:accounts: vede informațiile privind conturile read:blocks: vede blocurile tale read:bookmarks: vede marcajele tale - read:favourites: vede favoritele tale + read:favourites: vezi favoritele tale read:filters: vede filtrele tale read:follows: vede urmăririle tale read:lists: vede listele tale @@ -172,7 +174,7 @@ ro: write:blocks: blochează conturile și domeniile write:bookmarks: marchează stările write:conversations: dezactivează și șterge conversațiile - write:favourites: favorizează stările + write:favourites: Postări favorite write:filters: creează filtre write:follows: urmărește persoane write:lists: creează liste diff --git a/config/locales/doorkeeper.ru.yml b/config/locales/doorkeeper.ru.yml index d8262dae98..ce8392cb11 100644 --- a/config/locales/doorkeeper.ru.yml +++ b/config/locales/doorkeeper.ru.yml @@ -127,7 +127,7 @@ ru: bookmarks: Закладки conversations: Диалоги crypto: Сквозное шифрование - favourites: Избранное + favourites: Избранные filters: Фильтры follow: Подписки, заглушенные и заблокированные follows: Подписки @@ -184,7 +184,7 @@ ru: write:blocks: блокировать учётные записи и домены write:bookmarks: добавлять посты в закладки write:conversations: игнорировать и удалить разговоры - write:favourites: отмечать посты как избранные + write:favourites: добавить посты в избранное write:filters: создавать фильтры write:follows: подписываться на людей write:lists: создавать списки diff --git a/config/locales/doorkeeper.sc.yml b/config/locales/doorkeeper.sc.yml index 7631d2cc16..1f1d38f3a9 100644 --- a/config/locales/doorkeeper.sc.yml +++ b/config/locales/doorkeeper.sc.yml @@ -124,7 +124,6 @@ sc: read:accounts: bìdere is informatziones in su contu read:blocks: bìdere is blocos tuos read:bookmarks: bìdere is sinnalibros tuos - read:favourites: bìdere is preferidos tuos read:filters: bìdere is filtros tuos read:follows: bìdere is sighiduras tuas read:lists: bìdere is listas tuas @@ -137,7 +136,6 @@ sc: write:accounts: modificare su profilu tuo write:blocks: blocare contos e domìnios write:bookmarks: agiùnghere is istados a is sinnalibros - write:favourites: pone istados in is preferidos write:filters: creare filtros write:follows: sighire persones write:lists: creare listas diff --git a/config/locales/doorkeeper.sco.yml b/config/locales/doorkeeper.sco.yml index 8b6ac83557..70341c3c69 100644 --- a/config/locales/doorkeeper.sco.yml +++ b/config/locales/doorkeeper.sco.yml @@ -126,7 +126,6 @@ sco: bookmarks: Buikmairks conversations: Conversations crypto: En-tae-en encryption - favourites: Favourites filters: Filters follows: Follaes lists: Lists @@ -158,7 +157,6 @@ sco: read:accounts: see accoonts information read:blocks: see yer dingies read:bookmarks: see yer buikmairks - read:favourites: see yer favourites read:filters: see yer filters read:follows: see yer follaes read:lists: see yer lists @@ -172,7 +170,6 @@ sco: write:blocks: dingie accoonts an domains write:bookmarks: buikmairk posts write:conversations: wheesht an delete conversations - write:favourites: favourite posts write:filters: mak filters write:follows: follae fowk write:lists: mak lists diff --git a/config/locales/doorkeeper.si.yml b/config/locales/doorkeeper.si.yml index 3f5fcd5c03..d3550cf598 100644 --- a/config/locales/doorkeeper.si.yml +++ b/config/locales/doorkeeper.si.yml @@ -58,10 +58,10 @@ si: authorize: සත්‍යාපනය deny: ප්‍රතික්ෂේප කරන්න error: - title: දෝෂයක් සිදුවී ඇත + title: දෝෂයක් සිදු වී ඇත new: prompt_html: "%{client_name} ඔබගේ ගිණුමට ප්‍රවේශ වීමට අවසර ලබා ගැනීමට කැමති වේ. එය තෙවන පාර්ශවීය යෙදුමකි. ඔබ එය විශ්වාස නොකරන්නේ නම්, ඔබ එයට අවසර නොදිය යුතුය." - review_permissions: අවසර සමාලෝචනය කරන්න + review_permissions: අවසර සමාලෝචනය title: බලය පැවරීමේ අවශ්ය show: title: මෙම අවසර කේතය පිටපත් කර එය යෙදුමට අලවන්න. @@ -73,11 +73,11 @@ si: index: authorized_at: "%{date}මත අවසර දී ඇත" description_html: මේවා API භාවිතයෙන් ඔබගේ ගිණුමට ප්‍රවේශ විය හැකි යෙදුම් වේ. ඔබ මෙහි හඳුනා නොගත් යෙදුම් තිබේ නම්, හෝ යෙදුමක් වැරදි ලෙස හැසිරෙන්නේ නම්, ඔබට එහි ප්‍රවේශය අවලංගු කළ හැක. - last_used_at: අවසන් වරට භාවිතා කළේ %{date} - never_used: කවදාවත් පාවිච්චි කළේ නැහැ + last_used_at: අන්තිම භාවිතය %{date} + never_used: භාවිතා කර නැත scopes: අවසර - superapp: අභ්යන්තර - title: ඔබගේ බලයලත් අයදුම්පත් + superapp: අභ්‍යන්තර + title: ඔබගේ බලයලත් යෙදුම් errors: messages: access_denied: සම්පත් හිමිකරු හෝ අවසර සේවාදායකය ඉල්ලීම ප්‍රතික්ෂේප කළේය. @@ -104,34 +104,34 @@ si: flash: applications: create: - notice: යෙදුම නිර්මාණය කරන ලදී. + notice: යෙදුම සෑදිණි. destroy: - notice: යෙදුම මකා ඇත. + notice: යෙදුම මැකිණි. update: - notice: යෙදුම යාවත්කාලීන කරන ලදී. + notice: යෙදුම යාවත්කාල විය. authorized_applications: destroy: notice: අයදුම්පත අවලංගු කරන ලදී. grouped_scopes: access: - read: කියවීමට පමණක් ප්‍රවේශය - read/write: කියවීමට සහ ලිවීමට ප්‍රවේශය - write: ලිවීමට පමණක් ප්‍රවේශය + read: ප්‍රවේශය කියවීමට පමණි + read/write: කියවීමට හා ලිවීමට ප්‍රවේශය + write: ප්‍රවේශය ලිවීමට පමණි title: accounts: ගිණුම් - admin/accounts: ගිණුම් පරිපාලනය + admin/accounts: ගිණුම් කළමනාකරණය admin/all: සියලුම පරිපාලන කාර්යයන් admin/reports: වාර්තා පරිපාලනය + all: ඔබගේ මාස්ටඩන් ගිණුමට පූර්ණ ප්‍රවේශය blocks: කුට්ටි - bookmarks: පිටු සලකුණු + bookmarks: පොත්යොමු conversations: සංවාද crypto: අන්ත සංකේතනය - favourites: ප්රියතම + favourites: ප්‍රියතමයන් filters: පෙරහන් follows: පහත සඳහන් lists: ලැයිස්තු - media: මාධ්ය ඇමුණුම් - mutes: නිහඬ කරයි + media: මාධ්‍ය ඇමුණුම් notifications: දැනුම්දීම් push: තල්ලු දැනුම්දීම් reports: වාර්තා @@ -143,41 +143,40 @@ si: applications: යෙදුම් oauth2_provider: වි.සත්‍යා.2 (OAuth) සැපයුම්කරු application: - title: වි.සත්යා. (OAuth) තොරතුරු අවශ්‍යයි + title: වි.සත්‍යා. (OAuth) අනුමැතිය අවශ්‍යයයි scopes: - admin:read: සේවාදායකයේ ඇති සියලුම දත්ත කියවන්න - admin:read:accounts: සියලුම ගිණුම් වල සංවේදී තොරතුරු කියවන්න - admin:read:reports: සියලුම වාර්තා සහ වාර්තා කළ ගිණුම් වල සංවේදී තොරතුරු කියවන්න - admin:write: සේවාදායකයේ සියලුම දත්ත වෙනස් කරන්න - admin:write:accounts: ගිණුම් මත මධ්‍යස්ථ ක්‍රියා සිදු කරන්න - admin:write:reports: වාර්තා මත මධ්‍යස්ථ ක්‍රියා සිදු කරන්න - crypto: end-to-end encryption භාවිතා කරන්න + admin:read: සේවාදායකයේ ඇති සියලුම දත්ත කියවයි + admin:read:accounts: සියලුම ගිණුම් වල සංවේදී තොරතුරු කියවයි + admin:read:reports: සියලුම වාර්තා සහ වාර්තා කළ ගිණුම් වල සංවේදී තොරතුරු කියවයි + admin:write: සේවාදායකයේ සියලුම දත්ත සංශෝධනය කරයි + admin:write:accounts: ගිණුම් සඳහා මැදිහත්කරණ ක්‍රියාමාර්ග ගනියි + admin:write:reports: වාර්තා සඳහා මැදිහත්කරණ ක්‍රියාමාර්ග ගනියි + crypto: අන්ත සංකේතනය භාවිතා කරයි follow: ගිණුම් සබඳතා වෙනස් කරන්න - push: ඔබගේ තල්ලු දැනුම්දීම් ලබා ගන්න - read: ඔබගේ ගිණුමේ සියලුම දත්ත කියවන්න - read:accounts: ගිණුම් තොරතුරු බලන්න + push: ඔබගේ තල්ලු දැනුම්දීම් ලබන්න + read: ඔබගේ ගිණුමේ සියලුම දත්ත කියවයි + read:accounts: ගිණුම්වල තොරතුරු දකියි read:blocks: ඔබගේ වාරණ බලන්න - read:bookmarks: ඔබගේ පිටු සලකුණු බලන්න - read:favourites: ඔබේ ප්රියතම බලන්න + read:bookmarks: ඔබගේ පොත්යොමු දකියි + read:favourites: ඔබගේ ප්‍රියතමයන් බලන්න read:filters: ඔබගේ පෙරහන් බලන්න read:follows: ඔබගේ පහත සඳහන් බලන්න read:lists: ඔබගේ ලැයිස්තු බලන්න read:mutes: ඔබේ ගොළු බලන්න - read:notifications: ඔබගේ දැනුම්දීම් බලන්න + read:notifications: ඔබගේ දැනුම්දීම් බලයි read:reports: ඔබගේ වාර්තා බලන්න - read:search: ඔබ වෙනුවෙන් සොයන්න - read:statuses: සියලුම පෝස්ට් බලන්න + read:search: ඔබ වෙනුවෙන් සොයයි + read:statuses: සියලු ලිපි බලයි write: ඔබගේ ගිණුමේ සියලුම දත්ත වෙනස් කරන්න write:accounts: ඔබගේ පැතිකඩ වෙනස් කරන්න - write:blocks: ගිණුම් සහ වසම් අවහිර කරන්න - write:bookmarks: පිටු සලකුණු සටහන් + write:blocks: ගිණුම් සහ වසම් අවහිර කරයි + write:bookmarks: ලිපි වලට පොත්යොමු තබයි write:conversations: සංවාද නිහඬ කිරීම සහ මකා දැමීම write:favourites: ප්‍රියතම ලිපි - write:filters: පෙරහන් කරන්න + write:filters: පෙරහන් සාදයි write:follows: මිනිසුන් අනුගමනය කරන්න write:lists: ලැයිස්තු සාදන්න - write:media: මාධ්‍ය ගොනු උඩුගත කරන්න - write:mutes: මිනිසුන් සහ සංවාද කරන්න - write:notifications: ඔබගේ දැනුම්දීම් හිස්කරන්න - write:reports: වෙනත් පුද්ගලයින් වාර්තා කරන්න - write:statuses: පළ කිරීම් පළ කරන්න + write:media: මාධ්‍ය ගොනු උඩුගත කරයි + write:mutes: සංවාද හා පුද්ගලයින් නිහඬ කරයි + write:notifications: ඔබගේ දැනුම්දීම් හිස් කරයි + write:statuses: ලිපි පළ කරයි diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml index ed85ab1c9d..acfd59b3e7 100644 --- a/config/locales/doorkeeper.sk.yml +++ b/config/locales/doorkeeper.sk.yml @@ -159,7 +159,6 @@ sk: read:accounts: prezri si informácie o účte read:blocks: prezri svoje bloky read:bookmarks: pozri svoje záložky - read:favourites: prezri svoje obľúbené read:filters: prezri svoje filtrovanie read:follows: prezri si svoje sledovania read:lists: prezri si svoje zoznamy diff --git a/config/locales/doorkeeper.sq.yml b/config/locales/doorkeeper.sq.yml index afa91bc870..308a5429a6 100644 --- a/config/locales/doorkeeper.sq.yml +++ b/config/locales/doorkeeper.sq.yml @@ -170,7 +170,7 @@ sq: read:accounts: të shohë hollësi llogarish read:blocks: të shohë blloqet tuaja read:bookmarks: të shohë faqerojtësit tuaj - read:favourites: të shohë të parapëlqyerit tuaj + read:favourites: shihni të parapëlqyerit tuaj read:filters: të shohë filtrat tuaj read:follows: të shohë ndjekësit tuaj read:lists: të shohë listat tuaja @@ -184,7 +184,7 @@ sq: write:blocks: të bllokojë llogari dhe përkatësi write:bookmarks: të faqeruajë gjendje write:conversations: heshtoni dhe fshini biseda - write:favourites: të parapëlqejë gjendje + write:favourites: postime të parapëlqyer write:filters: të krijojë filtra write:follows: të ndjekë persona write:lists: të krijojë lista diff --git a/config/locales/doorkeeper.sr-Latn.yml b/config/locales/doorkeeper.sr-Latn.yml index 5e46d01240..a4eb7bd33e 100644 --- a/config/locales/doorkeeper.sr-Latn.yml +++ b/config/locales/doorkeeper.sr-Latn.yml @@ -122,16 +122,18 @@ sr-Latn: admin/accounts: Administracija naloga admin/all: Sve funkcije administracije admin/reports: Administracija prijava + all: Potpuni pristup vašem Mastodon nalogu blocks: Blokirani bookmarks: Obeleživači conversations: Razgovori crypto: End-to-end enkripcija - favourites: Omiljeni + favourites: Omiljeno filters: Filteri + follow: Praćenja, ignorisanja i blokiranja follows: Praćeni lists: Liste media: Multimedijalni prilozi - mutes: Utišani + mutes: Ignorisani notifications: Obaveštenja push: Prosleđena obaveštenja reports: Prijave @@ -147,17 +149,22 @@ sr-Latn: scopes: admin:read: čitanje svih podataka na serveru admin:read:accounts: čitanje osetljivih podataka za sve naloge + admin:read:canonical_email_blocks: pročitaj osetljive informacije i kanonske imejl blokove admin:read:domain_allows: pročitaj osetljive informacije za sve dozvole domena admin:read:domain_blocks: pročitaj osetljive informacije za sve blokove domena + admin:read:email_domain_blocks: pročitaj osetljive informacije svih blokova imejl domena admin:read:ip_blocks: pročitaj osetljive informacije za sve IP blokove admin:read:reports: čitanje osetljivih podataka svih izveštaja i prijavljenih naloga admin:write: menjanje svih podataka na serveru admin:write:accounts: vršenje moderatorskih aktivnosti nad nalozima + admin:write:canonical_email_blocks: izvrši moderacijske radnje nad kanonskim imejl blokovima + admin:write:domain_allows: izvrši moderacijske radnje nad dozvolama domena admin:write:domain_blocks: izvrši moderatorske aktivnosti na blokovima domena + admin:write:email_domain_blocks: izvrši moderacijske radnje nad blokovima imejl domena admin:write:ip_blocks: izvrši moderatorske aktivnosti na IP blokovima admin:write:reports: vršenje moderatorskih aktivnosti nad izveštajima crypto: korišćenje end-to-end enkripcije - follow: prati, blokira, odblokira i otprati naloge + follow: menja odnose naloga push: primanje prosleđenih obaveštenja read: čita podatke Vašeg naloga read:accounts: pogledaj informacije o nalozima @@ -167,7 +174,7 @@ sr-Latn: read:filters: pogledaj svoje filtere read:follows: pogledaj koga pratiš read:lists: pogledaj svoje liste - read:mutes: pogledaj svoje utišane + read:mutes: pogledaj ignorisanja read:notifications: pogledaj svoja obaveštenja read:reports: pogledaj svoje prijave read:search: pretraži u svoje ime @@ -176,13 +183,13 @@ sr-Latn: write:accounts: izmeni svoj profil write:blocks: blokiraj naloge i domene write:bookmarks: obeleži objave - write:conversations: utišaj i obriši razgovore + write:conversations: ignoriši i izbriši razgovore write:favourites: omiljene objave write:filters: kreiraj filtere write:follows: prati korisnike write:lists: kreiraj liste write:media: otpremi medijske datoteke - write:mutes: utišaj korinsike i razgovore + write:mutes: ignoriši korisnike i razgovore write:notifications: obriši svoja obaveštenja write:reports: prijavi druge korisnike write:statuses: objavi objave diff --git a/config/locales/doorkeeper.sr.yml b/config/locales/doorkeeper.sr.yml index 887a218953..a0439d6060 100644 --- a/config/locales/doorkeeper.sr.yml +++ b/config/locales/doorkeeper.sr.yml @@ -122,16 +122,18 @@ sr: admin/accounts: Администрација налога admin/all: Све функције администрације admin/reports: Администрација пријава + all: Потпуни приступ вашем Mastodon налогу blocks: Блокирани bookmarks: Обележивачи conversations: Разговори crypto: End-to-end енкрипција - favourites: Омиљени + favourites: Омиљено filters: Филтери + follow: Праћења, игнорисања и блокирања follows: Праћени lists: Листе media: Мултимедијални прилози - mutes: Утишани + mutes: Игнорисани notifications: Обавештења push: Прослеђена обавештења reports: Пријаве @@ -147,17 +149,22 @@ sr: scopes: admin:read: читање свих података на серверу admin:read:accounts: читање осетљивих података за све налоге + admin:read:canonical_email_blocks: прочитај осетљиве информације и канонске имејл блокове admin:read:domain_allows: прочитај осетљиве информације за све дозволе домена admin:read:domain_blocks: прочитај осетљиве информације за све блокове домена + admin:read:email_domain_blocks: прочитај осетљиве информације свих блокова имејл домена admin:read:ip_blocks: прочитај осетљиве информације за све IP блокове admin:read:reports: читање осетљивих података свих извештаја и пријављених налога admin:write: мењање свих података на серверу admin:write:accounts: вршење модераторских активности над налозима + admin:write:canonical_email_blocks: изврши модерацијске радње над канонским имејл блоковима + admin:write:domain_allows: изврши модерацијске радње над дозволама домена admin:write:domain_blocks: изврши модераторске активности на блоковима домена + admin:write:email_domain_blocks: изврши модерацијске радње над блоковима имејл домена admin:write:ip_blocks: изврши модераторске активности на IP блоковима admin:write:reports: вршење модераторских активности над извештајима crypto: коришћење end-to-end енкрипције - follow: прати, блокира, одблокира и отпрати налоге + follow: мења односе налога push: примање прослеђених обавештења read: чита податке Вашег налога read:accounts: погледај информације о налозима @@ -167,7 +174,7 @@ sr: read:filters: погледај своје филтере read:follows: погледај кога пратиш read:lists: погледај своје листе - read:mutes: погледај своје утишане + read:mutes: погледај игнорисања read:notifications: погледај своја обавештења read:reports: погледај своје пријаве read:search: претражи у своје име @@ -176,13 +183,13 @@ sr: write:accounts: измени свој профил write:blocks: блокирај налоге и домене write:bookmarks: обележи објаве - write:conversations: утишај и обриши разговоре + write:conversations: игнориши и избриши разговоре write:favourites: омиљене објаве write:filters: креирај филтере write:follows: прати кориснике write:lists: креирај листе write:media: отпреми медијске датотеке - write:mutes: утишај коринсике и разговоре + write:mutes: игнориши кориснике и разговоре write:notifications: обриши своја обавештења write:reports: пријави друге кориснике write:statuses: објави објаве diff --git a/config/locales/doorkeeper.sv.yml b/config/locales/doorkeeper.sv.yml index b6c4998967..f2c8bd34b8 100644 --- a/config/locales/doorkeeper.sv.yml +++ b/config/locales/doorkeeper.sv.yml @@ -184,7 +184,7 @@ sv: write:blocks: blockera konton och domäner write:bookmarks: bokmärka inlägg write:conversations: tysta och radera konversationer - write:favourites: favoritmarkera inlägg + write:favourites: favoritinlägg write:filters: skapa filter write:follows: följa folk write:lists: skapa listor diff --git a/config/locales/doorkeeper.th.yml b/config/locales/doorkeeper.th.yml index b36ec21b9e..3c2c75565b 100644 --- a/config/locales/doorkeeper.th.yml +++ b/config/locales/doorkeeper.th.yml @@ -82,12 +82,12 @@ th: messages: access_denied: เจ้าของทรัพยากรหรือเซิร์ฟเวอร์การอนุญาตปฏิเสธคำขอ credential_flow_not_configured: โฟลว์ข้อมูลประจำตัวรหัสผ่านเจ้าของทรัพยากรล้มเหลวเนื่องจากไม่ได้กำหนดค่า Doorkeeper.configure.resource_owner_from_credentials - invalid_client: การรับรองความถูกต้องไคลเอ็นต์ล้มเหลวเนื่องจากไคลเอ็นต์ที่ไม่รู้จัก ไม่มีการรับรองความถูกต้องไคลเอ็นต์ที่รวมอยู่ หรือวิธีการรับรองความถูกต้องที่ไม่รองรับ + invalid_client: การรับรองความถูกต้องไคลเอ็นต์ล้มเหลวเนื่องจากไคลเอ็นต์ที่ไม่รู้จัก ไม่ได้รวมการรับรองความถูกต้องไคลเอ็นต์ หรือวิธีการรับรองความถูกต้องที่ไม่รองรับ invalid_grant: การให้การรับรองความถูกต้องที่ให้มาไม่ถูกต้อง หมดอายุแล้ว เพิกถอนแล้ว ไม่ตรงกับ URI การเปลี่ยนเส้นทางที่ใช้ในคำขอการรับรองความถูกต้อง หรือออกให้ไคลเอ็นต์อื่น invalid_redirect_uri: URI การเปลี่ยนเส้นทางที่รวมอยู่ไม่ถูกต้อง invalid_request: missing_param: 'พารามิเตอร์ที่จำเป็นขาดหายไป: %{value}' - request_not_authorized: คำขอจำเป็นต้องได้รับอนุญาต พารามิเตอร์ที่จำเป็นสำหรับการอนุญาตคำขอขาดหายไปหรือไม่ถูกต้อง + request_not_authorized: จำเป็นต้องอนุญาตคำขอ พารามิเตอร์ที่จำเป็นสำหรับการอนุญาตคำขอขาดหายไปหรือไม่ถูกต้อง unknown: คำขอไม่มีพารามิเตอร์ที่จำเป็น รวมค่าพารามิเตอร์ที่ไม่รองรับ หรือมิฉะนั้นผิดรูปแบบ invalid_resource_owner: ข้อมูลประจำตัวเจ้าของทรัพยากรที่ให้มาไม่ถูกต้อง หรือไม่พบเจ้าของทรัพยากร invalid_scope: ขอบเขตที่ขอไม่ถูกต้อง ไม่รู้จัก หรือผิดรูปแบบ @@ -98,8 +98,8 @@ th: resource_owner_authenticator_not_configured: การค้นหาเจ้าของทรัพยากรล้มเหลวเนื่องจากไม่ได้กำหนดค่า Doorkeeper.configure.resource_owner_authenticator server_error: เซิร์ฟเวอร์การรับรองความถูกต้องพบเงื่อนไขที่ไม่คาดคิดซึ่งป้องกันไม่ให้เซิร์ฟเวอร์ดำเนินการตามคำขอ temporarily_unavailable: เซิร์ฟเวอร์การรับรองความถูกต้องไม่สามารถจัดการคำขอได้ในปัจจุบันเนื่องจากการทำงานเกินพิกัดชั่วคราวหรือการบำรุงรักษาเซิร์ฟเวอร์ - unauthorized_client: ไคลเอ็นต์ไม่ได้รับอนุญาตให้ทำคำขอนี้โดยใช้วิธีการนี้ - unsupported_grant_type: ชนิดการให้การรับรองความถูกต้องไม่รองรับโดยเซิร์ฟเวอร์การรับรองความถูกต้อง + unauthorized_client: ไม่อนุญาตให้ไคลเอ็นต์ทำคำขอนี้โดยใช้วิธีการนี้ + unsupported_grant_type: ไม่รองรับชนิดการให้การรับรองความถูกต้องโดยเซิร์ฟเวอร์การรับรองความถูกต้อง unsupported_response_type: เซิร์ฟเวอร์การอนุญาตไม่รองรับชนิดการตอบสนองนี้ flash: applications: diff --git a/config/locales/doorkeeper.tr.yml b/config/locales/doorkeeper.tr.yml index 46ab470acd..fce8c646e8 100644 --- a/config/locales/doorkeeper.tr.yml +++ b/config/locales/doorkeeper.tr.yml @@ -127,7 +127,7 @@ tr: bookmarks: Yer imleri conversations: Sohbetler crypto: Uçtan uca şifreleme - favourites: Beğeniler + favourites: Favoriler filters: Filtreler follow: Takipler, Sessizler ve Engeller follows: Takip edilenler @@ -170,7 +170,7 @@ tr: read:accounts: hesap bilgilerini görün read:blocks: engellemelerinizi görün read:bookmarks: yer imlerinizi görün - read:favourites: beğenilerinizi görün + read:favourites: favorilerinizi görün read:filters: filtrelerinizi görün read:follows: takip ettiklerinizi görün read:lists: listelerinizi görün @@ -184,7 +184,7 @@ tr: write:blocks: hesapları ve alan adlarını engelleyin write:bookmarks: durumları yer imleyin write:conversations: sessize al ve sohbetleri sil - write:favourites: durumları beğenin + write:favourites: favori gönderiler write:filters: filtreler oluşturun write:follows: insanları takip edin write:lists: listeler oluşturun diff --git a/config/locales/doorkeeper.tt.yml b/config/locales/doorkeeper.tt.yml index 41af088bfe..876e7138db 100644 --- a/config/locales/doorkeeper.tt.yml +++ b/config/locales/doorkeeper.tt.yml @@ -1,12 +1,48 @@ --- tt: + activerecord: + attributes: + doorkeeper/application: + scopes: Рөхсәтләр doorkeeper: applications: buttons: cancel: Баш тарту + destroy: Бетерү edit: Үзгәртү submit: Җибәрү index: + application: Кушымта delete: Бетерү name: Исем + scopes: Рөхсәтләр show: Күрсәтү + show: + actions: Гамәлләр + application_id: Клиент ачкычы + scopes: Рөхсәтләр + authorizations: + buttons: + deny: Тыю + authorized_applications: + buttons: + revoke: Кире алу + confirmations: + revoke: Раслыйсызмы? + index: + scopes: Рөхсәтләр + grouped_scopes: + title: + blocks: Блоклаулар + bookmarks: Кыстыргычлар + conversations: Әңгәмәләр + filters: Сезгечләр + lists: Исемлекләр + notifications: Искәртүләр + push: Push-искәртүләр + search: Эзләү + statuses: Язмалар + layouts: + admin: + nav: + oauth2_provider: OAuth2 провайдеры diff --git a/config/locales/doorkeeper.uk.yml b/config/locales/doorkeeper.uk.yml index 4e06a3590f..8af404a736 100644 --- a/config/locales/doorkeeper.uk.yml +++ b/config/locales/doorkeeper.uk.yml @@ -127,7 +127,7 @@ uk: bookmarks: Закладки conversations: Бесіди crypto: Наскрізне шифрування - favourites: Вподобане + favourites: Уподобане filters: Фільтри follow: Підписки, ігнорування і блокування follows: Підписки @@ -176,7 +176,7 @@ uk: read:accounts: бачити інформацію про облікові записи read:blocks: бачити Ваші блокування read:bookmarks: бачити ваші закладки - read:favourites: бачити вподобані дописи + read:favourites: бачити вподобані read:filters: бачити Ваші фільтри read:follows: бачити Ваші підписки read:lists: бачити Ваші списки diff --git a/config/locales/doorkeeper.vi.yml b/config/locales/doorkeeper.vi.yml index a3a0f158b0..8375795273 100644 --- a/config/locales/doorkeeper.vi.yml +++ b/config/locales/doorkeeper.vi.yml @@ -5,7 +5,7 @@ vi: doorkeeper/application: name: Tên ứng dụng redirect_uri: URL chuyển hướng - scopes: Quyền hạn + scopes: Quyền website: Trang web ứng dụng errors: models: @@ -41,7 +41,7 @@ vi: empty: Bạn không có ứng dụng nào. name: Tên new: Ứng dụng mới - scopes: Quyền hạn + scopes: Quyền show: Xem title: Ứng dụng của bạn new: @@ -50,7 +50,7 @@ vi: actions: Hành động application_id: Mã Client callback_urls: Gọi lại URLs - scopes: Quyền hạn + scopes: Quyền secret: Bí ẩn của Client title: 'Ứng dụng: %{name}' authorizations: @@ -71,7 +71,7 @@ vi: confirmations: revoke: Bạn có chắc không? index: - authorized_at: Cho phép vào %{date} + authorized_at: Cho phép %{date} description_html: Đây là những ứng dụng có thể truy cập tài khoản của bạn bằng API. Nếu có ứng dụng bạn không nhận ra ở đây hoặc ứng dụng hoạt động sai, bạn có thể thu hồi quyền truy cập của ứng dụng đó. last_used_at: Dùng lần cuối %{date} never_used: Chưa dùng @@ -147,7 +147,7 @@ vi: application: title: Đăng nhập bằng OAuth scopes: - admin:read: đọc tất cả dữ liệu trên máy chủ + admin:read: đọc mọi dữ liệu trên máy chủ admin:read:accounts: đọc thông tin nhạy cảm của tất cả các tài khoản admin:read:canonical_email_blocks: đọc thông tin nhạy cảm của tất cả các khối email chuẩn admin:read:domain_allows: đọc thông tin nhạy cảm của tất cả các tên miền cho phép @@ -157,39 +157,39 @@ vi: admin:read:reports: đọc thông tin của các báo cáo và các tài khoản bị báo cáo admin:write: sửa đổi tất cả dữ liệu trên máy chủ admin:write:accounts: áp đặt hành động kiểm duyệt trên tài khoản - admin:write:canonical_email_blocks: thực hiện các hành động kiểm duyệt đối với chặn email - admin:write:domain_allows: thực hiện các hành động kiểm duyệt đối với các email cho phép - admin:write:domain_blocks: thực hiện các hành động kiểm duyệt đối với các tên miền chặn - admin:write:email_domain_blocks: thực hiện các hành động kiểm duyệt đối với các tên miền email chặn + admin:write:canonical_email_blocks: áp đặt kiểm duyệt đối với chặn email + admin:write:domain_allows: áp đặt kiểm duyệt đối với các email cho phép + admin:write:domain_blocks: áp đặt kiểm duyệt đối với các tên miền chặn + admin:write:email_domain_blocks: áp đặt kiểm duyệt đối với các tên miền email chặn admin:write:ip_blocks: áp đặt kiểm duyệt với các IP chặn admin:write:reports: áp đặt kiểm duyệt với các báo cáo crypto: dùng mã hóa đầu cuối follow: sửa đổi các mối quan hệ tài khoản - push: nhận thông báo đẩy của bạn - read: đọc tất cả dữ liệu tài khoản của bạn + push: nhận thông báo đẩy + read: đọc mọi dữ liệu tài khoản read:accounts: xem thông tin tài khoản - read:blocks: xem những người bạn chặn - read:bookmarks: xem những thứ bạn đã lưu + read:blocks: xem những người đã chặn + read:bookmarks: xem tút đã lưu read:favourites: xem lượt thích - read:filters: xem bộ lọc của bạn - read:follows: xem lượt theo dõi của bạn - read:lists: xem danh sách của bạn - read:mutes: xem những người bạn đã ẩn - read:notifications: xem thông báo của bạn + read:filters: xem bộ lọc + read:follows: xem những người theo dõi + read:lists: xem danh sách + read:mutes: xem những người đã ẩn + read:notifications: xem thông báo read:reports: xem báo cáo của bạn - read:search: thay mặt bạn tìm kiếm + read:search: tìm kiếm read:statuses: xem toàn bộ tút write: sửa đổi mọi dữ liệu tài khoản của bạn - write:accounts: sửa đổi trang hồ sơ của bạn + write:accounts: sửa đổi trang hồ sơ write:blocks: chặn người và máy chủ - write:bookmarks: sửa đổi những thứ bạn lưu + write:bookmarks: sửa đổi những tút lưu write:conversations: ẩn và xóa thảo luận - write:favourites: lượt thích + write:favourites: thích tút write:filters: tạo bộ lọc write:follows: theo dõi ai đó write:lists: tạo danh sách write:media: tải lên tập tin write:mutes: ẩn người và thảo luận - write:notifications: xóa thông báo của bạn + write:notifications: xóa thông báo write:reports: báo cáo người khác write:statuses: đăng tút diff --git a/config/locales/doorkeeper.zh-CN.yml b/config/locales/doorkeeper.zh-CN.yml index bcaa5d0b87..36c7fb8127 100644 --- a/config/locales/doorkeeper.zh-CN.yml +++ b/config/locales/doorkeeper.zh-CN.yml @@ -38,7 +38,7 @@ zh-CN: application: 应用 callback_url: 回调 URL delete: 删除 - empty: 你没有申请。 + empty: 暂无应用。 name: 名称 new: 创建新应用 scopes: 权限范围 @@ -104,14 +104,14 @@ zh-CN: flash: applications: create: - notice: 应用创建成功 + notice: 应用创建成功。 destroy: - notice: 应用删除成功 + notice: 应用删除成功。 update: - notice: 应用修改成功 + notice: 应用已更新。 authorized_applications: destroy: - notice: 已成功撤销对此应用的授权 + notice: 已成功撤销对此应用的授权。 grouped_scopes: access: read: 只读权限 @@ -184,7 +184,7 @@ zh-CN: write:blocks: 屏蔽账号和域名 write:bookmarks: 为嘟文添加书签 write:conversations: 静音并删除会话 - write:favourites: 喜欢的嘟文 + write:favourites: 喜欢嘟文 write:filters: 创建过滤器 write:follows: 关注其他人 write:lists: 创建列表 diff --git a/config/locales/doorkeeper.zh-HK.yml b/config/locales/doorkeeper.zh-HK.yml index 59e133a707..79629b12fe 100644 --- a/config/locales/doorkeeper.zh-HK.yml +++ b/config/locales/doorkeeper.zh-HK.yml @@ -122,12 +122,14 @@ zh-HK: admin/accounts: 帳號管理 admin/all: 所有管理功能 admin/reports: 檢舉報告管理 + all: 完整存取你的 Mastodon 帳號 blocks: 封鎖 bookmarks: 書籤 conversations: 對話 crypto: 端到端加密 favourites: 最愛 filters: 篩選器 + follow: 追蹤、靜音及封鎖 follows: 追蹤 lists: 名單 media: 媒體附件 @@ -182,7 +184,7 @@ zh-HK: write:blocks: 封鎖帳號及域名 write:bookmarks: 把文章加入最愛 write:conversations: 靜音及刪除對話 - write:favourites: 喜歡的文章 + write:favourites: 最愛的帖文 write:filters: 建立過濾條件 write:follows: 關注其他人 write:lists: 建立清單 diff --git a/config/locales/doorkeeper.zh-TW.yml b/config/locales/doorkeeper.zh-TW.yml index da5597c85c..6073096c31 100644 --- a/config/locales/doorkeeper.zh-TW.yml +++ b/config/locales/doorkeeper.zh-TW.yml @@ -38,7 +38,7 @@ zh-TW: application: 應用程式 callback_url: 回傳網址 delete: 刪除 - empty: 您沒有安裝應用程式。 + empty: 您沒有任何應用程式。 name: 名稱 new: 新增應用程式 scopes: 範圍 @@ -131,7 +131,7 @@ zh-TW: filters: 過濾器 follow: 跟隨、靜音與封鎖 follows: 跟隨的使用者 - lists: 名單 + lists: 列表 media: 多媒體附加檔案 mutes: 靜音 notifications: 通知 @@ -154,7 +154,7 @@ zh-TW: admin:read:domain_blocks: 讀取所有網域黑名單之敏感內容 admin:read:email_domain_blocks: 讀取所有電子郵件黑名單之敏感內容 admin:read:ip_blocks: 讀取所有 IP 黑名單之敏感內容 - admin:read:reports: 讀取所有回報 / 被回報之帳號的敏感內容 + admin:read:reports: 讀取所有回報 / 被回報帳號之敏感內容 admin:write: 修改伺服器的所有資料 admin:write:accounts: 對帳號進行管理動作 admin:write:canonical_email_blocks: 對電子郵件黑名單進行管理動作 @@ -168,12 +168,12 @@ zh-TW: push: 接收帳號的推播通知 read: 讀取您所有的帳號資料 read:accounts: 檢視帳號資訊 - read:blocks: 檢視您的封鎖名單 + read:blocks: 檢視您的封鎖列表 read:bookmarks: 檢視您的書籤 - read:favourites: 檢視您收藏的最愛 + read:favourites: 檢視您收藏之最愛嘟文 read:filters: 檢視您的過濾條件 read:follows: 檢視您跟隨的人 - read:lists: 檢視您的名單 + read:lists: 檢視您的列表 read:mutes: 檢視您靜音的人 read:notifications: 檢視您的通知 read:reports: 檢視您的檢舉 diff --git a/config/locales/el.yml b/config/locales/el.yml index d3ef048a98..c4c3d39397 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -11,111 +11,122 @@ el: followers: one: Ακόλουθος other: Ακόλουθοι - following: Ακολουθεί + following: Ακολουθείτε + instance_actor_flash: Αυτός ο λογαριασμός είναι εικονικός και χρησιμοποιείται για να αντιπροσωπεύει τον ίδιο τον διακομιστή και όχι κάποιον μεμονωμένο χρήστη. Χρησιμοποιείται για σκοπούς συναλλαγών και δεν πρέπει να ανασταλεί. last_active: τελευταία ενεργός/ή - link_verified_on: Η κυριότητα αυτού του συνδέσμου ελέγχθηκε στις %{date} + link_verified_on: Η ιδιοκτησία αυτού του συνδέσμου ελέγχθηκε στις %{date} nothing_here: Δεν υπάρχει τίποτα εδώ! pin_errors: following: Πρέπει ήδη να ακολουθείς το άτομο που θέλεις να επιδοκιμάσεις posts: - one: Τουτ - other: Τουτ - posts_tab_heading: Τουτ + one: Ανάρτηση + other: Αναρτήσεις + posts_tab_heading: Αναρτήσεις admin: account_actions: action: Εκτέλεση ενέργειας - title: Εκτέλεση ενέργειας διαχείρισης στο %{acct} + title: Εκτέλεση ενέργειας συντονισμού στον %{acct} account_moderation_notes: create: Άφησε σημείωση - created_msg: Επιτυχής δημιουργία σημειώματος μεσολάβησης! - destroyed_msg: Επιτυχής καταστροφή σημειώματος μεσολάβησης! + created_msg: Επιτυχής δημιουργία σημειώματος συντονισμού! + destroyed_msg: Η σημείωση συντονισμού καταστράφηκε επιτυχώς! accounts: - add_email_domain_block: Εγγραφή τομέα email σε μαύρη λίστα + add_email_domain_block: Αποκλεισμός τομέα email approve: Έγκριση approved_msg: Επιτυχής έγκριση αίτησης εγγραφής του/της %{username} are_you_sure: Σίγουρα; - avatar: Αβατάρ + avatar: Άβαταρ by_domain: Τομέας change_email: + changed_msg: Το email άλλαξε επιτυχώς! current_email: Τρέχον email label: Αλλαγή email new_email: Νέο email submit: Αλλαγή email title: Αλλαγή email για %{username} change_role: + changed_msg: Ο ρόλος άλλαξε επιτυχώς! label: Αλλαγή ρόλου no_role: Κανένας ρόλος title: Αλλαγή ρόλου για %{username} confirm: Επιβεβαίωση confirmed: Επιβεβαιώθηκε confirming: Προς επιβεβαίωση + custom: Προσαρμοσμένο delete: Διαγραφή δεδομένων - deleted: Διαγραμμένοι - demote: Υποβίβαση + deleted: Διαγεγραμμένοι + demote: Υποβιβασμός destroyed_msg: Τα δεδομένα του/της %{username} εκκρεμούν για άμεση διαγραφή - disable: Απενεργοποίηση + disable: Πάγωμα + disable_sign_in_token_auth: Απενεργοποίηση επαλήθευσης μέσω email disable_two_factor_authentication: Απενεργοποίηση 2FA - disabled: Απενεργοποιημένο - display_name: Όνομα εμφάνισης + disabled: Παγωμένος + display_name: Εμφανιζόμενο όνομα domain: Τομέας edit: Επεξεργασία email: Email email_status: Κατάσταση email - enable: Ενεργοποίηση + enable: Ξεπάγωμα + enable_sign_in_token_auth: Ενεργοποίηση ελέγχου ταυτότητας μέσω e-mail enabled: Ενεργοποιημένο enabled_msg: Επιτυχές ξεπάγωμα λογαριασμού του/της %{username} followers: Ακόλουθοι follows: Ακολουθεί - header: Επικεφαλίδα + header: Κεφαλίδα inbox_url: URL εισερχομένων - invite_request_text: Λόγοι για εγγραφή + invite_request_text: Λόγοι για συμμετοχή invited_by: Προσκλήθηκε από ip: IP - joined: Γράφτηκε + joined: Έγινε μέλος location: all: Όλες local: Τοπική - remote: Απομακρυσμένα + remote: Απομακρυσμένη title: Τοποθεσία login_status: Κατάσταση σύνδεσης media_attachments: Συνημμένα πολυμέσα - memorialize: Μετατροπή σε νεκρολογία - memorialized: Μετατροπή σε αναμνηστικό - memorialized_msg: Επιτυχής μετατροπή λογαριασμού του/της %{username} σε αναμνηστικό + memorialize: Μετατροπή σε εις μνήμην + memorialized: Μετατράπηκε σε εις μνήμην + memorialized_msg: Επιτυχής μετατροπή λογαριασμού του/της %{username} σε εις μνήμην moderation: - active: Ενεργός/ή - all: Όλα + active: Ενεργός + all: Όλοι + disabled: Απενεργοποιημένο pending: Εκκρεμούν - silenced: Περιορισμένοι + silenced: Περιορισμένη suspended: Σε αναστολή - title: Μεσολάβηση - moderation_notes: Σημειώσεις μεσολάβησης + title: Συντονισμός + moderation_notes: Σημειώσεις συντονισμού most_recent_activity: Πιο πρόσφατη δραστηριότητα most_recent_ip: Πιο πρόσφατη IP no_account_selected: Κανείς λογαριασμός δεν ενημερώθηκε αφού κανείς δεν ήταν επιλεγμένος no_limits_imposed: Χωρίς όρια no_role_assigned: Δεν έχει ανατεθεί ρόλος - not_subscribed: Άνευ συνδρομής - pending: Εκκρεμεί έγκριση + not_subscribed: Δεν έγινε εγγραφή + pending: Εκκρεμεί αξιολόγηση perform_full_suspension: Αναστολή - promote: Προβίβασε + previous_strikes: Προηγούμενα παραπτώματα + previous_strikes_description_html: + one: Αυτός ο λογαριασμός έχει ένα παράπτωμα. + other: Αυτός ο λογαριασμός έχει %{count} παραπτώματα. + promote: Προαγωγή protocol: Πρωτόκολλο public: Δημόσιο push_subscription_expires: Η εγγραφή PuSH λήγει - redownload: Ανανέωση αβατάρ - redownloaded_msg: Επιτυχής ανανέωη προφίλ του/της %{username} από την πηγή + redownload: Ανανέωση άβαταρ + redownloaded_msg: Επιτυχής ανανέωση προφίλ του/της %{username} από την πηγή reject: Απόρριψη rejected_msg: Επιτυχής απόρριψη αίτησης εγγραφής του/της %{username} remote_suspension_irreversible: Τα δεδομένα αυτού του λογαριασμού έχουν διαγραφεί αμετάκλητα. - remote_suspension_reversible_hint_html: Ο λογαριασμός έχει ανασταλλεί στον server του και τα δεδομένα του θα διαγραφούν πλήρως στις %{date}. Μέχρι τότε, ο απομακρυσμένος server μπορεί να επαναφέρει τον λογαριασμό χωρίς επιπτώσεις. Αν θέλεις να διαγράψεις αμέσως όλα τα δεδομένα του λογαριασμού, μπορείς να το κάνεις παρακάτω. - remove_avatar: Απομακρυσμένο αβατάρ - remove_header: Αφαίρεση επικεφαλίδας - removed_avatar_msg: Επιτυχής αφαίρεση εικόνας προφίλ του/της%{username} + remote_suspension_reversible_hint_html: Ο λογαριασμός έχει ανασταλλεί στον διακομιστή του και τα δεδομένα του θα διαγραφούν πλήρως στις %{date}. Μέχρι τότε, ο απομακρυσμένος διακομιστής μπορεί να επαναφέρει τον λογαριασμό χωρίς επιπτώσεις. Αν θέλεις να διαγράψεις αμέσως όλα τα δεδομένα του λογαριασμού, μπορείς να το κάνεις παρακάτω. + remove_avatar: Αφαίρεση άβαταρ + remove_header: Αφαίρεση κεφαλίδας + removed_avatar_msg: Επιτυχής αφαίρεση εικόνας προφίλ του/της %{username} removed_header_msg: Επιτυχής αφαίρεση εικόνας κεφαλίδας του/της %{username} resend_confirmation: - already_confirmed: Ήδη επιβεβαιωμένος χρήστης - send: Επανάληψη αποστολής email επιβεβαίωσης - success: Το email επιβεβαίωσης στάλθηκε επιτυχώς! + already_confirmed: Αυτός ο χρήστης έχει ήδη επιβεβαιωθεί + send: Επανάληψη αποστολής συνδέσμου επιβεβαίωσης + success: Ο σύνδεσμος επιβεβαίωσης στάλθηκε επιτυχώς! reset: Επαναφορά reset_password: Επαναφορά συνθηματικού resubscribe: Επανεγγραφή @@ -123,35 +134,40 @@ el: search: Αναζήτηση search_same_email_domain: Άλλοι χρήστες με τον ίδιο τομέα e-mail search_same_ip: Υπόλοιποι χρήστες με την ίδια διεύθυνση IP + security: Ασφάλεια + security_measures: + only_password: Μόνο κωδικός πρόσβασης + password_and_2fa: Κωδικός πρόσβασης και 2FA sensitive: Ευαίσθητο - sensitized: σήμανση ως ευαίσθητο + sensitized: Επισημάνθηκε ως ευαίσθητος shared_inbox_url: URL κοινόχρηστων εισερχομένων show: - created_reports: Αναφορές από αυτόν το λογαριασμό - targeted_reports: Αναφορές για αυτόν το λογαριασμό - silence: Αποσιώπησε - silenced: Αποσιωπημένοι - statuses: Καταστάσεις + created_reports: Αναφορές από τον ίδιο + targeted_reports: Αναφορές από άλλους + silence: Περιορισμός + silenced: Περιορισμένος + statuses: Αναρτήσεις + strikes: Προηγούμενα παραπτώματα subscribe: Εγγραφή suspend: Αναστολή suspended: Σε αναστολή suspension_irreversible: Τα δεδομένα αυτού του λογαριασμού έχουν διαγραφεί οριστικά. Μπορείς να άρεις την αναστολή του λογαριασμού για να μπορέσει να χρησιμοποιηθεί αλλά αυτό δεν θα επαναφέρει όσα δεδομένα είχε προηγουμένως. suspension_reversible_hint_html: Ο λογαριασμός έχει ανασταλλεί και τα δεδομένα του θα διαγραφούν πλήρως στις %{date}. Μέχρι τότε ο λογαριασμός μπορεί να επανέλθει κανονικά. Αν θέλεις να διαγράψεις όλα τα δεδομένα του λογαριασμού, μπορείς να το κάνεις παρακάτω. title: Λογαριασμοί - unblock_email: Ξεμπλοκάρισμα διεύθυνσης email - unblocked_email_msg: Επιτυχής κατάργηση αποκλεισμού διεύθυνσης ηλεκτρονικού ταχυδρομείου %{username} + unblock_email: Άρση αποκλεισμού διεύθυνσης email + unblocked_email_msg: Επιτυχής άρση αποκλεισμού διεύθυνσης email %{username} unconfirmed_email: Ανεπιβεβαίωτο email - undo_sensitized: Αναίρεση ευαίσθητου - undo_silenced: Αναίρεση αποσιώπησης + undo_sensitized: Άρση ευαίσθητου + undo_silenced: Άρση περιορισμού undo_suspension: Αναίρεση παύσης unsilenced_msg: Επιτυχής άρση περιορισμών λογαριασμού του/της %{username} unsubscribe: Κατάργηση εγγραφής unsuspended_msg: Επιτυχής άρση αναστολής λογαριασμού του/της %{username} username: Όνομα χρήστη - view_domain: Προβολή περίληψης για τομέα + view_domain: Προβολή περίληψης τομέα warn: Προειδοποίηση web: Διαδίκτυο - whitelisted: Εγκεκριμένοι + whitelisted: Εγκεκριμένοι για συναλλαγές action_logs: action_types: approve_appeal: Έγκριση Έφεσης @@ -162,67 +178,116 @@ el: confirm_user: Επιβεβαίωση Χρήστη create_account_warning: Δημιουργία Προειδοποίησης create_announcement: Δημιουργία Ανακοίνωσης + create_canonical_email_block: Δημιουργία αποκλεισμού e-mail create_custom_emoji: Δημιουργία Προσαρμοσμένου Emoji - create_domain_allow: Δημιουργία Επιτρεπτού Τομέα - create_domain_block: Δημιουργία Αποκλεισμένου Τομέα - create_email_domain_block: Δημουργία Αποκλεισμένου Τομέα email + create_domain_allow: Δημιουργία Αποδεκτού Τομέα + create_domain_block: Δημιουργία Αποκλεισμού Τομέα + create_email_domain_block: Δημουργία Αποκλεισμού Τομέα email create_ip_block: Δημιουργία κανόνα IP + create_unavailable_domain: Δημιουργία Μη Διαθέσιμου Τομέα create_user_role: Δημιουργία ρόλου demote_user: Υποβιβασμός Χρήστη destroy_announcement: Διαγραφή Ανακοίνωσης + destroy_canonical_email_block: Διαγραφή Αποκλεισμού email destroy_custom_emoji: Διαγραφή Προσαρμοσμένου Emoji - destroy_domain_allow: Διαγραφή Επιτρεπτού Τομέα + destroy_domain_allow: Διαγραφή Αποδεκτού Τομέα destroy_domain_block: Διαγραφή Αποκλεισμού Τομέα destroy_email_domain_block: Διαγραφή Αποκλεισμένου Τομέα email destroy_instance: Εκκαθάριση Τομέα destroy_ip_block: Διαγραφή κανόνα IP - destroy_status: Διαγραφή Κατάστασης + destroy_status: Διαγραφή Ανάρτησης + destroy_unavailable_domain: Διαγραφή Μη Διαθέσιμου Τομέα + destroy_user_role: Καταστροφή Ρόλου disable_2fa_user: Απενεργοποίηση 2FA disable_custom_emoji: Απενεργοποίηση Προσαρμοσμένων Emoji + disable_sign_in_token_auth_user: Απενεργοποίηση Ελέγχου Ταυτότητας Μέσω E-mail για το Χρήστη disable_user: Απενεργοποίηση Χρήστη enable_custom_emoji: Ενεργοποίηση Προσαρμοσμένων Emoji + enable_sign_in_token_auth_user: Ενεργοποίηση Ελέγχου Ταυτότητας Μέσω E-mail για το Χρήστη enable_user: Ενεργοποίηση Χρήστη - memorialize_account: Μετατροπή Λογαριασμού σε Αναμνηστικό + memorialize_account: Μετατροπή Λογαριασμού σε Εις Μνήμην promote_user: Προαγωγή Χρήστη reject_appeal: Απόρριψη Έφεσης reject_user: Απόρριψη Χρήστη - remove_avatar_user: Αφαίρεση Avatar - reopen_report: Ξανάνοιγμα Καταγγελίας + remove_avatar_user: Αφαίρεση Άβαταρ + reopen_report: Ξανάνοιγμα Ανααφοράς resend_user: Επαναποστολή του email επιβεβαίωσης reset_password_user: Επαναφορά Συνθηματικού - resolve_report: Επίλυση Καταγγελίας - sensitive_account: Σήμανση των πολυμέσων στον λογαριασμό σας ως ευαίσθητων - silence_account: Σίγαση Λογαριασμού + resolve_report: Επίλυση Αναφοράς + sensitive_account: Ευαίσθητος Λογιαριασμός + silence_account: Περιορισμός Λογαριασμού suspend_account: Αναστολή Λογαριασμού - unassigned_report: Αποδέσμευση Καταγγελίας - unblock_email_account: Ξεμπλοκάρισμα διεύθυνσης email - unsensitive_account: Αφαίρεση σήμανσης των πολυμέσων στον λογαριασμό σας ως ευαίσθητων - unsilence_account: Άρση Σίγασης Λογαριασμού + unassigned_report: Αποδέσμευση Αναφοράς + unblock_email_account: Άρση αποκλεισμού διεύθυνσης email + unsensitive_account: Άρση επισήμανσης Λογαριασμού ως Ευαίσθητο + unsilence_account: Άρση Περιορισμού Λογαριασμού unsuspend_account: Άρση Αναστολής Λογαριασμού update_announcement: Ενημέρωση Ανακοίνωσης update_custom_emoji: Ενημέρωση Προσαρμοσμένου Emoji - update_status: Ενημέρωση Κατάστασης + update_domain_block: Ενημέρωση Αποκλεισμού Τομέα + update_ip_block: Ενημέρωση κανόνα IP + update_status: Ενημέρωση Ανάρτησης update_user_role: Ενημέρωση ρόλου actions: - approve_user_html: "%{name} εγκρίθηκε εγγραφή από %{target}" + approve_appeal_html: Ο/Η %{name} ενέκρινε την ένσταση της απόφασης των συντονιστών από %{target} + approve_user_html: ο/η %{name} ενέκρινε την εγγραφή του %{target} + assigned_to_self_report_html: Ο/Η %{name} ανάθεσε την αναφορά %{target} στον εαυτό του/της + change_email_user_html: Ο/Η %{name} άλλαξε τη διεύθυνση email του χρήστη %{target} + change_role_user_html: Ο/Η %{name} άλλαξε ρόλο του/της %{target} + confirm_user_html: Ο/Η %{name} επιβεβαίωσε τη διεύθυνση email του χρήστη %{target} + create_account_warning_html: Ο/Η %{name} έστειλε προειδοποίηση προς %{target} + create_announcement_html: Ο/Η %{name} δημιούργησε νέα ανακοίνωση %{target} + create_canonical_email_block_html: Ο/Η %{name} απέκλεισε e-mail με το hash %{target} + create_custom_emoji_html: Ο/Η %{name} ανέβασε νέο emoji %{target} + create_domain_allow_html: Ο/Η %{name} επέτρεψε την συναλλαγή με τον τομέα %{target} + create_domain_block_html: Ο/Η %{name} απέκλεισε τον τομέα %{target} + create_email_domain_block_html: Ο/Η %{name} απέκλεισε τον τομέα email %{target} + create_ip_block_html: Ο/Η %{name} δημιούργησε κανόνα για την IP %{target} + create_unavailable_domain_html: Ο/Η %{name} σταμάτησε να τροφοδοτεί τον τομέα %{target} + create_user_role_html: Ο/Η %{name} δημιούργησε ρόλο %{target} + demote_user_html: Ο/Η %{name} υποβίβασε τον χρήστη %{target} + destroy_announcement_html: Ο/Η %{name} διέγραψε την ανακοίνωση %{target} + destroy_canonical_email_block_html: Ο/Η %{name} επέτρεψε email με το hash %{target} + destroy_custom_emoji_html: Ο/Η %{name} διέγραψε το emoji %{target} + destroy_domain_allow_html: Ο/Η %{name} αφαίρεσε τον τομέα %{target} από τη λίστα εγκρίσεων + destroy_domain_block_html: Ο/Η %{name} επέτρεψε τον τομέα %{target} destroy_email_domain_block_html: Ο/Η %{name} ξεμπλόκαρε το email domain %{target} destroy_instance_html: Ο/Η %{name} εκκαθάρισε τον τομέα %{target} destroy_ip_block_html: Ο/Η %{name} διέγραψε τον κανόνα για την IP %{target} destroy_status_html: Ο/Η %{name} αφαίρεσε την ανάρτηση του/της %{target} destroy_unavailable_domain_html: Ο/Η %{name} ξανάρχισε να τροφοδοτεί το domain %{target} destroy_user_role_html: Ο/Η %{name} διέγραψε τον ρόλο του %{target} - disable_2fa_user_html: Ο/Η %{name} απενεργοποίησε το two factor requirement για τον χρήστη %{target} + disable_2fa_user_html: Ο/Η %{name} απενεργοποίησε την απαίτηση για ταυτοποίηση δύο παραγόντων για τον χρήστη %{target} disable_custom_emoji_html: Ο/Η %{name} απενεργοποίησε το emoji %{target} - disable_sign_in_token_auth_user_html: Ο/Η %{name} απενεργοποίησε την πιστοποίηση e-mail token του %{target} + disable_sign_in_token_auth_user_html: Ο/Η %{name} απενεργοποίησε την ταυτοποίηση χαρακτηριστικού μέσω e-mail του %{target} disable_user_html: Ο/Η %{name} απενεργοποίησε τη σύνδεση για τον χρήστη %{target} enable_custom_emoji_html: Ο/Η %{name} ενεργοποίησε το emoji %{target} - enable_sign_in_token_auth_user_html: Ο/Η %{name} ενεργοποίησε την πιστοποίηση e-mail token του %{target} + enable_sign_in_token_auth_user_html: Ο/Η %{name} ενεργοποίησε την ταυτοποίηση χαρακτηριστικού μέσω e-mail του %{target} enable_user_html: Ο/Η %{name} ενεργοποίησε τη σύνδεση για τον χρήστη %{target} - memorialize_account_html: O/H %{name} μετέτρεψε τον λογαριασμό του %{target} σε σελίδα μνήμης + memorialize_account_html: O/H %{name} μετέτρεψε τον λογαριασμό του %{target} σε σελίδα εις μνήμην promote_user_html: Ο/Η %{name} προβίβασε το χρήστη %{target} - reject_user_html: "%{name} απορρίφθηκε εγγραφή από %{target}" - unblock_email_account_html: "%{name} ξεμπλόκαρε τη διεύθυνση ηλεκτρονικού ταχυδρομείου του %{target}" - deleted_account: διαγραμμένος λογαριασμός + reject_appeal_html: Ο/Η %{name} απέρριψε την ένσταση της απόφασης των συντονιστών από %{target} + reject_user_html: ο/η %{name} απέρριψε την εγγραφή από %{target} + remove_avatar_user_html: ο/η %{name} αφαίρεσε το άβαταρ του/της %{target} + reopen_report_html: Ο/Η %{name} ξανάνοιξε την αναφορά %{target} + resend_user_html: Ο/Η %{name} έστειλε ξανά e-mail επιβεβαίωσης για τον/την %{target} + reset_password_user_html: Ο/Η %{name} επανέφερε το συνθηματικό του χρήστη %{target} + resolve_report_html: Ο/Η %{name} επέλυσε την αναφορά %{target} + sensitive_account_html: Ο/Η %{name} επισήμανε τα πολυμέσα του/της %{target} ως ευαίσθητα + silence_account_html: Ο/Η %{name} περιόρισε τον λογαριασμό του/της %{target} + suspend_account_html: Ο/Η %{name} ανέστειλε τον λογαριασμό του/της %{target} + unassigned_report_html: Ο/Η %{name} αποδέσμευσε την αναφορά %{target} + unblock_email_account_html: "%{name} έκανε άρση αποκλεισμού στη διεύθυνση email του %{target}" + unsensitive_account_html: Ο/Η %{name} επισήμανε τα πολυμέσα του/της %{target} ως μη ευαίσθητα + unsilence_account_html: Ο/Η %{name} αφαίρεσε το περιορισμό του λογαριασμού του/της %{target} + unsuspend_account_html: Ο/Η %{name} επανέφερε τον λογαριασμό του/της %{target} + update_announcement_html: Ο/Η %{name} ενημέρωσε την ανακοίνωση %{target} + update_custom_emoji_html: Ο/Η %{name} ενημέρωσε το emoji %{target} + update_domain_block_html: Ο/Η %{name} ενημέρωσε τον αποκλεισμό τομέα για %{target} + update_ip_block_html: Ο/Η %{name} άλλαξε τον κανόνα για την IP %{target} + update_status_html: Ο/Η %{name} ενημέρωσε την ανάρτηση του/της %{target} + update_user_role_html: Ο/Η %{name} άλλαξε τον ρόλο %{target} + deleted_account: διαγεγραμμένος λογαριασμός empty: Δεν βρέθηκαν αρχεία καταγραφής. filter_by_action: Φιλτράρισμα ανά ενέργεια filter_by_user: Φιλτράρισμα ανά χρήστη @@ -245,12 +310,12 @@ el: unpublished_msg: Επιτυχής ακύρωση δημοσίευσης ανακοίνωσης! updated_msg: Επιτυχής ενημέρωση ανακοίνωσης! custom_emojis: - assign_category: Κατηγορία + assign_category: Ανάθεση κατηγορίας by_domain: Τομέας copied_msg: Επιτυχής δημιουργία τοπικού αντίγραφου του emoji copy: Αντιγραφή copy_failed_msg: Αδυναμία δημιουργίας τοπικού αντίγραφου αυτού του emoji - create_new_category: Νέα κατηγορία + create_new_category: Δημιούργησε νέα κατηγορία created_msg: Επιτυχής δημιουργία του emoji! delete: Διαγραφή destroyed_msg: Επιτυχής καταστροφή του emojo! @@ -262,110 +327,203 @@ el: enabled: Ενεργοποιημένα enabled_msg: Επιτυχής ενεργοποίηση αυτού του emoji image_hint: PNG ή GIF έως %{size} - list: Εμφάνιση - listed: Αναφερθέντα + list: Παράθεση + listed: Καταχωρημένα new: title: Προσθήκη νέου προσαρμοσμένου emoji - not_permitted: Δεν επιτρέπεται να κάνετε αυτή την λειτουργία + no_emoji_selected: Δεν άλλαξαν τα emoji καθώς δεν επιλέχθηκε κανένα + not_permitted: Δεν επιτρέπεται να εκτελέσεις αυτήν την ενέργεια overwrite: Αντικατάσταση shortcode: Σύντομος κωδικός shortcode_hint: Τουλάχιστον 2 χαρακτήρες, μόνο αλφαριθμητικοί και κάτω παύλες title: Προσαρμοσμένα emoji uncategorized: Χωρίς κατηγορία - unlist: Απόκρυψη + unlist: Αφαίρεση από λίστα unlisted: Μη καταχωρημένα update_failed_msg: Αδυναμία ενημέρωσης του emoji updated_msg: Επιτυχής ενημέρωση του emoji! - upload: Ανέβασμα + upload: Μεταμόρφωση dashboard: active_users: ενεργοί χρήστες + interactions: αλληλεπιδράσεις + media_storage: Χώρος πολυμέσων new_users: νέοι χρήστες + opened_reports: ανοιγμένες αναφορές + pending_appeals_html: + one: "%{count} έφεση σε εκκρεμότητα" + other: "%{count} εφέσεις σε εκκρεμότητα" + pending_reports_html: + one: "%{count} εκκρεμής αναφορά" + other: "%{count} εκκρεμείς αναφορές" + pending_tags_html: + one: "%{count} εκκρεμής ετικέτα" + other: "%{count} εκκρεμείς ετικέτες" + pending_users_html: + one: "%{count} χρήστης σε εκκρεμότητα" + other: "%{count} χρήστες σε εκκρεμότητα" + resolved_reports: επιλυμμένες αναφορές software: Λογισμικό + sources: Πηγές εγγραφής space: Κατανάλωση χώρου title: Ταμπλό + top_languages: Κορυφαίες ενεργές γλώσσες + top_servers: Κορυφαίοι ενεργοί διακομιστές + website: Ιστοσελίδα disputes: appeals: + empty: Καμία ένσταση. title: Εφέσεις domain_allows: add_new: Έγκριση τομέα - created_msg: Ο τομέας εγκρίθηκε με επιτυχία - destroyed_msg: Ο τομέας δεν είναι πια εγκεκριμένος + created_msg: Ο τομέας εγκρίθηκε με επιτυχία για συναλλαγές + destroyed_msg: Ο τομέας δεν είναι πια εγκεκριμένος για συναλλαγές export: Εξαγωγή import: Εισαγωγή - undo: Αφαίρεση έγκρισης + undo: Αφαίρεση συναλλαγής με τον τομέα domain_blocks: - add_new: Προσθήκη νέου + add_new: Προσθήκη νέου αποκλεισμού τομέα created_msg: Ο αποκλεισμός τομέα είναι υπό επεξεργασία - destroyed_msg: Ο αποκλεισμός τομέα άρθηκε + destroyed_msg: Ο αποκλεισμός τομέα αναιρέθηκε domain: Τομέας - edit: Επεξεργασία αποκλεισμένου τομέα + edit: Επεξεργασία αποκλεισμού τομέα existing_domain_block: Έχετε ήδη επιβάλει αυστηρότερα όρια στο %{name}. existing_domain_block_html: Έχεις ήδη επιβάλλει αυστηρότερους περιορισμούς στο %{name}, πρώτα θα πρέπει να τους αναιρέσεις. export: Εξαγωγή import: Εισαγωγή new: create: Δημιουργία αποκλεισμού - hint: Ο αποκλεισμός τομέα δεν θα αποτρέψει νέες καταχωρίσεις λογαριασμών στην βάση δεδομένων, αλλά θα εφαρμόσει αναδρομικά και αυτόματα συγκεκριμένες πολιτικές μεσολάβησης σε αυτούς τους λογαριασμούς. + hint: Ο αποκλεισμός τομέα δεν θα αποτρέψει νέες καταχωρίσεις λογαριασμών στην βάση δεδομένων, αλλά θα εφαρμόσει αναδρομικά και αυτόματα συγκεκριμένες πολιτικές συντονισμού σε αυτούς τους λογαριασμούς. severity: + desc_html: Ο περιορισμός θα κάνει αόρατες τις ανάρτησεις ενός λογαριασμού σε όσους δεν τον ακολουθούν. Η αναστολή θα αφαιρέσει όλο το περιεχόμενο, τα πολυμέσα και τα στοιχεία προφίλ ενός λογαριασμού. Χρησιμοποίησε το κανένα αν θέλεις απλά να απορρίψεις τα αρχεία πολυμέσων. noop: Κανένα silence: Περιορισμός suspend: Αναστολή title: Αποκλεισμός νέου τομέα + no_domain_block_selected: Δεν άλλαξαν οι αποκλεισμοί τομέα καθώς δεν επιλέχθηκε κανένας + not_permitted: Δεν επιτρέπεται να εκτελέσεις αυτήν την ενέργεια + obfuscate: Θόλωμα ονόματος τομέα + obfuscate_hint: Μερικό θόλωμα του ονόματος τομέα στη λίστα, εάν η ανακοίνωση της λίστας των περιορισμών τομέα είναι ενεργή private_comment: Ιδιωτικό σχόλιο - private_comment_hint: Σχόλιο για τον περιορισμό αυτού του τομέα για εσωτερική χρήση από τους διαχειριστές. + private_comment_hint: Σχόλιο για τον περιορισμό αυτού του τομέα για εσωτερική χρήση από τους συντονιστές. public_comment: Δημόσιο σχόλιο - public_comment_hint: Σχόλιο σχετικά με τον περιορισμό αυτού του τομέα προς το κοινό, αν η λειτουργία δημοσιοποίησης των περιορισμένων τομέων είναι ενεργοποιημένη. - reject_media: Απόρριψη πολυμέσων + public_comment_hint: Σχόλιο σχετικά με τον περιορισμό αυτού του τομέα προς το κοινό, αν η λειτουργία διαφήμισης των περιορισμένων τομέων είναι ενεργοποιημένη. + reject_media: Απόρριψη αρχείων πολυμέσων reject_media_hint: Αφαιρεί τα τοπικά αποθηκευμένα αρχεία πολυμέσων και αποτρέπει τη λήψη άλλων στο μέλλον. Δεν έχει σημασία για τις αναστολές - reject_reports: Απόρριψη καταγγελιών - reject_reports_hint: Αγνόηση όσων καταγγελιών προέρχονται από αυτό τον τομέα. Δεν σχετίζεται με τις παύσεις - undo: Αναίρεση + reject_reports: Απόρριψη αναφορών + reject_reports_hint: Αγνόησε όσων αναφορών που προέρχονται από αυτό τον τομέα. Δεν σχετίζεται με τις παύσεις + undo: Αναίρεση αποκλεισμού τομέα view: Εμφάνιση αποκλεισμού τομέα email_domain_blocks: - add_new: Πρόσθεση νέου + add_new: Προσθήκη νέου attempts_over_week: one: "%{count} προσπάθεια την τελευταία εβδομάδα" other: "%{count} προσπάθειες εγγραφής την τελευταία εβδομάδα" - created_msg: Επιτυχής πρόσθεση email τομέα σε μαύρη λίστα + created_msg: Επιτυχής αποκλεισμού email τομέα delete: Διαγραφή dns: types: mx: Εγγραφή MX domain: Τομέας new: - create: Πρόσθεση τομέα - title: Νέα εγγραφή email στη μαύρη λίστα - title: Μαύρη λίστα email + create: Προσθήκη τομέα + resolve: Επίλυση τομέα + title: Αποκλεισμός νέου τομέα email + no_email_domain_block_selected: Δεν άλλαξαν οι αποκλεισμοί τομέα καθώς δεν επιλέχθηκε κανένας + not_permitted: Δεν επιτρέπεται + resolved_dns_records_hint_html: Το όνομα τομέα επιλύεται στους ακόλουθους τομείς MX, οι οποίοι είναι τελικά υπεύθυνοι για την αποδοχή των e-mail. Αποκλείοντας έναν τομέα MX θα μπλοκάρει τις εγγραφές από οποιαδήποτε διεύθυνση email που χρησιμοποιεί τον ίδιο τομέα MX, ακόμη και αν το ορατό όνομα τομέα είναι διαφορετικό. Προσέξτε να μην αποκλείσετε τους μεγάλους παρόχους ηλεκτρονικού ταχυδρομείου. + resolved_through_html: Επιλύθηκε μέσω %{domain} + title: Αποκλεισμένοι τομείς email export_domain_allows: + new: + title: Εισαγωγή επιτρεπόμενων τομέων no_file: Δεν επιλέχθηκε αρχείο export_domain_blocks: + import: + description_html: Πρόκειται να εισαγάγετε μια λίστα με αποκλεισμένους τομείς. Παρακαλώ ελέγξτε τη λίστα πολύ προσεκτικά, ειδικά αν δεν έχετε συντάξει τη λίστα μόνοι σας. + existing_relationships_warning: Υπάρχουσες σχέσεις ακολούθησης + private_comment_description_html: 'Για να σε βοηθήσουμε να παρακολουθείς από πού προέρχονται οι εισαγόμενοι αποκλεισμοί, οι εισαγόμενοι αποκλεισμοί θα δημιουργηθούν με το ακόλουθο ιδιωτικό σχόλιο: %{comment}' + private_comment_template: Εισήχθη από %{source} στις %{date} + title: Εισαγωγή αποκλεισμένων τομέων + invalid_domain_block: 'Ένας ή περισσότεροι αποκλεισμοί τομέα παραλείφθηκαν λόγω των ακόλουθων σφαλμάτων: %{error}' + new: + title: Εισαγωγή αποκλεισμένων τομέων no_file: Δεν επιλέχθηκε αρχείο follow_recommendations: + description_html: "Ακολουθώντας συστάσεις βοηθάει τους νέους χρήστες να βρουν γρήγορα ενδιαφέρον περιεχόμενο. Όταν ένας χρήστης δεν έχει αλληλεπιδράσει με άλλους αρκετά για να διαμορφώσει εξατομικευμένες συστάσεις, συνιστώνται αυτοί οι λογαριασμοί. Υπολογίζονται εκ νέου σε καθημερινή βάση από ένα σύνολο λογαριασμών με τις υψηλότερες πρόσφατες αλληλεπιδράσεις και μεγαλύτερο αριθμό τοπικών ακόλουθων για μια δεδομένη γλώσσα." language: Για τη γλώσσα status: Κατάσταση + suppress: Καταστολή της πρότασης ακολούθησης + suppressed: Σε καταστολή + title: Ακολούθησε τις προτάσεις + unsuppress: Επαναφορά των συστάσεων ακολούθησης instances: + availability: + description_html: + one: Εάν η παράδοση στον τομέα αποτύχει για %{count} ημέρα, δεν θα γίνουν περαιτέρω προσπάθειες παράδοσης εκτός αν μια παράδοση από τον τομέα ληφθεί. + other: Εάν η παράδοση στον τομέα αποτύχει για %{count} διαφορετικές ημέρες, δεν θα γίνουν περαιτέρω προσπάθειες παράδοσης εκτός αν μια παράδοση από τον τομέα ληφθεί. + failure_threshold_reached: Το όριο αποτυχίας επετεύχθη στις %{date}. + failures_recorded: + one: Αποτυχία προσπάθειας την %{count} ημέρα. + other: Αποτυχημένες προσπάθειες σε %{count} διαφορετικές ημέρες. + no_failures_recorded: Καμία καταγεγραμμένη αποτυχία. + title: Διαθεσιμότητα + warning: Η τελευταία προσπάθεια σύνδεσης σε αυτόν τον διακομιστή απέτυχε + back_to_all: Όλα + back_to_limited: Περιορισμένος + back_to_warning: Προειδοποίηση by_domain: Τομέας - confirm_purge: Είστε βέβαιοι ότι θέλετε να διαγράψετε μόνιμα τα δεδομένα από αυτόν τον τομέα; + confirm_purge: Είσαι βέβαιος ότι θες να διαγράψεις μόνιμα τα δεδομένα από αυτόν τον τομέα; + content_policies: + comment: Εσωτερική σημείωση + description_html: Μπορείς να ορίσεις τις πολιτικές περιεχομένου που θα εφαρμόζονται σε όλους τους λογαριασμούς από αυτόν τον τομέα και οποιονδήποτε από τους υποτομείς του. + limited_federation_mode_description_html: Μπορείτε να επιλέξετε αν θα επιτρέψετε τις συναλλαγές με αυτόν τον τομέα. + policies: + reject_media: Απόρριψη πολυμέσων + reject_reports: Απόρριψη αναφορών + silence: Περιορισμός + suspend: Αναστολή + policy: Πολιτική + reason: Δημόσιος λόγος + title: Πολιτικές περιεχομένου dashboard: + instance_accounts_dimension: Λογαριασμοί με τους περισσότερους ακόλουθους + instance_accounts_measure: αποθηκευμένοι λογαριασμοί + instance_followers_measure: οι ακόλουθοί μας εκεί + instance_follows_measure: οι ακόλουθοί τους εδώ instance_languages_dimension: Κορυφαίες γλώσσες + instance_media_attachments_measure: αποθηκευμένα συνημμένα πολυμέσων + instance_reports_measure: αναφορές γι' αυτές + instance_statuses_measure: αποθηκευμένες αναρτήσεις delivery: - failing: Αποτυγχάνει + all: Όλες + clear: Εκκαθάριση σφαλμάτων παράδοσης + failing: Αποτυχημένες + restart: Επανεκκίνηση παράδοσης + stop: Διακοπή παράδοσης + unavailable: Μη διαθέσιμο delivery_available: Διαθέσιμη παράδοση + delivery_error_days: Ημέρες σφάλματος παράδοσης + delivery_error_hint: Εάν η παράδοση δεν είναι δυνατή για %{count} ημέρες, θα επισημανθεί αυτόματα ως μη παραδόσιμη. destroyed_msg: Τα δεδομένα από το %{domain} βρίσκονται σε αναμονή για επικείμενη διαγραφή. empty: Δεν βρέθηκαν τομείς. + known_accounts: + one: "%{count} γνωστός λογαριασμός" + other: "%{count} γνωστοί λογαριασμοί" moderation: all: Όλα limited: Περιορισμένα - title: Διαμεσολάβηση + title: Συντονισμός private_comment: Ιδιωτικό σχόλιο public_comment: Δημόσιο σχόλιο purge: Εκκαθάριση - title: Γνωστοί κόμβοι - total_blocked_by_us: Μπλοκάρονται από εμάς + purge_description_html: Εάν πιστεύεις ότι αυτός ο τομέας είναι εκτός σύνδεσης μόνιμα, μπορείς να διαγράψεις όλες τις καταχωρήσεις λογαριασμών και τα σχετικά δεδομένα από αυτόν τον τομέα από τον αποθηκευτικό σου χώρο. Αυτό μπορεί να διαρκέσει λίγη ώρα. + title: Συναλλαγές + total_blocked_by_us: Αποκλεισμένοι από εμάς total_followed_by_them: Ακολουθούνται από εκείνους total_followed_by_us: Ακολουθούνται από εμάς - total_reported: Καταγγελίες προς εκείνους + total_reported: Αναφορές προς εκείνους total_storage: Συνημμένα πολυμέσα + totals_time_period_hint_html: Τα σύνολα που εμφανίζονται παρακάτω περιλαμβάνουν στοιχεία από την αρχή. invites: deactivate_all: Απενεργοποίηση όλων filter: @@ -387,28 +545,29 @@ el: '94670856': 3 χρόνια new: title: Δημιουργία νέου κανόνα IP + no_ip_block_selected: Δεν άλλαξαν οι κανόνες IP καθώς κανένας δεν επιλέχθηκε title: Κανόνες IP relationships: - title: Σχέσεις %{acct} + title: Σχέσεις του %{acct} relays: - add_new: Πρόσθεσε νέο ανταποκριτή (relay) + add_new: Προσθήκη νέου ανταποκριτή delete: Διαγραφή - description_html: Ο ομοσπονδιακός ανταποκριτής είναι ένας ενδιάμεσος εξυπηρετητής (server) που ανταλλάσσει μεγάλους όγκους δημόσιων τουτ μεταξύ εξυπηρετητών που εγγράφονται και δημοσιεύουν σε αυτόν. Βοηθάει μικρούς και μεσαίους εξυπηρετητές να ανακαλύψουν περιεχόμενο στο fediverse, που υπό άλλες συνθήκες θα χρειαζόταν κάποιους τοπικούς χρήστες που να ακολουθούν χρήστες σε απομακρυσμένους εξυπηρετητές. + description_html: Ο ανταποκριτής συναλλαγών είναι ένας ενδιάμεσος διακομιστής που ανταλλάσσει μεγάλους όγκους δημόσιων αναρτήσεων μεταξύ διακομιστών που εγγράφονται και δημοσιεύουν σε αυτόν. Βοηθάει μικρούς και μεσαίους διακομιστές να ανακαλύψουν περιεχόμενο στο fediverse, που υπό άλλες συνθήκες θα χρειαζόταν κάποιους τοπικούς χρήστες που να ακολουθούν χρήστες σε απομακρυσμένους διακομιστές. disable: Απενεργοποίηση disabled: Απενεργοποιημένο enable: Ενεργοποίηση - enable_hint: Μόλις ενεργοποιηθεί, ο εξυπηρετητής (server) σου θα εγγραφεί σε όλα τα δημόσια τουτ αυτού του ανταποκριτή (relay) και θα αρχίσει να προωθεί τα δικά του δημόσια τουτ σε αυτόν. + enable_hint: Μόλις ενεργοποιηθεί, ο διακομιστής σου θα εγγραφεί σε όλα τις δημόσιες αναρτήσεις αυτού του ανταποκριτή και θα αρχίσει να προωθεί τις δικές του δημόσιες αναρτήσεις σε αυτόν. enabled: Ενεργοποιημένο inbox_url: URL ανταποκριτή pending: Περιμένοντας την έγκριση του ανταποκριτή save_and_enable: Αποθήκευση και ενεργοποίηση setup: Όρισε μια σύνδεση ανταπόκρισης - signatures_not_enabled: Οι ανταποκριτές δεν θα λειτουργούν σωστά όσο είναι ενεργοποιημένες οι επιλογές ασφαλούς λειτουργίας ή επιτρεπόμενων συνδέσεων + signatures_not_enabled: Οι ανταποκριτές δεν θα λειτουργούν σωστά όσο είναι ενεργοποιημένες οι επιλογές ασφαλούς λειτουργίας ή περιορισμένων συναλλαγών status: Κατάσταση title: Ανταποκριτές report_notes: - created_msg: Επιτυχής δημιουργία σημείωσης καταγγελίας! - destroyed_msg: Επιτυχής διαγραφή σημείωσης καταγγελίας! + created_msg: Επιτυχής δημιουργία σημείωσης αναφοράς! + destroyed_msg: Επιτυχής διαγραφή σημείωσης αναφοράς! reports: account: notes: @@ -417,43 +576,78 @@ el: action_log: Αρχείο ελέγχου action_taken_by: Ενέργεια από τον/την actions: + delete_description_html: Οι δημοσιεύσεις με αναφορά θα διαγραφούν και θα καταγραφεί μια ποινή που θα σας βοηθήσει να αποφασίσετε σε μελλοντικές παραβάσεις από τον ίδιο λογαριασμό. + mark_as_sensitive_description_html: Τα πολυμέσα με αναφορά θα επισημανθούν ως ευαίσθητα και θα καταγραφεί μια ποινή που θα σας βοηθήσει να αποφασίσετε σε μελλοντικές παραβάσεις από τον ίδιο λογαριασμό. other_description_html: Δείτε περισσότερες επιλογές για τον έλεγχο της συμπεριφοράς του λογαριασμού και προσαρμόσετε την επικοινωνία στον αναφερόμενο λογαριασμό. - add_to_report: Προσθέστε περισσότερα στην αναφορά + resolve_description_html: Δεν θα ληφθούν μέτρα κατά του αναφερόμενου λογαριασμού, δεν θα καταγραφεί κανένα παράπτωμα, και η αναφορά θα κλείσει. + silence_description_html: Ο λογαριασμός θα είναι ορατός μόνο σε εκείνους που ήδη τον ακολουθούν ή τον αναζητούν χειροκίνητα, περιορίζοντας κατά πολύ την εμβέλειά του. Η ενέργεια αυτή είναι αναστρέψιμη. Κλείνει όλες τις αναφορές εναντίον αυτού του λογαριασμού. + suspend_description_html: Ο λογαριασμός και όλο το περιεχόμενό του θα είναι απρόσιτα και τελικά θα διαγραφούν και η αλληλεπίδραση με αυτόν θα είναι αδύνατη. Αναστρέψιμη εντός 30 ημερών. Κλείνει όλες τις αναφορές εναντίον αυτού του λογαριασμού. + actions_description_html: Αποφάσισε ποια μέτρα θα ληφθούν για την επίλυση αυτής της αναφοράς. Εάν προβείς σε τιμωρητική ενέργεια κατά του αναφερόμενου λογαριασμού, θα αποσταλεί ειδοποίηση μέσω ηλεκτρονικού ταχυδρομείου σε αυτόν, εκτός όταν η κατηγορία Σπαμ είναι επιλεγμένη. + actions_description_remote_html: Αποφάσισε ποια μέτρα θα ληφθούν για την επίλυση αυτής της αναφοράς. Αυτό θα επηρεάσει μόνο το πώς ο δικός σας διακομιστής επικοινωνεί με αυτόν τον απομακρυσμένο λογαριασμό και χειρίζεται το περιεχόμενό του. + add_to_report: Πρόσθεσε περισσότερα στην αναφορά are_you_sure: Σίγουρα; assign_to_self: Ανάθεση σε μένα assigned: Αρμόδιος συντονιστής - by_target_domain: Κόμβος του λογαριασμού υπό καταγγελία + by_target_domain: Τομέας του αναφερόμενου λογαριασμού + cancel: Άκυρο category: Κατηγορία + category_description_html: Ο λόγος για τον οποίο αναφέρθηκε αυτός ο λογαριασμός και/ή το περιεχόμενο θα εσωκλείεται σε επικοινωνία με τον αναφερόμενο λογαριασμό comment: none: Κανένα - created_at: Καταγγέλθηκε - delete_and_resolve: Διαγραφή δημοσιεύσεων + comment_description_html: 'Για να δώσει περισσότερες πληροφορίες, ο/η %{name} έγραψε:' + confirm: Επιβεβαίωση + confirm_action: Επιβεβαίωση ενέργειας συντονισμού ενάντια στον λογαριασμό @%{acct} + created_at: Αναφέρθηκε + delete_and_resolve: Διαγραφή αναρτήσεων forwarded: Προωθημένα forwarded_to: Προώθημένα προς %{domain} - mark_as_resolved: Σημειωμένο ως επιλυμένο + mark_as_resolved: Σημείωση ως επιλυμένο mark_as_sensitive: Σήμανση ως ευαίσθητο - mark_as_unresolved: Σημειωμένο ως ανεπίλυτο + mark_as_unresolved: Σήμανση ως ανεπίλυτο no_one_assigned: Κανένας notes: create: Πρόσθεσε σημείωση create_and_resolve: Επίλυσε με σημείωση create_and_unresolve: Ξανάνοιξε με σημείωση delete: Διαγραφή - placeholder: Περιέγραψε τις ενέργειες που έγιναν, ή οποιαδήποτε άλλη ενημέρωση... + placeholder: Περιέγραψε τις ενέργειες που έγιναν ή οποιαδήποτε άλλη σχετική ενημέρωση... title: Σημειώσεις - quick_actions_description_html: 'Κάντε μια γρήγορη ενέργεια ή μετακινηθείτε προς τα κάτω για να δείτε το αναφερόμενο περιεχόμενο:' + notes_description_html: Δες και άφησε σημειώσεις σε άλλους συντονιστές και στον μελλοντικό εαυτό σου + processed_msg: 'Η αναφορά #%{id} διεκπεραιώθηκε με επιτυχία' + quick_actions_description_html: 'Κάνε μια γρήγορη ενέργεια ή μετακινήσου προς τα κάτω για να δεις το αναφερόμενο περιεχόμενο:' remote_user_placeholder: ο απομακρυσμένος χρήστης από %{instance} - reopen: Ξανάνοιξε την καταγγελία - report: 'Καταγγελία #%{id}' + reopen: Ξανάνοιξε την αναφορά + report: 'Αναφορά #%{id}' reported_account: Αναφερόμενος λογαριασμός reported_by: Αναφέρθηκε από resolved: Επιλύθηκε - resolved_msg: Η καταγγελία επιλύθηκε επιτυχώς! + resolved_msg: Η αναφορά επιλύθηκε επιτυχώς! skip_to_actions: Μετάβαση στις ενέργειες status: Κατάσταση statuses: Αναφερόμενο περιεχόμενο + statuses_description_html: Το προσβλητικό περιεχόμενο θα εσωκλείεται στην επικοινωνία με τον αναφερόμενο λογαριασμό + summary: + action_preambles: + delete_html: 'Πρόκειται να αφαιρέσεις μερικές από τις αναρτήσεις του @%{acct}. Αυτό θα:' + mark_as_sensitive_html: 'Πρόκειται να επισημάνεις μερικές από τις αναρτήσεις του @%{acct} ως ευαίσθητες. Αυτό θα:' + silence_html: 'Πρόκειται να περιορίσεις τον λογαριασμό του @%{acct}. Αυτό θα:' + suspend_html: 'Πρόκειται να αναστείλεις τον λογαριασμό του @%{acct}. Αυτό θα:' + actions: + delete_html: Αφαίρεσε τις προσβλητικές αναρτήσεις + mark_as_sensitive_html: Σημειώστε τα πολυμέσα των προσβλητικών αναρτήσεων ως ευαίσθητα + silence_html: Περιορίσε σοβαρά την εμβέλεια του @%{acct} κάνοντας το προφίλ και το περιεχόμενό του ορατά μόνο σε άτομα που ήδη τον ακολουθούν ή που αναζητούν χειροκίνητα το προφίλ του + suspend_html: Αναστολή του @%{acct}, καθιστώντας το προφίλ και το περιεχόμενό του μη προσβάσιμα και αδύνατο να αλληλεπιδράσει κανείς με αυτά + close_report: 'Επισήμανση αναφοράς #%{id} ως επιλυμένη' + close_reports_html: Επισήμανε όλες τις αναφορές ενάντια στον λογαριασμό @%{acct} ως επιλυμένες + delete_data_html: Διάγραψε το προφίλ και το περιεχόμενο του @%{acct} σε 30 ημέρες από τώρα εκτός αν, εν τω μεταξύ, ανακληθεί η αναστολή + preview_preamble_html: 'Ο @%{acct} θα λάβει μια προειδοποίηση με τα ακόλουθο περιεχόμενο:' + record_strike_html: Κατάγραψε ένα παράπτωμα εναντίον του @%{acct} για να σε βοηθήσει να αποφασίσεις σε μελλοντικές παραβιάσεις από αυτόν τον λογαριασμό + send_email_html: Στείλε στον @%{acct} ένα προειδοποιητικό e-mail + warning_placeholder: Προαιρετικές επιπλέον εξηγήσεις για αυτή την ενέργεια από την ομάδα συντονισμού. + target_origin: Προέλευση του αναφερόμενου λογαριασμού title: Αναφορές - unassign: Αποσύνδεση + unassign: Αναίρεση ανάθεσης + unknown_action_msg: 'Άγνωστη ενέργεια: %{action}' unresolved: Άλυτη updated_at: Ενημερωμένη view_profile: Προβολή προφίλ @@ -464,57 +658,106 @@ el: other: "%{count} χρήστες" categories: administration: Διαχείριση - devops: Devops + devops: DevOps invites: Προσκλήσεις + moderation: Συντονισμός + special: Ειδικός delete: Διαγραφή + description_html: Με τους ρόλους χρηστών, μπορείς να προσαρμόσεις σε ποιες λειτουργίες και περιοχές του Mastodon, οι χρήστες σας μπορούν να έχουν πρόσβαση. edit: Επεξεργασία ρόλου '%{name}' everyone: Προεπιλεγμένα δικαιώματα + everyone_full_description_html: Αυτός είναι ο βασικός ρόλος που επηρεάζει όλους τους χρήστες, ακόμη και εκείνους που δεν έχουν κάποιον ρόλο. Όλοι οι άλλοι ρόλοι κληρονομούν δικαιώματα από αυτόν. permissions_count: one: "%{count} δικαίωμα" other: "%{count} δικαιώματα" privileges: administrator: Διαχειριστής - invite_users: Πρόσκληση χρηστών - manage_announcements: Διαχείριση ανακοινώσεων - manage_roles: Διαχείριση ρόλων + administrator_description: Οι χρήστες με αυτό το δικαίωμα θα παρακάμπτουν κάθε δικαίωμα + delete_user_data: Διαγραφή Δεδομένων Χρήστη + delete_user_data_description: Επιτρέπει στους χρήστες να διαγράφουν τα δεδομένα άλλων χρηστών χωρίς καθυστέρηση + invite_users: Πρόσκληση Χρηστών + invite_users_description: Επιτρέπει στους χρήστες να προσκαλούν νέα άτομα στον διακομιστή + manage_announcements: Διαχείριση Ανακοινώσεων + manage_announcements_description: Επιτρέπει στους χρήστες να διαχειρίζονται ανακοινώσεις στον διακομιστή + manage_appeals: Διαχείριση Εφέσεων + manage_appeals_description: Επιτρέπει στους χρήστες να εξετάζουν τις εφέσεις κατά των ενεργειών της ομάδας συντονισμού + manage_blocks: Διαχείριση Αποκλεισμών + manage_blocks_description: Επιτρέπει στους χρήστες να αποκλείουν παρόχους e-mail και διευθύνσεις IP + manage_custom_emojis: Διαχείριση Προσαρμοσμένων Emojis + manage_custom_emojis_description: Επιτρέπει στους χρήστες να διαχειρίζονται προσαρμοσμένα emojis στον διακομιστή + manage_federation: Διαχείριση Συναλλαγών + manage_federation_description: Επιτρέπει στους χρήστες να αποκλείουν ή να επιτρέπουν τις συναλλαγές με άλλους τομείς και να ελέγχουν την παράδοση + manage_invites: Διαχείριση Προσκλήσεων + manage_invites_description: Επιτρέπει στους χρήστες να περιηγούνται και να απενεργοποιούν τους συνδέσμους πρόσκλησης + manage_reports: Διαχείριση Αναφορών + manage_reports_description: Επιτρέπει στους χρήστες να εξετάζουν τις αναφορές και να εκτελούν ενέργειες συντονισμού εναντίον τους + manage_roles: Διαχείριση Ρόλων + manage_roles_description: Επιτρέπει στους χρήστες να διαχειρίζονται και να αναθέτουν ρόλους κατώτερων των δικών τους + manage_rules: Διαχείριση Κανόνων + manage_rules_description: Επιτρέπει στους χρήστες να αλλάξουν τους κανόνες του διακομιστή manage_settings: Διαχείριση ρυθμίσεων - manage_users: Διαχείριση χρηστών + manage_settings_description: Επιτρέπει στους χρήστες να αλλάξουν τις ρυθμίσεις του ιστοτόπου + manage_taxonomies: Διαχείριση Ταξινομιών + manage_taxonomies_description: Επιτρέπει στους χρήστες να εξετάζουν το δημοφιλές περιεχόμενο και να ενημερώνουν τις ρυθμίσεις ετικέτας + manage_user_access: Διαχείριση Πρόσβασης Χρήστη + manage_user_access_description: Επιτρέπει στους χρήστες να απενεργοποιούν την ταυτοποίηση δύο παραγόντων άλλων χρηστών, να αλλάξουν τη διεύθυνση ηλεκτρονικού ταχυδρομείου τους και να επαναφέρουν τον κωδικό πρόσβασής τους + manage_users: Διαχείριση Χρηστών + manage_users_description: Επιτρέπει στους χρήστες να βλέπουν τις λεπτομέρειες άλλων χρηστών και να εκτελούν ενέργειες συντονισμού εναντίον τους + manage_webhooks: Διαχείριση Webhooks + manage_webhooks_description: Επιτρέπει στους χρήστες να ορίζουν webhooks για συμβάντα διαχείρισης + view_audit_log: Προβολή Καταλόγου Καταγραφών + view_audit_log_description: Επιτρέπει στους χρήστες να βλέπουν ένα ιστορικό ενεργειών διαχείρισης στον διακομιστή + view_dashboard: Προβολή Ταμπλό + view_dashboard_description: Επιτρέπει στους χρήστες να έχουν πρόσβαση στον ταμπλό πληροφοριών και σε διάφορες μετρήσεις view_devops: DevOps + view_devops_description: Επιτρέπει στους χρήστες να έχουν πρόσβαση στα ταμπλό πληροφοριών Sidekiq και pgHero title: Ρόλοι rules: add_new: Προσθήκη κανόνα delete: Διαγραφή - description_html: Ενώ οι περισσότεροι ισχυρίζονται ότι έχουν διαβάσει και συμφωνούν με τους όρους της υπηρεσίας, συνήθως οι άνθρωποι δεν διαβάζουν μέχρι μετά την εμφάνιση ενός προβλήματος. Κάντε ευκολότερο να δουν τους κανόνες του διακομιστή σας με μια ματιά παρέχοντας τους σε μια λίστα σημείων. Προσπαθήστε να κρατήσετε μεμονωμένους κανόνες σύντομους και απλούς, αλλά προσπαθήστε να μην τους χωρίσετε σε πολλά ξεχωριστά αντικείμενα. + description_html: Ενώ οι περισσότεροι ισχυρίζονται ότι έχουν διαβάσει και συμφωνούν με τους όρους της υπηρεσίας, συνήθως οι άνθρωποι δεν διαβάζουν μέχρι μετά την εμφάνιση ενός προβλήματος. Κάνε ευκολότερο να δουν τους κανόνες του διακομιστή σας με μια ματιά παρέχοντας τους σε μια λίστα. Προσπάθησε να κρατήσεις τους μεμονωμένους κανόνες σύντομους και απλούς, αλλά προσπάθησε να μην τους χωρίσεις σε πολλά ξεχωριστά αντικείμενα. edit: Επεξεργασία κανόνα empty: Δεν έχουν οριστεί ακόμα κανόνες διακομιστή. title: Κανόνες διακομιστή settings: about: manage_rules: Διαχείριση κανόνων διακομιστή + preamble: Παρέχετε αναλυτικές πληροφορίες σχετικά με τη λειτουργία του διακομιστή, τον συντονισμό και τη χρηματοδότηση. + rules_hint: Υπάρχει μια ειδική περιοχή για τους κανόνες που αναμένεται να τηρούν οι χρήστες σας. title: Σχετικά με appearance: + preamble: Προσάρμοσε την ιστοσελίδα του Mastodon. title: Εμφάνιση + branding: + preamble: Η ταυτότητα του διακομιστή σου, τον διαφοροποιεί από άλλους διακομιστές του δικτύου. Αυτές οι πληροφορίες μπορεί να εμφανίζονται σε διάφορα περιβάλλοντα, όπως η ιστοσελίδα του Mastodon, εγγενείς εφαρμογές, σε προεπισκοπήσεις συνδέσμου σε άλλους ιστότοπους και εντός εφαρμογών μηνυμάτων και ούτω καθεξής. Γι' αυτό, είναι καλύτερο να διατηρούνται αυτές οι πληροφορίες σαφείς, σύντομες και συνοπτικές. + title: Ταυτότητα content_retention: + preamble: Έλεγξε πώς αποθηκεύεται το περιεχόμενο που δημιουργείται από τους χρήστες στο Mastodon. title: Διατήρηση περιεχομένου default_noindex: - desc_html: Επηρεάζει όσους χρήστες δεν έχουν αλλάξει αυτή τη ρύθμιση οι ίδιοι + desc_html: Επηρεάζει όσους χρήστες δεν έχουν αλλάξει οι ίδιοι αυτή τη ρύθμιση title: Εξαίρεση χρηστών από τις μηχανές αναζήτησης discovery: + follow_recommendations: Ακολούθησε τις προτάσεις + preamble: Δημοσιεύοντας ενδιαφέρον περιεχόμενο είναι καθοριστικό για την ενσωμάτωση νέων χρηστών που μπορεί να μη γνωρίζουν κανέναν στο Mastodon. Έλεγξε πώς λειτουργούν διάφορες δυνατότητες ανακάλυψης στον διακομιστή σας. profile_directory: Κατάλογος προφίλ public_timelines: Δημόσιες ροές + publish_discovered_servers: Δημοσίευση διακομιστών που έχουν ανακαλυφθεί + publish_statistics: Δημοσίευση στατιστικών + title: Ανακάλυψη trends: Τάσεις domain_blocks: all: Για όλους disabled: Για κανέναν users: Προς συνδεδεμένους τοπικούς χρήστες registrations: + preamble: Έλεγξε ποιος μπορεί να δημιουργήσει ένα λογαριασμό στον διακομιστή σας. title: Εγγραφές registrations_mode: modes: approved: Απαιτείται έγκριση για εγγραφή none: Δεν μπορεί να εγγραφεί κανείς open: Μπορεί να εγγραφεί ο οποιοσδήποτε - title: Ρυθμίσεις διακομιστή site_uploads: delete: Διαγραφή μεταφορτωμένου αρχείου destroyed_msg: Η μεταφόρτωση ιστότοπου διαγράφηκε επιτυχώς! @@ -522,10 +765,11 @@ el: account: Συντάκτης application: Εφαρμογή back_to_account: Επιστροφή στη σελίδα λογαριασμού + back_to_report: Πίσω στη σελίδα αναφοράς batch: remove_from_report: Αφαίρεση από την αναφορά report: Αναφορά - deleted: Διαγραμμένα + deleted: Διαγεγραμμένα favourites: Αγαπημένα history: Ιστορικό εκδόσεων in_reply_to: Απάντηση σε @@ -534,146 +778,267 @@ el: title: Πολυμέσα metadata: Μεταδεδομένα no_status_selected: Καμία δημοσίευση δεν άλλαξε αφού καμία δεν ήταν επιλεγμένη - open: Άνοιγμα δημοσίευσης + open: Άνοιγμα ανάρτησης + original_status: Αρχική ανάρτηση reblogs: Αναδημοσιεύσεις status_changed: Η ανάρτηση άλλαξε title: Καταστάσεις λογαριασμού - trending: Δημοφιλή + trending: Τάσεις visibility: Ορατότητα with_media: Με πολυμέσα + strikes: + actions: + delete_statuses: Ο/Η %{name} διέγραψε τις αναρτήσεις του/της %{target} + disable: Ο/Η %{name} πάγωσε τον λογαριασμό του/της %{target} + mark_statuses_as_sensitive: Ο/Η %{name} επισήμανε τα πολυμέσα του/της %{target} ως ευαίσθητα + none: Ο/Η %{name} έστειλε προειδοποίηση προς τον/την %{target} + sensitive: Ο/Η %{name} επισήμανε τα πολυμέσα του λογαριασμού %{target} ως ευαίσθητα + silence: Ο/Η %{name} περιόρισε τον λογαριασμό %{target} + suspend: ο/η %{name} ανέστειλε τον λογαριασμό %{target} + appeal_approved: Έγινε έφεση + appeal_pending: Έφεση σε εκκρεμότητα + appeal_rejected: Η έφεση απορρίφθηκε system_checks: database_schema_check: - message_html: Υπάρχουν μετακινήσεις βάσης δεδομένων που εκκρεμούν. Παρακαλώ εκτελέστε τις για να βεβαιωθείτε ότι η εφαρμογή συμπεριφέρεται όπως αναμένεται + message_html: Υπάρχουν μετακινήσεις βάσεων δεδομένων που εκκρεμούν. Παρακαλώ εκτέλεσέ τες για να βεβαιωθείς ότι η εφαρμογή συμπεριφέρεται όπως αναμένεται + elasticsearch_running_check: + message_html: Δεν ήταν δυνατή η σύνδεση στο Elasticsearch. Παρακαλώ έλεγξε ότι εκτελείται ή απενεργοποίησε την αναζήτηση πλήρους κειμένου + elasticsearch_version_check: + message_html: 'Μη συμβατή έκδοση Elasticsearch: %{value}' + version_comparison: Εκτελείται η έκδοση Elasticsearch %{running_version} ενώ απαιτείται %{required_version} rules_check: action: Διαχείριση κανόνων διακομιστή - message_html: Δεν έχετε ορίσει κανέναν κανόνα διακομιστή. + message_html: Δεν έχεις ορίσει κανέναν κανόνα διακομιστή. + sidekiq_process_check: + message_html: Καμία διεργασία Sidekiq δεν εκτελείται για την ουρά %{value}. Παρακαλώ έλεγξε τη διαμόρφωση του Sidekiq + upload_check_privacy_error: + action: Δες εδώ για περισσότερες πληροφορίες + message_html: "Ο διακομιστής σας δεν έχει ρυθμιστεί σωστά. Το απόρρητο των χρηστών σας κινδυνεύει." + upload_check_privacy_error_object_storage: + action: Δες εδώ για περισσότερες πληροφορίες + message_html: "Ο χώρος αποθήκευσης αντικειμένων σου δεν έχει ρυθμιστεί σωστά. Το απόρρητο των χρηστών σου κινδυνεύει." tags: - review: Κατάσταση έγκρισης + review: Κατάσταση αξιολόγησης updated_msg: Οι ρυθμίσεις των ετικετών ενημερώθηκαν επιτυχώς title: Διαχείριση trends: + allow: Επιτρέπεται + approved: Εγκρίθηκε + disallow: Να μην επιτρέπεται + links: + allow: Να επιτρέπεται σύνδεσμος + allow_provider: Να επιτρέπεται ο εκδότης + description_html: Αυτοί οι σύνδεσμοι μοιράζονται αρκετά από λογαριασμούς των οποίων τις δημοσιεύσεις, βλέπει ο διακομιστής σας. Μπορεί να βοηθήσει τους χρήστες σας να μάθουν τί συμβαίνει στον κόσμο. Οι σύνδεσμοι δεν εμφανίζονται δημόσια μέχρι να εγκρίνετε τον εκδότη. Μπορείς επίσης να επιτρέψεις ή να απορρίψεις μεμονωμένους συνδέσμους. + disallow: Να μην επιτρέπεται ο σύνδεσμος + disallow_provider: Να μην επιτρέπεται ο εκδότης + no_link_selected: Κανένας σύνδεσμος δεν άλλαξε αφού κανείς δεν επιλέχθηκε + publishers: + no_publisher_selected: Κανένας εκδότης δεν άλλαξε καθώς κανένας δεν επιλέχθηκε + shared_by_over_week: + one: Κοινοποιήθηκε από ένα άτομο την τελευταία εβδομάδα + other: Κοινοποιήθηκε από %{count} άτομα την τελευταία εβδομάδα + title: Σύνδεσμοι σε τάση + usage_comparison: Κοινοποιήθηκε %{today} φορές σήμερα, σε σύγκριση με %{yesterday} χθες + not_allowed_to_trend: Δεν επιτρέπεται να γίνει δημοφιλές only_allowed: Μόνο επιτρεπόμενα + pending_review: Εκκρεμεί αξιολόγηση + preview_card_providers: + allowed: Σύνδεσμοι από αυτόν τον εκδότη μπορούν να γίνουν δημοφιλείς + description_html: Αυτοί είναι τομείς από τους οποίους οι σύνδεσμοι συχνά μοιράζονται στον διακομιστή σας. Σύνδεσμοι δεν γίνουν δημοφιλείς δημοσίως εκτός και αν ο τομέας του συνδέσμου εγκριθεί. Η έγκρισή σας (ή απόρριψη) περιλαμβάνει και τους υποτομείς. + rejected: Σύνδεσμοι από αυτόν τον εκδότη δε θα γίνουν δημοφιλείς + title: Εκδότες + rejected: Απορρίφθηκε + statuses: + allow: Να επιτρέπεται η ανάρτηση + allow_account: Να επιτρέπεται ο συγγραφέας + description_html: Αυτές είναι αναρτήσεις για τις οποίες ο διακομιστής σας γνωρίζει ότι κοινοποιούνται και αρέσουν πολύ αυτή τη περίοδο. Μπορεί να βοηθήσει νέους και χρήστες που επιστρέφουν, να βρουν περισσότερα άτομα να ακολουθήσουν. Καμία ανάρτηση δεν εμφανίζεται δημόσια μέχρι να εγκρίνεις τον συντάκτη και ο συντάκτης να επιτρέπει ο λογαριασμός του να προτείνεται και σε άλλους. Μπορείς επίσης να επιτρέψεις ή να απορρίψεις μεμονωμένες δημοσιεύσεις. + disallow: Να μην επιτρέπεται η δημοσίευση + disallow_account: Να μην επιτρέπεται ο συντάκτης + no_status_selected: Καμία δημοφιλής ανάρτηση δεν άλλαξε αφού καμία δεν επιλέχθηκε + not_discoverable: Ο συντάκτης δεν έχει επιλέξει να είναι ανακαλύψιμος + shared_by: + one: Μοιράστηκε ή προστέθηκε στα αγαπημένα μία φορά + other: Μοιράστηκε και προστέθηκε στα αγαπημένα %{friendly_count} φορές + title: Αναρτήσεις σε τάση tags: + current_score: Τρέχουσα βαθμολογία %{score} dashboard: + tag_accounts_measure: μοναδικές χρήσεις tag_languages_dimension: Κορυφαίες γλώσσες tag_servers_dimension: Κορυφαίοι διακομιστές tag_servers_measure: διαφορετικοί διακομιστές - trending: Δημοφιλή + tag_uses_measure: συνολικές χρήσεις + description_html: Αυτές είναι ετικέτες που εμφανίζονται αυτή τη στιγμή σε πολλές αναρτήσεις που βλέπει ο διακομιστής σας. Μπορεί να βοηθήσει τους χρήστες σας να μάθουν τί συζητείται αυτή τη στιγμή. Δεν εμφανίζονται ετικέτες δημοσίως μέχρι να τις εγκρίνεις. + listable: Μπορεί να προταθεί + no_tag_selected: Καμία ετικέτα δεν άλλαξε αφού καμία δεν ήταν επιλεγμένη + not_listable: Δεν θα προτείνεται + not_trendable: Δεν θα εμφανίζεται στις τάσεις + not_usable: Δεν μπορεί να χρησιμοποιηθεί + peaked_on_and_decaying: Κορυφαία θέση στις %{date}, τώρα φθίνει + title: Ετικέτες σε τάση + trendable: Μπορεί να εμφανιστεί στις τάσεις + trending_rank: 'Τάση #%{rank}' + usable: Μπορεί να χρησιμοποιηθεί + usage_comparison: Χρησιμοποιήθηκε %{today} φορές σήμερα, σε σύγκριση με %{yesterday} χθες + used_by_over_week: + one: Χρησιμοποιήθηκε από ένα άτομο την τελευταία εβδομάδα + other: Χρησιμοποιήθηκε από %{count} άτομα την τελευταία εβδομάδα + title: Τάσεις + trending: Τάσεις warning_presets: add_new: Πρόσθεση νέου delete: Διαγραφή edit_preset: Ενημέρωση προκαθορισμένης προειδοποίησης - empty: Δεν έχετε ακόμη ορίσει κάποια προεπιλογή προειδοποίησης. + empty: Δεν έχετε ακόμη ορίσει κάποια προκαθορισμένη προειδοποίηση. title: Διαχείριση προκαθορισμένων προειδοποιήσεων webhooks: + add_new: Προσθήκη σημείου τερματισμού delete: Διαγραφή + description_html: Ένα webhook επιτρέπει στο Mastodon να στείλει ειδοποιήσεις πραγματικού χρόνου σχετικά με επιλεγμένα γεγονότα στη δική σου εφαρμογή, ώστε η εφαρμογή σας να μπορεί να προκαλέσει αντιδράσεις αυτόματα. disable: Απενεργοποίηση disabled: Απενεργοποιημένα + edit: Επεξεργασία σημείου τερματισμού + empty: Δεν έχεις ακόμα ρυθμισμένα σημεία τερματισμού webhook. enable: Ενεργοποίηση + enabled: Ενεργό + enabled_events: + one: 1 ενεργό συμβάν + other: "%{count} ενεργά συμβάντα" + events: Συμβάντα + new: Νέο webhook + rotate_secret: Περιστροφή μυστικού + secret: Υπογραφή μυστικού status: Κατάσταση + title: Webhooks + webhook: Webhook admin_mailer: new_appeal: actions: + delete_statuses: διαγραφή των αναρτήσεών του + disable: να παγώσει τον λογαριασμό του + mark_statuses_as_sensitive: να επισημάνουν τις δημοσιεύσεις του ως ευαίσθητες none: μια προειδοποίηση + sensitive: να επισημάνουν τον λογαριασμό του ως ευαίσθητο + silence: να περιορίσουν το λογαριασμό του + suspend: να αναστείλουν τον λογαριασμό του + body: 'Ο/Η %{target} κάνει έφεση στην απόφαση συντονισμού που έγινε από τον/την %{action_taken_by} στις %{date}, η οποία ήταν %{type}. Έγραψαν:' + next_steps: Μπορείς να εγκρίνεις την έφεση για να αναιρέσεις την απόφαση της ομάδας συντονισμού ή να την αγνοήσεις. + subject: Ο/Η %{username} κάνει έφεση σε μια απόφαση της ομάδας συντονισμού στον %{instance} new_pending_account: body: Τα στοιχεία του νέου λογαριασμού είναι παρακάτω. Μπορείς να εγκρίνεις ή να απορρίψεις αυτή την αίτηση. subject: Νέος λογαριασμός προς έγκριση στο %{instance} (%{username}) new_report: - body: Ο/Η %{reporter} κατήγγειλε τον/την %{target} - body_remote: Κάποιος/α από τον τομέα %{domain} κατήγγειλε τον/την %{target} - subject: Νέα καταγγελία για %{instance} (#%{id}) + body: Ο/Η %{reporter} ανέφερε τον/την %{target} + body_remote: Κάποιος/α από τον τομέα %{domain} ανέφερε τον/την %{target} + subject: Νέα αναφορά για %{instance} (#%{id}) + new_trends: + body: 'Τα ακόλουθα στοιχεία χρειάζονται αξιολόγηση για να μπορούν να προβληθούν δημόσια:' + new_trending_links: + title: Σύνδεσμοι σε τάση + new_trending_statuses: + title: Αναρτήσεις σε τάση + new_trending_tags: + no_approved_tags: Προς το παρόν δεν υπάρχουν εγκεκριμένες ετικέτεςσε τάση. + requirements: 'Οποιοσδήποτε από αυτούς τους υποψηφίους θα μπορούσε να ξεπεράσει την #%{rank} εγκεκριμένη ετικέτα σε τάση, που επί του παρόντος είναι #%{lowest_tag_name} με βαθμολογία %{lowest_tag_score}.' + title: Ετικέτες σε τάση + subject: Νέες τάσεις προς αξιολόγηση στο %{instance} aliases: add_new: Δημιουργία ψευδώνυμου created_msg: Δημιουργήθηκε νέο ψευδώνυμο. Τώρα μπορείς να ξεκινήσεις τη μεταφορά από τον παλιό λογαριασμό. deleted_msg: Αφαιρέθηκε το ψευδώνυμο. Η μεταφορά από εκείνον τον λογαριασμό σε αυτόν εδώ δε θα είναι πλέον δυνατή. empty: Δεν έχεις ψευδώνυμα. - hint_html: Αν θέλεις να μετακομίσεις από έναν άλλο λογαριασμό σε αυτόν εδώ, μπορείς εδώ να δημιουργήσεις ένα ψευδώνυμο, πράγμα που απαιτείται πριν προχωρήσεις για να μεταφέρεις τους ακολούθους σου από τον παλιό λογαριασμό σε αυτόν εδώ. Η ενέργεια αυτή είναι ακίνδυνη και αναστρέψιμη.Η μετακόμιση του λογαριασμού ξεκινάει από τον παλιό λογαριασμό. - remove: Αφαίρεση ψευδώνυμου + hint_html: Αν θέλεις να μετακινηθείς από έναν άλλο λογαριασμό σε αυτόν εδώ, εδώ μπορείς να δημιουργήσεις ένα ψευδώνυμο, πράγμα που απαιτείται πριν προχωρήσεις για να μεταφέρεις τους ακολούθους σου από τον παλιό λογαριασμό σε αυτόν εδώ. Η ενέργεια αυτή είναι ακίνδυνη και αναστρέψιμη.Η μετακόμιση του λογαριασμού ξεκινάει από τον παλιό λογαριασμό. + remove: Αποσύνδεση ψευδώνυμου appearance: - advanced_web_interface: Προηγμένη λειτουργία χρήσης - advanced_web_interface_hint: 'Αν θέλεις να χρησιμοποιήσεις ολόκληρο το πλάτος της οθόνης σου, η προηγμένη λειτουργία χρήσης σου επιτρέπει να ορίσεις πολλαπλές κολώνες ώστε να βλέπεις ταυτόχρονα όση πληροφορία θέλεις: Την αρχική ροή, τις ειδοποιήσεις, την ομοσπονδιακή ροή και όσες λίστες και ετικέτες θέλεις.' - animations_and_accessibility: Κίνηση και προσβασιμότητα + advanced_web_interface: Προηγμένη διεπαφή ιστού + advanced_web_interface_hint: 'Αν θέλεις να χρησιμοποιήσεις ολόκληρο το πλάτος της οθόνης σου, η προηγμένη λειτουργία χρήσης σου επιτρέπει να ορίσεις πολλαπλές στύλες ώστε να βλέπεις ταυτόχρονα όση πληροφορία θέλεις: Την αρχική ροή, τις ειδοποιήσεις, την ροή συναλλαγών και όσες λίστες και ετικέτες θέλεις.' + animations_and_accessibility: Εφέ κινήσεων και προσβασιμότητα confirmation_dialogs: Ερωτήσεις επιβεβαίωσης - discovery: Εξερεύνηση + discovery: Ανακάλυψη localization: body: Το Mastodon μεταφράζεται από εθελοντές. guide_link: https://crowdin.com/project/mastodon guide_link_text: Μπορεί να συνεισφέρει ο οποιοσδήποτε. sensitive_content: Ευαίσθητο περιεχόμενο - toot_layout: Διαρρύθμιση τουτ application_mailer: notification_preferences: Αλλαγή προτιμήσεων email salutation: "%{name}," settings: 'Άλλαξε τις προτιμήσεις email: %{link}' view: 'Προβολή:' view_profile: Προβολή προφίλ - view_status: Προβολή κατάστασης + view_status: Προβολή ανάρτησης applications: created: Η εφαρμογή δημιουργήθηκε επιτυχώς destroyed: Η εφαρμογή διαγράφηκε επιτυχώς - regenerate_token: Αναδημιουργία του διακριτικού πρόσβασης (access token) - token_regenerated: Το διακριτικό πρόσβασης (access token) αναδημιουργήθηκε επιτυχώς - warning: Μεγάλη προσοχή με αυτά τα στοιχεία. Μην τα μοιραστείς ποτέ με κανέναν! - your_token: Το διακριτικό πρόσβασής σου (access token) + logout: Αποσύνδεση + regenerate_token: Αναδημιουργία του διακριτικού πρόσβασης + token_regenerated: Το διακριτικό πρόσβασης αναδημιουργήθηκε επιτυχώς + warning: Να είσαι πολύ προσεκτικός με αυτά τα στοιχεία. Μην τα μοιραστείς ποτέ με κανέναν! + your_token: Το διακριτικό πρόσβασής σου auth: - apply_for_account: Ζητήστε έναν λογαριασμό - change_password: Συνθηματικό + apply_for_account: Ζήτα έναν λογαριασμό + confirmations: + wrong_email_hint: Εάν αυτή η διεύθυνση email δεν είναι σωστή, μπορείς να την αλλάξεις στις ρυθμίσεις λογαριασμού. delete_account: Διαγραφή λογαριασμού delete_account_html: Αν θέλεις να διαγράψεις το λογαριασμό σου, μπορείς να συνεχίσεις εδώ. Θα σου ζητηθεί επιβεβαίωση. description: prefix_invited_by_user: Ο/Η @%{name} σε προσκαλεί να συνδεθείς με αυτό τον διακομιστή του Mastodon! - prefix_sign_up: Άνοιξε λογαριασμό στο Mastodon σήμερα! + prefix_sign_up: Κάνε εγγραφή στο Mastodon σήμερα! suffix: Ανοίγοντας λογαριασμό θα μπορείς να ακολουθείς άλλους, να ανεβάζεις ενημερώσεις και να ανταλλάζεις μηνύματα με χρήστες σε οποιοδήποτε διακομιστή Mastodon, καθώς και άλλα! - didnt_get_confirmation: Δεν έλαβες τις οδηγίες επιβεβαίωσης; - dont_have_your_security_key: Δεν έχετε κλειδί ασφαλείας; + didnt_get_confirmation: Δεν έλαβες τον σύνδεσμο επιβεβαίωσης; + dont_have_your_security_key: Δεν έχεις κλειδί ασφαλείας; forgot_password: Ξέχασες το συνθηματικό σου; invalid_reset_password_token: Το διακριτικό επαναφοράς συνθηματικού είναι άκυρο ή ληγμένο. Παρακαλώ αιτήσου νέο. - link_to_otp: Γράψε τον κωδικό πιστοποίησης 2 παραγόντων (2FA) από το τηλέφωνό σου ή τον κωδικό επαναφοράς + link_to_otp: Γράψε τον κωδικό ταυτοποίησης 2 παραγόντων από το τηλέφωνό σου ή τον κωδικό επαναφοράς link_to_webauth: Χρήση συσκευής κλειδιού ασφαλείας log_in_with: Σύνδεση με login: Σύνδεση logout: Αποσύνδεση - migrate_account: Μετακόμιση σε διαφορετικό λογαριασμό + migrate_account: Μεταφορά σε διαφορετικό λογαριασμό migrate_account_html: Αν θέλεις να ανακατευθύνεις αυτό τον λογαριασμό σε έναν διαφορετικό, μπορείς να το διαμορφώσεις εδώ. or_log_in_with: Ή συνδέσου με + privacy_policy_agreement_html: Έχω διαβάσει και συμφωνώ με την πολιτική απορρήτου + progress: + confirm: Επιβεβαίωση email + details: Τα στοιχεία σας + review: Η αξιολόγησή μας + rules: Αποδοχή κανόνων providers: cas: Υπηρεσία Κεντρικής Πιστοποίησης (CAS) saml: Πρωτόκολλο SAML register: Εγγραφή registration_closed: Το %{instance} δεν δέχεται νέα μέλη - resend_confirmation: Στείλε ξανά τις οδηγίες επιβεβαίωσης + resend_confirmation: Επανάληψη αποστολής συνδέσμου επιβεβαίωσης reset_password: Επαναφορά συνθηματικού rules: + accept: Αποδοχή + back: Πίσω + preamble: Αυτά ορίζονται και επιβάλλονται από τους συντονιστές του%{domain}. title: Ορισμένοι βασικοί κανόνες. security: Ασφάλεια set_new_password: Ορισμός νέου συνθηματικού setup: - email_below_hint_html: Αν η παρακάτω διεύθυνση email είναι λανθασμένη, μπορείτε να την ενημερώσετε και να λάβετε νέο email επιβεβαίωσης. - email_settings_hint_html: Το email επιβεβαίωσης στάλθηκε στο %{email}. Αν η διεύθυνση αυτή δεν είναι σωστή, μπορείτε να την ενημερώσετε στις ρυθμίσεις λογαριασμού. - title: Ρυθμίσεις + email_below_hint_html: Έλεγξε τον φάκελο ανεπιθύμητης αλληλογραφίας ή ζήτα καινούργιο. Μπορείς να διορθώσεις τη διεύθυνση email σου αν είναι λάθος. + email_settings_hint_html: Πάτησε το σύνδεσμο που σου στείλαμε για να επαληθεύσεις το %{email}. Θα σε περιμένουμε εδώ. + link_not_received: Δεν έλαβες τον σύνδεσμο; + new_confirmation_instructions_sent: Θα λάβεις ένα νέο e-mail με το σύνδεσμο επιβεβαίωσης σε λίγα λεπτά! + title: Ελέγξτε τα εισερχόμενά σας sign_in: + preamble_html: Συνδεθείτε με τα διαπιστευτήριά σας στον %{domain}. Αν ο λογαριασμός σας φιλοξενείται σε διαφορετικό διακομιστή, δε θα μπορείτε να συνδεθείτε εδώ. title: Συνδεθείτε στο %{domain} sign_up: + manual_review: Οι εγγραφές στο %{domain} περνούν από χειροκίνητη αξιολόγηση από τους συντονιστές μας. Για να μας βοηθήσεις να επεξεργαστούμε την εγγραφή σου, γράψε λίγα λόγια για τον εαυτό σου και γιατί θέλεις έναν λογαριασμό στο %{domain}. + preamble: Με έναν λογαριασμό σ' αυτόν τον διακομιστή Mastodon, θα μπορείτε να ακολουθήσετε οποιοδήποτε άλλο άτομο στο δίκτυο, ανεξάρτητα από το πού φιλοξενείται ο λογαριασμός του. title: Ας ξεκινήσουμε τις ρυθμίσεις στο %{domain}. status: account_status: Κατάσταση λογαριασμού confirming: Αναμονή για ολοκλήρωση επιβεβαίωσης του email. + functional: Ο λογαριασμός σας είναι πλήρως λειτουργικός. pending: Η εφαρμογή σας εκκρεμεί έγκρισης, πιθανόν θα διαρκέσει κάποιο χρόνο. Θα λάβετε email αν εγκριθεί. redirecting_to: Ο λογαριασμός σου είναι ανενεργός γιατί επί του παρόντος ανακατευθύνει στον %{acct}. + view_strikes: Προβολή προηγούμενων ποινών εναντίον του λογαριασμού σας too_fast: Η φόρμα υποβλήθηκε πολύ γρήγορα, προσπαθήστε ξανά. use_security_key: Χρήση κλειδιού ασφαλείας - authorize_follow: - already_following: Ήδη ακολουθείς αυτό το λογαριασμό - already_requested: Έχετε ήδη στείλει ένα αίτημα ακολούθησης σε αυτόν τον λογαριασμό - error: Δυστυχώς παρουσιάστηκε ένα σφάλμα κατά την αναζήτηση του απομακρυσμένου λογαριασμού - follow: Ακολούθησε - follow_request: 'Έστειλες αίτημα παρακολούθησης προς:' - following: 'Επιτυχία! Πλέον ακολουθείς τον/την:' - post_follow: - close: Ή, μπορείς απλά να κλείσεις αυτό το παράθυρο. - return: Δείξε το προφίλ του χρήστη - web: Πήγαινε στο δίκτυο - title: Ακολούθησε %{acct} challenge: confirm: Συνέχεια hint_html: "Συμβουλή: Δεν θα σου ζητήσουμε τον κωδικό ασφαλείας σου ξανά για την επόμενη ώρα." @@ -683,6 +1048,10 @@ el: errors: invalid_key: δεν είναι έγκυρο κλειδί Ed25519 ή Curve25519 invalid_signature: δεν είναι έγκυρη υπογραφή Ed25519 + date: + formats: + default: "%b %d, %Y" + with_month_name: "%B %d, %Y" datetime: distance_in_words: about_x_hours: "%{count}ω" @@ -698,17 +1067,17 @@ el: x_months: "%{count}μ" x_seconds: "%{count}δ" deletes: - challenge_not_passed: Τα στοιχεία δεν ήταν σωστά + challenge_not_passed: Οι πληροφορίες που εισήγαγες δεν ήταν σωστές confirm_password: Γράψε το τρέχον συνθηματικό σου για να πιστοποιήσεις την ταυτότητά σου confirm_username: Γράψε το όνομα χρήστη σου για επιβεβαίωση proceed: Διαγραφή λογαριασμού success_msg: Ο λογαριασμός σου διαγράφηκε με επιτυχία warning: before: 'Πριν συνεχίσεις, παρακαλούμε να διαβάσεις τις παρακάτω σημειώσεις προσεκτικά:' - caches: Οποίο περιεχόμενο έχει αποθηκευτεί προσωρινά σε άλλους διακομιστές μπορεί να παραμείνει - data_removal: Οι δημοσιεύσεις σου και άλλα δεδομένα θα διαγραφούν οριστικά - email_change_html: Μπορείς να αλλάξεις τη διεύθυνση email σου Χωρίς να διαγράψεις το λογαριασμό σου - email_contact_html: Αν και πάλι δεν εμφανιστεί, μπορείς να στείλεις email προς %{email} για βοήθεια + caches: Περιεχόμενο που έχει αποθηκευτεί προσωρινά σε άλλους διακομιστές ίσως παραμείνει + data_removal: Οι αναρτήσεις σου και άλλα δεδομένα θα διαγραφούν οριστικά + email_change_html: Μπορείς να αλλάξεις τη διεύθυνση email σου χωρίς να διαγράψεις τον λογαριασμό σου + email_contact_html: Αν και πάλι δεν έρθει, μπορείς να στείλεις email προς %{email} για βοήθεια email_reconfirmation_html: Αν δεν έχεις λάβει το email επιβεβαίωσης, μπορείς να το ζητήσεις ξανά irreversible: Δεν θα μπορείς να ανακτήσεις ή ενεργοποιήσεις ξανά το λογαριασμό σου more_details_html: Για περισσότερες πληροφορίες, δες την πολιτική απορρήτου. @@ -716,8 +1085,34 @@ el: username_unavailable: Το όνομα χρήστη σου θα παραμείνει μη διαθέσιμο disputes: strikes: + action_taken: Ενέργεια που πραγματοποιήθηκε + appeal: Έφεση + appeal_approved: Αυτό το παράπτωμα έχει αναιρεθεί επιτυχώς και δεν είναι πλέον έγκυρο + appeal_rejected: Η έφεση απορρίφθηκε + appeal_submitted_at: Η έφεση υποβλήθηκε + appealed_msg: Η έφεσή σου έχει υποβληθεί. Αν εγκριθεί, θα ειδοποιηθείς. + appeals: + submit: Υποβολή έφεσης approve_appeal: Έγκριση έφεσης + associated_report: Συσχετισμένη αναφορά + created_at: Χρονολογείται + description_html: Αυτές είναι ενέργειες που λήφθηκαν κατά του λογαριασμού σου και προειδοποιήσεις που σου έχουν σταλεί από το προσωπικό του %{instance}. + recipient: Απευθύνεται σε reject_appeal: Απόρριψη έφεσης + status: 'Ανάρτηση #%{id}' + status_removed: Η ανάρτηση έχει ήδη αφαιρεθεί από το σύστημα + title: "%{action} στις %{date}" + title_actions: + delete_statuses: Αφαίρεση ανάρτησης + disable: Πάγωμα λογαριασμού + mark_statuses_as_sensitive: Σήμανση αναρτήσεων ως ευαίσθητες + none: Προειδοποίηση + sensitive: Σήμανση λογαριασμού ως ευαίσθητο + silence: Περιορισμός λογαριασμού + suspend: Αναστολή λογαριασμού + your_appeal_approved: Η έφεση σου έχει εγκριθεί + your_appeal_pending: Υπέβαλλες έφεση + your_appeal_rejected: Η έφεση σου απορρίφθηκε domain_validator: invalid_domain: δεν είναι έγκυρο όνομα τομέα errors: @@ -729,12 +1124,12 @@ el: '422': content: Απέτυχε η επιβεβαίωση ασφαλείας. Μήπως μπλοκάρεις τα cookies; title: Η επιβεβαίωση ασφαλείας απέτυχε - '429': Περιορισμένο + '429': Πάρα πολλές αιτήσεις '500': content: Λυπούμαστε, κάτι πήγε στραβά από τη δική μας μεριά. title: Η σελίδα αυτή δεν είναι σωστή '503': Η σελίδα δε μπόρεσε να εμφανιστεί λόγω προσωρινού σφάλματος του διακομιστή. - noscript_html: Για να χρησιμοποιήσετε τη δικτυακή εφαρμογή του Mastodon, ενεργοποίησε την Javascript. Εναλλακτικά, δοκίμασε μια από τις εφαρμογές για το Mastodon στην πλατφόρμα σου. + noscript_html: Για να χρησιμοποιήσεις τη δικτυακή εφαρμογή του Mastodon, ενεργοποίησε την Javascript. Εναλλακτικά, δοκίμασε μια από τις εφαρμογές για το Mastodon για την πλατφόρμα σου. existing_username_validator: not_found: δεν βρέθηκε τοπικός χρήστης με αυτό το όνομα not_found_multiple: δεν βρέθηκε %{usernames} @@ -742,78 +1137,119 @@ el: archive_takeout: date: Ημερομηνία download: Κατέβασε το αρχείο σου - hint_html: Μπορείς να αιτηθείς ένα αρχείο των τουτ και των ανεβασμένων πολυμέσων σου. Τα δεδομένα θα είναι σε μορφή ActivityPub, προσπελάσιμα από οποιοδήποτε συμβατό πρόγραμμα. Μπορείς να αιτηθείς αρχείο κάθε 7 μέρες. + hint_html: Μπορείς να αιτηθείς ένα αρχείο των αναρτήσεων και των ανεβασμένων πολυμέσων σου. Τα δεδομένα θα είναι σε μορφή ActivityPub, προσπελάσιμα από οποιοδήποτε συμβατό πρόγραμμα. Μπορείς να αιτηθείς ένα αρχείο κάθε 7 μέρες. in_progress: Συγκεντρώνουμε το αρχείο σου... request: Αιτήσου το αρχείο σου size: Μέγεθος blocks: Μπλοκάρεις bookmarks: Σελιδοδείκτες csv: CSV - domain_blocks: Μπλοκαρίσματα κόμβων + domain_blocks: Αποκλεισμοί τομέων lists: Λίστες - mutes: Αποσιωπήσεις - storage: Αποθήκευση πολυμέσων + mutes: Έχεις σε σίγαση + storage: Χώρος πολυμέσων featured_tags: add_new: Προσθήκη νέας errors: limit: Έχεις ήδη προσθέσει το μέγιστο αριθμό ετικετών - hint_html: "Τι είναι οι προβεβλημένες ετικέτες; Προβάλλονται στο δημόσιο προφίλ σου επιτρέποντας σε όποιον το βλέπει να χαζέψει τις δημοσιεύσεις που τις χρησιμοποιούν. Είναι ένας ωραίος τρόπος να παρακολουθείς την πορεία μιας δημιουργία ή ενός μακροπρόθεσμου έργου." + hint_html: "Τί είναι οι προβεβλημένες ετικέτες; Προβάλλονται στο δημόσιο προφίλ σου επιτρέποντας σε όποιον θέλει να περιηγηθεί στις αναρτήσεις που τις χρησιμοποιούν. Είναι ένας ωραίος τρόπος να παρακολουθείς την πορεία δημιουργικών εργασιών ή ενός μακροπρόθεσμου έργου." filters: contexts: account: Προφίλ - home: Αρχική ροή + home: Αρχική σελίδα και λίστες notifications: Ειδοποιήσεις public: Δημόσιες ροές thread: Συζητήσεις edit: add_keyword: Προσθήκη λέξης-κλειδιού keywords: Λέξεις-κλειδιά - title: Ενημέρωση φίλτρου + statuses: Μεμονωμένες αναρτήσεις + statuses_hint_html: Αυτό το φίλτρο εφαρμόζεται για την επιλογή μεμονωμένων αναρτήσεων, ανεξάρτητα από το αν ταιριάζουν με τις λέξεις - κλειδιά παρακάτω. Επισκόπηση ή αφαίρεση αναρτήσεων από το φίλτρο. + title: Επεξεργασία φίλτρου errors: - invalid_context: Έδωσες λάθος ή ανύπαρκτο πλαίσιο + deprecated_api_multiple_keywords: Αυτές οι παράμετροι δεν μπορούν να αλλάξουν από αυτήν την εφαρμογή επειδή ισχύουν για περισσότερες από μία λέξεις - κλειδιά φίλτρου. Χρησιμοποίησε μια πιο πρόσφατη εφαρμογή ή την ιστοσελίδα. + invalid_context: Δόθηκε κενό ή μη έγκυρο περιεχόμενο index: contexts: Φίλτρα σε %{contexts} delete: Διαγραφή empty: Δεν έχεις φίλτρα. expires_in: Λήγει σε %{distance} expires_on: Λήγει στις %{date} + keywords: + one: "%{count} λέξη - κλειδί" + other: "%{count} λέξεις - κλειδιά" + statuses: + one: "%{count} ανάρτηση" + other: "%{count} αναρτήσεις" + statuses_long: + one: "%{count} κρυμμένη μεμονωμένη ανάρτηση" + other: "%{count} κρυμμένες μεμονωμένες αναρτήσεις" title: Φίλτρα new: save: Αποθήκευση νέου φίλτρου title: Πρόσθεσε νέο φίλτρο - footer: - trending_now: Τάσεις + statuses: + back_to_filter: Πίσω στο φίλτρο + batch: + remove: Αφαίρεση από φίλτρο + index: + hint: Αυτό το φίλτρο ισχύει για την επιλογή μεμονωμένων αναρτήσεων ανεξάρτητα από άλλα κριτήρια. Μπορείς να προσθέσεις περισσότερες αναρτήσεις σε αυτό το φίλτρο από την ιστοσελίδα. + title: Φιλτραρισμένες αναρτήσεις generic: all: Όλα + all_items_on_page_selected_html: + one: "%{count} στοιχείο σε αυτή τη σελίδα είναι επιλεγμένο." + other: Όλα τα %{count} στοιχεία σε αυτή τη σελίδα είναι επιλεγμένα. + all_matching_items_selected_html: + one: "%{count} στοιχείο που ταιριάζει με την αναζήτησή σου είναι επιλεγμένο." + other: Όλα τα %{count} στοιχεία που ταιριάζουν στην αναζήτησή σου είναι επιλεγμένα. + cancel: Άκυρο changes_saved_msg: Οι αλλαγές αποθηκεύτηκαν! + confirm: Επιβεβαίωση copy: Αντιγραφή delete: Διαγραφή + deselect: Αποεπιλογή όλων + none: Κανένα order_by: Ταξινόμηση κατά save_changes: Αποθήκευση αλλαγών + select_all_matching_items: + one: Επέλεξε %{count} στοιχείο που ταιριάζει με την αναζήτησή σου. + other: Επέλεξε και τα %{count} αντικείμενα που ταιριάζουν στην αναζήτησή σου. today: σήμερα validation_errors: - one: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε το παρακάτω σφάλμα - other: Κάτι δεν είναι εντάξει ακόμα! Για κοίταξε τα παρακάτω %{count} σφάλματα - html_validator: - invalid_markup: 'περιέχει λάθος μορφοποίηση HTML: %{error}' + one: Κάτι δεν πάει καλά! Για κοίταξε το παρακάτω σφάλμα + other: Κάτι δεν πάει καλά! Για κοίταξε τα παρακάτω %{count} σφάλματα imports: errors: + empty: Κενό αρχείο CSV invalid_csv_file: 'Μη έγκυρο αρχείο CSV. Σφάλμα: %{error}' over_rows_processing_limit: περιέχει περισσότερες από %{count} γραμμές + too_large: Το αρχείο είναι πολύ μεγάλο + failures: Αποτυχίες modes: merge: Συγχώνευση - merge_long: Διατήρηση των εγγράφων που υπάρχουν και προσθηκη των νέων + merge_long: Διατήρηση των εγγράφων που υπάρχουν και προσθήκη των νέων overwrite: Αντικατάσταση overwrite_long: Αντικατάσταση των υπαρχόντων εγγράφων με τις καινούργιες - preface: Μπορείς να εισάγεις τα δεδομένα που έχεις εξάγει από άλλο κόμβο, όπως τη λίστα των ανθρώπων που ακολουθείς ή μπλοκάρεις. - success: Τα δεδομένα σου μεταφορτώθηκαν επιτυχώς και θα επεξεργαστούν εν καιρώ + preface: Μπορείς να εισάγεις τα δεδομένα που έχεις εξάγει από άλλο διακομιστή, όπως τη λίστα των ατόμων που ακολουθείς ή έχεις αποκλείσει. + recent_imports: Πρόσφατες Εισαγωγές + states: + finished: Ολοκληρώθηκε + in_progress: Σε εξέλιξη + scheduled: Προγραμματισμένη + status: Κατάσταση + success: Τα δεδομένα σου μεταφορτώθηκαν επιτυχώς και θα επεξεργαστούν σύντομα + time_started: Ξεκίνησε στις + type: Τύπος εισαγωγής + type_groups: + destructive: Μπλοκ & σίγαση types: blocking: Λίστα αποκλεισμού bookmarks: Σελιδοδείκτες domain_blocking: Λίστα αποκλεισμένων τομέων following: Λίστα ακολούθων muting: Λίστα αποσιωπήσεων - upload: Ανέβασμα + upload: Μεταμόρφωση invites: delete: Απενεργοποίησε expired: Ληγμένη @@ -825,62 +1261,73 @@ el: '604800': 1 εβδομάδα '86400': 1 μέρα expires_in_prompt: Ποτέ - generate: Δημιούργησε + generate: Δημιουργία συνδέσμου πρόσκλησης invited_by: 'Σε προσκάλεσε ο/η:' max_uses: one: 1 χρήσης other: "%{count} χρήσεων" max_uses_prompt: Απεριόριστη - prompt: Φτιάξε και μοίρασε συνδέσμους με τρίτους για να δώσεις πρόσβαση σε αυτόν τον κόμβο + prompt: Φτιάξε και μοίρασε συνδέσμους με τρίτους για να δώσεις πρόσβαση σε αυτόν τον διακομιστή table: expires_at: Λήγει uses: Χρήσεις title: Προσκάλεσε κόσμο lists: errors: - limit: Έχεις φτάσει το μέγιστο πλήθος επιτρεπτών λιστών + limit: Έχεις φτάσει το μέγιστο αριθμό λιστών + login_activities: + authentication_methods: + otp: εφαρμογή ταυτοποίησης δύο παραγόντων + password: συνθηματικό + sign_in_token: κωδικός ασφαλείας e-mail + webauthn: κλειδιά ασφαλείας + description_html: Αν δεις δραστηριότητα που δεν αναγνωρίζεις, σκεφτείς να αλλάξεις τον κωδικό πρόσβασής σου και να ενεργοποιήσεις τον έλεγχο ταυτότητας δύο παραγόντων. + empty: Δεν υπάρχει διαθέσιμο ιστορικό ελέγχου ταυτότητας + failed_sign_in_html: Αποτυχημένη προσπάθεια σύνδεσης με %{method} από %{ip} (%{browser}) + successful_sign_in_html: Επιτυχής σύνδεση με %{method} από %{ip} (%{browser}) + title: Ιστορικό ελέγχου ταυτότητας media_attachments: validations: - images_and_video: Δεν γίνεται να προσθέσεις βίντεο σε ενημέρωση που ήδη περιέχει εικόνες + images_and_video: Δεν γίνεται να προσθέσεις βίντεο σε ανάρτηση που ήδη περιέχει εικόνες not_ready: Δεν μπορούν να επισυναφθούν αρχεία για τα οποία δεν έχει τελειώσει η επεξεργασία. Προσπαθήστε ξανά σε λίγο! - too_many: Δεν γίνεται να προσθέσεις περισσότερα από 4 αρχεία + too_many: Δεν γίνεται να επισυνάψεις περισσότερα από 4 αρχεία migrations: - acct: ΌνομαΧρήστη@Τομέας του νέου λογαριασμού + acct: Μεταφέρθηκε στο cancel: Ακύρωση ανακατεύθυνσης - cancel_explanation: Ακυρώνοντας την ανακατεύθυνση θα ενεργοποιήσει ξανά τον τρέχοντα λογαριασμό σου, αλλά δεν θα φέρει πίσω τους ακόλουθους που έχουν μεταφερθεί σε εκείνον το λογαριασμό. + cancel_explanation: Ακυρώνοντας την ανακατεύθυνση θα ενεργοποιηθεί ξανά ο τρέχων λογαριασμό σου, αλλά δεν θα φέρει πίσω τους ακόλουθους που έχουν μεταφερθεί σε εκείνον το λογαριασμό. cancelled_msg: Η ανακατεύθυνση ακυρώθηκε επιτυχώς. errors: already_moved: είναι ο ίδιος λογαριασμός στον οποίο έχεις ήδη μεταφερθεί - missing_also_known_as: δεν αναφέρει αυτόν τον λογαριασμό - move_to_self: δεν επιτρέπεται να είναι ο τρέχων λογαριασμός + missing_also_known_as: δεν είναι ψευδώνυμο αυτού του λογαριασμού + move_to_self: δεν μπορεί να είναι ο τρέχων λογαριασμός not_found: δεν βρέθηκε - on_cooldown: Είσαι σε περίοδο προσαρμογής + on_cooldown: Είσαι σε περίοδο ηρεμίας followers_count: Ακόλουθοι τη στιγμή της μεταφοράς incoming_migrations: Μεταφορά από διαφορετικό λογαριασμό incoming_migrations_html: Για να μετακομίσεις από έναν άλλο λογαριασμό σε αυτόν εδώ, πρώτα πρέπει να δημιουργήσεις ένα ψευδώνυμο λογαριασμού. - moved_msg: Ο λογαριασμός σου πλέον ανακατευθύνει στον %{acct} και οι ακόλουθοί σου μεταφέρονται εκεί. - not_redirecting: Ο λογαριασμός σου δεν ανακατευθύνει σε κανέναν άλλο προς το παρόν. + moved_msg: Ο λογαριασμός σου πλέον ανακατευθύνεται στον %{acct} και οι ακόλουθοί σου μεταφέρονται εκεί. + not_redirecting: Ο λογαριασμός σου δεν ανακατευθύνεται σε κανέναν άλλο προς το παρόν. on_cooldown: Έχεις μετακομίσει το λογαριασμό σου πρόσφατα. Η δυνατότητα αυτή θα γίνει πάλι διαθέσιμη σε %{count} μέρες. past_migrations: Προηγούμενες μετακινήσεις proceed_with_move: Μετακίνηση ακολούθων - redirected_msg: Ο λογαριασμός σου ανακατευθύνει στο %{acct}. - redirecting_to: Ο λογαριασμός σου ανακατευθύνει στο %{acct}. + redirected_msg: Ο λογαριασμός σου ανακατευθύνεται στον %{acct}. + redirecting_to: Ο λογαριασμός σου ανακατευθύνεται στον %{acct}. set_redirect: Όρισε ανακατεύθυνση warning: - backreference_required: Θα πρέπει πρώτα να ρυθμιστεί μια αναφορά από τον νέο λογαριασμό προς αυτόν + backreference_required: Θα πρέπει πρώτα να ρυθμιστεί μια παραπομπή από τον νέο λογαριασμό προς αυτόν before: 'Πριν συνεχίσεις, παρακαλούμε διάβασε αυτές τις σημειώσεις προσεκτικά:' - cooldown: Άπαξ και μεταφερθείς υπάρχει μια περίοδος προσαρμογής κατά την οποία δε θα μπορείς να μετακινηθείς ξανά + cooldown: Μετά τη μετακίνηση υπάρχει μια περίοδος αναμονής κατά τη διάρκεια της οποίας δεν θα είσαι σε θέση να μετακινηθείς ξανά disabled_account: Ο τρέχων λογαριασμός σου δε θα είναι πλήρως ενεργός μετά. Πάντως θα έχεις πρόσβαση στην εξαγωγή δεδομένων καθώς και στην επανενεργοποίηση. - followers: Αυτή η ενέργεια θα μεταφέρει όλους τους ακόλουθούς σου από τον τρέχοντα λογαριασμός στον νέο λογαριασμό + followers: Αυτή η ενέργεια θα μεταφέρει όλους τους ακόλουθούς σου από τον τρέχοντα λογαριασμό στον νέο λογαριασμό only_redirect_html: Εναλλακτικά, μπορείς απλά να προσθέσεις μια ανακατατεύθυνση στο προφίλ σου. other_data: Κανένα άλλο δεδομένο δε θα μεταφερθεί αυτόματα - redirect: Το προφίλ του τρέχοντος λογαριασμό σου θα ενημερωθεί με μια σημείωση ανακατεύθυνσης και θα εξαιρεθεί από τα αποτελέσματα αναζητήσεων + redirect: Το προφίλ του τρέχοντος λογαριασμού σου θα ενημερωθεί με μια σημείωση ανακατεύθυνσης και θα εξαιρεθεί από τα αποτελέσματα αναζητήσεων moderation: title: Συντονισμός move_handler: - carry_blocks_over_text: Ο/Η χρήστης μετακόμισε από το %{acct}, που είχες αποκλείσει. - carry_mutes_over_text: Ο/Η χρήστης μετακόμισε από το %{acct}, που είχες αποσιωπήσει. - copy_account_note_text: 'Ο/Η χρήστης μετακόμισε από το %{acct}, ορίστε οι προηγούμενες σημειώσεις σου:' + carry_blocks_over_text: Ο χρήστης μετακόμισε από το %{acct}, που είχες αποκλείσει. + carry_mutes_over_text: Ο χρήστης μετακόμισε από το %{acct}, που είχες αποσιωπήσει. + copy_account_note_text: 'Ο χρήστης μετακόμισε από τον %{acct}, ορίστε οι προηγούμενες σημειώσεις σου για εκείνον:' navigation: toggle_menu: Εμφάνιση/Απόκρυψη μενού notification_mailer: @@ -890,7 +1337,7 @@ el: sign_up: subject: "%{name} έχει εγγραφεί" favourite: - body: 'Η κατάστασή σου αγαπήθηκε από τον/την %{name}:' + body: 'Η ανάρτησή σου αγαπήθηκε από τον/την %{name}:' subject: Ο/Η %{name} αγάπησε την κατάστασή σου title: Νέο αγαπημένο follow: @@ -898,23 +1345,25 @@ el: subject: Ο/Η %{name} πλέον σε ακολουθεί title: Νέος/α ακόλουθος follow_request: - action: Διαχειρίσου τα αιτήματα παρακολούθησης + action: Διαχειρίσου τα αιτήματα ακολούθησης body: "%{name} αιτήθηκε να σε ακολουθήσει" subject: 'Ακόλουθος που εκκρεμεί: %{name}' title: Νέο αίτημα ακολούθησης mention: action: Απάντησε - body: 'Αναφέρθηκες από τον/την %{name} στο:' - subject: Αναφέρθηκες από τον/την %{name} - title: Νέα αναφορά + body: 'Επισημάνθηκες από τον/την %{name} στο:' + subject: Επισημάνθηκες από τον/την %{name} + title: Νέα επισήμανση + poll: + subject: Μια δημοσκόπηση του %{name} έληξε reblog: - body: 'Η κατάστασή σου προωθήθηκε από τον/την %{name}:' - subject: Ο/Η %{name} προώθησε την κατάστασή σου - title: Νέα προώθηση + body: 'Η ανάρτησή σου ενισχύθηκε από τον/την %{name}:' + subject: Ο/Η %{name} ενίσχυσε την ανάρτηση σου + title: Νέα ενίσχυση status: - subject: Ο/Η %{name} μόλις έγραψε κάτι + subject: Ο/Η %{name} μόλις ανέρτησε κάτι update: - subject: "%{name} επεξεργάστηκε μια δημοσίευση" + subject: "%{name} επεξεργάστηκε μια ανάρτηση" notifications: email_events: Συμβάντα για ειδοποιήσεις μέσω email email_events_hint: 'Επέλεξε συμβάντα για τα οποία θέλεις να λαμβάνεις ειδοποιήσεις μέσω email:' @@ -924,15 +1373,19 @@ el: decimal_units: format: "%n%u" units: - billion: δις. - million: εκ. - quadrillion: τετράκις. - thousand: χ. - trillion: τρις. + billion: Δις + million: Εκ + quadrillion: Τετρ + thousand: Χιλ + trillion: Τρις otp_authentication: code_hint: Για να συνεχίσεις, γράψε τον κωδικό που δημιούργησε η εφαρμογή πιστοποίησης + description_html: Αν ενεργοποιήσεις την ταυτοποίηση δύο παραγόντων χρησιμοποιώντας εφαρμογή ταυτοποίησης, για να συνδεθείς θα πρέπει να έχεις το τηλέφωνό σου, που θα σού δημιουργήσει κλειδιά εισόδου. enable: Ενεργοποίηση + instructions_html: "Σάρωσε αυτόν τον κωδικό QR με την εφαρμογή Google Authenticator ή κάποια άλλη αντίστοιχη στο τηλέφωνό σου. Από εδώ και στο εξής, η εφαρμογή θα δημιουργεί κλειδιά που θα πρέπει να εισάγεις όταν συνδέεσαι." + manual_instructions: 'Αν δεν μπορείς να σαρώσεις τον κωδικό QR και χρειάζεσαι να τον εισάγεις χειροκίνητα, ορίστε η μυστική φράση σε μορφή κειμένου:' setup: Ρύθμιση + wrong_code: Ο κωδικός που έβαλες ήταν άκυρος! Είναι σωστή ώρα στον διακομιστή και τη συσκευή; pagination: newer: Νεότερο next: Επόμενο @@ -941,40 +1394,45 @@ el: truncate: "…" polls: errors: - already_voted: Έχεις ήδη ψηφίσει σε αυτή την ψηφοφορία - duplicate_options: περιέχει επαναλαμβανόμενες επιλογές + already_voted: Έχετε ήδη ψηφίσει σε αυτή τη δημοσκόπηση + duplicate_options: περιέχει διπλότυπα αντικείμενα duration_too_long: είναι πολύ μακριά στο μέλλον duration_too_short: είναι πολύ σύντομα - expired: Η ψηφοφορία έχει ήδη λήξει + expired: Η δημοσκόπηση έχει ήδη λήξει invalid_choice: Αυτή η επιλογή ψήφου δεν υπάρχει over_character_limit: δε μπορεί να υπερβαίνει τους %{max} χαρακτήρες έκαστη too_few_options: πρέπει να έχει περισσότερες από μια επιλογές too_many_options: δεν μπορεί να έχει περισσότερες από %{max} επιλογές preferences: other: Άλλες - posting_defaults: Προεπιλογές δημοσίευσης + posting_defaults: Προεπιλογές ανάρτησης public_timelines: Δημόσιες ροές privacy_policy: title: Πολιτική Απορρήτου reactions: errors: limit_reached: Το όριο διαφορετικών αντιδράσεων ξεπεράστηκε - unrecognized_emoji: δεν αναγνωρίζεται ως emoji + unrecognized_emoji: δεν είναι ένα αναγνωρισμένο emoji relationships: activity: Δραστηριότητα λογαριασμού + confirm_follow_selected_followers: Είσαι βέβαιος ότι θες να ακολουθήσεις τους επιλεγμένους ακόλουθους; + confirm_remove_selected_followers: Είσαι βέβαιος ότι θες να αφαιρέσεις τους επιλεγμένους ακόλουθους; + confirm_remove_selected_follows: Είσαι βέβαιος ότι θες να αφαιρέσεις τα επιλεγμένα άτομα που ακολουθείς; dormant: Αδρανείς - followers: Σε ακολουθούν + follow_failure: Δεν ήταν δυνατή η παρακολούθηση ορισμένων από τους επιλεγμένους λογαριασμούς. + follow_selected_followers: Ακολούθησε τους επιλεγμένους ακόλουθους + followers: Ακόλουθοι following: Ακολουθείς invited: Προσκεκλημένοι - last_active: Τελευταία δραστηριότητα - most_recent: Πιο πρόσφατα + last_active: Τελευταία ενεργός + most_recent: Πιο πρόσφατος moved: Μετακόμισε mutual: Αμοιβαίοι primary: Βασικός relationship: Σχέση - remove_selected_domains: Αφαίρεση ακόλουθων που βρίσκονται στους επιλεγμένους κόμβους - remove_selected_followers: Αφαίρεση επιλεγμένων ακόλουθων - remove_selected_follows: Διακοπή παρακολούθησης επιλεγμένων χρηστών + remove_selected_domains: Αφαίρεση ακόλουθων που βρίσκονται από τους επιλεγμένους τομείς + remove_selected_followers: Αφαίρεση επιλεγμένων ακολούθων + remove_selected_follows: Άρση ακολούθησης επιλεγμένων χρηστών status: Κατάσταση λογαριασμού remote_follow: missing_resource: Δεν βρέθηκε το απαιτούμενο URL ανακατεύθυνσης για το λογαριασμό σου @@ -983,41 +1441,58 @@ el: invalid_rules: δεν παραπέμπει σε έγκυρους κανόνες rss: content_warning: 'Προειδοποίηση περιεχομένου:' + descriptions: + account: Δημόσιες αναρτήσεις από @%{acct} + tag: 'Δημόσιες αναρτήσεις με ετικέτα #%{hashtag}' scheduled_statuses: - over_daily_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων τουτ για εκείνη τη μέρα - over_total_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων τουτ + over_daily_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων αναρτήσεων για εκείνη τη μέρα + over_total_limit: Έχεις υπερβεί το όριο των %{limit} προγραμματισμένων αναρτήσεων too_soon: Η προγραμματισμένη ημερομηνία πρέπει να είναι στο μέλλον sessions: activity: Τελευταία δραστηριότητα - browser: Φυλλομετρητής (Browser) + browser: Φυλλομετρητής browsers: + alipay: Alipay blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge + electron: Electron firefox: Firefox generic: Άγνωστος φυλλομετρητής + huawei_browser: Huawei Browser ie: Internet Explorer + micro_messenger: MicroMessenger + nokia: Nokia S40 Ovi Browser opera: Opera otter: Otter phantom_js: PhantomJS qq: QQ Browser safari: Safari uc_browser: UC Browser - current_session: Τρέχουσα σύνδεση + unknown_browser: Άγνωστος φυλλομετρητής + weibo: Weibo + current_session: Τρέχουσα συνεδρία description: "%{browser} σε %{platform}" - explanation: Αυτοί είναι οι φυλλομετρητές (browsers) που είναι συνδεδεμένοι στον λογαριασμό σου στο Mastodon αυτή τη στιγμή. + explanation: Αυτοί είναι οι φυλλομετρητές που είναι συνδεδεμένοι στον λογαριασμό σου στο Mastodon αυτή τη στιγμή. + ip: IP platforms: + adobe_air: Adobe Air android: Android blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux - mac: Mac - other: άγνωστη πλατφόρμα - revoke: Ανακάλεσε + mac: macOS + unknown_platform: Άγνωστη Πλατφόρμα + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone + revoke: Ανάκληση revoke_success: Η σύνδεση ανακλήθηκε επιτυχώς - title: Σύνδεση + title: Συνεδρίες + view_authentication_history: Δες το ιστορικό ταυτοποιήσεων του λογαριασμού σου settings: account: Λογαριασμός account_settings: Ρυθμίσεις λογαριασμού @@ -1029,20 +1504,23 @@ el: development: Ανάπτυξη edit_profile: Επεξεργασία προφίλ export: Εξαγωγή δεδομένων - featured_tags: Χαρακτηριστικές ετικέτες + featured_tags: Παρεχόμενες ετικέτες import: Εισαγωγή - import_and_export: Εισαγωγή & Εξαγωγή + import_and_export: Εισαγωγή και εξαγωγή migrate: Μετακόμιση λογαριασμού notifications: Ειδοποιήσεις preferences: Προτιμήσεις profile: Προφίλ relationships: Ακολουθείς και σε ακολουθούν - two_factor_authentication: Πιστοποίηση 2 παραγόντων (2FA) + statuses_cleanup: Αυτοματοποιημένη διαγραφή αναρτήσεων + strikes: Παραπτώματα από ομάδα συντονισμού + two_factor_authentication: Πιστοποίηση 2 παραγόντων + webauthn_authentication: Κλειδιά ασφαλείας statuses: attached: audio: - one: "%{count} ηχητικό" - other: "%{count} ηχητικό" + one: "%{count} ήχος" + other: "%{count} ήχος" description: 'Συνημμένα: %{attached}' image: one: "%{count} εικόνα" @@ -1050,7 +1528,7 @@ el: video: one: "%{count} βίντεο" other: "%{count} βίντεο" - boosted_from_html: Προωθήθηκε από %{acct_link} + boosted_from_html: Ενισχύθηκε από %{acct_link} content_warning: 'Προειδοποίηση περιεχομένου: %{warning}' default_language: Ίδια με γλώσσα διεπαφής disallowed_hashtags: @@ -1058,14 +1536,14 @@ el: other: περιέχει μη επιτρεπτές ετικέτες %{tags} edited_at_html: Επεξεργάστηκε στις %{date} errors: - in_reply_not_found: Η κατάσταση στην οποία προσπαθείτε να απαντήσετε δεν υπάρχει. - open_in_web: Δες στο διαδίκτυο + in_reply_not_found: Η ανάρτηση στην οποία προσπαθείς να απαντήσεις δεν φαίνεται να υπάρχει. + open_in_web: Άνοιγμα στο διαδίκτυο over_character_limit: υπέρβαση μέγιστου ορίου %{max} χαρακτήρων pin_errors: direct: Αναρτήσεις που είναι ορατές μόνο στους αναφερόμενους χρήστες δεν μπορούν να καρφιτσωθούν - limit: Έχεις ήδη καρφιτσώσει το μέγιστο αριθμό επιτρεπτών τουτ - ownership: Δεν μπορείς να καρφιτσώσεις τουτ κάποιου άλλου - reblog: Οι προωθήσεις δεν καρφιτσώνονται + limit: Έχεις ήδη καρφιτσώσει το μέγιστο αριθμό επιτρεπτών αναρτήσεων + ownership: Δεν μπορείς να καρφιτσώσεις ανάρτηση κάποιου άλλου + reblog: Οι ενισχύσεις δεν καρφιτσώνονται poll: total_people: one: "%{count} άτομο" @@ -1078,15 +1556,36 @@ el: show_newer: Εμφάνιση νεότερων show_older: Εμφάνιση παλαιότερων show_thread: Εμφάνιση νήματος - sign_in_to_participate: Συνδέσου για να συμμετάσχεις στη συζήτηση + title: '%{name}: "%{quote}"' visibilities: + direct: Άμεση private: Μόνο ακόλουθοι private_long: Εμφάνιση μόνο σε ακόλουθους public: Δημόσιο - public_long: Βλέπει οποιοσδήποτε + public_long: Βλέπει ο οποιοσδήποτε unlisted: Μη καταχωρημένο - unlisted_long: Βλέπει οποιοσδήποτε, αλλά δεν καταχωρείται στις δημόσιες ροές + unlisted_long: Βλέπει ο οποιοσδήποτε, αλλά δεν καταχωρείται στις δημόσιες ροές statuses_cleanup: + enabled: Αυτόματη διαγραφή παλιών αναρτήσεων + enabled_hint: Διαγράφει αυτόματα τις αναρτήσεις σου μόλις φτάσουν σε ένα καθορισμένο όριο ηλικίας, εκτός αν ταιριάζουν με μία από τις παρακάτω εξαιρέσεις + exceptions: Εξαιρέσεις + explanation: Επειδή η διαγραφή αναρτήσεων είναι μια κοστοβόρα διαδικασία, γίνεται σε αραιά τακτά διαστήματα, όταν ο διακομιστής δεν είναι ιδιαίτερα απασχολημένος. Γι' αυτό, οι αναρτήσεις σου μπορεί να διαγραφούν λίγο μετά το πέρας του ορίου ηλικίας. + ignore_favs: Αγνόηση αγαπημένων + ignore_reblogs: Αγνόηση ενισχύσεων + interaction_exceptions: Εξαιρέσεις βασισμένες σε αλληλεπιδράσεις + interaction_exceptions_explanation: Σημείωσε ότι δεν υπάρχει εγγύηση για πιθανή διαγραφή αναρτήσεων αν αυτά πέσουν κάτω από το όριο αγαπημένων ή ενισχύσεων ακόμα και αν κάποτε το είχαν ξεπεράσει. + keep_direct: Διατήρηση άμεσων μηνυμάτων + keep_direct_hint: Δεν διαγράφει κανένα από τα άμεσα μηνύματά σου + keep_media: Διατήρηση αναρτήσεων με συνημμένα πολυμέσων + keep_media_hint: Δεν διαγράφει καμία από τις αναρτήσεις σου που έχουν συνημμένα πολυμέσων + keep_pinned: Διατήρηση καρφιτσωμένων αναρτήσεων + keep_pinned_hint: Δεν διαγράφει καμία από τις καρφιτσωμένες αναρτήσεις σου + keep_polls: Διατήρηση δημοσκοπήσεων + keep_polls_hint: Δεν διαγράφει καμία από τις δημοσκοπήσεις σου + keep_self_bookmark: Διατήρηση αναρτήσεων που έχετε βάλει σελιδοδείκτη + keep_self_bookmark_hint: Δεν διαγράφει τις αναρτήσεις σου αν τις έχεις προσθέσει στους σελιδοδείκτες + keep_self_fav: Κράτα τις αναρτήσεις που έχεις στα αγαπημένα + keep_self_fav_hint: Δεν διαγράφει τις αναρτήσεις σου αν τις έχεις στα αγαπημένα min_age: '1209600': 2 εβδομάδες '15778476': 6 μήνες @@ -1096,10 +1595,16 @@ el: '604800': 1 εβδομάδα '63113904': 2 χρόνια '7889238': 3 μήνες + min_age_label: Όριο ηλικίας + min_favs: Κράτα τις αναρτήσεις που έχουν γίνει αγαπημένες τουλάχιστον + min_favs_hint: Δεν διαγράφει καμία από τις αναρτήσεις σου που έχει λάβει τουλάχιστον αυτόν τον αριθμό αγαπημένων. Άσε κενό για να διαγράψεις αναρτήσεις ανεξάρτητα από τον αριθμό των αγαπημένων + min_reblogs: Διατήρηση αναρτήσεων που έχουν ενισχυθεί τουλάχιστον + min_reblogs_hint: Δεν διαγράφει καμία από τις δημοσιεύσεις σας που έχει λάβει τουλάχιστον αυτόν τον αριθμό ενισχύσεων. Αφήστε κενό για να διαγράψετε δημοσιεύσεις ανεξάρτητα από τον αριθμό των ενισχύσεων stream_entries: - pinned: Καρφιτσωμένο τουτ - reblogged: προωθημένο sensitive_content: Ευαίσθητο περιεχόμενο + strikes: + errors: + too_late: Είναι πολύ αργά για να κάνεις έφεση σε αυτό το παράπτωμα tags: does_not_match_previous_name: δεν ταιριάζει με το προηγούμενο όνομα themes: @@ -1108,64 +1613,109 @@ el: mastodon-light: Mastodon (Ανοιχτόχρωμο) time: formats: + default: "%b %d, %Y, %H:%M" + month: "%b %Y" time: "%H:%M" two_factor_authentication: add: Προσθήκη - disable: Απενεργοποίησε + disable: Απενεργοποίηση 2FA + disabled_success: Η ταυτοποίηση δύο παραγόντων απενεργοποιήθηκε επιτυχώς edit: Επεξεργασία - enabled: Η πιστοποίηση 2 παραγόντων (2FA) είναι ενεργοποιημένη - enabled_success: Η πιστοποίηση 2 παραγόντων (2FA) ενεργοποιήθηκε επιτυχώς - generate_recovery_codes: Δημιούργησε κωδικούς ανάκτησης - lost_recovery_codes: Οι κωδικοί ανάκτησης σου επιτρέπουν να ανακτήσεις ξανά πρόσβαση στον λογαριασμό σου αν χάσεις το τηλέφωνό σου. Αν έχεις χάσει τους κωδικούς ανάκτησης, μπορείς να τους δημιουργήσεις ξανά εδώ. Οι παλιοί κωδικοί σου θα ακυρωθούν. + enabled: Η πιστοποίηση 2 παραγόντων είναι ενεργοποιημένη + enabled_success: Η πιστοποίηση 2 παραγόντων ενεργοποιήθηκε επιτυχώς + generate_recovery_codes: Γέννησε κωδικούς ανάκτησης + lost_recovery_codes: Οι κωδικοί ανάκτησης σού επιτρέπουν να ανακτήσεις ξανά πρόσβαση στον λογαριασμό σου αν χάσεις το τηλέφωνό σου. Αν έχεις χάσει τους κωδικούς ανάκτησης, μπορείς να τους δημιουργήσεις ξανά εδώ. Οι παλιοί κωδικοί σου θα ακυρωθούν. + methods: Μέθοδοι δύο παραγόντων otp: Εφαρμογή επαλήθευσης recovery_codes: Εφεδρικοί κωδικοί ανάκτησης recovery_codes_regenerated: Οι εφεδρικοί κωδικοί ανάκτησης δημιουργήθηκαν επιτυχώς recovery_instructions_html: Αν ποτέ δεν έχεις πρόσβαση στο κινητό σου, μπορείς να χρησιμοποιήσεις έναν από τους παρακάτω κωδικούς ανάκτησης για να αποκτήσεις πρόσβαση στο λογαριασμό σου. Διαφύλαξε τους κωδικούς ανάκτησης. Για παράδειγμα, μπορείς να τους εκτυπώσεις και να τους φυλάξεις μαζί με άλλα σημαντικά σου έγγραφα. + webauthn: Κλειδιά ασφαλείας user_mailer: + appeal_approved: + action: Μετάβαση στον λογαριασμό σου + explanation: Η έφεση του παραπτώματος εναντίον του λογαριασμού σου στις %{strike_date}, που υπέβαλες στις %{appeal_date} έχει εγκριθεί. Ο λογαριασμός σου είναι και πάλι σε καλή κατάσταση. + subject: Η έφεση σου από τις %{date} έχει εγκριθεί + title: Έφεση εγκρίθηκε + appeal_rejected: + explanation: Η έφεση του παραπτώματος εναντίον του λογαριασμού σου στις %{strike_date}, που υπέβαλες στις %{appeal_date} έχει απορριφθεί. + subject: Η έφεση σου από τις %{date} έχει απορριφθεί + title: Έφεση απορρίφθηκε backup_ready: - explanation: Είχες ζητήσει εφεδρικό αντίγραφο του λογαριασμού σου στο Mastodon. Είναι έτοιμο για κατέβασμα! - subject: Το εφεδρικό αντίγραφό σου είναι έτοιμο για κατέβασμα + explanation: Είχες ζητήσει εφεδρικό αντίγραφο του λογαριασμού σου στο Mastodon. Είναι έτοιμο για λήψη! + subject: Το αρχείο σου είναι έτοιμο για λήψη title: Λήψη εφεδρικού αρχείου suspicious_sign_in: - change_password: αλλάξτε τον κωδικό πρόσβασής σας + change_password: άλλαξε τον κωδικό πρόσβασής σου + details: 'Εδώ είναι οι λεπτομέρειες της σύνδεσης:' + explanation: Εντοπίσαμε μια σύνδεση στο λογαριασμό σου από μια νέα διεύθυνση IP. + further_actions_html: Αν δεν ήσουν εσύ, σας συνιστούμε να %{action} αμέσως και να ενεργοποιήσεις τον έλεγχο ταυτοποίησης δύο παραγόντων για να διατηρήσεις τον λογαριασμό σου ασφαλή. + subject: Ο λογαριασμός σου έχει συνδεθεί από μια νέα διεύθυνση IP + title: Μια νέα σύνδεση warning: + appeal: Υποβολή έφεσης + appeal_description: Αν πιστεύεις ότι έγινε λάθος, μπορείς να υποβάλεις μια αίτηση στο προσωπικό του %{instance}. categories: spam: Ανεπιθύμητο + violation: Το περιεχόμενο παραβιάζει τις ακόλουθες οδηγίες κοινότητας + explanation: + delete_statuses: Μερικές από τις αναρτήσεις σου έχουν βρεθεί να παραβιάζουν μία ή περισσότερες οδηγίες κοινότητας και έχουν συνεπώς αφαιρεθεί από τους συντονιστές του %{instance}. + disable: Δεν μπορείς πλέον να χρησιμοποιήσεις τον λογαριασμό σου, αλλά το προφίλ σου και άλλα δεδομένα παραμένουν άθικτα. Μπορείς να ζητήσεις ένα αντίγραφο ασφαλείας των δεδομένων σου, να αλλάξεις τις ρυθμίσεις του λογαριασμού σου ή να διαγράψεις τον λογαριασμό σου. + mark_statuses_as_sensitive: Μερικές από τις αναρτήσεις σου έχουν επισημανθεί ως ευαίσθητες από τους συντονιστές του %{instance}. Αυτό σημαίνει ότι οι άνθρωποι θα πρέπει να πατήσουν τα πολυμέσα στις αναρτήσεις πριν εμφανιστεί μια προεπισκόπηση. Μπορείς να επισημάνεις τα πολυμέσα ως ευαίσθητα όταν δημοσιεύεις στο μέλλον. + sensitive: Από δω και στο εξής, όλα τα μεταφορτωμένα αρχεία πολυμέσων σου θα επισημανθούν ως ευαίσθητα και κρυμμένα πίσω από μια προειδοποίηση -πατήστε για εμφάνιση. + silence: Μπορείς ακόμα να χρησιμοποιείς τον λογαριασμό σου, αλλά μόνο άτομα που σε ακολουθούν ήδη θα δουν τις αναρτήσεις σου σε αυτόν τον διακομιστή και μπορεί να αποκλειστείς από διάφορες δυνατότητες ανακάλυψης. Ωστόσο, οι άλλοι μπορούν ακόμα να σε ακολουθήσουν με μη αυτόματο τρόπο. + suspend: Δε μπορείς πλέον να χρησιμοποιήσεις τον λογαριασμό σου και το προφίλ σου και άλλα δεδομένα δεν είναι πλέον προσβάσιμα. Μπορείς ακόμα να συνδεθείς για να αιτηθείς αντίγραφο των δεδομένων σου μέχρι να αφαιρεθούν πλήρως σε περίπου 30 μέρες αλλά, θα διατηρήσουμε κάποια βασικά δεδομένα για να σε αποτρέψουμε να παρακάμψεις την αναστολή. reason: 'Αιτιολογία:' + statuses: 'Αναφερόμενες αναρτήσεις:' subject: + delete_statuses: Οι αναρτήσεις σου στον %{acct} έχουν αφαιρεθεί disable: Ο λογαριασμός σου %{acct} έχει παγώσει + mark_statuses_as_sensitive: Οι αναρτήσεις σου στον %{acct} έχουν επισημανθεί ως ευαίσθητες none: Προειδοποίηση προς %{acct} + sensitive: Οι αναρτήσεις σου στο %{acct} θα επισημαίνονται ως ευαίσθητες από 'δω και στο εξής silence: Ο λογαριασμός σου %{acct} έχει περιοριστεί suspend: Ο λογαριασμός σου %{acct} έχει ανασταλεί title: + delete_statuses: Οι αναρτήσεις αφαιρέθηκαν disable: Παγωμένος λογαριασμός + mark_statuses_as_sensitive: Οι αναρτήσεις επισημάνθηκαν ως ευαίσθητες none: Προειδοποίηση + sensitive: Ο λογαριασμός επισημάνθηκε ως ευαίσθητος silence: Περιορισμένος λογαριασμός suspend: Λογαριασμός σε αναστολή welcome: edit_profile_action: Στήσιμο προφίλ + edit_profile_step: Μπορείς να προσαρμόσεις το προφίλ σου ανεβάζοντας μια εικόνα προφίλ, αλλάζοντας το εμφνιζόμενο όνομα και άλλα. Μπορείς να επιλέξεις να αξιολογείς νέους ακόλουθους πριν τους επιτραπεί να σε ακολουθήσουν. explanation: Μερικές συμβουλές για να ξεκινήσεις - final_action: Ξεκίνα τις δημοσιεύσεις + final_action: Ξεκίνα να αναρτάς + final_step: 'Ξεκίνα να δημοσιεύεις! Ακόμα και χωρίς ακόλουθους τις δημόσιες δημοσιεύσεις σου μπορεί να τις δουν άλλοι, για παράδειγμα στην τοπική ροή ή στις ετικέτες. Ίσως να θέλεις να μας γνωρίσεις τον εαυτό σου με την ετικέτα #introductions.' full_handle: Το πλήρες όνομά σου - full_handle_hint: Αυτό θα εδώ θα πεις στους φίλους σου για να σου μιλήσουν ή να σε ακολουθήσουν από άλλο κόμβο. + full_handle_hint: Αυτό θα εδώ θα πεις στους φίλους σου για να σου μιλήσουν ή να σε ακολουθήσουν από άλλο διακομιστή. subject: Καλώς ήρθες στο Mastodon title: Καλώς όρισες, %{name}! users: follow_limit_reached: Δεν μπορείς να ακολουθήσεις περισσότερα από %{limit} άτομα - invalid_otp_token: Άκυρος κωδικός πιστοποίησης 2 παραγόντων (2FA) - otp_lost_help_html: Αν χάσεις και τα δύο, μπορείς να επικοινωνήσεις με τον/την %{email} + go_to_sso_account_settings: Πήγαινε στις ρυθμίσεις λογαριασμού του παρόχου ταυτότητας σου + invalid_otp_token: Άκυρος κωδικός πιστοποίησης 2 παραγόντων + otp_lost_help_html: Αν χάσεις πρόσβαση και στα δύο, μπορείς να επικοινωνήσεις με %{email} seamless_external_login: Επειδή έχεις συνδεθεί μέσω τρίτης υπηρεσίας, οι ρυθμίσεις συνθηματικού και email δεν είναι διαθέσιμες. signed_in_as: 'Έχεις συνδεθεί ως:' verification: - explanation_html: 'Μπορείς να πιστοποιήσεις τον εαυτό σου ως ιδιοκτήτη των συνδέσμων που εμφανίζεις στα μεταδεδομένα του προφίλ σου. Για να συμβεί αυτό, ο συνδεδεμένος ιστότοπος πρέπει να περιέχει ένα σύνδεσμο που να επιστρέφει προς το προφίλ σου στο Mastodon. Ο σύνδεσμος επιστροφής πρέπει περιέχει την ιδιότητα (attribute) rel="me". Το περιεχόμενο του κειμένου δεν έχει σημασία. Για παράδειγμα:' verification: Πιστοποίηση webauthn_credentials: add: Προσθήκη νέου κλειδιού ασφαλείας create: - success: Το κλειδί ασφαλείας σας προστέθηκε με επιτυχία. + error: Παρουσιάστηκε πρόβλημα κατά την προσθήκη του κλειδιού ασφαλείας. Παρακαλώ δοκίμασε ξανά. + success: Το κλειδί ασφαλείας σου προστέθηκε με επιτυχία. delete: Διαγραφή - delete_confirmation: Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το κλειδί ασφαλείας; + delete_confirmation: Είσαι βέβαιος ότι θες να διαγράψεις αυτό το κλειδί ασφαλείας; + description_html: Αν ενεργοποιήσεις την ταυτοποίηση κλειδιού ασφαλείας, κατά τη σύνδεσή σου θα χρειαστεί να χρησιμοποιήσεις ένα από τα κλειδιά ασφαλείας σου. destroy: - success: Το κλειδί ασφαλείας σας διαγράφηκε με επιτυχία. + error: Παρουσιάστηκε πρόβλημα κατά την διαγραφή του κλειδιού ασφαλείας. Παρακαλώ δοκίμασε ξανά. + success: Το κλειδί ασφαλείας σου διαγράφηκε με επιτυχία. invalid_credential: Άκυρο κλειδί ασφαλείας + nickname_hint: Βάλε το ψευδώνυμο του νέου κλειδιού ασφαλείας σου + not_enabled: Δεν έχεις ενεργοποιήσει το WebAuthn ακόμα + not_supported: Αυτό το πρόγραμμα περιήγησης δεν υποστηρίζει κλειδιά ασφαλείας + otp_required: Για να χρησιμοποιήσεις κλειδιά ασφαλείας, ενεργοποίησε πρώτα την ταυτοποίηση δύο παραγόντων. registered_on: Εγγραφή στις %{date} diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 17fea72274..98a40c45cf 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -91,6 +91,7 @@ en-GB: moderation: active: Active all: All + disabled: Disabled pending: Pending silenced: Limited suspended: Suspended @@ -124,8 +125,8 @@ en-GB: removed_header_msg: Successfully removed %{username}'s header image resend_confirmation: already_confirmed: This user is already confirmed - send: Resend confirmation email - success: Confirmation email successfully sent! + send: Resend confirmation link + success: Confirmation link successfully sent! reset: Reset reset_password: Reset password resubscribe: Resubscribe @@ -133,6 +134,7 @@ en-GB: search: Search search_same_email_domain: Other users with the same e-mail domain search_same_ip: Other users with the same IP + security: Security security_measures: only_password: Only password password_and_2fa: Password and 2FA @@ -226,27 +228,1532 @@ en-GB: update_ip_block: Update IP rule update_status: Update Post update_user_role: Update Role + actions: + approve_appeal_html: "%{name} approved moderation decision appeal from %{target}" + approve_user_html: "%{name} approved sign-up from %{target}" + assigned_to_self_report_html: "%{name} assigned report %{target} to themselves" + change_email_user_html: "%{name} changed the e-mail address of user %{target}" + change_role_user_html: "%{name} changed role of %{target}" + confirm_user_html: "%{name} confirmed e-mail address of user %{target}" + create_account_warning_html: "%{name} sent a warning to %{target}" + create_announcement_html: "%{name} created new announcement %{target}" + create_canonical_email_block_html: "%{name} blocked e-mail with the hash %{target}" + create_custom_emoji_html: "%{name} uploaded new emoji %{target}" + create_domain_allow_html: "%{name} allowed federation with domain %{target}" + create_domain_block_html: "%{name} blocked domain %{target}" + create_email_domain_block_html: "%{name} blocked e-mail domain %{target}" + create_ip_block_html: "%{name} created rule for IP %{target}" + create_unavailable_domain_html: "%{name} stopped delivery to domain %{target}" + create_user_role_html: "%{name} created %{target} role" + demote_user_html: "%{name} demoted user %{target}" + destroy_announcement_html: "%{name} deleted announcement %{target}" + destroy_canonical_email_block_html: "%{name} unblocked e-mail with the hash %{target}" + destroy_custom_emoji_html: "%{name} deleted emoji %{target}" + destroy_domain_allow_html: "%{name} disallowed federation with domain %{target}" + destroy_domain_block_html: "%{name} unblocked domain %{target}" + destroy_email_domain_block_html: "%{name} unblocked e-mail domain %{target}" + destroy_instance_html: "%{name} purged domain %{target}" + destroy_ip_block_html: "%{name} deleted rule for IP %{target}" + destroy_status_html: "%{name} removed post by %{target}" + destroy_unavailable_domain_html: "%{name} stopped delivery to domain %{target}" + destroy_user_role_html: "%{name} deleted %{target} role" + disable_2fa_user_html: "%{name} disabled two factor requirement for user %{target}" + disable_custom_emoji_html: "%{name} disabled emoji %{target}" + disable_sign_in_token_auth_user_html: "%{name} disabled e-mail token authentication for %{target}" + disable_user_html: "%{name} disabled login for user %{target}" + enable_custom_emoji_html: "%{name} enabled emoji %{target}" + enable_sign_in_token_auth_user_html: "%{name} enabled e-mail token authentication for %{target}" + enable_user_html: "%{name} enabled login for user %{target}" + memorialize_account_html: "%{name} turned %{target}'s account into a memoriam page" + promote_user_html: "%{name} promoted user %{target}" + reject_appeal_html: "%{name} rejected moderation decision appeal from %{target}" + reject_user_html: "%{name} rejected sign-up from %{target}" + remove_avatar_user_html: "%{name} removed %{target}'s avatar" + reopen_report_html: "%{name} reopened report %{target}" + resend_user_html: "%{name} resent confirmation e-mail for %{target}" + reset_password_user_html: "%{name} reset password of user %{target}" + resolve_report_html: "%{name} resolved report %{target}" + sensitive_account_html: "%{name} marked %{target}'s media as sensitive" + silence_account_html: "%{name} limited %{target}'s account" + suspend_account_html: "%{name} suspended %{target}'s account" + unassigned_report_html: "%{name} unassigned report %{target}" + unblock_email_account_html: "%{name} unblocked %{target}'s email address" + unsensitive_account_html: "%{name} unmarked %{target}'s media as sensitive" + unsilence_account_html: "%{name} undid limit of %{target}'s account" + unsuspend_account_html: "%{name} unsuspended %{target}'s account" + update_announcement_html: "%{name} updated announcement %{target}" + update_custom_emoji_html: "%{name} updated emoji %{target}" + update_domain_block_html: "%{name} updated domain block for %{target}" + update_ip_block_html: "%{name} changed rule for IP %{target}" + update_status_html: "%{name} updated post by %{target}" + update_user_role_html: "%{name} changed %{target} role" + deleted_account: deleted account + empty: No logs found. + filter_by_action: Filter by action + filter_by_user: Filter by user + title: Audit log + announcements: + destroyed_msg: Announcement successfully deleted! + edit: + title: Edit announcement + empty: No announcements found. + live: Live + new: + create: Create announcement + title: New announcement + publish: Publish + published_msg: Announcement successfully published! + scheduled_for: Scheduled for %{time} + scheduled_msg: Announcement scheduled for publication! + title: Announcements + unpublish: Unpublish + unpublished_msg: Announcement successfully unpublished! + updated_msg: Announcement successfully updated! + critical_update_pending: Critical update pending + custom_emojis: + assign_category: Assign category + by_domain: Domain + copied_msg: Successfully created local copy of the emoji + copy: Copy + copy_failed_msg: Could not make a local copy of that emoji + create_new_category: Create new category + created_msg: Emoji successfully created! + delete: Delete + destroyed_msg: Emojo successfully destroyed! + disable: Disable + disabled: Disabled + disabled_msg: Successfully disabled that emoji + emoji: Emoji + enable: Enable + enabled: Enabled + enabled_msg: Successfully enabled that emoji + image_hint: PNG or GIF up to %{size} + list: List + listed: Listed + new: + title: Add new custom emoji + no_emoji_selected: No emojis were changed as none were selected + not_permitted: You are not permitted to perform this action + overwrite: Overwrite + shortcode: Shortcode + shortcode_hint: At least 2 characters, only alphanumeric characters and underscores + title: Custom emojis + uncategorized: Uncategorised + unlist: Unlist + unlisted: Unlisted + update_failed_msg: Could not update that emoji + updated_msg: Emoji successfully updated! + upload: Upload + dashboard: + active_users: active users + interactions: interactions + media_storage: Media storage + new_users: new users + opened_reports: reports opened + pending_appeals_html: + one: "%{count} pending appeal" + other: "%{count} pending appeals" + pending_reports_html: + one: "%{count} pending report" + other: "%{count} pending reports" + pending_tags_html: + one: "%{count} pending hashtag" + other: "%{count} pending hashtags" + pending_users_html: + one: "%{count} pending user" + other: "%{count} pending users" + resolved_reports: reports resolved + software: Software + sources: Sign-up sources + space: Space usage + title: Dashboard + top_languages: Top active languages + top_servers: Top active servers + website: Website + disputes: + appeals: + empty: No appeals found. + title: Appeals + domain_allows: + add_new: Allow federation with domain + created_msg: Domain has been successfully allowed for federation + destroyed_msg: Domain has been disallowed from federation + export: Export + import: Import + undo: Disallow federation with domain + domain_blocks: + add_new: Add new domain block + confirm_suspension: + cancel: Cancel + confirm: Suspend + permanent_action: Undoing the suspension will not restore any data or relationship. + preamble_html: You are about to suspend %{domain} and its subdomains. + remove_all_data: This will remove all content, media, and profile data for this domain's accounts from your server. + stop_communication: Your server will stop communicating with these servers. + title: Confirm domain block for %{domain} + undo_relationships: This will undo any follow relationship between accounts of these servers and yours. + created_msg: Domain block is now being processed + destroyed_msg: Domain block has been undone + domain: Domain + edit: Edit domain block + existing_domain_block: You have already imposed stricter limits on %{name}. + existing_domain_block_html: You have already imposed stricter limits on %{name}, you need to unblock it first. + export: Export + import: Import + new: + create: Create block + hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts. + severity: + desc_html: "Limit will make posts from accounts at this domain invisible to anyone who isn't following them. Suspend will remove all content, media, and profile data for this domain's accounts from your server. Use None if you just want to reject media files." + noop: None + silence: Limit + suspend: Suspend + title: New domain block + no_domain_block_selected: No domain blocks were changed as none were selected + not_permitted: You are not permitted to perform this action + obfuscate: Obfuscate domain name + obfuscate_hint: Partially obfuscate the domain name in the list if advertising the list of domain limitations is enabled + private_comment: Private comment + private_comment_hint: Comment about this domain limitation for internal use by the moderators. + public_comment: Public comment + public_comment_hint: Comment about this domain limitation for the general public, if advertising the list of domain limitations is enabled. + reject_media: Reject media files + reject_media_hint: Removes locally stored media files and refuses to download any in the future. Irrelevant for suspensions + reject_reports: Reject reports + reject_reports_hint: Ignore all reports coming from this domain. Irrelevant for suspensions + undo: Undo domain block + view: View domain block + email_domain_blocks: + add_new: Add new + attempts_over_week: + one: "%{count} attempt over the last week" + other: "%{count} sign-up attempts over the last week" + created_msg: Successfully blocked e-mail domain + delete: Delete + dns: + types: + mx: MX record + domain: Domain + new: + create: Add domain + resolve: Resolve domain + title: Block new e-mail domain + no_email_domain_block_selected: No e-mail domain blocks were changed as none were selected + not_permitted: Not permitted + resolved_dns_records_hint_html: The domain name resolves to the following MX domains, which are ultimately responsible for accepting e-mail. Blocking an MX domain will block sign-ups from any e-mail address which uses the same MX domain, even if the visible domain name is different. Be careful not to block major e-mail providers. + resolved_through_html: Resolved through %{domain} + title: Blocked e-mail domains + export_domain_allows: + new: + title: Import domain allows + no_file: No file selected + export_domain_blocks: + import: + description_html: You are about to import a list of domain blocks. Please review this list very carefully, especially if you have not authored this list yourself. + existing_relationships_warning: Existing follow relationships + private_comment_description_html: 'To help you track where imported blocks come from, imported blocks will be created with the following private comment: %{comment}' + private_comment_template: Imported from %{source} on %{date} + title: Import domain blocks + invalid_domain_block: 'One or more domain blocks were skipped because of the following error(s): %{error}' + new: + title: Import domain blocks + no_file: No file selected + follow_recommendations: + description_html: "Follow recommendations help new users quickly find interesting content. When a user has not interacted with others enough to form personalised follow recommendations, these accounts are recommended instead. They are re-calculated on a daily basis from a mix of accounts with the highest recent engagements and highest local follower counts for a given language." + language: For language + status: Status + suppress: Suppress follow recommendation + suppressed: Suppressed + title: Follow recommendations + unsuppress: Restore follow recommendation + instances: + availability: + description_html: + one: If delivering to the domain fails %{count} day without succeeding, no further delivery attempts will be made unless a delivery from the domain is received. + other: If delivering to the domain fails on %{count} different days without succeeding, no further delivery attempts will be made unless a delivery from the domain is received. + failure_threshold_reached: Failure threshold reached on %{date}. + failures_recorded: + one: Failed attempt on %{count} day. + other: Failed attempts on %{count} different days. + no_failures_recorded: No failures on record. + title: Availability + warning: The last attempt to connect to this server has been unsuccessful + back_to_all: All + back_to_limited: Limited + back_to_warning: Warning + by_domain: Domain + confirm_purge: Are you sure you want to permanently delete data from this domain? + content_policies: + comment: Internal note + description_html: You can define content policies that will be applied to all accounts from this domain and any of its subdomains. + limited_federation_mode_description_html: You can chose whether to allow federation with this domain. + policies: + reject_media: Reject media + reject_reports: Reject reports + silence: Limit + suspend: Suspend + policy: Policy + reason: Public reason + title: Content policies + dashboard: + instance_accounts_dimension: Most followed accounts + instance_accounts_measure: stored accounts + instance_followers_measure: our followers there + instance_follows_measure: their followers here + instance_languages_dimension: Top languages + instance_media_attachments_measure: stored media attachments + instance_reports_measure: reports about them + instance_statuses_measure: stored posts + delivery: + all: All + clear: Clear delivery errors + failing: Failing + restart: Restart delivery + stop: Stop delivery + unavailable: Unavailable + delivery_available: Delivery is available + delivery_error_days: Delivery error days + delivery_error_hint: If delivery is not possible for %{count} days, it will be automatically marked as undeliverable. + destroyed_msg: Data from %{domain} is now queued for imminent deletion. + empty: No domains found. + known_accounts: + one: "%{count} known account" + other: "%{count} known accounts" + moderation: + all: All + limited: Limited + title: Moderation + private_comment: Private comment + public_comment: Public comment + purge: Purge + purge_description_html: If you believe this domain is offline for good, you can delete all account records and associated data from this domain from your storage. This may take a while. + title: Federation + total_blocked_by_us: Blocked by us + total_followed_by_them: Followed by them + total_followed_by_us: Followed by us + total_reported: Reports about them + total_storage: Media attachments + totals_time_period_hint_html: The totals displayed below include data for all time. + invites: + deactivate_all: Deactivate all + filter: + all: All + available: Available + expired: Expired + title: Filter + title: Invites + ip_blocks: + add_new: Create rule + created_msg: Successfully added new IP rule + delete: Delete + expires_in: + '1209600': 2 weeks + '15778476': 6 months + '2629746': 1 month + '31556952': 1 year + '86400': 1 day + '94670856': 3 years + new: + title: Create new IP rule + no_ip_block_selected: No IP rules were changed as none were selected + title: IP rules + relationships: + title: "%{acct}'s relationships" + relays: + add_new: Add new relay + delete: Delete + description_html: A federation relay is an intermediary server that exchanges large volumes of public posts between servers that subscribe and publish to it. It can help small and medium servers discover content from the fediverse, which would otherwise require local users manually following other people on remote servers. + disable: Disable + disabled: Disabled + enable: Enable + enable_hint: Once enabled, your server will subscribe to all public posts from this relay, and will begin sending this server's public posts to it. + enabled: Enabled + inbox_url: Relay URL + pending: Waiting for relay's approval + save_and_enable: Save and enable + setup: Setup a relay connection + signatures_not_enabled: Relays may not work correctly while secure mode or limited federation mode is enabled + status: Status + title: Relays + report_notes: + created_msg: Report note successfully created! + destroyed_msg: Report note successfully deleted! + reports: + account: + notes: + one: "%{count} note" + other: "%{count} notes" + action_log: Audit log + action_taken_by: Action taken by + actions: + delete_description_html: The reported posts will be deleted and a strike will be recorded to help you escalate on future infractions by the same account. + mark_as_sensitive_description_html: The media in the reported posts will be marked as sensitive and a strike will be recorded to help you escalate on future infractions by the same account. + other_description_html: See more options for controlling the account's behaviour and customise communication to the reported account. + resolve_description_html: No action will be taken against the reported account, no strike recorded, and the report will be closed. + silence_description_html: The account will be visible only to those who already follow it or manually look it up, severely limiting its reach. Can always be reverted. Closes all reports against this account. + suspend_description_html: The account and all its contents will be inaccessible and eventually deleted, and interacting with it will be impossible. Reversible within 30 days. Closes all reports against this account. + actions_description_html: Decide which action to take to resolve this report. If you take a punitive action against the reported account, an e-mail notification will be sent to them, except when the Spam category is selected. + actions_description_remote_html: Decide which action to take to resolve this report. This will only affect how your server communicates with this remote account and handle its content. + add_to_report: Add more to report + are_you_sure: Are you sure? + assign_to_self: Assign to me + assigned: Assigned moderator + by_target_domain: Domain of reported account + cancel: Cancel + category: Category + category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account + comment: + none: None + comment_description_html: 'To provide more information, %{name} wrote:' + confirm: Confirm + confirm_action: Confirm moderation action against @%{acct} + created_at: Reported + delete_and_resolve: Delete posts + forwarded: Forwarded + forwarded_to: Forwarded to %{domain} + mark_as_resolved: Mark as resolved + mark_as_sensitive: Mark as sensitive + mark_as_unresolved: Mark as unresolved + no_one_assigned: No one + notes: + create: Add note + create_and_resolve: Resolve with note + create_and_unresolve: Reopen with note + delete: Delete + placeholder: Describe what actions have been taken, or any other related updates... + title: Notes + notes_description_html: View and leave notes to other moderators and your future self + processed_msg: 'Report #%{id} successfully processed' + quick_actions_description_html: 'Take a quick action or scroll down to see reported content:' + remote_user_placeholder: the remote user from %{instance} + reopen: Reopen report + report: 'Report #%{id}' + reported_account: Reported account + reported_by: Reported by + resolved: Resolved + resolved_msg: Report successfully resolved! + skip_to_actions: Skip to actions + status: Status + statuses: Reported content + statuses_description_html: Offending content will be cited in communication with the reported account + summary: + action_preambles: + delete_html: 'You are about to remove some of @%{acct}''s posts. This will:' + mark_as_sensitive_html: 'You are about to mark some of @%{acct}''s posts as sensitive. This will:' + silence_html: 'You are about to limit @%{acct}''s account. This will:' + suspend_html: 'You are about to suspend @%{acct}''s account. This will:' + actions: + delete_html: Remove the offending posts + mark_as_sensitive_html: Mark the offending posts' media as sensitive + silence_html: Severely limit @%{acct}'s reach by making their profile and contents only visible to people already following them or manually looking it profile up + suspend_html: Suspend @%{acct}, making their profile and contents inaccessible and impossible to interact with + close_report: 'Mark report #%{id} as resolved' + close_reports_html: Mark all reports against @%{acct} as resolved + delete_data_html: Delete @%{acct}'s profile and contents 30 days from now unless they get unsuspended in the meantime + preview_preamble_html: "@%{acct} will receive a warning with the following contents:" + record_strike_html: Record a strike against @%{acct} to help you escalate on future violations from this account + send_email_html: Send @%{acct} a warning e-mail + warning_placeholder: Optional additional reasoning for the moderation action. + target_origin: Origin of reported account + title: Reports + unassign: Unassign + unknown_action_msg: 'Unknown action: %{action}' + unresolved: Unresolved + updated_at: Updated + view_profile: View profile roles: + add_new: Add role + assigned_users: + one: "%{count} user" + other: "%{count} users" categories: + administration: Administration devops: DevOps + invites: Invites + moderation: Moderation + special: Special + delete: Delete + description_html: With user roles, you can customize which functions and areas of Mastodon your users can access. + edit: Edit '%{name}' role + everyone: Default permissions + everyone_full_description_html: This is the base role affecting all users, even those without an assigned role. All other roles inherit permissions from it. + permissions_count: + one: "%{count} permission" + other: "%{count} permissions" privileges: + administrator: Administrator + administrator_description: Users with this permission will bypass every permission + delete_user_data: Delete User Data + delete_user_data_description: Allows users to delete other users' data without delay + invite_users: Invite Users + invite_users_description: Allows users to invite new people to the server + manage_announcements: Manage Announcements + manage_announcements_description: Allows users to manage announcements on the server + manage_appeals: Manage Appeals + manage_appeals_description: Allows users to review appeals against moderation actions + manage_blocks: Manage Blocks + manage_blocks_description: Allows users to block e-mail providers and IP addresses + manage_custom_emojis: Manage Custom Emojis + manage_custom_emojis_description: Allows users to manage custom emojis on the server + manage_federation: Manage Federation + manage_federation_description: Allows users to block or allow federation with other domains, and control deliverability + manage_invites: Manage Invites + manage_invites_description: Allows users to browse and deactivate invite links + manage_reports: Manage Reports + manage_reports_description: Allows users to review reports and perform moderation actions against them + manage_roles: Manage Roles + manage_roles_description: Allows users to manage and assign roles below theirs + manage_rules: Manage Rules + manage_rules_description: Allows users to change server rules + manage_settings: Manage Settings + manage_settings_description: Allows users to change site settings + manage_taxonomies: Manage Taxonomies + manage_taxonomies_description: Allows users to review trending content and update hashtag settings + manage_user_access: Manage User Access + manage_user_access_description: Allows users to disable other users' two-factor authentication, change their e-mail address, and reset their password + manage_users: Manage Users + manage_users_description: Allows users to view other users' details and perform moderation actions against them + manage_webhooks: Manage Webhooks + manage_webhooks_description: Allows users to set up webhooks for administrative events + view_audit_log: View Audit Log + view_audit_log_description: Allows users to see a history of administrative actions on the server + view_dashboard: View Dashboard + view_dashboard_description: Allows users to access the dashboard and various metrics view_devops: DevOps + view_devops_description: Allows users to access Sidekiq and pgHero dashboards + title: Roles + rules: + add_new: Add rule + delete: Delete + description_html: While most claim to have read and agree to the terms of service, usually people do not read through until after a problem arises. Make it easier to see your server's rules at a glance by providing them in a flat bullet point list. Try to keep individual rules short and simple, but try not to split them up into many separate items either. + edit: Edit rule + empty: No server rules have been defined yet. + title: Server rules + settings: + about: + manage_rules: Manage server rules + preamble: Provide in-depth information about how the server is operated, moderated, funded. + rules_hint: There is a dedicated area for rules that your users are expected to adhere to. + title: About + appearance: + preamble: Customise Mastodon's web interface. + title: Appearance + branding: + preamble: Your server's branding differentiates it from other servers in the network. This information may be displayed across a variety of environments, such as Mastodon's web interface, native applications, in link previews on other websites and within messaging apps, and so on. For this reason, it is best to keep this information clear, short and concise. + title: Branding + captcha_enabled: + desc_html: This relies on external scripts from hCaptcha, which may be a security and privacy concern. In addition, this can make the registration process significantly less accessible to some (especially disabled) people. For these reasons, please consider alternative measures such as approval-based or invite-based registration. + title: Require new users to solve a CAPTCHA to confirm their account + content_retention: + preamble: Control how user-generated content is stored in Mastodon. + title: Content retention + default_noindex: + desc_html: Affects all users who have not changed this setting themselves + title: Opt users out of search engine indexing by default + discovery: + follow_recommendations: Follow recommendations + preamble: Surfacing interesting content is instrumental in onboarding new users who may not know anyone Mastodon. Control how various discovery features work on your server. + profile_directory: Profile directory + public_timelines: Public timelines + publish_discovered_servers: Publish discovered servers + publish_statistics: Publish statistics + title: Discovery + trends: Trends + domain_blocks: + all: To everyone + disabled: To no one + users: To logged-in local users + registrations: + preamble: Control who can create an account on your server. + title: Registrations + registrations_mode: + modes: + approved: Approval required for sign up + none: Nobody can sign up + open: Anyone can sign up + security: + authorized_fetch: Require authentication from federated servers + authorized_fetch_hint: Requiring authentication from federated servers enables stricter enforcement of both user-level and server-level blocks. However, this comes at the cost of a performance penalty, reduces the reach of your replies, and may introduce compatibility issues with some federated services. In addition, this will not prevent dedicated actors from fetching your public posts and accounts. + authorized_fetch_overridden_hint: You are currently unable to change this setting because it is overridden by an environment variable. + federation_authentication: Federation authentication enforcement + title: Server settings + site_uploads: + delete: Delete uploaded file + destroyed_msg: Site upload successfully deleted! + software_updates: + critical_update: Critical — please update quickly + description: It is recommended to keep your Mastodon installation up to date to benefit from the latest fixes and features. Moreover, it is sometimes critical to update Mastodon in a timely manner to avoid security issues. For these reasons, Mastodon checks for updates every 30 minutes, and will notify you according to your e-mail notification preferences. + documentation_link: Learn more + release_notes: Release notes + title: Available updates + type: Type + types: + major: Major release + minor: Minor release + patch: Patch release — bugfixes and easy to apply changes + version: Version + statuses: + account: Author + application: Application + back_to_account: Back to account page + back_to_report: Back to report page + batch: + remove_from_report: Remove from report + report: Report + deleted: Deleted + favourites: Favourites + history: Version history + in_reply_to: Replying to + language: Language + media: + title: Media + metadata: Metadata + no_status_selected: No posts were changed as none were selected + open: Open post + original_status: Original post + reblogs: Reblogs + status_changed: Post changed + title: Account posts + trending: Trending + visibility: Visibility + with_media: With media + strikes: + actions: + delete_statuses: "%{name} deleted %{target}'s posts" + disable: "%{name} froze %{target}'s account" + mark_statuses_as_sensitive: "%{name} marked %{target}'s posts as sensitive" + none: "%{name} sent a warning to %{target}" + sensitive: "%{name} marked %{target}'s account as sensitive" + silence: "%{name} limited %{target}'s account" + suspend: "%{name} suspended %{target}'s account" + appeal_approved: Appealed + appeal_pending: Appeal pending + appeal_rejected: Appeal rejected + system_checks: + database_schema_check: + message_html: There are pending database migrations. Please run them to ensure the application behaves as expected + elasticsearch_health_red: + message_html: Elasticsearch cluster is unhealthy (red status), search features are unavailable + elasticsearch_health_yellow: + message_html: Elasticsearch cluster is unhealthy (yellow status), you may want to investigate the reason + elasticsearch_index_mismatch: + message_html: Elasticsearch index mappings are outdated. Please run tootctl search deploy --only=%{value} + elasticsearch_preset: + action: See documentation + message_html: Your Elasticsearch cluster has more than one node, but Mastodon is not configured to use them. + elasticsearch_preset_single_node: + action: See documentation + message_html: Your Elasticsearch cluster has only one node, ES_PRESET should be set to single_node_cluster. + elasticsearch_reset_chewy: + message_html: Your Elasticsearch system index is outdated due to a setting change. Please run tootctl search deploy --reset-chewy to update it. + elasticsearch_running_check: + message_html: Could not connect to Elasticsearch. Please check that it is running, or disable full-text search + elasticsearch_version_check: + message_html: 'Incompatible Elasticsearch version: %{value}' + version_comparison: Elasticsearch %{running_version} is running while %{required_version} is required + rules_check: + action: Manage server rules + message_html: You haven't defined any server rules. + sidekiq_process_check: + message_html: No Sidekiq process running for the %{value} queue(s). Please review your Sidekiq configuration + software_version_critical_check: + action: See available updates + message_html: A critical Mastodon update is available, please update as quickly as possible. + software_version_patch_check: + action: See available updates + message_html: A bugfix Mastodon update is available. + upload_check_privacy_error: + action: Check here for more information + message_html: "Your web server is misconfigured. The privacy of your users is at risk." + upload_check_privacy_error_object_storage: + action: Check here for more information + message_html: "Your object storage is misconfigured. The privacy of your users is at risk." + tags: + review: Review status + updated_msg: Hashtag settings updated successfully + title: Administration + trends: + allow: Allow + approved: Approved + disallow: Disallow + links: + allow: Allow link + allow_provider: Allow publisher + description_html: These are links that are currently being shared a lot by accounts that your server sees posts from. It can help your users find out what's going on in the world. No links are displayed publicly until you approve the publisher. You can also allow or reject individual links. + disallow: Disallow link + disallow_provider: Disallow publisher + no_link_selected: No links were changed as none were selected + publishers: + no_publisher_selected: No publishers were changed as none were selected + shared_by_over_week: + one: Shared by one person over the last week + other: Shared by %{count} people over the last week + title: Trending links + usage_comparison: Shared %{today} times today, compared to %{yesterday} yesterday + not_allowed_to_trend: Not allowed to trend + only_allowed: Only allowed + pending_review: Pending review + preview_card_providers: + allowed: Links from this publisher can trend + description_html: These are domains from which links are often shared on your server. Links will not trend publicly unless the domain of the link is approved. Your approval (or rejection) extends to subdomains. + rejected: Links from this publisher won't trend + title: Publishers + rejected: Rejected + statuses: + allow: Allow post + allow_account: Allow author + description_html: These are posts that your server knows about that are currently being shared and favourited a lot at the moment. It can help your new and returning users to find more people to follow. No posts are displayed publicly until you approve the author, and the author allows their account to be suggested to others. You can also allow or reject individual posts. + disallow: Disallow post + disallow_account: Disallow author + no_status_selected: No trending posts were changed as none were selected + not_discoverable: Author has not opted-in to being discoverable + shared_by: + one: Shared or favourited one time + other: Shared and favourited %{friendly_count} times + title: Trending posts + tags: + current_score: Current score %{score} + dashboard: + tag_accounts_measure: unique uses + tag_languages_dimension: Top languages + tag_servers_dimension: Top servers + tag_servers_measure: different servers + tag_uses_measure: total uses + description_html: These are hashtags that are currently appearing in a lot of posts that your server sees. It can help your users find out what people are talking the most about at the moment. No hashtags are displayed publicly until you approve them. + listable: Can be suggested + no_tag_selected: No tags were changed as none were selected + not_listable: Won't be suggested + not_trendable: Won't appear under trends + not_usable: Cannot be used + peaked_on_and_decaying: Peaked on %{date}, now decaying + title: Trending hashtags + trendable: Can appear under trends + trending_rank: 'Trending #%{rank}' + usable: Can be used + usage_comparison: Used %{today} times today, compared to %{yesterday} yesterday + used_by_over_week: + one: Used by one person over the last week + other: Used by %{count} people over the last week + title: Trends + trending: Trending + warning_presets: + add_new: Add new + delete: Delete + edit_preset: Edit warning preset + empty: You haven't defined any warning presets yet. + title: Manage warning presets + webhooks: + add_new: Add endpoint + delete: Delete + description_html: A webhook enables Mastodon to push real-time notifications about chosen events to your own application, so your application can automatically trigger reactions. + disable: Disable + disabled: Disabled + edit: Edit endpoint + empty: You don't have any webhook endpoints configured yet. + enable: Enable + enabled: Active + enabled_events: + one: 1 enabled event + other: "%{count} enabled events" + events: Events + new: New webhook + rotate_secret: Rotate secret + secret: Signing secret + status: Status + title: Webhooks + webhook: Webhook + admin_mailer: + new_appeal: + actions: + delete_statuses: to delete their posts + disable: to freeze their account + mark_statuses_as_sensitive: to mark their posts as sensitive + none: a warning + sensitive: to mark their account as sensitive + silence: to limit their account + suspend: to suspend their account + body: "%{target} is appealing a moderation decision by %{action_taken_by} from %{date}, which was %{type}. They wrote:" + next_steps: You can approve the appeal to undo the moderation decision, or ignore it. + subject: "%{username} is appealing a moderation decision on %{instance}" + new_critical_software_updates: + body: New critical versions of Mastodon have been released, you may want to update as soon as possible! + subject: Critical Mastodon updates are available for %{instance}! + new_pending_account: + body: The details of the new account are below. You can approve or reject this application. + subject: New account up for review on %{instance} (%{username}) + new_report: + body: "%{reporter} has reported %{target}" + body_remote: Someone from %{domain} has reported %{target} + subject: New report for %{instance} (#%{id}) + new_software_updates: + body: New Mastodon versions have been released, you may want to update! + subject: New Mastodon versions are available for %{instance}! + new_trends: + body: 'The following items need a review before they can be displayed publicly:' + new_trending_links: + title: Trending links + new_trending_statuses: + title: Trending posts + new_trending_tags: + no_approved_tags: There are currently no approved trending hashtags. + requirements: 'Any of these candidates could surpass the #%{rank} approved trending hashtag, which is currently #%{lowest_tag_name} with a score of %{lowest_tag_score}.' + title: Trending hashtags + subject: New trends up for review on %{instance} + aliases: + add_new: Create alias + created_msg: Successfully created a new alias. You can now initiate the move from the old account. + deleted_msg: Successfully removed the alias. Moving from that account to this one will no longer be possible. + empty: You have no aliases. + hint_html: If you want to move from another account to this one, here you can create an alias, which is required before you can proceed with moving followers from the old account to this one. This action by itself is harmless and reversible. The account migration is initiated from the old account. + remove: Unlink alias + appearance: + advanced_web_interface: Advanced web interface + advanced_web_interface_hint: 'If you want to make use of your entire screen width, the advanced web interface allows you to configure many different columns to see as much information at the same time as you want: Home, notifications, federated timeline, any number of lists and hashtags.' + animations_and_accessibility: Animations and accessibility + confirmation_dialogs: Confirmation dialogues + discovery: Discovery + localization: + body: Mastodon is translated by volunteers. + guide_link: https://crowdin.com/project/mastodon + guide_link_text: Everyone can contribute. + sensitive_content: Sensitive content + application_mailer: + notification_preferences: Change e-mail preferences + salutation: "%{name}," + settings: 'Change e-mail preferences: %{link}' + unsubscribe: Unsubscribe + view: 'View:' + view_profile: View profile + view_status: View post + applications: + created: Application successfully created + destroyed: Application successfully deleted + logout: Log out + regenerate_token: Regenerate access token + token_regenerated: Access token successfully regenerated + warning: Be very careful with this data. Never share it with anyone! + your_token: Your access token + auth: + apply_for_account: Request an account + captcha_confirmation: + help_html: If you have issues solving the CAPTCHA, you can get in touch with us through %{email} and we can assist you. + hint_html: Just one more thing! We need to confirm you're a human (this is so we can keep the spam out!). Solve the CAPTCHA below and click "Continue". + title: Security check + confirmations: + wrong_email_hint: If that e-mail address is not correct, you can change it in account settings. + delete_account: Delete account + delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. + description: + prefix_invited_by_user: "@%{name} invites you to join this server of Mastodon!" + prefix_sign_up: Sign up on Mastodon today! + suffix: With an account, you will be able to follow people, post updates and exchange messages with users from any Mastodon server and more! + didnt_get_confirmation: Didn't receive a confirmation link? + dont_have_your_security_key: Don't have your security key? + forgot_password: Forgot your password? + invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one. + link_to_otp: Enter a two-factor code from your phone or a recovery code + link_to_webauth: Use your security key device + log_in_with: Log in with + login: Log in + logout: Log out + migrate_account: Move to a different account + migrate_account_html: If you wish to redirect this account to a different one, you can configure it here. + or_log_in_with: Or log in with + privacy_policy_agreement_html: I have read and agree to the privacy policy + progress: + confirm: Confirm e-mail + details: Your details + review: Our review + rules: Accept rules + providers: + cas: CAS + saml: SAML + register: Sign up + registration_closed: "%{instance} is not accepting new members" + resend_confirmation: Resend confirmation link + reset_password: Reset password + rules: + accept: Accept + back: Back + invited_by: 'You can join %{domain} thanks to the invitation you have received from:' + preamble: These are set and enforced by the %{domain} moderators. + preamble_invited: Before you proceed, please consider the ground rules set by the moderators of %{domain}. + title: Some ground rules. + title_invited: You've been invited. + security: Security + set_new_password: Set new password + setup: + email_below_hint_html: Check your spam folder, or request another one. You can correct your e-mail address if it's wrong. + email_settings_hint_html: Click the link we sent you to verify %{email}. We'll wait right here. + link_not_received: Didn't get a link? + new_confirmation_instructions_sent: You will receive a new e-mail with the confirmation link in a few minutes! + title: Check your inbox + sign_in: + preamble_html: Log in with your %{domain} credentials. If your account is hosted on a different server, you will not be able to log in here. + title: Log in to %{domain} + sign_up: + manual_review: Sign-ups on %{domain} go through manual review by our moderators. To help us process your registration, write a bit about yourself and why you want an account on %{domain}. + preamble: With an account on this Mastodon server, you'll be able to follow any other person on the network, regardless of where their account is hosted. + title: Let's get you set up on %{domain}. + status: + account_status: Account status + confirming: Waiting for e-mail confirmation to be completed. + functional: Your account is fully operational. + pending: Your application is pending review by our staff. This may take some time. You will receive an e-mail if your application is approved. + redirecting_to: Your account is inactive because it is currently redirecting to %{acct}. + view_strikes: View past strikes against your account + too_fast: Form submitted too fast, try again. + use_security_key: Use security key + challenge: + confirm: Continue + hint_html: "Tip: We won't ask you for your password again for the next hour." + invalid_password: Invalid password + prompt: Confirm password to continue + crypto: + errors: + invalid_key: is not a valid Ed25519 or Curve25519 key + invalid_signature: is not a valid Ed25519 signature + date: + formats: + default: "%b %d, %Y" + with_month_name: "%B %d, %Y" + datetime: + distance_in_words: + about_x_hours: "%{count}h" + about_x_months: "%{count}mo" + about_x_years: "%{count}y" + almost_x_years: "%{count}y" + half_a_minute: Just now + less_than_x_minutes: "%{count}m" + less_than_x_seconds: Just now + over_x_years: "%{count}y" + x_days: "%{count}d" + x_minutes: "%{count}m" + x_months: "%{count}mo" + x_seconds: "%{count}s" + deletes: + challenge_not_passed: The information you entered was not correct + confirm_password: Enter your current password to verify your identity + confirm_username: Enter your username to confirm the procedure + proceed: Delete account + success_msg: Your account was successfully deleted + warning: + before: 'Before proceeding, please read these notes carefully:' + caches: Content that has been cached by other servers may persist + data_removal: Your posts and other data will be permanently removed + email_change_html: You can change your e-mail address without deleting your account + email_contact_html: If it still doesn't arrive, you can e-mail %{email} for help + email_reconfirmation_html: If you are not receiving the confirmation e-mail, you can request it again + irreversible: You will not be able to restore or reactivate your account + more_details_html: For more details, see the privacy policy. + username_available: Your username will become available again + username_unavailable: Your username will remain unavailable + disputes: + strikes: + action_taken: Action taken + appeal: Appeal + appeal_approved: This strike has been successfully appealed and is no longer valid + appeal_rejected: The appeal has been rejected + appeal_submitted_at: Appeal submitted + appealed_msg: Your appeal has been submitted. If it is approved, you will be notified. + appeals: + submit: Submit appeal + approve_appeal: Approve appeal + associated_report: Associated report + created_at: Dated + description_html: These are actions taken against your account and warnings that have been sent to you by the staff of %{instance}. + recipient: Addressed to + reject_appeal: Reject appeal + status: 'Post #%{id}' + status_removed: Post already removed from system + title: "%{action} from %{date}" + title_actions: + delete_statuses: Post removal + disable: Freezing of account + mark_statuses_as_sensitive: Marking of posts as sensitive + none: Warning + sensitive: Marking of account as sensitive + silence: Limitation of account + suspend: Suspension of account + your_appeal_approved: Your appeal has been approved + your_appeal_pending: You have submitted an appeal + your_appeal_rejected: Your appeal has been rejected + domain_validator: + invalid_domain: is not a valid domain name + edit_profile: + basic_information: Basic information + hint_html: "Customise what people see on your public profile and next to your posts. Other people are more likely to follow you back and interact with you when you have a filled out profile and a profile picture." + other: Other errors: '400': The request you submitted was invalid or malformed. '403': You don't have permission to view this page. '404': The page you are looking for isn't here. '406': This page is not available in the requested format. '410': The page you were looking for doesn't exist here anymore. + '422': + content: Security verification failed. Are you blocking cookies? + title: Security verification failed '429': Too many requests + '500': + content: We're sorry, but something went wrong on our end. + title: This page is not correct '503': The page could not be served due to a temporary server failure. + noscript_html: To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the native apps for Mastodon for your platform. + existing_username_validator: + not_found: could not find a local user with that username + not_found_multiple: could not find %{usernames} + exports: + archive_takeout: + date: Date + download: Download your archive + hint_html: You can request an archive of your posts and uploaded media. The exported data will be in the ActivityPub format, readable by any compliant software. You can request an archive every 7 days. + in_progress: Compiling your archive... + request: Request your archive + size: Size + blocks: You block + bookmarks: Bookmarks + csv: CSV + domain_blocks: Domain blocks + lists: Lists + mutes: You mute + storage: Media storage + featured_tags: + add_new: Add new + errors: + limit: You have already featured the maximum number of hashtags + hint_html: "What are featured hashtags? They are displayed prominently on your public profile and allow people to browse your public posts specifically under those hashtags. They are a great tool for keeping track of creative works or long-term projects." + filters: + contexts: + account: Profiles + home: Home and lists + notifications: Notifications + public: Public timelines + thread: Conversations + edit: + add_keyword: Add keyword + keywords: Keywords + statuses: Individual posts + statuses_hint_html: This filter applies to select individual posts regardless of whether they match the keywords below. Review or remove posts from the filter. + title: Edit filter + errors: + deprecated_api_multiple_keywords: These parameters cannot be changed from this application because they apply to more than one filter keyword. Use a more recent application or the web interface. + invalid_context: None or invalid context supplied + index: + contexts: Filters in %{contexts} + delete: Delete + empty: You have no filters. + expires_in: Expires in %{distance} + expires_on: Expires on %{date} + keywords: + one: "%{count} keyword" + other: "%{count} keywords" + statuses: + one: "%{count} post" + other: "%{count} posts" + statuses_long: + one: "%{count} individual post hidden" + other: "%{count} individual posts hidden" + title: Filters + new: + save: Save new filter + title: Add new filter + statuses: + back_to_filter: Back to filter + batch: + remove: Remove from filter + index: + hint: This filter applies to select individual posts regardless of other criteria. You can add more posts to this filter from the web interface. + title: Filtered posts + generic: + all: All + all_items_on_page_selected_html: + one: "%{count} item on this page is selected." + other: All %{count} items on this page are selected. + all_matching_items_selected_html: + one: "%{count} item matching your search is selected." + other: All %{count} items matching your search are selected. + cancel: Cancel + changes_saved_msg: Changes successfully saved! + confirm: Confirm + copy: Copy + delete: Delete + deselect: Deselect all + none: None + order_by: Order by + save_changes: Save changes + select_all_matching_items: + one: Select %{count} item matching your search. + other: Select all %{count} items matching your search. + today: today + validation_errors: + one: Something isn't quite right yet! Please review the error below + other: Something isn't quite right yet! Please review %{count} errors below + imports: + errors: + empty: Empty CSV file + incompatible_type: Incompatible with the selected import type + invalid_csv_file: 'Invalid CSV file. Error: %{error}' + over_rows_processing_limit: contains more than %{count} rows + too_large: File is too large + failures: Failures + imported: Imported + mismatched_types_warning: It appears you may have selected the wrong type for this import, please double-check. + modes: + merge: Merge + merge_long: Keep existing records and add new ones + overwrite: Overwrite + overwrite_long: Replace current records with the new ones + overwrite_preambles: + blocking_html: You are about to replace your block list with up to %{total_items} accounts from %{filename}. + bookmarks_html: You are about to replace your bookmarks with up to %{total_items} posts from %{filename}. + domain_blocking_html: You are about to replace your domain block list with up to %{total_items} domains from %{filename}. + following_html: You are about to follow up to %{total_items} accounts from %{filename} and stop following anyone else. + lists_html: You are about to replace your lists with contents of %{filename}. Up to %{total_items} accounts will be added to new lists. + muting_html: You are about to replace your list of muted accounts with up to %{total_items} accounts from %{filename}. + preambles: + blocking_html: You are about to block up to %{total_items} accounts from %{filename}. + bookmarks_html: You are about to add up to %{total_items} posts from %{filename} to your bookmarks. + domain_blocking_html: You are about to block up to %{total_items} domains from %{filename}. + following_html: You are about to follow up to %{total_items} accounts from %{filename}. + lists_html: You are about to add up to %{total_items} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. + muting_html: You are about to mute up to %{total_items} accounts from %{filename}. + preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking. + recent_imports: Recent imports + states: + finished: Finished + in_progress: In progress + scheduled: Scheduled + unconfirmed: Unconfirmed + status: Status + success: Your data was successfully uploaded and will be processed in due time + time_started: Started at + titles: + blocking: Importing blocked accounts + bookmarks: Importing bookmarks + domain_blocking: Importing blocked domains + following: Importing followed accounts + lists: Importing lists + muting: Importing muted accounts + type: Import type + type_groups: + constructive: Follows & Bookmarks + destructive: Blocks & mutes + types: + blocking: Blocking list + bookmarks: Bookmarks + domain_blocking: Domain blocking list + following: Following list + lists: Lists + muting: Muting list + upload: Upload + invites: + delete: Deactivate + expired: Expired + expires_in: + '1800': 30 minutes + '21600': 6 hours + '3600': 1 hour + '43200': 12 hours + '604800': 1 week + '86400': 1 day + expires_in_prompt: Never + generate: Generate invite link + invited_by: 'You were invited by:' + max_uses: + one: 1 use + other: "%{count} uses" + max_uses_prompt: No limit + prompt: Generate and share links with others to grant access to this server + table: + expires_at: Expires + uses: Uses + title: Invite people + lists: + errors: + limit: You have reached the maximum number of lists + login_activities: + authentication_methods: + otp: two-factor authentication app + password: password + sign_in_token: e-mail security code + webauthn: security keys + description_html: If you see activity that you don't recognise, consider changing your password and enabling two-factor authentication. + empty: No authentication history available + failed_sign_in_html: Failed login attempt with %{method} from %{ip} (%{browser}) + successful_sign_in_html: Successful login with %{method} from %{ip} (%{browser}) + title: Authentication history + mail_subscriptions: + unsubscribe: + action: Yes, unsubscribe + complete: Unsubscribed + confirmation_html: Are you sure you want to unsubscribe from receiving %{type} for Mastodon on %{domain} to your e-mail at %{email}? You can always re-subscribe from your e-mail notification settings. + emails: + notification_emails: + favourite: favourite notification e-mails + follow: follow notification e-mails + follow_request: follow request e-mails + mention: mention notification e-mails + reblog: boost notification e-mails + resubscribe_html: If you've unsubscribed by mistake, you can re-subscribe from your e-mail notification settings. + success_html: You'll no longer receive %{type} for Mastodon on %{domain} to your e-mail at %{email}. + title: Unsubscribe + media_attachments: + validations: + images_and_video: Cannot attach a video to a post that already contains images + not_ready: Cannot attach files that have not finished processing. Try again in a moment! + too_many: Cannot attach more than 4 files + migrations: + acct: Moved to + cancel: Cancel redirect + cancel_explanation: Cancelling the redirect will re-activate your current account, but will not bring back followers that have been moved to that account. + cancelled_msg: Successfully cancelled the redirect. + errors: + already_moved: is the same account you have already moved to + missing_also_known_as: is not an alias of this account + move_to_self: cannot be current account + not_found: could not be found + on_cooldown: You are on cooldown + followers_count: Followers at time of move + incoming_migrations: Moving from a different account + incoming_migrations_html: To move from another account to this one, first you need to create an account alias. + moved_msg: Your account is now redirecting to %{acct} and your followers are being moved over. + not_redirecting: Your account is not redirecting to any other account currently. + on_cooldown: You have recently migrated your account. This function will become available again in %{count} days. + past_migrations: Past migrations + proceed_with_move: Move followers + redirected_msg: Your account is now redirecting to %{acct}. + redirecting_to: Your account is redirecting to %{acct}. + set_redirect: Set redirect + warning: + backreference_required: The new account must first be configured to back-reference this one + before: 'Before proceeding, please read these notes carefully:' + cooldown: After moving there is a waiting period during which you will not be able to move again + 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 + move_handler: + carry_blocks_over_text: This user moved from %{acct}, which you had blocked. + carry_mutes_over_text: This user moved from %{acct}, which you had muted. + copy_account_note_text: 'This user moved from %{acct}, here were your previous notes about them:' + navigation: + toggle_menu: Toggle menu + notification_mailer: + admin: + report: + subject: "%{name} submitted a report" + sign_up: + subject: "%{name} signed up" + favourite: + body: 'Your post was favourited by %{name}:' + subject: "%{name} favourited your post" + title: New favourite + follow: + body: "%{name} is now following you!" + subject: "%{name} is now following you" + title: New follower + follow_request: + action: Manage follow requests + body: "%{name} has requested to follow you" + subject: 'Pending follower: %{name}' + title: New follow request + mention: + action: Reply + body: 'You were mentioned by %{name} in:' + subject: You were mentioned by %{name} + title: New mention + poll: + subject: A poll by %{name} has ended + reblog: + body: 'Your post was boosted by %{name}:' + subject: "%{name} boosted your post" + title: New boost + status: + subject: "%{name} just posted" + update: + subject: "%{name} edited a post" + notifications: + administration_emails: Admin e-mail notifications + email_events: Events for e-mail notifications + email_events_hint: 'Select events that you want to receive notifications for:' + other_settings: Other notifications settings + number: + human: + decimal_units: + format: "%n%u" + units: + billion: B + million: M + quadrillion: Q + thousand: K + trillion: T + otp_authentication: + code_hint: Enter the code generated by your authenticator app to confirm + description_html: If you enable two-factor authentication using an authenticator app, logging in will require you to be in possession of your phone, which will generate tokens for you to enter. + enable: Enable + instructions_html: "Scan this QR code into Google Authenticator or a similar TOTP app on your phone. From now on, that app will generate tokens that you will have to enter when logging in." + manual_instructions: 'If you can''t scan the QR code and need to enter it manually, here is the plain-text secret:' + setup: Set up + wrong_code: The entered code was invalid! Are server time and device time correct? + pagination: + newer: Newer + next: Next + older: Older + prev: Prev + truncate: "…" + polls: + errors: + already_voted: You have already voted on this poll + duplicate_options: contain duplicate items + duration_too_long: is too far into the future + duration_too_short: is too soon + expired: The poll has already ended + invalid_choice: The chosen vote option does not exist + over_character_limit: cannot be longer than %{max} characters each + self_vote: You cannot vote in your own polls + too_few_options: must have more than one item + too_many_options: can't contain more than %{max} items + preferences: + other: Other + posting_defaults: Posting defaults + public_timelines: Public timelines + privacy: + hint_html: "Customise how you want your profile and your posts to be found. A variety of features in Mastodon can help you reach a wider audience when enabled. Take a moment to review these settings to make sure they fit your use case." + privacy: Privacy + privacy_hint_html: Control how much you want to disclose for the benefit of others. People discover interesting profiles and cool apps by browsing other people's follows and seeing which apps they post from, but you may prefer to keep it hidden. + reach: Reach + reach_hint_html: Control whether you want to be discovered and followed by new people. Do you want your posts to appear on the Explore screen? Do you want other people to see you in their follow recommendations? Do you want to accept all new followers automatically, or have granular control over each one? + search: Search + search_hint_html: Control how you want to be found. Do you want people to find you by what you've publicly posted about? Do you want people outside Mastodon to find your profile when searching the web? Please mind that total exclusion from all search engines cannot be guaranteed for public information. + title: Privacy and reach + privacy_policy: + title: Privacy Policy + reactions: + errors: + limit_reached: Limit of different reactions reached + unrecognized_emoji: is not a recognised emoji + relationships: + activity: Account activity + confirm_follow_selected_followers: Are you sure you want to follow selected followers? + confirm_remove_selected_followers: Are you sure you want to remove selected followers? + confirm_remove_selected_follows: Are you sure you want to remove selected follows? + dormant: Dormant + follow_failure: Could not follow some of the selected accounts. + follow_selected_followers: Follow selected followers + followers: Followers + following: Following + invited: Invited + last_active: Last active + most_recent: Most recent + moved: Moved + mutual: Mutual + primary: Primary + relationship: Relationship + remove_selected_domains: Remove all followers from the selected domains + remove_selected_followers: Remove selected followers + remove_selected_follows: Unfollow selected users + status: Account status + remote_follow: + missing_resource: Could not find the required redirect URL for your account + reports: + errors: + invalid_rules: does not reference valid rules + rss: + content_warning: 'Content warning:' + descriptions: + account: Public posts from @%{acct} + tag: 'Public posts tagged #%{hashtag}' + scheduled_statuses: + over_daily_limit: You have exceeded the limit of %{limit} scheduled posts for today + over_total_limit: You have exceeded the limit of %{limit} scheduled posts + too_soon: The scheduled date must be in the future sessions: + activity: Last activity + browser: Browser browsers: + alipay: Alipay blackberry: BlackBerry + chrome: Chrome + edge: Microsoft Edge + electron: Electron + firefox: Firefox + generic: Unknown browser + huawei_browser: Huawei Browser + ie: Internet Explorer + micro_messenger: MicroMessenger + nokia: Nokia S40 Ovi Browser + opera: Opera + otter: Otter + phantom_js: PhantomJS + qq: QQ Browser + safari: Safari uc_browser: UC Browser + unknown_browser: Unknown Browser + weibo: Weibo + current_session: Current session + description: "%{browser} on %{platform}" + explanation: These are the web browsers currently logged in to your Mastodon account. + ip: IP platforms: + adobe_air: Adobe Air + android: Android blackberry: BlackBerry chrome_os: ChromeOS + firefox_os: Firefox OS + ios: iOS + kai_os: KaiOS + linux: Linux + mac: macOS + unknown_platform: Unknown Platform + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone + revoke: Revoke + revoke_success: Session successfully revoked + title: Sessions + view_authentication_history: View authentication history of your account + settings: + account: Account + account_settings: Account settings + aliases: Account aliases + appearance: Appearance + authorized_apps: Authorised apps + back: Back to Mastodon + delete: Account deletion + development: Development + edit_profile: Edit profile + export: Data export + featured_tags: Featured hashtags + import: Import + import_and_export: Import and export + migrate: Account migration + notifications: Notifications + preferences: Preferences + profile: Profile + relationships: Follows and followers + statuses_cleanup: Automated post deletion + strikes: Moderation strikes + two_factor_authentication: Two-factor Auth + webauthn_authentication: Security keys + statuses: + attached: + audio: + one: "%{count} audio" + other: "%{count} audio" + description: 'Attached: %{attached}' + image: + one: "%{count} image" + other: "%{count} images" + video: + one: "%{count} video" + other: "%{count} videos" + boosted_from_html: Boosted from %{acct_link} + content_warning: 'Content warning: %{warning}' + default_language: Same as interface language + disallowed_hashtags: + one: 'contained a disallowed hashtag: %{tags}' + other: 'contained the disallowed hashtags: %{tags}' + edited_at_html: Edited %{date} + errors: + in_reply_not_found: The post you are trying to reply to does not appear to exist. + open_in_web: Open in web + over_character_limit: character limit of %{max} exceeded + pin_errors: + direct: Posts that are only visible to mentioned users cannot be pinned + limit: You have already pinned the maximum number of posts + ownership: Someone else's post cannot be pinned + reblog: A boost cannot be pinned + poll: + total_people: + one: "%{count} person" + other: "%{count} people" + total_votes: + one: "%{count} vote" + other: "%{count} votes" + vote: Vote + show_more: Show more + show_newer: Show newer + show_older: Show older + show_thread: Show thread + title: '%{name}: "%{quote}"' + visibilities: + direct: Direct + private: Followers-only + private_long: Only show to followers + public: Public + public_long: Everyone can see + unlisted: Unlisted + unlisted_long: Everyone can see, but not listed on public timelines + statuses_cleanup: + enabled: Automatically delete old posts + enabled_hint: Automatically deletes your posts once they reach a specified age threshold, unless they match one of the exceptions below + exceptions: Exceptions + explanation: Because deleting posts is an expensive operation, this is done slowly over time when the server is not otherwise busy. For this reason, your posts may be deleted a while after they reach the age threshold. + ignore_favs: Ignore favourites + ignore_reblogs: Ignore boosts + interaction_exceptions: Exceptions based on interactions + interaction_exceptions_explanation: Note that there is no guarantee for posts to be deleted if they go below the favourite or boost threshold after having once gone over them. + keep_direct: Keep direct messages + keep_direct_hint: Doesn't delete any of your direct messages + keep_media: Keep posts with media attachments + keep_media_hint: Doesn't delete any of your posts that have media attachments + keep_pinned: Keep pinned posts + keep_pinned_hint: Doesn't delete any of your pinned posts + keep_polls: Keep polls + keep_polls_hint: Doesn't delete any of your polls + keep_self_bookmark: Keep posts you bookmarked + keep_self_bookmark_hint: Doesn't delete your own posts if you have bookmarked them + keep_self_fav: Keep posts you favourited + keep_self_fav_hint: Doesn't delete your own posts if you have favourited them + min_age: + '1209600': 2 weeks + '15778476': 6 months + '2629746': 1 month + '31556952': 1 year + '5259492': 2 months + '604800': 1 week + '63113904': 2 years + '7889238': 3 months + min_age_label: Age threshold + min_favs: Keep posts favourited at least + min_favs_hint: Doesn't delete any of your posts that has received at least this number of favourites. Leave blank to delete posts regardless of their number of favourites + min_reblogs: Keep posts boosted at least + min_reblogs_hint: Doesn't delete any of your posts that has been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts + stream_entries: + sensitive_content: Sensitive content + strikes: + errors: + too_late: It is too late to appeal this strike + tags: + does_not_match_previous_name: does not match the previous name + themes: + contrast: Mastodon (High contrast) + default: Mastodon (Dark) + mastodon-light: Mastodon (Light) + time: + formats: + default: "%b %d, %Y, %H:%M" + month: "%b %Y" + time: "%H:%M" + translation: + errors: + quota_exceeded: The server-wide usage quota for the translation service has been exceeded. + too_many_requests: There have been too many requests to the translation service recently. two_factor_authentication: + add: Add + disable: Disable 2FA + disabled_success: Two-factor authentication successfully disabled + edit: Edit + enabled: Two-factor authentication is enabled + enabled_success: Two-factor authentication successfully enabled + generate_recovery_codes: Generate recovery codes + lost_recovery_codes: Recovery codes allow you to regain access to your account if you lose your phone. If you've lost your recovery codes, you can regenerate them here. Your old recovery codes will be invalidated. + methods: Two-factor methods + otp: Authenticator app + recovery_codes: Backup recovery codes recovery_codes_regenerated: Recovery codes successfully regenerated recovery_instructions_html: If you ever lose access to your phone, you can use one of the recovery codes below to regain access to your account. Keep the recovery codes safe. For example, you may print them and store them with other important documents. webauthn: Security keys @@ -255,8 +1762,43 @@ en-GB: action: Go to your account explanation: The appeal of the strike against your account on %{strike_date} that you submitted on %{appeal_date} has been approved. Your account is once again in good standing. subject: Your appeal from %{date} has been approved + title: Appeal approved + appeal_rejected: + explanation: The appeal of the strike against your account on %{strike_date} that you submitted on %{appeal_date} has been rejected. + subject: Your appeal from %{date} has been rejected + title: Appeal rejected + backup_ready: + explanation: You requested a full backup of your Mastodon account. It's now ready for download! + subject: Your archive is ready for download + title: Archive takeout + suspicious_sign_in: + change_password: change your password + details: 'Here are details of the login:' + explanation: We've detected a login to your account from a new IP address. + further_actions_html: If this wasn't you, we recommend that you %{action} immediately and enable two-factor authentication to keep your account secure. + subject: Your account has been accessed from a new IP address + title: A new login warning: + appeal: Submit an appeal + appeal_description: If you believe this is an error, you can submit an appeal to the staff of %{instance}. + categories: + spam: Spam + violation: Content violates the following community guidelines + explanation: + delete_statuses: Some of your posts have been found to violate one or more community guidelines and have been subsequently removed by the moderators of %{instance}. + disable: You can no longer use your account, but your profile and other data remains intact. You can request a backup of your data, change account settings or delete your account. + mark_statuses_as_sensitive: Some of your posts have been marked as sensitive by the moderators of %{instance}. This means that people will need to tap the media in the posts before a preview is displayed. You can mark media as sensitive yourself when posting in the future. + sensitive: From now on, all your uploaded media files will be marked as sensitive and hidden behind a click-through warning. + silence: You can still use your account but only people who are already following you will see your posts on this server, and you may be excluded from various discovery features. However, others may still manually follow you. + suspend: You can no longer use your account, and your profile and other data are no longer accessible. You can still log in to request a backup of your data until the data is fully removed in about 30 days, but we will retain some basic data to prevent you from evading the suspension. + reason: 'Reason:' + statuses: 'Posts cited:' subject: + delete_statuses: Your posts on %{acct} have been removed + disable: Your account %{acct} has been frozen + mark_statuses_as_sensitive: Your posts on %{acct} have been marked as sensitive + none: Warning for %{acct} + sensitive: Your posts on %{acct} will be marked as sensitive from now on silence: Your account %{acct} has been limited suspend: Your account %{acct} has been suspended title: @@ -279,11 +1821,23 @@ en-GB: title: Welcome aboard, %{name}! users: follow_limit_reached: You cannot follow more than %{limit} people + go_to_sso_account_settings: Go to your identity provider's account settings invalid_otp_token: Invalid two-factor code otp_lost_help_html: If you lost access to both, you may get in touch with %{email} seamless_external_login: You are logged in via an external service, so password and e-mail settings are not available. - signed_in_as: 'Signed in as:' + signed_in_as: 'Logged in as:' + verification: + extra_instructions_html: Tip: The link on your website can be invisible. The important part is rel="me" which prevents impersonation on websites with user-generated content. You can even use a link tag in the header of the page instead of a, but the HTML must be accessible without executing JavaScript. + here_is_how: Here's how + hint_html: "Verifying your identity on Mastodon is for everyone. Based on open web standards, now and forever free. All you need is a personal website that people recognize you by. When you link to this website from your profile, we will check that the website links back to your profile and show a visual indicator on it." + instructions_html: Copy and paste the code below into the HTML of your website. Then add the address of your website into one of the extra fields on your profile from the "Edit profile" tab and save changes. + verification: Verification + verified_links: Your verified links webauthn_credentials: + add: Add new security key + create: + error: There was a problem adding your security key. Please try again. + success: Your security key was successfully added. delete: Delete delete_confirmation: Are you sure you want to delete this security key? description_html: If you enable security key authentication, logging in will require you to use one of your security keys. diff --git a/config/locales/en.yml b/config/locales/en.yml index b81fe85e05..3a90616451 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -91,6 +91,7 @@ en: moderation: active: Active all: All + disabled: Disabled pending: Pending silenced: Limited suspended: Suspended @@ -124,8 +125,8 @@ en: removed_header_msg: Successfully removed %{username}'s header image resend_confirmation: already_confirmed: This user is already confirmed - send: Resend confirmation email - success: Confirmation email successfully sent! + send: Resend confirmation link + success: Confirmation link successfully sent! reset: Reset reset_password: Reset password resubscribe: Resubscribe @@ -133,6 +134,7 @@ en: search: Search search_same_email_domain: Other users with the same e-mail domain search_same_ip: Other users with the same IP + security: Security security_measures: only_password: Only password password_and_2fa: Password and 2FA @@ -307,6 +309,7 @@ en: unpublish: Unpublish unpublished_msg: Announcement successfully unpublished! updated_msg: Announcement successfully updated! + critical_update_pending: Critical update pending custom_emojis: assign_category: Assign category by_domain: Domain @@ -380,6 +383,15 @@ en: undo: Disallow federation with domain domain_blocks: add_new: Add new domain block + confirm_suspension: + cancel: Cancel + confirm: Suspend + permanent_action: Undoing the suspension will not restore any data or relationship. + preamble_html: You are about to suspend %{domain} and its subdomains. + remove_all_data: This will remove all content, media, and profile data for this domain's accounts from your server. + stop_communication: Your server will stop communicating with these servers. + title: Confirm domain block for %{domain} + undo_relationships: This will undo any follow relationship between accounts of these servers and yours. created_msg: Domain block is now being processed destroyed_msg: Domain block has been undone domain: Domain @@ -427,6 +439,7 @@ en: resolve: Resolve domain title: Block new e-mail domain no_email_domain_block_selected: No e-mail domain blocks were changed as none were selected + not_permitted: Not permitted resolved_dns_records_hint_html: The domain name resolves to the following MX domains, which are ultimately responsible for accepting e-mail. Blocking an MX domain will block sign-ups from any e-mail address which uses the same MX domain, even if the visible domain name is different. Be careful not to block major e-mail providers. resolved_through_html: Resolved through %{domain} title: Blocked e-mail domains @@ -473,6 +486,7 @@ en: content_policies: comment: Internal note description_html: You can define content policies that will be applied to all accounts from this domain and any of its subdomains. + limited_federation_mode_description_html: You can chose whether to allow federation with this domain. policies: reject_media: Reject media reject_reports: Reject reports @@ -585,11 +599,13 @@ en: assign_to_self: Assign to me assigned: Assigned moderator by_target_domain: Domain of reported account + cancel: Cancel category: Category category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account comment: none: None comment_description_html: 'To provide more information, %{name} wrote:' + confirm: Confirm confirm_action: Confirm moderation action against @%{acct} created_at: Reported delete_and_resolve: Delete posts @@ -725,6 +741,9 @@ en: branding: preamble: Your server's branding differentiates it from other servers in the network. This information may be displayed across a variety of environments, such as Mastodon's web interface, native applications, in link previews on other websites and within messaging apps, and so on. For this reason, it is best to keep this information clear, short and concise. title: Branding + captcha_enabled: + desc_html: This relies on external scripts from hCaptcha, which may be a security and privacy concern. In addition, this can make the registration process significantly less accessible to some (especially disabled) people. For these reasons, please consider alternative measures such as approval-based or invite-based registration. + title: Require new users to solve a CAPTCHA to confirm their account content_retention: preamble: Control how user-generated content is stored in Mastodon. title: Content retention @@ -752,10 +771,27 @@ en: approved: Approval required for sign up none: Nobody can sign up open: Anyone can sign up - title: Server Settings + security: + authorized_fetch: Require authentication from federated servers + authorized_fetch_hint: Requiring authentication from federated servers enables stricter enforcement of both user-level and server-level blocks. However, this comes at the cost of a performance penalty, reduces the reach of your replies, and may introduce compatibility issues with some federated services. In addition, this will not prevent dedicated actors from fetching your public posts and accounts. + authorized_fetch_overridden_hint: You are currently unable to change this setting because it is overridden by an environment variable. + federation_authentication: Federation authentication enforcement + title: Server settings site_uploads: delete: Delete uploaded file destroyed_msg: Site upload successfully deleted! + software_updates: + critical_update: Critical — please update quickly + description: It is recommended to keep your Mastodon installation up to date to benefit from the latest fixes and features. Moreover, it is sometimes critical to update Mastodon in a timely manner to avoid security issues. For these reasons, Mastodon checks for updates every 30 minutes, and will notify you according to your e-mail notification preferences. + documentation_link: Learn more + release_notes: Release notes + title: Available updates + type: Type + types: + major: Major release + minor: Minor release + patch: Patch release — bugfixes and easy to apply changes + version: Version statuses: account: Author application: Application @@ -765,7 +801,7 @@ en: remove_from_report: Remove from report report: Report deleted: Deleted - favourites: Favourites + favourites: Favorites history: Version history in_reply_to: Replying to language: Language @@ -792,9 +828,24 @@ en: suspend: "%{name} suspended %{target}'s account" appeal_approved: Appealed appeal_pending: Appeal pending + appeal_rejected: Appeal rejected system_checks: database_schema_check: message_html: There are pending database migrations. Please run them to ensure the application behaves as expected + elasticsearch_health_red: + message_html: Elasticsearch cluster is unhealthy (red status), search features are unavailable + elasticsearch_health_yellow: + message_html: Elasticsearch cluster is unhealthy (yellow status), you may want to investigate the reason + elasticsearch_index_mismatch: + message_html: Elasticsearch index mappings are outdated. Please run tootctl search deploy --only=%{value} + elasticsearch_preset: + action: See documentation + message_html: Your Elasticsearch cluster has more than one node, but Mastodon is not configured to use them. + elasticsearch_preset_single_node: + action: See documentation + message_html: Your Elasticsearch cluster has only one node, ES_PRESET should be set to single_node_cluster. + elasticsearch_reset_chewy: + message_html: Your Elasticsearch system index is outdated due to a setting change. Please run tootctl search deploy --reset-chewy to update it. elasticsearch_running_check: message_html: Could not connect to Elasticsearch. Please check that it is running, or disable full-text search elasticsearch_version_check: @@ -805,6 +856,12 @@ en: message_html: You haven't defined any server rules. sidekiq_process_check: message_html: No Sidekiq process running for the %{value} queue(s). Please review your Sidekiq configuration + software_version_critical_check: + action: See available updates + message_html: A critical Mastodon update is available, please update as quickly as possible. + software_version_patch_check: + action: See available updates + message_html: A bugfix Mastodon update is available. upload_check_privacy_error: action: Check here for more information message_html: "Your web server is misconfigured. The privacy of your users is at risk." @@ -833,6 +890,7 @@ en: other: Shared by %{count} people over the last week title: Trending links usage_comparison: Shared %{today} times today, compared to %{yesterday} yesterday + not_allowed_to_trend: Not allowed to trend only_allowed: Only allowed pending_review: Pending review preview_card_providers: @@ -844,14 +902,14 @@ en: statuses: allow: Allow post allow_account: Allow author - description_html: These are posts that your server knows about that are currently being shared and favourited a lot at the moment. It can help your new and returning users to find more people to follow. No posts are displayed publicly until you approve the author, and the author allows their account to be suggested to others. You can also allow or reject individual posts. + description_html: These are posts that your server knows about that are currently being shared and favorited a lot at the moment. It can help your new and returning users to find more people to follow. No posts are displayed publicly until you approve the author, and the author allows their account to be suggested to others. You can also allow or reject individual posts. disallow: Disallow post disallow_account: Disallow author no_status_selected: No trending posts were changed as none were selected not_discoverable: Author has not opted-in to being discoverable shared_by: - one: Shared or favourited one time - other: Shared and favourited %{friendly_count} times + one: Shared or favorited one time + other: Shared and favorited %{friendly_count} times title: Trending posts tags: current_score: Current score %{score} @@ -917,6 +975,9 @@ en: body: "%{target} is appealing a moderation decision by %{action_taken_by} from %{date}, which was %{type}. They wrote:" next_steps: You can approve the appeal to undo the moderation decision, or ignore it. subject: "%{username} is appealing a moderation decision on %{instance}" + new_critical_software_updates: + body: New critical versions of Mastodon have been released, you may want to update as soon as possible! + subject: Critical Mastodon updates are available for %{instance}! new_pending_account: body: The details of the new account are below. You can approve or reject this application. subject: New account up for review on %{instance} (%{username}) @@ -924,6 +985,9 @@ en: body: "%{reporter} has reported %{target}" body_remote: Someone from %{domain} has reported %{target} subject: New report for %{instance} (#%{id}) + new_software_updates: + body: New Mastodon versions have been released, you may want to update! + subject: New Mastodon versions are available for %{instance}! new_trends: body: 'The following items need a review before they can be displayed publicly:' new_trending_links: @@ -953,24 +1017,28 @@ en: guide_link: https://crowdin.com/project/mastodon guide_link_text: Everyone can contribute. sensitive_content: Sensitive content - toot_layout: Post layout application_mailer: notification_preferences: Change e-mail preferences salutation: "%{name}," settings: 'Change e-mail preferences: %{link}' + unsubscribe: Unsubscribe view: 'View:' view_profile: View profile view_status: View post applications: created: Application successfully created destroyed: Application successfully deleted + logout: Logout regenerate_token: Regenerate access token token_regenerated: Access token successfully regenerated warning: Be very careful with this data. Never share it with anyone! your_token: Your access token auth: apply_for_account: Request an account - change_password: Password + captcha_confirmation: + help_html: If you have issues solving the CAPTCHA, you can get in touch with us through %{email} and we can assist you. + hint_html: Just one more thing! We need to confirm you're a human (this is so we can keep the spam out!). Solve the CAPTCHA below and click "Continue". + title: Security check confirmations: wrong_email_hint: If that e-mail address is not correct, you can change it in account settings. delete_account: Delete account @@ -979,7 +1047,7 @@ en: prefix_invited_by_user: "@%{name} invites you to join this server of Mastodon!" prefix_sign_up: Sign up on Mastodon today! suffix: With an account, you will be able to follow people, post updates and exchange messages with users from any Mastodon server and more! - didnt_get_confirmation: Didn't receive confirmation instructions? + didnt_get_confirmation: Didn't receive a confirmation link? dont_have_your_security_key: Don't have your security key? forgot_password: Forgot your password? invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one. @@ -992,26 +1060,39 @@ en: migrate_account_html: If you wish to redirect this account to a different one, you can configure it here. or_log_in_with: Or log in with privacy_policy_agreement_html: I have read and agree to the privacy policy + progress: + confirm: Confirm e-mail + details: Your details + review: Our review + rules: Accept rules providers: cas: CAS saml: SAML register: Sign up registration_closed: "%{instance} is not accepting new members" - resend_confirmation: Resend confirmation instructions + resend_confirmation: Resend confirmation link reset_password: Reset password rules: + accept: Accept + back: Back + invited_by: 'You can join %{domain} thanks to the invitation you have received from:' preamble: These are set and enforced by the %{domain} moderators. + preamble_invited: Before you proceed, please consider the ground rules set by the moderators of %{domain}. title: Some ground rules. + title_invited: You've been invited. security: Security set_new_password: Set new password setup: - email_below_hint_html: If the below e-mail address is incorrect, you can change it here and receive a new confirmation e-mail. - email_settings_hint_html: The confirmation e-mail was sent to %{email}. If that e-mail address is not correct, you can change it in account settings. - title: Setup + email_below_hint_html: Check your spam folder, or request another one. You can correct your e-mail address if it's wrong. + email_settings_hint_html: Click the link we sent you to verify %{email}. We'll wait right here. + link_not_received: Didn't get a link? + new_confirmation_instructions_sent: You will receive a new e-mail with the confirmation link in a few minutes! + title: Check your inbox sign_in: - preamble_html: Sign in with your %{domain} credentials. If your account is hosted on a different server, you will not be able to log in here. - title: Sign in to %{domain} + preamble_html: Login with your %{domain} credentials. If your account is hosted on a different server, you will not be able to log in here. + title: Login to %{domain} sign_up: + manual_review: Sign-ups on %{domain} go through manual review by our moderators. To help us process your registration, write a bit about yourself and why you want an account on %{domain}. preamble: With an account on this Mastodon server, you'll be able to follow any other person on the network, regardless of where their account is hosted. title: Let's get you set up on %{domain}. status: @@ -1023,18 +1104,6 @@ en: view_strikes: View past strikes against your account too_fast: Form submitted too fast, try again. use_security_key: Use security key - authorize_follow: - already_following: You are already following this account - already_requested: You have already sent a follow request to that account - error: Unfortunately, there was an error looking up the remote account - follow: Follow - follow_request: 'You have sent a follow request to:' - following: 'Success! You are now following:' - post_follow: - close: Or, you can just close this window. - return: Show the user's profile - web: Go to web - title: Follow %{acct} challenge: confirm: Continue hint_html: "Tip: We won't ask you for your password again for the next hour." @@ -1111,6 +1180,10 @@ en: your_appeal_rejected: Your appeal has been rejected domain_validator: invalid_domain: is not a valid domain name + edit_profile: + basic_information: Basic information + hint_html: "Customize what people see on your public profile and next to your posts. Other people are more likely to follow you back and interact with you when you have a filled out profile and a profile picture." + other: Other errors: '400': The request you submitted was invalid or malformed. '403': You don't have permission to view this page. @@ -1122,9 +1195,9 @@ en: title: Security verification failed '429': Too many requests '500': - content: We're sorry, but something went wrong on our end. + content: We're sorry, but something went wrong on our end. You can check the status of Wobbl and its companion systems at our status page - https://status.wobbl.xyz. title: This page is not correct - '503': The page could not be served due to a temporary server failure. + '503': The page could not be served due to a temporary server failure. You can check the status of Wobbl and its companion systems at our status page - https://status.wobbl.xyz. noscript_html: To use the Mastodon web application, please enable JavaScript. Alternatively, try one of the native apps for Mastodon for your platform. existing_username_validator: not_found: could not find a local user with that username @@ -1147,8 +1220,8 @@ en: featured_tags: add_new: Add new errors: - limit: You have already featured the maximum amount of hashtags - hint_html: "What are featured hashtags? They are displayed prominently on your public profile and allow people to browse your public posts specifically under those hashtags. They are a great tool for keeping track of creative works or long-term projects." + limit: You have already featured the maximum number of hashtags + hint_html: "Feature your most important hashtags on your profile. A great tool for keeping track of your creative works and long-term projects, featured hashtags are displayed prominently on your profile and allow quick access to your own posts." filters: contexts: account: Profiles @@ -1191,8 +1264,6 @@ en: index: hint: This filter applies to select individual posts regardless of other criteria. You can add more posts to this filter from the web interface. title: Filtered posts - footer: - trending_now: Trending now generic: all: All all_items_on_page_selected_html: @@ -1201,7 +1272,9 @@ en: all_matching_items_selected_html: one: "%{count} item matching your search is selected." other: All %{count} items matching your search are selected. + cancel: Cancel changes_saved_msg: Changes successfully saved! + confirm: Confirm copy: Copy delete: Delete deselect: Deselect all @@ -1215,24 +1288,62 @@ en: validation_errors: one: Something isn't quite right yet! Please review the error below other: Something isn't quite right yet! Please review %{count} errors below - html_validator: - invalid_markup: 'contains invalid HTML markup: %{error}' imports: errors: + empty: Empty CSV file + incompatible_type: Incompatible with the selected import type invalid_csv_file: 'Invalid CSV file. Error: %{error}' over_rows_processing_limit: contains more than %{count} rows + too_large: File is too large + failures: Failures + imported: Imported + mismatched_types_warning: It appears you may have selected the wrong type for this import, please double-check. modes: merge: Merge merge_long: Keep existing records and add new ones overwrite: Overwrite overwrite_long: Replace current records with the new ones + overwrite_preambles: + blocking_html: You are about to replace your block list with up to %{total_items} accounts from %{filename}. + bookmarks_html: You are about to replace your bookmarks with up to %{total_items} posts from %{filename}. + domain_blocking_html: You are about to replace your domain block list with up to %{total_items} domains from %{filename}. + following_html: You are about to follow up to %{total_items} accounts from %{filename} and stop following anyone else. + lists_html: You are about to replace your lists with contents of %{filename}. Up to %{total_items} accounts will be added to new lists. + muting_html: You are about to replace your list of muted accounts with up to %{total_items} accounts from %{filename}. + preambles: + blocking_html: You are about to block up to %{total_items} accounts from %{filename}. + bookmarks_html: You are about to add up to %{total_items} posts from %{filename} to your bookmarks. + domain_blocking_html: You are about to block up to %{total_items} domains from %{filename}. + following_html: You are about to follow up to %{total_items} accounts from %{filename}. + lists_html: You are about to add up to %{total_items} accounts from %{filename} to your lists. New lists will be created if there is no list to add to. + muting_html: You are about to mute up to %{total_items} accounts from %{filename}. preface: You can import data that you have exported from another server, such as a list of the people you are following or blocking. + recent_imports: Recent imports + states: + finished: Finished + in_progress: In progress + scheduled: Scheduled + unconfirmed: Unconfirmed + status: Status success: Your data was successfully uploaded and will be processed in due time + time_started: Started at + titles: + blocking: Importing blocked accounts + bookmarks: Importing bookmarks + domain_blocking: Importing blocked domains + following: Importing followed accounts + lists: Importing lists + muting: Importing muted accounts + type: Import type + type_groups: + constructive: Follows & Bookmarks + destructive: Blocks & mutes types: blocking: Blocking list bookmarks: Bookmarks domain_blocking: Domain blocking list following: Following list + lists: Lists muting: Muting list upload: Upload invites: @@ -1259,7 +1370,7 @@ en: title: Invite people lists: errors: - limit: You have reached the maximum amount of lists + limit: You have reached the maximum number of lists login_activities: authentication_methods: otp: two-factor authentication app @@ -1271,6 +1382,21 @@ en: failed_sign_in_html: Failed sign-in attempt with %{method} from %{ip} (%{browser}) successful_sign_in_html: Successful sign-in with %{method} from %{ip} (%{browser}) title: Authentication history + mail_subscriptions: + unsubscribe: + action: Yes, unsubscribe + complete: Unsubscribed + confirmation_html: Are you sure you want to unsubscribe from receiving %{type} for Mastodon on %{domain} to your e-mail at %{email}? You can always re-subscribe from your e-mail notification settings. + emails: + notification_emails: + favourite: favorite notification e-mails + follow: follow notification e-mails + follow_request: follow request e-mails + mention: mention notification e-mails + reblog: boost notification e-mails + resubscribe_html: If you've unsubscribed by mistake, you can re-subscribe from your e-mail notification settings. + success_html: You'll no longer receive %{type} for Mastodon on %{domain} to your e-mail at %{email}. + title: Unsubscribe media_attachments: validations: images_and_video: Cannot attach a video to a post that already contains images @@ -1322,9 +1448,9 @@ en: sign_up: subject: "%{name} signed up" favourite: - body: 'Your post was favourited by %{name}:' - subject: "%{name} favourited your post" - title: New favourite + body: 'Your post was favorited by %{name}:' + subject: "%{name} favorited your post" + title: New favorite follow: body: "%{name} is now following you!" subject: "%{name} is now following you" @@ -1350,6 +1476,7 @@ en: update: subject: "%{name} edited a post" notifications: + administration_emails: Admin e-mail notifications email_events: Events for e-mail notifications email_events_hint: 'Select events that you want to receive notifications for:' other_settings: Other notifications settings @@ -1394,6 +1521,15 @@ en: other: Other posting_defaults: Posting defaults public_timelines: Public timelines + privacy: + hint_html: "Customize how you want your profile and your posts to be found. A variety of features in Mastodon can help you reach a wider audience when enabled. Take a moment to review these settings to make sure they fit your use case." + privacy: Privacy + privacy_hint_html: Control how much you want to disclose for the benefit of others. People discover interesting profiles and cool apps by browsing other people's follows and seeing which apps they post from, but you may prefer to keep it hidden. + reach: Reach + reach_hint_html: Control whether you want to be discovered and followed by new people. Do you want your posts to appear on the Explore screen? Do you want other people to see you in their follow recommendations? Do you want to accept all new followers automatically, or have granular control over each one? + search: Search + search_hint_html: Control how you want to be found. Do you want people to find you by what you've publicly posted about? Do you want people outside Mastodon to find your profile when searching the web? Please mind that total exclusion from all search engines cannot be guaranteed for public information. + title: Privacy and reach privacy_policy: title: Privacy Policy reactions: @@ -1446,6 +1582,7 @@ en: electron: Electron firefox: Firefox generic: Unknown browser + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1455,6 +1592,7 @@ en: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Unknown Browser weibo: Weibo current_session: Current session description: "%{browser} on %{platform}" @@ -1467,9 +1605,10 @@ en: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: unknown platform + unknown_platform: Unknown Platform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1494,7 +1633,7 @@ en: migrate: Account migration notifications: Notifications preferences: Preferences - profile: Profile + profile: Public profile relationships: Follows and followers statuses_cleanup: Automated post deletion strikes: Moderation strikes @@ -1540,7 +1679,6 @@ en: show_newer: Show newer show_older: Show older show_thread: Show thread - sign_in_to_participate: Sign in to participate in the conversation title: '%{name}: "%{quote}"' visibilities: direct: Direct @@ -1555,10 +1693,10 @@ en: enabled_hint: Automatically deletes your posts once they reach a specified age threshold, unless they match one of the exceptions below exceptions: Exceptions explanation: Because deleting posts is an expensive operation, this is done slowly over time when the server is not otherwise busy. For this reason, your posts may be deleted a while after they reach the age threshold. - ignore_favs: Ignore favourites + ignore_favs: Ignore favorites ignore_reblogs: Ignore boosts interaction_exceptions: Exceptions based on interactions - interaction_exceptions_explanation: Note that there is no guarantee for posts to be deleted if they go below the favourite or boost threshold after having once gone over them. + interaction_exceptions_explanation: Note that there is no guarantee for posts to be deleted if they go below the favorite or boost threshold after having once gone over them. keep_direct: Keep direct messages keep_direct_hint: Doesn't delete any of your direct messages keep_media: Keep posts with media attachments @@ -1569,8 +1707,8 @@ en: keep_polls_hint: Doesn't delete any of your polls keep_self_bookmark: Keep posts you bookmarked keep_self_bookmark_hint: Doesn't delete your own posts if you have bookmarked them - keep_self_fav: Keep posts you favourited - keep_self_fav_hint: Doesn't delete your own posts if you have favourited them + keep_self_fav: Keep posts you favorited + keep_self_fav_hint: Doesn't delete your own posts if you have favorited them min_age: '1209600': 2 weeks '15778476': 6 months @@ -1581,13 +1719,11 @@ en: '63113904': 2 years '7889238': 3 months min_age_label: Age threshold - min_favs: Keep posts favourited at least - min_favs_hint: Doesn't delete any of your posts that has received at least this amount of favourites. Leave blank to delete posts regardless of their number of favourites + min_favs: Keep posts favorited at least + min_favs_hint: Doesn't delete any of your posts that has received at least this number of favorites. Leave blank to delete posts regardless of their number of favorites min_reblogs: Keep posts boosted at least min_reblogs_hint: Doesn't delete any of your posts that has been boosted at least this number of times. Leave blank to delete posts regardless of their number of boosts stream_entries: - pinned: Pinned post - reblogged: boosted sensitive_content: Sensitive content strikes: errors: @@ -1596,19 +1732,18 @@ en: does_not_match_previous_name: does not match the previous name themes: contrast: Mastodon (High contrast) - dark: Mastodon (Dark) + default: Mastodon (Dark) mastodon-light: Mastodon (Light) - wobbl: Mastodon (Dark - Wobbl theme) - wobbl-light: Mastodon (Light - Wobbl theme) - modern-dark: Modern (Dark) - modern-light: Modern (Light) - modern-light-wobbl: Modern (Light - Wobbl theme) - default: Modern (Dark - Wobbl theme) (Default) time: formats: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: The server-wide usage quota for the translation service has been exceeded. + too_many_requests: There have been too many requests to the translation service recently. two_factor_authentication: add: Add disable: Disable 2FA @@ -1688,13 +1823,18 @@ en: title: Welcome aboard, %{name}! users: follow_limit_reached: You cannot follow more than %{limit} people + go_to_sso_account_settings: Go to your identity provider's account settings invalid_otp_token: Invalid two-factor code otp_lost_help_html: If you lost access to both, you may get in touch with %{email} seamless_external_login: You are logged in via an external service, so password and e-mail settings are not available. signed_in_as: 'Signed in as:' verification: - explanation_html: 'You can verify yourself as the owner of the links in your profile metadata. For that, the linked website must contain a link back to your Mastodon profile. The link back must have a rel="me" attribute. The text content of the link does not matter. Here is an example:' + extra_instructions_html: Tip: The link on your website can be invisible. The important part is rel="me" which prevents impersonation on websites with user-generated content. You can even use a link tag in the header of the page instead of a, but the HTML must be accessible without executing JavaScript. + here_is_how: Here's how + hint_html: "Verifying your identity on Mastodon is for everyone. Based on open web standards, now and forever free. All you need is a personal website that people recognize you by. When you link to this website from your profile, we will check that the website links back to your profile and show a visual indicator on it." + instructions_html: Copy and paste the code below into the HTML of your website. Then add the address of your website into one of the extra fields on your profile from the "Edit profile" tab and save changes. verification: Verification + verified_links: Your verified links webauthn_credentials: add: Add new security key create: diff --git a/config/locales/eo.yml b/config/locales/eo.yml index ce532d6029..066899995f 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -38,14 +38,14 @@ eo: avatar: Profilbildo by_domain: Domajno change_email: - changed_msg: Retpoŝta adreso estis sukcese ŝanĝita! + changed_msg: Retpoŝta adreso sukcese ŝanĝita! current_email: Nuna retadreso label: Ŝanĝi retadreson new_email: Nova retadreso submit: Ŝanĝi retadreson title: Ŝanĝi retadreson por %{username} change_role: - changed_msg: Rolo estis sukcese ŝanĝita! + changed_msg: Rolo sukcese ŝanĝita! label: Ŝanĝi rolon no_role: Neniu rolo title: Ŝanĝi rolon por %{username} @@ -91,6 +91,7 @@ eo: moderation: active: Aktivaj all: Ĉio + disabled: Neebligita pending: Pritraktata silenced: Limigita suspended: Suspendita @@ -113,7 +114,7 @@ eo: public: Publika push_subscription_expires: Eksvalidiĝo de la abono al PuSH redownload: Aktualigi profilon - redownloaded_msg: Sukcese refreŝis profilon de %{username} de origino + redownloaded_msg: Sukcese aktualigis profilon de %{username} el origino reject: Malakcepti rejected_msg: Sukcese malaprobis aliĝ-peton de %{username} remote_suspension_irreversible: La informoj de ĉi tiu konto estis neinversigeble forigitaj. @@ -121,11 +122,11 @@ eo: remove_avatar: Forigi la profilbildon remove_header: Forigi kapan bildon removed_avatar_msg: La rolfiguro de %{username} estas sukcese forigita - removed_header_msg: Sukcese forigis kapbildon de %{username} + removed_header_msg: Kapbildo de %{username} suksece forigita resend_confirmation: already_confirmed: Ĉi tiu uzanto jam estas konfirmita - send: Resendi konfirman retpoŝton - success: Konfirma retpoŝto estis sukcese sendita! + send: Resendi la ligilon de konfirmo + success: Konfirma ligilo estis sukcese sendita! reset: Restarigi reset_password: Restarigi pasvorton resubscribe: Reaboni @@ -133,6 +134,7 @@ eo: search: Serĉi search_same_email_domain: Aliaj uzantoj kun la sama domajno de retpoŝto search_same_ip: Aliaj uzantoj kun la sama IP + security: Sekureco security_measures: only_password: Nur pasvorto password_and_2fa: Pasvorto kaj 2FA @@ -149,7 +151,7 @@ eo: subscribe: Aboni suspend: Haltigu suspended: Suspendita - suspension_irreversible: La datumoj de ĉi tiu konto neinverseble forigitas. + suspension_irreversible: La datumoj de ĉi tiu konto estas porĉiame forigitaj. Vi povas malsuspendi tiun konton por igi ĝin uzebla, sed ĝi ne rehavos ajnan datumon kiun ĝi antaŭe havis. suspension_reversible_hint_html: La konto estas suspendita, kaj la datumoj estos komplete forigitaj je %{date}. Ĝis tiam, la konto povas esti malsuspendita sen flankefiko. Se vi deziras tuj forigi ĉiujn datumojn de la konto, vi povas fari tion sube. title: Kontoj unblock_email: Malbloki retpoŝtadresojn @@ -227,7 +229,7 @@ eo: update_status: Ĝisdatigi afiŝon update_user_role: Ĝisdatigi rolon actions: - approve_appeal_html: "%{name} aprobis kontroldecidapelacion de %{target}" + approve_appeal_html: "%{name} aprobis apelacion kontraŭ moderiga decido de %{target}" approve_user_html: "%{name} aprobis registriĝon de %{target}" assigned_to_self_report_html: "%{name} asignis signalon %{target} al si mem" change_email_user_html: "%{name} ŝanĝis retadreson de uzanto %{target}" @@ -253,7 +255,7 @@ eo: destroy_instance_html: "%{name} forigis domajnon %{target}" destroy_ip_block_html: "%{name} forigis regulon por IP %{target}" destroy_status_html: "%{name} forigis mesaĝojn de %{target}" - destroy_unavailable_domain_html: "%{name} daurigis sendon al domajno %{target}" + destroy_unavailable_domain_html: "%{name} restartigis sendon al domajno %{target}" destroy_user_role_html: "%{name} forigis rolon de %{target}" disable_2fa_user_html: "%{name} malebligis dufaktoran aŭtentigon por uzanto %{target}" disable_custom_emoji_html: "%{name} malebligis la emoĝion %{target}" @@ -264,20 +266,20 @@ eo: enable_user_html: "%{name} ebligis ensaluton por uzanto %{target}" memorialize_account_html: "%{name} ŝanĝis la konton de %{target} al memora paĝo" promote_user_html: "%{name} plirangigis uzanton %{target}" - reject_appeal_html: "%{name} malakceptis kontroldecidapelacion de %{target}" + reject_appeal_html: "%{name} malakceptis apelacion kontraŭ moderiga decido de %{target}" reject_user_html: "%{name} malakceptis registriĝon de %{target}" remove_avatar_user_html: "%{name} forigis la profilbildon de %{target}" reopen_report_html: "%{name} remalfermis signalon %{target}" resend_user_html: "%{name} resendis konfirman retmesaĝon por %{target}" reset_password_user_html: "%{name} restarigis la pasvorton de la uzanto %{target}" resolve_report_html: "%{name} solvis raporton %{target}" - sensitive_account_html: "%{name} markis audovidaĵojn de %{target} kiel sentemaj" + sensitive_account_html: "%{name} markis audovidaĵon de %{target} kiel tiklan" silence_account_html: "%{name} limigis la konton de %{target}" suspend_account_html: "%{name} suspendis la konton de %{target}" unassigned_report_html: "%{name} malasignis raporton %{target}" unblock_email_account_html: "%{name} malblokis retpoŝtoadreson de %{target}" - unsensitive_account_html: "%{name} malmarkis audovidaĵojn de %{target} kiel sentemaj" - unsilence_account_html: "%{name} malfaris limon de konto de %{target}" + unsensitive_account_html: "%{name} malmarkis audovidaĵon de %{target} kiel tiklan" + unsilence_account_html: "%{name} malfaris limon al konto de %{target}" unsuspend_account_html: "%{name} malsuspendis la konton de %{target}" update_announcement_html: "%{name} ĝisdatigis la anoncon %{target}" update_custom_emoji_html: "%{name} ĝisdatigis la emoĝion %{target}" @@ -323,13 +325,13 @@ eo: emoji: Emoĝio enable: Ebligi enabled: Ebligita - enabled_msg: Tiu emoĝio estis sukcese ebligita + enabled_msg: Emoĝio sukcese ebligita image_hint: PNG aŭ GIF malpli granda ol %{size} list: Listo listed: Listigita new: title: Aldoni novan propran emoĝion - no_emoji_selected: Neniuj emoĝioj ŝanĝitas ĉar nenio elektitas + no_emoji_selected: Neniu emoĝio estis ŝanĝita ĉar neniu estis elektita not_permitted: Vi ne rajtas plenumi ĉi tiun agon overwrite: Anstataŭigi shortcode: Mallonga kodo @@ -348,17 +350,17 @@ eo: new_users: novaj uzantoj opened_reports: raportoj malfermitaj pending_appeals_html: - one: "%{count} restanta apelacio" - other: "%{count} restantaj aplecioj" + one: "%{count} apelacio atendas kontrolon" + other: "%{count} apelacioj atendas kontrolon" pending_reports_html: - one: "%{count} restanta raporto" - other: "%{count} restantaj raportoj" + one: "%{count} raporto atendas kontrolon" + other: "%{count} raportoj atendas kontrolon" pending_tags_html: one: "%{count} pritraktota kradvorto" other: "%{count} pritraktotaj kradvortoj" pending_users_html: - one: "%{count} restanta uzanto" - other: "%{count} restantaj uzantoj" + one: "%{count} uzanto atendas kontrolon" + other: "%{count} uzantoj atendas kontrolon" resolved_reports: raportoj solvitaj software: Programo sources: Fontoj de konto-kreado @@ -373,13 +375,22 @@ eo: title: Apelacioj domain_allows: add_new: Aldoni domajnon al la blanka listo - created_msg: Domajno estis sukcese aldonita al la blanka listo + created_msg: Domajno sukcese permesita al federacii destroyed_msg: Domajno estis forigita el la blanka listo export: Eksporti import: Enporti undo: Forigi el la blanka listo domain_blocks: add_new: Aldoni novan blokadon de domajno + confirm_suspension: + cancel: Nuligi + confirm: Haltigi + permanent_action: Malfari la suspendon restarigos neniun datumon aŭ rilaton. + preamble_html: Vi estas suspendonta %{domain} kaj ĝiajn subdomajnojn. + remove_all_data: Tio forigos ĉiujn enhavojn, amaskomunikilarojn kaj profilajn datumojn por la kontoj de ĉi tiu domajno de via servilo. + stop_communication: Via servilo haltos komuniki kun tiuj serviloj. + title: Konfirmu domajnan blokon por %{domain} + undo_relationships: Ĉi tio malfaros ajnan sekvan rilaton inter kontoj de ĉi tiuj serviloj kaj viaj. created_msg: Domajna blokado en traktado destroyed_msg: Domajna blokado malfarita domain: Domajno @@ -427,6 +438,7 @@ eo: resolve: Solvi domajnon title: Nova blokado de retadresa domajno no_email_domain_block_selected: Neniuj retpoŝtoadresodomajnblokoj ŝanĝitas ĉar nenio elektitas + not_permitted: Ne permesita resolved_dns_records_hint_html: La domajnnomo referencas al la MX-domajnoj kiuj akceptas retpoŝton. Ne bloku grandajn retpoŝtoservilojn. resolved_through_html: Solvis tra %{domain} title: Nigra listo de retadresaj domajnoj @@ -473,6 +485,7 @@ eo: content_policies: comment: Interna noto description_html: Vi povas difini enhavopolitikojn al la ĉiuj kontoj. + limited_federation_mode_description_html: Vi povas elekti, ĉu permesi federacion kun tiu domajno. policies: reject_media: Malakcepti plurmediojn reject_reports: Malakcepti raportojn @@ -585,11 +598,13 @@ eo: assign_to_self: Asigni al mi assigned: Asignita kontrolanto by_target_domain: Domajno de la signalita konto + cancel: Nuligi category: Kategorio category_description_html: La kialo pri ĉi tiuj konto kaj enhavo raportitaj sendotas al la raportita konto comment: none: Nenio comment_description_html: 'Por doni pli da informo, %{name} skribis:' + confirm: Konfirmi confirm_action: Konfirmi moderigadagon kontra @%{acct} created_at: Signalita delete_and_resolve: Forigi afiŝojn @@ -725,6 +740,9 @@ eo: branding: preamble: Via markeco de servilo malsamigas ĝin de aliaj servilojn en la reto. Do, la informo devus esti simpla kaj mallonga. title: Markeco + captcha_enabled: + desc_html: Ĉi tio dependas de eksteraj hCaptcha-skriptoj, kiuj povas esti problemo pri sekureco kaj privateco. Ankaŭ, ĝi povas igi la registran procezon multe malpli alirebla por iuj homoj (precipe homoj kun handikapoj). Pro ĉi tiuj kialoj, bonvolu konsideri alternativajn rimedojn kiel registradon per aprobo aŭ per invito. + title: Postuli novajn uzantojn solvi CAPTCHA por konfirmi sian konton content_retention: preamble: Regi kiel uzantogenerita enhavo konservitis en Mastodon. title: Enhavkonservo @@ -752,7 +770,6 @@ eo: approved: Bezonas aprobi por aliĝi none: Neniu povas aliĝi open: Iu povas aliĝi - title: Agordoj de la servilo site_uploads: delete: Forigi elŝutitan dosieron destroyed_msg: Reteja alŝuto sukcese forigita! @@ -792,6 +809,7 @@ eo: suspend: "%{name} suspendis la konton de %{target}" appeal_approved: Apelaciita appeal_pending: Apelacio pritraktiĝos + appeal_rejected: Apelacio malakceptita system_checks: database_schema_check: message_html: Estas pritraktataj datumbazaj migradoj. Bonvolu ekzekuti ilin por certigi, ke la apliko kondutas kiel atendite @@ -805,6 +823,12 @@ eo: message_html: Vi ne difinis iujn servilajn regulojn. sidekiq_process_check: message_html: Neniu Sidekiq-procezo por la %{value} vico + upload_check_privacy_error: + action: Klaku ĉi tie por pliaj informoj + message_html: "Via retservilo estas misagordita. La privateco de viaj uzantoj estas en risko." + upload_check_privacy_error_object_storage: + action: Klaku ĉi tie por pliaj informoj + message_html: "Via objektostokado estas misagordita. La privateco de viaj uzantoj estas en risko." tags: review: La statuso de la recenzo updated_msg: Kradvorto agordoj ĝisdatigis sukcese @@ -827,6 +851,7 @@ eo: other: Diskonita de %{count} personoj ekde lasta semajno title: Tendencantaj ligiloj usage_comparison: Diskonita %{today}-foje hodiau, sed estas %{yesterday} hierau + not_allowed_to_trend: Ne rajtas fariĝi furoraĵo only_allowed: Nur permesitas pending_review: Atendante revizion preview_card_providers: @@ -947,24 +972,27 @@ eo: guide_link: https://crowdin.com/project/mastodon guide_link_text: Ĉiu povas kontribui. sensitive_content: Tikla enhavo - toot_layout: Mesaĝo aranĝo application_mailer: notification_preferences: Ŝanĝi retmesaĝajn preferojn salutation: "%{name}," settings: 'Ŝanĝi retmesaĝajn preferojn: %{link}' + unsubscribe: Malabonu view: 'Vidi:' view_profile: Vidi profilon view_status: Vidi mesaĝon applications: created: Aplikaĵo sukcese kreita destroyed: Aplikaĵo sukcese forigita + logout: Elsaluti regenerate_token: Regeneri aliran ĵetonon token_regenerated: Alira ĵetono sukcese regeneria warning: Estu tre atenta kun ĉi tiu datumo. Neniam diskonigu ĝin al iu ajn! your_token: Via alira ĵetono auth: apply_for_account: Peti konton - change_password: Pasvorto + captcha_confirmation: + help_html: Se vi havas problemojn solvi la CAPTCHA, vi povas kontakti nin per %{email} kaj ni povas helpi vin. + title: Sekureckontrolo confirmations: wrong_email_hint: Se tiu retpoŝtadreso ne estas ĝusta, vi povas ŝanĝi ĝin en la agordoj pri la konto. delete_account: Forigi konton @@ -973,35 +1001,46 @@ eo: prefix_invited_by_user: "@%{name} invitigi vin aligiĝi ĉi tiu servilo de Mastodon!" prefix_sign_up: Registriĝu en Mastodon hodiaŭ! suffix: Per konto, vi povos sekvi aliajn homojn, afiŝi kaj interŝanĝi mesaĝojn kun uzantoj de ajna Mastodona servilo kaj multe pli! - didnt_get_confirmation: Ĉu vi ne ricevis la instrukciojn por konfirmi? + didnt_get_confirmation: Ĉu vi ne ricevis konfirman ligilon? dont_have_your_security_key: Ne havas vi vian sekurecan ŝlosilon? forgot_password: Pasvorto forgesita? invalid_reset_password_token: La ĵetono por restarigi la pasvorton estas nevalida aŭ eksvalida. Bonvolu peti novon. link_to_otp: Enigu 2-faktorkodo de via telefono au regajnkodo link_to_webauth: Uzi vian sekurecan ŝlosilon log_in_with: Ensaluti per - login: Saluti + login: Ensaluti logout: Adiaŭi migrate_account: Movi al alia konto migrate_account_html: Se vi deziras alidirekti ĉi tiun konton al alia, vi povas agordi ĝin ĉi tie. or_log_in_with: Aŭ saluti per privacy_policy_agreement_html: Mi legis kaj konsentis pri privatpolitiko + progress: + confirm: Konfirmi retpoŝtadreson + details: Viaj detaloj + review: Niaj recenzoj + rules: Akcepti regulojn providers: cas: CAS saml: SAML register: Krei konton registration_closed: "%{instance} ne estas akcepti nova uzantojn" - resend_confirmation: Resendi la instrukciojn por konfirmi + resend_confirmation: Resendu konfirman ligilon reset_password: Restarigi pasvorton rules: + accept: Akcepti + back: Reen + invited_by: 'Vi povas aliĝi al %{domain} danke al la invito, kiun vi ricevis de:' preamble: Ĉi tioj fiksitas kaj devigitas de kontrolantoj de %{domain}. + preamble_invited: Antaŭ ol daŭrigi, bonvolu konsideri la bazajn regulojn fiksitajn de la moderigaĵoj de %{domain}. title: Bazaj reguloj. + title_invited: Vi estis invitita. security: Sekureco set_new_password: Elekti novan pasvorton setup: - email_below_hint_html: Se malsupra retpoŝtoadreso estas neĝusta, vi povas ŝanĝi ĉi tie kaj ricevi novan konfirmretpoŝton. - email_settings_hint_html: La konfirmretpoŝto senditas al %{email}. - title: Agordi + email_below_hint_html: Kontrolu vian spam-dosierujon aŭ petu novan ligon. Se necese, vi povas korekti vian retadreson. + link_not_received: Ĉu vi ne ricevis ligilon? + new_confirmation_instructions_sent: Vi devus ricevi novan retpoŝton kun la konfirma ligilo post kelkaj minutoj! + title: Kontrolu vian retpoŝta enirkesto sign_in: preamble_html: Ensalutu per via detaloj de %{domain}. Se via konto gastigantigas sur malsama servilo, vi ne povas ensaluti ĉi tie. title: Saluti en %{domain} @@ -1012,23 +1051,11 @@ eo: account_status: Statuso de la konto confirming: Retpoŝtokonfirmo bezonas kompletigitis. functional: Via konto estas tute funkcia. - pending: Via apliko ankarou bezonas kontrolon de nia teamo. Vi ricevos retpoŝto malantau ol aprobo. + pending: Via aliĝo estos kontrolita de nia teamo. Tio povas bezoni iom da tempo. Vi ricevos retpoŝtmesaĝon se via aliĝo estas aprobita. redirecting_to: Via konto estas neaktiva ĉar ĝi nun alidirektas al %{acct}. view_strikes: Vidi antauaj admonoj kontra via konto too_fast: Formularo sendita tro rapide, klopodu denove. use_security_key: Uzi sekurecan ŝlosilon - authorize_follow: - already_following: Vi jam sekvas tiun konton - already_requested: Vi jam sendis peton de sekvado al ĉi tiu konto - error: Bedaŭrinde, estis eraro en la serĉado de la fora konto - follow: Sekvi - follow_request: 'Vi sendis peton de sekvado al:' - following: 'Sukceson! Vi nun sekvas:' - post_follow: - close: Aŭ, vi povas simple fermi ĉi tiun fenestron. - return: Montri la profilon de la uzanto - web: Iri al reto - title: Sekvi %{acct} challenge: confirm: Daŭrigi hint_html: "Konsileto: Ni ne demandos pri via pasvorto ĝis 1 horo." @@ -1105,6 +1132,9 @@ eo: your_appeal_rejected: Via apelacio malakceptitas domain_validator: invalid_domain: ne estas valida domajna nomo + edit_profile: + basic_information: Baza informo + other: Alia errors: '400': La peto kiun vi sendis estas nevalida au malformas. '403': Vi ne havas la rajton por vidi ĉi tiun paĝon. @@ -1187,8 +1217,6 @@ eo: index: hint: Ĉi tiu filtrilo kongruas kelkaj mesaĝoj sendepende de aliaj kriterioj. title: Filtritaj mesaĝoj - footer: - trending_now: Nunaj furoraĵoj generic: all: Ĉio all_items_on_page_selected_html: @@ -1197,7 +1225,9 @@ eo: all_matching_items_selected_html: one: "%{count} ero kiu kongruas vian serĉon elektitas." other: "%{count} eroj kiuj kongruas vian serĉon elektitas." + cancel: Nuligi changes_saved_msg: Ŝanĝoj sukcese konservitaj! + confirm: Konfirmi copy: Kopii delete: Forigi deselect: Malelekti ĉiujn @@ -1211,12 +1241,16 @@ eo: validation_errors: one: Io mise okazis! Bonvolu konsulti la suban erar-raporton other: Io mise okazis! Bonvolu konsulti la subajn %{count} erar-raportojn - html_validator: - invalid_markup: 'havas nevalidan HTML-markadon: %{error}' imports: errors: + empty: Malpena CSV-dosiero + incompatible_type: Nekongrua kun la elektita importotipo invalid_csv_file: Nevalida CSV-dosiero. %{error} over_rows_processing_limit: enhavas pli ol %{count} vicoj + too_large: La dosiero estas tro larĝa + failures: Malsukcesoj + imported: Importitaj + mismatched_types_warning: Ŝajnas, ke vi eble elektis la malĝustan tipon por ĉi tiu importo, bonvolu denove kontroli. modes: merge: Kunigi merge_long: Konservi ekzistajn registrojn kaj aldoni novajn @@ -1267,6 +1301,9 @@ eo: failed_sign_in_html: Malsukcese ensalutprovo per %{method} de %{ip} (%{browser}) successful_sign_in_html: Sukcese ensaluto per %{method} de %{ip} (%{browser}) title: Aŭtentiga historio + mail_subscriptions: + unsubscribe: + title: Malaboni media_attachments: validations: images_and_video: Aldoni videon al mesaĝo, kiu jam havas bildojn ne eblas @@ -1318,8 +1355,8 @@ eo: sign_up: subject: "%{name} registriĝis" favourite: - body: "%{name} stelumis vian mesaĝon:" - subject: "%{name} stelumis vian mesaĝon" + body: "%{name} stelumis vian afiŝon:" + subject: "%{name} stelumis vian afiŝon" title: Nova stelumo follow: body: "%{name} nun sekvas vin!" @@ -1339,10 +1376,10 @@ eo: subject: Enketo de %{name} finitas reblog: body: 'Via mesaĝo estis diskonigita de %{name}:' - subject: "%{name} diskonigis vian mesaĝon" + subject: "%{name} diskonigis vian afiŝon" title: Nova diskonigo status: - subject: "%{name} ĵus afiŝita" + subject: "%{name} ĵus afiŝis" update: subject: "%{name} redaktis afiŝon" notifications: @@ -1388,6 +1425,8 @@ eo: other: Aliaj aferoj posting_defaults: Afiŝaj defaŭltoj public_timelines: Publikaj templinioj + privacy: + privacy: Privateco privacy_policy: title: Privateca politiko reactions: @@ -1400,6 +1439,7 @@ eo: confirm_remove_selected_followers: Ĉu vi certas, ke vi volas forigi la elektitajn sekvantojn? confirm_remove_selected_follows: Ĉu vi certas, ke vi volas forigi la elektitajn sekvatojn? dormant: Dormanta + follow_failure: Ne eblis sekvi iom da la elektitaj kontoj. follow_selected_followers: Sekvi selektitajn sekvantojn followers: Sekvantoj following: Sekvatoj @@ -1439,6 +1479,7 @@ eo: electron: Electron firefox: Firefox generic: Nekonata retumilo + huawei_browser: Retumilo Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1448,6 +1489,7 @@ eo: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Nekonata retumilo weibo: Weibo current_session: Nuna seanco description: "%{browser} en %{platform}" @@ -1460,9 +1502,10 @@ eo: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: nekonata substrato + unknown_platform: Nekonata platformo windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1533,7 +1576,6 @@ eo: show_newer: Montri pli novajn show_older: Montri pli malnovajn show_thread: Montri la mesaĝaron - sign_in_to_participate: Ensalutu por partopreni la konversacion title: "%{name}: “%{quote}”" visibilities: direct: Rekta @@ -1575,12 +1617,10 @@ eo: '7889238': 3 monatoj min_age_label: Aĝlimo min_favs: Konservi mesaĝojn stelumitajn almenaŭ - min_favs_hint: Ne forigas mesaĝojn de vi kiuj ricevis almenaŭ tiom da stelumoj. Lasu malplena por forigi mesaĝojn sendepende de la nombro de stelumoj + min_favs_hint: Oni ne forigas viajn afiŝojn, kiuj estas diskonigitaj almenaŭ ĉi tiun nombron da fojoj. Lasu malplena por forigi afiŝojn sendepende de iliaj nombroj da diskonigoj min_reblogs: Konservi diskonitajn mesaĝojn almenau min_reblogs_hint: Oni ne forigas viajn afiŝojn kiuj estas diskonigitaj almenaŭ ĉi tiun nombron da fojoj. Lasu malplena por forigi afiŝojn sendepende de iliaj nombroj da diskonigoj stream_entries: - pinned: Fiksita afiŝo - reblogged: diskonigita sensitive_content: Tikla enhavo strikes: errors: @@ -1680,8 +1720,8 @@ eo: seamless_external_login: Vi estas ensalutinta per ekstera servo, do pasvortaj kaj retadresaj agordoj ne estas disponeblaj. signed_in_as: 'Salutinta kiel:' verification: - explanation_html: 'Vi povas pruvi, ke vi estas la posedanto de la ligiloj en viaj profilaj metadatumoj. Por fari tion, la alligita retejo devas enhavi ligilon reen al via Mastodon-profilo. La religilo devas havi la atributon rel="me". Ne gravas la teksta enhavo de la religilo. Jen ekzemplo:' verification: Kontrolo + verified_links: Via kontrolitaj ligiloj webauthn_credentials: add: Aldoni novan sekurecan ŝlosilon create: @@ -1695,7 +1735,7 @@ eo: success: Via sekureca ŝlosilo estis sukcese forigita. invalid_credential: Nevalida sekureca ŝlosilo nickname_hint: Enigu alinomon de via nova sekurecŝlosilo - not_enabled: Vu ne ebligas WebAuthn ĝis nun + not_enabled: Vi ankoraŭ ne ŝaltis WebAuth not_supported: Ĉi tiu legilo ne povas uzi sekurecŝlosilojn otp_required: Por uzi sekurecŝlosilojn, ebligu 2-faktoran autentigon unue. registered_on: Registrigita je %{date} diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 9b0ab12cce..8357c31490 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -91,6 +91,7 @@ es-AR: moderation: active: Activas all: Todas + disabled: Deshabilitadas pending: Pendientes silenced: Limitada suspended: Suspendidas @@ -124,8 +125,8 @@ es-AR: removed_header_msg: Se quitó exitosamente la cabecera de %{username} resend_confirmation: already_confirmed: Este usuario ya está confirmado - send: Reenviar correo electrónico de confirmación - success: "¡Correo electrónico de confirmación enviado exitosamente!" + send: Reenviar enlace de confirmación + success: "¡Enlace de confirmación enviado exitosamente!" reset: Restablecer reset_password: Cambiar contraseña resubscribe: Resuscribir @@ -133,6 +134,7 @@ es-AR: search: Buscar search_same_email_domain: Otros usuarios con el mismo dominio de correo electrónico search_same_ip: Otros usuarios con la misma dirección IP + security: Seguridad security_measures: only_password: Sólo contraseña password_and_2fa: Contraseña y 2FA @@ -307,6 +309,7 @@ es-AR: unpublish: Eliminar publicación unpublished_msg: "¡Se dejó de publicar el anuncio exitosamente!" updated_msg: "¡Anuncio actualizado exitosamente!" + critical_update_pending: Actualización crítica pendiente custom_emojis: assign_category: Asignar categoría by_domain: Dominio @@ -380,6 +383,15 @@ es-AR: undo: No permitir federación con el dominio domain_blocks: add_new: Agregar nuevo bloqueo de dominio + confirm_suspension: + cancel: Cancelar + confirm: Suspender + permanent_action: Deshacer la suspensión no recuperará ningún dato ni relación (seguidores y en seguimiento). + preamble_html: Estás a punto de suspender a %{domain} y sus subdominios. + remove_all_data: Esto eliminará todo el contenido, medios y datos de perfil de las cuentas de este dominio en tu servidor. + stop_communication: Tu servidor dejará de comunicarse con estos servidores. + title: Confirmar bloqueo del dominio para %{domain} + undo_relationships: Esto deshará cualquier relación (seguidores y en seguimiento) entre las cuentas de estos servidores y el tuyo. created_msg: Ahora se está procesando el bloqueo de dominio destroyed_msg: Se deshizo el bloqueo de dominio domain: Dominio @@ -427,6 +439,7 @@ es-AR: resolve: Resolver dominio title: Bloquear nuevo dominio de correo electrónico no_email_domain_block_selected: No se cambiaron bloques de dominio ya que no se seleccionó ninguno + not_permitted: No permitidos resolved_dns_records_hint_html: El nombre de dominio resuelve los siguientes dominios MX, los cuales son responsables en última instancia de aceptar el correo electrónico. Bloquear un dominio MX bloqueará los registros de cualquier dirección de correo electrónico que utilice el mismo dominio MX, incluso si el nombre de dominio visible es diferente. Tené cuidado de no bloquear los principales proveedores de correo electrónico. resolved_through_html: Resuelto a través de %{domain} title: Dominios bloqueados de correo electrónico @@ -473,6 +486,7 @@ es-AR: content_policies: comment: Nota interna description_html: Podés definir políticas de contenido que se aplicarán a todas las cuentas de este dominio y a cualquiera de sus subdominios. + limited_federation_mode_description_html: Podés elegir si permit´s la federación con este dominio. policies: reject_media: Rechazar medios reject_reports: Rechazar denuncias @@ -585,11 +599,13 @@ es-AR: assign_to_self: Asignármela a mí assigned: Moderador asignado by_target_domain: Dominio de la cuenta denunciada + cancel: Cancelar category: Categoría category_description_html: El motivo por el que se denunció esta cuenta o contenido será citado en las comunicaciones con la cuenta denunciada comment: none: Ninguno comment_description_html: 'Para proporcionar más información, %{name} escribió:' + confirm: Confirmar confirm_action: Confirmar acción de moderación contra @%{acct} created_at: Denunciado delete_and_resolve: Eliminar mensajes @@ -635,7 +651,7 @@ es-AR: close_reports_html: Marcar todas las denuncias contra @%{acct} como resueltas delete_data_html: Eliminar el perfil y contenido de @%{acct} en 30 días a partir de ahora, a menos que se revierta la suspensión en ese tiempo preview_preamble_html: "@%{acct} recibirá una advertencia con el siguiente contenido:" - record_strike_html: Registrá una amonestación contra @%{acct} para ayudarte a escalar futuras violaciones de esta cuenta + record_strike_html: Registrar una amonestación contra @%{acct} para ayudarte a escalar futuras violaciones de esta cuenta send_email_html: Enviar a @%{acct} un correo electrónico de advertencia warning_placeholder: Razones adicionales opcionales para la acción de moderación. target_origin: Origen de la cuenta denunciada @@ -725,6 +741,9 @@ es-AR: branding: preamble: La marca de tu servidor lo diferencia de otros servidores de la red. Esta información puede mostrarse a través de una variedad de entornos, como en la interface web de Mastodon, en aplicaciones nativas, en previsualizaciones de enlaces en otros sitios web y en aplicaciones de mensajería, etc. Por esta razón, es mejor mantener esta información clara, breve y concisa. title: Marca + captcha_enabled: + desc_html: Esto depende de scripts externos de hCaptcha, que pueden ser una preocupación de seguridad y privacidad. Además, esto puede hacer el proceso de registro significativamente menos accesible para algunas personas (especialmente para gente con discapacidades). Por estas razones, por favor, considerá medidas alternativas, como el registro basado en la aprobación o la invitación. + title: Solicitar a los nuevos usuarios que resuelvan una CAPTCHA para confirmar su cuenta content_retention: preamble: Controlá cómo el contenido generado por el usuario se almacena en Mastodon. title: Retención de contenido @@ -752,10 +771,27 @@ es-AR: approved: Se requiere aprobación para registrarse none: Nadie puede registrarse open: Cualquiera puede registrarse - title: Configuraciones del servidor + security: + authorized_fetch: Requiere autenticación de servidores federados + authorized_fetch_hint: Requerir autenticación de servidores federados permite un cumplimiento más estricto tanto de los bloques de nivel de usuario como de nivel de servidor. Sin embargo, esto se produce a costa de una penalidad en el rendimiento, reduce el alcance de tus respuestas y puede introducir problemas de compatibilidad con algunos servicios federados. Además, esto no impedirá que actores dedicados obtengan tus mensajes y cuentas públicas. + authorized_fetch_overridden_hint: Actualmente no podés cambiar esta configuración porque está sobreescrita por una variable de entorno. + federation_authentication: Ejecución de autenticación de federación + title: Configuración del servidor site_uploads: delete: Eliminar archivo subido destroyed_msg: "¡Subida al sitio eliminada exitosamente!" + software_updates: + critical_update: Crítica — por favor, actualizá cuanto antes + description: Se recomienda mantener actualizada tu instalación de Mastodon para beneficiarte de las últimas correcciones y funciones. Además, a veces es crítico actualizar Mastodon inmediatamente para evitar problemas de seguridad. Por estas razones, Mastodon comprueba si hay actualizaciones cada 30 minutos, y te notificará de acuerdo a tu configuración de notificaciones por correo electrónico. + documentation_link: Aprendé más + release_notes: Notas de lanzamiento + title: Actualización disponible + type: Tipo + types: + major: Lanzamiento importante + minor: Lanzamiento menor + patch: Lanzamiento parche — correcciones de errores y cambios fáciles de aplicar + version: Versión statuses: account: Autor application: Aplicación @@ -792,9 +828,24 @@ es-AR: suspend: "%{name} suspendió la cuenta de %{target}" appeal_approved: Apelado appeal_pending: Apelación pendiente + appeal_rejected: Apelación rechazada system_checks: database_schema_check: message_html: Hay migraciones pendientes de la base de datos. Por favor, ejecutalas para asegurarte de que la aplicación funciona según lo esperado + elasticsearch_health_red: + message_html: El estado del clúster de Elasticsearch no es saludable (estado rojo), las funciones de búsqueda no están disponibles + elasticsearch_health_yellow: + message_html: El estado del clúster de Elasticsearch no es saludable (estado amarillo), es posible que quieras investigar el motivo + elasticsearch_index_mismatch: + message_html: Las asignaciones de índices de Elasticsearch están desactualizadas. Por favor, ejecutá tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ver documentación + message_html: Tu clúster de Elasticsearch tiene más de un nodo, pero Mastodon no está configurado para usarlos. + elasticsearch_preset_single_node: + action: Ver documentación + message_html: Tu clúster de Elasticsearch solo tiene un nodo, ES_PRESET debe establecerse a single_node_cluster. + elasticsearch_reset_chewy: + message_html: Tu sistema de indexado Elasticsearch está desactualizado debido a un cambio de configuración. Ejecutá tootctl search deploy --reset-chewy para actualizarlo. elasticsearch_running_check: message_html: No se pudo conectar a Elasticsearch. Por favor, revisá que se esté ejecutando, o deshabilitá la búsqueda de texto completo elasticsearch_version_check: @@ -805,6 +856,18 @@ es-AR: message_html: No definiste ninguna regla del servidor. sidekiq_process_check: message_html: No hay ningún proceso Sidekiq en ejecución para la/s cola/s %{value}. Por favor, revisá tu configuración de Sidekiq + software_version_critical_check: + action: Ver actualizaciones disponibles + message_html: Una actualización crítica de Mastodon está disponible; por favor, actualizá lo antes posible. + software_version_patch_check: + action: Ver actualizaciones disponibles + message_html: Hay disponible una corrección de errores en la actualización de Mastodon. + upload_check_privacy_error: + action: Revisá acá para más información + message_html: "Tu servidor web está mal configurado. La privacidad de tus usuarios está en riesgo." + upload_check_privacy_error_object_storage: + action: Revisá acá para más información + message_html: "El almacenamiento de tu objeto está mal configurado. La privacidad de tus usuarios está en riesgo." tags: review: Estado de revisión updated_msg: La configuración de la etiqueta se actualizó exitosamente @@ -827,6 +890,7 @@ es-AR: other: Compartido por %{count} personas durante la última semana title: Enlaces en tendencia usage_comparison: Compartido %{today} veces hoy, comparado con la/s %{yesterday} vez/veces de ayer + not_allowed_to_trend: No se permite la tendencia only_allowed: Sólo permitidas pending_review: Revisión pendiente preview_card_providers: @@ -844,7 +908,7 @@ es-AR: no_status_selected: No se cambió ningún mensaje en tendencia, ya que ninguno fue seleccionado not_discoverable: El autor optó ser detectable shared_by: - one: Compartido o marcado como favorito una vez + one: Compartido y marcado como favorito %{friendly_count} vez other: Compartido y marcado como favorito %{friendly_count} veces title: Mensajes en tendencia tags: @@ -911,6 +975,9 @@ es-AR: body: "%{target} está apelando a una solicitud de moderación de %{action_taken_by} de %{date}, del tipo %{type}. Ellos escribieron:" next_steps: Podés aprobar la apelación para deshacer la solicitud de moderación, o ignorarla. subject: "%{username} está apelando a una solicitud de moderación en %{instance}" + new_critical_software_updates: + body: Se lanzaron nuevas versiones críticas de Mastodon; ¡es posible que quieras actualizar lo antes posible! + subject: "¡Las actualizaciones críticas de Mastodon están disponibles para %{instance}!" new_pending_account: body: Abajo están los detalles de la nueva cuenta. Podés aprobar o rechazar esta solicitud. subject: Nueva cuenta para revisión en %{instance} (%{username}) @@ -918,6 +985,9 @@ es-AR: body: "%{reporter} denunció a %{target}" body_remote: Alguien de %{domain} denunció a %{target} subject: Nueva denuncia para %{instance} (#%{id}) + new_software_updates: + body: Se liberaron nuevas versiones de Mastodon; ¡es posible que quieras actualizar! + subject: "¡Las nuevas versiones de Mastodon están disponibles para %{instance}!" new_trends: body: 'Los siguientes elementos necesitan una revisión antes de que se puedan mostrar públicamente:' new_trending_links: @@ -947,24 +1017,28 @@ es-AR: guide_link: https://es.crowdin.com/project/mastodon guide_link_text: Todos pueden contribuir. sensitive_content: Contenido sensible - toot_layout: Diseño del mensaje application_mailer: notification_preferences: Cambiar configuración de correo electrónico salutation: "%{name}:" settings: 'Cambiar configuración de correo electrónico: %{link}' + unsubscribe: Desuscribirse view: 'Visitá:' view_profile: Ver perfil view_status: Ver mensaje applications: created: Aplicación creada exitosamente destroyed: Aplicación eliminada exitosamente + logout: Cerrar sesión regenerate_token: Regenerar clave de acceso token_regenerated: Clave de acceso regenerada exitosamente warning: Ojo con estos datos. ¡Nunca los compartas con nadie! your_token: Tu clave de acceso auth: apply_for_account: Solicitar una cuenta - change_password: Contraseña + captcha_confirmation: + help_html: Si tenés problemas resolviendo la CAPTCHA, podés ponerte en contacto con nosotros a través de %{email} y te vamos a ayudar. + hint_html: ¡Sólo una cosa más! Necesitamos confirmar que sos humano (¡esto es para que podamos mantener el spam fuera!). Resuelvé la CAPTCHA abajo y hacé clic en "Continuar". + title: Comprobación de seguridad confirmations: wrong_email_hint: Si esa dirección de correo electrónico no es correcta, podés cambiarla en la configuración de la cuenta. delete_account: Eliminar cuenta @@ -973,7 +1047,7 @@ es-AR: prefix_invited_by_user: "¡@%{name} te invita para que te unás a este servidor de Mastodon!" prefix_sign_up: "¡Unite a Mastodon hoy!" suffix: Con una cuenta vas a poder seguir a otras cuentas, escribir mensajes e intercambiarlos con usuarios de cualquier servidor de Mastodon, ¡y mucho más! - didnt_get_confirmation: "¿No recibiste el correo electrónico de confirmación?" + didnt_get_confirmation: "¿No recibiste un enlace de confirmación?" dont_have_your_security_key: "¿No tenés tu llave de seguridad?" forgot_password: "¿Te olvidaste la contraseña?" invalid_reset_password_token: La clave para cambiar la contraseña no es válida o venció. Por favor, solicitá una nueva. @@ -986,27 +1060,40 @@ es-AR: migrate_account_html: Si querés redireccionar esta cuenta a otra distinta, podés configurar eso acá. or_log_in_with: O iniciar sesión con privacy_policy_agreement_html: Leí y acepto la política de privacidad + progress: + confirm: Confirmar correo electrónico + details: Tus detalles + review: Nuestra reseña + rules: Aceptar reglas providers: cas: CAS saml: SAML register: Registrarse registration_closed: "%{instance} no está aceptando nuevos miembros" - resend_confirmation: Reenviar correo electrónico de confirmación + resend_confirmation: Reenviar enlace de confirmación reset_password: Cambiar contraseña rules: + accept: Aceptar + back: Volver + invited_by: 'Podés unirte a %{domain} gracias a la invitación que recibiste de:' preamble: Estas reglas son establecidas y aplicadas por los moderadores de %{domain}. + preamble_invited: Antes de continuar, por favor, tené en cuenta las reglas básicas establecidas por los moderadores de %{domain}. title: Algunas reglas básicas. + title_invited: Te invitaron. security: Seguridad set_new_password: Establecer nueva contraseña setup: - email_below_hint_html: Si la dirección de correo electrónico que aparece a continuación es incorrecta, podés cambiarla acá y recibir un nuevo correo electrónico de confirmación. - email_settings_hint_html: Se envió el correo electrónico de confirmación a %{email}. Si esa dirección de correo electrónico no es correcta, podés cambiarla en la configuración de la cuenta. - title: Configuración + email_below_hint_html: Revisá tu carpeta de correo no deseado / spam, o solicitá otro enlace de confirmación. Podés corregir tu dirección de correo electrónico si está mal. + email_settings_hint_html: Hacé clic en el enlace que te enviamos para verificar %{email}. Te esperamos por acá. + link_not_received: "¿No recibiste un enlace?" + new_confirmation_instructions_sent: "¡Recibirás un nuevo correo electrónico con el enlace de confirmación en unos minutos!" + title: Revisá tu bandeja de entrada sign_in: preamble_html: Iniciá sesión con tus credenciales de %{domain}. Si tu cuenta está alojada en un servidor diferente, no vas a poder iniciar sesión acá. title: Iniciar sesión en %{domain} sign_up: - preamble: Con una cuenta en este servidor de Mastodon, podrás seguir a cualquier otra cuenta en la red, independientemente de en qué servidor esté alojada su cuenta. + manual_review: Los registros en %{domain} pasan por la revisión manual de nuestros moderadores. Para ayudarnos a procesar tu registro, escribinos un poco sobre vos y contanos por qué querés una cuenta en %{domain}. + preamble: Con una cuenta en este servidor de Mastodon, podrás seguir a cualquier otra cuenta en la red, independientemente de en qué servidor esté alojada esa cuenta. title: Dejá que te preparemos en %{domain}. status: account_status: Estado de la cuenta @@ -1017,18 +1104,6 @@ es-AR: view_strikes: Ver incumplimientos pasados contra tu cuenta too_fast: Formulario enviado demasiado rápido, probá de nuevo. use_security_key: Usar la llave de seguridad - authorize_follow: - already_following: Ya estás siguiendo a esta cuenta - already_requested: Ya enviaste una solicitud de seguimiento a esa cuenta - error: Lamentablemente, ocurrió un error buscando la cuenta remota - follow: Seguir - follow_request: 'Enviaste una solicitud de seguimiento a:' - following: "¡Listo! Ahora estás siguiendo a:" - post_follow: - close: O simplemente podés cerrar esta ventana. - return: Mostrar el perfil del usuario - web: Ir a la web - title: Seguir a %{acct} challenge: confirm: Continuar hint_html: "Dato: No volveremos a preguntarte por la contraseña durante la siguiente hora." @@ -1040,22 +1115,22 @@ es-AR: invalid_signature: no es una firma Ed25519 válida date: formats: - default: "%Y.%b.%d" - with_month_name: "%Y.%B.%d" + default: "%d de %b de %Y" + with_month_name: "%d de %B de %Y" datetime: distance_in_words: - about_x_hours: "%{count}h" - about_x_months: "%{count}M" - about_x_years: "%{count}A" - almost_x_years: "%{count}A" + about_x_hours: "%{count}hrs." + about_x_months: "%{count}mes." + about_x_years: "%{count}año." + almost_x_years: "%{count}año." half_a_minute: Recién - less_than_x_minutes: "%{count}min" + less_than_x_minutes: "%{count}min." less_than_x_seconds: Recién - over_x_years: "%{count}A" - x_days: "%{count}D" - x_minutes: "%{count}min" - x_months: "%{count}M" - x_seconds: "%{count}s" + over_x_years: "%{count}año." + x_days: "%{count}día." + x_minutes: "%{count}min." + x_months: "%{count}mes." + x_seconds: "%{count}seg." deletes: challenge_not_passed: La información que ingresaste no es correcta confirm_password: Ingresá tu contraseña actual para verificar tu identidad @@ -1105,6 +1180,10 @@ es-AR: your_appeal_rejected: Se rechazó tu apelación domain_validator: invalid_domain: no es un nombre de dominio válido + edit_profile: + basic_information: Información básica + hint_html: "Personalizá lo que la gente ve en tu perfil público y junto a tus publicaciones. Es más probable que otras personas te sigan e interactúen con vos cuando tengas un perfil completo y una foto de perfil." + other: Otros errors: '400': La solicitud que enviaste no era válida o estaba corrompida. '403': No tenés permiso para ver esta página. @@ -1141,8 +1220,8 @@ es-AR: featured_tags: add_new: Agregar nueva errors: - limit: Alcanzaste el máximo de etiquetas destacadas - hint_html: "¿Qué son las etiquetas destacadas? Son etiquetas que se muestran de forma permanente en tu perfil público y permiten a los usuarios navegar por tus mensajes públicos que contengan esas etiquetas. Las etiquetas destacadas son una gran herramienta para hacer un seguimiento de trabajos creativos o proyectos a largo plazo." + limit: Ya estableciste el número máximo de etiquetas + hint_html: "Destacá tus etiquetas más importantes en tu perfil. Una gran herramienta para realizar un seguimiento de tus obras creativas y de tus proyectos a largo plazo. Las etiquetas destacadas se muestran de tal forma en tu perfil y permiten un acceso rápido a tus propios mensajes." filters: contexts: account: Perfiles @@ -1185,8 +1264,6 @@ es-AR: index: hint: Este filtro se aplica a la selección de mensajes individuales, independientemente de otros criterios. Podés agregar más mensajes a este filtro desde la interface web. title: Mensajes filtrados - footer: - trending_now: Tendencia ahora generic: all: Todas all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ es-AR: all_matching_items_selected_html: one: "%{count} elemento que coincide con tu búsqueda está seleccionado." other: Todos los %{count} elementos que coinciden con tu búsqueda están seleccionados. + cancel: Cancelar changes_saved_msg: "¡Cambios guardados exitosamente!" + confirm: Confirmar copy: Copiar delete: Eliminar deselect: Deseleccionar todo @@ -1209,24 +1288,62 @@ es-AR: validation_errors: one: "¡Falta algo! Por favor, revisá el error abajo" other: "¡Falta algo! Por favor, revisá los %{count} errores abajo" - html_validator: - invalid_markup: 'contiene markup HTML no válido: %{error}' imports: errors: + empty: Archivo CSV vacío + incompatible_type: Incompatible con el tipo de importación seleccionado invalid_csv_file: 'Archivo CSV no válido. Error: %{error}' over_rows_processing_limit: contiene más de %{count} filas + too_large: El archivo es demasiado grande + failures: Fallos + imported: Importadas + mismatched_types_warning: Parece que podrías haber seleccionado el tipo incorrecto para esta importación; por favor, volvé a verificarlo. modes: merge: Combinar merge_long: Mantener registros existentes y agregar nuevos overwrite: Sobrescribir overwrite_long: Reemplazar registros actuales con los nuevos + overwrite_preambles: + blocking_html: Estás a punto de reemplazar tu lista de bloqueos por hasta %{total_items} cuentas provenientes de %{filename}. + bookmarks_html: Estás a punto de reemplazar tus marcadores por hasta %{total_items} mensajes provenientes de %{filename}. + domain_blocking_html: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{total_items} dominios provenientes de %{filename}. + following_html: Estás a punto de seguir hasta %{total_items} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + lists_html: Estás a punto de reemplazar tus listas con el contenido de %{filename}. Se agregarán hasta %{total_items} cuentas a listas nuevas. + muting_html: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{total_items} cuentas provenientes de %{filename}. + preambles: + blocking_html: Estás a punto de bloquear hasta %{total_items} cuentas provenientes de %{filename}. + bookmarks_html: Está a punto de agregar hasta %{total_items} mensajes provenientes de %{filename} a tus marcadores. + domain_blocking_html: Estás a punto de bloquear hasta %{total_items} dominios provenientes de %{filename}. + following_html: Estás a punto de seguir hasta cuentas%{total_items} provenientes de %{filename}. + lists_html: Estás a punto de agregar hasta %{total_items} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay lista a cual agregar. + muting_html: Estás a punto de silenciar hasta %{total_items} cuentas provenientes de %{filename}. preface: Podés importar ciertos datos que exportaste desde otro servidor, como una lista de las cuentas que estás siguiendo o bloqueando. + recent_imports: Importaciones recientes + states: + finished: Finalizadas + in_progress: En progreso + scheduled: Programadas + unconfirmed: Sin confirmar + status: Estado success: Tus datos se subieron exitosamente y serán procesados en brevedad + time_started: Comenzada el + titles: + blocking: Importación de cuentas bloqueadas + bookmarks: Importación de marcadores + domain_blocking: Importación de dominios bloqueados + following: Importación de cuentas seguidas + lists: Importando listas + muting: Importación de cuentas silenciadas + type: Importar tipo + type_groups: + constructive: Seguimientos y marcadores + destructive: Bloqueos y silencios types: blocking: Lista de bloqueados bookmarks: Marcadores domain_blocking: Lista de dominios bloqueados following: Lista de seguidos + lists: Listas muting: Lista de silenciados upload: Subir invites: @@ -1253,7 +1370,7 @@ es-AR: title: Invitar a gente lists: errors: - limit: Alcanzaste el máximo de listas + limit: Alcanzaste el número máximo de listas login_activities: authentication_methods: otp: aplicación de autenticación de dos factores @@ -1265,6 +1382,21 @@ es-AR: failed_sign_in_html: Intento de inicio de sesión fallido con %{method} desde %{ip} (%{browser}) successful_sign_in_html: Inicio de sesión exitoso con %{method} desde %{ip} (%{browser}) title: Historial de autenticación + mail_subscriptions: + unsubscribe: + action: Sí, desuscribir + complete: Desuscripto + confirmation_html: ¿Estás seguro que querés dejar de recibir %{type} de Mastodon en %{domain} a tu correo electrónico %{email}? Siempre podrás volver a suscribirte desde la configuración de notificaciones por correo electrónico.. + emails: + notification_emails: + favourite: notificaciones de favoritos por correo electrónico + follow: notificaciones de seguidores por correo electrónico + follow_request: notificaciones de solicitudes de seguimiento por correo electrónico + mention: notificaciones de menciones por correo electrónico + reblog: notificaciones de adhesiones por correo electrónico + resubscribe_html: Si te desuscribiste por error, podés resuscribirte desde la configuración de notificaciones por correo electrónico. + success_html: Ya no recibirás %{type} de mastodon en %{domain} a tu correo electrónico %{email}. + title: Desuscribirse media_attachments: validations: images_and_video: No se puede adjuntar un video a un mensaje que ya contenga imágenes @@ -1344,6 +1476,7 @@ es-AR: update: subject: "%{name} editó un mensaje" notifications: + administration_emails: Notificaciones de administración por correo electrónico email_events: Eventos para notificaciones por correo electrónico email_events_hint: 'Seleccioná los eventos para los que querés recibir notificaciones:' other_settings: Configuración de otras notificaciones @@ -1380,12 +1513,22 @@ es-AR: expired: La encuesta ya finalizó invalid_choice: La opción elegida no existe over_character_limit: no puede ser más largo de %{max} caracteres, cada uno + self_vote: No podés votar en tus propias encuestas too_few_options: debe tener más de un elemento too_many_options: no puede contener más de %{max} elementos preferences: other: Otras opciones posting_defaults: Configuración predeterminada de mensajes public_timelines: Líneas temporales públicas + privacy: + hint_html: "Personalizá cómo querés que sean encontrados tu perfil y tus mensajes. Una variedad de funciones en Mastodon pueden ayudarte a alcanzar una mayor audiencia al estar activada. Tomate un momento para revisar esta configuración para asegurarte de que se ajusta a tu caso." + privacy: Privacidad + privacy_hint_html: Controlá cuánto querés revelar a los demás. La gente descubre perfiles interesantes y aplicaciones copadas explorando los seguimientos de otras personas y viendo qué aplicaciones usan, pero puede que prefieras mantener esto oculto. + reach: Alcance + reach_hint_html: Controla si querés ser descubierto y seguido por nuevas cuentas. ¿Querés que tus mensajes aparezcan en la sección de Explorar? ¿Querés que otras personas te vean en las recomendaciones para seguir? ¿Querés aceptar automáticamente a todos los nuevos seguidores, o querés tener el control sobre cada uno de ellos? + search: Búsqueda + search_hint_html: Controlá cómo querés ser encontrado. ¿Querés que la gente te encuentre por lo que publicaste? ¿Querés que desde fuera de Mastodon se encuentre tu perfil al buscar en la web? Por favor, tené en cuenta que la exclusión total de información pública de todos los motores de búsqueda no puede ser garantizada. + title: Privacidad y alcance privacy_policy: title: Política de privacidad reactions: @@ -1398,6 +1541,7 @@ es-AR: confirm_remove_selected_followers: "¿Estás seguro que querés quitar a los seguidores seleccionados?" confirm_remove_selected_follows: "¿Estás seguro que querés quitar a las cuentas seguidas seleccionadas?" dormant: Inactivas + follow_failure: No se pudieron seguir algunas de las cuentas seleccionadas. follow_selected_followers: Seguir a los seguidores seleccionados followers: Seguidores following: Siguiendo @@ -1437,6 +1581,7 @@ es-AR: electron: Electron firefox: Mozilla Firefox generic: "[Navegador web desconocido]" + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Navegador web de Nokia S40 Ovi @@ -1446,6 +1591,7 @@ es-AR: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: "[Navegador web desconocido]" weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1458,9 +1604,10 @@ es-AR: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: GNU/Linux mac: macOS - other: "[Plataforma desconocida]" + unknown_platform: "[Plataforma desconocida]" windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1485,7 +1632,7 @@ es-AR: migrate: Migración de la cuenta notifications: Notificaciones preferences: Configuración - profile: Perfil + profile: Perfil público relationships: Seguimientos statuses_cleanup: Eliminación auto. de mensajes strikes: Moderación de incumplimientos @@ -1531,7 +1678,6 @@ es-AR: show_newer: Mostrar más recientes show_older: Mostrar más antiguos show_thread: Mostrar hilo - sign_in_to_participate: Iniciá sesión para participar en la conversación title: '%{name}: "%{quote}"' visibilities: direct: Directo @@ -1573,12 +1719,10 @@ es-AR: '7889238': 3 meses min_age_label: Umbral de edad min_favs: Conservar mensajes marcados como favoritos de por lo menos - min_favs_hint: No elimina ninguno de tus mensajes que haya recibido más de esta cantidad de favoritos. Dejá en blanco para eliminar mensajes independientemente de su número de favoritos. + min_favs_hint: No elimina ninguno de tus mensajes que haya recibido al menos esta cantidad de favoritos. Dejá en blanco para eliminar mensajes independientemente de su número de favoritos. min_reblogs: Conservar adhesiones de por lo menos min_reblogs_hint: No elimina ninguno de tus mensajes que haya recibido más de esta cantidad de adhesiones. Dejá en blanco para eliminar mensajes independientemente de su número de adhesiones. stream_entries: - pinned: Mensaje fijado - reblogged: adhirió a este mensaje sensitive_content: Contenido sensible strikes: errors: @@ -1594,6 +1738,11 @@ es-AR: default: "%Y.%b.%d, %H:%M" month: "%b de %Y" time: "%H:%M" + with_time_zone: "%d de %b de %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Se excedió la cuota de uso del servicio de traducción en todo el servidor. + too_many_requests: Han habido demasiadas solicitudes al servicio de traducción recientemente. two_factor_authentication: add: Agregar disable: Deshabilitar 2FA @@ -1673,13 +1822,18 @@ es-AR: title: "¡Bienvenido a bordo, %{name}!" users: follow_limit_reached: No podés seguir a más de %{limit} cuentas + go_to_sso_account_settings: Andá a la configuración de cuenta de tu proveedor de identidad invalid_otp_token: Código de dos factores no válido otp_lost_help_html: Si perdiste al acceso a ambos, podés ponerte en contacto con %{email} seamless_external_login: Iniciaste sesión desde un servicio externo, así que la configuración de contraseña y correo electrónico no están disponibles. signed_in_as: 'Iniciaste sesión como:' verification: - explanation_html: 'Podés verificarte a vos mismo como el propietario de los enlaces en los metadatos de tu perfil. Para eso, el sitio web del enlace debe contener un enlace de vuelta a tu perfil de Mastodon. El enlace en tu sitio debe tener un atributo rel="me". El contenido del texto del enlace no importa. Acá tenés un ejemplo:' + extra_instructions_html: Dato: El enlace en tu sitio web puede ser invisible. La parte importante es rel="me", que evita la suplantación de identidad en sitios con contenido generado por el usuario. Incluso podés usar una etiqueta link en el encabezado de la página en vez de a, pero el HTML debe ser accesible sin ejecutar JavaScript. + here_is_how: Así es cómo se hace + hint_html: "La verificación de tu identidad en Mastodon es válida para todos. Está basada en estándares web abiertos, y es gratis ahora y para siempre. Todo lo que necesitás es un sitio web propio que la gente reconozca. Cuando enlacés a este sitio web desde tu perfil, comprobaremos que el sitio web se enlaza a tu perfil y mostraremos un indicador visual en él." + instructions_html: Copiá y pegá el siguiente código en el HTML de tu sitio web. Luego, agregá la dirección de tu sitio web en uno de los campos extras de tu perfil desde la pestaña "Editar perfil" y guardá los cambios. verification: Verificación + verified_links: Tus enlaces verificados webauthn_credentials: add: Agregar nueva llave de seguridad create: diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 486a122b14..542478f716 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -91,6 +91,7 @@ es-MX: moderation: active: Activo all: Todos + disabled: Deshabilitado pending: Pendiente silenced: Limitado suspended: Suspendidos @@ -124,8 +125,8 @@ es-MX: removed_header_msg: Se ha eliminado con éxito la imagen de cabecera de %{username} resend_confirmation: already_confirmed: Este usuario ya está confirmado - send: Reenviar el correo electrónico de confirmación - success: "¡Correo electrónico de confirmación enviado con éxito!" + send: Reenviar enlace de confirmación + success: "¡Enlace de confirmación enviado con éxito!" reset: Reiniciar reset_password: Reiniciar contraseña resubscribe: Re-suscribir @@ -133,6 +134,7 @@ es-MX: search: Buscar search_same_email_domain: Otros usuarios con el mismo dominio de correo search_same_ip: Otros usuarios con la misma IP + security: Seguridad security_measures: only_password: Sólo contraseña password_and_2fa: Contraseña y 2FA @@ -307,6 +309,7 @@ es-MX: unpublish: Retirar publicación unpublished_msg: "¡Anuncio despublicado con éxito!" updated_msg: "¡Anuncio actualizado con éxito!" + critical_update_pending: Actualización crítica pendiente custom_emojis: assign_category: Asignar categoría by_domain: Dominio @@ -380,6 +383,15 @@ es-MX: undo: Quitar de la lista blanca domain_blocks: add_new: Añadir nuevo + confirm_suspension: + cancel: Cancelar + confirm: Suspender + permanent_action: Deshacer la suspensión no recuperará ningún data o relaciones. + preamble_html: Estás a punto de suspender a %{domain} y sus subdominios. + remove_all_data: Esto eliminará todo el contenido, multimedia y datos de perfil de las cuentas de este dominio de tu servidor. + stop_communication: Tu servidor dejará de comunicarse con estos servidores. + title: Confirmar bloqueo de dominio para %{domain} + undo_relationships: Esto deshará cualquier relación de seguimiento entre las cuentas de estos servidores y la suya. created_msg: El bloque de dominio está siendo procesado destroyed_msg: El bloque de dominio se deshizo domain: Dominio @@ -427,6 +439,7 @@ es-MX: resolve: Resolver dominio title: Nueva entrada en la lista negra de correo no_email_domain_block_selected: No se han cambiado bloqueos de dominio ya que ninguno ha sido seleccionado + not_permitted: No permitido resolved_dns_records_hint_html: El nombre de dominio resuelve los siguientes dominios MX, los cuales son responsables en última instancia de aceptar el correo electrónico. Bloquear un dominio MX bloqueará los registros de cualquier dirección de correo electrónico que utilice el mismo dominio MX, incluso si el nombre de dominio visible es diferente. Tenga cuidado de no bloquear los principales proveedores de correo electrónico. resolved_through_html: Resuelto a través de %{domain} title: Lista negra de correo @@ -473,6 +486,7 @@ es-MX: content_policies: comment: Nota interna description_html: Puedes definir políticas de contenido que se aplicarán a todas las cuentas de este dominio y a cualquiera de sus subdominios. + limited_federation_mode_description_html: Puedes elegir si permites la federación con este dominio. policies: reject_media: Rechazar multimedia reject_reports: Rechazar informes @@ -585,11 +599,13 @@ es-MX: assign_to_self: Asignármela a mí assigned: Moderador asignado by_target_domain: Dominio de la cuenta reportada + cancel: Cancelar category: Categoría category_description_html: La razón por la que se reportó esta cuenta o contenido será citada en las comunicaciones con la cuenta reportada comment: none: Ninguno comment_description_html: 'Para proporcionar más información, %{name} escribió:' + confirm: Confirmar confirm_action: Confirmar acción de moderación contra @%{acct} created_at: Denunciado delete_and_resolve: Eliminar publicaciones @@ -725,6 +741,9 @@ es-MX: branding: preamble: La marca de tu servidor lo diferencia de otros servidores de la red. Esta información puede mostrarse a través de una variedad de entornos, como en la interfaz web de Mastodon, en aplicaciones nativas, en previsualizaciones de enlaces en otros sitios web y en aplicaciones de mensajería, etc. Por esta razón, es mejor mantener esta información clara, breve y concisa. title: Marca + captcha_enabled: + desc_html: Esto se basa en scripts externos de hCaptcha, que pueden suponer una preocupación de seguridad y privacidad. Además, esto puede volver el proceso de registro significativamente menos accesible para algunas personas (especialmente con discapacidades). Por estas razones, por favor, considera medidas alternativas como el registro por aprobación manual o con invitación. + title: Solicita a los nuevos usuarios que resuelvan un CAPTCHA para confirmar su cuenta content_retention: preamble: Controlar cómo el contenido generado por el usuario se almacena en Mastodon. title: Retención de contenido @@ -752,10 +771,27 @@ es-MX: approved: Se requiere aprobación para registrarse none: Nadie puede registrarse open: Cualquiera puede registrarse - title: Ajustes del Servidor + security: + authorized_fetch: Requerir autenticación de servidores federados + authorized_fetch_hint: Requerir autenticación de servidores federados permite un cumplimiento más estricto tanto de los bloqueos a nivel de usuario como a nivel de servidor. Sin embargo, esto se produce a costa de una penalización en el rendimiento, reduce el alcance de tus respuestas y puede introducir problemas de compatibilidad con algunos servicios federados. Además, esto no impedirá que actores dedicados obtengan tus cuentas y publicaciones públicas. + authorized_fetch_overridden_hint: No puedes cambiar esta configuración porque está sobreescrita por una variable de entorno. + federation_authentication: Forzar autenticación federada + title: Ajustes del servidor site_uploads: delete: Eliminar archivo subido destroyed_msg: "¡Carga del sitio eliminada con éxito!" + software_updates: + critical_update: Crítico — por favor actualiza rápidamente + description: Se recomienda mantener actualizada su instalación de Mastodon para beneficiarse de las últimas correcciones y características. Además, a veces es crítico actualizar Mastodon de manera oportuna para evitar problemas de seguridad. Por estas razones, Mastodon comprueba si hay actualizaciones cada 30 minutos, y le notificará de acuerdo a sus preferencias de notificación por correo electrónico. + documentation_link: Saber más + release_notes: Notas de la versión + title: Actualizaciones disponibles + type: Tipo + types: + major: Versión principal + minor: Versión menor + patch: Versión del parche — correcciones de errores y cambios fáciles de aplicar + version: Versión statuses: account: Autor application: Aplicación @@ -792,9 +828,24 @@ es-MX: suspend: "%{name} suspendio la cuenta de %{target}" appeal_approved: Apelado appeal_pending: Apelación pendiente + appeal_rejected: Apelación rechazada system_checks: database_schema_check: message_html: Hay migraciones pendientes de la base de datos. Por favor, ejecútalas para asegurarte de que la aplicación funciona como debería + elasticsearch_health_red: + message_html: Clúster de Elasticsearch no es saludable (estado rojo), las funciones de búsqueda no están disponibles + elasticsearch_health_yellow: + message_html: Clúster de Elasticsearch es poco saludable (estado amarillo), es posible que quiera investigar la razón + elasticsearch_index_mismatch: + message_html: Las asignaciones de índices de Elasticsearch están desactualizadas. Por favor, ejecute tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ver documentación + message_html: Tu clúster de Elasticsearch tiene más de un nodo, pero Mastodon no está configurado para usarlos. + elasticsearch_preset_single_node: + action: Ver documentación + message_html: Tu clúster de Elasticsearch solo tiene un nodo, ES_PRESET debe establecerse a single_node_cluster. + elasticsearch_reset_chewy: + message_html: Tu sistema de indexado Elasticsearch está desactualizado debido a un cambio de configuración. Ejecute tootctl search deploy --reset-chewy para actualizarlo. elasticsearch_running_check: message_html: No se pudo conectar a Elasticsearch. Por favor, comprueba que está ejecutándose, o desactiva la búsqueda de texto completo elasticsearch_version_check: @@ -805,6 +856,18 @@ es-MX: message_html: No ha definido ninguna regla del servidor. sidekiq_process_check: message_html: No hay ningún proceso Sidekiq en ejecución para la(s) cola(s) %{value}. Por favor, revise su configuración de Sidekiq + software_version_critical_check: + action: Ver actualizaciones disponibles + message_html: Una actualización crítica de Mastodon está disponible, por favor actualice lo antes posible. + software_version_patch_check: + action: Ver actualizaciones disponibles + message_html: Hay disponible una corrección de errores en la actualización de Mastodon. + upload_check_privacy_error: + action: Para más información aquí + message_html: "Su servidor web no está configurado. Está en riesgo la privacidad de sus usuarios." + upload_check_privacy_error_object_storage: + action: Para más información aquí + message_html: "Su almacenamiento no está configurado. Está en riesgo la privacidad de sus usuarios." tags: review: Estado de revisión updated_msg: Hashtags actualizados exitosamente @@ -827,6 +890,7 @@ es-MX: other: Compartido por %{count} personas durante la última semana title: Enlaces en tendencia usage_comparison: Compartido %{today} veces hoy, comparado a %{yesterday} ayer + not_allowed_to_trend: No permitido para tendencia only_allowed: Sólo las permitidas pending_review: Revisión pendiente preview_card_providers: @@ -911,6 +975,9 @@ es-MX: body: "%{target} está apelando a una solicitud de moderación de %{action_taken_by} el %{date}, del tipo %{type}. Ellos escribieron:" next_steps: Puedes aprobar la apelación para deshacer la decisión de moderación, o ignorarla. subject: "%{username} está apelando a una decisión de moderación en %{instance}" + new_critical_software_updates: + body: Se han lanzado nuevas versiones críticas de Mastodon, ¡es posible que quiera actualizar lo antes posible! + subject: "¡Las actualizaciones críticas de Mastodon están disponibles para %{instance}!" new_pending_account: body: Los detalles de la nueva cuenta están abajos. Puedes aprobar o rechazar esta aplicación. subject: Nueva cuenta para revisión en %{instance} (%{username}) @@ -918,6 +985,9 @@ es-MX: body: "%{reporter} ha reportado a %{target}" body_remote: Alguien de %{domain} a reportado a %{target} subject: Nuevo reporte para la %{instance} (#%{id}) + new_software_updates: + body: Se han liberado nuevas versiones de Mastodon, ¡es posible que quiera actualizar! + subject: "¡Nuevas versiones de Mastodon están disponibles para %{instance}!" new_trends: body: 'Los siguientes elementos necesitan una revisión antes de que se puedan mostrar públicamente:' new_trending_links: @@ -947,24 +1017,28 @@ es-MX: guide_link: https://es.crowdin.com/project/mastodon guide_link_text: Todos pueden contribuir. sensitive_content: Contenido sensible - toot_layout: Diseño de los toots application_mailer: notification_preferences: Cambiar preferencias de correo electrónico salutation: "%{name}:" settings: 'Cambiar preferencias de correo: %{link}' + unsubscribe: Cancelar suscripción view: 'Vista:' view_profile: Ver perfil view_status: Ver estado applications: created: Aplicación creada exitosamente destroyed: Apicación eliminada exitosamente + logout: Cerrar sesión regenerate_token: Regenerar token de acceso token_regenerated: Token de acceso regenerado exitosamente warning: Ten mucho cuidado con estos datos. ¡No los compartas con nadie! your_token: Tu token de acceso auth: apply_for_account: Solicitar una cuenta - change_password: Contraseña + captcha_confirmation: + help_html: Si tienes problemas resolviendo el CAPTCHA, puedes contactarnos a través del correo %{email} y te ayudaremos. + hint_html: ¡Una última cosita! Necesitamos confirmar que eres humano (¡así podemos evitar el spam!). Resuelve este CAPTCHA de debajo y pulsa en "Continuar". + title: Comprobación de seguridad confirmations: wrong_email_hint: Si esa dirección de correo electrónico no es correcta, puedes cambiarla en la configuración de la cuenta. delete_account: Borrar cuenta @@ -973,7 +1047,7 @@ es-MX: prefix_invited_by_user: "¡@%{name} te invita a unirte a este servidor de Mastodon!" prefix_sign_up: "¡Únete a Mastodon hoy!" suffix: "¡Con una cuenta podrás seguir a gente, publicar novedades e intercambiar mensajes con usuarios de cualquier servidor de Mastodon y más!" - didnt_get_confirmation: "¿No recibió el correo de confirmación?" + didnt_get_confirmation: "¿No recibiste un enlace de confirmación?" dont_have_your_security_key: "¿No tienes tu clave de seguridad?" forgot_password: "¿Olvidaste tu contraseña?" invalid_reset_password_token: El token de reinicio de contraseña es inválido o expiró. Por favor pide uno nuevo. @@ -986,26 +1060,39 @@ es-MX: migrate_account_html: Si deseas redireccionar esta cuenta a otra distinta, puedes configurarlo aquí. or_log_in_with: O inicia sesión con privacy_policy_agreement_html: He leído y acepto la política de privacidad + progress: + confirm: Confirmar correo + details: Tus detalles + review: Nuestra revisión + rules: Aceptar reglas providers: cas: CAS saml: SAML register: Registrarse registration_closed: "%{instance} no está aceptando nuevos miembros" - resend_confirmation: Volver a enviar el correo de confirmación + resend_confirmation: Reenviar enlace de confirmación reset_password: Restablecer contraseña rules: + accept: Aceptar + back: Atrás + invited_by: 'Puedes unirte a %{domain} gracias a la invitación que has recibido de:' preamble: Estas son establecidas y aplicadas por los moderadores de %{domain}. + preamble_invited: Antes de continuar, por favor, revisa las reglas básicas establecidas por los moderadores de %{domain}. title: Algunas reglas básicas. + title_invited: Has sido invitado. security: Cambiar contraseña set_new_password: Establecer nueva contraseña setup: - email_below_hint_html: Si la dirección de correo electrónico que aparece a continuación es incorrecta, se puede cambiarla aquí y recibir un nuevo correo electrónico de confirmación. - email_settings_hint_html: El correo electrónico de confirmación fue enviado a %{email}. Si esa dirección de correo electrónico no sea correcta, se puede cambiarla en la configuración de la cuenta. - title: Configuración + email_below_hint_html: Comprueba tu carpeta de correo no deseado o solicita otro enlace de confirmación. Puedes corregir tu correo electrónico si está mal. + email_settings_hint_html: Pulsa el enlace que te hemos enviado para verificar %{email}. Esperaremos aquí mismo. + link_not_received: "¿No recibiste un enlace?" + new_confirmation_instructions_sent: "¡Recibirás un nuevo correo electrónico con el enlace de confirmación en unos minutos!" + title: Revisa tu bandeja de entrada sign_in: preamble_html: Registrate con tus credenciales de %{domain}. Si tu cuenta está alojada en un servidor diferente, no podrás iniciar sesión aquí. title: Registrate en %{domain} sign_up: + manual_review: Los registros en %{domain} pasan por la revisión manual de nuestros moderadores. Para ayudarnos a procesar tu registro, escribe un poco sobre ti mismo y por qué quieres una cuenta en %{domain}. preamble: Con una cuenta en este servidor de Mastodon, podrás seguir a cualquier otra persona en la red, independientemente del servidor en el que se encuentre. title: Crear cuenta de Mastodon en %{domain}. status: @@ -1017,18 +1104,6 @@ es-MX: view_strikes: Ver amonestaciones pasadas contra tu cuenta too_fast: Formulario enviado demasiado rápido, inténtelo de nuevo. use_security_key: Usar la clave de seguridad - authorize_follow: - already_following: Ya estás siguiendo a esta cuenta - already_requested: Ya has enviado una solicitud de seguimiento a esa cuenta - error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota - follow: Seguir - follow_request: 'Tienes una solicitud de seguimiento de:' - following: "¡Éxito! Ahora estás siguiendo a:" - post_follow: - close: O, puedes simplemente cerrar esta ventana. - return: Regresar al perfil del usuario - web: Ir al sitio web - title: Seguir a %{acct} challenge: confirm: Continuar hint_html: "Tip: No volveremos a preguntarte por la contraseña durante la siguiente hora." @@ -1105,6 +1180,10 @@ es-MX: your_appeal_rejected: Tu apelación ha sido rechazada domain_validator: invalid_domain: no es un nombre de dominio válido + edit_profile: + basic_information: Información básica + hint_html: "Personaliza lo que la gente ve en tu perfil público junto a tus publicaciones. Es más probable que otras personas te sigan e interactúen contigo cuando completes tu perfil y agregues una foto." + other: Otro errors: '400': La solicitud que has enviado no es valida o estaba malformada. '403': No tienes permiso para acceder a esta página. @@ -1185,8 +1264,6 @@ es-MX: index: hint: Este filtro se aplica a la selección de publicaciones individuales independientemente de otros criterios. Puede añadir más publicaciones a este filtro desde la interfaz web. title: Publicaciones filtradas - footer: - trending_now: Tendencia ahora generic: all: Todos all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ es-MX: all_matching_items_selected_html: one: "%{count} elemento que coincide con su búsqueda está seleccionado." other: Todos los %{count} elementos que coinciden con su búsqueda están seleccionados. + cancel: Cancelar changes_saved_msg: "¡Cambios guardados con éxito!" + confirm: Confirmar copy: Copiar delete: Eliminar deselect: Deseleccionar todo @@ -1209,24 +1288,62 @@ es-MX: validation_errors: one: "¡Algo no está bien! Por favor, revisa el error" other: "¡Algo no está bien! Por favor, revise %{count} errores más abajo" - html_validator: - invalid_markup: 'contiene código HTML no válido: %{error}' imports: errors: + empty: Archivo CSV vacío + incompatible_type: Incompatible con el tipo de importación seleccionado invalid_csv_file: 'Archivo CSV no válido. Error: %{error}' over_rows_processing_limit: contiene más de %{count} filas + too_large: El archivo es demasiado grande + failures: Fallos + imported: Importado + mismatched_types_warning: Parece que podrías haber seleccionado el tipo incorrecto para esta importación, por favor vuelve a verificarlo. modes: merge: Unir merge_long: Mantener registros existentes y añadir nuevos overwrite: Sobrescribir overwrite_long: Reemplazar registros actuales con los nuevos + overwrite_preambles: + blocking_html: Estás a punto de reemplazar tu lista de bloqueos por hasta %{total_items} cuentas provenientes de %{filename}. + bookmarks_html: Estás a punto de reemplazar tus marcadores por hasta %{total_items} publicaciones provenientes de %{filename}. + domain_blocking_html: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{total_items} dominios provenientes de %{filename}. + following_html: Estás a punto de seguir hasta %{total_items} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + lists_html: Estás a punto de reemplazar tus listas con contenidos de %{filename}. %{total_items} cuentas se añadirán a listas nuevas. + muting_html: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{total_items} cuentas proveninetes de %{filename}. + preambles: + blocking_html: Estás a punto de bloquear hasta %{total_items} cuentas proveninetes de %{filename}. + bookmarks_html: Estás a punto de añadir hasta %{total_items} publicaciones proveninetes de %{filename} a tus marcadores. + domain_blocking_html: Estás a punto de bloquear hasta %{total_items} dominios provenientes de %{filename}. + following_html: Estás a punto de seguir hasta cuentas%{total_items} provenientes de %{filename}. + lists_html: Estás a punto de añadir %{total_items} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay listas para añadirlas. + muting_html: Estás a punto de silenciar hasta %{total_items} cuentas provenientes de %{filename}. preface: Puedes importar ciertos datos, como todas las personas que estás siguiendo o bloqueando en tu cuenta en esta instancia, desde archivos exportados de otra instancia. + recent_imports: Importaciones recientes + states: + finished: Finalizado + in_progress: En curso + scheduled: Programado + unconfirmed: No confirmado + status: Estado success: Sus datos se han cargado correctamente y serán procesados en brevedad + time_started: Comenzado el + titles: + blocking: Importando cuentas bloqueadas + bookmarks: Importando marcadores + domain_blocking: Importando dominios bloqueados + following: Importando cuentas seguidas + lists: Importando listas + muting: Importando cuentas silenciadas + type: Importar tipo + type_groups: + constructive: Seguidores y marcadores + destructive: Bloqueos y silencios types: blocking: Lista de bloqueados bookmarks: Marcadores domain_blocking: Lista de dominios bloqueados following: Lista de seguidos + lists: Listas muting: Lista de silenciados upload: Cargar invites: @@ -1265,6 +1382,21 @@ es-MX: failed_sign_in_html: Intento de inicio de sesión fallido con %{method} de %{ip} (%{browser}) successful_sign_in_html: Inicio de sesión exitoso con %{method} desde %{ip} (%{browser}) title: Historial de autenticación + mail_subscriptions: + unsubscribe: + action: Sí, darse de baja + complete: Has cancelado tu suscripción + confirmation_html: ¿Estás seguro de que quieres dejar de recibir %{type} de Mastodon en %{domain} a tu email %{email}? Siempre podrás volver a suscribirte desde los ajustes de notificación por correo.. + emails: + notification_emails: + favourite: notificaciones de me gusta por correo + follow: notificaciones de seguidores por correo + follow_request: notificaciones de peticiones de seguimiento por correo + mention: notificaciones de menciones por correo + reblog: notificaciones de boost por correo + resubscribe_html: Si te has dado de baja por error, puedes volver a suscribirte desde tus ajustes de notificaciones por correo. + success_html: Ya no recibirás %{type} de mastodon en %{domain} a tu correo %{email}. + title: Cancelar suscripción media_attachments: validations: images_and_video: No se puede adjuntar un video a un estado que ya contenga imágenes @@ -1344,6 +1476,7 @@ es-MX: update: subject: "%{name} editó una publicación" notifications: + administration_emails: Notificaciones de administración por correo electrónico email_events: Eventos para notificaciones por correo electrónico email_events_hint: 'Selecciona los eventos para los que deseas recibir notificaciones:' other_settings: Otros ajustes de notificaciones @@ -1380,12 +1513,22 @@ es-MX: expired: La encuesta ya ha terminado invalid_choice: La opción de voto seleccionada no existe over_character_limit: no puede exceder %{max} caracteres cada uno + self_vote: No puedes votar en tus propias encuestas too_few_options: debe tener más de un elemento too_many_options: no puede contener más de %{max} elementos preferences: other: Otros posting_defaults: Configuración por defecto de publicaciones public_timelines: Líneas de tiempo públicas + privacy: + hint_html: "Personaliza cómo te gustaría que tu perfil y tus publicaciones sean encontradas. En Mastodon tienes a tu disposición distintas características que pueden ayudarte a llegar a una audiencia más amplia cuando se encuentran activadas. Toma un momento para revisar estos ajustes para asegurarte si cumplen tus necesidades." + privacy: Privacidad + privacy_hint_html: Controla cuánto quieres compartir para el beneficio de otros. Las personas descubren perfiles interesantes y aplicaciones geniales al navegar por los seguidores de otras personas y viendo desde cuáles aplicaciones publican, pero también puedes preferir mantenerlo oculto. + reach: Alcance + reach_hint_html: Controla si quieres ser descubierto y seguido por nuevas personas. ¿Quieres que tus publicaciones aparezcan en la pantalla de Explorar? ¿Quieres que otras personas te encuentren en sus recomendaciones de cuentas a seguir? ¿Quieres aceptar todos los nuevos seguidores automáticamente o controlar cada uno? + search: Búsqueda + search_hint_html: Controla cómo quieres ser encontrado. ¿Quieres que otras personas te encuentren por lo que has compartido públicamente? ¿Quieres que las personas afuera de Mastodon encuentren tu perfil al navegar por Internet? Por favor, toma en cuenta que la exclusión total de todos los motores de búsqueda no se puede garantizar para información pública. + title: Privacidad y alcance privacy_policy: title: Política de Privacidad reactions: @@ -1398,6 +1541,7 @@ es-MX: confirm_remove_selected_followers: "¿Estás seguro de que quieres eliminar a los seguidores seleccionados?" confirm_remove_selected_follows: "¿Estás seguro de que quieres eliminar los seguidos seleccionados?" dormant: Inactivo + follow_failure: No se pudo seguir algunas de las cuentas seleccionadas. follow_selected_followers: Seguir a los seguidores seleccionados followers: Seguidores following: Siguiendo @@ -1437,6 +1581,7 @@ es-MX: electron: Electron firefox: Firefox generic: Desconocido + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Navegador de Nokia S40 Ovi @@ -1446,6 +1591,7 @@ es-MX: qq: Navegador QQ safari: Safari uc_browser: Navegador UC + unknown_browser: Navegador desconocido weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1458,9 +1604,10 @@ es-MX: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: GNU Linux mac: Mac - other: Desconocido + unknown_platform: Plataforma desconocida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1531,7 +1678,6 @@ es-MX: show_newer: Mostrar más recientes show_older: Mostrar más antiguos show_thread: Mostrar discusión - sign_in_to_participate: Regístrate para participar en la conversación title: "%{name}: «%{quote}»" visibilities: direct: Directa @@ -1573,12 +1719,10 @@ es-MX: '7889238': 3 meses min_age_label: Umbral de tiempo min_favs: Mantener mensajes con un número de favoritos mayor que - min_favs_hint: No borra ninguna de las publicaciones que hayan recibido más de esta cantidad de favoritos. Deja en blanco para eliminar publicaciones sin importar el número de favoritos + min_favs_hint: No borra ninguna de las publicaciones que hayan recibido al menos esta cantidad de favoritos. Deja en blanco para eliminar publicaciones sin importar el número de favoritos min_reblogs: Mantener publicaciones reblogueadas más de min_reblogs_hint: No borra ninguna de las publicaciones que hayan sido reblogueadas más de este número de veces. Deja en blanco para eliminar publicaciones sin importar el número de reblogueos stream_entries: - pinned: Toot fijado - reblogged: retooteado sensitive_content: Contenido sensible strikes: errors: @@ -1594,6 +1738,11 @@ es-MX: default: "%d de %b del %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d de %b de %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Se ha excedido la cuota de uso del servicio de traducción en todo el servidor. + too_many_requests: Se han registrado muchas solicitudes al servicio de traducción recientemente. two_factor_authentication: add: Añadir disable: Deshabilitar @@ -1673,13 +1822,18 @@ es-MX: title: Te damos la bienvenida a bordo, %{name}! users: follow_limit_reached: No puedes seguir a más de %{limit} personas + go_to_sso_account_settings: Diríjete a la configuración de la cuenta de su proveedor de identidad invalid_otp_token: Código de dos factores incorrecto otp_lost_help_html: Si perdiste al acceso a ambos, puedes ponerte en contancto con %{email} seamless_external_login: Has iniciado sesión desde un servicio externo, así que los ajustes de contraseña y correo no están disponibles. signed_in_as: 'Sesión iniciada como:' verification: - explanation_html: 'Puedes verificarte a ti mismo como el dueño de los links en los metadatos de tu perfil . Para eso, el sitio vinculado debe contener un vínculo a tu perfil de Mastodon. El vínculo en tu sitio debe tener un atributo rel="me". El texto del vínculo no importa. Aquí un ejemplo:' + extra_instructions_html: Consejo: El enlace en tu web puede ser invisible. La parte importante es rel="me", que evita la suplantación de identidad en sitios con contenido generado por el usuario. Puedes incluso usar un tag link en el encabezado de la página en vez de a, pero el HTML debe ser accesible sin ejecutar JavaScript. + here_is_how: Así es como se hace + hint_html: "Verificar tu identidad en Mastodon es para todos. Basado en estándares web abiertos, ahora y para siempre libres. Todo lo que necesitas es un sitio web propio por lo que la gente te reconozca. Cuando enlaces a este sitio web desde tu perfil, comprobaremos que el sitio web se enlaza a tu perfil y mostraremos un indicador visual en él." + instructions_html: Copia y pega el siguiente código en el HTML de tu sitio web. A continuación, añade la dirección de su sitio web en uno de los campos extra de tu perfil desde la pestaña "Editar perfil" y guarda los cambios. verification: Verificación + verified_links: Tus links verificados webauthn_credentials: add: Agregar nueva clave de seguridad create: diff --git a/config/locales/es.yml b/config/locales/es.yml index 38cee2adbb..4ad353e3aa 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -91,6 +91,7 @@ es: moderation: active: Activo all: Todos + disabled: Deshabilitado pending: Pendiente silenced: Limitado suspended: Suspendidos @@ -124,8 +125,8 @@ es: removed_header_msg: Se ha eliminado con éxito la imagen de cabecera de %{username} resend_confirmation: already_confirmed: Este usuario ya está confirmado - send: Reenviar el correo electrónico de confirmación - success: "¡Correo electrónico de confirmación enviado con éxito!" + send: Reenviar enlace de confirmación + success: "¡Enlace de confirmación enviado con éxito!" reset: Reiniciar reset_password: Reiniciar contraseña resubscribe: Re-suscribir @@ -133,6 +134,7 @@ es: search: Buscar search_same_email_domain: Otros usuarios con el mismo dominio de correo search_same_ip: Otros usuarios con la misma IP + security: Seguridad security_measures: only_password: Sólo contraseña password_and_2fa: Contraseña y 2FA @@ -144,7 +146,7 @@ es: targeted_reports: Reportes hechos sobre esta cuenta silence: Silenciar silenced: Silenciado - statuses: Estados + statuses: Publicaciones strikes: Amonestaciones previas subscribe: Suscribir suspend: Suspender @@ -193,7 +195,7 @@ es: destroy_email_domain_block: Eliminar Bloqueo de Dominio de Correo Electrónico destroy_instance: Purgar Dominio destroy_ip_block: Eliminar regla IP - destroy_status: Eliminar Estado + destroy_status: Eliminar Publicación destroy_unavailable_domain: Eliminar Dominio No Disponible destroy_user_role: Destruir Rol disable_2fa_user: Deshabilitar 2FA @@ -224,7 +226,7 @@ es: update_custom_emoji: Actualizar Emoji Personalizado update_domain_block: Actualizar el Bloqueo de Dominio update_ip_block: Actualizar regla IP - update_status: Actualizar Estado + update_status: Actualizar Publicación update_user_role: Actualizar Rol actions: approve_appeal_html: "%{name} aprobó la solicitud de moderación de %{target}" @@ -252,7 +254,7 @@ es: destroy_email_domain_block_html: "%{name} desbloqueó el dominio de correo electrónico %{target}" destroy_instance_html: "%{name} purgó el dominio %{target}" destroy_ip_block_html: "%{name} eliminó una regla para la IP %{target}" - destroy_status_html: "%{name} eliminó el estado por %{target}" + destroy_status_html: "%{name} eliminó la publicación de %{target}" destroy_unavailable_domain_html: "%{name} reanudó las entregas al dominio %{target}" destroy_user_role_html: "%{name} eliminó el rol %{target}" disable_2fa_user_html: "%{name} desactivó el requisito de dos factores para el usuario %{target}" @@ -283,7 +285,7 @@ es: update_custom_emoji_html: "%{name} actualizó el emoji %{target}" update_domain_block_html: "%{name} actualizó el bloqueo de dominio para %{target}" update_ip_block_html: "%{name} cambió la regla para la IP %{target}" - update_status_html: "%{name} actualizó el estado de %{target}" + update_status_html: "%{name} actualizó la publicación de %{target}" update_user_role_html: "%{name} cambió el rol %{target}" deleted_account: cuenta eliminada empty: No se encontraron registros. @@ -307,6 +309,7 @@ es: unpublish: Retirar publicación unpublished_msg: "¡Anuncio despublicado con éxito!" updated_msg: "¡Anuncio actualizado con éxito!" + critical_update_pending: Actualización crítica pendiente custom_emojis: assign_category: Asignar categoría by_domain: Dominio @@ -380,6 +383,15 @@ es: undo: Quitar de la lista blanca domain_blocks: add_new: Añadir nuevo + confirm_suspension: + cancel: Cancelar + confirm: Suspender + permanent_action: Deshacer la suspensión no recuperará ningún dato ni relación. + preamble_html: Estás a punto de suspender a %{domain} y sus subdominios. + remove_all_data: Esto eliminará todo el contenido, multimedia y datos de perfil de las cuentas de este dominio de tu servidor. + stop_communication: Tu servidor dejará de comunicarse con estos servidores. + title: Confirmar bloqueo del dominio %{domain} + undo_relationships: Esto deshará cualquier relación (seguidores y seguidos) entre las cuentas de estos servidores y el tuyo. created_msg: El bloqueo del dominio está siendo procesado destroyed_msg: El bloqueo del dominio se deshizo domain: Dominio @@ -427,6 +439,7 @@ es: resolve: Resolver dominio title: Nueva entrada en la lista negra de correo no_email_domain_block_selected: No se han cambiado bloqueos de dominio ya que ninguno ha sido seleccionado + not_permitted: No permitido resolved_dns_records_hint_html: El nombre de dominio resuelve los siguientes dominios MX, los cuales son responsables en última instancia de aceptar el correo electrónico. Bloquear un dominio MX bloqueará los registros de cualquier dirección de correo electrónico que utilice el mismo dominio MX, incluso si el nombre de dominio visible es diferente. Tenga cuidado de no bloquear los principales proveedores de correo electrónico. resolved_through_html: Resuelto a través de %{domain} title: Lista negra de correo @@ -473,6 +486,7 @@ es: content_policies: comment: Nota interna description_html: Puedes definir políticas de contenido que se aplicarán a todas las cuentas de este dominio y a cualquiera de sus subdominios. + limited_federation_mode_description_html: Puedes elegir si permites la federación con este dominio. policies: reject_media: Rechazar multimedia reject_reports: Rechazar informes @@ -585,11 +599,13 @@ es: assign_to_self: Asignármela a mí assigned: Moderador asignado by_target_domain: Dominio de la cuenta reportada + cancel: Cancelar category: Categoría category_description_html: La razón por la que se reportó esta cuenta o contenido será citada en las comunicaciones con la cuenta reportada comment: none: Ninguno comment_description_html: 'Para proporcionar más información, %{name} escribió:' + confirm: Confirmar confirm_action: Confirmar acción de moderación contra @%{acct} created_at: Denunciado delete_and_resolve: Eliminar publicaciones @@ -725,6 +741,9 @@ es: branding: preamble: La marca de tu servidor lo diferencia de otros servidores de la red. Esta información puede mostrarse a través de una variedad de entornos, como en la interfaz web de Mastodon, en aplicaciones nativas, en previsualizaciones de enlaces en otros sitios web y en aplicaciones de mensajería, etc. Por esta razón, es mejor mantener esta información clara, breve y concisa. title: Marca + captcha_enabled: + desc_html: Esto se basa en scripts externos de hCaptcha, que pueden suponer una preocupación de seguridad y privacidad. Además, esto puede volver el proceso de registro significativamente menos accesible para algunas personas (especialmente con discapacidades). Por estas razones, por favor, considera medidas alternativas como el registro por aprobación manual o con invitación. + title: Solicita a los nuevos usuarios que resuelvan un CAPTCHA para confirmar su cuenta content_retention: preamble: Controlar cómo el contenido generado por el usuario se almacena en Mastodon. title: Retención de contenido @@ -752,10 +771,27 @@ es: approved: Se requiere aprobación para registrarse none: Nadie puede registrarse open: Cualquiera puede registrarse - title: Ajustes del Servidor + security: + authorized_fetch: Requerir autenticación de servidores federados + authorized_fetch_hint: Requerir autenticación de servidores federados permite un cumplimiento más estricto tanto de los bloqueos a nivel de usuario como a nivel de servidor. Sin embargo, esto se produce a costa de una penalización en el rendimiento, reduce el alcance de tus respuestas y puede introducir problemas de compatibilidad con algunos servicios federados. Además, esto no impedirá que actores dedicados obtengan tus cuentas y publicaciones públicas. + authorized_fetch_overridden_hint: No puedes cambiar esta configuración porque está sobreescrita por una variable de entorno. + federation_authentication: Forzar autenticación federada + title: Ajustes del servidor site_uploads: delete: Eliminar archivo subido destroyed_msg: "¡Carga del sitio eliminada con éxito!" + software_updates: + critical_update: Crítica— por favor actualiza rápidamente + description: Se recomienda mantener actualizada tu instalación de Mastodon para beneficiarte de las últimas correcciones y características. Además, a veces es crítico actualizar Mastodon de manera oportuna para evitar problemas de seguridad. Por estas razones, Mastodon comprueba si hay actualizaciones cada 30 minutos, y te notificará de acuerdo a tus preferencias de notificación por correo electrónico. + documentation_link: Aprender más + release_notes: Notas de la versión + title: Actualizaciones disponibles + type: Tipo + types: + major: Versión principal + minor: Versión menor + patch: Versión de parche — correcciones de errores y cambios fáciles de aplicar + version: Versión statuses: account: Autor application: Aplicación @@ -772,12 +808,12 @@ es: media: title: Multimedia metadata: Metadatos - no_status_selected: No se cambió ningún estado al no seleccionar ninguno + no_status_selected: No se cambió ninguna publicación al no seleccionar ninguna open: Abrir publicación original_status: Publicación original reblogs: Impulsos status_changed: Publicación cambiada - title: Estado de las cuentas + title: Publicaciones de la cuenta trending: En tendencia visibility: Visibilidad with_media: Con multimedia @@ -792,9 +828,24 @@ es: suspend: "%{name} suspendió la cuenta de %{target}" appeal_approved: Apelado appeal_pending: Apelación pendiente + appeal_rejected: Apelación rechazada system_checks: database_schema_check: message_html: Hay migraciones pendientes de la base de datos. Por favor, ejecútalas para asegurarte de que la aplicación funciona como debería + elasticsearch_health_red: + message_html: El estado del clúster de Elasticsearch no es saludable (estado rojo), las funciones de búsqueda no están disponibles + elasticsearch_health_yellow: + message_html: El estado del clúster de Elasticsearch no es saludable (estado amarillo), es posible que quieras investigar la razón + elasticsearch_index_mismatch: + message_html: Las asignaciones de índices de Elasticsearch están desactualizadas. Por favor, ejecute tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ver documentación + message_html: Tu clúster de Elasticsearch tiene más de un nodo, pero Mastodon no está configurado para usarlos. + elasticsearch_preset_single_node: + action: Ver documentación + message_html: Tu clúster de Elasticsearch solo tiene un nodo, ES_PRESET debe establecerse a single_node_cluster. + elasticsearch_reset_chewy: + message_html: Tu sistema de indexado Elasticsearch está desactualizado debido a un cambio de configuración. Ejecute tootctl search deploy --reset-chewy para actualizarlo. elasticsearch_running_check: message_html: No se pudo conectar a Elasticsearch. Por favor, comprueba que está ejecutándose, o desactiva la búsqueda de texto completo elasticsearch_version_check: @@ -805,6 +856,18 @@ es: message_html: No ha definido ninguna regla del servidor. sidekiq_process_check: message_html: No hay ningún proceso Sidekiq en ejecución para la(s) cola(s) %{value}. Por favor, revise su configuración de Sidekiq + software_version_critical_check: + action: Ver actualizaciones disponibles + message_html: Una actualización crítica de Mastodon está disponible, por favor actualiza lo antes posible. + software_version_patch_check: + action: Ver actualizaciones disponibles + message_html: Hay una actualización de Mastodon disponible con corrección de errores. + upload_check_privacy_error: + action: Haga clic aquí para obtener más información + message_html: "Su servidor web está mal configurado. La privacidad de sus usuarios está en riesgo." + upload_check_privacy_error_object_storage: + action: Haga clic aquí para obtener más información + message_html: "El almacenamiento de su objeto está mal configurado. La privacidad de sus usuarios está en riesgo." tags: review: Estado de revisión updated_msg: Hashtags actualizados exitosamente @@ -827,6 +890,7 @@ es: other: Compartido por %{count} personas durante la última semana title: Enlaces en tendencia usage_comparison: Compartido %{today} veces hoy, comparado con %{yesterday} ayer + not_allowed_to_trend: No permitido para tendencia only_allowed: Sólo las permitidas pending_review: Revisión pendiente preview_card_providers: @@ -838,7 +902,7 @@ es: statuses: allow: Permitir publicación allow_account: Permitir autor - description_html: Estos son publicaciones que su servidor conoce que están siendo compartidas y marcadas como favoritas mucho en este momento. Pueden ayudar a tus usuarios nuevos y retornantes a encontrar más gente a la que seguir. No hay mensajes que se muestren públicamente hasta que apruebes el autor y el autor permita que su cuenta sea sugerida a otros. También puedes permitir o rechazar mensajes individuales. + description_html: Estos son publicaciones que tu servidor conoce que están siendo compartidas y marcadas como favoritas mucho en este momento. Pueden ayudar a tus usuarios nuevos y retornantes a encontrar más personas a las que seguir. No hay mensajes que se muestren públicamente hasta que apruebes el autor y el autor permita que su cuenta sea sugerida a otros. También puedes permitir o rechazar mensajes individuales. disallow: No permitir publicación disallow_account: No permitir autor no_status_selected: No se cambió ninguna publicación en tendencia ya que no se seleccionó ninguna @@ -855,7 +919,7 @@ es: tag_servers_dimension: Servidores principales tag_servers_measure: diferentes servidores tag_uses_measure: usos totales - description_html: Estos son etiquetas que están apareciendo en muchos posts que tu servidor ve. Pueden ayudar a tus usuarios a averiguar de qué habla más gente en estos momentos. No hay hashtags que se muestren públicamente hasta que los apruebes. + description_html: Estos son etiquetas que están apareciendo en muchas publicaciones que llegan a tu servidor. Pueden ayudar a tus usuarios a averiguar de qué es lo que más hablan las personas en estos momentos. No hay etiquetas que se muestren públicamente hasta que las apruebes. listable: Pueden ser recomendadas no_tag_selected: No se cambió ninguna etiqueta ya que no se seleccionó ninguna not_listable: No serán recomendadas @@ -911,13 +975,19 @@ es: body: "%{target} está apelando a una solicitud de moderación de %{action_taken_by} el %{date}, del tipo %{type}. Ellos escribieron:" next_steps: Puedes aprobar la apelación para deshacer la decisión de moderación, o ignorarla. subject: "%{username} está apelando a una decisión de moderación en %{instance}" + new_critical_software_updates: + body: Se han lanzado nuevas versiones críticas de Mastodon, ¡es posible que quieras actualizar lo antes posible! + subject: "¡Hay actualizaciones de Mastodon críticas disponibles para %{instance}!" new_pending_account: body: Los detalles de la nueva cuenta están abajos. Puedes aprobar o rechazar esta aplicación. subject: Nueva cuenta para revisión en %{instance} (%{username}) new_report: body: "%{reporter} ha reportado a %{target}" body_remote: Alguien de %{domain} a reportado a %{target} - subject: Nuevo reporte para la %{instance} (#%{id}) + subject: Nuevo informe para %{instance} (#%{id}) + new_software_updates: + body: Se han liberado nuevas versiones de Mastodon, ¡es posible que quieras actualizar! + subject: "¡Las nuevas versiones de Mastodon están disponibles para %{instance}!" new_trends: body: 'Los siguientes elementos necesitan una revisión antes de que se puedan mostrar públicamente:' new_trending_links: @@ -947,24 +1017,28 @@ es: guide_link: https://es.crowdin.com/project/mastodon guide_link_text: Todos pueden contribuir. sensitive_content: Contenido sensible - toot_layout: Diseño de las publicaciones application_mailer: notification_preferences: Cambiar preferencias de correo electrónico salutation: "%{name}:" settings: 'Cambiar preferencias de correo: %{link}' + unsubscribe: Cancelar suscripción view: 'Vista:' view_profile: Ver perfil - view_status: Ver estado + view_status: Ver publicación applications: created: Aplicación creada exitosamente destroyed: Apicación eliminada exitosamente + logout: Cerrar sesión regenerate_token: Regenerar token de acceso token_regenerated: Token de acceso regenerado exitosamente warning: Ten mucho cuidado con estos datos. ¡No los compartas con nadie! your_token: Tu token de acceso auth: apply_for_account: Solicitar una cuenta - change_password: Contraseña + captcha_confirmation: + help_html: Si tienes problemas resolviendo el CAPTCHA, puedes contactarnos por email en %{email} y te ayudaremos. + hint_html: ¡Una última cosita! Necesitamos confirmar que eres humano (¡así podemos evitar el spam!). Resuelve este CAPTCHA de debajo y pulsa en "Continuar". + title: Comprobación de seguridad confirmations: wrong_email_hint: Si esa dirección de correo electrónico no es correcta, puedes cambiarla en la configuración de la cuenta. delete_account: Borrar cuenta @@ -972,8 +1046,8 @@ es: description: prefix_invited_by_user: "¡@%{name} te invita a unirte a este servidor de Mastodon!" prefix_sign_up: "¡Únete a Mastodon hoy!" - suffix: "¡Con una cuenta podrás seguir a gente, publicar novedades e intercambiar mensajes con usuarios de cualquier servidor de Mastodon y más!" - didnt_get_confirmation: "¿No recibió el correo de confirmación?" + suffix: "¡Con una cuenta podrás seguir a personas, publicar novedades e intercambiar mensajes con usuarios de cualquier servidor de Mastodon y más!" + didnt_get_confirmation: "¿No recibiste un enlace de confirmación?" dont_have_your_security_key: "¿No tienes tu clave de seguridad?" forgot_password: "¿Olvidaste tu contraseña?" invalid_reset_password_token: El token de reinicio de contraseña es inválido o expiró. Por favor pide uno nuevo. @@ -986,26 +1060,39 @@ es: migrate_account_html: Si deseas redireccionar esta cuenta a otra distinta, puedes configurarlo aquí. or_log_in_with: O inicia sesión con privacy_policy_agreement_html: He leído y acepto la política de privacidad + progress: + confirm: Confirmar dirección de correo + details: Tus detalles + review: Nuestra revisión + rules: Aceptar reglas providers: cas: CAS saml: SAML register: Registrarse registration_closed: "%{instance} no está aceptando nuevos miembros" - resend_confirmation: Volver a enviar el correo de confirmación + resend_confirmation: Reenviar enlace de confirmación reset_password: Restablecer contraseña rules: + accept: Aceptar + back: Atrás + invited_by: 'Puedes unirte a %{domain} gracias a la invitación que has recibido de:' preamble: Estas son establecidas y aplicadas por los moderadores de %{domain}. + preamble_invited: Antes de continuar, por favor, revisa las reglas básicas establecidas por los moderadores de %{domain}. title: Algunas reglas básicas. + title_invited: Has sido invitado. security: Cambiar contraseña set_new_password: Establecer nueva contraseña setup: - email_below_hint_html: Si la dirección de correo electrónico que aparece a continuación es incorrecta, se puede cambiarla aquí y recibir un nuevo correo electrónico de confirmación. - email_settings_hint_html: El correo electrónico de confirmación fue enviado a %{email}. Si esa dirección de correo electrónico no sea correcta, se puede cambiarla en la configuración de la cuenta. - title: Configuración + email_below_hint_html: Comprueba tu carpeta de correo no deseado o solicita otro enlace de confirmación. Puedes corregir tu dirección de correo electrónico si está mal. + email_settings_hint_html: Pulsa el enlace que te hemos enviado para verificar %{email}. Esperaremos aquí mismo. + link_not_received: "¿No recibiste un enlace?" + new_confirmation_instructions_sent: "¡Recibirás un nuevo correo electrónico con el enlace de confirmación en unos minutos!" + title: Revisa tu bandeja de entrada sign_in: preamble_html: Inicia sesión con tus credenciales de %{domain}. Si tu cuenta está alojada en un servidor diferente, no podrás iniciar sesión aquí. title: Iniciar sesión en %{domain} sign_up: + manual_review: Los registros en %{domain} pasan por la revisión manual de nuestros moderadores. Para ayudarnos a procesar tu registro, escribe un poco sobre ti mismo y por qué quieres una cuenta en %{domain}. preamble: Con una cuenta en este servidor de Mastodon, podrás seguir a cualquier otra persona en la red, independientemente del servidor en el que se encuentre. title: Crear cuenta de Mastodon en %{domain}. status: @@ -1017,18 +1104,6 @@ es: view_strikes: Ver amonestaciones pasadas contra tu cuenta too_fast: Formulario enviado demasiado rápido, inténtelo de nuevo. use_security_key: Usar la clave de seguridad - authorize_follow: - already_following: Ya estás siguiendo a esta cuenta - already_requested: Ya has enviado una solicitud de seguimiento a esa cuenta - error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota - follow: Seguir - follow_request: 'Tienes una solicitud de seguimiento de:' - following: "¡Éxito! Ahora estás siguiendo a:" - post_follow: - close: O, puedes simplemente cerrar esta ventana. - return: Regresar al perfil del usuario - web: Ir al sitio web - title: Seguir a %{acct} challenge: confirm: Continuar hint_html: "Tip: No volveremos a preguntarte por la contraseña durante la siguiente hora." @@ -1105,6 +1180,10 @@ es: your_appeal_rejected: Tu apelación ha sido rechazada domain_validator: invalid_domain: no es un nombre de dominio válido + edit_profile: + basic_information: Información básica + hint_html: "Personaliza lo que la gente ve en tu perfil público junto a tus publicaciones. Es más probable que otras personas te sigan e interactúen contigo cuando completas tu perfil y foto." + other: Otros errors: '400': La solicitud que has enviado no es valida o estaba malformada. '403': No tienes permiso para acceder a esta página. @@ -1185,8 +1264,6 @@ es: index: hint: Este filtro se aplica a la selección de publicaciones individuales independientemente de otros criterios. Puede añadir más publicaciones a este filtro desde la interfaz web. title: Publicaciones filtradas - footer: - trending_now: Tendencia ahora generic: all: Todos all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ es: all_matching_items_selected_html: one: "%{count} elemento que coincide con su búsqueda está seleccionado." other: Todos los %{count} elementos que coinciden con su búsqueda están seleccionados. + cancel: Cancelar changes_saved_msg: "¡Cambios guardados con éxito!" + confirm: Confirmar copy: Copiar delete: Eliminar deselect: Deseleccionar todo @@ -1209,24 +1288,62 @@ es: validation_errors: one: "¡Algo no está bien! Por favor, revisa el error" other: "¡Algo no está bien! Por favor, revise %{count} errores más abajo" - html_validator: - invalid_markup: 'contiene código HTML no válido: %{error}' imports: errors: + empty: Archivo CSV vacío + incompatible_type: Incompatible con el tipo de importación seleccionado invalid_csv_file: 'Archivo CSV no válido. Error: %{error}' over_rows_processing_limit: contiene más de %{count} filas + too_large: El archivo es demasiado grande + failures: Fallos + imported: Importado + mismatched_types_warning: Parece que podrías haber seleccionado el tipo incorrecto para esta importación, por favor vuelve a verificarlo. modes: merge: Unir merge_long: Mantener registros existentes y añadir nuevos overwrite: Sobrescribir overwrite_long: Reemplazar registros actuales con los nuevos + overwrite_preambles: + blocking_html: Estás a punto de reemplazar tu lista de bloqueos por hasta %{total_items} cuentas provenientes de %{filename}. + bookmarks_html: Estás a punto de reemplazar tus marcadores por hasta %{total_items} publicaciones provenientes de %{filename}. + domain_blocking_html: Estás a punto de reemplazar tu lista de bloqueos de dominio por hasta %{total_items} dominios provenientes de %{filename}. + following_html: Estás a punto de seguir hasta %{total_items} cuentas provenientes de %{filename} y dejar de seguir a cualquier otra cuenta. + lists_html: Estás a punto de reemplazar tus listas con contenidos de %{filename}. Se añadirán %{total_items} cuentas a nuevas listas. + muting_html: Estás a punto de reemplazar tu lista de cuentas silenciadas con hasta %{total_items} cuentas proveninetes de %{filename}. + preambles: + blocking_html: Estás a punto de bloquear hasta %{total_items} cuentas proveninetes de %{filename}. + bookmarks_html: Está a punto de añadir hasta %{total_items} publicaciones proveninetes de %{filename} a tus marcadores. + domain_blocking_html: Estás a punto de bloquear hasta %{total_items} dominios provenientes de %{filename}. + following_html: Estás a punto de seguir hasta cuentas%{total_items} provenientes de %{filename}. + lists_html: Estás a punto de añadir %{total_items} cuentas desde %{filename} a tus listas. Se crearán nuevas listas si no hay listas para añadirlas. + muting_html: Estás a punto de silenciar hasta %{total_items} cuentas provenientes de %{filename}. preface: Puedes importar ciertos datos, como todas las personas que estás siguiendo o bloqueando en tu cuenta en esta instancia, desde archivos exportados de otra instancia. + recent_imports: Importaciones recientes + states: + finished: Finalizado + in_progress: En curso + scheduled: Programado + unconfirmed: No confirmado + status: Estado success: Sus datos se han cargado correctamente y serán procesados en brevedad + time_started: Comenzado el + titles: + blocking: Importando cuentas bloqueadas + bookmarks: Importando marcadores + domain_blocking: Importando dominios bloqueados + following: Importando cuentas seguidas + lists: Importando listas + muting: Importando cuentas silenciadas + type: Importar tipo + type_groups: + constructive: Seguidores y marcadores + destructive: Bloqueos y silencios types: blocking: Lista de bloqueados bookmarks: Marcadores domain_blocking: Lista de dominios bloqueados following: Lista de seguidos + lists: Listas muting: Lista de silenciados upload: Cargar invites: @@ -1265,9 +1382,24 @@ es: failed_sign_in_html: Intento de inicio de sesión fallido con %{method} de %{ip} (%{browser}) successful_sign_in_html: Inicio de sesión exitoso con %{method} desde %{ip} (%{browser}) title: Historial de autenticación + mail_subscriptions: + unsubscribe: + action: Sí, cancelar suscripción + complete: Has cancelado tu suscripción + confirmation_html: ¿Estás seguro de que quieres dejar de recibir %{type} de Mastodon en %{domain} a tu email %{email}? Siempre podrás volver a suscribirte desde los ajustes de notificación por correo.. + emails: + notification_emails: + favourite: notificaciones de me gusta por correo + follow: notificaciones de seguidores por correo + follow_request: notificaciones de peticiones de seguimiento por correo + mention: notificaciones de menciones por correo + reblog: notificaciones de impulsos por correo + resubscribe_html: Si te has dado de baja por error, puedes volver a darte de alta desde tus ajustes de notificaciones por correo. + success_html: Ya no recibirás %{type} de mastodon en %{domain} a tu correo %{email}. + title: Cancelar suscripición media_attachments: validations: - images_and_video: No se puede adjuntar un video a un estado que ya contenga imágenes + images_and_video: No se puede adjuntar un video a unapublicación que ya contenga imágenes not_ready: No se pueden adjuntar archivos que no se han terminado de procesar. ¡Inténtalo de nuevo en un momento! too_many: No se pueden adjuntar más de 4 archivos migrations: @@ -1316,8 +1448,8 @@ es: sign_up: subject: "%{name} se registró" favourite: - body: 'Tu estado fue marcado como favorito por %{name}:' - subject: "%{name} marcó como favorito tu estado" + body: 'Tu publicación fue marcada como favorita por %{name}:' + subject: "%{name} marcó como favorita tu publicación" title: Nuevo favorito follow: body: "¡%{name} te está siguiendo!" @@ -1336,14 +1468,15 @@ es: poll: subject: Una encuesta de %{name} ha terminado reblog: - body: "%{name} ha retooteado tu publicación:" - subject: "%{name} ha retooteado tu publicación" + body: 'Tu publicación fue impulsada por %{name}:' + subject: "%{name} impulsó tu publicación" title: Nueva difusión status: subject: "%{name} acaba de publicar" update: subject: "%{name} editó una publicación" notifications: + administration_emails: Notificaciones de administración por correo electrónico email_events: Eventos para notificaciones por correo electrónico email_events_hint: 'Selecciona los eventos para los que deseas recibir notificaciones:' other_settings: Otros ajustes de notificaciones @@ -1380,12 +1513,22 @@ es: expired: La encuesta ya ha terminado invalid_choice: La opción de voto seleccionada no existe over_character_limit: no puede exceder %{max} caracteres cada uno + self_vote: No puedes votar en tus propias encuestas too_few_options: debe tener más de un elemento too_many_options: no puede contener más de %{max} elementos preferences: other: Otros posting_defaults: Configuración por defecto de publicaciones public_timelines: Líneas de tiempo públicas + privacy: + hint_html: "Personaliza el descubrimiento de tu perfil y tus publicaciones. En Mastodon tienes distintas características que te ayudarán a alcanzar una mayor audiencia si las activas. Tómate un momento para revisar estas configuraciones y asegurarte de que cumplen tus necesidades." + privacy: Privacidad + privacy_hint_html: Controla cuánto deseas revelar a los demás. Las personas descubren perfiles y aplicaciones interesantes navegando por los seguidores de otras personas y viendo desde qué aplicaciones publican, pero puede que prefieras mantenerlo oculto. + reach: Alcance + reach_hint_html: Controla si quieres ser descubierto y seguido por nuevas personas. ¿Quieres que tus publicaciones aparezcan en la sección de Explorar? ¿Quieres que tu cuenta se recomiende a otras personas? ¿Quieres aceptar automáticamente a todos los nuevos seguidores o tener control sobre cada uno de ellos? + search: Búsqueda + search_hint_html: Controla cómo quieres que te encuentren. ¿Quieres que otras personas te encuentren por lo que has publicado públicamente? ¿Quieres que las personas de fuera de Mastodon encuentren tu perfil al buscar en la web? Por favor, ten en cuenta que la exclusión total de todos los motores de búsqueda no puede ser garantizada para información pública. + title: Privacidad y alcance privacy_policy: title: Política de Privacidad reactions: @@ -1398,6 +1541,7 @@ es: confirm_remove_selected_followers: "¿Estás seguro de que quieres eliminar los seguidores seleccionados?" confirm_remove_selected_follows: "¿Estás seguro de que quieres eliminar los seguidos seleccionados?" dormant: Inactivo + follow_failure: No se pudieron seguir algunas de las cuentas seleccionadas. follow_selected_followers: Seguir a los seguidores seleccionados followers: Seguidores following: Siguiendo @@ -1437,6 +1581,7 @@ es: electron: Electron firefox: Firefox generic: Desconocido + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Navegador de Nokia S40 Ovi @@ -1446,6 +1591,7 @@ es: qq: Navegador QQ safari: Safari uc_browser: Navegador UC + unknown_browser: Navegador Desconocido weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1458,9 +1604,10 @@ es: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: GNU Linux mac: Mac - other: Desconocido + unknown_platform: Plataforma Desconocida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1511,7 +1658,7 @@ es: other: 'contenía los hashtags no permitidos: %{tags}' edited_at_html: Editado %{date} errors: - in_reply_not_found: El estado al que intentas responder no existe. + in_reply_not_found: La publicación a la que intentas responder no existe. open_in_web: Abrir en web over_character_limit: Límite de caracteres de %{max} superado pin_errors: @@ -1521,8 +1668,8 @@ es: reblog: Un boost no puede fijarse poll: total_people: - one: persona %{count} - other: "%{count} gente" + one: "%{count} persona" + other: "%{count} personas" total_votes: one: "%{count} voto" other: "%{count} votos" @@ -1531,7 +1678,6 @@ es: show_newer: Mostrar más recientes show_older: Mostrar más antiguos show_thread: Mostrar discusión - sign_in_to_participate: Regístrate para participar en la conversación title: "%{name}: «%{quote}»" visibilities: direct: Directa @@ -1573,12 +1719,10 @@ es: '7889238': 3 meses min_age_label: Umbral de tiempo min_favs: Mantener mensajes con un número de favoritos mayor que - min_favs_hint: No borra ninguna de las publicaciones que hayan recibido más de esta cantidad de favoritos. Deja en blanco para eliminar publicaciones sin importar el número de favoritos + min_favs_hint: No borra ninguna de las publicaciones que hayan recibido al menos esta cantidad de favoritos. Deja en blanco para eliminar publicaciones sin importar el número de favoritos min_reblogs: Mantener publicaciones reblogueadas más de min_reblogs_hint: No borra ninguna de las publicaciones que hayan sido reblogueadas más de este número de veces. Deja en blanco para eliminar publicaciones sin importar el número de reblogueos stream_entries: - pinned: Publicación fijada - reblogged: retooteado sensitive_content: Contenido sensible strikes: errors: @@ -1594,6 +1738,11 @@ es: default: "%d de %b del %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d de %b de %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Se ha sobrepasado la cuota de uso del servicio de traducción para todo el servidor. + too_many_requests: Ha habido demasiadas solicitudes al servicio de traducción recientemente. two_factor_authentication: add: Añadir disable: Deshabilitar @@ -1639,7 +1788,7 @@ es: explanation: delete_statuses: Se ha determinado que algunos de tus mensajes violan una o más directrices de la comunidad y han sido por tanto eliminados por los moderadores de %{instance}. disable: Ya no puedes usar tu cuenta, pero tu perfil y el resto de datos permanecen intactos. Puedes solicitar una copia de seguridad de tus datos, cambiar la configuración de tu cuenta o eliminarla. - mark_statuses_as_sensitive: Algunos de tus mensajes han sido marcados como sensibles por los moderadores de %{instance}. Esto significa que la gente tendrá que pulsar los archivos multimedia en las publicaciones antes de que se muestre una vista previa. Puedes marcar los archivos multimedia como sensibles tú mismo cuando publiques en el futuro. + mark_statuses_as_sensitive: Algunos de tus mensajes han sido marcados como sensibles por los moderadores de %{instance}. Esto significa que otras personas tendrán que pulsar los archivos multimedia en las publicaciones antes de que se muestre una vista previa. Puedes marcar los archivos multimedia como sensibles tú mismo cuando publiques en el futuro. sensitive: A partir de ahora, todos los archivos multimedia que subas serán marcados como sensibles y ocultos tras una advertencia que habrá que clicar. silence: Aún puedes usar tu cuenta, pero solo las personas que te están siguiendo verán tus publicaciones en este servidor, y puedes ser excluido de varias funcionalidades de descubrimiento. Sin embargo, otras cuentas podrán empezar a seguirte manualmente. suspend: Ya no puedes utilizar tu cuenta, y tu perfil y el resto de datos ya no son accesibles. Todavía puedes iniciar sesión para solicitar una copia de seguridad de tus datos, hasta que estos sean eliminados por completo en unos 30 días, aunque conservaremos algunos datos básicos para impedir que esquives la suspensión. @@ -1673,13 +1822,18 @@ es: title: Te damos la bienvenida a bordo, %{name}! users: follow_limit_reached: No puedes seguir a más de %{limit} personas + go_to_sso_account_settings: Diríjase a la configuración de la cuenta de su proveedor de identidad invalid_otp_token: Código de dos factores incorrecto otp_lost_help_html: Si perdiste al acceso a ambos, puedes ponerte en contancto con %{email} seamless_external_login: Has iniciado sesión desde un servicio externo, así que los ajustes de contraseña y correo no están disponibles. signed_in_as: 'Sesión iniciada como:' verification: - explanation_html: 'Puedes verificarte a ti mismo como el dueño de los links en los metadatos de tu perfil . Para eso, el sitio vinculado debe contener un vínculo a tu perfil de Mastodon. El vínculo en tu sitio debe tener un atributo rel="me". El texto del vínculo no importa. Aquí un ejemplo:' + extra_instructions_html: Consejo: El enlace en tu web puede ser invisible. La parte importante es rel="me", que evita la suplantación de identidad en sitios con contenido generado por el usuario. Puedes incluso usar una etiqueta enlace en el encabezado de la página en vez de a, pero el HTML debe ser accesible sin ejecutar JavaScript. + here_is_how: Así es como se hace + hint_html: "Verificar tu identidad en Mastodon es para todos. Basado en estándares web abiertos, ahora y para siempre. Todo lo que necesitas es un sitio web propio que la gente reconozca. Cuando enlaces a este sitio web desde tu perfil, comprobaremos que el sitio web se enlaza a tu perfil y mostraremos un indicador visual en él." + instructions_html: Copia y pega el siguiente código en el HTML de tu sitio web. A continuación, añade la dirección de su sitio web en uno de los campos extra de tu perfil desde la pestaña "Editar perfil" y guarda los cambios. verification: Verificación + verified_links: Tus enlaces verificados webauthn_credentials: add: Agregar nueva clave de seguridad create: diff --git a/config/locales/et.yml b/config/locales/et.yml index 12dabbbc21..4f5a83624e 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -91,6 +91,7 @@ et: moderation: active: Aktiivne all: Kõik + disabled: Keelatud pending: Ootel silenced: Vaigistatud suspended: Kustutatud @@ -124,8 +125,8 @@ et: removed_header_msg: "%{username} päisepilt eemaldatud" resend_confirmation: already_confirmed: See kasutaja on juba kinnitatud - send: Saada kinnituskiri uuesti - success: Kinnituskiri saadetud edukalt! + send: Saada kinnituslink uuesti + success: Kinnituslink saadetud edukalt! reset: Lähtesta reset_password: Salasõna lähtestamine resubscribe: Telli taas @@ -133,6 +134,7 @@ et: search: Otsi search_same_email_domain: Muud kasutajad sama e-posti domeeniga search_same_ip: Teised kasutajad, kellel on sama IP + security: Turvalisus security_measures: only_password: Ainult salasõna password_and_2fa: Salasõna ja 2-etapine autentimine (2FA) @@ -307,6 +309,7 @@ et: unpublish: Tühista avaldamine unpublished_msg: Teadaande eemaldamine avalikkusest õnnestus! updated_msg: Teadaande uuendamine õnnestus! + critical_update_pending: Kriitiline turvauuendus ootel custom_emojis: assign_category: Määra kategooria by_domain: Domeen @@ -380,6 +383,15 @@ et: undo: Eemalda lubatute nimekirjast domain_blocks: add_new: Lisa uus domeeniblokeering + confirm_suspension: + cancel: Tühista + confirm: Peata + permanent_action: Peatamise tühistamine ei taasta andmeid ega seoseid. + preamble_html: Oled peatamas domeeni %{domain} ja selle alamdomeene. + remove_all_data: See eemaldab sinu serverist selle domeeni kontode kogu sisu, meedia ja profiilide info. + stop_communication: Sinu server lõpetab infovahetuse nende serveritega. + title: Kinnita domeeni %{domain} blokeerimine + undo_relationships: See tühistab kõik sinu ja nende serverite kontode vahel loodud jälgimisseosed. created_msg: Domeeni blokeeringut töödeldakse destroyed_msg: Domeeniblokeering on tagasi võetud domain: Domeen @@ -427,6 +439,7 @@ et: resolve: Domeeni lahendamine title: Blokeeri uus e-posti domeen no_email_domain_block_selected: Ühtegi e-posti domeeni keeldu ei muudetud, kuna midagi polnud valitud + not_permitted: Ei ole lubatud resolved_dns_records_hint_html: Domeeninimi lahendub järgnevateks MX-domeenideks, mis vastutavad e-kirjade vastuvõtmise eest. MX-domeeni blokeerimine blokeerib liitumistaotlused kõigilt e-postiaadressidelt, mis kasutavad sama MX-domeeni, kuigi kasutatav domeeninimi on erinev. Ole tähelepanelik, et mitte blokeerida suuremaid e-postiteenuse pakkujaid. resolved_through_html: Lahendatud %{domain} kaudu title: E-posti keelunimekiri @@ -473,6 +486,7 @@ et: content_policies: comment: Sisemine märge description_html: On võimalik kirjeldada sisureeglid kõigile kontodele sellelt domeenilt ja alamdomeenidelt. + limited_federation_mode_description_html: Saad valida, kas selle domeeniga on födereerumine lubatud. policies: reject_media: Meedia hülgamine reject_reports: Lükka raportid tagasi @@ -585,16 +599,18 @@ et: assign_to_self: Määra mulle assigned: Määratud moderaator by_target_domain: Teavitatud konto domeen + cancel: Tühista category: Kategooria category_description_html: Põhjus, miks sellest kontost ja/või sisust teatati, kaasatakse raporteeritud kontoga suhtlemisel comment: none: Pole comment_description_html: 'Täiendava infona kirjutas %{name}:' + confirm: Kinnita confirm_action: Kinnita @%{acct} modereering created_at: Teavitatud delete_and_resolve: Kustuta postitused forwarded: Edastatud - forwarded_to: Edastatud domeenile %{domain} + forwarded_to: Edastatud %{domain} domeeni mark_as_resolved: Märgi lahendatuks mark_as_sensitive: Märgi kui tundlik sisu mark_as_unresolved: Märgi lahendamata @@ -725,6 +741,9 @@ et: branding: preamble: Serveri bränding eristab seda teistest serveritest võrgus. Seda teavet võidakse kuvada erinevates keskkondades, näiteks Mastodoni veebiliideses, rakendustes, viitade eelvaadetes teistel veebisaitidel, sõnumsiderakendustes jne. Sel põhjusel on kõige parem hoida see teave selge, lühike ja ülevaatlik. title: Märgistus + captcha_enabled: + desc_html: See tugineb välistele hCaptcha skriptidele, mis võib olla turvalisuse ja privaatsuse probleem. Lisaks võib see muuta registreerimisprotsessi mõnede inimeste (eriti puudega inimeste) jaoks, oluliselt vähem ligipääsetavaks. Neil põhjustel kaalu palun teisi võimalusi, näiteks kinnitamis- või kutsepõhiseid registreerimislahendusi. + title: Nõua uutelt kasutajatelt konto kinnitamiseks CAPTCHA lahendamist content_retention: preamble: Määra, kuidas kasutajate loodud sisu Mastodonis talletatakse. title: Sisu talletamine @@ -752,10 +771,27 @@ et: approved: Kinnitus vajalik konto loomisel none: Keegi ei saa kontoid luua open: Kõik võivad kontoid luua - title: Serveri seadistused + security: + authorized_fetch: Nõua föderatiivse serveripoolset autoriseerimist + authorized_fetch_hint: Föderatiivsete serverite poolse autoriseerimise nõudmine võimaldab nii kasutaja- kui ka serveritasandi blokeeringute rangemat jõustamist. See toob aga kaasa jõudluse vähenemise, vähendab vastuste ulatust ja võib tekitada ühilduvusprobleeme mõne ühendatud teenusega. Lisaks ei takista see teatud kasutajatel sinu avalike postituste ja kontode kättesaamist. + authorized_fetch_overridden_hint: Sa ei saa hetkel seda seadistust muuta, sest see on keskkonnamuutuja poolt alistatud. + federation_authentication: Föderatiivse autentimise jõustamine + title: Serveri seaded site_uploads: delete: Kustuta üleslaetud fail destroyed_msg: Üleslaetud fail edukalt kustutatud! + software_updates: + critical_update: Kriitiline — uuenda kiiresti + description: On soovitav hoida oma Mastodoni paigaldus kõige uuemal kujul, et saada kasu kõige värskematest parandustest ja oskustest. Lisaks, vahel on Mastodoni kiire uuendamine kriitiline, et vältida turvaprobleeme. Neil põhjustel kontrollib Mastodon uuendusi iga 30 minuti tagant ja teavitab sind vastavalt su e-posti teavituste eelistustele. + documentation_link: Saa rohkem teada + release_notes: Väljalaskemärkused + title: Saadaval uuendused + type: Tüüp + types: + major: Suur uuendus + minor: Väike uuendus + patch: Parandusuuendus — veaparandused ja hõlpsalt rakendatavad muudatused + version: Versioon statuses: account: Autor application: Rakendus @@ -792,6 +828,7 @@ et: suspend: "%{name} kustutas %{target} konto" appeal_approved: Vaidlustatud appeal_pending: Vaidlustus on ootel + appeal_rejected: Vaidlustus tagasi lükatud system_checks: database_schema_check: message_html: On ootel andmebaasi migreerimisi. Rakenduse ootuspäraseks toimimiseks palun käivita need @@ -805,6 +842,18 @@ et: message_html: Serverireegleid pole defineeritud. sidekiq_process_check: message_html: Ühtegi Sidekiq protsessi pole %{value} järjekorra jaoks. Sidekiq seadistus vajab üle vaatamist + software_version_critical_check: + action: Vaata saadaolevaid uuendusi + message_html: Saadaval on Mastodoni kriitiline uuendus, uuenda nii kiiresti kui võimalik. + software_version_patch_check: + action: Vaata saadaolevaid uuendusi + message_html: Saadaval on Mastodoni veaparandusuuendus. + upload_check_privacy_error: + action: Klõpsa lisainfo saamiseks siia + message_html: "Veebiserver on valesti seadistatud. Kasutajate privaatsus on ohustatud." + upload_check_privacy_error_object_storage: + action: Klõpsa lisainfo saamiseks siia + message_html: "Objektihoidla on valesti seadistatud. Kasutajate privaatsus on ohustatud." tags: review: Vaata olek üle updated_msg: Sildi sätted edukalt uuendatud @@ -827,6 +876,7 @@ et: other: Jagatud %{count} kasutaja poolt viimase nädala jooksul title: Trendikad viited usage_comparison: Jagatud %{today} korda täna, eile %{yesterday} korda + not_allowed_to_trend: Trend ei ole lubatud only_allowed: Ainult lubatud pending_review: Ootab ülevaatust preview_card_providers: @@ -911,6 +961,9 @@ et: body: "%{target} vaidlustab %{action_taken_by} modereerimisotsuse kuupäevaga %{date}: %{type}. Põhjendus:" next_steps: Võid modereeringu tagasi pööramiseks vaidlustuse rahuldada, või ka mitte. subject: "%{username} on vaidlustanud %{instance} modereerimisotsuse" + new_critical_software_updates: + body: Avaldatud on Mastodoni uus kriitiline versioon, sa võiksid selle paigaldada nii ruttu kui võimalik! + subject: Saadaval on Mastodoni kriitilised uuendused %{instance} jaoks! new_pending_account: body: Uue konto üksikasjad on allpool. Saad taotluse vastu võtta või tagasi lükata. subject: Uus konto valmis ülevaatluseks serveril %{instance} (%{username}) @@ -918,6 +971,9 @@ et: body: "%{reporter} teavitas kasutajast %{target}" body_remote: Keegi domeenist %{domain} teavitas kasutajast %{target} subject: Uus teavitus %{instance}-ile (#%{id}) + new_software_updates: + body: Avaldatud on Mastodoni uued versioonid. Sa võiksid uuendada! + subject: Saadaval on Mastodoni uued versioonid %{instance} jaoks! new_trends: body: 'Järgmised üksused vajavad enne avalikustamist ülevaatust:' new_trending_links: @@ -947,33 +1003,37 @@ et: guide_link: https://crowdin.com/project/mastodon/et guide_link_text: Panustada võib igaüks! sensitive_content: Tundlik sisu - toot_layout: Postituse väljanägemine application_mailer: notification_preferences: Muuda e-kirjade eelistusi salutation: "%{name}!" settings: 'Muuda e-kirjade eelistusi: %{link}' + unsubscribe: Loobu tellimisest view: 'Vaade:' view_profile: Vaata profiili view_status: Vaata postitust applications: created: Rakenduse loomine õnnestus destroyed: Rakenduse kustutamine õnnestus + logout: Logi välja regenerate_token: Loo uus access token token_regenerated: Access tokeni loomine õnnestus warning: Ole nende andmetega ettevaatlikud. Ära jaga neid kellegagi! your_token: Su juurdepääsutunnus auth: apply_for_account: Konto taotluse esitamine - change_password: Salasõna + captcha_confirmation: + help_html: Kui sul on probleeme CAPTCHA lahendamisega, saad meiega kontakti võta %{email} kaudu ja saame pakkuda sulle tuge. + hint_html: Üks asi veel! Me peame veenduma, et oled inimene (et me saaksime spämmi väljaspoole jätta!). Lahenda allpool olev CAPTCHA ja klõpsa "Jätka". + title: Turvalisuse kontroll confirmations: wrong_email_hint: Kui see e-postiaadress pole korrektne, saad seda kontosätetes muuta. delete_account: Konto kustutamine delete_account_html: Kui soovid oma konto kustutada, siis jätka siit. Pead kustutamise eraldi kinnitama. description: - prefix_invited_by_user: "@%{name} kutsub Teid liituma selle Mastodoni serveriga!" + prefix_invited_by_user: "@%{name} kutsub sind liituma selle Mastodoni serveriga!" prefix_sign_up: Loo Mastodoni konto juba täna! suffix: Kasutajakontoga saad jälgida inimesi, postitada uudiseid ning pidada kirjavahetust ükskõik millise Mastodoni serveri kasutajatega ja muudki! - didnt_get_confirmation: Ei saanud kinnituse juhendeid? + didnt_get_confirmation: Ei saanud kinnituslinki? dont_have_your_security_key: Pole turvavõtit? forgot_password: Salasõna ununenud? invalid_reset_password_token: Salasõna lähtestusvõti on vale või aegunud. Palun taotle uus. @@ -986,26 +1046,39 @@ et: migrate_account_html: Kui soovid konto siit ära kolida, saad seda teha siin. or_log_in_with: Või logi sisse koos privacy_policy_agreement_html: Olen tutvunud isikuandmete kaitse põhimõtetega ja nõustun nendega + progress: + confirm: Kinnita e-post + details: Sinu üksikasjad + review: Meie ülevaatamine + rules: Nõustu reeglitega providers: cas: CAS saml: SAML register: Loo konto registration_closed: "%{instance} ei võta vastu uusi liikmeid" - resend_confirmation: Saada kinnitusjuhendid uuesti + resend_confirmation: Saada kinnituslink uuesti reset_password: Salasõna lähtestamine rules: + accept: Nõus + back: Tagasi + invited_by: 'Saad ühineda paigaga %{domain} tänu saadud kutsele, mille said kohast:' preamble: Neist kinnipidamist jälgivad %{domain} moderaatorid. + preamble_invited: Enne jätkamist kaalu põhireegleid, mille on kehtestanud %{domain} moderaatorid. title: Mõned põhireeglid. + title_invited: Oled kutsutud. security: Turvalisus set_new_password: Uue salasõna määramine setup: - email_below_hint_html: Kui allolev e-posti aadress on vale, saad seda muuta siin. Seejärel saadetakse uus kinnituskiri. - email_settings_hint_html: Kinnituskiri saadeti e-posti aadressile %{email}. Kui see aadress pole õige, saad muuta seda oma konto sätetest. - title: Seadistamine + email_below_hint_html: Kontrolli rämpspostikausta või taotle uut. Saad parandada e-postiaadressi, kui see on vale. + email_settings_hint_html: Klõpsa linki, mis saadeti sulle, et kinnitada %{email}. Seni me ootame. + link_not_received: Kas ei saanud linki? + new_confirmation_instructions_sent: Saad mõne minutiga uue kinnituslingiga e-kirja! + title: Kontrolli sisendkasti sign_in: preamble_html: Logi sisse oma %{domain} volitustega. Kui konto asub teises serveris, ei saa siin sisse logida. title: Logi sisse kohta %{domain} sign_up: + manual_review: Liitumised kohas %{domain} vaadatakse meie moderaatorite poolt käsitsi läbi. Aitamaks meil sinu taotlust läbi vaadata, kirjuta palun natuke endast ja miks soovid kontot kohas %{domain}. preamble: Selle kontoga saad jälgida ja suhelda kõigi teiste kasutajatega erinevates Mastodoni serverites. title: Loo konto serverisse %{domain}. status: @@ -1017,18 +1090,6 @@ et: view_strikes: Vaata enda eelnevaid juhtumeid too_fast: Vorm esitatud liiga kiirelt, proovi uuesti. use_security_key: Kasuta turvavõtit - authorize_follow: - already_following: Juba jälgid seda kontot - already_requested: Saatsid juba sellele kontole jälgimistaotluse - error: Kahjuks ilmus viga kasutaja kaugserverist otsimisel - follow: Jälgi - follow_request: 'Oled saatnud jälgimistaotluse kasutajale:' - following: 'Õnnestus! Jälgid nüüd kasutajat:' - post_follow: - close: Või sulge lihtsalt see aken. - return: Näita kasutaja profiili - web: Mine veebi - title: Jälgi %{acct} challenge: confirm: Jätka hint_html: "Nõuanne: Me ei küsi salasõna uuesti järgmise tunni jooksul." @@ -1105,6 +1166,10 @@ et: your_appeal_rejected: Vaidlustus on tagasi lükatud domain_validator: invalid_domain: ei ole sobiv domeeni nimi + edit_profile: + basic_information: Põhiinfo + hint_html: "Kohanda, mida inimesed näevad su avalikul profiilil ja postituste kõrval. Inimesed alustavad tõenäolisemalt sinu jälgimist ja interakteeruvad sinuga, kui sul on täidetud profiil ja profiilipilt." + other: Muu errors: '400': Esitatud päring oli vigane või valesti vormindatud. '403': Sul puudub õigus seda lehte vaadata. @@ -1185,8 +1250,6 @@ et: index: hint: See filter kehtib üksikute postituste valimisel, sõltumata muudest kriteeriumidest. Sellesse filtrisse saab veebiliidese kaudu rohkem postitusi lisada. title: Filtreeritud postitused - footer: - trending_now: Praegu trendikad generic: all: Kõik all_items_on_page_selected_html: @@ -1195,7 +1258,9 @@ et: all_matching_items_selected_html: one: "%{count} otsinguvaste valitud." other: Kõik %{count} otsinguvastet valitud. + cancel: Tühista changes_saved_msg: Muudatuste salvestamine õnnestus! + confirm: Kinnita copy: Kopeeri delete: Kustuta deselect: Ära vali midagi @@ -1209,24 +1274,62 @@ et: validation_errors: one: Midagi pole ikka õigesti! Palun vaata allolev veateade üle other: Midagi pole ikka õigesti! Palun vaata all olevad %{count} veateadet üle - html_validator: - invalid_markup: 'sisaldab valet HTMLi süntaksi: %{error}' imports: errors: + empty: Tühi CSV-fail + incompatible_type: Ei sobi kokku valitud importimistüübiga invalid_csv_file: 'Vigane CSV-fail. Tõrge: %{error}' over_rows_processing_limit: sisaldab rohkem, kui %{count} rida + too_large: Fail on liiga suur + failures: Ebaõnnestumised + imported: Imporditud + mismatched_types_warning: Näib, et oled selle importimise jaoks valinud vale tüübi. Palun kontrolli üle. modes: merge: Lõimi merge_long: Hoia olemasolevad andmed ja lisa uusi overwrite: Kirjuta üle overwrite_long: Vaheta praegused andmed uute vastu + overwrite_preambles: + blocking_html: Oled asendamas oma blokeeringute loetelu kuni %{total_items} kontoga kohast %{filename}. + bookmarks_html: Oled asendamas oma järjehoidjaid kuni %{total_items} postitusega kohast %{filename}. + domain_blocking_html: Oled asendamas oma domeenide blokeeringute loetelu kuni %{total_items} domeeniga kohast %{filename}. + following_html: Oled jälgima hakkamas kuni %{total_items} kontot kohast %{filename} ja lõpetad kõigi teiste jälgimise. + lists_html: Oled asendamas oma loetelusid faili %{filename} sisuga. Uutesse loeteludesse lisatakse kuni %{total_items} kontot. + muting_html: Oled asendamas oma vaigistatud kontode loetelu kuni %{total_items} kontoga kohast %{filename}. + preambles: + blocking_html: Oled blokeerimas kuni %{total_items} kontoga kohast %{filename}. + bookmarks_html: Oled lisamas kuni %{total_items} postitust kohast %{filename} to your bookmarks. + domain_blocking_html: Oled blokeerimas kuni %{total_items} domeeni kohast %{filename}. + following_html: Oled jälgima hakkamas kuni %{total_items} kontot kohast %{filename}. + lists_html: Oled lisamas oma loeteludesse failist %{filename} kuni %{total_items} kontot. Kui pole loetelusi, kuhu lisada, luuakse uued loetelud. + muting_html: Oled vaigistamas kuni %{total_items} kontot kohast %{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: + finished: Valmis + in_progress: Töös + scheduled: Ajastatud + unconfirmed: Kinnitamata + status: Olek success: Andmete üleslaadimine õnnestus ning neid töödeldakse + time_started: Algus + titles: + blocking: Blokeeritud kontode importimine + bookmarks: Järjehoidjate importimine + domain_blocking: Blokeeritud domeenide importimine + following: Jälgitavate kontode importimine + lists: Loetelude importimine + muting: Vaigistatud kontode importimine + type: Importimise tüüp + type_groups: + constructive: Jälgimised & Järjehoidjad + destructive: Blokeerimised & Vaigistamised types: blocking: Blokeeringute nimekiri bookmarks: Järjehoidjad domain_blocking: Domeeniblokeeringute nimekiri following: Jälgimiste nimekiri + lists: Loetelud muting: Vaigistuse nimekiri upload: Lae üles invites: @@ -1241,7 +1344,7 @@ et: '86400': 1 päev expires_in_prompt: Mitte kunagi generate: Loo - invited_by: 'Teid kutsus:' + invited_by: 'Sind kutsus:' max_uses: one: 1 kasutus other: "%{count} kasutust" @@ -1265,6 +1368,21 @@ et: failed_sign_in_html: Nurjunud sisenemine meetodiga %{method} aadressilt %{ip} (%{browser}) successful_sign_in_html: Edukas sisenemine meetodiga %{method} aadressilt %{ip} (%{browser}) title: Autentimise ajalugu + mail_subscriptions: + unsubscribe: + action: Jah, lõpeta tellimine + complete: Tellimine lõpetatud + confirmation_html: Oled kindel, et soovid lõpetada domeenilt %{domain} Mastodoni %{type} teadete tellimise oma e-postile %{email}? Saad alati neid teavitusi uuesti tellida oma e-posti teavituste seadetest. + emails: + notification_emails: + favourite: lemmikuks märkimise e-kirjad + follow: jälgimisest teatamise e-kirjad + follow_request: jälgimise taotluse e-kirjad + mention: mainimistest teatamise e-kirjad + reblog: jagamise teavitamise e-kirjad + resubscribe_html: Kui loobusid tellimisest ekslikult, saad uuesti tellida oma e-posti teavituste seadetest. + success_html: Sa ei saa rohkem %{domain} Mastodoni jaoks %{type} teavitusi e-postiaadressile %{email}. + title: Loobu tellimisest media_attachments: validations: images_and_video: Ei saa lisada video postitusele, milles on juba pildid @@ -1325,13 +1443,13 @@ et: title: Uus jälgija follow_request: action: Halda jälgimistaotlusi - body: "%{name} soovib Teid jälgida" + body: "%{name} soovib sind jälgida" subject: 'Ootav jälgija: %{name}' title: Uus jälgimistaotlus mention: action: Vasta - body: "%{name} mainis Teid:" - subject: "%{name} mainis Teid" + body: "%{name} mainis sind:" + subject: "%{name} mainis sind" title: Uus mainimine poll: subject: "%{name} küsitlus lõppes" @@ -1344,6 +1462,7 @@ et: update: subject: "%{name} muutis postitust" notifications: + administration_emails: Admini e-postiteavitused email_events: E-posti teadete sündmused email_events_hint: 'Vali sündmused, mille kohta soovid teavitusi:' other_settings: Muud teadete sätted @@ -1380,12 +1499,22 @@ et: expired: See küsitlus on juba lõppenud invalid_choice: Valitud küsitluse valikut pole olemas over_character_limit: igaüks ei saa olla rohkem kui %{max} tähemärki + self_vote: Sa ei saa enda hääletustel hääletada too_few_options: peab olema rohkem kui üks vastus too_many_options: ei saa sisaldada rohkem kui %{max} vastust preferences: other: Muu posting_defaults: Postitamise vaikesätted public_timelines: Avalikud ajajooned + privacy: + hint_html: "Kohanda, kuidas peaks su postitused ja profiil leitav olema. Mastodonis olevad paljud oskused võimaldavad jõuda sul rohkemate inimesteni, kui need lubada. Võta üks hetk, et vaadata need üle, et veenduda, kas sinu puhul need sobivad." + privacy: Privaatsus + privacy_hint_html: Määra, kui palju soovid teiste heaks infot avaldada. Inimesed leiavad huvitavaid profiile ning lahedaid äppe sirvides teiste inimeste jälgimisi ja vaadates, milliste äppidega nad postitavad, kuid sa võid soovida hoida seda varjatuna. + reach: Ulatus + reach_hint_html: Määra, kas soovid olla leitav ja jälgitav uute inimeste poolt. Kas soovid, et su postitused ilmuksid uurimise ekraanil? Kas soovid, et teised inimesed näeksid sind oma jälgitavate soovituste hulgas? Kas soovid nõustuda kõigi uute jälgijatega automaatselt või soovid igaühe puhul täpsemaid valikuid? + search: Otsi + search_hint_html: Määra, kuidas sind leitakse. Kas soovid, et inimesed leiavad sind su avalike postituste alusel? Kas soovid, et väljaspool Mastodoni olevad inimesed leiavad veebis otsides su profiili? Pea meeles, et avaliku info puhul pole kõigist otsimootoritest info välistamine tagatav. + title: Privaatsus ja ulatus privacy_policy: title: Isikuandmete kaitse reactions: @@ -1398,6 +1527,7 @@ et: confirm_remove_selected_followers: Oled kindel, et soovid eemaldada valitud jälgijad? confirm_remove_selected_follows: Oled kindel, et soovid eemaldada valitud jälgitavad? dormant: Seisev + follow_failure: Mõne valitud konto jälgimine polnud võimalik. follow_selected_followers: Valitud jälgijate jälgimine followers: Jälgijad following: Jälgib @@ -1437,6 +1567,7 @@ et: electron: Electron firefox: Firefox generic: Tundmatu veebilehitseja + huawei_browser: Huawei veebilehitseja ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1577,7 @@ et: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Tundmatu veebilehitseja weibo: Weibo current_session: Praegune seanss description: "%{browser} platvormil %{platform}" @@ -1458,9 +1590,10 @@ et: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: tundmatu platvorm + unknown_platform: Tundmatu platvorm windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1531,7 +1664,6 @@ et: show_newer: Uuemate kuvamine show_older: Vanemate kuvamine show_thread: Kuva lõim - sign_in_to_participate: Logi sisse, et liituda vestlusega title: '%{name}: "%{quote}"' visibilities: direct: Otsene @@ -1573,12 +1705,12 @@ et: '7889238': 3 kuud min_age_label: Ajalimiit min_favs: Säilita postitused, meeldimistega vähemalt - min_favs_hint: Ei kustuta ühtegi postitust, mis on saanud vähemalt nii palju lemmikuks märkimist. Postituste kustutamiseks olenemata nende lemmikuks märkimise arvust, jäta tühjaks + min_favs_hint: |- + Ei kustuta ühtegi postitust, mis on saanud vähemalt nii palju lemmikuks märkimist. Postituste kustutamiseks olenemata nende lemmikuks märkimise arvust, + jäta tühjaks min_reblogs: Säilita postitused jagatud vähemalt min_reblogs_hint: Ei kustuta postitusi, kui need on jagatud vähemalt nii mitu korda. Tühjaks jättes kustuvad postitused olenemata jagamistest stream_entries: - pinned: Kinnitatud postitus - reblogged: jagatud sensitive_content: Tundlik sisu strikes: errors: @@ -1594,6 +1726,11 @@ et: default: "%d. %B, %Y. aastal, kell %H:%M" month: "%B %Y" time: "%H:%M" + with_time_zone: "%b. %d %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Üle-serveriline tõlketeenuse kasutuskvoot on ületatud. + too_many_requests: Viimane aeg on tõlketeenusele esitatud liiga palju taotlusi. two_factor_authentication: add: Lisa disable: Keela 2FA @@ -1676,13 +1813,18 @@ et: title: Tere tulemast, %{name}! users: follow_limit_reached: Ei saa jälgida rohkem kui %{limit} inimest + go_to_sso_account_settings: Mine oma idenditeedipakkuja kontosätetesse invalid_otp_token: Vale kaheastmeline võti otp_lost_help_html: Kui kaotasid ligipääsu mõlemale, saad võtta ühendust %{email}-iga seamless_external_login: Välise teenuse kaudu sisse logides pole salasõna ja e-posti sätted saadaval. signed_in_as: 'Sisse logitud kasutajana:' verification: - explanation_html: 'Saad kinnitada ennast oma profiili veebiviidete omanikuna. Selleks peab viidatud veebilehel olema link tagasi su Mastodoni profiilile. Tagasi saatval lingil peab olema rel="me" atribuut. Lingi tekstiline sisu ei ole oluline. Siin on üks näide:' + extra_instructions_html: Soovitus: Sinu kodulehel olev link võib olla nähtamatu. Oluline osa on rel="me", mis väldib kasutaja loodud sisuga lehtedel libaisikustamist. Sa saad isegi kasutada lehe HEADER osas silti link sildi a asemel, kuid HTML peab olema kättesaadav ilma JavaScripti käivitamata. + here_is_how: Siin on, kuidas + hint_html: "Oma isiku tuvastamine on Mastodonis kõigi jaoks. Toetub avatud veebistandarditele, nüüd ja igavesti tasuta. Kõik, mida vajad, on isiklik veebileht, mille järgi inimesed sind tunnevad. Kui lingid oma profiililt sellele veebilehele, kontrollime me, et see veebileht lingib tagasi sinu profiilile ning näitame profiilil visuaalset tähist." + instructions_html: Kopeeri ja kleebi allpool olev kood oma lehe HTML lähtekoodi. Seejärel lisa oma kodulehe aadress profiili "Muuda profiili" taabi ühte lisavälja ning salvesta muudatused. verification: Kinnitamine + verified_links: Sinu kontrollitud lingid webauthn_credentials: add: Uue turvavõtme lisamine create: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 917a70e401..d21259ee77 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -38,12 +38,12 @@ eu: avatar: Abatarra by_domain: Domeinua change_email: - changed_msg: Eposta kontua ongi aldatu da! - current_email: Uneko e-mail helbidea - label: Aldatu e-mail helbidea - new_email: E-mail berria - submit: Aldatu e-mail helbidea - title: Aldatu %{username}(r)en e-mail helbidea + changed_msg: Ongi aldatu da eposta kontua! + current_email: Uneko eposta helbidea + label: Aldatu eposta helbidea + new_email: Eposta berria + submit: Aldatu eposta helbidea + title: Aldatu %{username}(r)en eposta helbidea change_role: changed_msg: Rola ondo aldatu da! label: Aldatu rola @@ -64,8 +64,8 @@ eu: display_name: Pantaila-izena domain: Domeinua edit: Editatu - email: E-mail - email_status: Posta elektronikoaren egoera + email: Eposta + email_status: Epostaren egoera enable: Gaitu enable_sign_in_token_auth: Gaitu e-posta token autentifikazioa enabled: Gaituta @@ -91,6 +91,7 @@ eu: moderation: active: Aktiboa all: Denak + disabled: Desgaituta pending: Zain silenced: Mugatua suspended: Kanporatua @@ -124,8 +125,8 @@ eu: removed_header_msg: "%{username} erabiltzailearen goiburuko irudia behar bezala kendu da" resend_confirmation: already_confirmed: Erabiltzaile hau berretsita dago - send: Birbidali baieztapen e-maila - success: Baieztapen e-maila ongi bidali da! + send: Bidali berrespen-esteka berriro + success: Berrespen-esteka ongi bidali da! reset: Berrezarri reset_password: Berrezarri pasahitza resubscribe: Berriro harpidetu @@ -133,6 +134,7 @@ eu: search: Bilatu search_same_email_domain: E-mail domeinu bera duten beste erabiltzailean search_same_ip: IP bera duten beste erabiltzaileak + security: Segurtasuna security_measures: only_password: Soilik pasahitza password_and_2fa: Pasahitza eta 2FA @@ -154,7 +156,7 @@ eu: title: Kontuak unblock_email: Desblokeatu eposta helbidea unblocked_email_msg: Behar bezala desblokeatu da %{username} eposta helbidea - unconfirmed_email: Baieztatu gabeko e-mail helbidea + unconfirmed_email: Baieztatu gabeko eposta helbidea undo_sensitized: Desegin hunkigarria undo_silenced: Utzi isilarazteari undo_suspension: Desegin kanporatzea @@ -307,6 +309,7 @@ eu: unpublish: Desargitaratu unpublished_msg: Iragarpena ongi desargitaratu da! updated_msg: Iragarpena ongi eguneratu da! + critical_update_pending: Eguneraketa kritikoa egiteke custom_emojis: assign_category: Esleitu kategoria by_domain: Domeinua @@ -380,6 +383,15 @@ eu: undo: Kendu zerrenda zuritik domain_blocks: add_new: Gehitu domeinuaren blokeo berria + confirm_suspension: + cancel: Utzi + confirm: Eten + permanent_action: Etenaldia uzteak ez ditu datuak edo elkarreraginak leheneratuko. + preamble_html: "%{domain} eta bere azpidomeinuak etetzera zoaz." + remove_all_data: Honek domeinuko kontuen eduki, media, eta profiletako datu guztiak kenduko ditu zure zerbitzaritik. + stop_communication: Zure zerbitzariak zerbitzari hauekin komunikatzeari utziko dio. + title: Berretsi %{domain} domeinuaren blokeoa + undo_relationships: Honek zerbitzari honetako eta zure zerbitzariko edozein elkarreragin desegingo ditu. created_msg: Domeinuaren blokeoa orain prozesatzen ari da destroyed_msg: Domeinuaren blokeoa desegin da domain: Domeinua @@ -429,6 +441,7 @@ eu: resolve: Ebatzi domeinua title: Sarrera berria e-mail zerrenda beltzean no_email_domain_block_selected: Ez da eposta domeinu blokeorik aldatu ez delako bat ere hautatu + not_permitted: Baimendu gabea resolved_dns_records_hint_html: Domeinu-izena ondorengo MX domeinuetara ebazten da, zeinek eposta onartzeko ardura duten. MX domeinu bat blokeatzeak MX domeinu hori erabiltzen duen edozein helbide elektronikotatik izena-ematea blokeatzen du, baita ikusgai dagoen domeinu-izena beste bat bada ere. Kontuz ibili eposta hornitzaile nagusiak blokeatu gabe. resolved_through_html: "%{domain} domeinuaren bidez ebatzia" title: E-mail zerrenda beltza @@ -471,10 +484,11 @@ eu: back_to_limited: Mugatua back_to_warning: Abisua by_domain: Domeinua - confirm_purge: Ziur zaude domeinu honen datuak behin betiko ezabatu nahi dituzula? + confirm_purge: Ziur domeinu honen datuak behin betiko ezabatu nahi dituzula? content_policies: comment: Barne-oharra description_html: Domeinu honetako eta bere azpi-domeinuetako kontu guztiei aplikatuko zaizkien eduki-politikak definitu ditzakezu. + limited_federation_mode_description_html: Domeinu honekin federatu ahal izatea baimendu dezakezu. policies: reject_media: Errefusatu multimediak reject_reports: Errefusatu salaketak @@ -587,12 +601,14 @@ eu: assign_to_self: Esleitu niri assigned: Esleitutako moderatzailea by_target_domain: Jakinarazitako kontuaren domeinua + cancel: Utzi category: Kategoria category_description_html: Kontu edo/eta eduki hau salatu izanaren arrazoia salatutako kontuarekiko komunikazioan aipatuko da comment: none: Bat ere ez comment_description_html: 'Informazio gehiago emateko, %{name} idatzi:' - confirm_action: "@%{acct} kontuaren aurkako moderazio-ekintza baieztatu" + confirm: Berretsi + confirm_action: Berretsi @%{acct} kontuaren aurkako moderazio-ekintza created_at: Salatua delete_and_resolve: Ezabatu bidalketak forwarded: Birbidalia @@ -727,6 +743,9 @@ eu: branding: preamble: 'Zure zerbitzariaren markak sareko beste zerbitzarietatik bereizten du. Informazio hau hainbat ingurunetan bistaratuko da: Mastodonen web interfazean, aplikazio natiboetan, esteken aurrebistak beste webguneetan eta mezularitza aplikazioetan eta abar. Horregatik, informazio hau garbia eta laburra izatea komeni da.' title: Marka + captcha_enabled: + desc_html: Hori egiteko hCaptcha-ko scriptak behar dira, hirugarrenenak izanik, segurtasun eta pribatutasun arazoak ekarri ditzaketeenak. Horrez gain, script horiengatik nabarmen zailagoa egiten zaie pertsona batzuei izena ematea (batez ere desgaitasunen bat duenei). Hori dela eta, hausnartu beste neurri batzuk hartu ditzakezun, esaterako onarpenean oinarritutako izen ematea, edo gonbidapenen bidezkoa. + title: Eskatu erabiltzaile berriei CAPTCHA bat ebazteko beren kontua berresteko content_retention: preamble: Kontrolatu erabiltzaileek sortutako edukia nola biltegiratzen den Mastodonen. title: Edukia atxikitzea @@ -738,8 +757,8 @@ eu: preamble: Eduki interesgarria aurkitzea garrantzitsua da Mastodoneko erabiltzaile berrientzat, behar bada inor ez dutelako ezagutuko. Kontrolatu zure zerbitzariko aurkikuntza-ezaugarriek nola funtzionatzen duten. profile_directory: Profil-direktorioa public_timelines: Denbora-lerro publikoak - publish_discovered_servers: Deskubritutako zerbitzariak argitaratu - publish_statistics: Estatistikak argitaratu + publish_discovered_servers: Argitaratu aurkitutako zerbitzariak + publish_statistics: Argitaratu estatistikak title: Aurkitzea trends: Joerak domain_blocks: @@ -754,10 +773,22 @@ eu: approved: Izena emateko onarpena behar da none: Ezin du inork izena eman open: Edonork eman dezake izena - title: Zerbitzariaren ezarpenak + security: + authorized_fetch: Eskatu autentifikazioa federatutako zerbitzarietatik + title: Zerbitzariko ezarpenak site_uploads: delete: Ezabatu igotako fitxategia destroyed_msg: Guneko igoera ongi ezabatu da! + software_updates: + critical_update: Kritikoa — mesedez, eguneratu azkar + documentation_link: Informazio gehiago + release_notes: Bertsio oharrak + title: Eguneraketak eskuragarri + type: Mota + types: + major: Argitalpen handia + minor: Argitalpen txikia + version: Bertsioa statuses: account: Egilea application: Aplikazioa @@ -794,9 +825,24 @@ eu: suspend: "%{name} erabiltzaileak %{target} kontua kanporatu du" appeal_approved: Apelatua appeal_pending: Apelazioa zain + appeal_rejected: Apelazioa baztertuta system_checks: database_schema_check: message_html: Aplikatu gabeko datu-basearen migrazioak daude. Exekutatu aplikazioak esperotako portaera izan dezan + elasticsearch_health_red: + message_html: Elasticsearch-en klusterra ez dago osasuntsu (egoera gorria), bilaketa-eginbideak ez daude erabilgarri + elasticsearch_health_yellow: + message_html: Elasticsearch-en klusterra ez dago osasuntsu (egoera horia), baliteke arrazoia ikertu nahi izatea + elasticsearch_index_mismatch: + message_html: Elasticsearch indexatze-mapeatzeak zaharkituta daude. Exekutatu tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ikusi dokumentazioa + message_html: Zure Elasticsearch-eko klusterrak nodo bat baino gehiago dauka, baina Mastodonek ezin ditu erabili ez dagoelako horretarako konfiguratuta. + elasticsearch_preset_single_node: + action: Ikusi dokumentazioa + message_html: 'Zure Elasticsearch-eko klusterrak nodo bakarra dauka, hortaz, ES_PRESET balore honetan ezarri beharko zenuke: single_node_cluster.' + elasticsearch_reset_chewy: + message_html: Zure Elasticsearch indexatze sistematikoa zaharkituta dago ezarpen bat aldatu delako. Eguneratzeko, exekutatu tootctl search deploy --reset-chewy. elasticsearch_running_check: message_html: Ezin izan da Elasticsearch-era konektatu. Egiaztatu martxan dagoela edo desgaitu testu osoko bilaketa elasticsearch_version_check: @@ -807,6 +853,17 @@ eu: message_html: Ez duzu zerbitzariaren araurik definitu. sidekiq_process_check: message_html: Ez da ari Sidekiq prozesurik exekutatzen %{value} ilad(et)an. Egiaztatu Sidekiq konfigurazioa + software_version_critical_check: + action: Ikusi eguneraketa eskuragarriak + message_html: Mastodon eguneraketa kritikoa eskuragarri, mesedez eguneratu ahal bezain azkar. + software_version_patch_check: + action: Ikusi eguneraketa eskuragarriak + upload_check_privacy_error: + action: Ikus hemen informazio gehiagorako + message_html: "Zure zerbitzaria ez dago ongi konfiguratua. Zure erabiltzaileen pribatutasuna arriskuan dago." + upload_check_privacy_error_object_storage: + action: Ikus hemen informazio gehiagorako + message_html: "Zure objektuen biltegiratzea ez dago ongi konfiguratua. Zure erabiltzaileen pribatutasuna arriskuan dago." tags: review: Berrikusketaren egoera updated_msg: Traola-ezarpenak ongi eguneratu dira @@ -829,6 +886,7 @@ eu: other: "%{count} pertsonak partekatua azken astean" title: Esteken joerak usage_comparison: "%{today} aldiz partekatua gaur, atzo %{yesterday} aldiz" + not_allowed_to_trend: Joeretan agertzeko baimenik gabe only_allowed: Soilik onartutakoak pending_review: Berrikusketaren zain preview_card_providers: @@ -913,6 +971,8 @@ eu: body: "%{target} erabiltzaileak apelazioa jarri dio %{action_taken_by} erabiltzaileak %{date}(e)an hartutako %{type} motako erabakiari. Hau idatzi du:" next_steps: Apelazioa onartu dezakezu moderazio erabakia desegiteko, edo ez ikusia egin. subject: "%{username} erabiltzailea %{instance} instantziako moderazio erabaki bat apelatzen ari da" + new_critical_software_updates: + subject: "%{instance} ek eguneraketa kritikoak eskuragarri ditu!" new_pending_account: body: Kontu berriaren xehetasunak azpian daude. Eskaera hau onartu edo ukatu dezakezu. subject: Kontu berria berrikusteko %{instance} instantzian (%{username}) @@ -949,24 +1009,28 @@ eu: guide_link: https://crowdin.com/project/mastodon guide_link_text: Edonork lagundu dezake. sensitive_content: Eduki hunkigarria - toot_layout: Bidalketen diseinua application_mailer: notification_preferences: Aldatu e-mail hobespenak salutation: "%{name}," settings: 'Aldatu e-mail hobespenak: %{link}' + unsubscribe: Kendu harpidetza view: 'Ikusi:' view_profile: Ikusi profila view_status: Ikusi bidalketa applications: created: Aplikazioa ongi sortu da destroyed: Aplikazioa ongi ezabatu da + logout: Amaitu saioa regenerate_token: Birsortu sarbide token-a token_regenerated: Sarbide token-a ongi birsortu da warning: Kontuz datu hauekin, ez partekatu inoiz inorekin! your_token: Zure sarbide token-a auth: - apply_for_account: Kontu bat eskatu - change_password: Pasahitza + apply_for_account: Eskatu kontu bat + captcha_confirmation: + help_html: CAPTCHA ebazteko arazoak badituzu, bidali eposta bat %{email} helbidera eta lagunduko dizugu. + hint_html: Azken kontu bat! Gizakia zarela berretsi behar dugu (zabor-kontuak kanpoan mantentzeko baino ez da!) Ebatzi azpiko CAPTCHA eta sakatu "Jarraitu". + title: Segurtasun txekeoa confirmations: wrong_email_hint: Helbide-elektroniko hori zuzena ez bada, kontuaren ezarpenetan alda dezakezu. delete_account: Ezabatu kontua @@ -974,8 +1038,8 @@ eu: description: prefix_invited_by_user: "@%{name} erabiltzaileak Mastodon zerbitzari honetara elkartzera gonbidatzen zaitu!" prefix_sign_up: Eman izena Mastodon-en! - suffix: Kontu bat baduzu, jendea jarraitu ahal izango duzu, bidalketak sortu eta Mastodon zein kanpoko zerbitzarietako erabiltzaileekin elkarrizketan aritu! - didnt_get_confirmation: Ez dituzu berresteko argibideak jaso? + suffix: Kontu bat baduzu, jendeari jarraitu ahal izango diozu, bidalketak sortu eta Mastodon zein kanpoko zerbitzarietako erabiltzaileekin elkarrizketan aritu! + didnt_get_confirmation: Ez al duzu berrespen-esteka jaso? dont_have_your_security_key: Ez daukazu zure segurtasun gakoa? forgot_password: Pasahitza ahaztu duzu? invalid_reset_password_token: Pasahitza berrezartzeko token-a baliogabea da edo iraungitu du. Eskatu beste bat. @@ -988,26 +1052,39 @@ eu: migrate_account_html: Kontu hau beste batera birbideratu nahi baduzu, hemen konfiguratu dezakezu. or_log_in_with: Edo hasi saioa honekin privacy_policy_agreement_html: Pribatutasun politika irakurri dut eta ados nago + progress: + confirm: Berretsi eposta + details: Zure xehetasunak + review: Gure berrikuspena + rules: Onartu arauak providers: cas: CAS saml: SAML register: Eman izena registration_closed: "%{instance} instantziak ez du kide berririk onartzen" - resend_confirmation: Birbidali berresteko argibideak + resend_confirmation: Bidali berrespen-esteka berriro reset_password: Berrezarri pasahitza rules: + accept: Onartu + back: Atzera + invited_by: "%{domain} webgunean kontua ireki dezakezu lagun honek gonbidapena bidali dizulako:" preamble: Hauek %{domain} instantziako moderatzaileek ezarriak eta betearaziak dira. + preamble_invited: Jarraitu baino lehen, kontuan hartu %{domain}-(e)ko moderatzaileek ezarritako oinarrizko arauak. title: Oinarrizko arau batzuk. + title_invited: Gonbidatu zaituzte. security: Segurtasuna set_new_password: Ezarri pasahitza berria setup: - email_below_hint_html: Beheko e-mail helbidea okerra bada, hemen aldatu dezakezu eta baieztapen e-mail berria jaso. - email_settings_hint_html: Baieztamen e-maila %{email} helbidera bidali da. E-mail helbide hori zuzena ez bada, kontuaren ezarpenetan aldatu dezakezu. - title: Ezarpena + email_below_hint_html: Begiratu zure spameko karpetan, edo eskatu beste bat. Zure helbide elektronikoa zuzen dezakezu oker badago. + email_settings_hint_html: Egin klik bidali dizugun estekan %{email} helbidea egiaztatzeko. Hementxe itxarongo zaitugu. + link_not_received: Ez duzu estekarik jaso? + new_confirmation_instructions_sent: Berrespen-esteka duen mezu berri bat jasoko duzu minutu gutxi barru! + title: Begiratu zure sarrera-ontzia sign_in: preamble_html: Zure %{domain}-(e)ko egiaztagiriekin saioa hasi. Zure kontua beste zerbitzari batean badago, ezin izango duzu hemen saioa hasi. title: "%{domain}-(e)an saioa hasi" sign_up: + manual_review: "%{domain}-(e)n eginiko izen-emateak gure moderatzaileek eskuz aztertzen dituzte. Zure izen-ematea prozesatzen lagun gaitzazun, idatz ezazu zertxobait zuri buruz eta azaldu zergatik nahi duzun %{domain}-(e)n kontu bat." preamble: Mastodon zerbitzari honetako kontu batekin, aukera izango duzu sareko edozein pertsona jarraitzeko, ez dio axola kontua non ostatatua dagoen. title: "%{domain} zerbitzariko kontua prestatuko dizugu." status: @@ -1019,18 +1096,6 @@ eu: view_strikes: Ikusi zure kontuaren aurkako neurriak too_fast: Formularioa azkarregi bidali duzu, saiatu berriro. use_security_key: Erabili segurtasun gakoa - authorize_follow: - already_following: Kontu hau aurretik jarraitzen duzu - already_requested: Bidali duzu dagoeneko kontu hori jarraitzeko eskaera bat - error: Zoritxarrez, urruneko kontua bilatzean errore bat gertatu da - follow: Jarraitu - follow_request: 'Jarraitzeko eskari bat bidali duzu hona:' - following: 'Ongi! Orain jarraitzen duzu:' - post_follow: - close: Edo, leiho hau besterik gabe itxi dezakezu. - return: Erakutsi erabiltzailearen profila - web: Joan webera - title: Jarraitu %{acct} challenge: confirm: Jarraitu hint_html: "Oharra: Ez dizugu pasahitza berriro eskatuko ordu batez." @@ -1060,7 +1125,7 @@ eu: x_seconds: "%{count}s" deletes: challenge_not_passed: Sartu duzun informazioa ez da zuzena - confirm_password: Sartu zure oraingo pasahitza zure identitatea baieztatzeko + confirm_password: Sartu zure oraingo pasahitza zure identitatea egiaztatzeko confirm_username: Sartu zure erabiltzaile-izena prozedura berresteko proceed: Ezabatu kontua success_msg: Zure kontua ongi ezabatu da @@ -1069,7 +1134,7 @@ eu: caches: Beste zerbitzariek cachean duten edukia mantentzea gerta daiteke data_removal: Zure bidalketak eta beste datuak behin betiko ezabatuko dira email_change_html: Zure e-mail helbidea aldatu dezakezu kontua ezabatu gabe - email_contact_html: Oraindik heltzen ez bada, e-mail bai bidali dezakezu %{email} helbidera laguntza eskatzeko + email_contact_html: Oraindik heltzen ez bada, eposta bai bidali dezakezu %{email} helbidera laguntza eskatzeko email_reconfirmation_html: Ez baduzu baieztamen e-maila jasotzen, berriro eskatu dezakezu irreversible: Ezin izango duzu kontua berreskuratu edo berraktibatu more_details_html: Xehetasun gehiagorako, ikusi pribatutasun politika. @@ -1107,8 +1172,12 @@ eu: your_appeal_rejected: Zure apelazioa baztertu da domain_validator: invalid_domain: ez da domeinu izen baliogarria + edit_profile: + basic_information: Oinarrizko informazioa + hint_html: "Pertsonalizatu jendeak zer ikusi dezakeen zure profil publikoan eta zure bidalketen baitan. Segur aski, jende gehiagok jarraituko dizu eta interakzio gehiago izango dituzu profila osatuta baduzu, profil irudia eta guzti." + other: Bestelakoak errors: - '400': Bidali duzun eskaria baliogabea da edo gaizki osatua dago. + '400': Bidali duzun eskaera baliogabea da edo gaizki osatua dago. '403': Ez duzu orri hau ikusteko baimenik. '404': Bilatu duzun orria ez dago hemen. '406': Orri hau ez dago eskatutako formatuan eskuragarri. @@ -1143,7 +1212,7 @@ eu: featured_tags: add_new: Gehitu berria errors: - limit: Gehienezko traola kopurua nabarmendu duzu jada + limit: Gehienezko traola kopurua erakutsi duzu jada hint_html: "Zer dira nabarmendutako traolak? Zure profilean toki nabarmendu batean agertzen dira eta jendeari traola hau daukaten bidalketa publikoak arakatzea ahalbidetzen diote. Sormen lana edo epe luzerako proiektuak jarraitzeko primerakoak dira." filters: contexts: @@ -1187,8 +1256,6 @@ eu: index: hint: Iragazki honek banako bidalketei eragiten die, beste kriterioak badaude ere. Bidalketa gehiago gehitu ditzakezu iragazkira web interfazetik. title: Iragazitako bidalketak - footer: - trending_now: Joera orain generic: all: Denak all_items_on_page_selected_html: @@ -1197,7 +1264,9 @@ eu: all_matching_items_selected_html: one: Zure bilaketarekin bat datorren elementu %{count} hautatuta. other: Zure bilaketarekin bat datozen %{count} elementu hautatuta. + cancel: Utzi changes_saved_msg: Aldaketak ongi gorde dira! + confirm: Berretsi copy: Kopiatu delete: Ezabatu deselect: Desautatu guztiak @@ -1211,24 +1280,62 @@ eu: validation_errors: one: Zerbait ez dabil ongi! Egiaztatu beheko errorea mesedez other: Zerbait ez dabil ongi! Egiaztatu beheko %{count} erroreak mesedez - html_validator: - invalid_markup: 'HTML markaketa baliogabea du: %{error}' imports: errors: + empty: CSV fitxategi hutsa + incompatible_type: Ez da bateragarria aukeratutako inportatze-motarekin invalid_csv_file: 'CSV fitxategi baliogabea. Errorea: %{error}' over_rows_processing_limit: "%{count} lerro baina gehiago ditu" + too_large: Fitxategia handiegia da + failures: Akatsak + imported: Inportatuta + mismatched_types_warning: Badirudi mota okerra aukeratu duzula inportatze honetarako, mesedez, berrikusi. modes: merge: Bateratu merge_long: Mantendu dauden erregistroak eta gehitu berriak overwrite: Gainidatzi overwrite_long: Ordeztu oraingo erregistroak berriekin + overwrite_preambles: + blocking_html: "Blokeatutakoen zerrenda %{filename} fitxategiak dituen %{total_items} kontuekin ordeztear zaude." + bookmarks_html: "Laster-markak %{filename} fitxategiak dituen %{total_items} argitalpenekin ordeztear zaude." + domain_blocking_html: "Blokeatutako domeinuen zerrenda %{filename} fitxategiak dituen %{total_items} domeinuekin ordeztear zaude." + following_html: "%{filename} fitxategiak dituen %{total_items} kontuei jarraitzear zaude; gainontzekoak jarraitzeari utziko diozu." + lists_html: "Zerrendak %{filename} fitxategiak duen edukiarekin ordeztear zaude. %{total_items} kontu gehituko dira zerrenda berrietara." + muting_html: "Mutututako kontuen zerrenda %{filename} fitxategiak dituen %{total_items} kontuekin ordeztear zaude." + preambles: + blocking_html: "%{filename} fitxategiak dituen %{total_items} kontuak blokeatzear zaude." + bookmarks_html: "%{filename} fitxategiak dituen %{total_items} argitalpenei laster-marka jartzear zaude." + domain_blocking_html: "%{filename} fitxategiak dituen %{total_items} domeinuak blokeatzear zaude." + following_html: "%{filename} fitxategiak dituen %{total_items} konturi jarraitzear zaude." + lists_html: "%{filename} fitxategiak dituen %{total_items} kontu zerrendetan gehitzear zaude. Zerrenda berriak sortuko dira zerrendarik ez badago." + muting_html: "%{filename} fitxategiak dituen %{total_items} kontuak mututzear zaude." preface: Beste zerbitzari bateko datuak inportatu ditzakezu, esaterako jarraitzen duzun edo blokeatu duzun jendearen zerrenda. + recent_imports: Azken inportazioak + states: + finished: Amaitua + in_progress: Abian + scheduled: Programatuta + unconfirmed: Berretsi gabe + status: Egoera success: Zure datuak ongi igo dira eta dagokionean prozesatuko dira + time_started: Noiz hasia + titles: + blocking: Blokeatutako kontuak inportatzen + bookmarks: Laster-markak inportatzen + domain_blocking: Blokeatutako domeinuak inportatzen + following: Jarraitutako kontuak inportatzen + lists: Zerrendak inportatzen + muting: Mutututako kontuak inportatzen + type: Inportazio mota + type_groups: + constructive: Jarraipenak eta laster-markak + destructive: Blokeatzeak eta mututzeak types: blocking: Blokeatutakoen zerrenda bookmarks: Laster-markak domain_blocking: Domeinuen blokeo zerrenda following: Jarraitutakoen zerrenda + lists: Zerrendak muting: Mutututakoen zerrenda upload: Igo invites: @@ -1255,7 +1362,7 @@ eu: title: Gonbidatu jendea lists: errors: - limit: Gehieneko zerrenda kopurura heldu zara + limit: Gehienezko zerrenda kopurura iritsi zara login_activities: authentication_methods: otp: bi faktoreko autentifikazio aplikazioa @@ -1267,6 +1374,23 @@ eu: failed_sign_in_html: Huts egindako saioa hasteko saiakera %{method} erabiliz %{ip} IPtik (%{browser}) successful_sign_in_html: Saioa hasiera arrakastatsua %{method} erabiliz %{ip} IPtik (%{browser}) title: Autentifikazioen historia + mail_subscriptions: + unsubscribe: + action: Bai, kendu harpidetza + complete: Harpidetza kenduta + confirmation_html: |- + Ziur Mastodonen %{domain} zerbitzariko %{type} %{email} helbide elektronikoan jasotzeari utzi nahi diozula? + Beti harpidetu zaitezke berriro eposta jakinarazpenen hobespenetan. + emails: + notification_emails: + favourite: zure argitalpena gogoko egin dutenaren jakinarazpen e-mailak + follow: jarraitu dizutenaren jakinarazpen e-mailak + follow_request: jarraipen-eskaeren jakinarazpen e-mailak + mention: aipamenen jakinarazpen e-mailak + reblog: bultzaden jakinarazpen e-mailak + resubscribe_html: Nahi gabe utzi badiozu jakinarazpenak jasotzeari, berriro harpidetu zaitezke e-mail jakinarazpenen hobespenetan. + success_html: Ez duzu Mastodonen %{domain} zerbitzariko %{type} jasoko %{email} helbide elektronikoan. + title: Kendu harpidetza media_attachments: validations: images_and_video: Ezin da irudiak dituen bidalketa batean bideo bat erantsi @@ -1346,6 +1470,7 @@ eu: update: subject: "%{name} erabiltzaileak bidalketa bat editatu du" notifications: + administration_emails: Administratzailearen posta elektroniko bidezko jakinarazpenak email_events: E-mail jakinarazpenentzako gertaerak email_events_hint: 'Hautatu jaso nahi dituzun gertaeren jakinarazpenak:' other_settings: Bezte jakinarazpen konfigurazioak @@ -1382,12 +1507,22 @@ eu: expired: Inkesta amaitu da jada invalid_choice: Hautatutako boto aukera ez da existitzen over_character_limit: bakoitzak gehienez %{max} karaktere izan ditzake + self_vote: Ezin duzu zuk sortutako inkestetan bozka eman too_few_options: elementu bat baino gehiago izan behar du too_many_options: ezin ditu %{max} elementu baino gehiago izan preferences: other: Denetarik posting_defaults: Bidalketarako lehenetsitakoak public_timelines: Denbora-lerro publikoak + privacy: + hint_html: "Pertsonalizatu nola nahi duzun zure profila eta argitalpenak aurkitzea. Mastodonen hainbat ezaugarri gaituta daudenean lagungarri izan dakizkizuke publiko zabalago batera iristeko. Hartu une bat ezarpen horiek berrikusteko, zure erabilerara egokitzen direla ziurtatzeko." + privacy: Pribatutasuna + privacy_hint_html: Kontrolatu besteen onurarako zenbat partekatu nahi duzun. Jendeak profil interesgarriak eta aplikazio apartak aurki ditzazke zuk nor jarraitzen duzun eta argitaratzeko darabilzun aplikazioak ikustean, baina baliteke ezkutuan mantentzea nahiago izatea. + reach: Irismena + reach_hint_html: Kontrolatu jende berriak zu jarrai eta aurki zaitzakeen. Zure mezuak Arakatu pantailan agertzea nahi duzu? Beste pertsona batzuek nor jarraitzeko gomendioetan zu ikus zaitzaten nahi duzu? Automatikoki onartu nahi dituzu jarraitzaile berri guztiak, edo bakoitzaren gainean erabaki? + search: Bilatu + search_hint_html: Kontrolatu nola aurki zaitzaketen. Nahi duzu jendeak publikoki argitaratu duzunagatik aurki zaitzala? Nahi duzu Mastodonetik kanpoko pertsonek weba arakatzean zure profila aurki dezatela? Kontuan izan bilaketa-motor guztien erabateko bazterketa ezin dela bermatu jendaurreko informaziorako. + title: Pribatutasuna eta irismena privacy_policy: title: Pribatutasun politika reactions: @@ -1396,10 +1531,11 @@ eu: unrecognized_emoji: ez da emoji ezaguna relationships: activity: Kontuaren aktibitatea - confirm_follow_selected_followers: Ziur al zaude hautatutako jarraitzaileak jarraitu nahi dituzula? - confirm_remove_selected_followers: Ziur al zaude hautatutako jarraitzaileak ezabatu nahi dituzula? - confirm_remove_selected_follows: Ziur al zaude hautatutako jarraipenak ezabatu nahi dituzula? + confirm_follow_selected_followers: Ziur hautatutako jarraitzaileei jarraitu nahi dituzula? + confirm_remove_selected_followers: Ziur hautatutako jarraitzaileak ezabatu nahi dituzula? + confirm_remove_selected_follows: Ziur hautatutako jarraipenak ezabatu nahi dituzula? dormant: Ez aktiboa + follow_failure: Ezin izan dira aukeratutako kontu batzuk jarraitu. follow_selected_followers: Jarraitu hautatutako jarraitzaileak followers: Jarraitzaileak following: Jarraitzen @@ -1439,6 +1575,7 @@ eu: electron: Electron firefox: Firefox generic: Nabigatzaile ezezaguna + huawei_browser: Huawei nabigatzailea ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi nabigatzailea @@ -1448,6 +1585,7 @@ eu: qq: QQ nabigatzailea safari: Safari uc_browser: UC nabigatzailea + unknown_browser: Nabigatzaile ezezaguna weibo: Weibo current_session: Uneko saioa description: "%{browser} - %{platform}" @@ -1460,9 +1598,10 @@ eu: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: plataforma ezezaguna + unknown_platform: Plataforma ezezaguna windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1533,7 +1672,6 @@ eu: show_newer: Erakutsi berriagoak show_older: Erakutsi zaharragoak show_thread: Erakutsi haria - sign_in_to_participate: Eman izena elkarrizketan parte hartzeko title: '%{name}: "%{quote}"' visibilities: direct: Zuzena @@ -1575,12 +1713,10 @@ eu: '7889238': 3 hilabete min_age_label: Denbora muga min_favs: Mantendu gogoko kopuru hau duten bidalketak - min_favs_hint: Gutxienez gogoko kopuru hau jaso duten zure bidalketak ez dira ezabatuko. Hutsik utziz gero gogoko kopurua ez da kontuan hartuko bidalketak ezabatzean + min_favs_hint: Gogoko dutenen kopuru hau gutxienez duten bidalketak ez dira ezabatuko. Hutsik utzi, gogoko dutenen kopurua aintzat hartu gabe bidalketak ezabatzeko min_reblogs: Mantendu bultzada kopuru hau duten bidalketak min_reblogs_hint: Gutxienez bultzada kopuru hau jaso duten zure bidalketak ez dira ezabatuko. Hutsik utziz gero bultzada kopurua ez da kontuan hartuko bidalketak ezabatzean stream_entries: - pinned: Finkatutako bidalketa - reblogged: "(r)en bultzada" sensitive_content: 'Kontuz: Eduki hunkigarria' strikes: errors: @@ -1596,6 +1732,7 @@ eu: default: "%Y(e)ko %b %d, %H:%M" month: "%Y(e)ko %b" time: "%H:%M" + with_time_zone: "%Y(e)ko %b %d, %H:%M %Z" two_factor_authentication: add: Gehitu disable: Desgaitu @@ -1675,20 +1812,25 @@ eu: title: Ongi etorri, %{name}! users: follow_limit_reached: Ezin dituzu %{limit} pertsona baino gehiago jarraitu + go_to_sso_account_settings: Jo zure identitate-hornitzaileko kontuaren ezarpenetara invalid_otp_token: Bi faktoreetako kode baliogabea otp_lost_help_html: 'Bietara sarbidea galdu baduzu, jarri kontaktuan hemen: %{email}' seamless_external_login: Kanpo zerbitzu baten bidez hasi duzu saioa, beraz pasahitza eta e-mail ezarpenak ez daude eskuragarri. signed_in_as: 'Saioa honela hasita:' verification: - explanation_html: 'Ezin duzu zure burua zure profileko metadatuen esteken jabe gisa egiaztatu. Horretarako, estekatutako webgunean zure Mastodon profilera daraman esteka bat egon behar du. Mastodonera daraman esteka horrekderrigorrez rel="me" artibutua izan behar du . Estekaren testuak ez du axola. Hona adibide bat:' + extra_instructions_html: Aholkua: webguneko esteka ikusezina izan daiteke. Muina rel="me" da, erabiltzaileak sortutako edukia duten webguneetan beste inor zure burutzat aurkeztea eragozten duena. a beharrean esteka-etiketa bat ere erabil dezakezu orrialdearen goiburuan, baina HTMLak eskuragarri egon behar du JavaScript exekutatu gabe. + here_is_how: Hemen duzu nola + hint_html: "Mastodonen nortasun-egiaztapena guztiontzat da. Web estandar irekietan oinarritua, orain eta betiko doan. Behar duzun guztia jendeak ezagutzen duen webgune pertsonal bat da. Mastodon profiletik webgune honetara estekatzen duzunean, webguneak mastodon profilera estekatzen duela egiaztatuko dugu eta adierazle bat erakutsiko du." + instructions_html: Kopiatu eta itsatsi ondoko kodea zure webguneko HTMLan. Ondoren, gehitu zure webgunearen helbidea zure profileko eremu gehigarrietako batean, "Editatu profila" fitxatik eta gorde aldaketak. verification: Egiaztaketa + verified_links: Zure lotura egiaztatuak webauthn_credentials: add: Gehitu segurtasun gako berria create: error: Arazo bat egon da zure segurtasun gakoa gehitzean. Saiatu berriro mesedez. success: Zure segurtasun gakoa behar bezala gehitu da. delete: Ezabatu - delete_confirmation: Ziur zaude segurtasun gako hau ezabatu nahi duzula? + delete_confirmation: Ziur segurtasun gako hau ezabatu nahi duzula? description_html: "Segurtasun gako bidezko autentifikazioa gaitzen baduzu, saioa hasteko zure segurtasun gakoetako bat erabili beharko duzu." destroy: error: Arazo bat egon da zure segurtasun gakoa ezabatzean. Saiatu berriro mesedez. diff --git a/config/locales/fa.yml b/config/locales/fa.yml index e4ba9441c3..e2138e0aeb 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -1,7 +1,7 @@ --- fa: about: - about_mastodon_html: 'شبکهٔ اجتماعی آینده: بدون تبلیغات، بدون شنود از طرف شرکت‌ها، طراحی اخلاق‌مدار، و معماری غیرمتمرکز! با ماستودون صاحب داده‌های خودتان باشید!' + about_mastodon_html: 'شبکه‌ی اجتماعی آینده: بدون تبلیغات، بدون شنود از طرف شرکت‌ها، طراحی اخلاق‌مدار، و معماری غیرمتمرکز! با ماستودون صاحب داده‌های خودتان باشید!' contact_missing: تنظیم نشده contact_unavailable: موجود نیست hosted_on: ماستودون، میزبانی‌شده روی %{domain} @@ -31,7 +31,7 @@ fa: created_msg: یادداشت مدیر با موفقیت ساخته شد! destroyed_msg: یادداشت نظارتی با موفقیت نابود شد! accounts: - add_email_domain_block: مسدود کردن دامنهٔ رایانامه + add_email_domain_block: انسداد دامنهٔ رایانامه approve: پذیرفتن approved_msg: کارهٔ ثبت‌نام %{username} با موفقیت تأیید شد are_you_sure: مطمئنید؟ @@ -91,6 +91,7 @@ fa: moderation: active: فعّال all: همه + disabled: غیرفعال pending: منتظر silenced: محدود suspended: تعلیق شده @@ -104,7 +105,10 @@ fa: not_subscribed: مشترک نیست pending: در انتظار بررسی perform_full_suspension: تعلیق - previous_strikes: اخطارهای پیشین + previous_strikes: شکایت‌های پیشین + previous_strikes_description_html: + one: این حساب یک شکایت دارد. + other: این حساب %{count} شکایت دارد. promote: ترفیع‌دادن protocol: پروتکل public: عمومی @@ -113,21 +117,24 @@ fa: redownloaded_msg: حساب %{username} با موفقیت از ابتدا نوسازی شد reject: نپذیرفتن rejected_msg: کارهٔ ثبت‌نام %{username} با موفقیت رد شد + remote_suspension_irreversible: داده‌های این حساب به طور غیرقابل برگشت حذف شده است. + remote_suspension_reversible_hint_html: حساب روی کارسازشان معلّق شد و داده‌ها به صورت کامل در %{date} برداشته خواهند شد. تا آن زمان، کارساز دوردست می‌تواند این حساب را بی هیچ عوارضی بازگرداند. اگر می‌خواهید فوراً همهٔ داده‌های حساب را بردارید، می‌توانید در پایین این کار را بکنید. remove_avatar: حذف تصویر نمایه remove_header: برداشتن تصویر زمینه removed_avatar_msg: تصویر آواتار %{username} با موفّقیت برداشته شد removed_header_msg: تصویر سرایند %{username} با موفّقیت برداشته شد resend_confirmation: already_confirmed: این کاربر قبلا تایید شده است - send: ارسال دوبارهٔ رایانامهٔ تأیید - success: رایانامه تأیید با موفقیت ارسال شد! + send: ارسال مجدد پیوند تایید + success: پیوند تایید با موفقیت ارسال شد! reset: بازنشانی - reset_password: بازنشانی رمز + reset_password: بازنشانی گذرواژه resubscribe: اشتراک دوباره role: نقش search: جستجو search_same_email_domain: دیگر کاربران با دامنهٔ رایانامهٔ یکسان search_same_ip: دیگر کاربران با IP یکسان + security: امنیت security_measures: only_password: فقط گذرواژه password_and_2fa: گذرواژه و ۲عاملی @@ -140,7 +147,7 @@ fa: silence: خموشاندن silenced: خموشانده statuses: نوشته‌ها - strikes: اخطارهای پیشین + strikes: شکایت‌های پیشین subscribe: اشتراک suspend: تعلیق suspended: تعلیق‌شده @@ -167,9 +174,11 @@ fa: approve_user: تایید کاربر assigned_to_self_report: واگذاری گزارش change_email_user: تغییر رایانامه برای کاربر + change_role_user: تغیر نقش کاربر confirm_user: تأیید کاربر create_account_warning: ایجاد هشدار create_announcement: ایجاد اعلامیه + create_canonical_email_block: ایجاد انسداد ایمیل create_custom_emoji: ایجاد اموجی سفارشی create_domain_allow: ایجاد اجازهٔ دامنه create_domain_block: ایجاد انسداد دامنه @@ -188,6 +197,7 @@ fa: destroy_ip_block: حذف قاعدهٔ آی‌پی destroy_status: حذف وضعیت destroy_unavailable_domain: حذف دامنهٔ ناموجود + destroy_user_role: نابودی نقش disable_2fa_user: از کار انداختن ورود دومرحله‌ای disable_custom_emoji: از کار انداختن اموجی سفارشی disable_sign_in_token_auth_user: از کار انداختن تأیید هویت ژتون رایانامه‌ای برای کاربر @@ -201,6 +211,7 @@ fa: reject_user: رد کاربر remove_avatar_user: برداشتن تصویر نمایه reopen_report: بازگشایی گزارش + resend_user: ارسال مجدد رایانامه تایید reset_password_user: بازنشانی گذرواژه resolve_report: رفع گزارش sensitive_account: علامت‌گذاری رسانه در حسابتان به عنوان حساس @@ -214,23 +225,30 @@ fa: update_announcement: به‌روز رسانی اعلامیه update_custom_emoji: به‌روز رسانی اموجی سفارشی update_domain_block: به‌روزرسانی مسدودسازی دامنه + update_ip_block: بروزرسانی قاعدهٔ آی‌پی update_status: به‌روز رسانی وضعیت + update_user_role: به روزرسانی نقش actions: approve_appeal_html: "%{name} درخواست تجدیدنظر تصمیم مدیر را از %{target} پذیرفت" approve_user_html: "%{name} ثبت نام %{target} را تایید کرد" assigned_to_self_report_html: "%{name} رسیدگی به گزارش %{target} را به عهده گرفت" change_email_user_html: "%{name} نشانی رایانامهٔ کاربر %{target} را عوض کرد" + change_role_user_html: "%{name} نقش %{target} را تغییر داد" confirm_user_html: "%{name} نشانی رایانامهٔ کاربر %{target} را تأیید کرد" create_account_warning_html: "%{name} هشداری برای %{target} فرستاد" create_announcement_html: "%{name} اعلامیه‌ای جدید ایجاد کرد %{target}" + create_canonical_email_block_html: "%{name} رایانامه با درهم‌ریزی %{target} را مسدود کرد" create_custom_emoji_html: "%{name} اموجی تازهٔ %{target} را بارگذاشت" create_domain_allow_html: "%{name} دامنهٔ %{target} را مجاز کرد" create_domain_block_html: "%{name} دامنهٔ %{target} را مسدود کرد" create_email_domain_block_html: "%{name} دامنهٔ رایانامهٔ %{target} را مسدود کرد" create_ip_block_html: "%{name} برای آی‌پی %{target} قانونی ایجاد کرد" create_unavailable_domain_html: "%{name} تحویل محتوا به دامنه %{target} را متوقف کرد" + create_user_role_html: "%{name} نقش %{target} را ایجاد کرد" demote_user_html: "%{name} کاربر %{target} را تنزل داد" destroy_announcement_html: "%{name} اعلامیهٔ %{target} را حذف کرد" + destroy_canonical_email_block_html: "%{name} رایانامه با درهم‌ریزی %{target} را نامسدود کرد" + destroy_custom_emoji_html: "%{name} شکلک %{target} را حذف کرد" destroy_domain_allow_html: "%{name} دامنهٔ %{target} را از فهرست مجاز برداشت" destroy_domain_block_html: "%{name} انسداد دامنهٔ %{target} را رفع کرد" destroy_email_domain_block_html: "%{name} انسداد دامنهٔ رایانامهٔ %{target} را برداشت" @@ -238,6 +256,7 @@ fa: destroy_ip_block_html: "%{name} قاعدهٔ آی‌پی %{target} را حذف کرد" destroy_status_html: "%{name} وضعیت %{target} را برداشت" destroy_unavailable_domain_html: "%{name} تحویل محتوا به دامنه %{target} را از سر گرفت" + destroy_user_role_html: "%{name} نقش %{target} را حذف کرد" disable_2fa_user_html: "%{name} ضرورت ورود دو مرحله‌ای را برای کاربر %{target} غیر فعال کرد" disable_custom_emoji_html: "%{name} شکلک %{target} را غیرفعال کرد" disable_sign_in_token_auth_user_html: "%{name}، احراز هویت با توکن رایانامه را برای %{target} غیرفعال کرد" @@ -251,6 +270,7 @@ fa: reject_user_html: "%{name} ثبت نام %{target} را رد کرد" remove_avatar_user_html: "%{name} تصویر نمایهٔ %{target} را حذف کرد" reopen_report_html: "%{name} گزارش %{target} را دوباره به جریان انداخت" + resend_user_html: "%{name} رایانامهٔ تأیید برای %{target} را دوباره فرستاد" reset_password_user_html: "%{name} گذرواژه کاربر %{target} را بازنشاند" resolve_report_html: "%{name} گزارش %{target} را رفع کرد" sensitive_account_html: "%{name} رسانهٔ %{target} را به عنوان حساس علامت‌گذاری کرد" @@ -264,7 +284,9 @@ fa: update_announcement_html: "%{name} اعلامیهٔ %{target} را به‌روز کرد" update_custom_emoji_html: "%{name} شکلک %{target} را به‌روز کرد" update_domain_block_html: "%{name} مسدودسازی دامنه را برای %{target} به‌روزرسانی کرد" + update_ip_block_html: "%{name} قانون آی‌پی %{target} را تغییر داد" update_status_html: "%{name} نوشتهٔ %{target} را به‌روز کرد" + update_user_role_html: "%{name} نقش %{target} را تغییر داد" deleted_account: حساب حذف شد empty: هیچ گزارشی پیدا نشد. filter_by_action: پالایش بر اساس کنش @@ -287,6 +309,7 @@ fa: unpublish: عدم انتشار unpublished_msg: انتشار اعلامیه با موفقیت لغو شد! updated_msg: اعلامیه با موفقیت به‌روز شد! + critical_update_pending: به‌روز رسانی‌های بحرانی منتظرند custom_emojis: assign_category: تعیین دسته by_domain: دامنه @@ -309,6 +332,7 @@ fa: listed: فهرست شده new: title: افزودن شکلک سفارشی + no_emoji_selected: هیچ ایموجی‌ای تغییری نکرد زیرا هیچ‌کدام از آن‌ها انتخاب نشده بودند not_permitted: مجاز به انجام این کنش نیستید overwrite: بازنویسی shortcode: کد کوتاه @@ -321,7 +345,7 @@ fa: updated_msg: شکلک با موفقیت به‌روز شد! upload: بارگذاری dashboard: - active_users: کاربران فعّال + active_users: کاربر فعّال interactions: برهم‌کنش‌ها media_storage: ذخیره‌ساز رسانه new_users: کاربران جدید @@ -344,7 +368,7 @@ fa: space: فضای مصرف‌شده title: ابزارهای مدیریت top_languages: زبان‌های فعّال‌تر - top_servers: کاربران فعّال‌تر + top_servers: فعّال‌ترین کارسازها website: پایگاه وب disputes: appeals: @@ -359,8 +383,12 @@ fa: undo: برداشتن از فهرست مجاز domain_blocks: add_new: افزودن مسدودسازی دامین تازه + confirm_suspension: + cancel: لغو + confirm: تعلیق + title: تأیید انسداد دامنه برای %{domain} created_msg: مسدودسازی دامنه در حال پردازش است - destroyed_msg: مسدودکردن دامنه واگردانده شد + destroyed_msg: انسداد دامنه واگردانده شد domain: دامنه edit: ویرایش مسدودسازی دامنه existing_domain_block_html: شما پیش‌تر محدودیت‌های سخت‌تری روی %{name} اعمال کرده‌اید، و باید نخست مسدودسازی را لغو کنید. @@ -374,6 +402,7 @@ fa: silence: محدود suspend: تعلیق title: مسدودسازی دامین تازه + not_permitted: شما مجاز به انجام این عملیات نیستید obfuscate: مبهم‌سازی نام دامنهٔ obfuscate_hint: در صورت به کار افتاده بودن اعلام فهرست محدودیت‌های دامنه، نام دامنه در فهرست را به صورت جزیی مبهم می‌کند private_comment: یادداشت خصوصی @@ -388,6 +417,9 @@ fa: view: دیدن مسدودسازی دامنه email_domain_blocks: add_new: افزودن تازه + attempts_over_week: + one: "%{count} تلاش در هفتهٔ گذشته" + other: "%{count} تلاش ورود در هفتهٔ گذشته" created_msg: دامنهٔ رایانامه با موفقیت مسدود شد delete: پاک‌کردن dns: @@ -396,8 +428,22 @@ fa: domain: دامین new: create: ساختن مسدودسازی + resolve: حل و فصل دامنه title: مسدودسازی دامنهٔ رایانامهٔ جدید + not_permitted: مجاز نیست title: دامنه‌های رایانامهٔ مسدود شده + export_domain_allows: + new: + title: درون‌ریزی اجازه‌های دامنه + no_file: هیچ پرونده‌ای گزیده نشده + export_domain_blocks: + import: + existing_relationships_warning: رابطه‌های پی‌گیری موجود + private_comment_template: درون‌ریخته از %{source} در %{date} + title: درون‌ریزی انسدادهای دامنه + new: + title: درون‌ریزی انسدادهای دامنه + no_file: هیچ پرونده‌ای گزیده نشده follow_recommendations: description_html: "پیشنهادات پیگیری به کاربران جدید کک می‌کند تا سریع‌تر محتوای جالب را پیدا کنند. زمانی که کاربری هنوز به اندازه کافی با دیگران تعامل نداشته است تا پیشنهادات پیگیری شخصی‌سازی‌شده دریافت کند، این حساب‌ها را به جای آن فهرست مشاهده خواهد کرد. این حساب‌ها به صورت روزانه و در ترکیب با بیشتری تعاملات و بالاترین دنبال‌کنندگان محلی برای یک زبان مشخص بازمحاسبه می‌شوند." language: برای زبان @@ -408,6 +454,7 @@ fa: unsuppress: بازگردانی پیشنهادهای پی‌گیری instances: availability: + failure_threshold_reached: در %{date} به آستانهٔ شکست رسید. no_failures_recorded: هیچ شکستی در سابقه نیست. title: موجود بودن back_to_all: همه @@ -418,6 +465,8 @@ fa: content_policies: comment: یادداشت داخلی policies: + reject_media: رد کردن رسانه + reject_reports: نپذیرفتن گزارش‌ها silence: کران suspend: تعلیق policy: سیاست @@ -425,13 +474,16 @@ fa: title: سیاست‌های محتوا dashboard: instance_accounts_dimension: حساب‌های پیش‌تر پی‌گیری شده + instance_accounts_measure: حساب‌های ذخیره شده instance_followers_measure: پی‌گیرندگانمان در آن‌جا instance_follows_measure: پی‌گیرندگانشان در این‌جا instance_languages_dimension: زبان‌های برتر instance_reports_measure: گزارش‌ها درباره‌شان + instance_statuses_measure: فرسته‌های ذخیره شده delivery: all: همه clear: پاک کردن خطاهای تحول محتوا + failing: شکست خوردن restart: بازراه‌اندازی تحویل محتوا stop: متوقف‌کردن تحویل محتوا unavailable: ناموجود @@ -440,6 +492,9 @@ fa: delivery_error_hint: اگر تحویل محتوا به مدت %{count} روز ممکن نباشد، به طور خودکار به عنوان تحویل‌ناشونده علامت‌گذاری خواهد شد. destroyed_msg: هم اکنون داده دامنه %{domain} در صف حذف حتمی است. empty: هیج دامنه‌ای پیدا نشد. + known_accounts: + one: "%{count} حساب شناخته" + other: "%{count} حساب شناخته" moderation: all: همه limited: محدود @@ -505,15 +560,20 @@ fa: action_log: گزارش حسابرسی action_taken_by: انجام‌دهنده actions: + delete_description_html: فرستهٔ گزارش شده حذف و شکایتی ضبط خواهد شد تا بتوانید خلاف‌های آینده از همین حساب را بهتر مدیریت کنید. + mark_as_sensitive_description_html: رسانهٔ درون فرستهٔ گزارش شده به عنوان حسّاس علامت خورده و شکایتی ضبط خواهد شد تا بتوانید خلاف‌های آینده از همین حساب را بهتر مدیریت کنید. other_description_html: دیدن انتخاب های بیشتر برای کنترل رفتار حساب و سفارشی سازی ارتباط با حساب گزارش شده. + resolve_description_html: هیچ کنشی علیه حساب گزارش شده انجام نخواهد شد. هیچ شکایتی ضبط نشده و گزارش بسته خواهد شد. add_to_report: افزودن بیش‌تر به گزارش are_you_sure: مطمئنید؟ assign_to_self: به عهدهٔ من بگذار assigned: مدیر عهده‌دار by_target_domain: دامنهٔ حساب گزارش‌شده + cancel: لغو category: دسته comment: none: هیچ + confirm: تأیید created_at: گزارش‌شده delete_and_resolve: حذف فرسته‌ها forwarded: هدایت شده @@ -539,6 +599,8 @@ fa: skip_to_actions: پرش به کنش‌ها status: نوشته statuses: محتوای گزارش شده + summary: + record_strike_html: ضبط شکایتی علیه ‪@%{acct}‬ برای کمک به تصمیم‌گیری برای قانون‌شکنی‌های آیندهٔ این حساب target_origin: خاستگاه حساب گزارش‌شده title: گزارش‌ها unassign: پس‌گرفتن مسئولیت @@ -547,26 +609,44 @@ fa: view_profile: دیدن نمایه roles: add_new: افزودن نقش + assigned_users: + one: "%{count} کاربر" + other: "%{count} کاربر" categories: administration: مدیریت + devops: DevOps invites: دعوت‌ها moderation: نظارت special: ویژه delete: حذف edit: ویراش نقش %{name} everyone: اجازه‌های پیش‌گزیده + permissions_count: + one: "%{count} اجازه" + other: "%{count} اجازه" privileges: administrator: مدیر delete_user_data: حذف داده‌های کاربر invite_users: دعوت کاربران manage_announcements: مدیریت اعلامیه‌ها + manage_appeals: مدیریت درخواست‌های بازنگری manage_blocks: مدیریت مسدودی‌ها manage_custom_emojis: مدیریت ایموجی‌های سفارشی + manage_federation: مدیریت خودگردانی manage_invites: مدیریت دعوت‌ها manage_reports: مدیریت گزارش‌ها manage_roles: مدیریت نقش‌ها manage_rules: مدیریت قوانین + manage_rules_description: اجازه به کاربران برای تغییر قوانین کارساز manage_settings: مدیریت تنظیمات + manage_settings_description: اجازه به کاربران برای تغییر تنظیمات پایگاه + manage_taxonomies: مدیریت طیقه‌بندی‌ها + manage_user_access: مدیریت دسترسی کاربران + manage_users: مدیریت کاربران + view_dashboard: دیدن داشبورد + view_dashboard_description: اجازه به کاربران برای دسترسی به داشتبورد و سنجه‌های مختلف + view_devops: دواپس + title: نقش‌ها rules: add_new: افزودن قانون delete: حذف @@ -575,10 +655,20 @@ fa: empty: هنوز هیچ قانونی برای کارساز تعریف نشده. title: قوانین کارساز settings: + about: + manage_rules: مدیریت قانون‌های کارساز + title: درباره + appearance: + preamble: سفارشی‌سازی رابطس وب ماستودون. + title: ظاهر + default_noindex: + title: درخواست خروج از اندیس‌گذاری پیش‌گزیدهٔ موتور جست‌وجو discovery: follow_recommendations: پیروی از پیشنهادها profile_directory: شاخهٔ نمایه public_timelines: خط زمانی‌های عمومی + publish_discovered_servers: انتشار سرورهای یافته‌شده + publish_statistics: انتشار آمار title: کشف trends: پرطرفدارها domain_blocks: @@ -596,6 +686,16 @@ fa: site_uploads: delete: پرونده بارگذاری شده را پاک کنید destroyed_msg: بارگذاری پایگاه با موفقیت حذف شد! + software_updates: + critical_update: بحرانی — لطفاً به سرعت به‌روز کنید + documentation_link: بیش‌تر بیاموزید + release_notes: یادداشت‌های انتشار + title: به‌روز رسانی‌های موجود + type: گونه + types: + major: ارائه بزرگ + minor: ارائه کوچک + version: نگارش statuses: account: نگارنده application: برنامه @@ -624,16 +724,36 @@ fa: strikes: actions: delete_statuses: "%{name} فرستهٔ %{target} را حذف کرد" - appeal_approved: درخواست تجدیدنظر کرد - appeal_pending: درخواست تجدیدنظر در انتظار + disable: "%{name} حساب %{target} را منجمد کرد" + mark_statuses_as_sensitive: "%{name} فرسته‌های %{target} را به عنوان حسّاس علامت زد" + none: "%{name} هشداری به %{target} فرستاد" + sensitive: "%{name} حساب %{target} را به عنوان حسّاس علامت زد" + silence: "%{name} حساب %{target} را محدود کرد" + suspend: "%{name} حساب %{target} را تعلیق کرد" + appeal_approved: تجدیدنظر شده + appeal_pending: منتظر تجدیدنظر + appeal_rejected: درخواست تجدیدنظر رد شد system_checks: database_schema_check: message_html: تعداد مهاجرت پایگاه داده در انتظار انجام هستند. لطفا آن‌ها را اجرا کنید تا اطمینان یابید که برنامه مطابق انتظار رفتار خواهد کرد + elasticsearch_preset: + action: دیدن مستندات + elasticsearch_preset_single_node: + action: دیدن مستندات + elasticsearch_version_check: + message_html: 'نگارش الستیک‌سرچ ناسازگار: %{value}' + version_comparison: الستیک‌سرچ %{running_version} در حال اجراست، حال که %{required_version} لازم است rules_check: action: مدیریت قانون‌های کارساز message_html: هیچ قانون کارسازی تعریف نکرده‌اید. sidekiq_process_check: message_html: صف(های) %{value} فاقد هیچونه فرایند Sidekiq هستند. لطفا تنظیمات Sidekiq خود را بازبینی کنید + upload_check_privacy_error: + action: برای اطّلاعات بیش‌تر این‌جا را بررسی کنید + message_html: "کارساز وبتان بد پیکربندی شده. محرمانگی کاربرانتان در خطر است." + upload_check_privacy_error_object_storage: + action: برای اطّلاعات بیش‌تر این‌جا را بررسی کنید + message_html: "ذخیره‌سازتان بد پیکربندی شده. محرمانگی کاربرانتان در خطر است." tags: review: وضعیت بازبینی updated_msg: تنظیمات برچسب‌ها با موفقیت به‌روز شد @@ -647,6 +767,7 @@ fa: allow_provider: اجازه به ناشر disallow: اجازه ندادن به پیوند disallow_provider: اجازه ندادن به ناشر + no_link_selected: هیچ پیوندی تغییر نکرد زیرا هیچ‌کدام از آن‌ها انتخاب نشده بودند title: پیوندهای داغ pending_review: بازبینی منتظر preview_card_providers: @@ -669,6 +790,7 @@ fa: trending_rank: 'پرطرفدار #%{rank}' usable: قابل استفاده title: پرطرفدار + trending: پرطرفدار warning_presets: add_new: افزودن تازه delete: زدودن @@ -676,12 +798,33 @@ fa: empty: هنز هیچ پیش‌تنظیم هشداری را تعریف نکرده‌اید. title: مدیریت هشدارهای پیش‌فرض webhooks: + add_new: افزودن نقطهٔ پایانی + delete: حذف + disable: از کار انداختن + disabled: از کار افتاده + edit: ویرایش نقطهٔ پایانی + enable: به کار انداختن + enabled: فعّال + enabled_events: + one: ۱ رویداد به کار افتاده + other: "%{count} رویداد به کار افتاده" + events: رویدادها new: قلاب وب جدید + rotate_secret: چرخش رمز + secret: امضا کردن رمز + status: وضعیت + title: قلاب‌های وب + webhook: قلاب وب admin_mailer: new_appeal: actions: + delete_statuses: برای حذف فرسته‌هایشان + disable: برای انجماد حسابشان + mark_statuses_as_sensitive: برای علامت زدن فرسته‌هایشان به عنوان حسّاس none: یک هشدار + sensitive: برای علامت زدن حسابشان به عنوان حسّاس silence: برای محدود کردن حساب آنها + suspend: برای تعلیق حسابشان new_pending_account: body: جزئیات حساب تازه این‌جاست. شما می‌توانید آن را تأیید یا رد کنید. subject: حساب تازه‌ای در %{instance} نیازمند بررسی است (%{username}) @@ -694,6 +837,10 @@ fa: title: پیوندهای داغ new_trending_statuses: title: فرسته‌های داغ + new_trending_tags: + no_approved_tags: در حال حاضر هیچ برچسب پرطرفداری پذیرفته نشده است. + title: برچسب‌های داغ + subject: موضوغ داغ تازه‌ای در %{instance} نیازمند بررسی است aliases: add_new: ساختن نام مستعار created_msg: نام مستعار تازه با موفقیت ساخته شد. الان می‌توانید انتقال از حساب قدیمی را آغاز کنید. @@ -712,33 +859,36 @@ fa: guide_link: https://crowdin.com/project/mastodon guide_link_text: همه می‌توانند کمک کنند. sensitive_content: محتوای حساس - toot_layout: آرایش فرسته application_mailer: notification_preferences: تغییر ترجیحات ایمیل salutation: "%{name}،" settings: 'تغییر تنظیمات ایمیل: %{link}' + unsubscribe: لغو اشتراک view: 'نمایش:' view_profile: دیدن نمایه view_status: دیدن نوشته‌ها applications: created: برنامه با موفقیت ساخته شد destroyed: برنامه با موفقیت پاک شد + logout: خروج regenerate_token: دوباره‌سازی کد دسترسی token_regenerated: کد دسترسی با موفقیت ساخته شد warning: خیلی مواظب این اطلاعات باشید و آن را به هیچ کس ندهید! your_token: کد دسترسی شما auth: - change_password: رمز + apply_for_account: درخواست یک حساب + captcha_confirmation: + title: بررسی های امنیتی delete_account: پاک‌کردن حساب delete_account_html: اگر می‌خواهید حساب خود را پاک کنید، از این‌جا پیش بروید. از شما درخواست تأیید خواهد شد. description: prefix_invited_by_user: "@%{name} شما را به عضویت در این کارساز ماستودون دعوت کرده است!" prefix_sign_up: همین امروز عضو ماستودون شوید! suffix: با داشتن حساب می‌توانید دیگران را پی بگیرید، نوشته‌های تازه منتشر کنید، و با کاربران دیگر از هر سرور ماستودون دیگری و حتی سرورهای دیگر در ارتباط باشید! - didnt_get_confirmation: راهنمایی برای تأیید را دریافت نکردید؟ + didnt_get_confirmation: یک پیوند تأیید را دریافت نکردید؟ dont_have_your_security_key: کلید امنیتیتان را ندارید؟ - forgot_password: رمزتان را گم کرده‌اید؟ - invalid_reset_password_token: کد بازنشانی رمز نامعتبر یا منقضی شده است. لطفاً کد دیگری درخواست کنید. + forgot_password: گذرواژه خود را فراموش کرده‌اید؟ + invalid_reset_password_token: کد بازنشانی گذرواژه نامعتبر یا منقضی شده است. لطفاً کد دیگری درخواست کنید. link_to_otp: رمز بازگردانی یا رمز دوعاملی را از تلفنتان وارد کنید link_to_webauth: استفاده از افزارهٔ امنیتیتان log_in_with: ورود با @@ -747,43 +897,43 @@ fa: migrate_account: نقل مکان به یک حساب دیگر migrate_account_html: اگر می‌خواهید این حساب را به حساب دیگری منتقل کنید، این‌جا را کلیک کنید. or_log_in_with: یا ورود به وسیلهٔ + privacy_policy_agreement_html: سیاست محرمانگی را خوانده و پذیرفته‌ام + progress: + confirm: تأیید رایانامه + details: جزئیات شما providers: cas: CAS saml: SAML register: عضو شوید registration_closed: سرور %{instance} عضو تازه‌ای نمی‌پذیرد - resend_confirmation: راهنمایی برای تأیید را دوباره بفرست - reset_password: بازنشانی رمز + resend_confirmation: ارسال مجدد پیوند تایید + reset_password: بازنشانی گذرواژه + rules: + accept: پذیرفتن + back: بازگشت + title_invited: شما دعوت شده اید. security: امنیت - set_new_password: تعیین رمز تازه + set_new_password: تعین گذرواژه جدید setup: - email_below_hint_html: اگر نشانی ایمیل زیر نادرست است، می‌توانید آن را تغییر دهید و ایمیل تأیید دوباره‌ای دریافت کنید. - email_settings_hint_html: ایمیل تأیید به %{email} فرستاده شد. اگر این نشانی ایمیل درست نیست، می‌توانید از تنظیمات حساب آن را تغییر دهید. - title: راه اندازی + email_settings_hint_html: برای تأیید %{email}، روی پیوندی که برای شما ارسال کردیم ضربه بزنید. همین جا منتظر می‌مانیم. + link_not_received: پیوندی نگرفتید؟ + title: صندوق ورودیتان را بررسی کنید + sign_in: + title: ورود به %{domain} status: account_status: وضعیت حساب confirming: در حال انتظار برای کامل شدن تأیید ایمیل. + functional: حسابتان کاملاً قابل استفاده است. pending: درخواست شما منتظر تأیید مسئولان سایت است و این فرایند ممکن است کمی طول بکشد. اگر درخواست شما پذیرفته شود به شما ایمیلی فرستاده خواهد شد. redirecting_to: حساب شما غیرفعال است زیرا هم‌اکنون به %{acct} منتقل شده است. + view_strikes: دیدن شکایت‌های گذشته از حسابتان too_fast: فرم با سرعت بسیار زیادی فرستاده شد، دوباره تلاش کنید. use_security_key: استفاده از کلید امنیتی - authorize_follow: - already_following: شما همین الان هم این حساب را پی‌می‌گیرید - already_requested: درخواست پی‌گیری‌ای برای آن حساب فرستاده‌ بودید - error: متأسفانه حین یافتن آن حساب خطایی رخ داد - follow: پی بگیرید - follow_request: 'شما درخواست پیگیری فرستاده‌اید به:' - following: 'انجام شد! شما هم‌اینک پیگیر این کاربر هستید:' - post_follow: - close: یا این پنجره را ببندید. - return: نمایهٔ این کاربر را نشان بده - web: رفتن به وب - title: پیگیری %{acct} challenge: confirm: ادامه - hint_html: "نکته: ما در یک ساعت آینده رمزتان را از شما نخواهیم پرسید." - invalid_password: رمز نامعتبر - prompt: برای ادامه رمزتان را تأیید کنید + hint_html: "نکته: ما در یک ساعت آینده گذرواژه‌تان را از شما نخواهیم پرسید." + invalid_password: گذرواژه نامعتبر + prompt: برای ادامه گذرواژه‌تان را تأیید کنید crypto: errors: invalid_key: یک کلید معتبر Ed25519 یا Curve25519 نیست @@ -808,7 +958,7 @@ fa: x_seconds: "%{count} ثانیه" deletes: challenge_not_passed: اطلاعاتی که وارد کردید اشتباه بود - confirm_password: رمز فعلی خود را وارد کنید تا معلوم شود که خود شمایید + confirm_password: گذرواژه کنونی خود را وارد کنید تا هویتتان را تایید کنید confirm_username: برای تأیید این فرایند نام کاربری خود را وارد کنید proceed: پاک‌کردن حساب success_msg: حساب شما با موفقیت پاک شد @@ -825,18 +975,40 @@ fa: username_unavailable: نام کاربری شما برای دیگران غیرقابل دسترس خواهد ماند disputes: strikes: + action_taken: کنش انجام شده appeal: درخواست تجدیدنظر + appeal_approved: شکایت با موفّقیت تحدیدنظر شد و دیگر معتبر نیست appeal_rejected: درخواست تجدیدنظر رد شده است appeal_submitted_at: درخواست تجدیدنظر فرستاده شد + appealed_msg: درخواست تجدیدنظرتان ثبت شد. اگر پذیرفته شود آگاه خواهید شد. appeals: submit: فرستادن درخواست تجدیدنظر + approve_appeal: پذیرش درخواست تجدیدنظر + associated_report: گزارش همراه + created_at: مورخه + description_html: این‌ها کنش‌های انجام شده روی حسابتان و هشدارهاییند که از سوی مدیران %{instance} به شما فرستاده شده‌اند. + recipient: ابلاغی به + reject_appeal: رد کردن درخواست تجدیدنظر + status: فرستهٔ ‪#%{id}‬ + status_removed: فرسته از روس سامانه برداشته شده است + title: "%{action} در %{date}" title_actions: + delete_statuses: برداشتن فرسته + disable: انجماد حساب + mark_statuses_as_sensitive: علامت زدن فرسته به عنوان حسّاس none: هشدار - your_appeal_approved: درخواست تجدیدنظر شما پذیرفته شد + sensitive: علامت زدن حساب به عنوان حسّاس + silence: محدودیت حساب + suspend: تعلیق حساب + your_appeal_approved: درخواست تجدیدنظرتان پذیرفته شد your_appeal_pending: شما یک درخواست تجدیدنظر فرستادید - your_appeal_rejected: درخواست تجدیدنظر شما رد شد + your_appeal_rejected: درخواست تجدیدنظرتان رد شد domain_validator: invalid_domain: نام دامین معتبر نیست + edit_profile: + basic_information: اطلاعات پایه + hint_html: "شخصی‌سازی آن چه مردم روی نمایهٔ عمومیتان و کنار فرسته‌هایتان می‌بینند. هنگامی که نمایه‌ای کامل و یک تصویر نمایه داشته باشید،‌ احتمال پی‌گیری متقابل و تعامل با شما بیش‌تر است." + other: سایر errors: '400': درخواستی که فرستادید نامعتبر یا اشتباه بود. '403': شما اجازهٔ دیدن این صفحه را ندارید. @@ -851,7 +1023,7 @@ fa: content: شرمنده، یک چیزی از سمت ما اشتباه شده. title: این صفحه درست نیست '503': این صفحه به خاطر یک مشکل موقت در کارساز در دسترس نیست. - noscript_html: برای استفاده از نسخهٔ تحت وب ماستودون، لطفاً جاوااسکریپت را فعال کنید. یا به جایش می‌توانید یک کارهٔ ماستودون را به کار ببرید. + noscript_html: برای استفاده از کارهٔ وب ماستودون، لطفاً جاوااسکریپت را به کار بیندازید. یا به جایش می‌توانید یک کارهٔ بومی را به کار ببرید. existing_username_validator: not_found: کاربری با این نام کاربری در این کارساز پیدا نشد not_found_multiple: "%{usernames} پیدا نشد" @@ -883,22 +1055,47 @@ fa: public: خط زمانی‌های عمومی thread: گفتگوها edit: + add_keyword: افزودن کلیدواژه + keywords: کلیدواژه‌ها + statuses: فرسته‌های جدا title: ویرایش پالایه errors: + deprecated_api_multiple_keywords: این پارامترها نمی‌توانند از این برنامه تغییر یابند؛ چرا که به بیش از یک کلیدواژهٔ پالایه اعمال می‌شود. از برنامه‌ای جدیدتر یا میانای وب استفاده کنید. invalid_context: زمینه‌ای موجود نیست یا نامعتبر است index: delete: پاک‌کردن empty: هیچ پالایه‌ای ندارید. + expires_on: در %{date} منقضی می شود + keywords: + one: "%{count} کلیدواژه" + other: "%{count} کلیدواژه" + statuses: + one: "%{count} فرسته" + other: "%{count} فرسته" + statuses_long: + one: "%{count} فرستهٔ جداگانه نهفته" + other: "%{count} فرستهٔ جداگانه نهفته" title: پالایه‌ها new: + save: ذخیرهٔ پالایهٔ جدید title: افزودن پالایهٔ جدید - footer: - trending_now: پرطرفدار + statuses: + back_to_filter: بازگشت به پالایه + batch: + remove: برداشتن از پالایه + index: + title: فرسته‌های پالوده generic: all: همه + all_matching_items_selected_html: + one: "%{count} مورد مطابق با جست‌وجویتان گزیده شده." + other: "%{count} مورد مطابق با جست‌وجویتان گزیده شدند." + cancel: لغو changes_saved_msg: تغییرات با موفقیت ذخیره شدند! + confirm: تأیید copy: رونوشت delete: حذف + deselect: ناگزینش همه none: هیچ‌کدام order_by: مرتب‌سازی save_changes: ذخیرهٔ تغییرات @@ -906,18 +1103,26 @@ fa: validation_errors: one: یک چیزی هنوز درست نیست! لطفاً خطاهای زیر را ببینید other: یک چیزی هنوز درست نیست! لطفاً %{count} خطای زیر را ببینید - html_validator: - invalid_markup: 'دارای نشانه‌گذاری نامعتبر HTML است: %{error}' imports: errors: over_rows_processing_limit: دارای بیش از %{count} ردیف + too_large: حجم فایل خیلی بزرگ است + imported: وارد شد modes: merge: ادغام merge_long: داده‌های فعلی را داشته باشید و داده‌های تازه‌ای بیفزایید overwrite: بازنویسی overwrite_long: داده‌های فعلی را پاک کنید و داده‌های تازه‌ای بیفزایید preface: می‌توانید داده‌هایی را که از کارسازی دیگر برون‌ریخته‌اید، چون سیاهه‌ای از افرادی که پی گرفته یا مسدود می‌کنید را درون‌ریزی کنید. + recent_imports: واردشده‌های اخیر + states: + finished: پایان یافته + in_progress: در حال پیشرفت + scheduled: برنامه‌ریزی شده + unconfirmed: تایید نشده + status: وضعیت success: داده‌های شما با موفقیت بارگذاری شد و به زودی پردازش می‌شود + time_started: آغاز شده در types: blocking: سیاههٔ انسداد bookmarks: نشانک‌ها @@ -949,7 +1154,7 @@ fa: title: دعوت دیگران lists: errors: - limit: به بیشینهٔ مقدار سیاهه‌ها رسیدید + limit: به بیشینهٔ تعداد سیاهه‌ها رسیدید login_activities: authentication_methods: otp: کارهٔ تأیید هویت دوعاملی @@ -961,6 +1166,13 @@ fa: failed_sign_in_html: تلاش‌های شکست‌خوردهٔ ورود با %{method} از %{ip} (%{browser}) successful_sign_in_html: ورودهای موفق با %{method} از %{ip} (%{browser}) title: تاریخچهٔ تأیید هویت + mail_subscriptions: + unsubscribe: + complete: لغو اشتراک شد + emails: + notification_emails: + mention: رایانامه‌های آگاهی اشاره + title: لغو اشتراک media_attachments: validations: images_and_video: نمی‌توان برای نوشته‌ای که تصویر دارد ویدیو بارگذاری کرد @@ -1003,8 +1215,12 @@ fa: carry_blocks_over_text: این کاربر از %{acct} که مسدودش کرده‌اید، جابه‌جا شد. carry_mutes_over_text: این کاربر از %{acct} که خموشش کرده‌اید، جابه‌جا شد. copy_account_note_text: 'این کاربر از %{acct} جابه‌جا شده است. یادداشت‌های پیشینتان درباره‌اش این‌هاست:' + navigation: + toggle_menu: تغییر وضعیت فهرست notification_mailer: admin: + report: + subject: "%{name} گزارشی ثبت کرد" sign_up: subject: "%{name} ثبت نام کرد" favourite: @@ -1022,9 +1238,9 @@ fa: title: درخواست پیگیری تازه mention: action: پاسخ - body: "%{name} در این‌جا از شما نام برد:" - subject: "%{name} از شما نام برد" - title: نام‌برده‌شدن تازه + body: "%{name} در این‌جا به شما اشاره کرد:" + subject: "%{name} به شما اشاره کرد" + title: اشارهٔ جدید poll: subject: نظرسنجی‌ای از %{name} پایان یافت reblog: @@ -1033,6 +1249,8 @@ fa: title: تقویت تازه status: subject: "%{name} چیزی فرستاد" + update: + subject: "%{name} فرسته‌ای را ویرایست" notifications: email_events: رویدادها برای آگاهی‌های رایانامه‌ای email_events_hint: 'گزینش رویدادهایی که می‌خواهید برایشان آگاهی دریافت کنید:' @@ -1052,9 +1270,9 @@ fa: description_html: اگر ورود دومرحله‌ای را با استفاده از از یک کارهٔ تأییدکننده به کار بیندازید، لازم است برای ورود، به تلفن خود که برایتان یک ژتون خواهد ساخت دسترسی داشته باشید. enable: به کار انداختن instructions_html: "این کد QR را با برنامهٔ Google Authenticator یا برنامه‌های TOTP مشابه اسکن کنید. از این به بعد، آن برنامه کدهایی موقتی خواهد ساخت که برای ورود باید آن‌ها را وارد کنید." - manual_instructions: 'اگر نمی‌توانید رمز QR را بپویید و باید دستی واردظ کنید، متن رمز این‌جاست:' + manual_instructions: 'اگر نمی‌توانید رمز QR را بپویید و باید دستی وارد کنید، متن رمز این‌جاست:' setup: برپا سازی - wrong_code: رمز وارد شده نامعتبر بود! آیا زمان کارساز و زمان افزاره درستند؟ + wrong_code: کد وارد شده نامعتبر بود! آیا زمان کارساز و زمان افزاره درستند؟ pagination: newer: تازه‌تر next: بعدی @@ -1070,18 +1288,32 @@ fa: expired: این نظرسنجی به پایان رسیده است invalid_choice: گزینه رای دادن وجود ندارد over_character_limit: هر کدام نمی‌تواند از %{max} نویسه طولانی‌تر باشد + self_vote: شما نمی توانید در نظرسنجی خودتان رای دهید too_few_options: حتماً باید بیش از یک گزینه داشته باشد too_many_options: نمی‌تواند بیشتر از %{max} گزینه داشته باشد preferences: other: سایر تنظیمات posting_defaults: تنظیمات پیش‌فرض انتشار public_timelines: خط زمانی‌های عمومی + privacy: + hint_html: "شخصی‌سازی چگونگی پیدا شدن فرسته‌ها و نمایه‌تان. ویژگی‌های متعدّدی در ماستودون می‌توانند هنگام به کار افتادن در رسیدن به مخاطبینی گسترده‌تر یاریتان کنند. کمی وقت برای بازبینی این تنظیمات گذاشته تا مطمئن شوید برایتان مناسبند." + privacy: محرمانگی + reach: دسترسی + reach_hint_html: واپایش این که می‌خواهید به دست افراد جدید قابل کشف و پی‌گیری باشید یا نه. می‌خواهید فرسته‌هایتان روی صفحهٔ کشف ظاهر شوند؟ می‌خواهید دیگر افراد در پیشنهادهای پی‌گیریشان ببینندتان؟ می‌خواهید پی‌گیران جدید را به طور خودکار بپذیرید یا روی هرکدامشان واپایش داشته باشید؟ + search: جست‌وجو + search_hint_html: واپایش این که چگونه می‌خواهید پیدا شوید. می‌خواهید افراد با آن‌چه به صورت عمومی درباره‌اش فرستاده‌اید پیدایتان کنند؟ می‌خواهید افراد خارج از ماستودون هنگام جست‌وجوی وب نمایه‌تان را بیابند؟ لطفاً‌به خاطر داشته باشید که خروج کامل از تمامی موتورهای جست‌وجو برای اطّلاعات عمومی قابل تضمین نیست. + title: محرمانگی و دسترسی + privacy_policy: + title: سیاست محرمانگی reactions: errors: limit_reached: تجاوز از کران واکنش‌های مختلف unrecognized_emoji: شکلک شناخته‌شده‌ای نیست relationships: activity: فعالیت حساب + confirm_follow_selected_followers: آیا مطمئنید که می خواهید دنبال کننده های انتخابی را دنبال کنید؟ + confirm_remove_selected_followers: آیا شما واقعا می خواهید دنبال کننده های انتخابی را حذف کنید؟ + confirm_remove_selected_follows: آیا شما واقعا می خواهید دنبال شده های انتخابی را حذف کنید؟ dormant: غیرفعال follow_selected_followers: پیگیری پیگیران انتخاب شده followers: پی‌گیران @@ -1099,6 +1331,11 @@ fa: status: وضعیت حساب remote_follow: missing_resource: نشانی اینترنتی برای رسیدن به حساب شما پیدا نشد + rss: + content_warning: 'هشدا محتوا:' + descriptions: + account: فرسته‌های عمومی از ‪@%{acct}‬ + tag: فرسته‌های عمومی برچسب خورده با ‪#%{hashtag}‬ scheduled_statuses: over_daily_limit: شما از حد مجاز %{limit} فرسته زمان‌بندی‌شده در آن روز فراتر رفته‌اید over_total_limit: شما از حد مجاز %{limit} فرسته زمان‌بندی‌شده فراتر رفته‌اید @@ -1108,11 +1345,13 @@ fa: browser: مرورگر browsers: alipay: علی‌پی + blackberry: بلک‌بری chrome: کروم edge: مایکروسافت اج electron: الکترون firefox: فایرفاکس generic: مرورگر ناشناخته + huawei_browser: مرورگر هواوی ie: اینترنت اکسپلورر micro_messenger: مایکرومسنجر nokia: مرورگر اوی نوکیا اس۴۰ @@ -1121,6 +1360,8 @@ fa: phantom_js: فنتوم‌جی‌اس qq: مرورگر کیوکیو safari: سافاری + uc_browser: مرورگر یوسی + unknown_browser: مرورگر ناشناخته weibo: وبیو current_session: نشست فعلی description: "%{browser} روی %{platform}" @@ -1129,11 +1370,14 @@ fa: platforms: adobe_air: ایر ادوبی android: اندروید + blackberry: بلک‌بری + chrome_os: سیستم‌عامل کروم firefox_os: سیستم‌عامل فایرفاکس ios: آی‌اواس + kai_os: سیستم‌عامل کای linux: لینوکس mac: مک - other: سیستم ناشناخته + unknown_platform: بن‌سازهٔ ناشناخته windows: ویندوز windows_mobile: ویندوز همراه windows_phone: تلفن ویندوزی @@ -1161,6 +1405,7 @@ fa: profile: نمایه relationships: پیگیری‌ها و پیگیران statuses_cleanup: حذف فرستهٔ خودکار + strikes: شکایت‌های مدیریتی two_factor_authentication: ورود دومرحله‌ای webauthn_authentication: کلیدهای امنیتی statuses: @@ -1177,9 +1422,11 @@ fa: other: "%{count} ویدیو" boosted_from_html: تقویت شده از طرف %{acct_link} content_warning: 'هشدا محتوا: %{warning}' + default_language: همانند زبان واسط disallowed_hashtags: one: 'دارای برچسبی غیرمجاز: %{tags}' other: 'دارای برچسب‌های غیرمجاز: %{tags}' + edited_at_html: ویراسته در %{date} errors: in_reply_not_found: به نظر نمی‌رسد وضعیتی که می‌خواهید به آن پاسخ دهید، وجود داشته باشد. open_in_web: گشودن در وب @@ -1201,7 +1448,6 @@ fa: show_newer: نمایش جدیدتر show_older: نمایش قدیمی‌تر show_thread: نمایش رشته - sign_in_to_participate: برای شرکت در گفتگو وارد حساب خود شوید title: "%{name}: «%{quote}»" visibilities: direct: مستقیم @@ -1243,13 +1489,14 @@ fa: '7889238': ۳ ماه min_age_label: کرانهٔ سن min_favs: نگه داشتن فرسته‌هایی با برگزینش بیش از - min_favs_hint: هیچ یک از فرسته‌هایتان را که بیش از این تعداد برگزیده شده باشند، حذف نمی‌کند. برای حذف فرسته‌ها فارغ از تعداد برگزینش‌هایشان، خالی بگذارید + min_favs_hint: هیچ یک از فرسته‌هایتان را که کمینه این مقدار برگزیده شده باشند، حذف نمی‌کند. برای حذف فرسته‌ها فارغ از تعداد برگزینش‌هایشان، خالی بگذارید min_reblogs: نگه داشتن فرسته‌هایی با تقویت بیش از min_reblogs_hint: هیچ یک از فرسته‌هایتان را که بیش از این تعداد تقویت شده باشند، حذف نمی‌کند. برای حذف فرسته‌ها فارغ از تعداد تقویت‌هایشان، خالی بگذارید stream_entries: - pinned: نوشته‌های ثابت - reblogged: تقویت شده sensitive_content: محتوای حساس + strikes: + errors: + too_late: برای درخواست تجدیدنظر این شکایت بیش از حد دیر شده tags: does_not_match_previous_name: با نام پیشین مطابق نیست themes: @@ -1290,6 +1537,10 @@ fa: explanation: شما یک نسخهٔ پشتیبان کامل از حساب خود را درخواست کردید. این پشتیبان الان آمادهٔ بارگیری است! subject: بایگانی شما آمادهٔ دریافت است title: گرفتن بایگانی + suspicious_sign_in: + change_password: تغییر گذرواژه‌تان + details: 'جزییات ورود:' + title: یک ورود جدید warning: appeal: فرستادن یک درخواست تجدیدنظر appeal_description: اگر فکر می‌کنید این یک خطا است، می‌توانید یک درخواست تجدیدنظر به کارکنان %{instance} ارسال کنید. @@ -1304,26 +1555,35 @@ fa: title: delete_statuses: فرسته‌ها برداشته شدند disable: حساب متوقف شده است + mark_statuses_as_sensitive: فرسته‌ها به عنوان حسّاس علامت خوردند none: هشدار + sensitive: حساب به عنوان حساس علامت خورد silence: حساب محدود شده است suspend: حساب معلق شده است welcome: edit_profile_action: تنظیم نمایه + edit_profile_step: می‌توانید نمایه‌تان را با بارگذاری تصویر نمایه، تغییر نام نمایشی و بیش از این‌‌ها سفارشی کنید. می‌توانید تعیین کنید که پی‌گیران جدید را پیش‌از این که بتوانند دنبالتان کنند بازبینی کنید. explanation: نکته‌هایی که برای آغاز کار به شما کمک می‌کنند final_action: چیزی منتشر کنید + final_step: 'چیزی بنویسید! حتا بدون پی‌گیر ممکن است فرسته‌های عمومیتان دیده شود. برای مثال روی خط زمانی محلی یا در برچسب‌ها. شاید بخواهید با برچسب #معرفی خودتان را معرّفی کنید.' full_handle: نام کاربری کامل شما full_handle_hint: این چیزی است که باید به دوستانتان بگویید تا بتوانند از کارسازی دیگر به شما پیام داده یا پی‌گیرتان شوند. subject: به ماستودون خوش آمدید title: خوش آمدید، کاربر %{name}! users: follow_limit_reached: شما نمی‌توانید بیش از %{limit} نفر را پی بگیرید + go_to_sso_account_settings: به تنظیمات حساب فراهمگر هوبتتان بروید invalid_otp_token: کد ورود دومرحله‌ای نامعتبر است otp_lost_help_html: اگر شما دسترسی به هیچ‌کدامشان ندارید، باید با ایمیل %{email} تماس بگیرید - seamless_external_login: شما با یک سرویس خارج از مجموعه وارد شده‌اید، به همین دلیل تنظیمات ایمیل و رمز برای شما در دسترس نیست. + seamless_external_login: شما با یک سرویس خارج از مجموعه وارد شده‌اید، به همین دلیل تنظیمات ایمیل و گذرواژه برای شما در دسترس نیست. signed_in_as: 'واردشده به نام:' verification: - explanation_html: 'شما می‌توانید خود را به عنوان مالک صفحه‌ای که در نمایه‌تان به آن پیوند داده‌اید تأیید کنید. برای این کار، صفحه‌ای که به آن پیوند داده‌اید، خودش باید پیوندی به نمایهٔ ماستودون شما داشته باشد. پیوند در آن صفحه باید عبارت rel="me"‎ را به عنوان مشخّصهٔ (attribute) در خود داشته باشد. محتوای متن پیوند اهمتی ندارد. یک نمونه از چنین پیوندی:' + extra_instructions_html: نکته: پیوند روی پایگاه وبتان می‌تواند نامرئی باشد. بخش مهم rel="me" است که از جعل هویت روی پایگاه‌هایی با محتوای تولید شده به دست کاربر جلوگیری می‌کند. حتا می‌توانید به جای برچسب a از برچسب link در سرایند صفحه استفاده کنید؛ ولی HTML باید بدون اجرای جاوااسکریپت در دسترس باشد. + here_is_how: به اینصورت + hint_html: "تأیید هویتتان روی ماستودون برای همه است. برپایهٔ استانداردهای وب و رایگان برای همیشه. تمام آن چه نیاز دارید پایگاه وب شخصیست که افراد شما را با آن بشناسند. هنگام پیوند دادن به این پایگاه از نمایه‌تان، بررسی می‌کنیم که پیوندهای پایگاه وب نیز به نمایه‌تان پیوند داده باشد و نشانگری تصویری رویش نشان می‌دهیم." + instructions_html: کد زیر را رونوشت کرده و در HTML پایگاه وبتان جایگذاری کنید. سپس نشانی پایگاه وبتان را از زبانهٔ «ویرایش نمایه» در یکی از زمینه‌های اضافی روی نمایه‌تان افزوده و تغییرات را ذخیره کنید. verification: تأیید + verified_links: "‏پیوندهای تأییدشده‌ شما" webauthn_credentials: add: افزودن کلید امنیتی create: diff --git a/config/locales/fi.yml b/config/locales/fi.yml index cbff5c237a..2043d327a1 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1,7 +1,7 @@ --- fi: about: - about_mastodon_html: 'Tulevaisuuden sosiaalinen verkosto: Ei mainoksia, ei valvontaa, toteutettu avoimilla protokollilla ja hajautettu! Pidä tietosi ominasi Mastodonilla!' + about_mastodon_html: 'Tulevaisuuden sosiaalinen verkosto: ei mainoksia, ei valvontaa, toteutettu avoimilla protokollilla ja hajautettu rakenne! Pidä tietosi ominasi Mastodonin avulla!' contact_missing: Ei asetettu contact_unavailable: Ei saatavilla hosted_on: Mastodon palvelimella %{domain} @@ -9,10 +9,10 @@ fi: accounts: follow: Seuraa followers: - one: Seuraaja - other: Seuraajat - following: Seuraaja - instance_actor_flash: Tämä on virtuaalitili, jota käytetään edustamaan itse palvelinta eikä yksittäistä käyttäjää. Sitä käytetään yhdistämistarkoituksiin, eikä sitä tule jäädyttää. + one: seuraaja + other: seuraajaa + following: seurattu(a) + instance_actor_flash: Tämä tili on virtuaalinen toimija, jota käytetään edustamaan itse palvelinta eikä yksittäistä käyttäjää. Sitä käytetään federointitarkoituksiin, eikä sitä tule jäädyttää. last_active: viimeksi aktiivinen link_verified_on: Tämän linkin omistus on tarkastettu %{date} nothing_here: Täällä ei ole mitään! @@ -20,16 +20,16 @@ fi: following: Sinun täytyy seurata henkilöä jota haluat tukea posts: one: Julkaisu - other: Viestit - posts_tab_heading: Viestit + other: viestiä + posts_tab_heading: Julkaisut admin: account_actions: action: Suorita toimenpide - title: Suorita moderointitoiminto %{acct} + title: Suorita valvontatoimi käyttäjälle %{acct} account_moderation_notes: create: Jätä muistiinpano - created_msg: Moderointimerkinnän luonti onnistui! - destroyed_msg: Moderointimerkinnän poisto onnistui! + created_msg: Valvontamerkinnän luonti onnistui! + destroyed_msg: Valvontamerkinnän poisto onnistui! accounts: add_email_domain_block: Estä sähköpostidomain approve: Hyväksy @@ -43,12 +43,12 @@ fi: label: Vaihda sähköposti new_email: Uusi sähköposti submit: Vaihda sähköposti - title: Vaihda sähköposti käyttäjälle %{username} + title: Vaihda käyttäjän %{username} sähköposti-osoite change_role: changed_msg: Rooli vaihdettu onnistuneesti! label: Vaihda roolia no_role: Ei roolia - title: Vaihda roolia käyttäjälle %{username} + title: Vaihda käyttäjän %{username} roolia confirm: Vahvista confirmed: Vahvistettu confirming: Vahvistetaan @@ -61,7 +61,7 @@ fi: disable_sign_in_token_auth: Poista sähköpostitunnuksen todennus käytöstä disable_two_factor_authentication: Poista 2FA käytöstä disabled: Poistettu käytöstä - display_name: Nimimerkki + display_name: Näyttönimi domain: Verkkotunnus edit: Muokkaa email: Sähköposti @@ -71,12 +71,12 @@ fi: enabled: Käytössä enabled_msg: Käyttäjän %{username} tili palautettu onnistuneesti käyttöön followers: Seuraajat - follows: Seuraa + follows: Seuratut header: Otsakekuva inbox_url: Saapuvan postilaatikon osoite invite_request_text: Syitä liittymiseen invited_by: Kutsuja - ip: IP + ip: IP-osoite joined: Liittynyt location: all: Kaikki @@ -91,11 +91,12 @@ fi: moderation: active: Aktiivinen all: Kaikki + disabled: Ei käytössä pending: Odottavat silenced: Rajoitettu - suspended: Jäähyllä - title: Moderointi - moderation_notes: Moderointimerkinnät + suspended: Jäädytetty + title: Valvonta + moderation_notes: Valvontamerkinnät most_recent_activity: Viimeisin toiminta most_recent_ip: Viimeisin IP no_account_selected: Yhtään tiliä ei muutettu, koska mitään ei valittu @@ -103,7 +104,7 @@ fi: no_role_assigned: Roolia ei ole määritetty not_subscribed: Ei tilaaja pending: Odottaa tarkistusta - perform_full_suspension: Siirrä kokonaan jäähylle + perform_full_suspension: Jäädytä previous_strikes: Aiemmat varoitukset previous_strikes_description_html: one: Tällä tilillä on yksi varoitus. @@ -117,15 +118,15 @@ fi: reject: Hylkää rejected_msg: Käyttäjän %{username} rekisteröitymishakemus hylättiin remote_suspension_irreversible: Tämän tilin tiedot on poistettu peruuttamattomasti. - remote_suspension_reversible_hint_html: Tili on jäädytetty heidän palvelimellaan, ja tilin kaikki tiedot poistetaan %{date}. Ennen tätä ajankohtaa on kyseessä olevan palvelimen ylläpidolla mahdollisuus palauttaa tili ongelmitta. Jos puolestaan haluat poistaa tilin tietoineen heti, onnistuu se alta. + remote_suspension_reversible_hint_html: Tili on jäädytetty heidän palvelimellaan, ja kaikki tiedot poistetaan %{date}. Sitä ennen etäpalvelin voi palauttaa tilin ongelmitta. Jos haluat poistaa kaikki tilin tiedot heti, onnistuu se alta. remove_avatar: Poista profiilikuva remove_header: Poista otsakekuva removed_avatar_msg: Käyttäjän %{username} avatar-kuva poistettu onnistuneesti removed_header_msg: Käyttäjän %{username} otsakekuva poistettiin onnistuneesti resend_confirmation: already_confirmed: Tämä käyttäjä on jo vahvistettu - send: Lähetä vahvistusviesti uudelleen - success: Vahvistusviesti onnistuneesti lähetetty! + send: Lähetä vahvistuslinkki uudelleen + success: Vahvistuslinkki on lähetetty! reset: Palauta reset_password: Palauta salasana resubscribe: Tilaa uudelleen @@ -133,6 +134,7 @@ fi: search: Hae search_same_email_domain: Muut käyttäjät, joilla on sama sähköpostin verkkotunnus search_same_ip: Muut käyttäjät, joilla on sama IP-osoite + security: Turvallisuus security_measures: only_password: Vain salasana password_and_2fa: Salasana ja kaksivaiheinen tunnistautuminen @@ -142,21 +144,21 @@ fi: show: created_reports: Tämän tilin luomat raportit targeted_reports: Tästä tilistä tehdyt raportit - silence: Hiljennä - silenced: Mykistetty - statuses: Viestit + silence: Rajoita + silenced: Rajoitettu + statuses: Julkaisut strikes: Aiemmat varoitukset subscribe: Tilaa suspend: Jäädytä - suspended: Jäähyllä - suspension_irreversible: Tämän tilin tiedot on poistettu peruuttamattomasti. Voit peruuttaa tilin jäädyttämisen, jolloin siitä tulee käyttökelpoinen, mutta toiminto ei palauta sillä aiemmin olleita tietoja. - suspension_reversible_hint_html: Tili on jäädytetty, ja tiedot poistetaan kokonaan %{date}. Siihen asti tili voidaan palauttaa ilman haitallisia vaikutuksia. Jos haluat poistaa kaikki tilin tiedot välittömästi, voit tehdä sen alla. + suspended: Jäädytetty + suspension_irreversible: Tämän tilin tiedot on poistettu peruuttamattomasti. Voit kumota tilin jäädytyksen, jolloin siitä tulee käyttökelpoinen, mutta toiminto ei palauta sillä aiemmin olleita tietoja. + suspension_reversible_hint_html: Tili on jäädytetty, ja tiedot poistetaan kokonaan %{date}. Siihen asti tili voidaan palauttaa ongelmitta. Jos haluat poistaa kaikki tilin tiedot heti, onnistuu se alta. title: Tilit unblock_email: Poista sähköpostiosoitteen esto unblocked_email_msg: Käyttäjän %{username} sähköpostiosoitteen esto kumottiin unconfirmed_email: Sähköpostia ei vahvistettu undo_sensitized: Kumoa pakotus arkaluonteiseksi tiliksi - undo_silenced: Peru hiljennys + undo_silenced: Kumoa rajoitus undo_suspension: Peru jäähy unsilenced_msg: Tilin %{username} rajoituksen kumoaminen onnistui unsubscribe: Lopeta tilaus @@ -165,7 +167,7 @@ fi: view_domain: Näytä verkkotunnuksen yhteenveto warn: Varoita web: Verkko - whitelisted: Sallittu federaatioon + whitelisted: Sallittu federoimaan action_logs: action_types: approve_appeal: Hyväksy valitus @@ -175,7 +177,7 @@ fi: change_role_user: Muuta käyttäjän roolia confirm_user: Vahvista käyttäjä create_account_warning: Luo varoitus - create_announcement: Luo ilmoitus + create_announcement: Luo tiedote create_canonical_email_block: Luo sähköpostin esto create_custom_emoji: Luo mukautettu emoji create_domain_allow: Luo verkkotunnuksen salliminen @@ -185,7 +187,7 @@ fi: create_unavailable_domain: Luo ei-saatavilla oleva verkkotunnus create_user_role: Luo rooli demote_user: Alenna käyttäjä - destroy_announcement: Poista ilmoitus + destroy_announcement: Poista tiedote destroy_canonical_email_block: Poista sähköpostin esto destroy_custom_emoji: Poista mukautettu emoji destroy_domain_allow: Poista verkkotunnuksen salliminen @@ -193,7 +195,7 @@ fi: destroy_email_domain_block: Poista sähköpostin verkkotunnuksen esto destroy_instance: Tyhjennä verkkotunnus destroy_ip_block: Poista IP-sääntö - destroy_status: Poista viesti + destroy_status: Poista julkaisu destroy_unavailable_domain: Poista ei-saatavilla oleva verkkotunnus destroy_user_role: Hävitä rooli disable_2fa_user: Poista kaksivaiheinen tunnistautuminen käytöstä @@ -213,77 +215,77 @@ fi: reset_password_user: Nollaa salasana resolve_report: Selvitä raportti sensitive_account: Pakotus arkaluontoiseksi tiliksi - silence_account: Hiljennä tili + silence_account: Rajoita tiliä suspend_account: Jäädytä tili unassigned_report: Peruuta raportin määritys unblock_email_account: Poista sähköpostiosoitteen esto unsensitive_account: Kumoa pakotus arkaluontoiseksi tiliksi - unsilence_account: Peruuta tilin rajoitus - unsuspend_account: Peruuta tilin jäädytys - update_announcement: Päivitä ilmoitus - update_custom_emoji: Päivitä muokattu emoji + unsilence_account: Kumoa tilin rajoitus + unsuspend_account: Kumoa tilin jäädytys + update_announcement: Päivitä tiedote + update_custom_emoji: Päivitä mukautettu emoji update_domain_block: Päivitä verkkotunnuksen esto update_ip_block: Päivitä IP-sääntö - update_status: Päivitä viesti + update_status: Päivitä julkaisu update_user_role: Päivitä rooli actions: - approve_appeal_html: "%{name} hyväksyi moderointipäätöksen muutoksenhaun lähettäjältä %{target}" + approve_appeal_html: "%{name} hyväksyi valvontapäätöksen valituksen käyttäjältä %{target}" approve_user_html: "%{name} hyväksyi käyttäjän rekisteröitymisen kohteesta %{target}" assigned_to_self_report_html: "%{name} otti raportin %{target} tehtäväkseen" change_email_user_html: "%{name} vaihtoi käyttäjän %{target} sähköpostiosoitteen" change_role_user_html: "%{name} muutti käyttäjän %{target} roolia" confirm_user_html: "%{name} vahvisti käyttäjän %{target} sähköpostiosoitteen" create_account_warning_html: "%{name} lähetti varoituksen käyttäjälle %{target}" - create_announcement_html: "%{name} loi uuden ilmoituksen %{target}" + create_announcement_html: "%{name} loi uuden tiedotteen %{target}" create_canonical_email_block_html: "%{name} esti sähköpostin hashilla %{target}" create_custom_emoji_html: "%{name} lähetti uuden emojin %{target}" - create_domain_allow_html: "%{name} salli federaation verkkotunnuksella %{target}" + create_domain_allow_html: "%{name} salli federoinnin verkkotunnuksen %{target} kanssa" create_domain_block_html: "%{name} esti verkkotunnuksen %{target}" create_email_domain_block_html: "%{name} esti sähköpostin %{target}" create_ip_block_html: "%{name} loi IP-säännön %{target}" create_unavailable_domain_html: "%{name} pysäytti toimituksen verkkotunnukseen %{target}" create_user_role_html: "%{name} loi roolin %{target}" demote_user_html: "%{name} alensi käyttäjän %{target}" - destroy_announcement_html: "%{name} poisti ilmoituksen %{target}" + destroy_announcement_html: "%{name} poisti tiedotteen %{target}" destroy_canonical_email_block_html: "%{name} poisti sähköpostieston hashilla %{target}" destroy_custom_emoji_html: "%{name} poisti emojin %{target}" - destroy_domain_allow_html: "%{name} esti federaation verkkotunnuksella %{target}" + destroy_domain_allow_html: "%{name} kielsi federoinnin verkkotunnuksen %{target} kanssa" destroy_domain_block_html: "%{name} poisti verkkotunnuksen %{target} eston" destroy_email_domain_block_html: "%{name} poisti sähköpostin verkkotunnuksen %{target} eston" destroy_instance_html: "%{name} tyhjensi verkkotunnuksen %{target}" destroy_ip_block_html: "%{name} poisti IP-säännön %{target}" - destroy_status_html: "%{name} poisti käyttäjän %{target} viestin" + destroy_status_html: "%{name} poisti käyttäjän %{target} julkaisun" destroy_unavailable_domain_html: "%{name} jatkoi toimitusta verkkotunnukseen %{target}" destroy_user_role_html: "%{name} poisti roolin %{target}" disable_2fa_user_html: "%{name} poisti käyttäjältä %{target} vaatimuksen kaksivaiheisen todentamiseen" disable_custom_emoji_html: "%{name} poisti käytöstä emojin %{target}" disable_sign_in_token_auth_user_html: "%{name} poisti sähköpostitunnuksen %{target} todennuksen käytöstä" disable_user_html: "%{name} poisti kirjautumisen käyttäjältä %{target}" - enable_custom_emoji_html: "%{name} salli emojin %{target}" - enable_sign_in_token_auth_user_html: "%{name} aktivoi sähköpostitunnuksen käyttäjälle %{target}" - enable_user_html: "%{name} salli kirjautumisen käyttäjälle %{target}" + enable_custom_emoji_html: "%{name} otti käyttöön emojin %{target}" + enable_sign_in_token_auth_user_html: "%{name} otti todennuksen sähköpostivaltuutuksella käyttöön käyttäjälle %{target}" + enable_user_html: "%{name} otti kirjautumisen käyttöön käyttäjälle %{target}" memorialize_account_html: "%{name} muutti käyttäjän %{target} tilin muistosivuksi" promote_user_html: "%{name} ylensi käyttäjän %{target}" - reject_appeal_html: "%{name} hylkäsi moderointipäätöksen muutoksenhaun %{target}" + reject_appeal_html: "%{name} hylkäsi valvontapäätöksen valituksen käyttäjältä %{target}" reject_user_html: "%{name} hylkäsi käyttäjän rekisteröitymisen kohteesta %{target}" remove_avatar_user_html: "%{name} poisti käyttäjän %{target} profiilikuvan" reopen_report_html: "%{name} avasi uudelleen raportin %{target}" - resend_user_html: "%{name} lähetti vahvistusviestin sähköpostitse käyttäjälle %{target}" + resend_user_html: "%{name} lähetti vahvistussähköpostiviestin uudelleen käyttäjälle %{target}" reset_password_user_html: "%{name} palautti käyttäjän %{target} salasanan" resolve_report_html: "%{name} ratkaisi raportin %{target}" sensitive_account_html: "%{name} merkitsi käyttäjän %{target} median arkaluonteiseksi" - silence_account_html: "%{name} rajoitti käyttäjän %{target} tilin" - suspend_account_html: "%{name} siirsi käyttäjän %{target} jäähylle" + silence_account_html: "%{name} rajoitti käyttäjän %{target} tiliä" + suspend_account_html: "%{name} jäädytti käyttäjän %{target} tilin" unassigned_report_html: "%{name} peruutti raportin määrityksen %{target}" unblock_email_account_html: "%{name} poisti käyttäjän %{target} sähköpostiosoitteen eston" unsensitive_account_html: "%{name} poisti käyttäjän %{target} median arkaluonteisen merkinnän" - unsilence_account_html: "%{name} ei tehnyt rajoitusta %{target} tilille" - unsuspend_account_html: "%{name} perui käyttäjän %{target} jäähyn" - update_announcement_html: "%{name} päivitti ilmoituksen %{target}" + unsilence_account_html: "%{name} kumosi käyttäjän %{target} rajoituksen" + unsuspend_account_html: "%{name} kumosi käyttäjän %{target} tilin jäädytyksen" + update_announcement_html: "%{name} päivitti tiedotteen %{target}" update_custom_emoji_html: "%{name} päivitti emojin %{target}" update_domain_block_html: "%{name} päivitti verkkotunnuksen %{target} eston" update_ip_block_html: "%{name} muutti sääntöä IP-osoitteelle %{target}" - update_status_html: "%{name} päivitti viestin %{target}" + update_status_html: "%{name} päivitti käyttäjän %{target} julkaisun" update_user_role_html: "%{name} muutti roolia %{target}" deleted_account: poisti tilin empty: Lokeja ei löytynyt. @@ -291,53 +293,54 @@ fi: filter_by_user: Suodata käyttäjän mukaan title: Auditointiloki announcements: - destroyed_msg: Ilmoitus poistettu onnistuneesti! + destroyed_msg: Tiedote poistettu onnistuneesti! edit: - title: Muokkaa ilmoitusta - empty: Yhtään ilmoitusta ei löytynyt. - live: Suora + title: Muokkaa tiedotetta + empty: Tiedotteita ei löytynyt. + live: Julki new: - create: Luo ilmoitus - title: Uusi ilmoitus + create: Luo tiedote + title: Uusi tiedote publish: Julkaise - published_msg: Ilmoitus julkaistu onnistuneesti! - scheduled_for: Ajastettu %{time} - scheduled_msg: Ilmoitus on ajastettu julkaisua varten! - title: Ilmoitukset + published_msg: Tiedote julkaistu onnistuneesti! + scheduled_for: Ajoitettu %{time} + scheduled_msg: Tiedotteen julkaisu ajoitettu! + title: Tiedotteet unpublish: Lopeta julkaisu - unpublished_msg: Ilmoituksen julkaisu lopetettu! - updated_msg: Ilmoitus päivitetty onnistuneesti! + unpublished_msg: Tiedotteen julkaisu lopetettu onnistuneesti! + updated_msg: Tiedote päivitetty onnistuneesti! + critical_update_pending: Kriittinen päivitys odottaa custom_emojis: - assign_category: Aseta kategoria + assign_category: Aseta luokka by_domain: Verkkotunnus copied_msg: Emojin paikallisen kopion luonti onnistui copy: Kopioi copy_failed_msg: Emojista ei voitu tehdä paikallista kopiota - create_new_category: Luo uusi kategoria + create_new_category: Luo uusi luokka created_msg: Emojin luonti onnistui! delete: Poista destroyed_msg: Emojon poisto onnistui! disable: Poista käytöstä disabled: Ei käytössä - disabled_msg: Emojin poisto käytöstä onnistui + disabled_msg: Emojin käytöstäpoisto onnistui emoji: Emoji enable: Ota käyttöön enabled: Käytössä enabled_msg: Emojin käyttöönotto onnistui image_hint: PNG tai GIF, enintään %{size} - list: Listaa - listed: Listassa + list: Lisää listalle + listed: Listalla new: title: Lisää uusi mukautettu emoji no_emoji_selected: Emojeita ei muutettu, koska yhtään ei valittu not_permitted: Sinulla ei ole oikeutta suorittaa tätä toimintoa - overwrite: Kirjoita yli + overwrite: Korvaa shortcode: Lyhennekoodi shortcode_hint: Vähintään kaksi merkkiä, vain kirjaimia, numeroita ja alaviivoja title: Mukautetut emojit uncategorized: Luokittelemattomat unlist: Poista listalta - unlisted: Ei listassa + unlisted: Ei listalla update_failed_msg: Emojin päivitys epäonnistui updated_msg: Emojin päivitys onnistui! upload: Lähetä @@ -346,26 +349,26 @@ fi: interactions: vuorovaikutukset media_storage: Median tallennustila new_users: uudet käyttäjät - opened_reports: raportit avattu + opened_reports: avatut raportit pending_appeals_html: one: "%{count} vireillä oleva valitus" - other: "%{count} vireillä olevat valitukset" + other: "%{count} vireillä olevaa valitusta" pending_reports_html: one: "%{count} odottava raportti" - other: "%{count} odottavat raportit" + other: "%{count} odottavaa raporttia" pending_tags_html: - one: "%{count} odottava hashtagi" + one: "%{count} odottava aihetunniste" other: "%{count} odottavaa aihetunnistetta" pending_users_html: one: "%{count} odottava käyttäjä" - other: "%{count} odottavat käyttäjät" - resolved_reports: raportit ratkaistu + other: "%{count} odottavaa käyttäjää" + resolved_reports: ratkaistut raportit software: Ohjelmisto sources: Rekisteröitymisen lähteet space: Tilankäyttö title: Hallintapaneeli - top_languages: Aktiiviset kielet - top_servers: Aktiiviset palvelimet + top_languages: Aktiivisimmat kielet + top_servers: Aktiivisimmat palvelimet website: Sivusto disputes: appeals: @@ -373,38 +376,47 @@ fi: title: Valitukset domain_allows: add_new: Salli liitto verkkotunnuksella - created_msg: Verkkotunnus on onnistuneesti sallittu federaatiolle - destroyed_msg: Verkkotunnus on estetty federaatiossa + created_msg: Verkkotunnus on onnistuneesti sallittu federoinnille + destroyed_msg: Verkkotunnusta on kielletty federoimasta export: Vie import: Tuo undo: Estä liitto verkkotunnukselle domain_blocks: add_new: Lisää uusi + confirm_suspension: + cancel: Peruuta + confirm: Jäädytä + permanent_action: Jäädytyksen kumoaminen ei palauta mitään tietoja tai suhteita. + preamble_html: Olet jäädyttämässä verkkotunnuksen %{domain} ja sen aliverkkotunnukset. + remove_all_data: Tämä toiminto poistaa palvelimeltasi kaiken sisällön, median ja profiilitiedot tämän palvelun tileiltä. + stop_communication: Palvelimesi lopettaa viestinnän näiden palvelinten kanssa. + title: Vahvista verkkotunnuksen %{domain} esto + undo_relationships: Tämä kumoaa näiden palvelimien ja sinun tilien välisen seurannan. created_msg: Verkkotunnuksen estoa käsitellään destroyed_msg: Verkkotunnuksen esto on peruttu domain: Verkkotunnus edit: Muokkaa verkkotunnuksen estoa - existing_domain_block: Olet jo asettanut tiukemmat rajoitukset %{name}. - existing_domain_block_html: Olet jo asettanut %{name} tiukemmat rajat ja sinun täytyy poistaa se ensin. + existing_domain_block: Olet jo asettanut tiukemmat rajoitukset käyttäjälle %{name}. + existing_domain_block_html: Olet jo asettanut tiukemmat rajoitukset käyttäjälle %{name}, joten sinun täytyy poistaa sen esto ensin. export: Vie import: Tuo new: create: Luo esto - hint: Verkkotunnuksen esto ei estä tilien luomista ja lisäämistä tietokantaan, mutta se soveltaa näihin tileihin automaattisesti määrättyjä moderointitoimia tilin luomisen jälkeen. + hint: Verkkotunnuksen esto ei estä tilien lisäämistä tietokantaan, mutta se soveltaa näihin tileihin takautuvasti ja automaattisesti tiettyjä valvontatoimia. severity: - desc_html: "Rajoita -valinta piilottaa tämän verkkoalueen tilien julkaisut heiltä, jotka eivät seuraa kyseisiä tilejä. Lopeta poistaa kaiken sisällön, median ja profiilien tiedot tämän verkkotunnuksen tileiltä palvelimellasi. Käytä valintaa Ei mitään, jos haluat vain estää mediatiedostojen julkaisemisen." + desc_html: Valinta Rajoita piilottaa tässä verkkotunnuksessa sijaitsevien tilien julkaisut kaikilta, jotka eivät seuraa näitä tilejä. Valinta Jäädytä poistaa palvelimeltasi kaikkien tässä verkkotunnuksessa sijaitsevien tilien sisällön, median ja profiilitiedot. Käytä valintaa Ei mitään, jos haluat vain hylätä mediatiedostot. noop: Ei mitään silence: Rajoita - suspend: Jäähy + suspend: Jäädytä title: Uusi verkkotunnuksen esto no_domain_block_selected: Verkkoalue-estoihin ei tehty muutoksia, koska valintoja ei tehty not_permitted: Nykyiset käyttöoikeutesi eivät kata tätä toimintoa obfuscate: Peitä verkkotunnuksen nimi - obfuscate_hint: Peitä verkkotunnus osittain luettelossa, jos verkkotunnuksen rajoitusten luettelo on käytössä + obfuscate_hint: Peitä verkkotunnus osittain luettelossa, jos julkinen verkkotunnusten rajoitusluettelo on käytössä private_comment: Yksityinen kommentti private_comment_hint: Kommentoi tätä verkkotunnuksen rajoitusta, valvojien sisäiseen käyttöön. public_comment: Julkinen kommentti - public_comment_hint: Kommentoi tätä verkkotunnukselle koskevaa rajoitusta suurelle yleisölle, jos verkkotunnusten luettelon mainonta on käytössä. + public_comment_hint: Kommentoi tätä verkkotunnuksen rajoitusta suurelle yleisölle, jos julkinen verkkotunnusten rajoitusluettelo on käytössä. reject_media: Hylkää mediatiedostot reject_media_hint: Poistaa paikallisesti tallennetut mediatiedostot eikä lataa niitä enää jatkossa. Ei merkitystä jäähyn kohdalla reject_reports: Hylkää raportit @@ -420,13 +432,14 @@ fi: delete: Poista dns: types: - mx: MX tietue + mx: MX-tietue domain: Verkkotunnus new: create: Lisää verkkotunnus resolve: Ratkaise verkkotunnus title: Uusi sähköpostiestolistan merkintä no_email_domain_block_selected: Sähköpostin verkkotunnuksia ei muutettu, koska yhtään ei valittu + not_permitted: Ei sallittu resolved_dns_records_hint_html: Verkkotunnuksen nimi määräytyy seuraaviin MX-verkkotunnuksiin, jotka ovat viime kädessä vastuussa sähköpostin vastaanottamisesta. MX-verkkotunnuksen estäminen estää kirjautumisen mistä tahansa sähköpostiosoitteesta, joka käyttää samaa MX-verkkotunnusta, vaikka näkyvä verkkotunnuksen nimi olisikin erilainen. Varo estämästä suuria sähköpostin palveluntarjoajia. resolved_through_html: Ratkaistu %{domain} kautta title: Sähköpostiestolista @@ -436,7 +449,7 @@ fi: no_file: Yhtäkään tiedostoa ei ole valittu export_domain_blocks: import: - description_html: Olet tuomassa järjestelmään luetteloa verkkoalue-estoista. Tarkista luettelo huolella – etenkin, ellet ole itse tehnyt listausta. + description_html: Olet tuomassa verkkotunnusten estoluetteloa. Tarkista luettelo huolella – etenkin, jos et ole laatinut sitä itse. existing_relationships_warning: Olemassa olevat seuraussuhteet private_comment_description_html: 'Tuodun estolistan alkuperän selvillä pitämiseksi, lisätään tietojen yhteyteen seuraava yksityinen kommentti: %{comment}' private_comment_template: Tuotu lähteestä %{source}, pvm %{date} @@ -446,13 +459,13 @@ fi: title: Tuo luettelo verkkoalue-estoista no_file: Yhtäkään tiedostoa ei ole valittu follow_recommendations: - description_html: "Suositusten noudattaminen auttaa uusia käyttäjiä löytämään nopeasti mielenkiintoista sisältöä.. Jos käyttäjä ei ole ollut vuorovaikutuksessa tarpeeksi muiden kanssa luodakseen henkilökohtaisia seuraajia, näitä muita tilejä suositellaan sen sijaan. Ne lasketaan uudelleen päivittäin yhdistelmästä tilejä, joilla on korkein viimeaikainen käyttö ja korkein paikallinen seuraajien määrä tietyllä kielellä." + description_html: "Seuraamissuositukset auttavat uusia käyttäjiä löytämään nopeasti kiinnostavaa sisältöä. Kun käyttäjä ei ole ollut tarpeeksi vuorovaikutuksessa muiden kanssa, jotta hänelle olisi muodostunut henkilökohtaisia seuraamissuosituksia, suositellaan niiden sijaan näitä tilejä. Ne lasketaan päivittäin uudelleen yhdistelmästä tilejä, jotka ovat viime aikoina olleet aktiivisimmin sitoutuneita ja joilla on suurimmat paikalliset seuraajamäärät tietyllä kielellä." language: Kielelle status: Tila - suppress: Peitä noudata suosituksia - suppressed: Rajoitettu - title: Noudata suosituksia - unsuppress: Palauta seuraa suositus + suppress: Hylkää seuraamissuositus + suppressed: Hylätty + title: Seuraamissuositukset + unsuppress: Palauta seuraamissuositus instances: availability: description_html: @@ -473,10 +486,11 @@ fi: content_policies: comment: Sisäinen huomautus description_html: Voit määrittää sisältökäytännöt, joita sovelletaan kaikkiin tämän verkkotunnuksen ja sen aliverkkotunnuksien tileihin. + limited_federation_mode_description_html: Voit valita sallitaanko federointi tällä verkkotunnuksella. policies: reject_media: Hylkää media reject_reports: Hylkää raportit - silence: Rajoitus + silence: Rajoita suspend: Jäädytä policy: Käytännöt reason: Julkinen syy @@ -489,7 +503,7 @@ fi: instance_languages_dimension: Suosituimmat kielet instance_media_attachments_measure: tallennetut median liitteet instance_reports_measure: niitä koskevat raportit - instance_statuses_measure: tallennetut viestit + instance_statuses_measure: tallennetut julkaisut delivery: all: Kaikki clear: Tyhjennä toimitusvirheet @@ -508,12 +522,12 @@ fi: moderation: all: Kaikki limited: Rajoitettu - title: Moderointi + title: Valvonta private_comment: Yksityinen kommentti public_comment: Julkinen kommentti purge: Tyhjennä - purge_description_html: Jos uskot tämän verkkotunnuksen olevan offline-tilassa, voit poistaa kaikki tilitietueet ja niihin liittyvät tiedot sinun tallennustilasta. Tämä voi kestää jonkin aikaa. - title: Tiedossa olevat instanssit + purge_description_html: Jos uskot, että tämä verkkotunnus on offline-tilassa tarkoituksella, voit poistaa kaikki verkkotunnuksen tilitietueet ja niihin liittyvät tiedot tallennustilastasi. Tämä voi kestää jonkin aikaa. + title: Federointi total_blocked_by_us: Estetty meidän toimesta total_followed_by_them: Heidän seuraama total_followed_by_us: Meidän seuraama @@ -548,11 +562,11 @@ fi: relays: add_new: Lisää uusi välittäjä delete: Poista - description_html: "federaatiovälittäjä on välityspalvelin, joka siirtää siihen liittyneiden palvelimien välillä suuria julksia viestimääriä. Tämä voi auttaa pieniä ja keskikokoisia palvelimia löytämään fediversen sisältöä, joka muutoin vaatisi paikallisia käyttäjiä seuraamaan etäpalvelimien käyttäjiä manuaalisesti." + description_html: "Federointivälittäjä on välityspalvelin, joka siirtää suuria määriä julkisia julkaisuja siihen liittyneiden palvelinten välillä. Se voi auttaa pieniä ja keskisuuria palvelimia löytämään fediversumin sisältöä, mikä muutoin vaatisi paikallisia käyttäjiä seuraamaan etäpalvalinten käyttäjiä manuaalisesti." disable: Poista käytöstä - disabled: Ei käytössä + disabled: Poissa käytöstä enable: Ota käyttöön - enable_hint: Kun tämä on otettu käyttöön, palvelimesi liittyy välittäjään ja vastaanottaa jatkossa kaikki sen jakelemat julkiset julkaisut sekä välittää omat julkiset julkaisunsa sille. + enable_hint: Kun tämä on otettu käyttöön, palvelimesi tilaa välittäjältä kaikki sen välittämät julkiset julkaisut ja alkaa lähettää omansa sille. enabled: Käytössä inbox_url: Välittäjän URL pending: Odotetaan välittäjän hyväksyntää @@ -570,29 +584,31 @@ fi: one: "%{count} ilmoitus" other: "%{count} ilmoitusta" action_log: Tarkastusloki - action_taken_by: Toimenpiteen tekijä + action_taken_by: Toimen tehnyt actions: - delete_description_html: Ilmoitetut viestit poistetaan ja kirjataan varoitus, joka auttaa sinua saman tilin tulevista rikkomuksista. - mark_as_sensitive_description_html: Ilmoitettujen viestien media merkitään arkaluonteisiksi ja varoitus tallennetaan, jotta voit kärjistää saman tilin tulevia rikkomuksia. - other_description_html: Katso lisää vaihtoehtoja tilin käytöksen hallitsemiseksi ja ilmoitetun tilin viestinnän mukauttamiseksi. - resolve_description_html: Ilmoitettua tiliä vastaan ei ryhdytä toimenpiteisiin, varoitusta ei kirjata ja raportti suljetaan. - silence_description_html: Tili näkyy vain niille, jotka jo seuraavat sitä tai estävät sen manuaalisesti, mikä rajoittaa merkittävästi sen kattavuutta. Se voidaan aina palauttaa. Sulkee kaikki raportit tätä tiliä vastaan. - suspend_description_html: Tili ja kaikki sen sisältö eivät ole käytettävissä ja vuorovaikutus sen kanssa on mahdotonta, sekä lopulta poistetaan. Palautettava 30 päivän kuluessa. Sulkee kaikki raportit tätä tiliä vastaan. - actions_description_html: Päätä, mihin toimiin ryhdyt tämän ilmoituksen ratkaisemiseksi. Jos ryhdyt rangaistustoimeen ilmoitettua tiliä vastaan, heille lähetetään sähköposti-ilmoitus, paitsi jos Roskaposti luokka on valittuna. + delete_description_html: Raportoidut julkaisut poistetaan ja kirjataan varoitus, joka auttaa suhtautumaan vakavammin saman tilin tuleviin rikkomuksiin. + mark_as_sensitive_description_html: Raportoitujen julkaisujen media merkitään arkaluonteiseksi ja kirjataan varoitus, joka auttaa suhtautumaan vakavammin saman tilin tuleviin rikkomuksiin. + other_description_html: Katso lisää vaihtoehtoja tilin käytöksen hallitsemiseksi ja raportoidulle tilille kohdistuvan viestinnän mukauttamiseksi. + resolve_description_html: Ilmoitettua tiliä kohtaan ei ryhdytä toimiin, varoitusta ei kirjata ja raportti suljetaan. + silence_description_html: Tili näkyy vain niille, jotka jo seuraavat sitä tai etsivät sen manuaalisesti, mikä rajoittaa merkittävästi sen tavoitettavuutta. Voidaan perua milloin vain. Sulkee kaikki tilin vastaiset raportit. + suspend_description_html: Tili ja mikään sen sisältö eivät ole käytettävissä, ja lopulta ne poistetaan, ja vuorovaikutus tilin kanssa on mahdotonta. Peruttavissa 30 päivän ajan. Sulkee kaikki tämän tilin vastaiset raportit. + actions_description_html: Päätä, mihin toimiin ryhdyt tämän raportin ratkaisemiseksi. Jos ryhdyt rangaistustoimeen ilmoitettua tiliä kohtaan, hänelle lähetetään sähköposti-ilmoitus, paitsi jos Roskaposti-luokka on valittuna. actions_description_remote_html: Päätä, mihin toimiin ryhdyt tämän raportin ratkaisemiseksi. Tämä vaikuttaa vain siihen, miten palvelimesi kommunikoi tämän etätilin kanssa ja käsittelee sen sisältöä. add_to_report: Lisää raporttiin are_you_sure: Oletko varma? assign_to_self: Ota tehtäväksi assigned: Määritetty valvoja by_target_domain: Ilmoitetun tilin verkkotunnus - category: Kategoria - category_description_html: Syy, miksi tämä tili ja/tai sisältö ilmoitettiin, mainitaan yhteydenotossa ilmoitettuun tiliin + cancel: Peruuta + category: Luokka + category_description_html: Syy siihen, miksi tämä tili ja/tai sisältö raportoitiin, mainitaan ilmoitetun tilin kanssa viestiessä comment: none: Ei mitään comment_description_html: 'Antaakseen lisätietoja %{name} kirjoitti:' - confirm_action: Vahvista moderointitoiminto käyttäjää @%{acct} kohtaan + confirm: Vahvista + confirm_action: Vahvista valvontatoimi käyttäjää @%{acct} kohtaan created_at: Raportoitu - delete_and_resolve: Poista viestejä + delete_and_resolve: Poista julkaisut forwarded: Välitetty forwarded_to: Välitetty %{domain} mark_as_resolved: Merkitse ratkaistuksi @@ -622,22 +638,22 @@ fi: statuses_description_html: Loukkaava sisältö mainitaan ilmoitetun tilin yhteydessä summary: action_preambles: - delete_html: 'Olet aikeissa poistaa joitain käyttäjän @%{acct} viestejä. Tästä seuraa:' - mark_as_sensitive_html: 'Olet aikeissa merkitä joitain käyttäjän @%{acct} viestejä arkaluonteisiksi. Tästä seuraa:' + delete_html: 'Olet aikeissa poistaa käyttäjän @%{acct} julkaisuja. Tästä seuraa:' + mark_as_sensitive_html: 'Olet aikeissa merkitä käyttäjän @%{acct} julkaisuja arkaluonteisiksi. Tästä seuraa:' silence_html: 'Olet aikeissa rajoittaa käyttäjän @%{acct} tiliä. Tästä seuraa:' - suspend_html: 'Olet aikeissa rajoittaa käyttäjän @%{acct} tiliä. Tästä seuraa:' + suspend_html: 'Olet aikeissa jäädyttää käyttäjän @%{acct} tilin. Tästä seuraa:' actions: - delete_html: Loukkaavat viestit poistetaan - mark_as_sensitive_html: Loukkaavien viestien media merkitään arkaluonteiseksi - silence_html: Vakavasti rajoittaa käyttäjän @%{acct} tavoitettavuutta tekemällä profiilista ja sen sisällöstä näkyviä vain jo häntä seuraaville tai niille, jotka etsivät profiilia manuaalisesti - suspend_html: Rajoita @%{acct}, jolloin heidän profiilinsa ja sisällönsä ei ole käytettävissä ja on mahdotonta olla vuorovaikutuksessa + delete_html: Poista loukkaavat julkaisut + mark_as_sensitive_html: Merkitse loukkaavien julkaisujen media arkaluonteiseksi + silence_html: Rajoita merkittävästi käyttäjän @%{acct} tavoitettavuutta tekemällä profiilista ja sen sisällöstä näkyviä vain niille, jotka jo seuraavat tiliä tai etsivät sen manuaalisesti + suspend_html: Jäädytä @%{acct}, jolloin hänen profiilinsa ja sisältönsä ei ole käytettävissä ja hänen kanssaan on mahdotonta olla vuorovaikutuksessa close_report: 'Merkitse raportti #%{id} selvitetyksi' close_reports_html: Merkitse kaikki käyttäjään @%{acct} kohdistuvat raportit ratkaistuiksi - delete_data_html: Poista @%{acct}profiili ja sisältö 30 päivän kuluttua, ellei jäädytystä tällä välin peruuteta + delete_data_html: Poista käyttäjän @%{acct} profiili ja sen sisältö 30 päivän kuluttua, ellei jäädytystä sillä välin kumota preview_preamble_html: "@%{acct} saa varoituksen, jonka sisältö on seuraava:" record_strike_html: Tallenna varoitus @%{acct} vastaan, joka auttaa sinua selvittämään tulevia rikkomuksia tältä tililtä send_email_html: Lähetä käyttäjälle @%{acct} varoitus sähköpostitse - warning_placeholder: Valinnaiset lisäperustelut moderointitoimenpiteelle. + warning_placeholder: Valinnaiset lisäperustelut valvontatoimelle. target_origin: Raportoidun tilin alkuperä title: Raportit unassign: Määrittämätön @@ -654,10 +670,10 @@ fi: administration: Ylläpito devops: DevOps invites: Kutsut - moderation: Moderointi + moderation: Valvonta special: Erikois delete: Poista - description_html: Käyttäjän roolit, voit muokata toimintoja ja alueita mitä sinun Mastodon käyttäjät voivat käyttää. + description_html: "Käyttäjärooleilla voit muokata, mihin toimintoihin ja alueisiin käyttäjäsi pääsevät käsiksi." edit: Muokkaa "%{name}" roolia everyone: Oletus käyttöoikeudet everyone_full_description_html: Tämä on perusrooli joka vaikuttaa kaikkiin käyttäjiin, jopa ilman määrättyä roolia. Kaikki muut roolit perivät sen käyttöoikeudet. @@ -671,34 +687,34 @@ fi: delete_user_data_description: Salli käyttäjien poistaa muiden käyttäjien tiedot viipymättä invite_users: Kutsu käyttäjiä invite_users_description: Sallii käyttäjien kutsua uusia ihmisiä palvelimelle - manage_announcements: Hallitse Ilmoituksia - manage_announcements_description: Salli käyttäjien hallita ilmoituksia palvelimella + manage_announcements: Hallitse tiedotteita + manage_announcements_description: Sallii käyttäjien hallita tiedotteita palvelimella manage_appeals: Hallitse valituksia - manage_appeals_description: Antaa käyttäjien tarkastella valvontatoimia koskevia valituksia - manage_blocks: Hallitse lohkoja - manage_blocks_description: Sallii käyttäjien estää sähköpostipalvelujen ja IP-osoitteiden käytön - manage_custom_emojis: Hallita mukautettuja hymiöitä - manage_custom_emojis_description: Salli käyttäjien hallita mukautettuja hymiöitä palvelimella - manage_federation: Hallita liitoksia - manage_federation_description: Sallii käyttäjien estää tai sallia liitoksen muiden verkkotunnusten kanssa ja hallita toimitusta - manage_invites: Hallita kutsuja + manage_appeals_description: Sallii käyttäjien tarkistaa valvontatoimia koskevia valituksia + manage_blocks: Hallitse estoja + manage_blocks_description: Sallii käyttäjien estää sähköpostipalveluntarjoajia ja IP-osoitteita + manage_custom_emojis: Hallitse mukautettuja emojeita + manage_custom_emojis_description: Sallii käyttäjien hallita mukautettuja emojeita palvelimella + manage_federation: Hallitse federointia + manage_federation_description: Sallii käyttäjien estää tai sallia federointi muiden verkkotunnusten kanssa ja hallita toimitusta + manage_invites: Hallitse kutsuja manage_invites_description: Sallii käyttäjien selata ja poistaa kutsulinkkejä käytöstä - manage_reports: Hallita raportteja - manage_reports_description: Sallii käyttäjien tarkastella raportteja ja suorittaa valvontatoimia niitä vastaan - manage_roles: Hallita rooleja + manage_reports: Hallitse raportteja + manage_reports_description: Sallii käyttäjien tarkistaa raportteja ja suorittaa valvontatoimia niitä vastaan + manage_roles: Hallitse rooleja manage_roles_description: Sallii käyttäjien hallita ja määrittää rooleja heidän alapuolellaan - manage_rules: Hallita sääntöjä - manage_rules_description: Sallii käyttäjien vaihtaa palvelinsääntöjä - manage_settings: Hallita asetuksia - manage_settings_description: Salli käyttäjien muuttaa sivuston asetuksia - manage_taxonomies: Hallita luokittelua + manage_rules: Hallitse sääntöjä + manage_rules_description: Sallii käyttäjien muuttaa palvelimen sääntöjä + manage_settings: Hallitse asetuksia + manage_settings_description: Sallii käyttäjien muuttaa sivuston asetuksia + manage_taxonomies: Hallitse luokittelua manage_taxonomies_description: Sallii käyttäjien tarkistaa nousussa olevan sisällön ja päivittää aihetunnisteiden asetuksia - manage_user_access: Hallita käyttäjän oikeuksia - manage_user_access_description: Sallii käyttäjien poistaa käytöstä muiden käyttäjien kaksivaiheisen todennuksen, muuttaa heidän sähköpostiosoitettaan ja nollata heidän salasanansa - manage_users: Hallita käyttäjiä - manage_users_description: Sallii käyttäjien tarkastella muiden käyttäjien tietoja ja suorittaa valvontatoimia heitä vastaan - manage_webhooks: Hallita Webhookit - manage_webhooks_description: Sallii käyttäjien luoda webhookit hallinnollisiin tapahtumiin + manage_user_access: Hallitse käyttäjäoikeuksia + manage_user_access_description: Sallii käyttäjien poistaa muiden käyttäjien kaksivaiheinen todennus käytöstä, vaihtaa heidän sähköpostiosoitteensa ja nollata heidän salasanansa + manage_users: Hallitse käyttäjiä + manage_users_description: Sallii käyttäjien tarkastella muiden käyttäjien tietoja ja suorittaa valvontatoimia heitä kohtaan + manage_webhooks: Hallitse webhookeja + manage_webhooks_description: Sallii käyttäjien luoda webhookeja hallinnollisiin tapahtumiin view_audit_log: Katsoa valvontalokia view_audit_log_description: Sallii käyttäjien nähdä palvelimen hallinnollisten toimien historian view_dashboard: Näytä koontinäyttö @@ -709,22 +725,25 @@ fi: rules: add_new: Lisää sääntö delete: Poista - description_html: Vaikka useimmat väittävät, että ovat lukenut ja hyväksyneet käyttöehdot niin yleensä ihmiset eivät lue niitä läpi ennen kuin ongelma syntyy. Tee helpoksi nähdä palvelimen säännöt yhdellä silmäyksellä tarjoamalla ne tiiviissä luettelossa. Yritä pitää säännöt lyhyinä ja yksinkertaisina, mutta yritä olla jakamatta niitä moniin erillisiin kohteisiin. + description_html: Vaikka useimmat väittävät, että ovat lukeneet ja hyväksyneet käyttöehdot, niin yleensä ihmiset eivät lue niitä läpi ennen kuin ilmenee ongelma. Helpota palvelimen sääntöjen näkemistä yhdellä silmäyksellä tarjoamalla ne tiiviissä luettelossa. Yritä pitää säännöt lyhyinä ja yksinkertaisina, mutta yritä olla jakamatta niitä useisiin erillisiin kohtiin. edit: Muokkaa sääntöä empty: Palvelimen sääntöjä ei ole vielä määritelty. title: Palvelimen säännöt settings: about: - manage_rules: Hallinnoi palvelimen sääntöjä + manage_rules: Hallitse palvelimen sääntöjä preamble: Anna perusteellista tietoa siitä, miten palvelinta käytetään, valvotaan, rahoitetaan. rules_hint: On olemassa erityinen alue sääntöjä, joita käyttäjien odotetaan noudattavan. title: Tietoja appearance: - preamble: Muokkaa Mastodonin web-käyttöliittymää. + preamble: Mukauta Mastodonin verkkokäyttöliittymää. title: Ulkoasu branding: - preamble: Palvelimesi brändäys erottaa sen muista verkon palvelimista. Nämä tiedot voidaan näyttää useissa eri ympäristöissä, kuten Mastodonin käyttöliittymässä, sovelluksissa, linkkien esikatselu muilla sivustoilla ja viestisovelluksien sisällä ja niin edelleen. Tästä syystä on parasta pitää nämä tiedot selkeinä, lyhyinä ja ytimekkäinä. + preamble: Palvelimesi brändäys erottaa sen muista verkon palvelimista. Nämä tiedot voivat näkyä monissa eri ympäristöissä, kuten Mastodonin verkkokäyttöliittymässä, natiivisovelluksissa, linkkien esikatseluissa muilla sivustoilla, viestintäsovelluksissa ja niin edelleen. Siksi nämä tiedot kannattaa pitää selkeinä, lyhyinä ja ytimekkäinä. title: Brändäys + captcha_enabled: + desc_html: Tämä perustuu ulkoisiin skripteihin hCaptchasta, mikä voi olla turvallisuus- ja yksityisyysongelma. Lisäksi tämä voi tehdä rekisteröinnin ihmisille huomattavasti (erityisesti vammaisten) helpommaksi. Harkitse vaihtoehtoisia toimenpiteitä, kuten hyväksymisperusteista tai kutsupohjaista rekisteröintiä. + title: Vaadi uusia käyttäjiä vahvistaamaan tilinsä ratkaisemalla CAPTCHA-vahvistus content_retention: preamble: Määritä, miten käyttäjän luoma sisältö tallennetaan Mastodoniin. title: Sisällön säilyttäminen @@ -732,7 +751,7 @@ fi: desc_html: Vaikuttaa kaikkiin käyttäjiin, jotka eivät ole muuttaneet tätä asetusta itse title: Jätä käyttäjät oletusarvoisesti hakukoneindeksoinnin ulkopuolelle discovery: - follow_recommendations: Noudata suosituksia + follow_recommendations: Seuraamissuositukset preamble: Mielenkiintoisen sisällön esille tuominen auttaa saamaan uusia käyttäjiä, jotka eivät ehkä tunne ketään Mastodonista. Määrittele, kuinka erilaiset etsintäominaisuudet toimivat palvelimellasi. profile_directory: Profiilihakemisto public_timelines: Julkiset aikajanat @@ -752,10 +771,27 @@ fi: approved: Rekisteröinti vaatii hyväksynnän none: Kukaan ei voi rekisteröityä open: Kaikki voivat rekisteröityä + security: + authorized_fetch: Vaadi todennus yhdistetyiltä palvelimilta + authorized_fetch_hint: Todennuksen vaatiminen federoiduilta palvelimilta mahdollistaa sekä käyttäjä- että palvelintason estojen tiukemman valvonnan. Tämä tapahtuu kuitenkin suorituskyvyn kustannuksella, vähentää vastauksiesi tavoittavuutta ja voi aiheuttaa yhteensopivuusongelmia joidenkin federoitujen palvelujen kanssa. Tämä ei myöskään estä omistautuneita toimijoita hakemasta julkisia julkaisujasi ja tilejäsi. + authorized_fetch_overridden_hint: Et voi tällä hetkellä muuttaa tätä asetusta, koska se on ohitettu ympäristömuuttujalla. + federation_authentication: Yhdistettyjen palvelinten todentamisen täytäntöönpano title: Palvelimen asetukset site_uploads: delete: Poista ladattu tiedosto destroyed_msg: Sivuston lataus onnistuneesti poistettu! + software_updates: + critical_update: Kriittinen – päivitä viivyttelemättä + description: On suositeltavaa pitää Mastodon-asennus ajantasaisena ja siten hyödyntää uusimpia korjauksia sekä ominaisuuksia. Lisäksi joskus on ratkaisevan tärkeää päivittää Mastodon ajoissa tietoturvaongelmien välttämiseksi. Näistä syistä Mastodon tarkistaa päivitykset 30 minuutin välein, ja ilmoittaa sinulle sähköposti-ilmoitusasetustesi mukaisesti. + documentation_link: Lue lisää + release_notes: Julkaisutiedot + title: Saatavilla olevat päivitykset + type: Tyyppi + types: + major: Pääversiojulkaisu + minor: Väliversiojulkaisu + patch: Korjausjulkaisu — korjauksia virheisiin sekä yksinkertaisia muutoksia + version: Versio statuses: account: Tekijä application: Sovellus @@ -772,39 +808,66 @@ fi: media: title: Media metadata: Metadata - no_status_selected: Viestejä ei muutettu, koska yhtään ei ole valittuna - open: Avaa viesti - original_status: Alkuperäinen viesti + no_status_selected: Julkaisuja ei muutettu, koska yhtään ei ole valittuna + open: Avaa julkaisu + original_status: Alkuperäinen julkaisu reblogs: Edelleen jako - status_changed: Viesti muutettu + status_changed: Julkaisua muutettu title: Tilin tilat trending: Nousussa visibility: Näkyvyys with_media: Sisältää mediaa strikes: actions: - delete_statuses: "%{name} poisti käyttäjän %{target} viestit" + delete_statuses: "%{name} poisti käyttäjän %{target} julkaisut" disable: "%{name} jäädytti %{target} tilin" - mark_statuses_as_sensitive: "%{name} merkitsi %{target} viestiä arkaluonteiseksi" + mark_statuses_as_sensitive: "%{name} merkitsi käyttäjän %{target} julkaisut arkaluonteisiksi" none: "%{name} lähetti varoituksen henkilölle %{target}" sensitive: "%{name} merkitsi käyttäjän %{target} tilin arkaluonteiseksi" - silence: "%{name} rajoitti käyttäjän %{target} tilin" + silence: "%{name} rajoitti käyttäjän %{target} tiliä" suspend: "%{name} jäädytti käyttäjän %{target} tilin" appeal_approved: Valitti appeal_pending: Valitus vireillä + appeal_rejected: Muutoksenhaku hylättiin system_checks: database_schema_check: message_html: Tietokannan siirto on vireillä. Suorita ne varmistaaksesi, että sovellus toimii odotetulla tavalla + elasticsearch_health_red: + message_html: Elasticsearch-klusteri on vikatilassa (punainen tila); hakuominaisuudet eivät ole käytettävissä + elasticsearch_health_yellow: + message_html: Elasticsearch-klusteri on häiriötilassa (keltainen tila), joten suosittelemme tutkimaan syyn + elasticsearch_index_mismatch: + message_html: Elasticsearch-indeksin sidokset ovat vanhentuneet. Suorita tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Katso käyttöohjeet + message_html: Elasticsearch-klusterissa on useampi kuin yksi solmu, mutta Mastodonia ei ole määritetty käyttämään niitä. + elasticsearch_preset_single_node: + action: Katso käyttöohjeet + message_html: Elasticsearch-klusterissa on vain yksi solmu, ES_PRESET tulisi asettaa arvoon single_node_cluster. + elasticsearch_reset_chewy: + message_html: Elasticsearch-järjestelmäindeksi on vanhentunut asetusmuutoksen vuoksi. Suorita tootctl search deploy --reset-chewy päivittääksesi sen. elasticsearch_running_check: message_html: Ei saatu yhteyttä Elasticsearch. Tarkista, että se on käynnissä tai poista kokotekstihaku käytöstä elasticsearch_version_check: message_html: 'Yhteensopimaton Elasticsearch versio: %{value}' version_comparison: Elasticsearch %{running_version} on käynnissä, kun %{required_version} vaaditaan rules_check: - action: Hallinnoi palvelimen sääntöjä - message_html: Et ole määrittänyt mitään palvelimen sääntöä. + action: Hallitse palvelimen sääntöjä + message_html: Et ole määrittänyt lainkaan palvelimen sääntöjä. sidekiq_process_check: message_html: Ei ole Sidekiq-prosessia käynnissä jonossa %{value}. Tarkista Sidekiq-asetukset + software_version_critical_check: + action: Näytä saatavilla olevat päivitykset + message_html: Kriittinen Mastodon-päivitys on saatavilla. Tee päivitys mahdollisimman ripeästi. + software_version_patch_check: + action: Näytä saatavilla olevat päivitykset + message_html: Mastodonin virhekorjauspäivitys on saatavilla. + upload_check_privacy_error: + action: Katso täältä lisätietoja + message_html: "Verkkopalvelimesi on määritetty väärin. Käyttäjiesi yksityisyys on vaarassa." + upload_check_privacy_error_object_storage: + action: Katso täältä lisätietoja + message_html: "Objektivarastosi on määritetty virheellisesti, ja käyttäjiesi yksityisyys on vaarassa." tags: review: Tarkista tila updated_msg: Aihetunnisteen asetukset päivitetty onnistuneesti @@ -827,6 +890,7 @@ fi: other: Jakanut %{count} henkilöä viimeisen viikon aikana title: Suositut linkit usage_comparison: Jaettu %{today} kertaa tänään verrattuna eilen %{yesterday} + not_allowed_to_trend: Ei saa trendata only_allowed: Vain sallittu pending_review: Odottaa tarkistusta preview_card_providers: @@ -836,17 +900,17 @@ fi: title: Julkaisijat rejected: Hylätty statuses: - allow: Salli viesti + allow: Salli julkaisu allow_account: Salli tekijä - description_html: Nämä ovat viestejä, jotka palvelimesi tietää tällä hetkellä jaetuksi ja suosituksi. Tämä voi auttaa uusia ja palaavia ihmisiä löytämään lisää ihmisiä, joita seurata seurata. Julkaisuja ei näytetä julkisesti ennen kuin hyväksyt tekijän ja kirjoittaja sallii tilinsä ehdottamisen muille. Voit myös sallia tai hylätä yksittäiset viestit. - disallow: Estä viesti + description_html: Nämä ovat julkaisuja, joita palvelimesi tietää jaettavan ja lisättävän suosikkeihin paljon tällä hetkellä. Listaus voi auttaa uusia ja palaavia käyttäjiäsi löytämään lisää seurattavia. Julkaisut eivät näy julkisesti ennen kuin hyväksyt niiden julkaisijan ja julkaisija sallii tilinsä ehdottamisen. Voit myös sallia tai hylätä yksittäisiä julkaisuja. + disallow: Kiellä julkaisu disallow_account: Estä tekijä - no_status_selected: Suosittuja viestejä ei muutettu, koska yhtään ei valittu + no_status_selected: Suosittuja julkaisuja ei muutettu, koska yhtään ei ole valittuna not_discoverable: Tekijä ei ole ilmoittanut olevansa löydettävissä shared_by: - one: Jaettu tai suosikki kerran - other: Jaettu ja lisätty suosikkeihin %{friendly_count} kertaa - title: Suositut viestit + one: Jaettu tai lisätty suosikkeihin kerran + other: Jaettu tai merkitty suosikiksi %{friendly_count} kertaa + title: Suositut julkaisut tags: current_score: Nykyinen tulos %{score} dashboard: @@ -876,16 +940,16 @@ fi: add_new: Lisää uusi delete: Poista edit_preset: Muokkaa varoituksen esiasetusta - empty: Et ole vielä määrittänyt yhtään varoitusesiasetusta. - title: Hallinnoi varoitusesiasetuksia + empty: Et ole vielä määrittänyt yhtäkään varoitusten esiasetusta. + title: Hallitse varoitusten esiasetuksia webhooks: add_new: Lisää päätepiste delete: Poista - description_html: A webhook mahdollistaa Mastodonin työntää reaaliaikaisia ilmoituksia valituista tapahtumista omaan sovellukseesi, joten sovelluksesi voi laukaista automaattisesti reaktioita. + description_html: "Webhookin avulla Mastodon voi puskea sovellukseesi reaaliaikaisia ilmoituksia valituista tapahtumista, jotta sovelluksesi voi laukaista reaktioita automaattisesti." disable: Poista käytöstä - disabled: Ei käytössä + disabled: Pois käytöstä edit: Muokkaa päätepistettä - empty: Sinulla ei ole vielä määritetty webhook-päätepisteitä. + empty: Et ole vielä määrittänyt webhook-päätepisteitä. enable: Ota käyttöön enabled: Aktiivinen enabled_events: @@ -901,29 +965,35 @@ fi: admin_mailer: new_appeal: actions: - delete_statuses: poistaa heidän viestit + delete_statuses: poistaa hänen julkaisunsa disable: jäädyttää heidän tilinsä - mark_statuses_as_sensitive: merkitä heidän viestinsä arkaluonteisiksi + mark_statuses_as_sensitive: merkitä hänen julkaisunsa arkaluonteisiksi none: varoitus sensitive: merkitä heidän tilinsä arkaluonteiseksi - silence: rajoittaa heidän tilinsä - suspend: jäädyttää heidän tilinsä - body: "%{target} on valittanut valvojan päätöksestä %{action_taken_by} aika %{date}, joka oli %{type}. He kirjoittivat:" - next_steps: Voit hyväksyä vetoomuksen ja kumota päätöksen tai jättää sen huomiotta. - subject: "%{username} valittaa valvojan päätöksestä, joka koskee instanssia %{instance}" + silence: rajoittaa hänen tiliään + suspend: jäädyttää hänen tilinsä + body: "%{target} valittaa valvojan %{action_taken_by} päätöksestä %{date}, joka oli %{type}. Hän kirjoitti:" + next_steps: Voit hyväksyä valituksen, jolloin valvontapäätös kumoutuu, tai sivuuttaa sen. + subject: "%{username} valittaa valvontapäätöksestä, joka koskee instanssia %{instance}" + new_critical_software_updates: + body: Mastodonin uusia kriittisen tärkeitä versioita on julkaistu, joten saatat haluta päivittää niin pian kuin mahdollista! + subject: Kriittisiä Mastodon-päivityksiä on saatavilla instanssille %{instance}! new_pending_account: body: Uuden tilin tiedot ovat alla. Voit hyväksyä tai hylätä tämän hakemuksen. subject: Uusi tili tarkastettavana instanssissa %{instance} (%{username}) new_report: body: "%{reporter} on raportoinut kohteen %{target}" - body_remote: Joku osoitteesta %{domain} on raportoinut kohteen %{target} + body_remote: Joku palvelimelta %{domain} raportoi käyttäjän %{target} subject: Uusi raportti instanssista %{instance} (nro %{id}) + new_software_updates: + body: Uusia Mastodon-versioita on julkaistu, joten saatat haluta päivittää! + subject: Uusia Mastodon-versioita ovat saatavilla instanssille %{instance}! new_trends: body: 'Seuraavat kohteet on tarkistettava ennen kuin ne voidaan näyttää julkisesti:' new_trending_links: title: Suositut linkit new_trending_statuses: - title: Suositut viestit + title: Suositut julkaisut new_trending_tags: no_approved_tags: Tällä hetkellä ei ole hyväksyttyjä trendikkäitä aihetunnisteita. requirements: 'Mikä tahansa näistä ehdokkaista voisi ylittää #%{rank} hyväksytyn trendikkään aihetunnisteen, joka on tällä hetkellä #%{lowest_tag_name} arvosanalla %{lowest_tag_score}.' @@ -934,101 +1004,106 @@ fi: created_msg: Uusi alias luotiin onnistuneesti. Voit nyt aloittaa siirron vanhasta tilistä. deleted_msg: Alias poistettiin onnistuneesti. Siirtyminen tuolta tililtä tähän ei ole enää mahdollista. empty: Sinulla ei ole aliaksia. - hint_html: Jos haluat siirtyä toisesta tilistä tähän tiliin, voit luoda aliasin, joka on pakollinen, ennen kuin voit siirtää seuraajia vanhasta tilistä tähän tiliin. Tämä toiminto on itsessään vaaraton ja palautuva. Tilin siirtyminen aloitetaan vanhalta tililtä. + hint_html: Jos haluat muuttaa toiselta tililtä tälle tilille, voit luoda tässä aliaksen, mitä vaaditaan ennen kuin voit edetä siirtämään seuraajat vanhalta tililtä tälle tilille. Tänä toiminto on itsessään vaaraton ja kumottavissa. Tilin muuttaminen aloitetaan vanhalta tililtä. remove: Poista aliaksen linkitys appearance: advanced_web_interface: Edistynyt selainkäyttöliittymä - advanced_web_interface_hint: 'Jos haluat käyttää koko näytön leveyttä, edistyneen web-käyttöliittymän avulla voit määrittää useita eri sarakkeita näyttämään niin paljon tietoa samanaikaisesti kuin haluat: Koti, ilmoitukset, yhdistetty aikajana, mikä tahansa määrä luetteloita ja aihetunnisteita.' + advanced_web_interface_hint: 'Jos haluat hyödyntää näytön koko leveyttä, edistyneen webkäyttöliittymän avulla voit määrittää useita erilaisia sarakkeita, niin näet kerralla niin paljon tietoa kuin haluat: kotisyöte, ilmoitukset, yleinen aikajana, mikä tahansa määrä listoja ja aihetunnisteita.' animations_and_accessibility: Animaatiot ja saavutettavuus confirmation_dialogs: Vahvistusvalinnat - discovery: Löydöt + discovery: Löytäminen localization: body: Mastodonin ovat kääntäneet vapaaehtoiset. guide_link: https://crowdin.com/project/mastodon guide_link_text: Kaikki voivat osallistua. - sensitive_content: Arkaluontoista sisältöä - toot_layout: Viestin asettelu + sensitive_content: Arkaluonteinen sisältö application_mailer: notification_preferences: Muuta sähköpostiasetuksia salutation: "%{name}," settings: 'Muuta sähköpostiasetuksia: %{link}' + unsubscribe: Lopeta tilaus view: 'Näytä:' view_profile: Näytä profiili view_status: Näytä tila applications: created: Sovelluksen luonti onnistui destroyed: Sovelluksen poisto onnistui + logout: Kirjaudu ulos regenerate_token: Luo pääsytunnus uudelleen token_regenerated: Pääsytunnuksen uudelleenluonti onnistui warning: Säilytä tietoa hyvin. Älä milloinkaan jaa sitä muille! your_token: Pääsytunnus auth: apply_for_account: Pyydä tiliä - change_password: Salasana + captcha_confirmation: + help_html: Jos kohtaat ongelmia CAPTCHAn ratkaisemisessa, voit pyytää meiltä apua osoitteella %{email}. + hint_html: Vielä yksi juttu! Meidän on vahvistettava, että olet ihminen (tämän avulla pidämme roskapostin poissa!). Ratkaise alla oleva CAPTCHA-vahvistus ja paina "Jatka". + title: Turvatarkastus confirmations: wrong_email_hint: Jos sähköpostiosoite ei ole oikein, voit muuttaa sen tilin asetuksista. delete_account: Poista tili - delete_account_html: Jos haluat poistaa tilisi, paina tästä. Poisto on vahvistettava. + delete_account_html: Jos haluat poistaa tilisi, voit edetä tästä. Sinua pyydetään vahvistamaan poisto. description: prefix_invited_by_user: "@%{name} kutsuu sinut liittymään tälle Mastodonin palvelimelle!" prefix_sign_up: Liity Mastodoniin tänään! suffix: Tilillä voit seurata ihmisiä, julkaista päivityksiä ja lähetellä viestejä muille käyttäjille miltä palvelimelta tahansa ja paljon muuta! - didnt_get_confirmation: Etkö saanut vahvistusohjeita? + didnt_get_confirmation: Etkö saanut vahvistuslinkkiä? dont_have_your_security_key: Eikö sinulla ole suojausavainta? forgot_password: Unohditko salasanasi? - invalid_reset_password_token: Salasananpalautustunnus on virheellinen tai vanhentunut. Pyydä uusi. - link_to_otp: Syötä puhelimesi kaksivaiheinen koodi tai palautuskoodi + invalid_reset_password_token: Salasanan palautustunnus on virheellinen tai vanhentunut. Pyydä uusi. + link_to_otp: Syötä puhelimesi kaksivaiheisen todennuksen koodi tai palautuskoodi link_to_webauth: Käytä suojausavaintasi log_in_with: Kirjaudu käyttäen login: Kirjaudu sisään logout: Kirjaudu ulos migrate_account: Muuta toiseen tiliin - migrate_account_html: Jos haluat ohjata tämän tilin toiseen tiliin, voit asettaa toisen tilin tästä. + migrate_account_html: Jos haluat ohjata tämän tilin toiseen, voit asettaa toisen tilin tästä. or_log_in_with: Tai käytä kirjautumiseen privacy_policy_agreement_html: Olen lukenut ja hyväksynyt tietosuojakäytännön + progress: + confirm: Vahvista sähköpostiosoite + details: Omat tietosi + review: Arviomme + rules: Hyväksy säännöt providers: cas: CAS saml: SAML register: Rekisteröidy registration_closed: "%{instance} ei hyväksy uusia jäseniä" - resend_confirmation: Lähetä vahvistusohjeet uudestaan + resend_confirmation: Lähetä vahvistuslinkki uudelleen reset_password: Palauta salasana rules: - preamble: "%{domain} valvojat määrittävät ja valvovat sääntöjä." + accept: Hyväksy + back: Takaisin + invited_by: 'Seuraavalta käyttäjältä vastaanottamasi kutsun ansiosta voit liittyä palvelimelle %{domain}:' + preamble: Palvelimen %{domain} valvojat määrittävät ja valvovat sääntöjä. + preamble_invited: Ennen kuin jatkat, ota huomioon palvelimen %{domain} valvojien asettamat perussäännöt. title: Joitakin perussääntöjä. + title_invited: Sinut on kutsuttu. security: Tunnukset set_new_password: Aseta uusi salasana setup: - email_below_hint_html: Jos alla oleva sähköpostiosoite on virheellinen, voit muuttaa sitä täällä ja tilata uuden vahvistussähköpostiviestin. - email_settings_hint_html: Vahvistussähköposti lähetettiin osoitteeseen %{email}. Jos sähköpostiosoite ei ole oikea, voit muuttaa sitä tiliasetuksissa. - title: Asetukset + email_below_hint_html: Tarkista roskapostikansiosi tai pyydä uusi viesti. Voit korjata sähköpostiosoitteesi, jos se oli väärin. + email_settings_hint_html: Napsauta lähettämäämme linkkiä vahvistaaksesi osoitteen %{email}. Odotamme täällä. + link_not_received: Etkö saanut linkkiä? + new_confirmation_instructions_sent: Saat uuden vahvistuslinkin sisältävän sähköpostiviestin muutamassa minuutissa! + title: Tarkista sähköpostilaatikkosi sign_in: - preamble_html: Kirjaudu sisään %{domain}-tunnuksillasi. Jos tilisi sijaitsee eri palvelimella, et voi sisäänkirjautua täällä. - title: Kirjaudu palveluun %{domain} + preamble_html: Kirjaudu %{domain}-tunnuksellasi. Jos tilisi sijaitsee eri palvelimella, et voi kirjautua täällä. + title: Kirjaudu palvelimelle %{domain} sign_up: + manual_review: Palvelimen %{domain} valvojat tarkistavat rekisteröitymiset käsin. Helpottaaksesi rekisteröitymisesi käsittelyä kerro hieman itsestäsi ja miksi haluat luoda käyttäjätilin palvelimelle %{domain}. preamble: Kun sinulla on tili tällä Mastodon-palvelimella, voit seurata kaikkia muita verkossa olevia henkilöitä riippumatta siitä, missä heidän tilinsä on. title: Otetaan sinulle käyttöön %{domain}. status: account_status: Tilin tila confirming: Odotetaan sähköpostivahvistuksen valmistumista. - functional: Tilisi on täysin toimiva. - pending: Hakemuksesi odottaa henkilökuntamme tarkastusta. Tämä voi kestää jonkin aikaa. Saat sähköpostiviestin, jos hakemuksesi on hyväksytty. - redirecting_to: Tilisi ei ole aktiivinen, koska se ohjaa tällä hetkellä kohteeseen %{acct}. + functional: Tilisi on täysin toiminnassa. + pending: Hakemuksesi odottaa henkilökuntamme tarkastusta. Tämä voi kestää jonkin aikaa. Saat sähköpostiviestin, jos hakemuksesi hyväksytään. + redirecting_to: Tilisi ei ole aktiivinen, koska se ohjaa tällä hetkellä tilille %{acct}. view_strikes: Näytä tiliäsi koskevia aiempia varoituksia too_fast: Lomake lähetettiin liian nopeasti, yritä uudelleen. use_security_key: Käytä suojausavainta - authorize_follow: - already_following: Sinä seuraat jo tätä tiliä - already_requested: Olet jo lähettänyt seurantapyynnön tälle tilille - error: Valitettavasti etätilin haussa tapahtui virhe - follow: Seuraa - follow_request: 'Olet lähettänyt seuraamispyynnön käyttäjälle:' - following: 'Onnistui! Seuraat käyttäjää:' - post_follow: - close: Tai voit sulkea tämän ikkunan. - return: Palaa käyttäjän profiiliin - web: Siirry verkkosivulle - title: Seuraa käyttäjää %{acct} challenge: confirm: Jatka hint_html: "Vihje: Emme pyydä sinulta salasanaa uudelleen seuraavan tunnin aikana." @@ -1036,7 +1111,7 @@ fi: prompt: Vahvista salasanasi jatkaaksesi crypto: errors: - invalid_key: ei ole kelvollinen Ed25519- tai Curve25519 -avain + invalid_key: ei ole kelvollinen Ed25519- tai Curve25519-avain invalid_signature: ei ole kelvollinen Ed25519-allekirjoitus date: formats: @@ -1044,16 +1119,16 @@ fi: with_month_name: "%B %d, %Y" datetime: distance_in_words: - about_x_hours: "%{count} h" + about_x_hours: "%{count} t" about_x_months: "%{count} kk" about_x_years: "%{count} v" almost_x_years: "%{count} v" half_a_minute: Nyt - less_than_x_minutes: "%{count} m" + less_than_x_minutes: "%{count} min" less_than_x_seconds: Nyt over_x_years: "%{count} v" x_days: "%{count} pv" - x_minutes: "%{count} m" + x_minutes: "%{count} min" x_months: "%{count} kk" x_seconds: "%{count} s" deletes: @@ -1063,9 +1138,9 @@ fi: proceed: Poista tili success_msg: Tilin poisto onnistui warning: - before: 'Ennen kuin jatkat, lue nämä huomautukset huolellisesti:' + before: 'Ennen kuin etenet, lue nämä huomautukset huolellisesti:' caches: Muiden palvelimien välimuistiin tallentamaa sisältöä voi vielä löytyä - data_removal: Viestit ja muut tiedot poistetaan pysyvästi + data_removal: Julkaisusi ja muut tietosi poistetaan pysyvästi email_change_html: Voit muuttaa sähköpostiosoitettasi poistamatta tiliäsi email_contact_html: Jos ei saavu perille, voit pyytää apua sähköpostilla %{email} email_reconfirmation_html: Jos et saa vahvistuksen sähköpostia, niin voit pyytää sitä uudelleen @@ -1075,7 +1150,7 @@ fi: username_unavailable: Käyttäjänimesi ei tule saataville enää uudestaan disputes: strikes: - action_taken: Toteutetut toimet + action_taken: Tehty toimi appeal: Vetoomus appeal_approved: Tähän valitukseen on haettu muutosta, eikä se ole enää voimassa appeal_rejected: Valitus on hylätty @@ -1089,22 +1164,26 @@ fi: description_html: Nämä ovat tiliäsi koskevia toimia ja varoituksia, jotka instanssin %{instance} henkilökunta on lähettänyt sinulle. recipient: Osoitettu reject_appeal: Hylkää valitus - status: 'Viesti #%{id}' - status_removed: Viesti on jo poistettu järjestelmästä + status: 'Julkaisu #%{id}' + status_removed: Julkaisu on jo poistettu järjestelmästä title: "%{action} alkaen %{date}" title_actions: - delete_statuses: Viestin poisto + delete_statuses: Julkaisun poisto disable: Tilin jäädyttäminen - mark_statuses_as_sensitive: Viestien merkitseminen arkaluonteisiksi + mark_statuses_as_sensitive: Julkaisujen merkitseminen arkaluonteisiksi none: Varoitus sensitive: Tilin merkitseminen arkaluonteiseksi silence: Tilin rajoittaminen - suspend: Tilin jäädyttäminen + suspend: Tilin jäädytys your_appeal_approved: Valituksesi on hyväksytty your_appeal_pending: Olet lähettänyt valituksen your_appeal_rejected: Valituksesi on hylätty domain_validator: invalid_domain: ei ole kelvollinen toimialueen nimi + edit_profile: + basic_information: Perustiedot + hint_html: "Mukauta, mitä ihmiset näkevät julkisessa profiilissasi ja julkaisujesi vieressä. Ihmiset seuraavat sinua takaisin ja ovat kanssasi vuorovaikutuksessa todennäköisemmin, kun sinulla on täytetty profiili ja profiilikuva." + other: Muut errors: '400': Lähettämäsi pyyntö oli virheellinen tai muotoiltu virheellisesti. '403': Sinulla ei ole lupaa nähdä tätä sivua. @@ -1119,7 +1198,7 @@ fi: content: Valitettavasti jokin meni pieleen meidän päässämme. title: Sivu ei ole oikein '503': Sivua ei voitu näyttää palvelimen väliaikaisen vian vuoksi. - noscript_html: Käyttääksesi Mastodon-verkkopalvelua, ota JavaScript käyttöön. Vaihtoehtoisesti voit kokeilla myös jotakin juuri käyttämällesi alustalle kehitettyä Mastodon-sovellusta. + noscript_html: Käyttääksesi Mastodonin verkkosovellusta, ota JavaScript käyttöön. Vaihtoehtoisesti voit kokeilla käyttämällesi alustalle kehitettyjä Mastodonin natiivisovelluksia. existing_username_validator: not_found: paikallista käyttäjää ei löydy kyseisellä käyttäjänimellä not_found_multiple: "%{usernames} ei löytynyt" @@ -1127,37 +1206,37 @@ fi: archive_takeout: date: Päiväys download: Lataa arkisto - hint_html: Voit pyytää arkistoa omista tuuttauksistasi ja mediastasi. Vientitiedot ovat ActivityPub-muodossa, ja ne voi lukea millä tahansa yhteensopivalla ohjelmalla. + hint_html: Voit pyytää arkistoa omista julkaisuista ja mediasta. Viedyt tiedot ovat ActivityPub-muodossa, ja ne voi lukea millä tahansa yhteensopivalla ohjelmalla. Voit pyytää arkistoa 7 päivän välein. in_progress: Arkistoa kootaan... request: Pyydä arkisto size: Koko blocks: Estot bookmarks: Kirjanmerkit csv: CSV - domain_blocks: Verkkotunnus estetty + domain_blocks: Verkkotunnusten estot lists: Listat mutes: Mykistetyt storage: Media-arkisto featured_tags: add_new: Lisää uusi errors: - limit: Olet jo lisännyt enimmäismäärän aihetunnisteita + limit: Olet jo nostanut esille enimmäismäärän aihetunnisteita hint_html: "Mitä ovat näkyvillä olevat hashtagit eli aihetunnisteet? Ne ovat näkyvissä julkisessa profiilissasi ja niiden avulla ihmiset voivat selata julkisia viestejäsi nimenomaan näiden aihetunnisteiden alla. Ne auttavat esimerkiksi luovan työn tai pitkäaikaisten projektien seurannassa." filters: contexts: account: Profiilit - home: Kotiaikajana + home: Kotisyöte ja listat notifications: Ilmoitukset public: Julkiset aikajanat thread: Keskustelut edit: add_keyword: Lisää avainsana keywords: Avainsanat - statuses: Yksittäiset postaukset - statuses_hint_html: Tämä suodatin koskee yksittäisten postausten valintaa riippumatta siitä, vastaavatko ne alla olevia avainsanoja. Tarkista tai poista viestit suodattimesta. + statuses: Yksittäiset julkaisut + statuses_hint_html: Tämä suodatin koskee yksittäisten julkaisujen valintaa riippumatta siitä, vastaavatko ne alla olevia avainsanoja. Tarkista tai poista julkaisut suodattimesta. title: Muokkaa suodatinta errors: - deprecated_api_multiple_keywords: Näitä parametreja ei voi muuttaa tästä sovelluksesta, koska ne koskevat useampaa kuin yhtä suodattimen avainsanaa. Käytä uudempaa sovellusta tai web-käyttöliittymää. + deprecated_api_multiple_keywords: Näitä parametreja ei voi muuttaa tästä sovelluksesta, koska ne koskevat useampaa kuin yhtä suodattimen avainsanaa. Käytä uudempaa sovellusta tai verkkokäyttöliittymää. invalid_context: Ei sisältöä tai se on virheellinen index: contexts: Suodattimet %{contexts} @@ -1169,11 +1248,11 @@ fi: one: "%{count} avainsana" other: "%{count} avainsanaa" statuses: - one: "%{count} viesti" - other: "%{count} viestiä" + one: "%{count} julkaisu" + other: "%{count} julkaisua" statuses_long: - one: "%{count} yksittäinen viesti piilotettu" - other: "%{count} yksittäistä viestiä piilotettu" + one: "%{count} yksittäinen julkaisu piilotettu" + other: "%{count} yksittäistä julkaisua piilotettu" title: Suodattimet new: save: Tallenna uusi suodatin @@ -1183,51 +1262,89 @@ fi: batch: remove: Poista suodattimista index: - hint: Tämä suodatin koskee yksittäisten viestien valintaa muista kriteereistä riippumatta. Voit lisätä lisää viestejä tähän suodattimeen web-käyttöliittymästä. - title: Suodatetut viestit - footer: - trending_now: Suosittua nyt + hint: Tämä suodatin koskee yksittäisten julkaisujen valintaa muista kriteereistä riippumatta. Voit lisätä lisää julkaisuja tähän suodattimeen verkkokäyttöliittymästä. + title: Suodatetut julkaisut generic: all: Kaikki all_items_on_page_selected_html: one: "%{count} kohde tällä sivulla on valittu." other: Kaikki %{count} kohdetta tällä sivulla on valittu. all_matching_items_selected_html: - one: "%{count} tuotetta, joka vastaa hakuasi." + one: "%{count} kohde, joka vastaa hakuasi." other: Kaikki %{count} kohdetta, jotka vastaavat hakuasi. + cancel: Peruuta changes_saved_msg: Muutosten tallennus onnistui! + confirm: Vahvista copy: Kopioi delete: Poista deselect: Poista kaikki valinnat none: Ei mitään - order_by: Järjestä + order_by: Järjestys save_changes: Tallenna muutokset select_all_matching_items: - one: Valitse %{count} kohdetta, joka vastaa hakuasi. + one: Valitse %{count} kohde, joka vastaa hakuasi. other: Valitse kaikki %{count} kohdetta, jotka vastaavat hakuasi. today: tänään validation_errors: one: Kaikki ei ole aivan oikein! Tarkasta alla oleva virhe other: Kaikki ei ole aivan oikein! Tarkasta alla olevat %{count} virhettä - html_validator: - invalid_markup: 'sisältää virheellisen HTML-merkinnän: %{error}' imports: errors: + empty: Tyhjä CSV-tiedosto + incompatible_type: Yhteensopimaton valitun tuontilajin kanssa invalid_csv_file: 'Epäkelpo CSV-tiedosto. Virhe: %{error}' over_rows_processing_limit: sisältää yli %{count} riviä + too_large: Tiedosto on liian suuri + failures: Virheet + imported: Tuodut + mismatched_types_warning: Vaikuttaa siltä, ettei tuontityypin valinta ole oikea. Ole hyvä ja tarkista asia. modes: merge: Yhdistä merge_long: Säilytä olemassa olevat tietueet ja lisää uusia overwrite: Korvaa overwrite_long: Korvaa nykyiset tietueet uusilla - preface: Voit tuoda toisesta instanssista viemiäsi tietoja, kuten esimerkiksi seuraamiesi tai estämiesi henkilöiden listan. + overwrite_preambles: + blocking_html: Olet aikeissa korvata estoluettelosi kaikkiaan %{total_items} tilillä tiedostosta %{filename}. + bookmarks_html: Olet aikeissa korvata kirjanmerkkisi kaikkiaan %{total_items} julkaisulla tiedostosta %{filename}. + domain_blocking_html: Olet aikeissa korvata verkkotunnusten estoluettelosi kaikkiaan %{total_items} verkkotunnuksella tiedostosta %{filename}. + following_html: Olet aikeissa seurata kaikkiaan %{total_items} tiliä tiedostosta %{filename} ja lopettaa kaikkien muiden seuraamisen. + lists_html: Olet aikeissa korvata listojasi tiedoston %{filename} sisällöllä. Uusiin listoihin lisätään kaikkiaan %{total_items} tiliä. + muting_html: Olet aikeissa korvata mykistettyjen tilien luettelosi kaikkiaan %{total_items} tilillä tiedostosta %{filename}. + preambles: + blocking_html: Olet aikeissa estää kaikkiaan %{total_items} tiliä tiedostosta %{filename}. + bookmarks_html: Olet lisäämässä kaikkiaan %{total_items} julkaisua tiedostosta %{filename}kirjanmerkkeihisi. + domain_blocking_html: Olet aikeissa estää kaikkiaan %{total_items} verkkotunnusta tiedostosta %{filename}. + following_html: Olet aikeissa seurata kaikkiaan %{total_items} tiliä tiedostosta %{filename}. + lists_html: Olet lisäämässä listoihisi kaikkiaan %{total_items} tiliä tiedostosta %{filename}. Uusia listoja luodaan, jos sopivaa kohdelistaa ei ole olemassa. + muting_html: Olet aikeissa mykistää kaikkiaan %{total_items} tiliä tiedostosta %{filename}. + preface: Voit tuoda toiselta palvelimelta viemiäsi tietoja, kuten seuraamiesi tai estämiesi henkilöiden luettelon. + recent_imports: Viimeksi tuotu + states: + finished: Valmis + in_progress: Toiminto käynnissä + scheduled: Ajoitettu + unconfirmed: Varmistamaton + status: Tila success: Tietojen lähettäminen onnistui, ja ne käsitellään kohtapuoliin + time_started: Aloitettu + titles: + blocking: Tuodaan estettyjä tilejä + bookmarks: Tuodaan kirjanmerkkejä + domain_blocking: Tuodaan estettyjä verkkotunnuksia + following: Tuodaan seurattuja tilejä + lists: Listojen tuonti + muting: Tuodaan hiljennettyjä tilejä + type: Tuonnin tyyppi + type_groups: + constructive: Seuratut ja kirjanmerkit + destructive: Estot ja mykistykset types: - blocking: Estettyjen lista + blocking: Estoluettelo bookmarks: Kirjanmerkit - domain_blocking: Verkkoalueen estolista - following: Seurattujen lista - muting: Mykistettyjen lista + domain_blocking: Verkkotunnuksen estoluettelo + following: Seurattujen luettelo + lists: Listat + muting: Mykistettyjen luettelo upload: Lähetä invites: delete: Poista käytöstä @@ -1253,10 +1370,10 @@ fi: title: Kutsu ihmisiä lists: errors: - limit: Sinulla on jo suurin sallittu määrä listoja + limit: Sinulla on enimmäismäärä listoja login_activities: authentication_methods: - otp: kaksivaiheinen todennussovellus + otp: kaksivaiheisen todennuksen sovellus password: salasana sign_in_token: sähköpostin turvakoodi webauthn: suojausavaimet @@ -1265,6 +1382,21 @@ fi: failed_sign_in_html: Kirjautumisyritys epäonnistui %{method} - %{ip} (%{browser}) successful_sign_in_html: Kirjautuminen onnistui %{method} - %{ip} (%{browser}) title: Todennushistoria + mail_subscriptions: + unsubscribe: + action: Kyllä, peru tilaus + complete: Tilaus lopetettiin + confirmation_html: Haluatko varmasti lopettaa Mastodonin sähköposti-ilmoitusten vastaanottamisen aiheesta %{type} palvelimelta %{domain} osoitteeseesi %{email}? Voit tilata ilmoitusviestejä milloin tahansa uudelleen sähköposti-ilmoitusten asetuksista. + emails: + notification_emails: + favourite: sähköposti-ilmoituksia suosikkeihin lisäämisistä + follow: sähköposti-ilmoituksia seuraamisista + follow_request: sähköposti-ilmoituksia seuraamispyynnöistä + mention: sähköposti-ilmoituksia maininnoista + reblog: sähköposti-ilmoituksia tehostuksista + resubscribe_html: Jos olet perunut tilauksen erehdyksessä, voit tilata ilmoitusviestejä uudelleen sähköposti-ilmoitusten asetuksista. + success_html: Sinulle ei enää lähetetä Mastodonin %{type} palvelimelta %{domain} osoitteeseen %{email}. + title: Lopeta tilaus media_attachments: validations: images_and_video: Videota ei voi liittää tilapäivitykseen, jossa on jo kuvia @@ -1283,7 +1415,7 @@ fi: on_cooldown: Sinä olet jäähyllä followers_count: Seuraajat muuton aikana incoming_migrations: Siirtyminen toiselta tililtä - incoming_migrations_html: Siirtääksesi toisesta tilistä tähän tiliin, sinun täytyy ensin luoda tilin alias. + incoming_migrations_html: Siirtyäksesi toisesta tilistä tähän, sinun täytyy ensin luoda tilin alias. moved_msg: Tilisi ohjaa nyt kohteeseen %{acct} ja seuraajiasi siirretään. not_redirecting: Tilisi ei ohjaa tällä hetkellä mihinkään muuhun tiliin. on_cooldown: Olet siirtänyt tilisi äskettäin. Tämä toiminto tulee saataville uudelleen %{count} päivän kuluttua. @@ -1294,15 +1426,15 @@ fi: set_redirect: Aseta uudelleenohjaus warning: backreference_required: Uusi tili on ensin määritettävä viittaamaan tähän tiliin - before: 'Ennen jatkamista, lue nämä huomautukset huolellisesti:' - cooldown: Muuton jälkeen on odotusaika, jonka aikana et pysty enää liikkumaan - disabled_account: Nykyinen tilisi ei ole täysin käytettävissä jälkikäteen. Sinulla on kuitenkin pääsy tietojen vientiin ja uudelleenaktivointiin. + before: 'Ennen kuin etenet, lue nämä huomautukset huolellisesti:' + cooldown: Muuton jälkeen on odotusaika, jonka aikana et pysty enää muuttamaan + disabled_account: Nykyinen tilisi ei ole täysin käytettävissä tämän jälkeen. Sinulla on kuitenkin pääsy tietojen vientiin ja uudelleenaktivointiin. followers: Tämä toiminto siirtää kaikki seuraajat nykyisestä tilistä uudelle tilille - only_redirect_html: Vaihtoehtoisesti voit asettaa vain uudelleenohjauksen profiiliisi. + only_redirect_html: Vaihtoehtoisesti voit asettaa vain ohjauksen profiiliisi. other_data: Muita tietoja ei siirretä automaattisesti - redirect: Nykyinen tilisi profiili päivitetään, ohjataan uudelleen ja jätetään pois hausta + redirect: Nykyisen tilisi profiili päivitetään ohjaushuomautuksella ja suljetaan pois hauista moderation: - title: Moderointi + title: Valvonta move_handler: carry_blocks_over_text: Tämä käyttäjä siirtyi paikasta %{acct}, jonka olit estänyt. carry_mutes_over_text: Tämä käyttäjä siirtyi paikasta %{acct}, jonka mykistit. @@ -1314,17 +1446,17 @@ fi: report: subject: "%{name} lähetti raportin" sign_up: - subject: "%{name} kirjautunut" + subject: "%{name} rekisteröityi" favourite: - body: "%{name} tykkäsi tilastasi:" - subject: "%{name} tykkäsi tilastasi" - title: Uusi tykkäys + body: "%{name} lisäsi julkaisusi suosikkeihinsa:" + subject: "%{name} lisäsi julkaisusi suosikkeihinsa" + title: Uusi suosikkeihin lisäys follow: body: "%{name} seuraa nyt sinua!" subject: "%{name} seuraa nyt sinua" title: Uusi seuraaja follow_request: - action: Hallinnoi seuraamispyyntöjä + action: Hallitse seuraamispyyntöjä body: "%{name} haluaa seurata sinua" subject: 'Odottava seuraamispyyntö: %{name}' title: Uusi seuraamispyyntö @@ -1336,14 +1468,15 @@ fi: poll: subject: Äänestys käyttäjältä %{name} on päättynyt reblog: - body: "%{name} tehosti viestiäsi:" - subject: "%{name} tehosti viestiäsi" + body: "%{name} tehosti julkaisuasi:" + subject: "%{name} tehosti julkaisuasi" title: Uusi tehostus status: subject: "%{name} julkaisi juuri" update: - subject: "%{name} muokkasi viestiä" + subject: "%{name} muokkasi julkaisua" notifications: + administration_emails: Ylläpitäjän sähköposti-ilmoitukset email_events: Sähköposti-ilmoitusten tapahtumat email_events_hint: 'Valitse tapahtumat, joista haluat saada ilmoituksia:' other_settings: Muut ilmoitusasetukset @@ -1359,7 +1492,7 @@ fi: trillion: B otp_authentication: code_hint: Anna todennussovelluksen luoma koodi vahvistaaksesi - description_html: Jos otat käyttöön kaksivaiheisen todentamisen, käyttämällä todennussovellusta, kirjautumiseen vaaditaan puhelin, jolla voidaan luoda kirjautumistunnuksia. + description_html: Jos otat kaksivaiheisen todennuksen käyttöön käyttämällä todennussovellusta, kirjautumiseen vaaditaan puhelin, jolla voidaan luoda kirjautumistunnuksia. enable: Ota käyttöön instructions_html: "Lue tämä QR-koodi puhelimen Google Authenticator- tai vastaavalla TOTP-sovelluksella. Sen jälkeen sovellus luo tunnuksia, joita tarvitset kun kirjaudut sisään." manual_instructions: 'Jos et voi lukea QR-koodia ja haluat syöttää sen käsin, tässä on salainen koodi tekstinä:' @@ -1380,12 +1513,22 @@ fi: expired: Äänestys on jo loppunut invalid_choice: Valittua äänestysvaihtoehtoa ei ole over_character_limit: voi olla enintään %{max} merkkiä + self_vote: Et voi äänestää omissa äänestyksissäsi too_few_options: on oltava useampi kuin yksi too_many_options: ei voi sisältää enempää kuin %{max} kohdetta preferences: other: Muut - posting_defaults: Julkaisujen oletusasetukset + posting_defaults: Julkaisun oletusasetukset public_timelines: Julkiset aikajanat + privacy: + hint_html: "Määritä, kuinka haluat profiilisi ja julkaisujesi löytyvän. Mastodonissa on monia ominaisuuksia, joiden käyttöönotto voi auttaa sinua tavoittamaan laajemman yleisön. Käytä hetki tarkistaaksesi, sopivatko nämä asetukset käyttöösi." + privacy: Yksityisyys + privacy_hint_html: Määritä, kuinka paljon muita avustavia tietoja haluat paljastaa. Käyttäjät löytävät kiinnostavia profiileja ja hienoja sovelluksia, kun he selaavat toisten seuraamia käyttäjiä ja kun he näkevät, millä sovelluksilla nämä julkaisevat. Saatat kuitenkin haluta piilottaa nämä tiedot. + reach: Tavoittavuus + reach_hint_html: Määritä, haluatko tulla uusien käyttäjien löytämäksi ja seuraamaksi. Haluatko julkaisujesi näkyvän Selaa-sivulla? Haluatko muiden käyttäjien näkevän sinut seuraamissuosituksissaan? Haluatko hyväksyä kaikki uudet seuraajat automaattisesti vai päättää jokaisesta erikseen? + search: Haku + search_hint_html: Määritä, kuinka haluat tulla löydetyksi. Haluatko, että ihmiset löytävät sinut julkisten julkaisujesi perusteella? Haluatko, että ihmiset Mastodonin ulkopuolella löytävät profiilisi tehdessään hakuja verkossa? Otathan huomioon, ettei julkisten tietojen täyttä kaikista hakukoneista poisjäämistä voi taata. + title: Yksityisyys ja tavoittavuus privacy_policy: title: Tietosuojakäytäntö reactions: @@ -1398,15 +1541,16 @@ fi: confirm_remove_selected_followers: Haluatko varmasti poistaa valitut seuraajat? confirm_remove_selected_follows: Haluatko varmasti poistaa valitut seuraamiset? dormant: Horroksessa + follow_failure: Joitain valittuja tilejä ei voitu seurata. follow_selected_followers: Seuraa valittuja seuraajia followers: Seuraajat following: Seuratut invited: Kutsutut last_active: Viimeksi aktiivinen - most_recent: Viimeisin - moved: Muuttanut + most_recent: Viimeisimmät + moved: Muuttaneet mutual: Molemmat - primary: Ensisijainen + primary: Ensisijaiset relationship: Suhde remove_selected_domains: Poista kaikki seuraajat valituista verkkotunnuksista remove_selected_followers: Poista valitut seuraajat @@ -1418,14 +1562,14 @@ fi: errors: invalid_rules: ei viittaa voimassa oleviin sääntöihin rss: - content_warning: 'Sisällön varoitus:' + content_warning: 'Sisältövaroitus:' descriptions: - account: Julkiset viestit lähettäjältä @%{acct} - tag: 'Julkiset viestit merkitty #%{hashtag}' + account: Julkiset julkaisut tililtä @%{acct} + tag: 'Julkiset julkaisut aihetunnisteella #%{hashtag}' scheduled_statuses: - over_daily_limit: Olet ylittänyt %{limit} ajoitetun viestin rajan tälle päivälle - over_total_limit: Olet ylittänyt %{limit} ajoitetun viestin rajan - too_soon: Ajoitetun päivämäärän on oltava tulevaisuudessa + over_daily_limit: Olet ylittänyt %{limit} ajoitetun julkaisun rajan tälle päivälle + over_total_limit: Olet ylittänyt %{limit} ajoitetun julkaisun rajan + too_soon: Ajoitetun päiväyksen pitää olla tulevaisuudessa sessions: activity: Viimeisin toiminta browser: Selain @@ -1437,6 +1581,7 @@ fi: electron: Electron firefox: Firefox generic: Tuntematon selain + huawei_browser: Huawei-selain ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi -selain @@ -1446,10 +1591,11 @@ fi: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Tuntematon selain weibo: Weibo current_session: Nykyinen istunto description: "%{browser} alustalla %{platform}" - explanation: Nämä verkkoselaimet ovat tällä hetkellä kirjautuneet Mastodon-tilillesi. + explanation: Nämä verkkoselaimet ovat tällä hetkellä kirjautuneena Mastodon-tilillesi. ip: IP-osoite platforms: adobe_air: Adobe AIR @@ -1458,9 +1604,10 @@ fi: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: tuntematon alusta + unknown_platform: Tuntematon alusta windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1476,20 +1623,20 @@ fi: authorized_apps: Valtuutetut sovellukset back: Takaisin Mastodoniin delete: Tilin poisto - development: Kehittäminen + development: Kehitys edit_profile: Muokkaa profiilia export: Vie tietoja - featured_tags: Esitellyt aihetunnisteet + featured_tags: Esiteltävät aihetunnisteet import: Tuo - import_and_export: Tuo / Vie + import_and_export: Tuonti ja vienti migrate: Tilin muutto muualle notifications: Ilmoitukset preferences: Ominaisuudet - profile: Profiili - relationships: Seurattavat ja seuraajat - statuses_cleanup: Automaattinen viestin poisto - strikes: Valvojan varoitukset - two_factor_authentication: Kaksivaiheinen todentaminen + profile: Julkinen profiili + relationships: Seuratut ja seuraajat + statuses_cleanup: Autom. julkaisujen poisto + strikes: Valvontavaroitukset + two_factor_authentication: Kaksivaiheinen todennus webauthn_authentication: Suojausavaimet statuses: attached: @@ -1503,21 +1650,21 @@ fi: video: one: "%{count} video" other: "%{count} videota" - boosted_from_html: Tehostus lähteestä %{acct_link} + boosted_from_html: Tehosti lähteestä %{acct_link} content_warning: 'Sisältövaroitus: %{warning}' default_language: Sama kuin käyttöliittymän kieli disallowed_hashtags: - one: 'sisälsi aihetunnisteen jota ei sallita: %{tags}' - other: 'sisälsi aihetunnisteet joita ei sallita: %{tags}' + one: 'sisälsi kielletyn aihetunnisteen: %{tags}' + other: 'sisälsi kiellettyjä aihetunnisteita: %{tags}' edited_at_html: Muokattu %{date} errors: - in_reply_not_found: Viesti, johon yrität vastata, ei näytä olevan olemassa. + in_reply_not_found: Julkaisua, johon yrität vastata, ei näytä olevan olemassa. open_in_web: Avaa selaimessa over_character_limit: merkkimäärän rajoitus %{max} ylitetty pin_errors: - direct: Viestejä, jotka ovat näkyvissä vain mainituille käyttäjille, ei voi kiinnittää - limit: Olet jo kiinnittänyt suurimman mahdollisen määrän tuuttauksia - ownership: Muiden tuuttauksia ei voi kiinnittää + direct: Vain mainituille käyttäjille näkyviä julkaisuja ei voi kiinnittää + limit: Olet jo kiinnittänyt enimmäismäärän julkaisuja + ownership: Muiden julkaisuja ei voi kiinnittää reblog: Tehostusta ei voi kiinnittää poll: total_people: @@ -1531,37 +1678,36 @@ fi: show_newer: Näytä uudemmat show_older: Näytä vanhempi show_thread: Näytä ketju - sign_in_to_participate: Kirjaudu sisään osallistuaksesi keskusteluun title: "%{name}: ”%{quote}”" visibilities: direct: Suoraan - private: Vain seuraajille + private: Vain seuraajat private_long: Näytä vain seuraajille public: Julkinen public_long: Kaikki voivat nähdä - unlisted: Listaamaton julkinen + unlisted: Listaamaton unlisted_long: Kaikki voivat nähdä, mutta ei näytetä julkisilla aikajanoilla statuses_cleanup: - enabled: Poista vanhat viestit automaattisesti - enabled_hint: Poistaa viestit automaattisesti, kun ne saavuttavat tietyn ikärajan, elleivät ne täsmää yhtä alla olevista poikkeuksista + enabled: Poista vanhat julkaisut automaattisesti + enabled_hint: Poistaa julkaisusi automaattisesti, kun ne saavuttavat valitun ikärajan, ellei jokin alla olevista poikkeuksista tule kyseeseen exceptions: Poikkeukset - explanation: Koska viestien poistaminen on kallista toimintaa, sitä tehdään hitaasti ajan mittaan, kun palvelin ei ole muutoin kiireinen. Viestejäsi voidaankin siis poistaa myös viiveellä verrattuna niille määrittämääsi aikarajaan. + explanation: Koska julkaisujen poistaminen on raskas toimi, se tapahtuu hitaasti ajan mittaan, kun palvelin ei ole muutoin ruuhkainen. Siksi viestejäsi voi poistua vasta tovi sen jälkeen, kun ne ovat saavuttaneet ikärajan. ignore_favs: Ohita suosikit ignore_reblogs: Ohita tehostukset - interaction_exceptions: Poikkeukset, jotka perustuvat vuorovaikutukseen - interaction_exceptions_explanation: Huomaa, että ei ole takeita viestien poistamiselle, jos ne alittavat suosikki- tai tehostusrajan sen jälkeen, kun ne on kerran ylitetty. + interaction_exceptions: Vuorovaikutuksiin perustuvat poikkeukset + interaction_exceptions_explanation: Huomaa, ettei julkaisujen poistumisesta ole varmuutta, jos ne alittavat suosikki- tai tehostusrajan sen jälkeen kun ne on kerran ylitetty. keep_direct: Säilytä yksityisviestit - keep_direct_hint: Ei poista mitään sinun suoria viestejä - keep_media: Säilytä viestit, joissa on liitetiedostoja - keep_media_hint: Ei poista viestejä, joissa on liitteitä - keep_pinned: Pidä kiinnitettyt viestit - keep_pinned_hint: Ei poista mitään kiinnitettyä viestiä + keep_direct_hint: Ei poista yksityisviestejäsi + keep_media: Säilytä julkaisut, joissa on medialiitteitä + keep_media_hint: Ei poista julkaisujasi, joissa on medialiitteitä + keep_pinned: Säilytä kiinnitetyt julkaisut + keep_pinned_hint: Ei poista kiinnitettyjä julkaisujasi keep_polls: Säilytä äänestykset - keep_polls_hint: Ei poista yhtäkään äänestystä - keep_self_bookmark: Säilytä kirjanmerkkeihin lisäämäsi viestit - keep_self_bookmark_hint: Ei poista viestejäsi, jos olet lisännyt ne kirjanmerkkeihin - keep_self_fav: Säilyttää viestit suosikeissa - keep_self_fav_hint: Ei poista omia viestejäsi, jos olet lisännyt ne suosikkeihin + keep_polls_hint: Ei poista äänestyksiäsi + keep_self_bookmark: Säilytä kirjanmerkkeihin lisäämäsi julkaisut + keep_self_bookmark_hint: Ei poista julkaisujasi, jos olet lisännyt ne kirjanmerkkeihin + keep_self_fav: Säilytä suosikkeihin lisäämäsi julkaisut + keep_self_fav_hint: Ei poista julkaisujasi, jos olet lisännyt ne suosikkeihin min_age: '1209600': 2 viikkoa '15778476': 6 kuukautta @@ -1572,14 +1718,12 @@ fi: '63113904': 2 vuotta '7889238': 3 kuukautta min_age_label: Ikäraja - min_favs: Pidä viestit suosikeissa vähintään - min_favs_hint: Ei poista yhtään julkaisuasi, jotka ovat saaneet vähintään tämän määrän tykkäyksiä. Jätä tyhjäksi, jos haluat poistaa julkaisuja tykkäyksien määrästä riippumatta - min_reblogs: Pidä viestit tehostettuna vähintään - min_reblogs_hint: Ei poista yhtään viestiäsi, jota on tehostettu vähintään näin monta kertaa. Jätä tyhjäksi poistaaksesi viestejä riippumatta niiden tehosteiden määrästä + min_favs: Säilytä julkaisut, joilla on suosikiksi lisäyksiä vähintään + min_favs_hint: Ei poista julkaisujasi, joita on lisätty suosikeihin vähintään näin monta kertaa. Jätä tyhjäksi, jos haluat poistaa julkaisuja riippumatta suosikkeihin lisäysmääristä + min_reblogs: Säilytä julkaisut, joilla on tehostuksia vähintään + min_reblogs_hint: Ei poista julkaisujasi, joita on tehostettu vähintään näin monta kertaa. Jätä tyhjäksi, jos haluat poistaa julkaisuja riippumatta niiden tehostusten määrästä stream_entries: - pinned: Kiinnitetty tuuttaus - reblogged: tehosti - sensitive_content: Arkaluontoista sisältöä + sensitive_content: Arkaluonteista sisältöä strikes: errors: too_late: On liian myöhäistä vedota tähän varoitukseen @@ -1593,19 +1737,24 @@ fi: formats: default: "%d.%m.%Y klo %H.%M" month: "%b %Y" - time: "%H:%M" + time: "%H.%M" + with_time_zone: "%d.%m.%Y klo %H.%M %Z" + translation: + errors: + quota_exceeded: Palvelimen käännöspalvelun käyttökiintiö on ylitetty. + too_many_requests: Käännöspalvelulle on hiljattain esitetty liian monta pyyntöä. two_factor_authentication: add: Lisää - disable: Poista käytöstä + disable: Poista 2FA käytöstä disabled_success: Kaksivaiheinen todennus on poistettu käytöstä edit: Muokkaa - enabled: Kaksivaiheinen todentaminen käytössä - enabled_success: Kaksivaiheisen todentamisen käyttöönotto onnistui + enabled: Kaksivaiheinen todennus käytössä + enabled_success: Kaksivaiheisen todennuksen käyttöönotto onnistui generate_recovery_codes: Luo palautuskoodit - lost_recovery_codes: Palautuskoodien avulla voit käyttää tiliä, jos menetät puhelimesi. Jos olet hukannut palautuskoodit, voit luoda uudet tästä. Vanhat palautuskoodit poistetaan käytöstä. - methods: Kaksivaiheisen tunnistautumisen menetelmät + lost_recovery_codes: Palautuskoodien avulla voit käyttää tiliä, jos menetät puhelimesi. Jos olet hukannut palautuskoodisi, voit luoda uudet tästä. Vanhat palautuskoodit poistetaan käytöstä. + methods: Kaksivaiheisen todennuksen menetelmät otp: Todennussovellus - recovery_codes: Varapalautuskoodit + recovery_codes: Ota palautuskoodit talteen recovery_codes_regenerated: Uusien palautuskoodien luonti onnistui recovery_instructions_html: Jos menetät puhelimesi, voit kirjautua tilillesi jollakin alla olevista palautuskoodeista. Pidä palautuskoodit hyvässä tallessa. Voit esimerkiksi tulostaa ne ja säilyttää muiden tärkeiden papereiden joukossa. webauthn: Suojausavaimet @@ -1627,7 +1776,7 @@ fi: change_password: vaihda salasanasi details: 'Tässä on tiedot kirjautumisesta:' explanation: Olemme havainneet kirjautumisen tilillesi uudesta IP-osoitteesta. - further_actions_html: Jos tämä et ollut sinä, suosittelemme että %{action} välittömästi ja ota kaksivaiheinen todennus käyttöön säilyttääksesi tilisi turvallisena. + further_actions_html: Jos tämä et ollut sinä, suosittelemme, että %{action} heti ja otat käyttöön kaksivaiheisen todennuksen pitääksesi tilisi turvassa. subject: Tiliäsi on käytetty uudesta IP-osoitteesta title: Uusi kirjautuminen warning: @@ -1637,63 +1786,68 @@ fi: spam: Roskaposti violation: Sisältö rikkoo seuraavia yhteisön sääntöjä explanation: - delete_statuses: Joitakin viesteistäsi on havaittu rikkovan yhtä tai useampaa yhteisön sääntöä ja instanssin %{instance} valvojat ovat poistaneet ne. + delete_statuses: Joidenkin julkaisuistasi on havaittu rikkovan ainakin yhtä yhteisön sääntöä, ja instanssin %{instance} valvojat ovat poistaneet ne. 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: Instanssin %{instance} valvojat ovat merkinneet osan julkaisuistasi arkaluonteisiksi. Tämä tarkoittaa sitä, että ihmisten täytyy napauttaa viestiä ennen kuin esikatselu näytetään. Voit merkitä median itse arkaluonteiseksi kun julkaiset tulevaisuudessa. + mark_statuses_as_sensitive: Palvelimen %{instance} valvojat ovat merkinneet osan julkaisuistasi arkaluonteisiksi. Tämä tarkoittaa sitä, että ihmisten täytyy napauttaa mediaa ennen kuin sen esikatselu näytetään. Voit merkitä median itse arkaluonteiseksi, kun julkaiset tulevaisuudessa. sensitive: Tästä lähtien kaikki ladatut mediatiedostot merkitään arkaluonteisiksi ja piilotetaan napsautusvaroituksen taakse. - silence: Voit edelleen käyttää tiliäsi, mutta vain sinua jo seuraavat ihmiset näkevät viestisi tällä palvelimella ja sinut voidaan sulkea pois erilaisista hakuominaisuuksista. Toiset voivat kuitenkin edelleen seurata sinua manuaalisesti. - suspend: Et voi enää käyttää tiliäsi ja profiilisi ja muut tiedot eivät ole enää käytettävissä. Voit silti kirjautua sisään pyytääksesi varmuuskopiota tiedoistasi, kunnes tiedot on poistettu kokonaan noin 30 päivän kuluttua. Säilytämme joitakin perustietoja, jotka estävät sinua kiertämästä keskeyttämistä. + 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. + 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: 'Viestejä lainattu:' + statuses: 'Julkaisuja lainattu:' subject: - delete_statuses: Viestisi %{acct} on poistettu + delete_statuses: Julkaisusi tilillä %{acct} on poistettu disable: Tilisi %{acct} on jäädytetty - mark_statuses_as_sensitive: Viestisi %{acct} on merkitty arkaluonteisiksi + mark_statuses_as_sensitive: Julkaisusi tilillä %{acct} on merkitty arkaluonteisiksi none: Varoitus %{acct} - sensitive: Sinun viestisi %{acct} merkitään arkaluonteisiksi tästä lähtien - silence: Tilisi %{acct} on rajoitettu + sensitive: Julkaisusi tilillä %{acct} merkitään arkaluonteisiksi tästä lähtien + silence: Tiliäsi %{acct} on rajoitettu suspend: Tilisi %{acct} on jäädytetty title: - delete_statuses: Viestit poistettu + delete_statuses: Julkaisut poistettu disable: Tili jäädytetty - mark_statuses_as_sensitive: Viestit on merkitty arkaluonteisiksi + mark_statuses_as_sensitive: Julkaisut merkitty arkaluonteisiksi none: Varoitus sensitive: Tili on merkitty arkaluonteiseksi - silence: Rajoitettu tili - suspend: Tilin käyttäminen jäädytetty + silence: Tiliä rajoitettu + suspend: Tili jäädytetty welcome: - edit_profile_action: Aseta profiili - edit_profile_step: Voit muokata profiiliasi lataamalla profiilikuvan, vaihtamalla näyttönimeä ja paljon muuta. Voit halutessasi arvioida uudet seuraajat ennen kuin he saavat seurata sinua. + edit_profile_action: Määritä profiili + edit_profile_step: Voit mukauttaa profiiliasi muun muassa profiilikuvalla ja uudella näyttönimellä. Voit myös valita, haluatko tarkastaa ja hyväksyä uudet seuraajat itse. explanation: Näillä vinkeillä pääset alkuun final_action: Ala julkaista - final_step: 'Ala julkaista! Vaikkei sinulla olisi seuraajia, monet voivat nähdä julkiset viestisi esimerkiksi paikallisella aikajanalla ja aihetunnisteilla. Kannattaa myös esittäytyä! Käytä aihetunnistetta #esittely.' + final_step: 'Ala julkaista! Vaikkei sinulla olisi seuraajia, voivat muut nähdä julkisia julkaisujasi esimerkiksi paikallisella aikajanalla tai aihetunnisteissa. Kannattaa myös esitellä itsensä aihetunnisteella #esittely.' full_handle: Koko käyttäjätunnuksesi - full_handle_hint: Kerro tämä ystävillesi, niin he voivat lähettää sinulle viestejä tai löytää sinut toisen instanssin kautta. + full_handle_hint: Kerro tämä kavereillesi, niin he voivat lähettää sinulle viestejä tai seurata sinua toiselta palvelimelta. subject: Tervetuloa Mastodoniin title: Tervetuloa mukaan, %{name}! users: follow_limit_reached: Et voi seurata yli %{limit} henkilöä + go_to_sso_account_settings: Avaa identiteettitarjoajasi tiliasetukset invalid_otp_token: Virheellinen kaksivaiheisen todentamisen koodi otp_lost_help_html: Jos sinulla ei ole pääsyä kumpaankaan, voit ottaa yhteyttä osoitteeseen %{email} seamless_external_login: Olet kirjautunut ulkoisen palvelun kautta, joten salasana- ja sähköpostiasetukset eivät ole käytettävissä. - signed_in_as: 'Kirjautunut henkilönä:' + signed_in_as: 'Kirjautunut tilillä:' verification: - explanation_html: 'Voit vahvistaa olevasi profiilisi metatiedoissa olevien linkkien omistaja.. Tätä varten linkitetyn verkkosivuston täytyy sisältää linkki takaisin Mastodon-profiiliisi. Palauttavalla linkillä täytyy olla rel="me"-arvo. Linkin tekstisisällöllä ei ole merkitystä. Tässä on esimerkki:' + extra_instructions_html: Vinkki: Verkkosivustollasi oleva linkki voi olla myös näkymätön. Olennainen osuus on rel="me", joka estää toiseksi henkilöksi tekeytymisen verkkosivustoilla, joilla on käyttäjien luomaa sisältöä. Voit käyttää jopa link-elementtiä sivun head-osassa elementin a sijaan, mutta HTML:n pitää olla käytettävissä ilman JavaScript-koodin suorittamista. + here_is_how: Näin voit tehdä sen + hint_html: "Henkilöllisyyden vahvistaminen on Mastodonissa jokaisen käyttäjän ulottuvilla. Se perustuu avoimiin standardeihin ja on maksutonta nyt ja aina. Tarvitset vain henkilökohtaisen verkkosivuston, jonka perusteella sinut voidaan tunnistaa. Kun teet linkin tuolle verkkosivulle profiilistasi, tarkistamme, että verkkosivustolla on linkki takaisin profiiliisi, ja näytämme profiilissasi visuaalisen ilmaisimen." + instructions_html: Kopioi ja liitä alla oleva koodi verkkosivustosi HTML-lähdekoodiin. Lisää sitten verkkosivustosi osoite johonkin profiilisi lisäkentistä ”Muokkaa profiilia” -välilehdellä ja tallenna muutokset. verification: Vahvistus + verified_links: Vahvistetut linkkisi webauthn_credentials: add: Lisää uusi suojausavain create: - error: Suojausavaimen lisäämisessä tapahtui ongelma. Yritä uudelleen. - success: Sinun suojausavaimen lisääminen onnistui. + error: Suojausavaimen lisäämisessä oli ongelma. Yritä uudelleen. + success: Suojausavaimesi lisääminen onnistui. delete: Poista delete_confirmation: Haluatko varmasti poistaa tämän suojausavaimen? description_html: Jos otat suojausavaimen todennuksen käyttöön, kirjautuminen edellyttää jonkin suojausavaimen käyttämistä. destroy: - error: Suojausavaimen poistamisessa tapahtui ongelma. Yritä uudelleen. - success: Sinun suojausavaimen poistaminen onnistui. + error: Suojausavaimen poistamisessa oli ongelma. Yritä uudelleen. + success: Suojausavaimesi poistaminen onnistui. invalid_credential: Virheellinen suojausavain - nickname_hint: Anna nimimerkki uudelle suojausavaimelle - not_enabled: Et ole vielä ottanut käyttöön WebAuthn-ohjelmaa + nickname_hint: Anna uuden suojausaivaimesi lempinimi + not_enabled: Et ole vielä ottanut WebAuthn-ohjelmaa käyttöön not_supported: Tämä selain ei tue suojausavaimia - otp_required: Jos haluat käyttää suojausavaimia, ota ensin käyttöön kaksivaiheinen todennus. + otp_required: Jos haluat käyttää suojausavaimia, ota ensin kaksivaiheinen todennus käyttöön. registered_on: Rekisteröity %{date} diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 874bdc17f2..3c7fe4d997 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -91,6 +91,7 @@ fo: moderation: active: Virkin all: Allar + disabled: Óvirkið pending: Í bíðistøðu silenced: Avmarkað suspended: Avbrotin @@ -124,8 +125,8 @@ fo: removed_header_msg: Slettaði header myndina hjá %{username} resend_confirmation: already_confirmed: Hesi brúkarin er longu váttaður - send: Endursend váttanar teldupost - success: Váttanar teldupostur trygt sendur! + send: Endursend váttanarleinki + success: Váttanarleinki sent! reset: Endurset reset_password: Endurstilla loyniorð resubscribe: Tegna teg umaftur @@ -133,6 +134,7 @@ fo: search: Leita search_same_email_domain: Aðrir brúkarir eru við sama teldupost domaini search_same_ip: Aðrir brúkarar við somu IP + security: Trygd security_measures: only_password: Bara loyniorð password_and_2fa: Loyniorð og 2FA @@ -307,6 +309,7 @@ fo: unpublish: Tak útgávu aftur unpublished_msg: Kunngerð tikin aftur! updated_msg: Kunngerð dagførd! + critical_update_pending: Kritisk dagføring bíðar custom_emojis: assign_category: Tilluta bólk by_domain: Økisnavn @@ -380,6 +383,15 @@ fo: undo: Nokta sameining við navnaøki domain_blocks: add_new: Legg nýggja navnaøkisblokering afturat + confirm_suspension: + cancel: Angra + confirm: Ógilda + permanent_action: Afturkalling av ógilding endurskapar ikki dátur ella sambond. + preamble_html: Tú ert um at gera %{domain} og tess undirnavnaøki óvirkin. + remove_all_data: Hetta fer at strika alt tilfar, miðlar og vangadátur frá kontum hjá hesum navnaøkinum frá tínum ambætara. + stop_communication: Ambætarin fer at gevast at samskifta við hesar ambætararnar. + title: Vátta navnaøkisbann fyri %{domain} + undo_relationships: Hetta ger øll fylgjarasambond millum kontur á hesum ambætarum og tínum ambætara óvirkin. created_msg: Navnaøkisblokering verður nú viðgjørd destroyed_msg: Navnaøkisblokering er nú gjørd óvirkin domain: Økisnavn @@ -427,6 +439,7 @@ fo: resolve: Loys navnaøki title: Blokera nýtt teldupostanavnaøki no_email_domain_block_selected: Ongar teldupostanavnaøkisblokeringar vóru broyttar, tí ongar vóru valdar + not_permitted: Ikki loyvt resolved_dns_records_hint_html: Navnaøkið verður loyst til hesi MX navnaøki, sum í síðsta enda hava ábyrgdina av at móttaka teldupost. At blokera eitt MX navnaøki fer at blokera tilmeldingar frá einum og hvørjum teldupoststaði, sum brúkar sama MX navnaøki, sjálvt um sjónliga navnaøkið er eitt annað. Ansa eftir ikki at blokera stórar veitarar av telduposti resolved_through_html: Loyst gjøgnum %{domain} title: Blokeraði teldupostanavnaøki @@ -473,6 +486,7 @@ fo: content_policies: comment: Innanhýsis viðmerking description_html: Tú kanst áseta innihaldspolitikkir, sum verða áløgd øllum kontum frá hesum navnaøkinum og øllum tess undirnavnaøkjum. + limited_federation_mode_description_html: Tú kanst velja, hvørt tú loyvir sameining við hetta navnaøkið. policies: reject_media: Vraka miðil reject_reports: Vraka meldingar @@ -585,11 +599,13 @@ fo: assign_to_self: Tilluta mær assigned: Tilnevnt umsjónarfólk by_target_domain: Navnaøki hjá meldaðu kontuni + cancel: Angra category: Bólkur category_description_html: Orsøkin, at hendan kontan og/ella tilfarið var melda verður fráboðað í samskifti við meldaðu kontuni comment: none: Eingin comment_description_html: 'Fyri at veita fleiri upplýsingar skrivaði %{name}:' + confirm: Vátta confirm_action: Vátta umsjónaratgerð móti @%{acct} created_at: Meldað delete_and_resolve: Strika postar @@ -725,6 +741,9 @@ fo: branding: preamble: Brandingin av tínum ambætara skilir hann út frá øðrum ambætarum í netverkinum. Hesar upplýsingar kunnu vera vístar í nógvum ymiskum umhvørvum, so sum í vev-markamótinum hjá Mastodon, uppruna-appum, í undanvísingum av leinkjum á øðrum vevstøðum, í boðs-appum og so framvegis. Av hesi orsøk er tað best, um hesar upplýsingar eru klárar, stuttar og beinraknar. title: Branding + captcha_enabled: + desc_html: Hetta er bundið at uttanhýsis skriptum frá hCaptcha, sum kann vera ein trygdar- og privatlívsváði. Harafturat, so kann hetta gera skrásetingartilgongdina munandi minni atkomuliga til summi (brekaði) fólk. Tískil eigur tú at umhugsa aðrar hættir sosum góðkenningar-grundaða ella innbjóðingar-grundaða skráseting. + title: Set krav til nýggjar brúkarar at loysa eina CAPTHA fyri at vátta teirra kontu content_retention: preamble: Stýr hvussu brúkara-skapt tilfar er goymt í Mastodon. title: Varðveitsla av tilfari @@ -752,10 +771,27 @@ fo: approved: Góðkenning kravd fyri tilmelding none: Eingin kann tilmelda seg open: Øll kunnu tilmelda seg + security: + authorized_fetch: Krev samgildi frá sameindum ambætarum + authorized_fetch_hint: At krevja samgildi frá sameindum ambætarum ger strangari útinning av blokkum bæði á brúkara- og ambætara-stigi møguliga. Tó so, kostnaðurin er ein avriksstraffur, minkar um hvussu langt svarini hjá tær røkka og kann viðføra sambæristruplleikar við summar sameindar tænastur. Harafturat forðar hetta ikki teimum, ið miðvíst leggja seg eftir at heinta tínar almennu postar og kontur. + authorized_fetch_overridden_hint: Í løtuni er ikki møguligt hjá tær at broyta hesa stillingina, tí hon verður ógildað av einum umhvørvisbrigdli. + federation_authentication: Tvungið sameint samgildi title: Ambætarastillingar site_uploads: delete: Strika fílu, sum er løgd upp destroyed_msg: Vevstaðs-uppsending strikað! + software_updates: + critical_update: Kritiskt - vinarliga dagfør beinan vegin + description: Mælt verður til, at Mastodon-innleggingin hjá tær altíð er dagførd, soleiðis at hon fær gagn av nýggjastu ábótunum og hentleikunum. Harumframt er tað summatíðir kritiskt, at Mastodon umgangandi verður dagført fyri at mótvirka trygdartrupulleikum. Tí kekkar Mastodon hvørjar 30 minuttir, um dagføringar eru neyðugar, og letur teg frætta samsvarandi teldubrævafráboðanarstillingunum hjá tær. + documentation_link: Lær meira + release_notes: Útgávuviðmerkingar + title: Tøkar dagføringar + type: Slag + types: + major: Høvuðsútgáva + minor: Minni útgáva + patch: Bótarútgáva - feilrættingar og broytingar, sum eru lættar at íverkseta + version: Útgáva statuses: account: Høvundi application: Nýtsluskipan @@ -765,7 +801,7 @@ fo: remove_from_report: Strika frá melding report: Melding deleted: Strikað - favourites: Yndispostar + favourites: Dámdir postar history: Útgávusøga in_reply_to: Svarar language: Mál @@ -792,9 +828,24 @@ fo: suspend: "%{name} setti kontuna hjá %{target} úr gildi" appeal_approved: Kært appeal_pending: Kæra bíðar eftir avgerð + appeal_rejected: Kæra vrakað system_checks: database_schema_check: message_html: Dátugrunnaflytingar bíða. Vinarliga koyr flytingarnar fyri at tryggja at skipanin skikkar sær sum hon skal + elasticsearch_health_red: + message_html: Elasticsearch cluster er ósunt (reyð støða), leitimøguleikar eru ikki tøkir + elasticsearch_health_yellow: + message_html: Elasticsearch cluster er ósunt (gul støða), kanska tú vil kanna, hvør orsøkin er + elasticsearch_index_mismatch: + message_html: Elasticsearch indeks-mappingar eru avoldaðar. Vinarliga koyr tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Sí skjalfesting + message_html: Elasticsearch cluster'ið hjá tær hevur meira enn eina nodu, men Mastodon er ikki sett upp at brúka tær. + elasticsearch_preset_single_node: + action: Sí skjalfesting + message_html: Elasticsearch cluster'ið hjá tær hevur einans eina nodu, ES_PRESET átt at verið sett til single_node_cluster. + elasticsearch_reset_chewy: + message_html: Elasticsearch skipanar-indeksið hjá tær er avoldað orsakað av eini broyting í stillingunum. Vinarliga koyr tootctl search deploy --reset-chewy fyri at dagføra tað. elasticsearch_running_check: message_html: Fekk ikki samband við Elasticsearch. Vinarliga kanna eftir, at tað koyrir, ella ger fulltekstaleiting óvirkna elasticsearch_version_check: @@ -805,6 +856,18 @@ fo: message_html: Tú hevur ikki ásett nakrar ambætarareglur. sidekiq_process_check: message_html: Eingin Sidekiq gongd koyrir fyri %{value} bíðirøðina(r). Vinarliga eftirkanna Sidekiq uppsetingina + software_version_critical_check: + action: Sí tøkar dagføringar + message_html: Ein kritisk Mastodon-dagføring er tøk, vinarliga dagfør sum skjótast. + software_version_patch_check: + action: Sí tøkar dagføringar + message_html: Ein Mastdon-dagføring við feilrættingum er tøk. + upload_check_privacy_error: + action: Kekka her fyri at fáa fleiri upplýsingar + message_html: "Vevambætarin hjá tær er skeivt uppsettur. Privatlívið hjá brúkarunum hjá tær er í vanda." + upload_check_privacy_error_object_storage: + action: Kekka her fyri at fáa fleiri upplýsingar + message_html: "Objekt-goymslan hjá tær er skeivt uppsett. Privatlívið hjá brúkarunum hjá tær er í vanda." tags: review: Eftirkanna støðu updated_msg: Frámerkjastillingar dagførdar @@ -827,6 +890,7 @@ fo: other: Deilt av %{count} persónum seinastu vikuna title: Vælumtókt leinki usage_comparison: Deilt %{today} ferð í dag, samanborið við %{yesterday} ferð í gjár + not_allowed_to_trend: Ikki loyvt at gerast rák only_allowed: Einans loyvd pending_review: Bíðar eftir eftirkannan preview_card_providers: @@ -911,6 +975,9 @@ fo: body: "%{target} kærir eina umsjónaravgerð hjá %{action_taken_by} frá %{date}, sum var %{type}. Tey skrivaðu:" next_steps: Tú kanst góðtaka kæruna og soleiðis ógilda umsjónaravgerðina, ella ikki látast at síggja hana. subject: "%{username} kærir eina umsjónaravgerð á %{instance}" + new_critical_software_updates: + body: Nýggjar kritiskar útgávur av Mastodon eru útgivnar. Dagfør sum skjótast! + subject: Kritiskar Mastodon-dagføringar eru tøkar fyri %{instance}! new_pending_account: body: Smálutirnir hjá tí nýggju kontuni eru niðanfyri. Tú kanst góðkenna ella vraka hesa umsóknina. subject: Nýggj konta klár til ummælis á %{instance} (%{username}) @@ -918,6 +985,9 @@ fo: body: "%{reporter} hevur meldað %{target}" body_remote: Onkur frá %{domain} hevur meldað %{target} subject: Nýggj melding fyri %{instance} (#%{id}) + new_software_updates: + body: Nýggjar Mastodon-útgávur eru útgivnar; umhugsa at dagføra! + subject: Nýggjar Mastodon-útgávur eru tøkar fyri %{instance}! new_trends: body: 'Niðanfyristandandi lutir mugu eftirhyggjast áðrenn teir kunnu verða vístir alment:' new_trending_links: @@ -947,24 +1017,28 @@ fo: guide_link: https://crowdin.com/project/mastodon guide_link_text: Øll kunnu geva íkast. sensitive_content: Viðkvæmt innihald - toot_layout: Uppseting av postum application_mailer: notification_preferences: Broyt teldupostastillingar salutation: "%{name}" settings: 'Broyt teldupostastillingar: %{link}' + unsubscribe: Strika hald view: 'Vís:' view_profile: Vís vanga view_status: Vís post applications: created: Umsókn stovnað destroyed: Umsókn strikað + logout: Rita út regenerate_token: Ger atgongdstekn av nýggjum token_regenerated: Atgongdsteknið gjørt av nýggjum warning: Ver varin við hesum dátum. Deil tað aldrin við nakran! your_token: Títt atgongdstekn auth: apply_for_account: Bið um eina kontu - change_password: Loyniorð + captcha_confirmation: + help_html: Um tú hevur trupulleikar við at loysa CAPTCHA, so kanst tú fáa samband við okkum gjøgnum %{email} og vit kunnu hjálpa tær. + hint_html: Bara eitt afturat! Tað er neyðugt hjá okkum at vátta, at tú ert eitt menniskja (fyri at sleppa undan ruskposti!). Loys CAPTCHA niðanfyri og trýst á "Halt fram". + title: Trygdarkanning confirmations: wrong_email_hint: Um hesin teldupoststaðurin ikki er rættur, so kanst tú broyta hann í kontustillingunum. delete_account: Strika kontu @@ -973,7 +1047,7 @@ fo: prefix_invited_by_user: "@%{name} bjóðar tær at verða við í hesum Mastodon-ambætaranum!" prefix_sign_up: Tilmelda teg á Mastodon í dag! suffix: Við eini kontu, so er møguligt hjá tær at fylgja fólki, at posta dagføringar og at senda og móttaka boð til og frá brúkarum á øllum Mastodon ambætarum, umframt annað! - didnt_get_confirmation: Móttók tú ikki váttanarboðini? + didnt_get_confirmation: Móttók tú ikki váttanarleinkið? dont_have_your_security_key: Hevur tú ikki trygdarlyklin hjá tær? forgot_password: Hevur tú gloymt loyniorðið? invalid_reset_password_token: Teknið til nullstilling av loyniorði er ógyldugt ella útgingið. Vinarliga bið um eitt nýtt. @@ -986,26 +1060,39 @@ fo: migrate_account_html: Ynskir tú at víðaribeina hesa kontuna til eina aðra, so kanst tú seta tað upp her. or_log_in_with: Ella innrita við privacy_policy_agreement_html: Eg havi lisið og taki undir við privatlívspolitikkinum + progress: + confirm: Vátta teldupost + details: Tínir smálutir + review: Okkara kanning + rules: Góðtak reglur providers: cas: CAS saml: SAML register: Tilmelda registration_closed: "%{instance} tekur ikki ímóti nýggjum limum" - resend_confirmation: Send góðkenningarvegleiðing umaftur + resend_confirmation: Endursend váttanarleinki reset_password: Endurstilla loyniorð rules: + accept: Góðtak + back: Aftur + invited_by: 'Tú kanst binda í %{domain} takkað verið innbjóðingina, sum tú hevur fingið frá:' preamble: Hesi eru ásett og uppihildin av umsjónarfólkunum á %{domain}. + preamble_invited: Áðrenn tú heldur fram, vinarliga set teg inn í grundreglurnar, sum umsjónarfólkini á %{domain} hava ásett. title: Nakrar grundreglur. + title_invited: Tú hevur fingið innbjóðing. security: Trygd set_new_password: Áset nýtt loyniorð setup: - email_below_hint_html: Er telduposturin niðanfyri skeivur, so kanst tú broyta hann her og móttaka eitt nýtt váttanarteldubræv. - email_settings_hint_html: Váttanarteldubrævið varð sent til %{email}. Um telduposturin er skeivur, so kanst tú broyta hann í kontustillingunum. - title: Uppseting + email_below_hint_html: Kekka mappuna við ruskposti ella bið um ein annan. Tú kanst rætta teldupostadressuna, um hon er skeiv. + email_settings_hint_html: Kekka leinkið, sum vit sendu tær at eftirkanna %{email}. Vit bíða beint her. + link_not_received: Fekk tú einki leinki? + new_confirmation_instructions_sent: Tú fer at móttaka eitt nýtt teldubræv við váttanarleinkinum um nakrar fáar minuttir! + title: Kekka innbakkan hjá tær sign_in: preamble_html: Rita inn við tínum %{domain} heimildum. Er konta tín á einum øðrum ambætara, so er ikki gjørligt hjá tær at rita inn her. title: Rita inn á %{domain} sign_up: + manual_review: Tilmeldingar til %{domain} fara ígjøgnum eina manuella eftirkanning av okkara kjakleiðarum. Fyri at hjálpa okkum at skunda undir skrásetingina, skriva eitt sindur um teg sjálva/n og hví tú vil hava eina kontu á %{domain}. preamble: Við eini kontu á hesum Mastodon ambætaranum ber til hjá tær at fylgja ein og hvønn annan persón á netverkinum, óansæð hvar teirra konta er hýst. title: Latum okkum fáa teg settan upp á %{domain}. status: @@ -1017,18 +1104,6 @@ fo: view_strikes: Vís eldri atsóknir móti tíni kontu too_fast: Oyðublaðið innsent ov skjótt, royn aftur. use_security_key: Brúka trygdarlykil - authorize_follow: - already_following: Tú fylgir longu hesi kontuni - already_requested: Tú hevur longu sent eina fylgiumbøn til hasa kontuna - error: Tíverri kom ein feilur, tá vit royndu at finna fjarkontuna - follow: Fylg - follow_request: 'Tú hevur sent eina fylgjaraumbøn til:' - following: 'Góðkent! Tú fylgir nú:' - post_follow: - close: Ella kanst tú bara lata hetta vindeygað aftur. - return: Vís vangan hjá brúkaranum - web: Far á vevið - title: Fylg %{acct} challenge: confirm: Hald á hint_html: "Góð ráð: vit spyrja teg ikki aftur um loyniorðið næsta tíman." @@ -1105,6 +1180,10 @@ fo: your_appeal_rejected: Kæra tín er vrakað domain_validator: invalid_domain: er ikki eitt loyvt økisnavn + edit_profile: + basic_information: Grundleggjandi upplýsingar + hint_html: "Tillaga tað, sum fólk síggja á tínum almenna vanga og við síðna av tínum postum. Sannlíkindini fyri, at onnur fylgja tær og virka saman við tær eru størri, tá tú hevur fylt út vangan og eina vangamynd." + other: Onnur errors: '400': Umbønin, sum tú sendi inn, var ógildug ella hevði skeivt skap. '403': Tú hevur ikki loyvi at síggja hesa síðuna. @@ -1185,8 +1264,6 @@ fo: index: hint: Hetta filtrið er galdandi fyri útvaldar stakar postar óansæð aðrar treytir. Tú kanst leggja fleiri postar afturat hesum filtrinum frá vevmarkamótinum. title: Filtreraðir postar - footer: - trending_now: Rák beint nú generic: all: Alt all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ fo: all_matching_items_selected_html: one: "%{count} lutur, sum samsvarar við tína leiting, er valdur." other: Allir %{count} lutir, sum samsvara við tína leiting, eru valdir. + cancel: Ógilda changes_saved_msg: Broytingar goymdar! + confirm: Vátta copy: Avrita delete: Strika deselect: Frável alt @@ -1209,24 +1288,62 @@ fo: validation_errors: one: Okkurt er ikki heilt rætt enn! Vinarliga eftirhygg feilin niðanfyri other: Okkurt er ikki heilt rætt enn! Vinarliga eftirhygg teir %{count} feilirnar niðanfyri - html_validator: - invalid_markup: 'inniheldur ógyldugt HTML markup: %{error}' imports: errors: + empty: Tóm CSV fíla + incompatible_type: Ikki sambærligt við valda innflytingarslagnum invalid_csv_file: 'Ógildug CSV-fíla. Error: %{error}' over_rows_processing_limit: hevur fleiri enn %{count} rekkjur + too_large: Fílan er ov stór + failures: Brek + imported: Innflutt + mismatched_types_warning: Tað sær út sum at tú kanska hevur valt skeivt slag fyri hesa innflytingina, vinarliga dupult-kekka. modes: merge: Flætta merge_long: Varðveit verandi teigarøð og legg nýggjar afturat overwrite: Skriva omaná overwrite_long: Legg nýggj teigarøð inn fyri tey verandi + overwrite_preambles: + blocking_html: Tú ert í ferð við at útskifta blokeringslistan hjá tær við upp til %{total_items} kontum frá %{filename}. + bookmarks_html: Tú ert í ferð við at útskifta tíni bókamerki við upp til %{total_items} postum frá %{filename}. + domain_blocking_html: Tú ert í ferð við at útskifta navnaøkisblokeringslistan hjá tær við upp til %{total_items} navnaøkjum frá %{filename}. + following_html: Tú ert í ferð við at fylgja upp til %{total_items} kontum frá %{filename} og at gevast at fylgja øðrum. + lists_html: Tú ert í ferð við at skifta listarnar hjá tær út við tað, sum er í %{filename}. Upp til %{total_items} kontur verða lagdar afturat nýggjum listum. + muting_html: Tú ert í ferð við at útskifta listan hjá tær við doyvdum kontum við upp til %{total_items} kontum frá %{filename}. + preambles: + blocking_html: Tú ert í ferð við at blokera upp til %{total_items} kontur frá %{filename}. + bookmarks_html: Tú ert í ferð við at leggja upp til %{total_items} postar frá %{filename} afturat tínum bókamerkjum. + domain_blocking_html: Tú ert í ferð við at blokera upp til %{total_items} navnaøki frá %{filename}. + following_html: Tú ert í ferð við at fylgja upp til %{total_items} kontur frá %{filename}. + lists_html: Tú ert í ferð við at leggja upp til %{total_items} kontur frá %{filename} afturat tínum listum. Nýggir listar verða stovnaðir, um eingin listi er at leggja afturat. + muting_html: Tú ert í ferð við at doyva upp til %{total_items} kontur frá %{filename}. preface: Tú kanst innlesa dátur, sum tú hevur útlisið frá einum øðrum ambætara, so sum listar av fólki, sum tú fylgir ella blokerar. + recent_imports: Feskar innflytingar + states: + finished: Lidnar + in_progress: Í gongd + scheduled: Skrálagdar + unconfirmed: Ikki váttaðar + status: Støða success: Dátur tínar vóru lagdar upp og verða viðgjørdar, tá tíð er + time_started: Byrjaði + titles: + blocking: Innflyti blokeraðar kontur + bookmarks: Innflyti bókamerki + domain_blocking: Innflyti blokeraði navnaøki + following: Innflyti fylgdar kontur + lists: Innlesi listar + muting: Innflyti doyvdar kontur + type: Innflytingarslag + type_groups: + constructive: Fylgingar & bókamerki + destructive: Blokeringar & doyvingar types: blocking: Blokeringslisti bookmarks: Bókamerki domain_blocking: Navnaøkisblokeringslisti following: Fylgjaralisti + lists: Listar muting: Doyvingarlisti upload: Legg upp invites: @@ -1265,6 +1382,21 @@ fo: failed_sign_in_html: Miseydnað innritanarroynd við %{method} frá %{ip} (%{browser}) successful_sign_in_html: Eydnað innritan við %{method} frá %{ip} (%{browser}) title: Samgildissøga + mail_subscriptions: + unsubscribe: + action: Ja, strika hald + complete: Hald strikað + confirmation_html: Ert tú vís/ur í, at tú vil gevast at móttaka %{type} fyri Mastodon á %{domain} til tína teldupostadressu á %{email}? Tú kanst altíð gera haldið virkið aftur frá tínum teldupostfráboðanarstillingum. + emails: + notification_emails: + favourite: yndisfráboðanarteldupostar + follow: fylg fráboðanarteldupostar + follow_request: fylg umbønir um teldupost + mention: nevn fráboðanarteldupostar + reblog: stimbra fráboðanarpostar + resubscribe_html: Um tú hevur strikað haldið av misgávum, so kanst tú tekna haldið av nýggjum í tínum teldupostfráboðarstillingum. + success_html: Tú fer ikki longur at móttaka %{type} fyri Mastodon á %{domain} til tín teldupost á %{email}. + title: Strika hald media_attachments: validations: images_and_video: Kann ikki viðfesta sjónfílu til ein post, sum longu inniheldur myndir @@ -1344,6 +1476,7 @@ fo: update: subject: "%{name} rættaði ein post" notifications: + administration_emails: Fráboðanir um teldupost til umsitarar email_events: Hendingar fyri teldupostfráboðanir email_events_hint: 'Vel hendingar, sum tú vil hava fráboðanir um:' other_settings: Aðrar fráboðanarstillingar @@ -1380,12 +1513,22 @@ fo: expired: Atkvøðugreiðslan er longu endað invalid_choice: Valmøguleikin finst ikki over_character_limit: kann ikki vera longri enn %{max} tekn hvør + self_vote: Tú kanst ikki atkvøða í tínum egnum atkvøðugreiðslum too_few_options: má hava meiri enn ein valmøguleika too_many_options: kann ikki innihalda fleiri enn %{max} valmøguleikar preferences: other: Annað posting_defaults: Postingarstillingar public_timelines: Almennar tíðarlinjur + privacy: + hint_html: "Tillaga hvussu tú vilt hava tín vanga og tínar postar at blíva funnar Eitt úrval av tættum í Mastodon kunnu hjálpa tær at røkka einum størri skara, tá teir eru settir til. Brúka eina løtu at eftirhyggja hesar stillingar fyri at fáa vissu um at tær eru hóskandi fyri teg." + privacy: Privatlív + privacy_hint_html: Stýr hvussu nógv tú vil avdúka til gagns fyri onnur. Fólk varnast áhugaverdar vangar og kular appir tá tey síggja, hvørji fólk fylgja teimum og hvørjar appir, tey brúka at posta við, men tað kann vera, at tú heldur vilt halda tað fjalt. + reach: Útbreiðsla + reach_hint_html: Stýr um onnur skulu kunna finna teg og fylgja tær. Vilt tú hava, at postar tínir síggjast á Rannsaka-síðuni? Vilt tú hava at onnur síggja teg í viðmælum um hvørji tey skulu fylgja? Vilt tú góðkenna allar nýggjar fylgjarar sjálvvirkandi ella vilt tú stýra nágreiniliga hvør kann fylgja tær? + search: Leita + search_hint_html: Stýr, hvussu tú verður funnin. Vilt tú hava at fólk finna teg við tí, sum tú hevur postað fyri almenninginum? Vilt tú hava, at fólk uttan fyri Mastodon finna vangan hjá tær tá tey leita á netinum? Gev gætur, at vissa fyri fullkomnari verja móti øllum leitimaskinum ikki kann gevast fyri almennar upplýsingar. + title: Privatlív og skotmál privacy_policy: title: Privatlívspolitikkur reactions: @@ -1398,6 +1541,7 @@ fo: confirm_remove_selected_followers: Vil tú veruliga strika valdu fylgjararnar? confirm_remove_selected_follows: Vil tú veruliga strika valdu fylgingarnar? dormant: Í dvala + follow_failure: Tað bar ikki til at fylgja øllum valdu kontunum. follow_selected_followers: Fylg valdu fylgjarum followers: Fylgjarar following: Fylgi @@ -1437,6 +1581,7 @@ fo: electron: Electron firefox: Firefox generic: Ókendur kagi + huawei_browser: Huawei kagi ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1591,7 @@ fo: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Ókendur kagi weibo: Weibo current_session: Verandi seta description: "%{browser} á %{platform}" @@ -1458,9 +1604,10 @@ fo: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: ókendur pallur + unknown_platform: Ókendur pallur windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1484,7 +1631,7 @@ fo: import_and_export: Innflyt og útflyt migrate: Flyting av kontu notifications: Fráboðanir - preferences: Sertokki + preferences: Stillingar profile: Vangi relationships: Fylging og fylgjarar statuses_cleanup: Sjálvvirkandi striking av postum @@ -1531,7 +1678,6 @@ fo: show_newer: Vís nýggjari show_older: Vís eldri show_thread: Vís tráð - sign_in_to_participate: Rita inn fyri at luttaka í samrøðuni title: '%{name}: "%{quote}"' visibilities: direct: Beinleiðis @@ -1577,8 +1723,6 @@ fo: min_reblogs: Varðveit postar, sum eru stimbraðir í minsta lagi min_reblogs_hint: Strikar ikki postar hjá tær, sum eru stimbraðir í minsta lagi so ofta. Lat vera blankt, um postar skulu strikast óansæð, hvussu ofta teir eru stimbraðir stream_entries: - pinned: Festir postar - reblogged: stimbraður sensitive_content: Viðkvæmt innihald strikes: errors: @@ -1594,6 +1738,11 @@ fo: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d. %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Ambætarin hevur brúkt alla kvotuna, sum hann hevði hjá umsetaratænstuni. + too_many_requests: Ov nógv kall hava verið til umsetaratænastuna nýliga. two_factor_authentication: add: Legg afturat disable: Ger 2FA óvirkið @@ -1673,13 +1822,18 @@ fo: title: Vælkomin umborð, %{name}! users: follow_limit_reached: Tú kanst ikki fylgja fleiri enn %{limit} fólk + go_to_sso_account_settings: Far til kontustillingarnar hjá samleikaveitaranum hjá tær invalid_otp_token: Ógyldug tvey-stigs koda otp_lost_help_html: Hevur tú mist atgongd til bæði, so kanst tú koma í samband við %{email} seamless_external_login: Tú er ritað/ur inn umvegis eina uttanhýsis tænastu, so loyniorð og teldupoststillingar eru ikki tøkar. signed_in_as: 'Ritað/ur inn sum:' verification: - explanation_html: 'Tú kanst vátta teg sjálva/n sum eigara av leinkjunum í metadátunum á vanganum hjá tær. Til tess má leinkjaða vevstaðið innihalda eitt leinki aftur til Mastodon vangan hjá tær. Leinkið hava eina rel="me" viðseting. Tekstinnihaldið í leikinum er óviðkomandi. Her er eitt dømi:' + extra_instructions_html: Góð ráð: Leinkið á heimasíðuni hjá tær kann vera ósjónligt. Tann týdningarmikli parturin er rel="me" sum forðar tí, at onkur kann látast at vera ein annar á heimasíðuni við brúkara-gjørdum tilfari. Tú kanst enntá brúka eitt link frámerki í høvdinum á síðuni heldur enn a, men HTML kodan má vera atkomulig uttan at JavaScript skal koyra. + here_is_how: Her er hvussu + hint_html: "At vátta samleikan hjá tær á Mastodon er fyri øll. Grundað á opnar vevstandarar, nú og í allar ævir frítt. Alt, tú hevur tørv á, er ein persónlig heimasíða, sum fólk kunnu kenna teg aftur á. Tá tú ger leinki til ta heimasíðuna frá vanga tínum, so eftirkanna vit, at heimasíðan hevur eitt leinki aftur til vangan hjá tær og vísa tað á vanganum." + instructions_html: Avrita og innset koduna niðanfyri inn í HTML'ið á heimasíðuni hjá tær. Legg síðani adressuna á heimasíðuni hjá tær inn á eitt av eyka teigunum á vanganum hjá tær umvegis "Rætta vanga" teigin og goym broytingar. verification: Váttan + verified_links: Tíni váttaðu leinki webauthn_credentials: add: Legg nýggjan trygdarlykil afturat create: diff --git a/config/locales/fr-QC.yml b/config/locales/fr-QC.yml index 504ab8486b..b9605f3a6a 100644 --- a/config/locales/fr-QC.yml +++ b/config/locales/fr-QC.yml @@ -35,7 +35,7 @@ fr-QC: approve: Approuver approved_msg: La demande d’inscription de %{username} a été approuvée avec succès are_you_sure: Voulez-vous vraiment faire ça ? - avatar: Avatar + avatar: Image de profil by_domain: Domaine change_email: changed_msg: Courriel modifié avec succès ! @@ -91,6 +91,7 @@ fr-QC: moderation: active: Actifs all: Tous + disabled: Désactivé pending: En cours de traitement silenced: Limité suspended: Suspendus @@ -124,8 +125,8 @@ fr-QC: removed_header_msg: L’image d’en-tête de %{username} a été supprimée avec succès resend_confirmation: already_confirmed: Cet·te utilisateur·rice est déjà confirmé·e - send: Renvoyer un courriel de confirmation - success: Courriel de confirmation envoyé avec succès ! + send: Renvoyer le courriel de confirmation + success: Courriel de confirmation envoyé avec succès! reset: Réinitialiser reset_password: Réinitialiser le mot de passe resubscribe: Se réabonner @@ -133,6 +134,7 @@ fr-QC: search: Rechercher search_same_email_domain: Autres utilisateurs·trices avec le même domaine de courriel search_same_ip: Autres utilisateur·rice·s avec la même IP + security: Sécurité security_measures: only_password: Mot de passe uniquement password_and_2fa: Mot de passe et 2FA @@ -307,6 +309,7 @@ fr-QC: unpublish: Retirer l'annonce unpublished_msg: L’annonce a été dépubliée avec succès ! updated_msg: L’annonce a été mise à jour avec succès ! + critical_update_pending: Mise à jour critique en attente custom_emojis: assign_category: Attribuer une catégorie by_domain: Domaine @@ -380,6 +383,15 @@ fr-QC: undo: Supprimer de la liste blanche domain_blocks: add_new: Bloquer un nouveau domaine + confirm_suspension: + cancel: Annuler + confirm: Suspendre + permanent_action: Annuler la suspension ne restaure aucune donnée ou relation. + preamble_html: Vous êtes sur le point de suspendre %{domain} et ses sous-domaines. + remove_all_data: Cela supprimera de votre serveur tous les contenus, médias et données de profil pour les comptes de ce domaine. + stop_communication: Votre serveur cessera de communiquer avec ces serveurs. + title: Confirmer le blocage du domaine pour %{domain} + undo_relationships: Cela annulera toute relation de suivi entre les comptes de ces serveurs et du vôtre. created_msg: Le blocage de domaine est désormais activé destroyed_msg: Le blocage de domaine a été désactivé domain: Domaine @@ -427,17 +439,18 @@ fr-QC: resolve: Résoudre le domaine title: Nouveau blocage de domaine de courriel no_email_domain_block_selected: Aucun blocage de domaine de courriel n'a été modifié car aucun n'a été sélectionné + not_permitted: Non autorisé resolved_dns_records_hint_html: Le nom de domaine est relié aux domaines MX suivants, qui ont la responsabilité ultime d'accepter les courriels. Bloquer un domaine MX empêchera les inscriptions à partir de toute adresse courriel utilisant le même domaine MX, même si le nom de domaine affiché est différent. Veillez à ne pas bloquer les fournisseurs de messagerie d'envergure. resolved_through_html: Résolu par %{domain} title: Blocage de domaines de courriel export_domain_allows: new: - title: Autoriser l'importation de domaine + title: Importer les autorisations de domaine no_file: Aucun fichier sélectionné export_domain_blocks: import: - description_html: Vous êtes sur le point d'importer une liste de blocs de domaine. Veuillez examiner cette liste très attentivement, spécialement si vous n'êtes pas l'auteur de cette liste. - existing_relationships_warning: Relations de suivi existantes + description_html: Vous êtes sur le point d'importer une liste de bloqueurs de domaine. Veuillez examiner cette liste très attentivement, surtout si vous ne l'avez pas créée vous-même. + existing_relationships_warning: Relations d'abonnement existantes private_comment_description_html: 'Pour vous aider à savoir d''où proviennent les blocages importés, ceux-ci seront créés avec le commentaire privé suivant : %{comment}' private_comment_template: Importé depuis %{source} le %{date} title: Importer des blocages de domaine @@ -473,6 +486,7 @@ fr-QC: content_policies: comment: Note interne description_html: Vous pouvez définir des politiques de contenu qui seront appliquées à tous les comptes de ce domaine et à tous ses sous-domaines. + limited_federation_mode_description_html: Vous pouvez choisir d'autoriser la fédération avec ce domaine. policies: reject_media: Rejeter les médias reject_reports: Rejeter les signalements @@ -585,11 +599,13 @@ fr-QC: assign_to_self: Me l’assigner assigned: Modérateur assigné by_target_domain: Domaine du compte signalé + cancel: Annuler category: Catégorie category_description_html: La raison pour laquelle ce compte et/ou ce contenu a été signalé sera citée dans la communication avec le compte signalé comment: none: Aucun comment_description_html: 'Pour fournir plus d''informations, %{name} a écrit :' + confirm: Confirmer confirm_action: Confirmer l'action de modération contre @%{acct} created_at: Signalé delete_and_resolve: Supprimer les messages @@ -725,12 +741,15 @@ fr-QC: branding: preamble: L'image de marque de votre serveur la différencie des autres serveurs du réseau. Ces informations peuvent être affichées dans nombre d'environnements, tels que l'interface web de Mastodon, les applications natives, dans les aperçus de liens sur d'autres sites Web et dans les applications de messagerie, etc. C'est pourquoi il est préférable de garder ces informations claires, courtes et concises. title: Thème + captcha_enabled: + desc_html: Ceci se base sur des scripts externes de hCaptcha, ce qui peut engendrer des soucis de sécurité et de confidentialité. De plus, cela peut rendre l'inscription beaucoup moins accessible pour certaines personnes (surtout les personnes handicapées). Pour ces raisons, veuillez envisager des mesures alternatives telles que l'inscription par acceptation ou par invitation. + title: Obliger les nouveaux utilisateurs à résoudre un CAPTCHA pour vérifier leur compte content_retention: preamble: Contrôle comment le contenu créé par les utilisateurs est enregistré et stocké dans Mastodon. title: Rétention du contenu default_noindex: - desc_html: Affecte tous les utilisateurs qui n'ont pas modifié ce paramètre eux-mêmes - title: Ne pas indexer par défaut les utilisateurs dans les moteurs de recherche + desc_html: Affecte tous les comptes qui n'ont pas modifié ce paramètre + title: Par défaut, ne pas indexer les comptes dans les moteurs de recherche discovery: follow_recommendations: Suivre les recommandations preamble: Faire apparaître un contenu intéressant est essentiel pour interagir avec de nouveaux utilisateurs qui ne connaissent peut-être personne sur Mastodonte. Contrôlez le fonctionnement des différentes fonctionnalités de découverte sur votre serveur. @@ -752,10 +771,27 @@ fr-QC: approved: Approbation requise pour s’inscrire none: Personne ne peut s’inscrire open: N’importe qui peut s’inscrire + security: + authorized_fetch: Exiger une authentification de la part des serveurs fédérés + authorized_fetch_hint: Exiger l’authentification des serveurs fédérés permet une application plus stricte des blocages définis par les utilisateurs et le serveur. Cependant, cela entraîne une baisse des performances, réduit la portée de vos réponses et peut poser des problèmes de compatibilité avec certains services fédérés. En outre, cela n’empêchera pas les acteurs déterminés d’aller chercher vos messages et comptes publics. + authorized_fetch_overridden_hint: Vous ne pouvez pas modifier ce paramètre actuellement, car il est surchargé par une variable d’environnement. + federation_authentication: Contrôle de l’authentification de la fédération title: Paramètres du serveur site_uploads: delete: Supprimer le fichier téléversé destroyed_msg: Téléversement sur le site supprimé avec succès ! + software_updates: + critical_update: Critique — veuillez mettre à jour au plus vite + description: Il est recommandé de maintenir votre installation de Mastodon à jour afin de bénéficier des derniers correctifs et des dernières fonctionnalités. Il est également essentiel de mettre à jour Mastodon rapidement dans certains cas afin d’éviter des problèmes de sécurité. Pour ces raisons, Mastodon vérifie les mises à jour toutes les 30 minutes, et vous en informera selon vos préférences de notification par e-mail. + documentation_link: En savoir plus + release_notes: Notes de mises à jour + title: Mises à jour disponibles + type: Type + types: + major: Mise à jour majeure + minor: Mise à jour mineure + patch: Mise à jour « patch » — correctifs de bugs et changements faciles à faire + version: Version statuses: account: Auteur·rice application: Application @@ -792,9 +828,24 @@ fr-QC: suspend: "%{name} a suspendu le compte de %{target}" appeal_approved: Appel soumis appeal_pending: Appel en attente + appeal_rejected: Appel rejeté system_checks: database_schema_check: message_html: Vous avez des migrations de base de données en attente. Veuillez les exécuter pour vous assurer que l'application se comporte comme prévu + elasticsearch_health_red: + message_html: Le cluster Elasticsearch n’est pas sain (statut rouge), les fonctionnalités de recherche ne sont pas disponible + elasticsearch_health_yellow: + message_html: Le cluster Elasticsearch n’est pas sain (statut jaune), il est possible que vous souhaitiez en investiguer la raison + elasticsearch_index_mismatch: + message_html: Les correspondances (mappings) des indexes Elasticsearch ne sont plus à jour. Veuillez lancer tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Voir la documentation + message_html: Votre cluster Elasticsearch a plus d’un nœud, mais Mastodon n’a pas été configuré pour les utiliser. + elasticsearch_preset_single_node: + action: Voir la documentation + message_html: Votre cluster Elasticsearch n’a qu’un seul nœud, ES_PRESET devrait avoir la valeur single_node_cluster. + elasticsearch_reset_chewy: + message_html: L’index de votre système Elasticsearch n’est plus à jour à cause d’un changement de paramètre. Veuillez lancer tootctl search deploy --reset-chewy pour le mettre à jour. elasticsearch_running_check: message_html: Impossible de se connecter à Elasticsearch. Veuillez vérifier qu’il est en cours d’exécution ou désactiver la recherche en plein texte elasticsearch_version_check: @@ -805,6 +856,18 @@ fr-QC: message_html: Vous n'avez pas défini de règles pour le serveur. sidekiq_process_check: message_html: Aucun processus Sidekiq en cours d'exécution pour la/les file(s) d'attente %{value}. Veuillez vérifier votre configuration de Sidekiq + software_version_critical_check: + action: Voir les mises à jour disponibles + message_html: Une mise à jour critique de Mastodon est disponible, veuillez mettre à jour le plus rapidement possible. + software_version_patch_check: + action: Voir les mises à jour disponibles + message_html: Une mise à jour de correction de bug de Mastodon est disponible. + upload_check_privacy_error: + action: Pour plus d'informations, cliquez ici + message_html: "Votre serveur web est mal configuré. La confidentialité de vos utilisateurs est en péril." + upload_check_privacy_error_object_storage: + action: Pour plus d'informations, cliquez ici + message_html: "Votre serveur web est mal configuré. La confidentialité de vos utilisateurs est en péril." tags: review: État du traitement updated_msg: Paramètres du hashtag mis à jour avec succès @@ -827,6 +890,7 @@ fr-QC: other: Partagé par %{count} personnes au cours de la dernière semaine title: Liens tendances usage_comparison: Partagé %{today} fois aujourd'hui, comparé à %{yesterday} hier + not_allowed_to_trend: Non autorisé à apparaître dans les tendances only_allowed: Autorisées seulement pending_review: En attente de révision preview_card_providers: @@ -911,6 +975,9 @@ fr-QC: body: "%{target} fait appel de la décision de modération émise par %{action_taken_by} le %{date} et qui était : %{type}. Cette personne a écrit :" next_steps: Vous pouvez approuver l'appel pour annuler la décision de modération, ou l'ignorer. subject: "%{username} fait appel d'une décision de modération sur %{instance}" + new_critical_software_updates: + body: Des nouvelles mises à jour critiques de Mastodon ont été publiées, vous avez sans doute envie de les appliquer dès que possible ! + subject: Des mises à jour critiques de Mastodon sont disponibles pour %{instance} ! new_pending_account: body: Les détails du nouveau compte se trouvent ci-dessous. Vous pouvez approuver ou rejeter cette demande. subject: Nouveau compte à examiner sur %{instance} (%{username}) @@ -918,6 +985,9 @@ fr-QC: body: "%{reporter} a signalé %{target}" body_remote: Quelqu’un de %{domain} a signalé %{target} subject: Nouveau signalement sur %{instance} (#%{id}) + new_software_updates: + body: De nouvelles mises à jour de Mastodon ont été publiées, vous avez sans doute envie de les appliquer ! + subject: Nouvelles mises à jour disponibles pour %{instance} ! new_trends: body: 'Les éléments suivants doivent être approuvés avant de pouvoir être affichés publiquement :' new_trending_links: @@ -947,33 +1017,37 @@ fr-QC: guide_link: https://fr.crowdin.com/project/mastodon guide_link_text: Tout le monde peut y contribuer. sensitive_content: Contenu sensible - toot_layout: Agencement des messages application_mailer: notification_preferences: Modifier les préférences de courriel salutation: "%{name}," settings: 'Changer les préférences courriel : %{link}' + unsubscribe: Se désabonner view: 'Voir :' view_profile: Voir le profil view_status: Afficher le message applications: created: Application créée avec succès destroyed: Application supprimée avec succès + logout: Se déconnecter regenerate_token: Régénérer le jeton d’accès token_regenerated: Jeton d’accès régénéré avec succès warning: Soyez prudent·e avec ces données. Ne les partagez pas ! your_token: Votre jeton d’accès auth: apply_for_account: Demander un compte - change_password: Mot de passe + captcha_confirmation: + help_html: Si vous ne pouvez pas résoudre le CAPTCHA, vous pouvez nous contacter via %{email} et nous pouvons vous aider. + hint_html: Juste une autre chose! Nous avons besoin de confirmer que vous êtes un humain (pour que nous puissions empêcher les spams!). Résolvez le CAPTCHA ci-dessous et cliquez sur "Continuer". + title: Vérification de sécurité confirmations: - wrong_email_hint: Si cette adresse courriel est incorrecte, vous pouvez la modifier dans vos paramètres de compte. + wrong_email_hint: Si cette adresse de courriel est incorrecte, vous pouvez la modifier dans vos paramètres de compte. delete_account: Supprimer le compte delete_account_html: Si vous désirez supprimer votre compte, vous pouvez cliquer ici. Il vous sera demandé de confirmer cette action. description: prefix_invited_by_user: "@%{name} vous invite à rejoindre ce serveur Mastodon !" prefix_sign_up: Inscrivez-vous aujourd’hui sur Mastodon ! suffix: Avec un compte, vous pourrez suivre des gens, publier des statuts et échanger des messages avec les utilisateur·rice·s de n'importe quel serveur Mastodon et bien plus ! - didnt_get_confirmation: Vous n’avez pas reçu les consignes de confirmation ? + didnt_get_confirmation: Vous n'avez pas reçu de lien de confirmation? dont_have_your_security_key: Vous n'avez pas votre clé de sécurité? forgot_password: Mot de passe oublié ? invalid_reset_password_token: Le lien de réinitialisation du mot de passe est invalide ou a expiré. Merci de réessayer. @@ -986,26 +1060,39 @@ fr-QC: migrate_account_html: Si vous voulez rediriger ce compte vers un autre, vous pouvez le configurer ici. or_log_in_with: Ou authentifiez-vous avec privacy_policy_agreement_html: J’ai lu et j’accepte la politique de confidentialité + progress: + confirm: Confirmez l'adresse courriel + details: Vos infos + review: Notre avis + rules: Accepter les règles providers: cas: CAS saml: SAML register: S’inscrire registration_closed: "%{instance} a désactivé les inscriptions" - resend_confirmation: Envoyer à nouveau les consignes de confirmation + resend_confirmation: Renvoyer le courriel de confirmation reset_password: Réinitialiser le mot de passe rules: + accept: Accepter + back: Retour + invited_by: 'Vous pouvez rejoindre %{domain} grâve à l''invitation reçue de:' preamble: Celles-ci sont définies et appliqués par les modérateurs de %{domain}. + preamble_invited: Avant de continuer, veuillez lire les règles de base définies par les modérateurs de %{domain}. title: Quelques règles de base. + title_invited: Vous avez été invité·e. security: Sécurité set_new_password: Définir le nouveau mot de passe setup: - email_below_hint_html: Si l’adresse de courriel ci-dessous est incorrecte, vous pouvez la modifier ici et recevoir un nouveau courriel de confirmation. - email_settings_hint_html: Le courriel de confirmation a été envoyé à %{email}. Si cette adresse de courriel n’est pas correcte, vous pouvez la modifier dans les paramètres du compte. - title: Configuration + email_below_hint_html: Vérifiez votre dossier de spam ou demandez qu’on vous le renvoie. Vous pouvez corriger votre adresse courriel si elle est incorrecte. + email_settings_hint_html: Cliquez sur le lien que nous vous avons envoyé pour vérifier %{email}. Nous vous attendrons ici. + link_not_received: Vous n'avez pas reçu de lien? + new_confirmation_instructions_sent: Vous recevrez un nouveau courriel avec votre lien de confirmation dans quelques minutes! + title: Vérifiez votre boîte de réception sign_in: - preamble_html: Connectez-vous avec vos identifiants %{domain} . Si votre compte est hébergé sur un autre serveur, vous ne pourrez pas vous connecter ici. + preamble_html: Connectez-vous avec vos identifiants sur %{domain}. Si votre compte est hébergé sur un autre serveur, vous ne pourrez pas vous connecter ici. title: Se connecter à %{domain} sign_up: + manual_review: Les inscriptions sur %{domain} passent par une revue manuelle de nos modérateurs. Pour les aider, écrivez un peu plus sur vous et pourquoi vous souhaitez créer un compte sur %{domain}. preamble: Avec un compte sur ce serveur Mastodon, vous serez en mesure de suivre toute autre personne sur le réseau, quel que soit l’endroit où son compte est hébergé. title: Mettons les choses en place pour %{domain}. status: @@ -1017,18 +1104,6 @@ fr-QC: view_strikes: Voir les sanctions précédemment appliquées à votre compte too_fast: Formulaire envoyé trop rapidement, veuillez réessayer. use_security_key: Utiliser la clé de sécurité - authorize_follow: - already_following: Vous suivez déjà ce compte - already_requested: Vous avez déjà envoyé une demande d’abonnement à ce compte - error: Malheureusement, une erreur s'est produite lors de la recherche du compte distant - follow: Suivre - follow_request: 'Vous avez demandé à suivre :' - following: 'Youpi ! Vous suivez maintenant  :' - post_follow: - close: Ou bien, vous pouvez fermer cette fenêtre. - return: Afficher le profil de l’utilisateur·ice - web: Retour à l’interface web - title: Suivre %{acct} challenge: confirm: Continuer hint_html: "Astuce : Nous ne vous demanderons plus votre mot de passe pour la prochaine heure." @@ -1105,6 +1180,10 @@ fr-QC: your_appeal_rejected: Votre appel a été rejeté domain_validator: invalid_domain: n’est pas un nom de domaine valide + edit_profile: + 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 errors: '400': La demande que vous avez soumise est invalide ou mal formée. '403': Vous n’avez pas accès à cette page. @@ -1185,8 +1264,6 @@ fr-QC: index: hint: Ce filtre s'applique à la sélection de messages individuels, indépendamment d'autres critères. Vous pouvez ajouter plus de messages à ce filtre à partir de l'interface Web. title: Messages filtrés - footer: - trending_now: Tendance en ce moment generic: all: Tous all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ fr-QC: all_matching_items_selected_html: one: "%{count} élément correspondant à votre recherche est sélectionné." other: L'ensemble des %{count} éléments correspondant à votre recherche est sélectionné. + cancel: Annuler changes_saved_msg: Les modifications ont été enregistrées avec succès ! + confirm: Confirmer copy: Copier delete: Supprimer deselect: Tout déselectionner @@ -1209,24 +1288,62 @@ fr-QC: validation_errors: one: Quelque chose ne va pas ! Veuillez vérifiez l’erreur ci-dessous other: Certaines choses ne vont pas ! Veuillez vérifier les %{count} erreurs ci-dessous - html_validator: - invalid_markup: 'contient un balisage HTML invalide: %{error}' imports: errors: + empty: Fichier CSV vide + incompatible_type: Incompatible avec le type d’import sélectionné invalid_csv_file: 'Fichier CSV non valide. Erreur : %{error}' over_rows_processing_limit: contient plus de %{count} lignes + too_large: Fichier trop lourd + failures: Échecs + imported: Importé + mismatched_types_warning: Il semble que vous avez sélectionné le mauvais type pour cet import, veuillez vérifier à nouveau. modes: merge: Fusionner merge_long: Garder les enregistrements existants et ajouter les nouveaux overwrite: Écraser overwrite_long: Remplacer les enregistrements actuels par les nouveaux + overwrite_preambles: + blocking_html: Vous allez remplacer votre liste de blocages par jusqu'à %{total_items} comptes tirés de %{filename}. + bookmarks_html: Vous allez remplacer vos signets par jusqu'à %{total_items} posts tirés de %{filename}. + domain_blocking_html: Vous allez remplacer votre liste de blocages de domaines par jusqu'à %{total_items} domaines tirés de %{filename}. + following_html: Vous allez suivre jusqu’à %{total_items} comptes depuis %{filename} et arrêter de suivre n’importe qui d’autre. + lists_html: Vous allez remplacer vos listes par le contenu de %{filename}. Jusqu'à %{total_items} comptes seront ajoutés à de nouvelles listes. + muting_html: Vous allez remplacer votre liste de comptes masqués par jusqu'à %{total_items} comptes tirés de %{filename}. + preambles: + blocking_html: Vous allez bloquer jusqu'à %{total_items} comptes tirés de %{filename}. + bookmarks_html: Vous allez ajouter jusqu'à %{total_items} messages de %{filename} à vos signets. + domain_blocking_html: Vous allez bloquer jusqu'à %{total_items} domaines tirés de %{filename}. + following_html: Vous allez suivre jusqu'à %{total_items} comptes tirés de %{filename}. + lists_html: Vous allez ajouter jusqu'à %{total_items} comptes depuis %{filename} à vos listes. De nouvelles listes seront créées s'il n'y a aucune liste à laquelle les ajouter. + muting_html: Vous allez masquer jusqu'à %{total_items} comptes tirés de %{filename}. preface: Vous pouvez importer certaines données que vous avez exporté d’un autre serveur, comme une liste des personnes que vous suivez ou bloquez sur votre compte. + recent_imports: Importations récentes + states: + finished: Terminé + in_progress: En cours + scheduled: Planifié + unconfirmed: Non confirmé + status: Statut success: Vos données ont été importées avec succès et seront traitées en temps et en heure + time_started: Démarré le + titles: + blocking: En cours d’importation des comptes bloqués + bookmarks: En cours d’importation des signets + domain_blocking: En cours d’importation des domaines bloqués + following: En cours d’importation des comptes suivis + lists: En cours d’importation des listes + muting: En cours d’importation des comptes masqués + type: Type d’importation + type_groups: + constructive: Abonnements et signets + destructive: Blocages et masquages types: blocking: Liste de comptes bloqués bookmarks: Marque-pages domain_blocking: Liste des serveurs bloqués following: Liste d’utilisateur·rice·s suivi·e·s + lists: Listes muting: Liste d’utilisateur·rice·s que vous masquez upload: Importer invites: @@ -1265,6 +1382,21 @@ fr-QC: failed_sign_in_html: Tentative de connexion échouée avec %{method} de %{ip} (%{browser}) successful_sign_in_html: Connexion réussie avec %{method} de %{ip} (%{browser}) title: Historique d'authentification + mail_subscriptions: + unsubscribe: + action: Oui, me désabonner + complete: Désabonné·e + confirmation_html: Voulez-vous vraiment vous désabonner des %{type} de la part de Mastodon installés sur %{domain} vers votre adresse %{email}? Vous pouvez toujours vous réabonner à partir de vos paramètres de notification par courriel. + emails: + notification_emails: + favourite: courriels de notifications de favoris + follow: courriels de notifications d’abonnements + follow_request: courriels de demandes d’abonnements + mention: courriels de notifications de mentions + reblog: courriels de notifications de boost + resubscribe_html: Si vous vous êtes désabonné·e par erreur, vous pouvez vous réinscrire à partir de vos paramètres de notification par courriel. + success_html: Vous ne serez plus inscrits aux %{type} de Mastodon installés sur %{domain} à votre adresse %{email}. + title: Se désabonner media_attachments: validations: images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images @@ -1344,6 +1476,7 @@ fr-QC: update: subject: "%{name} a modifié un message" notifications: + administration_emails: Notifications par e-mail de l’admin email_events: Événements pour les notifications par courriel email_events_hint: 'Sélectionnez les événements pour lesquels vous souhaitez recevoir des notifications :' other_settings: Autres paramètres de notifications @@ -1380,12 +1513,22 @@ fr-QC: expired: Ce sondage est déjà terminé invalid_choice: L'option de vote choisie n'existe pas over_character_limit: ne peuvent être plus long que %{max} caractères chacun + 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 preferences: other: Autre posting_defaults: Paramètres de publication par défaut public_timelines: Fils publics + privacy: + hint_html: "Personnalisez la façon dont votre profil et vos messages peuvent être découverts. Mastodon peut vous aider à atteindre un public plus large lorsque certains paramètres sont activés. Prenez le temps de les examiner pour vous assurer qu’ils sont configurés comme vous le souhaitez." + privacy: Confidentialité + privacy_hint_html: Contrôlez ce que vous souhaitez divulguer. Les gens découvrent des profils intéressants en parcourant ceux suivis par d’autres personnes et des applications sympas en voyant lesquelles sont utilisées par d’autres pour publier des messages, mais vous préférez peut-être ne pas dévoiler ces informations. + reach: Portée + reach_hint_html: Contrôlez si vous souhaitez être découvert et suivi par de nouvelles personnes. Voulez-vous que vos publications apparaissent sur l’écran Explorer ? Voulez-vous que d’autres personnes vous voient dans leurs recommandations de suivi ? Souhaitez-vous approuver automatiquement tous les nouveaux abonnés ou avoir un contrôle granulaire sur chacun d’entre eux ? + search: Recherche + search_hint_html: Contrôlez la façon dont vous voulez être retrouvé. Voulez-vous que les gens vous trouvent selon ce que vous avez publié publiquement ? Voulez-vous que des personnes extérieures à Mastodon trouvent votre profil en faisant des recherches sur le web ? N’oubliez pas que l’exclusion totale de tous les moteurs de recherche ne peut être garantie pour les informations publiques. + title: Vie privée et visibilité privacy_policy: title: Politique de confidentialité reactions: @@ -1396,8 +1539,9 @@ fr-QC: activity: Activité du compte confirm_follow_selected_followers: Voulez-vous vraiment suivre les abonné⋅e⋅s sélectionné⋅e⋅s ? confirm_remove_selected_followers: Voulez-vous vraiment supprimer les abonné⋅e⋅s sélectionné⋅e⋅s ? - confirm_remove_selected_follows: Voulez-vous vraiment suivre les abonnements sélectionnés ? - dormant: Dormant + confirm_remove_selected_follows: Voulez-vous vraiment supprimer les abonnements sélectionnés ? + dormant: Inactif + follow_failure: Impossibilité de suivre certains des comptes sélectionnés. follow_selected_followers: Suivre les abonné·e·s sélectionné·e·s followers: Abonné·e following: Abonnement @@ -1437,6 +1581,7 @@ fr-QC: electron: Electron firefox: Firefox generic: Navigateur inconnu + huawei_browser: Navigateur Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1591,7 @@ fr-QC: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Navigateur inconnu weibo: Weibo current_session: Session courante description: "%{browser} sur %{platform}" @@ -1458,9 +1604,10 @@ fr-QC: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: système inconnu + unknown_platform: Plateforme inconnue windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1494,8 +1641,8 @@ fr-QC: statuses: attached: audio: - one: "%{count} audio" - other: "%{count} audio" + one: "%{count} fichier audio" + other: "%{count} fichiers audio" description: 'Attaché : %{attached}' image: one: "%{count} image" @@ -1531,7 +1678,6 @@ fr-QC: show_newer: Plus récents show_older: Plus anciens show_thread: Afficher le fil de discussion - sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation title: "%{name} : « %{quote} »" visibilities: direct: Direct @@ -1577,8 +1723,6 @@ fr-QC: min_reblogs: Conserver les messages partagés au moins min_reblogs_hint: Ne supprime aucun de vos messages qui ont été partagés au moins ce nombre de fois. Laisser vide pour supprimer les messages indépendamment de leur nombre de partages stream_entries: - pinned: Message épinglé - reblogged: a partagé sensitive_content: Contenu sensible strikes: errors: @@ -1594,6 +1738,11 @@ fr-QC: default: "%d %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Le quota d’utilisation du service de traduction à l’échelle du serveur a été dépassé. + too_many_requests: Il y a eu trop de requêtes au service de traduction récemment. two_factor_authentication: add: Ajouter disable: Désactiver @@ -1673,13 +1822,18 @@ fr-QC: title: Bienvenue à bord, %{name} ! users: follow_limit_reached: Vous ne pouvez pas suivre plus de %{limit} personnes + go_to_sso_account_settings: Accédez aux paramètres du compte de votre fournisseur d'identité invalid_otp_token: Le code d’authentification à deux facteurs est invalide otp_lost_help_html: Si vous perdez accès aux deux, vous pouvez contacter %{email} seamless_external_login: Vous êtes connecté via un service externe, donc les paramètres concernant le mot de passe et le courriel ne sont pas disponibles. signed_in_as: 'Connecté·e en tant que :' verification: - explanation_html: 'Vous pouvez vous vérifier en tant que propriétaire des liens dans les métadonnées de votre profil. Pour cela, le site web lié doit contenir un lien vers votre profil Mastodon. Le lien de retour doit avoir un attribut rel="me" . Le texte du lien n’a pas d’importance. Voici un exemple :' + extra_instructions_html: Astuce: Le lien sur votre site Web peut être invisible. La partie importante est rel="me" qui évite d’autres liens provenant de contenu générés par des utilisateurs tiers d'être pris en compte. Vous pouvez même utiliser une balise link dans l’en-tête de la page au lieu de a, mais le HTML doit être accessible sans avoir besoin d’exécuter du JavaScript. + here_is_how: Voici comment + hint_html: "La vérification de son profil sur Mastodon est accessible à tous. Elle s’appuie sur des standards ouverts du web, gratuits aujourd’hui et pour toujours. Tout ce dont vous avez besoin, c’est d’un site web personnel avec lequel les gens vous reconnaissent. Lorsque vous ajoutez un lien depuis votre profil, nous vérifierons que le site web renvoie à son tour à votre profil Mastodon et montrerons un indicateur visuel à côté du lien si c’est le cas." + instructions_html: Copiez et collez le code ci-dessous dans le code HTML de votre site web. Ajoutez ensuite l’adresse de votre site dans l’un des champs supplémentaires de votre profil à partir de l‘onglet "Modifier le profil" et enregistrez les modifications. verification: Vérification + verified_links: Vos liens vérifiés webauthn_credentials: add: Ajouter une nouvelle clé de sécurité create: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 278fc9e777..821ef39dbe 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -63,7 +63,7 @@ fr: disabled: Gelé display_name: Nom affiché domain: Domaine - edit: Éditer + edit: Modifier email: Adresse de courriel email_status: État du courriel enable: Dégeler @@ -91,6 +91,7 @@ fr: moderation: active: Actifs all: Tous + disabled: Désactivé pending: En cours de traitement silenced: Limité suspended: Suspendus @@ -124,8 +125,8 @@ fr: removed_header_msg: L’image d’en-tête de %{username} a été supprimée avec succès resend_confirmation: already_confirmed: Cet·te utilisateur·rice est déjà confirmé·e - send: Renvoyer un courriel de confirmation - success: Courriel de confirmation envoyé avec succès ! + send: Renvoyer le lien de confirmation + success: La confirmation a bien été envoyée ! reset: Réinitialiser reset_password: Réinitialiser le mot de passe resubscribe: Se réabonner @@ -133,6 +134,7 @@ fr: search: Rechercher search_same_email_domain: Autres utilisateurs·trices avec le même domaine de courriel search_same_ip: Autres utilisateur·rice·s avec la même IP + security: Sécurité security_measures: only_password: Mot de passe uniquement password_and_2fa: Mot de passe et A2F @@ -307,6 +309,7 @@ fr: unpublish: Retirer l'annonce unpublished_msg: L’annonce a été dépubliée avec succès ! updated_msg: L’annonce a été mise à jour avec succès ! + critical_update_pending: Mise à jour critique en attente custom_emojis: assign_category: Attribuer une catégorie by_domain: Domaine @@ -380,6 +383,15 @@ fr: undo: Supprimer de la liste blanche domain_blocks: add_new: Bloquer un nouveau domaine + confirm_suspension: + cancel: Annuler + confirm: Suspendre + permanent_action: Annuler la suspension ne restaure aucune donnée ou relation. + preamble_html: Vous êtes sur le point de suspendre %{domain} et ses sous-domaines. + remove_all_data: Cela supprimera de votre serveur tous les contenus, médias et données de profil pour les comptes de votre serveur. + stop_communication: Votre serveur cessera de communiquer avec ces serveurs. + title: Confirmer le blocage du domaine pour %{domain} + undo_relationships: Cela annulera toute relation de suivi entre les comptes de ces serveurs et le vôtre. created_msg: Le blocage de domaine est désormais activé destroyed_msg: Le blocage de domaine a été désactivé domain: Domaine @@ -427,6 +439,7 @@ fr: resolve: Résoudre le domaine title: Nouveau blocage de domaine de courriel no_email_domain_block_selected: Aucun blocage de domaine de courriel n'a été modifié car aucun n'a été sélectionné + not_permitted: Non autorisé resolved_dns_records_hint_html: Le nom de domaine est relié aux domaines MX suivants, qui ont la responsabilité ultime d'accepter les courriels. Bloquer un domaine MX empêchera les inscriptions à partir de toute adresse courriel utilisant le même domaine MX, même si le nom de domaine affiché est différent. Veillez à ne pas bloquer les fournisseurs de messagerie d'envergure. resolved_through_html: Résolu par %{domain} title: Blocage de domaines de courriel @@ -473,6 +486,7 @@ fr: content_policies: comment: Note interne description_html: Vous pouvez définir des politiques de contenu qui seront appliquées à tous les comptes de ce domaine et à tous ses sous-domaines. + limited_federation_mode_description_html: Vous pouvez choisir d'autoriser la fédération avec ce domaine. policies: reject_media: Rejeter les médias reject_reports: Rejeter les signalements @@ -585,11 +599,13 @@ fr: assign_to_self: Me l’assigner assigned: Modérateur assigné by_target_domain: Domaine du compte signalé + cancel: Annuler category: Catégorie category_description_html: La raison pour laquelle ce compte et/ou ce contenu a été signalé sera citée dans la communication avec le compte signalé comment: none: Aucun comment_description_html: 'Pour fournir plus d''informations, %{name} a écrit :' + confirm: Confirmer confirm_action: Confirmer l'action de modération contre @%{acct} created_at: Signalé delete_and_resolve: Supprimer les messages @@ -725,6 +741,9 @@ fr: branding: preamble: L'image de marque de votre serveur la différencie des autres serveurs du réseau. Ces informations peuvent être affichées dans nombre d'environnements, tels que l'interface web de Mastodon, les applications natives, dans les aperçus de liens sur d'autres sites Web et dans les applications de messagerie, etc. C'est pourquoi il est préférable de garder ces informations claires, courtes et concises. title: Thème + captcha_enabled: + desc_html: Ceci se base sur des scripts externes venant de hCaptcha, ce qui peut engendrer des soucis de sécurité et de confidentialité. De plus, cela peut rendre l'inscription beaucoup moins accessible pour certaines personnes (comme les personnes handicapées). Pour ces raisons, veuillez envisager des mesures alternatives telles que l'inscription sur acceptation ou invitation. + title: Exiger que les nouveaux utilisateurs résolvent un CAPTCHA pour confirmer leur compte content_retention: preamble: Contrôle comment le contenu créé par les utilisateurs est enregistré et stocké dans Mastodon. title: Rétention du contenu @@ -752,10 +771,27 @@ fr: approved: Approbation requise pour s’inscrire none: Personne ne peut s’inscrire open: N’importe qui peut s’inscrire + security: + authorized_fetch: Exiger une authentification de la part des serveurs fédérés + authorized_fetch_hint: Exiger l’authentification des serveurs fédérés permet une application plus stricte des blocages définis par les utilisateurs et le serveur. Cependant, cela entraîne une baisse des performances, réduit la portée de vos réponses et peut poser des problèmes de compatibilité avec certains services fédérés. En outre, cela n’empêchera pas les acteurs déterminés d’aller chercher vos messages et comptes publics. + authorized_fetch_overridden_hint: Vous ne pouvez pas modifier ce paramètre actuellement, car il est surchargé par une variable d’environnement. + federation_authentication: Contrôle de l’authentification de la fédération title: Paramètres du serveur site_uploads: delete: Supprimer le fichier téléversé destroyed_msg: Téléversement sur le site supprimé avec succès ! + software_updates: + critical_update: Critique — veuillez mettre à jour au plus vite + description: Il est recommandé de maintenir votre installation de Mastodon à jour afin de bénéficier des derniers correctifs et des dernières fonctionnalités. Il est également essentiel de mettre à jour Mastodon rapidement dans certains cas afin d’éviter des problèmes de sécurité. Pour ces raisons, Mastodon vérifie les mises à jour toutes les 30 minutes, et vous en informera selon vos préférences de notification par e-mail. + documentation_link: En savoir plus + release_notes: Notes de mises à jour + title: Mises à jour disponibles + type: Type + types: + major: Mise à jour majeure + minor: Mise à jour mineure + patch: Mise à jour « patch » — correctifs de bugs et changements faciles à faire + version: Version statuses: account: Auteur·rice application: Application @@ -792,9 +828,24 @@ fr: suspend: "%{name} a suspendu le compte de %{target}" appeal_approved: Appel soumis appeal_pending: Appel en attente + appeal_rejected: Appel rejeté system_checks: database_schema_check: message_html: Vous avez des migrations de base de données en attente. Veuillez les exécuter pour vous assurer que l'application se comporte comme prévu + elasticsearch_health_red: + message_html: Le cluster Elasticsearch n’est pas sain (statut rouge), les fonctionnalités de recherche ne sont pas disponible + elasticsearch_health_yellow: + message_html: Le cluster Elasticsearch n’est pas sain (statut jaune), il est possible que vous souhaitiez en investiguer la raison + elasticsearch_index_mismatch: + message_html: Les correspondances (mappings) des indexes Elasticsearch ne sont plus à jour. Veuillez lancer tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Voir la documentation + message_html: Votre cluster Elasticsearch a plus d’un nœud, mais Mastodon n’a pas été configuré pour les utiliser. + elasticsearch_preset_single_node: + action: Voir la documentation + message_html: Votre cluster Elasticsearch n’a qu’un seul nœud, ES_PRESET devrait avoir la valeur single_node_cluster. + elasticsearch_reset_chewy: + message_html: L’index de votre système Elasticsearch n’est plus à jour à cause d’un changement de paramètre. Veuillez lancer tootctl search deploy --reset-chewy pour le mettre à jour. elasticsearch_running_check: message_html: Impossible de se connecter à Elasticsearch. Veuillez vérifier qu’il est en cours d’exécution ou désactiver la recherche en plein texte elasticsearch_version_check: @@ -805,6 +856,18 @@ fr: message_html: Vous n'avez pas défini de règles pour le serveur. sidekiq_process_check: message_html: Aucun processus Sidekiq en cours d'exécution pour la/les file(s) d'attente %{value}. Veuillez vérifier votre configuration de Sidekiq + software_version_critical_check: + action: Voir les mises à jour disponibles + message_html: Une mise à jour critique de Mastodon est disponible, veuillez mettre à jour le plus rapidement possible. + software_version_patch_check: + action: Voir les mises à jour disponibles + message_html: Une mise à jour de correction de bug de Mastodon est disponible. + upload_check_privacy_error: + action: Pour plus d'informations, cliquez ici + message_html: "Votre serveur web est mal configuré. La confidentialité de vos utilisateurs est en péril." + upload_check_privacy_error_object_storage: + action: Pour plus d'informations, cliquez ici + message_html: "Votre serveur web est mal configuré. La confidentialité de vos utilisateurs est en péril." tags: review: État du traitement updated_msg: Paramètres du hashtag mis à jour avec succès @@ -827,6 +890,7 @@ fr: other: Partagé par %{count} personnes au cours de la dernière semaine title: Liens tendances usage_comparison: Partagé %{today} fois aujourd'hui, comparé à %{yesterday} hier + not_allowed_to_trend: Non autorisé à apparaître dans les tendances only_allowed: Autorisées seulement pending_review: En attente de révision preview_card_providers: @@ -841,7 +905,7 @@ fr: description_html: Voici les messages dont votre serveur a connaissance qui sont beaucoup partagés et mis en favoris en ce moment. Cela peut aider vos utilisateur⋅rice⋅s, néophytes comme aguerri⋅e⋅s, à trouver plus de comptes à suivre. Aucun message n'est publiquement affiché tant que vous n'en avez pas approuvé l'auteur⋅rice, et seulement si icellui permet que son compte soit suggéré aux autres. Vous pouvez également autoriser ou rejeter les messages individuellement. disallow: Proscrire le message disallow_account: Proscrire l'auteur·rice - no_status_selected: Aucune publication en tendance n'a été changée car aucune n'a été sélectionnée + no_status_selected: Aucun message tendance n'a été modifié car aucun n'était sélectionné not_discoverable: L'auteur⋅rice n'a pas choisi de pouvoir être découvert⋅e shared_by: one: Partagé ou ajouté aux favoris une fois @@ -911,6 +975,9 @@ fr: body: "%{target} fait appel de la décision de modération émise par %{action_taken_by} le %{date} et qui était : %{type}. Cette personne a écrit :" next_steps: Vous pouvez approuver l'appel pour annuler la décision de modération, ou l'ignorer. subject: "%{username} fait appel d'une décision de modération sur %{instance}" + new_critical_software_updates: + body: Des nouvelles mises à jour critiques de Mastodon ont été publiées, vous avez sans doute envie de les appliquer dès que possible ! + subject: Des mises à jour critiques de Mastodon sont disponibles pour %{instance} ! new_pending_account: body: Les détails du nouveau compte se trouvent ci-dessous. Vous pouvez approuver ou rejeter cette demande. subject: Nouveau compte à examiner sur %{instance} (%{username}) @@ -918,6 +985,9 @@ fr: body: "%{reporter} a signalé %{target}" body_remote: Quelqu’un de %{domain} a signalé %{target} subject: Nouveau signalement sur %{instance} (#%{id}) + new_software_updates: + body: De nouvelles mises à jour de Mastodon ont été publiées, vous avez sans doute envie de les appliquer ! + subject: Nouvelles mises à jour disponibles pour %{instance} ! new_trends: body: 'Les éléments suivants doivent être approuvés avant de pouvoir être affichés publiquement :' new_trending_links: @@ -938,7 +1008,7 @@ fr: remove: Détacher l'alias appearance: advanced_web_interface: Interface web avancée - advanced_web_interface_hint: 'Si vous voulez utiliser toute la largeur de votre écran, l’interface web avancée vous permet de configurer plusieurs colonnes différentes pour voir autant d’informations que vous le souhaitez en même temps : Accueil, notifications, fil public fédéré, un nombre illimité de listes et hashtags.' + advanced_web_interface_hint: 'Si vous voulez utiliser toute la largeur de votre écran, l’interface web avancée vous permet de configurer plusieurs colonnes différentes pour voir autant d’informations que vous le souhaitez en même temps : Accueil, notifications, fil fédéré, un nombre illimité de listes et hashtags.' animations_and_accessibility: Animations et accessibilité confirmation_dialogs: Dialogues de confirmation discovery: Découverte @@ -947,24 +1017,28 @@ fr: guide_link: https://fr.crowdin.com/project/mastodon guide_link_text: Tout le monde peut y contribuer. sensitive_content: Contenu sensible - toot_layout: Agencement des messages application_mailer: notification_preferences: Modifier les préférences de courriel salutation: "%{name}," settings: 'Changer les préférences courriel : %{link}' + unsubscribe: Se désabonner view: 'Voir :' view_profile: Voir le profil view_status: Afficher le message applications: created: Application créée avec succès destroyed: Application supprimée avec succès + logout: Se déconnecter regenerate_token: Régénérer le jeton d’accès token_regenerated: Jeton d’accès régénéré avec succès warning: Soyez prudent·e avec ces données. Ne les partagez pas ! your_token: Votre jeton d’accès auth: apply_for_account: Demander un compte - change_password: Mot de passe + captcha_confirmation: + help_html: Si vous avez des problèmes pour résoudre le CAPTCHA, vous pouvez nous contacter via %{email} et nous pourrons vous aider. + hint_html: Encore une chose ! Nous avons besoin de confirmer que vous êtes un humain (c'est pour que nous puissions empêcher les spams !). Résolvez le CAPTCHA ci-dessous et cliquez sur "Continuer". + title: Vérification de sécurité confirmations: wrong_email_hint: Si cette adresse de courriel est incorrecte, vous pouvez la modifier dans vos paramètres de compte. delete_account: Supprimer le compte @@ -973,7 +1047,7 @@ fr: prefix_invited_by_user: "@%{name} vous invite à rejoindre ce serveur Mastodon !" prefix_sign_up: Inscrivez-vous aujourd’hui sur Mastodon ! suffix: Avec un compte, vous pourrez suivre des gens, publier des statuts et échanger des messages avec les utilisateur·rice·s de n'importe quel serveur Mastodon et bien plus ! - didnt_get_confirmation: Vous n’avez pas reçu les consignes de confirmation ? + didnt_get_confirmation: Vous n'avez pas reçu de lien de confirmation ? dont_have_your_security_key: Vous n'avez pas votre clé de sécurité? forgot_password: Mot de passe oublié ? invalid_reset_password_token: Le lien de réinitialisation du mot de passe est invalide ou a expiré. Merci de réessayer. @@ -986,26 +1060,39 @@ fr: migrate_account_html: Si vous voulez rediriger ce compte vers un autre, vous pouvez le configurer ici. or_log_in_with: Ou authentifiez-vous avec privacy_policy_agreement_html: J’ai lu et j’accepte la politique de confidentialité + progress: + confirm: Confirmez l'e-mail + details: Vos infos + review: Notre avis + rules: Accepter les règles providers: cas: CAS saml: SAML register: S’inscrire registration_closed: "%{instance} a désactivé les inscriptions" - resend_confirmation: Envoyer à nouveau les consignes de confirmation + resend_confirmation: Renvoyer le lien de confirmation reset_password: Réinitialiser le mot de passe rules: + accept: Accepter + back: Retour + invited_by: 'Vous pouvez rejoindre %{domain} grâce à l''invitation de :' preamble: Celles-ci sont définies et appliqués par les modérateurs de %{domain}. + preamble_invited: Avant de continuer, veuillez lire les règles de base définies par les modérateurs de %{domain}. title: Quelques règles de base. + title_invited: Vous avez été invité·e. security: Sécurité set_new_password: Définir le nouveau mot de passe setup: - email_below_hint_html: Si l’adresse de courriel ci-dessous est incorrecte, vous pouvez la modifier ici et recevoir un nouveau courriel de confirmation. - email_settings_hint_html: Le courriel de confirmation a été envoyé à %{email}. Si cette adresse de courriel n’est pas correcte, vous pouvez la modifier dans les paramètres du compte. - title: Configuration + email_below_hint_html: Vérifiez votre dossier de spam ou demandez qu’on vous le renvoie. Vous pouvez corriger votre adresse e-mail si elle est incorrecte. + email_settings_hint_html: Cliquez sur le lien que nous vous avons envoyé pour vérifier l’adresse %{email}. Nous vous attendons ici. + link_not_received: Vous n'avez pas reçu de lien ? + new_confirmation_instructions_sent: Vous allez recevoir un nouvel e-mail de confirmation dans quelques minutes ! + title: Vérifiez votre boîte de réception sign_in: preamble_html: Connectez-vous avec vos identifiants sur %{domain}. Si votre compte est hébergé sur un autre serveur, vous ne pourrez pas vous connecter ici. title: Se connecter à %{domain} sign_up: + manual_review: Les inscriptions sur %{domain} passent par une revue manuelle de nos modérateurs. Pour les aider, écrivez un peu plus sur vous et pourquoi vous souhaitez créer un compte sur %{domain}. preamble: Avec un compte sur ce serveur Mastodon, vous serez en mesure de suivre toute autre personne sur le réseau, quel que soit l’endroit où son compte est hébergé. title: Mettons les choses en place pour %{domain}. status: @@ -1017,18 +1104,6 @@ fr: view_strikes: Voir les sanctions précédemment appliquées à votre compte too_fast: Formulaire envoyé trop rapidement, veuillez réessayer. use_security_key: Utiliser la clé de sécurité - authorize_follow: - already_following: Vous suivez déjà ce compte - already_requested: Vous avez déjà envoyé une demande d’abonnement à ce compte - error: Malheureusement, une erreur s'est produite lors de la recherche du compte distant - follow: Suivre - follow_request: 'Vous avez demandé à suivre :' - following: 'Youpi ! Vous suivez maintenant  :' - post_follow: - close: Ou bien, vous pouvez fermer cette fenêtre. - return: Afficher le profil de l’utilisateur·ice - web: Retour à l’interface web - title: Suivre %{acct} challenge: confirm: Continuer hint_html: "Astuce : Nous ne vous demanderons plus votre mot de passe pour la prochaine heure." @@ -1105,6 +1180,10 @@ fr: your_appeal_rejected: Votre appel a été rejeté domain_validator: invalid_domain: n’est pas un nom de domaine valide + edit_profile: + 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 errors: '400': La demande que vous avez soumise est invalide ou mal formée. '403': Vous n’avez pas accès à cette page. @@ -1155,7 +1234,7 @@ fr: keywords: Mots-clés statuses: Publications individuelles statuses_hint_html: Ce filtre s'applique à la sélection de messages individuels, qu'ils correspondent ou non aux mots-clés ci-dessous. Revoir ou supprimer des messages du filtre. - title: Éditer le filtre + title: Modifier le filtre errors: deprecated_api_multiple_keywords: Ces paramètres ne peuvent pas être modifiés depuis cette application, car ils s'appliquent à plus d'un filtre de mot-clé. Utilisez une application plus récente ou l'interface web. invalid_context: Contexte invalide ou insuffisant @@ -1185,8 +1264,6 @@ fr: index: hint: Ce filtre s'applique à la sélection de messages individuels, indépendamment d'autres critères. Vous pouvez ajouter plus de messages à ce filtre à partir de l'interface Web. title: Messages filtrés - footer: - trending_now: Tendance en ce moment generic: all: Tous all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ fr: all_matching_items_selected_html: one: "%{count} élément correspondant à votre recherche est sélectionné." other: L'ensemble des %{count} éléments correspondant à votre recherche est sélectionné. + cancel: Annuler changes_saved_msg: Les modifications ont été enregistrées avec succès ! + confirm: Confirmer copy: Copier delete: Supprimer deselect: Tout déselectionner @@ -1209,24 +1288,62 @@ fr: validation_errors: one: Quelque chose ne va pas ! Veuillez vérifiez l’erreur ci-dessous other: Certaines choses ne vont pas ! Veuillez vérifier les %{count} erreurs ci-dessous - html_validator: - invalid_markup: 'contient un balisage HTML invalide: %{error}' imports: errors: + empty: Fichier CSV vide + incompatible_type: Incompatible avec le type d’import sélectionné invalid_csv_file: 'Fichier CSV non valide. Erreur : %{error}' over_rows_processing_limit: contient plus de %{count} lignes + too_large: Le fichier est trop lourd + failures: Échecs + imported: Importé + mismatched_types_warning: Il semblerait que vous avez sélectionné le mauvais type pour cet import, veuillez vérifier attentivement. modes: merge: Fusionner merge_long: Garder les enregistrements existants et ajouter les nouveaux overwrite: Écraser overwrite_long: Remplacer les enregistrements actuels par les nouveaux + overwrite_preambles: + blocking_html: Vous allez remplacer votre liste de blocage par près de %{total_items} comptes tirés de %{filename}. + bookmarks_html: Vous allez remplacer vos signets par près de %{total_items} posts tirés de %{filename}. + domain_blocking_html: Vous allez remplacer votre liste de blocage de domaines par près de %{total_items} domaines tirés de %{filename}. + following_html: Vous allez suivre jusqu’à %{total_items} comptes depuis %{filename} et arrêter de suivre n’importe qui d’autre. + lists_html: Vous allez remplacer vos listes par le contenu de %{filename}. Près de %{total_items} comptes seront ajoutés à de nouvelles listes. + muting_html: Vous allez remplacer votre liste de comptes masqués par près de %{total_items} comptes tirés de %{filename}. + preambles: + blocking_html: Vous allez bloquer près de %{total_items} comptes tirés de %{filename}. + bookmarks_html: Vous allez ajouter près de %{total_items} messages de %{filename} à vos signets. + domain_blocking_html: Vous allez bloquer près de %{total_items} domaines tirés de %{filename}. + following_html: Vous allez suivre près de %{total_items} comptes tirés de %{filename}. + lists_html: Vous allez ajouter près de %{total_items} comptes depuis %{filename} à vos listes. De nouvelles listes seront créées si besoin. + muting_html: Vous allez masquer près de %{total_items} comptes tirés de %{filename}. preface: Vous pouvez importer certaines données que vous avez exporté d’un autre serveur, comme une liste des personnes que vous suivez ou bloquez sur votre compte. + recent_imports: Récents imports + states: + finished: Terminé + in_progress: En cours + scheduled: Programmé + unconfirmed: Non confirmé + status: Statut success: Vos données ont été importées avec succès et seront traitées en temps et en heure + time_started: Démarré le + titles: + blocking: En cours d’importation des comptes bloqués + bookmarks: En cours d’importation des signets + domain_blocking: En cours d’importation des domaines bloqués + following: En cours d’importation des comptes suivis + lists: En cours d’importation des listes + muting: En cours d’importation des comptes masqués + type: Type d’import + type_groups: + constructive: Abonnements et signets + destructive: Blocages et masquages types: blocking: Liste de comptes bloqués bookmarks: Marque-pages domain_blocking: Liste des serveurs bloqués following: Liste de comptes suivis + lists: Listes muting: Liste de comptes que vous masquez upload: Importer invites: @@ -1265,6 +1382,21 @@ fr: failed_sign_in_html: Tentative de connexion échouée avec %{method} de %{ip} (%{browser}) successful_sign_in_html: Connexion réussie avec %{method} de %{ip} (%{browser}) title: Historique d'authentification + mail_subscriptions: + unsubscribe: + action: Oui, se désinscrire + complete: Désinscrit + confirmation_html: Êtes-vous sûr de vouloir vous désinscrire des %{type} de la part du Mastodon installé sur %{domain} vers votre adresse %{email}? Vous pouvez toujours vous réabonner à partir de vos paramètres de notification par e-mail. + emails: + notification_emails: + favourite: e-mails de notifications de signets + follow: e-mails de notifications d’abonnements + follow_request: e-mails de demandes d’abonnements + mention: e-mails de notifications de mentions + reblog: e-mails de notifications de boost + resubscribe_html: Si vous vous êtes désabonné par erreur, vous pouvez vous réinscrire à partir de vos paramètres de notification par e-mail. + success_html: Vous ne serez plus inscrits aux %{type} du Mastodon installé sur %{domain} à votre adresse %{email}. + title: Se désinscrire media_attachments: validations: images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images @@ -1344,6 +1476,7 @@ fr: update: subject: "%{name} a modifié un message" notifications: + administration_emails: Notifications par e-mail de l’admin email_events: Événements pour les notifications par courriel email_events_hint: 'Sélectionnez les événements pour lesquels vous souhaitez recevoir des notifications :' other_settings: Autres paramètres de notifications @@ -1380,12 +1513,22 @@ fr: expired: Ce sondage est déjà terminé invalid_choice: L'option de vote choisie n'existe pas over_character_limit: ne peuvent être plus long que %{max} caractères chacun + 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 preferences: other: Autre posting_defaults: Paramètres de publication par défaut public_timelines: Fils publics + privacy: + hint_html: "Personnalisez la façon dont votre profil et vos messages peuvent être découverts. Mastodon peut vous aider à atteindre un public plus large lorsque certains paramètres sont activés. Prenez le temps de les examiner pour vous assurer qu’ils sont configurés comme vous le souhaitez." + privacy: Confidentialité + privacy_hint_html: Contrôlez ce que vous souhaitez divulguer. Les gens découvrent des profils intéressants en parcourant ceux suivis par d’autres personnes et des applications sympas en voyant lesquelles sont utilisées par d’autres pour publier des messages, mais vous préférez peut-être ne pas dévoiler ces informations. + reach: Portée + reach_hint_html: Contrôlez si vous souhaitez être découvert et suivi par de nouvelles personnes. Voulez-vous que vos publications apparaissent sur l’écran Explorer ? Voulez-vous que d’autres personnes vous voient dans leurs recommandations de suivi ? Souhaitez-vous approuver automatiquement tous les nouveaux abonnés ou avoir un contrôle granulaire sur chacun d’entre eux ? + search: Recherche + search_hint_html: Contrôlez la façon dont vous voulez être retrouvé. Voulez-vous que les gens vous trouvent selon ce que vous avez publié publiquement ? Voulez-vous que des personnes extérieures à Mastodon trouvent votre profil en faisant des recherches sur le web ? N’oubliez pas que l’exclusion totale de tous les moteurs de recherche ne peut être garantie pour les informations publiques. + title: Vie privée et visibilité privacy_policy: title: Politique de confidentialité reactions: @@ -1398,6 +1541,7 @@ fr: confirm_remove_selected_followers: Voulez-vous vraiment supprimer les abonné⋅e⋅s sélectionné⋅e⋅s ? confirm_remove_selected_follows: Voulez-vous vraiment supprimer les abonnements sélectionnés ? dormant: Dormant + follow_failure: Impossibilité de suivre certains des comptes sélectionnés. follow_selected_followers: Suivre les abonné·e·s sélectionné·e·s followers: Abonné·e following: Abonnement @@ -1437,6 +1581,7 @@ fr: electron: Electron firefox: Firefox generic: Navigateur inconnu + huawei_browser: Navigateur Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1591,7 @@ fr: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Navigateur inconnu weibo: Weibo current_session: Session courante description: "%{browser} sur %{platform}" @@ -1458,9 +1604,10 @@ fr: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: système inconnu + unknown_platform: Plateforme inconnue windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1509,7 +1656,7 @@ fr: disallowed_hashtags: one: 'contient un hashtag désactivé : %{tags}' other: 'contient les hashtags désactivés : %{tags}' - edited_at_html: Édité le %{date} + edited_at_html: Modifié le %{date} errors: in_reply_not_found: Le message auquel vous essayez de répondre ne semble pas exister. open_in_web: Ouvrir sur le web @@ -1531,7 +1678,6 @@ fr: show_newer: Plus récents show_older: Plus anciens show_thread: Afficher le fil de discussion - sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation title: "%{name} : « %{quote} »" visibilities: direct: Direct @@ -1577,8 +1723,6 @@ fr: min_reblogs: Conserver les messages partagés au moins min_reblogs_hint: Ne supprime aucun de vos messages qui ont été partagés au moins ce nombre de fois. Laisser vide pour supprimer les messages indépendamment de leur nombre de partages stream_entries: - pinned: Message épinglé - reblogged: a partagé sensitive_content: Contenu sensible strikes: errors: @@ -1594,6 +1738,11 @@ fr: default: "%d %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Le quota d’utilisation du service de traduction à l’échelle du serveur a été dépassé. + too_many_requests: Il y a eu trop de requêtes au service de traduction récemment. two_factor_authentication: add: Ajouter disable: Désactiver l’A2F @@ -1673,13 +1822,18 @@ fr: title: Bienvenue à bord, %{name} ! users: follow_limit_reached: Vous ne pouvez pas suivre plus de %{limit} personnes + go_to_sso_account_settings: Accédez aux paramètres du compte de votre fournisseur d'identité invalid_otp_token: Le code d’authentification à deux facteurs est invalide otp_lost_help_html: Si vous perdez accès aux deux, vous pouvez contacter %{email} seamless_external_login: Vous êtes connecté via un service externe, donc les paramètres concernant le mot de passe et le courriel ne sont pas disponibles. signed_in_as: 'Connecté·e en tant que :' verification: - explanation_html: 'Vous pouvez vous vérifier en tant que propriétaire des liens dans les métadonnées de votre profil. Pour cela, le site web lié doit contenir un lien vers votre profil Mastodon. Le lien de retour doit avoir un attribut rel="me" . Le texte du lien n’a pas d’importance. Voici un exemple :' + extra_instructions_html: Astuce : Le lien sur votre site Web peut être invisible. La partie importante est rel="me" qui évite que soient pris en compte d’autres liens provenant de contenu générés par des utilisateurs tiers. Vous pouvez même utiliser une balise link dans l’en-tête de la page au lieu de a, mais le HTML doit être accessible sans avoir besoin d’exécuter du JavaScript. + here_is_how: Voici comment + hint_html: "La vérification de son profil sur Mastodon est accessible à tous. Elle s’appuie sur des standards ouverts du web, gratuits aujourd’hui et pour toujours. Tout ce dont vous avez besoin, c’est d’un site web personnel qui vous est associé dans l’esprit des gens. Lorsque vous ajoutez un lien depuis votre profil, nous vérifierons que le site web renvoie à son tour à votre profil Mastodon et montrerons un indicateur visuel à côté du lien si c’est le cas." + instructions_html: Copiez et collez le code ci-dessous dans le code HTML de votre site web. Ajoutez ensuite l’adresse de votre site dans l’un des champs supplémentaires de votre profil à partir de l‘onglet « Modifier le profil » et enregistrez les modifications. verification: Vérification + verified_links: Vos liens vérifiés webauthn_credentials: add: Ajouter une nouvelle clé de sécurité create: diff --git a/config/locales/fy.yml b/config/locales/fy.yml index 74d211e363..41ad60cf69 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -91,6 +91,7 @@ fy: moderation: active: Aktyf all: Alle + disabled: Utskeakele pending: Yn ôfwachting silenced: Beheind suspended: Utsteld @@ -124,8 +125,8 @@ fy: removed_header_msg: It fuortsmiten fan de omslachfoto fan %{username} is slagge resend_confirmation: already_confirmed: Dizze brûker is al befêstige - send: Befêstigings-e-mailberjocht opnij ferstjoere - success: Befêstigings-e-mailberjocht mei sukses ferstjoerd! + send: Befêstigingskeppeling opnij ferstjoere + success: Befêstigingskeppeling mei sukses ferstjoerd! reset: Opnij ynstelle reset_password: Wachtwurd opnij ynstelle resubscribe: Opnij abonnearje @@ -133,6 +134,7 @@ fy: search: Sykje search_same_email_domain: Oare brûkers mei itselde e-maildomein search_same_ip: Oare brûkers mei itselde IP-adres + security: Befeiliging security_measures: only_password: Allinnich wachtwurd password_and_2fa: Wachtwurd en 2FA @@ -307,6 +309,7 @@ fy: unpublish: Depublisearje unpublished_msg: Ungedien meitsjen fan publisearre meidieling is slagge! updated_msg: Bywurkjen fan meidieling slagge! + critical_update_pending: Kritike fernijing yn behanneling custom_emojis: assign_category: Kategory tawize by_domain: Domein @@ -380,6 +383,15 @@ fy: undo: Federaasje mei domein net tastean domain_blocks: add_new: Nije domeinblokkade tafoegje + confirm_suspension: + cancel: Annulearje + confirm: Utstelle + permanent_action: It útstellen ûngedien meitsje sil gjin gegevens of folchrelaasjes werstelle. + preamble_html: Jo steane op it punt om %{domain} en subdomeinen út te stellen. + remove_all_data: Dit smyt alle ynhâld, media en profylgegevens fan de accounts fan dit domein fan jo server fuort. + stop_communication: Jo server sil net langer mei dizze servers kommunisearje. + title: Domeinblokkade foar %{domain} befêstigje + undo_relationships: Dit sil elke folchrelaasje tusken de accounts fan dizze servers en dy fan jo ûngedien meitsje. created_msg: Domeinblokkade wurdt no ferwurke destroyed_msg: Domeinblokkade is ûngedien makke domain: Domein @@ -423,10 +435,11 @@ fy: mx: MX-record domain: Domein new: - create: Domain tafoegje + create: Domein tafoegje resolve: Domein opsykje title: Nije e-maildomein blokkearje no_email_domain_block_selected: Der binne gjin e-maildomeinblokkaden wizige, omdat der gjin ien selektearre waard + not_permitted: Net tastien resolved_dns_records_hint_html: De domeinnamme slacht op de folgjende MX-domeinen dy’t úteinlik ferantwurdlik binne foar it akseptearjen fan e-mail. It blokkearjen fan in MX-domein blokkearret oanmeldingen fan elk e-mailadres dat itselde MX-domein brûkt, sels as de sichtbere domeinnamme oars is. Pas op dat jo gjin grutte e-mailproviders blokkearje. resolved_through_html: Blokkearre fia %{domain} title: Blokkearre e-maildomeinen @@ -473,6 +486,7 @@ fy: content_policies: comment: Ynterne reden description_html: Jo kinne it belied bepale dat op de accounts fan dit domein en alle subdomeinen fan tapassing is. + limited_federation_mode_description_html: Jo kinne kieze oft jo federaasje mei dit domein tastean wolle. policies: reject_media: Mediabestannen wegerje reject_reports: Rapportaazjes wegerje @@ -585,11 +599,13 @@ fy: assign_to_self: Oan my tawize assigned: Tawizen moderator by_target_domain: Domein fan rapportearre account + cancel: Annulearje category: Kategory category_description_html: De reden wêrom dizze account en/of ynhâld rapportearre waard, wurdt oan it rapportearre account meidield comment: none: Gjin comment_description_html: 'Om mear ynformaasje te jaan, skreau %{name}:' + confirm: Befêstigje confirm_action: Moderaasjemaatregelen tsjin %{acct} befêstigje created_at: Rapportearre op delete_and_resolve: Berjocht fuortsmite @@ -725,6 +741,9 @@ fy: branding: preamble: De branding fan jo server lit sjen hoe’t it fan oare servers yn it netwurk ferskilt. Dizze ynformaasje wurdt op ferskate plakken toand, lykas yn de webomjouwing fan Mastodon, yn mobile apps, yn foarfertoaningen op oare websites en berjochte-apps, ensfh. Dêrom is it wichtich om de ynformaasje helder, koart en bûnich te hâlden. title: Branding + captcha_enabled: + desc_html: Dit is ôfhinklik fan eksterne scripts fan hCaptcha, wat feilichheids- en privacyrisiko’s meibringe kin. Boppe dat kin dit it registraasjeproses bot minder tagonklik meitsje foar guon (foaral handicapte) minsken. Om dizze redenen kinne jo it beste alternative maatregels oerweagje, lykas registraasje op basis fan goedkarring of op útnûging. + title: Nije brûkers moatte in CAPTCHA oplosse om harren account te befêstigjen content_retention: preamble: Tafersjoch hâlde op hoe’t berjochten en media fan brûkers op Mastodon bewarre wurde. title: Bewartermyn berjochten @@ -752,10 +771,27 @@ fy: approved: Goedkarring fereaske om te registrearje te kinnen none: Net ien kin harren registrearje open: Elkenien kin harren registrearje + security: + authorized_fetch: Ferifikaasje fan fedearre servers fereaskje + authorized_fetch_hint: Ferifikaasje fereaskje fan federearre servers, makket in striktere hanthaving fan sawol brûkersnivo as server-levelblokken mooglik. Dit giet wol ten koste fan de prestaasjes, ferminderet it berik fan jo antwurden en kin kompatibiliteitsproblemen mei guon federearre services opleverje. Boppedat sil dit net foarkomme dat tawijde spilers jo iepenbiere artikelen en accounts ophelje. + authorized_fetch_overridden_hint: Jo kinne op dit stuit dizze ynstelling net wizigje, omdat dizze oerskreaun is troch in omjouwingsfariabele. + federation_authentication: Oftwongen federaasje-autentikaasje title: Serverynstellingen site_uploads: delete: Opladen bestân fuortsmite destroyed_msg: Fuortsmiten website-oplaad slagge! + software_updates: + critical_update: Krityk — fernij sa gau as mooglik + description: It wurdt oanrekommandearre om jo Mastodon-ynstallaasje by-de-tiid te hâlden om gebrûk meitsje te kinnen fan de nijste oplossingen en funksjes. Boppe dat is it somtiden krúsjaal om Mastodon tidich by te wurkjen om feiligheidsproblemen foar te kommen. Om dizze redenen kontrolearret Mastodon elke 30 minuten fernijingen en bringt jo hjirfan op de hichte neffens jo foarkarren foar e-mailmeldingen. + documentation_link: Mear ynfo + release_notes: Utjefte-opmerkingen + title: Beskikbere fernijingen + type: Type + types: + major: Haadferzje + minor: Lytse ferzje + patch: Patchferzje – bugfixes en ienfâldich ta te passen wizigingen + version: Ferzje statuses: account: Auteur application: Tapassing @@ -792,9 +828,24 @@ fy: suspend: Account %{target} is troch %{name} útsteld appeal_approved: Beswier yntsjinne appeal_pending: Beswier yn behanneling + appeal_rejected: Beswier ôfwêzen system_checks: database_schema_check: message_html: Der binne database migraasjes yn ôfwachting. Jo moatte dizze útfiere om der foar te soargjen dat de applikaasje wurkjen bliuwt sa as it heard + elasticsearch_health_red: + message_html: Elasticsearch-cluster is net sûn (reade status), sykfunksjes binne net beskikber + elasticsearch_health_yellow: + message_html: Elasticsearch-cluster is net sûn (giele status), miskien wolle jo de reden ûndersykje + elasticsearch_index_mismatch: + message_html: Elasticsearch-yndekstawizingen binne ferâldere. Fier tootctl search deploy --only=%{value} út + elasticsearch_preset: + action: Dokumintaasje besjen + message_html: Jo Elasticsearch-cluster hat mear as ien node, mar Mastodon is net konfigurearre om se te brûken. + elasticsearch_preset_single_node: + action: Dokumintaasje besjen + message_html: Jo Elasticsearch-cluster hat mar ien node, ES_PRESET moat ynsteld wurde op single_node_cluster. + elasticsearch_reset_chewy: + message_html: Jo Elasticsearch-systeemyndeks is ferâldere fanwegen in ynstellingswiziging. Fier tootctl search deploy --reset-chewy út om it by te wurkjen. elasticsearch_running_check: message_html: Koe gjin ferbining meitsje mei Elasticsearch. Kontrolearje dat Elasticsearch útfierd wurdt of skeakelje full-text-sykjen út elasticsearch_version_check: @@ -805,6 +856,18 @@ fy: message_html: Jo hawwe foar dizze server gjin regels opsteld. sidekiq_process_check: message_html: Der draait gjin Sidekiq-proses foar de wachtrige(n) %{value}. Kontrolearje jo Sidekiq-konfiguraasje + software_version_critical_check: + action: Beskikbere fernijingen besjen + message_html: Der is in kritike fernijing foar Mastodon beskikber. Wurkje sa gau as mooglik by. + software_version_patch_check: + action: Beskikbere fernijingen besjen + message_html: Der is in Mastodon-fernijing foar in bugfix beskikber. + upload_check_privacy_error: + action: Klik hjir foar mear ynformaasje + message_html: "Jo webserver is ferkeard konfigurearre. De privacy fan jo brûkers is yn gefaar." + upload_check_privacy_error_object_storage: + action: Klik hjir foar mear ynformaasje + message_html: "Jo objektûnthâld is ferkeard konfigurearre. De privacy fan jo brûkers is yn gefaar." tags: review: Steat beoardiele updated_msg: Hashtagynstellingen mei sukses bywurke @@ -827,6 +890,7 @@ fy: other: Dizze wike troch %{count} persoanen dield title: Trending keppelingen usage_comparison: Hjoed %{today} kear dield, fergelike mei %{yesterday} kear juster + not_allowed_to_trend: Trending wurdt net tastien only_allowed: Allinnich goedkarre pending_review: Moat noch beoardiele wurde preview_card_providers: @@ -911,6 +975,9 @@ fy: body: "%{target} makket beswier tsjin in moderaasjemaatregel troch %{action_taken_by} op %{date}, oangeande %{type}. De brûker skriuwt:" next_steps: Jo kinne it beswier goedkarre om dêrmei de moderaasjemaatregel ûngedien te meitsjen, of jo kinne it ferwerpe. subject: "%{username} makket beswier tsjin in moderaasjemaatregel op %{instance}" + new_critical_software_updates: + body: Nije krityske ferzjes fan Mastodon binne frijjûn. Jo moatte sa gau as mooglik bywurkje! + subject: Kritike Mastodon-fernijingen binne beskikber foar %{instance}! new_pending_account: body: Sjoch hjirûnder de details fan it nije account. Jo kinne de oanfraach goedkarre of ôfwize. subject: Der moat in nij account op %{instance} beoardiele wurde (%{username}) @@ -918,6 +985,9 @@ fy: body: "%{reporter} hat %{target} rapportearre" body_remote: Ien fan %{domain} hat %{target} rapportearre subject: Nije rapportaazje op %{instance} (#%{id}) + new_software_updates: + body: Nije ferzjes fan Mastodon binne frijjûn. Jo wolle miskien bywurkje! + subject: Nije ferzjes fan Mastodon binne beskikber foar %{instance}! new_trends: body: 'De folgjende items moatte beoardiele wurde eardat se iepenbier toand wurde kinne:' new_trending_links: @@ -947,24 +1017,28 @@ fy: guide_link: https://crowdin.com/project/mastodon/fy guide_link_text: Elkenien kin bydrage. sensitive_content: Gefoelige ynhâld - toot_layout: Lay-out fan berjochten application_mailer: - notification_preferences: E-mailfoarkarren wizigje + notification_preferences: E-mailynstellingen wizigje salutation: "%{name}," - settings: 'E-mailfoarkarren wizigje: %{link}' + settings: 'E-mailynstellingen wizigje: %{link}' + unsubscribe: Ofmelde view: 'Besjoch:' view_profile: Profyl besjen view_status: Berjocht besjen applications: created: Oanmeitsjen tapassing slagge destroyed: Fuortsmiten tapassing slagge + logout: Ofmelde regenerate_token: Tagongskoade opnij oanmeitsje token_regenerated: Opnij oanmeitsjen tagongskoade slagge warning: Wês foarsichtich mei dizze gegevens. Diel it nea mei in oar! your_token: Jo tagongskoade auth: apply_for_account: Account oanfreegje - change_password: Wachtwurd + captcha_confirmation: + help_html: As jo problemen tsjinkomme by it oplossen fan de CAPTCHA, kinne jo kontakt mei ús opnimme fia %{email}, sadat wy jo helpe kinne. + hint_html: Noch ien ding! Jo moatte befêstigje dat jo in minske binne (dit is om de spam bûten de doar te hâlden!). Los de ûndersteande CAPTCHA op en klik op ‘Trochgean’. + title: Befeiligingskontrôle confirmations: wrong_email_hint: As it e-mailadres net korrekt is, kinne jo dat wizigje yn de accountynstellingen. delete_account: Account fuortsmite @@ -973,7 +1047,7 @@ fy: prefix_invited_by_user: "@%{name} nûget jo hjirby út om in account oan te meitsjen op dizze Mastodon-server!" prefix_sign_up: Registrearje jo hjoed noch op Mastodon! suffix: Mei in account binne jo yn steat om minsken te folgjen, berjochten te pleatsen en út te wikseljen mei minsken dy’t op oare Mastodon-servers binne en mear! - didnt_get_confirmation: Gjin befêstigingsynstruksjes ûntfongen? + didnt_get_confirmation: Gjin befêstigingskeppeling ûntfongen? dont_have_your_security_key: Hawwe jo jo befeiligingskaai net by de hân? forgot_password: Wachtwurd ferjitten? invalid_reset_password_token: De koade om jo wachtwurd opnij yn te stellen is ferrûn. Freegje in nije oan. @@ -986,26 +1060,39 @@ fy: migrate_account_html: Wannear’t jo dizze account nei in oare account trochferwize wolle, kinne jo dit hjir ynstelle. or_log_in_with: Of oanmelde mei privacy_policy_agreement_html: Ik haw it privacybelied lêzen en gean dêrmei akkoard + progress: + confirm: E-mailadres werhelje + details: Jo gegevens + review: Us beoardieling + rules: Regels akseptearje providers: cas: CAS saml: SAML register: Registrearje registration_closed: "%{instance} lit gjin nije brûkers ta" - resend_confirmation: Ferstjoer de befêstigingsynstruksjes nochris + resend_confirmation: Befêstigingskeppeling opnij ferstjoere reset_password: Wachtwurd opnij ynstelle rules: + accept: Akseptearje + back: Tebek + invited_by: 'Jo kinne jo registrearje op %{domain} mei tank oan de útnûging dy’t jo ûntfongen hawwe fan:' preamble: Dizze binne fêststeld en wurde yn stân hâlden troch de moderatoaren fan %{domain}. + preamble_invited: Eardat jo fierder gean, moatte jo earst yn de kunde komme mei de basisregels dy’t troch de moderatoaren fan %{domain} fêststeld binne. title: Inkelde basisrigels. + title_invited: Jo binne útnûge. security: Befeiliging set_new_password: Nij wachtwurd ynstelle setup: - email_below_hint_html: Wannear ûndersteand e-mailadres net kloppet, kinne jo dat hjir wizigje. Jo ûntfange dan hjirnei in befêstigings-e-mailberjocht. - email_settings_hint_html: It befêstigings-e-mailberjocht is ferstjoerd nei %{email}. Wannear’t dat e-mailadres net kloppet, kinne jo dat wizigje yn jo accountynstellingen. - title: Ynstelle + email_below_hint_html: Kontrolearje jo map Net-winske, of freegje in nije befêstigingskeppeling oan. Jo kinne jo e-mailadres wizigje as it ferkeard is. + email_settings_hint_html: Klik op de keppeling dy’t wy jo stjoerd hawwe om %{email} te ferifiearjen. Wy wachtsje wol even. + link_not_received: Gjin keppeling krigen? + new_confirmation_instructions_sent: Jo ûntfange binnen inkelde minuten in nij e-mailberjocht mei de befêstigingskeppeling! + title: Kontrolearje jo Postfek YN sign_in: preamble_html: Meld jo oan mei de oanmeldgegevens fan %{domain}. As jo account op in oare server stiet, kinne jo hjir net oanmelde. title: Oanmelde op %{domain} sign_up: + manual_review: Ynskriuwingen op %{domain} wurde hânmjittich troch de moderator beoardiele. Skriuw wat oer josels en wêrom jo in account wolle op %{domain} om ús te helpen jo registraasje te ferwurkjen. preamble: Jo kinne mei in Mastodon-account elkenien yn it netwurk folgen, wêr’t dizze persoan ek in account hat. title: Litte wy jo account op %{domain} ynstelle. status: @@ -1017,18 +1104,6 @@ fy: view_strikes: Besjoch de earder troch moderatoaren fêststelde skeiningen dy’t jo makke hawwe too_fast: Formulier is te fluch yntsjinne. Probearje it nochris. use_security_key: Befeiligingskaai brûke - authorize_follow: - already_following: Jo folgje dizze account al - already_requested: Jo hawwe al in folchfersyk nei dat account ferstjoerd - error: Spitiger, der is in flater bard by it opsykjen fan de eksterne account - follow: Folgje - follow_request: 'Jo hawwe in folchfersyk yntsjinne by:' - following: 'Slagge! Jo folgje no:' - post_follow: - close: Of jo kinne dit finster gewoan slute. - return: Profyl fan dizze brûker toane - web: Gean nei de webapp - title: "%{acct} folgje" challenge: confirm: Trochgean hint_html: "Tip: Wy freegje jo it kommende oere net mear nei jo wachtwurd." @@ -1105,6 +1180,10 @@ fy: your_appeal_rejected: Jo beswier is ôfwêzen domain_validator: invalid_domain: is in ûnjildige domeinnamme + edit_profile: + basic_information: Algemiene ynformaasje + hint_html: "Pas oan wat minsken op jo iepenbiere profyl en njonken jo berjochten sjogge. Oare minsken sille jo earder folgje en mei jo kommunisearje wannear’t jo profyl ynfolle is en jo in profylfoto hawwe." + other: Oars errors: '400': De oanfraach dy’t jo yntsjinne hawwe wie ûnjildich of fout. '403': Jo hawwe gjin tastimming om dizze side te besjen. @@ -1185,8 +1264,6 @@ fy: index: hint: Dit filter is fan tapassing om yndividuele berjochten te selektearjen, ûnôfhinklik fan oare kritearia. Jo kinne yn de webomjouwing mear berjochten oan dit filter tafoegje. title: Filtere berjochten - footer: - trending_now: Trends generic: all: Alle all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ fy: all_matching_items_selected_html: one: "%{count} item dat mei jo sykopdracht oerienkomt is selektearre." other: Alle %{count} items dy’t mei jo sykopdracht oerienkomme binne selektearre. + cancel: Annulearje changes_saved_msg: Wizigingen mei sukses bewarre! + confirm: Befêstigje copy: Kopiearje delete: Fuortsmite deselect: Alles deselektearje @@ -1209,24 +1288,62 @@ fy: validation_errors: one: Der is wat net hielendal goed! Besjoch ûndersteande flater other: Der is wat net hielendal goed! Besjoch ûndersteande %{count} flaters - html_validator: - invalid_markup: 'befettet ûnjildige HTML-opmaak: %{error}' imports: errors: + empty: Leech CSV-bestân + incompatible_type: Ynkompatibel mei it keazen ymporttype invalid_csv_file: 'Unjildich CSV-bestân. Flater: %{error}' over_rows_processing_limit: befettet mear as %{count} rigen + too_large: Bestân is te grut + failures: Flaters + imported: Ymportearre + mismatched_types_warning: It liket der op dat jo it ferkearde ymporttype selektearre hawwe, kontrolearje nochris. modes: merge: Gearfoegje merge_long: Besteande gegevens behâlde en nije tafoegje overwrite: Oerskriuwe overwrite_long: Aktuele gegevens mei de nije gegevens ferfange + overwrite_preambles: + blocking_html: Jo steane op it punt om jo blokkearlist mei mear as %{total_items} accounts fan %{filename} te ferfangen. + bookmarks_html: Jo steane op it punt om jo blêdwizers mei mear as %{total_items} artikelen fan %{filename} te ferfangen. + domain_blocking_html: Jo steane op it punt om jo domeinblokkearlist mei mear as %{total_items} domeinen fan %{filename} te ferfangen. + following_html: Jo steane op it punt om %{total_items} accounts út %{filename} te folgjen en te stopjen mei folgjen fan alle oaren. + lists_html: Jo steane op it punt jo listen te ferfangen troch ynhâld fan %{filename}. Oant %{total_items} accounts sille oan nije listen tafoege wurde. + muting_html: Jo steane op it punt om jo list mei negearre accounts mei mear as %{total_items} accounts fan %{filename} út te ferfangen. + preambles: + blocking_html: Jo steane op it punt om %{total_items} accounts fan %{filename} út te blokkearjen. + bookmarks_html: Jo steane op it punt om %{total_items} berjochten fan %{filename} út oan jo blêdwizers ta te foegjen. + domain_blocking_html: Jo steane op it punt om %{total_items} domeinen fan %{filename} út te blokkearjen. + following_html: Jo steane op it punt om %{total_items} accounts fan %{filename} út te folgjen. + lists_html: Jo steane op it punt om oant %{total_items} accounts fan %{filename} ta te foegjen oan jo listen. Nije listen wurde oanmakke as der gjin list is om oan ta te foegjen. + muting_html: Jo steane op it punt om %{total_items} accounts fan %{filename} út te negearjen. preface: Jo kinne bepaalde gegevens, lykas de minsken dy’t jo folgje of blokkearre hawwe, nei jo account op dizze server ymportearje. Jo moatte dizze gegevens wol earst op de oarspronklike server eksportearje. + recent_imports: Resinte ymports + states: + finished: Klear + in_progress: Dwaande + scheduled: Pland + unconfirmed: Net befêstige + status: Steat success: Jo gegevens binne mei sukses opladen en wurde ynkoarten ferwurke + time_started: Start op + titles: + blocking: Blokkearre accounts ymportearje + bookmarks: Blêdwizers ymportearje + domain_blocking: Blokkearre domeinen ymportearje + following: Folge accounts ymportearje + lists: Listen ymportearje + muting: Negearre accounts ymportearje + type: Ymporttype + type_groups: + constructive: Folgje ik & blêdwizers + destructive: Blokkearre & negearre types: blocking: Blokkearlist bookmarks: Blêdwizers domain_blocking: Domeinblokkearlist following: Folchlist + lists: Listen muting: Negearlist upload: Oplade invites: @@ -1265,6 +1382,21 @@ fy: failed_sign_in_html: Mislearre oanmeldbesykjen mei %{method} fan %{ip} (%{browser}) successful_sign_in_html: Mei sukses oanmeld mei %{method} fan %{ip} (%{browser}) title: Oanmeldskiednis + mail_subscriptions: + unsubscribe: + action: Ja, ôfmelde + complete: Ofmelden + confirmation_html: Binne jo wis dat jo jo ôfmelde wolle foar it ûntfangen fan %{type} fan Mastodon op %{domain} op jo e-mailadres %{email}? Jo kinne jo altyd opnij abonnearje yn jo ynstellingen foar e-mailmeldingen. + emails: + notification_emails: + favourite: e-mailmeldingen foar favoriten + follow: e-mailmeldingen foar nije folgers + follow_request: e-mailmeldingen foar folchfersiken + mention: e-mailmeldingen foar fermeldingen + reblog: e-mailmeldingen foar boosts + resubscribe_html: As jo jo mei fersin ôfmeld hawwe, kinne jo jo opnij abonnearje yn jo ynstellingen foar e-mailmeldingen. + success_html: Jo ûntfange net langer %{type} fan Mastodon op %{domain} op jo e-mailadres %{email}. + title: Ofmelde media_attachments: validations: images_and_video: In fideo kin net oan in berjocht mei ôfbyldingen keppele wurde @@ -1344,6 +1476,7 @@ fy: update: subject: "%{name} hat in berjocht bewurke" notifications: + administration_emails: E-mailmeldingen behearder email_events: E-mailmeldingen foar eveneminten email_events_hint: 'Selektearje eveneminten wêrfoar’t jo meldingen ûntfange wolle:' other_settings: Oare meldingsynstellingen @@ -1380,12 +1513,22 @@ fy: expired: De enkête is al beëinige invalid_choice: De keazen enkêteopsje bestiet net over_character_limit: kin net langer wêze as %{max} tekens + self_vote: Jo kinne net op eigen peilingen stimme too_few_options: moat mear as ien item befetsje too_many_options: kin net mear as %{max} items befetsje preferences: other: Oars posting_defaults: Standertynstellingen foar berjochten public_timelines: Iepenbiere tiidlinen + privacy: + hint_html: "Hoe wolle jo dat jo profyl en berjochten fûn wurde kinne? In ferskaat oan funksjes yn Mastodon kinne jo helpe om een grutter publyk te berikken as se ynskeakele binne. Nim de tiid om dizze ynstellingen te besjen, om der wis fan te wêzen dat se oan jo winsken foldogge." + privacy: Privacy + privacy_hint_html: Hoefolle ynformaasje wolle jo oan oare brûkers kwyt? Minsken ûntdekke ynteressante accounts en coole apps troch te besjen hokker accounts jo folgje en troch te besjen hokker app jo brûke foar it pleatsen fan berjochten. It kin lykwols sa wêze dat jo dit leaver ferburgen hâlde. + reach: Berik + reach_hint_html: Wolle jo troch nije minsken ûntdekt en folge wurde? Wolle jo dat jo berjochten op de side Ferkenne toand wurde? Wolle jo oan oare minsken Oanrekommandearre wurde en yn de brûkersgids stean? Wolle jo nije folgers automatysk akseptearje of wolle jo dy hânmjittich goedkarre kinne? + search: Sykje + search_hint_html: Hoe wolle jo fûn wurde? Wolle jo dat minsken jo fine kinne fia jo iepenbiere berjochten? Wolle jo dat minsken bûten Mastodon jo profyl fine kinne wannear’t se op it web sykje? Ferjit lykwols net dat jo iepenbiere berjochten en profyl nea folslein beskerme wurde kinnen tsjin sykmasinen. + title: Privacy en berik privacy_policy: title: Privacybelied reactions: @@ -1398,6 +1541,7 @@ fy: confirm_remove_selected_followers: Binne jo wis dat jo de selektearre folgers net mear folgje wolle? confirm_remove_selected_follows: Binne jo wis dat jo de selektearre folge accounts net mear folgje wolle? dormant: Slommerjend + follow_failure: Kin guon fan de selektearre accounts net folgje. follow_selected_followers: Selektearre folgers folgje followers: Folgers following: Folgjend @@ -1437,6 +1581,7 @@ fy: electron: Electron firefox: Firefox generic: Unbekende browser + huawei_browser: Huawei-browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1591,7 @@ fy: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Unbekende browser weibo: Weibo current_session: Aktuele sesje description: "%{browser} op %{platform}" @@ -1458,9 +1604,10 @@ fy: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: ûnbekend platfoarm + unknown_platform: Unbekend platfoarm windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1484,7 +1631,7 @@ fy: import_and_export: Ymportearje en eksportearje migrate: Accountmigraasje notifications: Meldingen - preferences: Foarkarren + preferences: Ynstellingen profile: Profyl relationships: Folgers en folgjenden statuses_cleanup: Automatysk berjochten fuortsmite @@ -1531,7 +1678,6 @@ fy: show_newer: Nijere toane show_older: Aldere toane show_thread: Petear toane - sign_in_to_participate: Meld jo oan om oan dit petear mei te dwaan title: '%{name}: "%{quote}"' visibilities: direct: Direkt @@ -1577,8 +1723,6 @@ fy: min_reblogs: Berjochten dy’t op syn minst safolle kear boost binne behâlde min_reblogs_hint: Smyt gjin berjochten dy’t op syn minst safolle kear boost binne fuort. Lit leech om berjochten likefolle it tal boosts fuort te smiten stream_entries: - pinned: Fêstsette berjocht - reblogged: boostte sensitive_content: Gefoelige ynhâld strikes: errors: @@ -1594,6 +1738,11 @@ fy: default: "%d %B %Y om %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: It brûkerskwotum foar de oersettsjinst is oer de limyt. + too_many_requests: Der binne de lêste tiid te folle fersiken west by de oersettsjinst. two_factor_authentication: add: Tafoegje disable: 2FA útskeakelje @@ -1673,13 +1822,18 @@ fy: title: Wolkom oan board %{name}! users: follow_limit_reached: Jo kinne net mear as %{limit} accounts folgje + go_to_sso_account_settings: Gean nei de accountynstellingen fan jo identiteitsprovider invalid_otp_token: Unjildige twa-stapstagongskoade otp_lost_help_html: As jo tagong ta beide kwytrekke binne, nim dan kontakt op fia %{email} seamless_external_login: Jo binne oanmeld fia in eksterne tsjinst, dêrom binne wachtwurden en e-mailynstellingen net beskikber. signed_in_as: 'Oanmeld as:' verification: - explanation_html: 'Jo kinne josels ferifiearje as de eigener fan de keppelingen yn de metadata fan jo profyl. Hjirfoar moat op de keppele website in keppeling werom nei jo Mastodon-profyl stean. Dizze keppeling moat it rel="me"-attribút befetsje. De omskriuwing fan de keppeling makket net út. Hjir is in foarbyld:' + extra_instructions_html: Tip: De keppeling op jo website kin ûnsichtber wêze. It wichtige part is rel="me" dat ympersonaasje op websites mei user-generated ynhâld foarkomt. Jo kinne sels in link-label brûke yn de header fan de side yn stee fan a, mar de HTML moat ek sûnder JavaScript tagonklik wêze. + here_is_how: Sa wurket it + hint_html: "Ferifikaasje fan jo identiteit op Mastodon is foar elkenien. It is basearre op iepen webstanderts, en is en bliuwt altyd fergees. Alles wat nedich is, is in persoanlike website dêr’t minsken jo oan werkenne kinne. Wannear’t jo fan jo profyl út nei dizze website keppelje, sille wy kontrolearje oft de website nei jo profyl weromkeppelt en dêr in fisuele yndikator fan toane." + instructions_html: Kopiearje en plak de ûndersteande koade yn de HTML fan jo website. Foegje dernei it adres fan jo website ta oan ien fan de ekstra fjilden op jo profyl op it ljepblêd ‘Profyl bewurkje’ en bewarje de wizigingen. verification: Ferifikaasje + verified_links: Jo ferifiearre keppelingen webauthn_credentials: add: Nije befeiligingskaai tafoegje create: diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 073f2bad00..527512053b 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -87,8 +87,6 @@ ga: reject: Diúltaigh remove_avatar: Bain abhatár remove_header: Bain ceanntásc - resend_confirmation: - success: Seoladh go rathúil ríomhphost deimhnithe! reset: Athshocraigh reset_password: Athshocraigh pasfhocal resubscribe: Athchláraigh @@ -96,6 +94,7 @@ ga: search: Cuardaigh security_measures: only_password: Pasfhocal amháin + password_and_2fa: Pasfhocal agus fíordheimhniú déshraithe sensitized: Marcáladh mar íogair silence: Teorannaigh silenced: Teoranta @@ -240,6 +239,7 @@ ga: status: Stádas reports: are_you_sure: An bhfuil tú cinnte? + cancel: Cealaigh category: Catagóir created_at: Tuairiscithe delete_and_resolve: Scrios postálacha @@ -322,7 +322,6 @@ ga: delete_statuses: a gcuid postálacha a scrios none: rabhadh auth: - change_password: Pasfhocal delete_account: Scrios cuntas login: Logáil isteach logout: Logáil Amach @@ -332,11 +331,6 @@ ga: status: account_status: Stádas cuntais too_fast: Cuireadh an fhoirm isteach róthapa, triail arís. - authorize_follow: - follow: Lean - post_follow: - return: Taispeáin próifíl an úsáideora - title: Lean %{acct} challenge: confirm: Lean ar aghaidh datetime: @@ -363,14 +357,6 @@ ga: title_actions: none: Rabhadh your_appeal_pending: Chuir tú achomharc isteach - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. exports: archive_takeout: date: Dáta @@ -435,8 +421,6 @@ ga: prev: Ceann roimhe seo preferences: other: Eile - posting_defaults: Posting defaults - public_timelines: Public timelines relationships: follow_selected_followers: Lean leantóirí roghnaithe followers: Leantóirí @@ -465,7 +449,6 @@ ga: ios: iOS linux: Linux mac: macOS - other: ardán anaithnid windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -505,7 +488,6 @@ ga: '63113904': 2 bhliain '7889238': 3 mhí stream_entries: - pinned: Postáil pionnáilte sensitive_content: Ábhar íogair two_factor_authentication: edit: Cuir in eagar diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 147ee63517..e620db3a78 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -95,6 +95,7 @@ gd: moderation: active: Gnìomhach all: Na h-uile + disabled: À comas pending: Ri dhèiligeadh silenced: Cuingichte suspended: À rèim @@ -122,14 +123,16 @@ gd: redownloaded_msg: Chaidh a’ phròifil aig %{username} on tùs reject: Diùlt rejected_msg: Chaidh an t-iarrtas clàraidh aig %{username} a dhiùltadh + remote_suspension_irreversible: Chaidh dàta a’ chunntais seo a sguabadh às gu buan. + remote_suspension_reversible_hint_html: Chaidh an cunntas a chur à rèim air an fhrithealaiche aca agus thèid an dàta aige a sguabadh às gu buan %{date}. Gus an dig an t-àm ud, ’s urrainn dhan fhrithealaiche chèin an cunntas aiseag fhathast gun droch bhuaidh sam bith air. Nam bu toigh leat gach dàta a’ chunntais a thoirt air falbh sa bhad, ’s urrainn dhut sin a dhèanamh gu h-ìosal. remove_avatar: Thoir air falbh an t-avatar remove_header: Thoir air falbh am bann-cinn removed_avatar_msg: Chaidh dealbh an avatar aig %{username} a thoirt air falbh removed_header_msg: Chaidh dealbh a’ bhanna-chinn aig %{username} a thoirt air falbh resend_confirmation: already_confirmed: Chaidh an cleachdaiche seo a dhearbhadh mu thràth - send: Cuir am post-d dearbhaidh a-rithist - success: Chaidh post-d dearbhaidh a chur! + send: Cuir an ceangal dearbhaidh a-rithist + success: Chaidh ceangal dearbhaidh a chur! reset: Ath-shuidhich reset_password: Ath-shuidhich am facal-faire resubscribe: Fo-sgrìobh a-rithist @@ -137,6 +140,7 @@ gd: search: Lorg search_same_email_domain: Cleachdaichean eile aig a bheil an aon àrainn puist-d search_same_ip: Cleachdaichean eile aig a bheil an t-aon IP + security: Tèarainteachd security_measures: only_password: Facal-faire a-mhàin password_and_2fa: Facal-faire ’s dà-cheumnach @@ -166,7 +170,7 @@ gd: unsubscribe: Cuir crìoch air an fho-sgrìobhadh unsuspended_msg: Chaidh an cunntas aig %{username} a chur ann an rèim a-rithist username: Ainm-cleachdaiche - view_domain: Sealladh geàrr-chunntas na h-àrainn + view_domain: Seall geàrr-chunntas na h-àrainn warn: Thoir rabhadh web: Lìon whitelisted: Ceadaichte a chùm co-nasgaidh @@ -311,6 +315,7 @@ gd: unpublish: Neo-fhoillsich unpublished_msg: Chaidh am brath-fios a dhì-fhoillseachadh! updated_msg: Chaidh am brath-fios ùrachadh! + critical_update_pending: Ùrachadh èiginneach ri dhèiligeadh custom_emojis: assign_category: Iomruin roinn-seòrsa dha by_domain: Àrainn @@ -392,6 +397,15 @@ gd: undo: Na ceadaich co-nasgadh leis an àrainn domain_blocks: add_new: Cuir bacadh àrainne ùr ris + confirm_suspension: + cancel: Sguir dheth + confirm: Cuir à rèim + permanent_action: Ma chuireas tu seo ann an rèim a-rithist, cha dèid dàta no dàimh sam bith aiseag. + preamble_html: Tha thu an impis %{domain} ’s na fo-àrainnean aige a chur à rèim. + remove_all_data: Bheir seo air falbh gach susbaint, meadhan is dàta pròifil aig cunntasan na h-àrainne seo on fhrithealaiche agad. + stop_communication: Cha dèan am frithealaiche agad conaltradh leis na frithealaichean sin tuilleadh. + title: Dearbh bacadh na h-àrainne %{domain} + undo_relationships: Brisidh seo dàimh leantainn sam bith eadar cunntasan o na frithealaichean sin is am frithealaiche agad-sa. created_msg: Tha bacadh na h-àrainne ’ga phròiseasadh destroyed_msg: Chan eil an àrainn ’ga bacadh tuilleadh domain: Àrainn @@ -404,6 +418,7 @@ gd: create: Cruthaich bacadh hint: Cha chuir bacadh na h-àrainne crìoch air cruthachadh chunntasan san stòr-dàta ach cuiridh e dòighean maorsainneachd sònraichte an sàs gu fèin-obrachail air a h-uile dàta a tha aig na cunntasan ud. severity: + desc_html: Falaichidh an cuingeachadh postaichean o chunntasan na h-àrainne seo do dhuine sam bith nach ail a’ leantainn orra. Bheir an cur à rèim air falbh gach susbaint, meadhan is dàta pròifil aig cunntasan na h-àrainne seo on fhrithealaiche agad. Tagh Chan eil gin mur eil thu ach airson faidhlichean meadhain a dhiùltadh. noop: Chan eil gin silence: Cuingich suspend: Cuir à rèim @@ -440,18 +455,22 @@ gd: resolve: Fuasgail an àrainn title: Bac àrainn puist-d ùr no_email_domain_block_selected: Cha deach bacadh àrainn puist-d sam bith atharrachadh o nach deach gin dhiubh a thaghadh + not_permitted: Chan eil seo ceadaichte resolved_dns_records_hint_html: Thèid ainm na h-àrainne fhuasgladh nan àrainnean MX a leanas agus an urra riutha-san gun gabh iad ri post-d. Ma bhacas tu àrainn MX, bacaidh seo an clàradh o sheòladh puist-d sam bith a chleachdas an aon àrainn MX fiù ’s ma bhios ainm àrainne eadar-dhealaichte ’ga sealltainn. Thoir an aire nach bac thu solaraichean puist-d mòra. resolved_through_html: Chaidh fuasgladh slighe %{domain} - title: Àrainnean puist-d ’gam bacadh + title: Bacadh àrainnean puist-d export_domain_allows: new: title: Ion-phortaich àrainnean ceadaichte no_file: Cha deach faidhle a thaghadh export_domain_blocks: import: + description_html: Tha thu an impis bacaidhean àrainne ion-phortadh. Dèan lèirmheas glè chùramach air an liosta seo, gu h-àraidh mur an do chruinnich thu fhèin an liosta seo. existing_relationships_warning: Dàimhean leantainn làithreach + private_comment_description_html: 'Airson do chuideachadh ach an tracaich thu cò às a thàinig bacaidhean a chaidh ion-phortadh, thèid am beachd prìobhaideach seo a chur ris na bacaidhean air an ion-phortadh: %{comment}' private_comment_template: Chaidh ion-phortadh o %{source} %{date} title: Ion-phortaich bacaidhean àrainne + invalid_domain_block: 'Chaidh leum a ghearradh thar bacadh àrainne no dhà ri linn mearachd: %{error}' new: title: Ion-phortaich bacaidhean àrainne no_file: Cha deach faidhle a thaghadh @@ -487,6 +506,7 @@ gd: content_policies: comment: Nòta taobh a-staigh description_html: "’S urrainn dhut poileasaidhean susbainte a mhìneachadh a thèid a chur an sàs air a h-uile cunntas on àrainn seo ’s a fo-àrainnean-se." + limited_federation_mode_description_html: "’S urrainn dhut taghadh an ceadaich thu co-nasgadh leis an àrainn seo gus nach ceadaich." policies: reject_media: Diùlt meadhanan reject_reports: Diùlt gearanan @@ -574,7 +594,7 @@ gd: pending: A’ feitheamh ri aontachadh an ath-sheachadain save_and_enable: Sàbhail ’s cuir an comas setup: Suidhich ceangal ri ath-sheachadain - signatures_not_enabled: Chan obraich ath-sheachadain mar bu chòir nuair a bhios am modh tèarainte no modh a’ cho-nasgaidh chuingichte an comas + signatures_not_enabled: Dh’fhaoidte nach obraich ath-sheachadain mar bu chòir nuair a bhios am modh tèarainte no modh a’ cho-nasgaidh chuingichte an comas status: Staid title: Ath-sheachadain report_notes: @@ -594,17 +614,23 @@ gd: mark_as_sensitive_description_html: Thèid comharra an fhrionasachd a chur ris na meadhanan sna postaichean le gearan orra agus rabhadh a chlàradh gus do chuideachadh ach am bi thu nas teinne le droch-ghiùlan on aon chunntas sam àm ri teachd. other_description_html: Seall barrachd roghainnean airson giùlan a’ chunntais a stiùireadh agus an conaltradh leis a’ chunntas a chaidh gearan a dhèanamh mu dhèidhinn a ghnàthachadh. resolve_description_html: Cha dèid gnìomh sam bith a ghabhail an aghaidh a’ chunntais le gearan air agus thèid an gearan a dhùnadh gun rabhadh a chlàradh. + silence_description_html: Chan fhaic ach an fheadhainn a tha ’ga leantainn mu thràth no a lorgas a làimh e an cunntas seo agus cuingichidh seo uiread nan daoine a ruigeas e gu mòr. Gabhaidh seo a neo-dhèanamh uair sam bith. Dùinidh seo gach gearan mun chunntas seo. + suspend_description_html: Cha ghabh an cunntas seo agus an t-susbaint gu leòr aige inntrigeadh gus an dèid a sguabadh às air deireadh na sgeòil agus cha ghabh eadar-ghabhail a dhèanamh leis. Gabhaidh seo a neo-dhèanamh am broinn 30 latha. Dùinidh seo gach gearan mun chunntas seo. actions_description_html: Socraich dè a nì thu airson an gearan seo fhuasgladh. Ma chuireas tu peanas air a’ chunntas le gearan air, gheibh iad brath air a’ phost-d mura tagh thu an roinn-seòrsa Spama. + actions_description_remote_html: Cuir romhad dè an gnìomh a ghabhas tu airson an gearan seo fhuasgladh. Cha bheir seo buaidh ach air mar a làimhsicheas am frithealaiche agadsa an cunntas cèin seo is mar a nì e conaltradh leis. add_to_report: Cuir barrachd ris a’ ghearan are_you_sure: A bheil thu cinnteach? assign_to_self: Iomruin dhomh-sa assigned: Maor iomruinte by_target_domain: Àrainn cunntas a’ ghearain + cancel: Sguir dheth category: Roinn-seòrsa category_description_html: Thèid iomradh a thoirt air adhbhar a’ ghearain mun chunntas/susbaint seo sa chonaltradh leis a’ chunntas mun a chaidh an gearan a thogail comment: none: Chan eil gin comment_description_html: 'Airson barrachd fiosrachaidh a sholar, sgrìobh %{name}:' + confirm: Dearbh + confirm_action: Dearbh gnìomh na maorsainneachd an aghaidh @%{acct} created_at: Chaidh an gearan a dhèanamh delete_and_resolve: Sguab às na postaichean forwarded: Chaidh a shìneadh air adhart @@ -621,6 +647,7 @@ gd: placeholder: Mìnich dè na ghnìomhan a chaidh a ghabhail no naidheachd sam bith eile mu dhèidhinn… title: Nòtaichean notes_description_html: Seall is sgrìobh nòtaichean do mhaoir eile is dhut fhèin san àm ri teachd + processed_msg: 'Chaidh gearan #%{id} a phròiseasadh' quick_actions_description_html: 'Gabh gnìomh luath no sgrolaich sìos a dh’fhaicinn susbaint a’ ghearain:' remote_user_placeholder: cleachdaiche cèin o %{instance} reopen: Fosgail an gearan a-rithist @@ -633,9 +660,28 @@ gd: status: Staid statuses: Susbaint le gearan statuses_description_html: Thèid iomradh a thoirt air an t-susbaint oilbheumach sa chonaltradh leis a’ chunntas mun a chaidh an gearan a thogail + summary: + action_preambles: + delete_html: 'Tha thu an impis cuid de na postaichean aig @%{acct} a thoirt air falbh. Seo na thachras:' + mark_as_sensitive_html: 'Tha thu an impis comharra a chur gu bheil cuid de na postaichean aig @%{acct} frionasach. Seo na thachras:' + silence_html: 'Tha thu an impis an cunntas aig @%{acct} a chuingeachadh. Seo na thachras:' + suspend_html: 'Tha thu an impis an cunntas aig @%{acct} a chur à rèim. Seo na thachras:' + actions: + delete_html: Thoir air falbh na postaichean oilbheumach + mark_as_sensitive_html: Cuir comharra gu bheil meadhanan nam postaichean oilbheumach frionasach + silence_html: Thèid cò ruigeas @%{acct} a chuingeachadh gu mòr air sgàth ’s nach fhaic ach an fheadhainn a bheil ’ga leantainn mu thràth no a tha a’ lorg na pròifil aca a làimh a’ phròifil is an t-susbaint aca + suspend_html: Thèid @%{acct} a chur à rèim agus cha ghabh a’ phròifil is an t-susbaint aca a ruigsinn no eadar-ghabhail + close_report: 'Cuir comharra gun deach gearan #%{id} fhuasgladh' + close_reports_html: Cuir comharra gun deach gach gearan an aghaidh @%{acct} fhuasgladh + delete_data_html: Sguab às a’ phròifil ’s an t-susbaint aig @%{acct} an ceann 30 latha mura dèid an cur an gnìomh a-rithist roimhe sin + preview_preamble_html: 'Gheibh @%{acct} rabhadh leis an t-susbaint seo:' + record_strike_html: Clàraich rabhadh an aghaidh @%{acct} airson do chuideachadh ach am bi thu nas teinne le droch-ghiùlan on chunntas seo san àm ri teachd + send_email_html: Cuir post-d rabhaidh gu @%{acct} + warning_placeholder: Adhbharan roghainneil eile air gnìomh na maorsainneachd. target_origin: Tùs cunntas a’ ghearain title: Gearanan unassign: Dì-iomruin + unknown_action_msg: 'Gnìomh nach aithne dhuinn: %{action}' unresolved: Gun fhuasgladh updated_at: Air ùrachadh view_profile: Seall a’ phròifil @@ -723,14 +769,22 @@ gd: branding: preamble: Tha branndadh an fhrithealaiche agad eadar-dhealaichte o fhrithealaichean eile san lìonra. Faodaidh gun nochd am fiosrachadh seo thar iomadh àrainneachd, can eadar-aghaidh-lìn Mhastodon, aplacaidean tùsail, ro-sheallaidhean air ceanglaichean air làraichean-lìn eile agus am broinn aplacaidean theachdaireachdan is mar sin air adhart. Air an adhbhar seo, mholamaid gun cùm thu am fiosrachadh seo soilleir is goirid. title: Branndadh + captcha_enabled: + desc_html: Tha seo an eisimeil air sgriobtaichean hCaptcha on taobh a-muigh a dh’fhaodadh a bhith ’na dhragh tèarainteachd ’s prìobhaideachd. A bharrachd air sin, nì seo an clàradh mòran nas do-ruigsinn no chuid (gu h-àraidh an fheadhainn air a bheil ciorram). Air na h-adhbharan sin, beachdaich air dòighean eile mar clàradh stèidhichte air aontachadh no cuireadh. + title: Iarr air cleachdaichean ùra gum fuasgail iad CAPTCHA gus an cunntas aca a dhearbhadh content_retention: preamble: Stiùirich mar a tha susbaint an luchd-cleachdaidh ’ga stòradh ann am Mastodon. title: Glèidheadh na susbaint + default_noindex: + desc_html: Bidh buaidh air a h-uile cleachdaiche nach do dh’atharraich an roghainn seo dhaibh fhèin + title: Thoir air falbh ro-aonta nan cleachdaichean air inneacsadh le einnseanan-luirg mar a’ bhun-roghainn discovery: follow_recommendations: Molaidhean leantainn preamble: Tha tighinn an uachdar susbainte inntinniche fìor-chudromach airson toiseach-tòiseachaidh an luchd-cleachdaidh ùr nach eil eòlach air duine sam bith air Mastodon, ma dh’fhaoidte. Stiùirich mar a dh’obraicheas gleusan an rannsachaidh air an fhrithealaiche agad. profile_directory: Eòlaire nam pròifil public_timelines: Loidhnichean-ama poblach + publish_discovered_servers: Foillsich na frithealaichean a chaidh a lorg + publish_statistics: Foillsich an stadastaireachd title: Rùrachadh trends: Treandaichean domain_blocks: @@ -745,10 +799,27 @@ gd: approved: Tha aontachadh riatanach airson clàradh none: Chan fhaod neach sam bith clàradh open: "’S urrainn do neach sam bith clàradh" + security: + authorized_fetch: Iarr dearbhadh o fhrithealaichean co-naisgte + authorized_fetch_hint: Ma dh’iarras tu dearbhadh o fhrithealaichean cho-naisgte, gheibh thu an comas gus bacaidhean èigneachadh nas teinne an dà chuid air ìre an luchd-cleachdaidh ’s an fhrithealaiche. Gidheadh, ceannaichidh tu an comas seo le dèanadas nas miosa is ruigsinn nas lugha nam freagairtean agad agus dh’fhaoidte gun èirich duilgheadasan co-chòrdalachd le cuid a sheirbheisean cho-naisgte. A bharrachd air sin, cha bhac seo an fheadhainn dian o fhaighinn nam postaichean is cunntasan poblach agad. + authorized_fetch_overridden_hint: Chan urrainn dhut an roghainn seo atharrachadh an-dràsta on a tha caochladair àrainne ’ga thar-àithneadh. + federation_authentication: Èigneachadh dearbhadh a’ cho-nasgaidh title: Roghainnean an fhrithealaiche site_uploads: delete: Sguab às am faidhle a chaidh a luchdadh suas destroyed_msg: Chaidh an luchdadh suas dhan làrach a sguabadh às! + software_updates: + critical_update: Èiginneach – ùraich cho luath ’s a ghabhas + description: Mholamaid gun cùm thu an stàladh agad de Mhastodon ùraichte ach am faigh thu buannachd às na càraidhean ’s gleusan as ùire. A bharrachd air sin, bidh e èiginneach aig amannan gun ùraich thu Mastodon gun dàil airson duilgheadasan tèarainteachd a sheachnadh. Seo as adhbhar gun doir Mastodon sùil airson ùrachaidhean gach leth-uair a thìde ’s gun cuir e brath thugad a-rèir nan roghainnean puist-d agad. + documentation_link: Barrachd fiosrachaidh + release_notes: Nòtaichean sgaoilidh + title: Ùrachaidhean a tha ri fhaighinn + type: Seòrsa + types: + major: Sgaoileadh mòr + minor: Sgaoileadh beag + patch: Sgaoileadh brèide – càraidhean aig bugaichean ’s atharraichean a tha furasta a chur an sàs + version: Tionndadh statuses: account: Ùghdar application: Aplacaid @@ -785,9 +856,24 @@ gd: suspend: Chuir %{name} an cunntas aig %{target} à rèim appeal_approved: Air ath-thagradh appeal_pending: "’Ga ath-thagradh" + appeal_rejected: Chaidh ath-thagradh a dhiùltadh system_checks: database_schema_check: message_html: Tha imrichean stòir-dhàta ri dhèiligeadh ann. Ruith iad a dhèanamh cinnteach gum bi giùlan na h-aplacaid mar a bhiodhte ’n dùil + elasticsearch_health_red: + message_html: Tha droch-shlàinte air bagaid Elasticsearch (staid dhearg), chan eil gleusan an luirg ri fhaighinn + elasticsearch_health_yellow: + message_html: Tha droch-shlàinte air bagaid Elasticsearch (staid bhuidhe), bu chòir dhut sgrùdadh carson + elasticsearch_index_mismatch: + message_html: Tha mapachaidhean nan inneacsan Elasticsearch ro shean. Ruith tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Faic an docamaideadh + message_html: Tha iomadh nòd aig a’ bhagaid Elasticsearch agad ach cha deach Mastodon a rèiteachadh gus an cleachdadh uile. + elasticsearch_preset_single_node: + action: Faic an docamaideadh + message_html: Chan eil ach aon nòd a-mhàin air a’ bhagaid Elasticsearch agad, bu chòir dhut single_node_cluster a chur air ES_PRESET. + elasticsearch_reset_chewy: + message_html: Tha inneacs siostam Elasticsearch ro shean ri linn atharrachadh roghainne. Ruith tootctl search deploy --reset-chewy airson ùrachadh. elasticsearch_running_check: message_html: Cha b’ urrainn dhuinn ceangal ri Elasticsearch. Dearbh thu bheil e a’ ruith no cuir an lorg làn-teacsa à comas elasticsearch_version_check: @@ -798,6 +884,18 @@ gd: message_html: Cha do mhìnich thu riaghailtean an fhrithealaiche fhathast. sidekiq_process_check: message_html: Chan eil pròiseas Sidekiq sam bith a ruith dhan chiutha/dha na ciuthan %{value}. Thoir sùil air an rèiteachadh Sidekiq agad + software_version_critical_check: + action: Faic na h-ùrachaidhean a tha ri fhaighinn + message_html: Tha ùrachadh èiginneach air Mastodon ri fhaighinn, ùraich cho luath ’s a ghabhas. + software_version_patch_check: + action: Faic na h-ùrachaidhean a tha ri fhaighinn + message_html: Tha ùrachadh Mastodon le càraidhean ri fhaighinn. + upload_check_privacy_error: + action: Thoir sùil an-seo airson barrachd fiosrachaidh + message_html: "Chaidh am frithealaiche agad a dhroch-rèiteachadh. Tha prìobhaideachd an luchd-cleachdaidh agad fo chunnart." + upload_check_privacy_error_object_storage: + action: Thoir sùil an-seo airson barrachd fiosrachaidh + message_html: "Chaidh stòras nan oibseactan agad a dhroch-rèiteachadh. Tha prìobhaideachd an luchd-cleachdaidh agad fo chunnart." tags: review: Dèan lèirmheas air an staid updated_msg: Chaidh roghainnean nan tagaichean hais ùrachadh @@ -822,6 +920,7 @@ gd: two: Chaidh a cho-roinneadh le %{count} rè na seachdain seo chaidh title: Ceanglaichean a’ treandadh usage_comparison: Chaidh a cho-roinneadh %{today} tura(i)s an-diugh an coimeas ri %{yesterday} an-dè + not_allowed_to_trend: Chan fhaod seo treandadh only_allowed: An fheadhainn cheadaichte a-mhàin pending_review: A’ feitheamh air lèirmheas preview_card_providers: @@ -839,10 +938,10 @@ gd: no_status_selected: Cha deach post a’ treandadh sam bith atharrachadh o nach deach gin dhiubh a thaghadh not_discoverable: Cha do chuir an t-ùghdar roimhe gun gabh a rùrachadh shared_by: - few: Chaidh a cho-roinneadh no ’na annsachd %{friendly_count} tursan - one: Chaidh a cho-roinneadh no ’na annsachd %{friendly_count} turas - other: Chaidh a cho-roinneadh no ’na annsachd %{friendly_count} turas - two: Chaidh a cho-roinneadh no ’na annsachd %{friendly_count} thuras + few: Chaidh a cho-roinneadh no a chur ris na h-annsachdan %{friendly_count} tursan + one: Chaidh a cho-roinneadh no a chur ris na h-annsachdan %{friendly_count} turas + other: Chaidh a cho-roinneadh no a chur ris na h-annsachdan %{friendly_count} turas + two: Chaidh a cho-roinneadh no a chur ris na h-annsachdan %{friendly_count} thuras title: Postaichean a’ treandadh tags: current_score: Sgòr làithreach de %{score} @@ -856,11 +955,11 @@ gd: listable: Gabhaidh a mholadh no_tag_selected: Cha deach taga sam bith atharrachadh o nach deach gin dhiubh a thaghadh not_listable: Cha dèid a mholadh - not_trendable: Cha nochd e am measg nan treandaichean + not_trendable: Na nochd sna treandaichean not_usable: Cha ghabh a chleachdadh peaked_on_and_decaying: Air a’ bhàrr %{date}, a’ crìonadh an-dràsta title: Tagaichean hais a’ treandadh - trendable: Faodaidh e nochdadh am measg nan treandaichean + trendable: Nochd sna treandaichean trending_rank: 'A’ treandadh #%{rank}' usable: Gabhaidh a chleachdadh usage_comparison: Chaidh a chleachdadh %{today} tura(i)s an-diugh an coimeas ri %{yesterday} an-dè @@ -912,6 +1011,9 @@ gd: body: 'Tha %{target} ag ath-thagradh co-dhùnadh na maorsainneachd a thug %{action_taken_by} %{date} agus ’s e %{type} a bh’ ann. Sgrìobh iad:' next_steps: "’S urrainn dhut aontachadh ris an ath-thagradh air co-dhùnadh na maorsainneachd no a leigeil seachad." subject: Tha %{username} ag ath-thagradh co-dhùnadh na maorsainneachd air %{instance} + new_critical_software_updates: + body: Chaidh tionndaidhean èiginneach ùra de Mhastodon a sgaoileadh, bu chòir dhut ùrachadh cho luath ’s a ghabhas! + subject: Tha ùrachaidhean èiginneach air Mastodon ri fhaighinn dha %{instance}! new_pending_account: body: Chì thu mion-fhiosrachadh a’ chunntais ùir gu h-ìosal. ’S urrainn dhut gabhail ris an iarrtas seo no a dhiùltadh. subject: Tha cunntas ùr air %{instance} a’ feitheamh air lèirmheas (%{username}) @@ -919,6 +1021,9 @@ gd: body: Rinn %{reporter} gearan air %{target} body_remote: Rinn cuideigin o %{domain} gearan air %{target} subject: Tha gearan ùr aig %{instance} (#%{id}) + new_software_updates: + body: Chaidh tionndaidhean ùra de Mhastodon a sgaoileadh, saoil an dèan thu ùrachadh? + subject: Tha tionndaidhean ùra de Mhastodon ri fhaighinn dha %{instance}! new_trends: body: 'Tha na nithean seo feumach air lèirmheas mus nochd iad gu poblach:' new_trending_links: @@ -948,31 +1053,37 @@ gd: guide_link: https://crowdin.com/project/mastodon guide_link_text: "’S urrainn do neach sam bith cuideachadh." sensitive_content: Susbaint fhrionasach - toot_layout: Co-dhealbhachd nam postaichean application_mailer: notification_preferences: Atharraich roghainnean a’ phuist-d salutation: "%{name}," settings: 'Atharraich roghainnean a’ phuist-d: %{link}' + unsubscribe: Cuir crìoch air an fho-sgrìobhadh view: 'Faic:' view_profile: Seall a’ phròifil view_status: Seall am post applications: created: Chaidh an t-iarrtas a chruthachadh destroyed: Chaidh an t-iarrtas a sguabadh às + logout: Clàraich a-mach regenerate_token: Ath-ghin an tòcan inntrigidh token_regenerated: Chaidh an tòcan inntrigidh ath-ghintinn warning: Bi glè chùramach leis an dàta seo. Na co-roinn le duine sam bith e! your_token: An tòcan inntrigidh agad auth: apply_for_account: Iarr cunntas - change_password: Facal-faire + captcha_confirmation: + help_html: Ma tha duilgheadas agad le fuasgladh a’ CAPTCHA, leig fios leinn air %{email} ach an cuidich sinn thu. + hint_html: Dìreach aon rud eile! Feumaidh sinn dearbhadh gu bheil thu daonna (ach am fàg sinn an spama aig an doras!). Fuasgail an CAPTCHA gu h-ìosal is briog air “Lean air adhart”. + title: Deuchainn tèarainteachd + confirmations: + wrong_email_hint: Mur eil an seòladh puist-d seo mar bu chòir, ’s urrainn dhut atharrachadh ann an roghainnean a’ chunntais. delete_account: Sguab às an cunntas delete_account_html: Nam bu mhiann leat an cunntas agad a sguabadh às, nì thu an-seo e. Thèid dearbhadh iarraidh ort. description: prefix_invited_by_user: Thug @%{name} cuireadh dhut ach am faigh thu ballrachd air an fhrithealaiche seo de Mhastodon! prefix_sign_up: Clàraich le Mastodon an-diugh! suffix: Le cunntas, ’s urrainn dhut daoine a leantainn, naidheachdan a phostadh agus conaltradh leis an luchd-chleachdaidh air frithealaiche Mastodon sam bith is a bharrachd! - didnt_get_confirmation: Nach d’fhuair thu an stiùireadh mun dearbhadh? + didnt_get_confirmation: Nach d’fhuair thu an ceangal dearbhaidh? dont_have_your_security_key: Nach eil iuchair tèarainteachd agad? forgot_password: Na dhìochuimhnich thu am facal-faire agad? invalid_reset_password_token: Tha tòcan ath-shuidheachadh an fhacail-fhaire mì-dhligheach no dh’fhalbh an ùine air. Feuch an iarr thu fear ùr. @@ -985,23 +1096,39 @@ gd: migrate_account_html: Nam bu mhiann leat an cunntas seo ath-stiùireadh gu fear eile, ’s urrainn dhut a rèiteachadh an-seo. or_log_in_with: No clàraich a-steach le privacy_policy_agreement_html: Leugh mi is tha mi ag aontachadh ris a’ phoileasaidh prìobhaideachd + progress: + confirm: Post-d an dearbhaidh + details: Am fiosrachadh agad + review: An lèirmheas againn + rules: Gabh ris na riaghailtean providers: cas: CAS saml: SAML register: Clàraich leinn registration_closed: Cha ghabh %{instance} ri buill ùra - resend_confirmation: Cuir an stiùireadh mun dearbhadh a-rithist + resend_confirmation: Cuir an ceangal dearbhaidh a-rithist reset_password: Ath-shuidhich am facal-faire rules: + accept: Gabh ris + back: Air ais + invited_by: "’S urrainn dhut ballrachd fhaighinn air %{domain} leis a’ chuireadh a fhuair thu o:" preamble: Tha iad ’gan stèidheachadh is a chur an gnìomh leis na maoir aig %{domain}. + preamble_invited: Mus lean thu air adhart, thoir an aire air na riaghailtean a shuidhich na maoir aig %{domain}. title: Riaghailtean bunasach. + title_invited: Fhuair thu cuireadh. security: Tèarainteachd set_new_password: Suidhich facal-faire ùr setup: - email_below_hint_html: Mur eil am post-d gu h-ìosal mar bu chòir, ’s urrainn dhut atharrachadh an-seo agus gheibh thu post-d dearbhaidh ùr. - email_settings_hint_html: Chaidh am post-d dearbhaidh a chur gu %{email}. Mur eil an seòladh puist-d seo mar bu chòir, ’s urrainn dhut atharrachadh ann an roghainnean a’ chunntais. - title: Suidheachadh + email_below_hint_html: Thoir sùil air pasgan an spama agad no iarr fear eile. ’S urrainn dhut an seòladh puist-d agad a chur ceart ma tha e ceàrr. + email_settings_hint_html: Briog air a’ cheangal a chuir sinn thugad a dhearbhadh %{email}. Fuirichidh sinn ort an-seo. + link_not_received: Nach d’fhuair thu ceangal? + new_confirmation_instructions_sent: Gheibh thu post-d ùr le ceangal dearbhaidh an ceann corra mionaid! + title: Thoir sùil air a’ bhogsa a-steach agad + sign_in: + preamble_html: Clàraich a-steach le do theisteas %{domain}. Ma tha an cunntas agad ’ga òstadh air frithealaiche eile, chan urrainn dhut clàradh a-steach an-seo. + title: Clàraich a-steach gu %{domain} sign_up: + manual_review: Nì na maoir againn lèirmheas a làimh air clàraidhean air %{domain}. Airson ar cuideachadh le làimhseachadh do chlàraidh, sgrìobh beagan mu do dhèidhinn agus carson a tha thu ag iarraidh cunntas air %{domain}. preamble: Le cunntas air an fhrithealaiche Mastodon seo, ’s urrainn dhut neach sam bith a leantainn air an lìonra, ge b’ e càit a bheil an cunntas aca-san ’ga òstadh. title: Suidhicheamaid %{domain} dhut. status: @@ -1013,18 +1140,6 @@ gd: view_strikes: Seall na rabhaidhean a fhuair an cunntas agad roimhe too_fast: Chaidh am foirm a chur a-null ro luath, feuch ris a-rithist. use_security_key: Cleachd iuchair tèarainteachd - authorize_follow: - already_following: Tha thu a’ leantainn a’ chunntais seo mu thràth - already_requested: Chuir thu iarrtas leantainn dhan chunntas seo mu thràth - error: Gu mì-fhortanach, thachair mearachd le lorg a’ chunntais chèin - follow: Lean - follow_request: 'Chuir thu iarrtas leantainn gu:' - following: 'Taghta! Chaidh leat a’ leantainn:' - post_follow: - close: Air neo dùin an uinneag seo. - return: Seall pròifil a’ chleachdaiche - web: Tadhail air an duilleag-lìn - title: Lean %{acct} challenge: confirm: Lean air adhart hint_html: "Gliocas: Chan iarr sinn am facal-faire agad ort a-rithist fad uair a thìde." @@ -1101,6 +1216,10 @@ gd: your_appeal_rejected: Chaidh an t-ath-thagradh agad a dhiùltadh domain_validator: invalid_domain: "– chan eil seo ’na ainm àrainne dligheach" + edit_profile: + basic_information: Fiosrachadh bunasach + hint_html: "Gnàthaich na chithear air a’ phròifil phoblach agad is ri taobh nam postaichean agad. Bidh càch nas buailtiche do leantainn agus conaltradh leat nuair a bhios tu air a’ phròifil agad a lìonadh agus dealbh rithe." + other: Eile errors: '400': Cha robh an t-iarrtas a chuir thu a-null dligheach no bha droch-chruth air. '403': Chan eil cead agad gus an duilleag seo a shealltainn. @@ -1138,7 +1257,7 @@ gd: add_new: Cuir fear ùr ris errors: limit: Bhrosnaich thu an uiread as motha de thagaichean hais mu thràth - hint_html: "Dè th’ anns na tagaichean hais brosnaichte? Thèid an sealltainn gu follaiseach air a’ phròifil phoblach agad agus ’s urrainnear na postaichean poblach agad sa bheil na tagaichean hais sònraichte sin a bhrabhsadh leotha. ’S e deagh-acainn a th’ annta airson sùil a chumail air obair chruthachail no pròiseactan fada." + hint_html: "Brosnaich na tagaichean hais as cudromaiche agad air a’ phròifil agad. ’S e deagh-acainn a th’ annta airson sùil a chumail air an obair chruthachail no na pròiseactan fada agad on a thèid na tagaichean hais brosnaichte a shealltainn gu follaiseach air a’ phròifil agad agus ’s urrainnear na postaichean agad inntrigeadh gu luath leotha." filters: contexts: account: Pròifilean @@ -1187,8 +1306,6 @@ gd: index: hint: Bidh a’ chriathrag seo an sàs air postaichean fa leth ge b’ e dè na roghainnean eile. ’S urrainn dhut barrachd phostaichean a chur ris a’ chriathrag seo leis an eadar-aghaidh-lìn. title: Postaichean criathraichte - footer: - trending_now: A’ treandadh an-dràsta generic: all: Na h-uile all_items_on_page_selected_html: @@ -1201,7 +1318,9 @@ gd: one: Chaidh %{count} nì a thaghadh a fhreagras dha na lorg thu. other: Chaidh %{count} nì a thaghadh a fhreagras dha na lorg thu. two: Chaidh %{count} nì a thaghadh a fhreagras dha na lorg thu. + cancel: Sguir dheth changes_saved_msg: Chaidh na h-atharraichean a shàbhaladh! + confirm: Dearbh copy: Dèan lethbhreac delete: Sguab às deselect: Dì-thagh na h-uile @@ -1219,24 +1338,62 @@ gd: one: Tha rud ann nach eil buileach ceart fhathast! Thoir sùil air an %{count} mhearachd gu h-ìosal other: Tha rud ann nach eil buileach ceart fhathast! Thoir sùil air an %{count} mearachd gu h-ìosal two: Tha rud ann nach eil buileach ceart fhathast! Thoir sùil air an %{count} mhearachd gu h-ìosal - html_validator: - invalid_markup: 'tha HTML markup mì-dhligheach ann: %{error}' imports: errors: + empty: Faidhle CSV falamh + incompatible_type: Chan eil e co-chòrdail le seòrsa an ion-phortaidh a thagh thu invalid_csv_file: 'Faidhle CSV mì-dhligheach. Mearachd: %{error}' over_rows_processing_limit: tha còrr is %{count} ràgh(an) ann + too_large: Tha am faidhle ro mhòr + failures: Fàilligidhean + imported: Air ion-phortadh + mismatched_types_warning: Tha coltas gun do thagh thu an seòrsa ceàrr dhan ion-phortadh seo, an toir thu sùil air? modes: merge: Co-aonaich merge_long: Cùm na reacordan a tha ann is cuir feadhainn ùr ris overwrite: Sgrìobh thairis air overwrite_long: Cuir na reacordan ùra an àite na feadhna a tha ann + overwrite_preambles: + blocking_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a chur an àite liosta nam bacaidhean agad. + bookmarks_html: Tha thu an impis suas ri %{total_items} post(aichean) o %{filename} a chur an àite nan comharra-lìn agad. + domain_blocking_html: Tha thu an impis suas ri %{total_items} àrainn(ean) o %{filename} a chur an àite liosta nam bacaidhean àrainne agad. + following_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a leantainn agus sguiridh tu a leantainn duine sam bith eile. + lists_html: Tha thu an impis susbaint %{filename} a chur an àite nan liostaichean agad. Thèid suas ri %{total_items}cunntas(an) a chur ri liostaichean ùra. + muting_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a chur an àite liosta nan cunntasan mùchte agad. + preambles: + blocking_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a bhacadh. + bookmarks_html: Tha thu an impis suas ri %{total_items} post(aichean) o %{filename} a chur ris na h-annsachdan agad. + domain_blocking_html: Tha thu an impis suas ri %{total_items} àrainn(ean) o %{filename} a bhacadh. + following_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a leantainn. + lists_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a chur ris na liostaichean agad. Thèid liostaichean ùra a chruthachadh mur eil liostaichean ann airson nan cunntasan a chur ris. + muting_html: Tha thu an impis suas ri %{total_items} cunntas(an) o %{filename} a mhùchadh. preface: "’S urrainn dhut dàta ion-phortadh a dh’às-phortaich thu o fhrithealaiche eile, can liosta nan daoine a leanas tu no a tha thu a’ bacadh." + recent_imports: Ion-phortaidhean o chionn goirid + states: + finished: Deiseil + in_progress: A’ dol air adhart + scheduled: Air an sgeideal + unconfirmed: Gun dearbhadh + status: Staid success: Chaidh an dàta agad a luchdadh suas is thèid a phròiseasadh a-nis + time_started: Chaidh a thòiseachadh aig + titles: + blocking: Ag ion-phortadh cunntasan bacte + bookmarks: Ag ion-phortadh comharran-leabhair + domain_blocking: Ag ion-phortadh àrainnean bacte + following: Ion-phortaich cunntasan ’gan leantainn + lists: Ag ion-phortadh liostaichean + muting: Ag ion-phortadh cunntasan mùchte + type: Seòrsa an ion-phortaidh + type_groups: + constructive: Leantainn ⁊ comharran-lìn + destructive: Bacadh ⁊ mùchadh types: blocking: Liosta-bhacaidh bookmarks: Comharran-lìn domain_blocking: Liosta-bhacaidh àrainnean following: Liosta dhen fheadhainn a leanas tu + lists: Liostaichean muting: Liosta a’ mhùchaidh upload: Luchdaich suas invites: @@ -1277,6 +1434,21 @@ gd: failed_sign_in_html: Oidhirp clàraidh a-steach nach deach leis le %{method} o %{ip} (%{browser}) successful_sign_in_html: Oidhirp clàraidh a-steach a shoirbhich leis le %{method} o %{ip} (%{browser}) title: Eachdraidh an dearbhaidh + mail_subscriptions: + unsubscribe: + action: Tha, cuir crìoch air an fho-sgrìobhadh + complete: Chaidh crìoch a chur air an fho-sgrìobhadh + confirmation_html: A bheil thu cinnteach nach eil thu airson %{type} fhaighinn tuilleadh o Mhastodon air %{domain} dhan post-d agad aig %{email}? ’S urrainn dhut fo-sgrìobhadh a-rithist uair sam bith o roghainnean a’ puist-d agad. + emails: + notification_emails: + favourite: puist-d le brathan mu annsachdan + follow: puist-d le brathan mu leantainn + follow_request: puist-d le brathan mu iarrtasan leantainn + mention: puist-d le brathan mu iomraidhean + reblog: puist-d le brathan mu bhrosnachaidhean + resubscribe_html: Ma chuir thu crìoch air an fho-sgrìobhadh le mearachd, ’s urrainn dhut fo-sgrìobhadh a-rithist o roghainnean a’ puist-d agad. + success_html: Chan fhaigh thu %{type} o Mhastodon air %{domain} dhan phost-d agad aig %{email} tuilleadh. + title: Cuir crìoch air an fho-sgrìobhadh media_attachments: validations: images_and_video: Chan urrainn dhut video a cheangal ri post sa bheil dealbh mu thràth @@ -1356,6 +1528,7 @@ gd: update: subject: Dheasaich %{name} post notifications: + administration_emails: Brathan puist-d na rianachd email_events: Tachartasan nam brathan puist-d email_events_hint: 'Tagh na tachartasan dhan a bheil thu airson brathan fhaighinn:' other_settings: Roghainnean eile nam brathan @@ -1392,12 +1565,22 @@ gd: expired: Tha an cunntas-bheachd air a thighinn gu crìoch invalid_choice: Chan eil an roghainn dhan a bhòt thu ann over_character_limit: "– chan fhaod a bhith nas fhaide na %{max} caractar" + self_vote: Chan urrainn dhut bhòtadh sna chunntasan-bheachd agad fhèin too_few_options: "– feumaidh iomadh nì a bhith aige" too_many_options: "– chan fhaod còrr is %{max} nì a bhith ’na bhroinn" preferences: other: Eile posting_defaults: Bun-roghainnean a’ phostaidh public_timelines: Loidhnichean-ama poblach + privacy: + hint_html: "Gnàthaich an dòigh air an dèid a’ phròifil ’s na postaichean agad a lorg. Tha grunn ghleusan aig Mastodon a chuidicheas ach an ruig thu èisteachd nas fharsainge nuair a bhios iad an comas. Thoir sùil air na roghainnean seo a dhèanamh cinnteach gum freagair iad ri d’ fheumalachdan." + privacy: Prìobhaideachd + privacy_hint_html: Stiùirich na tha thu airson foillseachadh do chàch. Gheibh daoine lorg air pròifilean inntinneach is deagh aplacaidean a’ brabhsadh cò tha daoine eile a’ leantainn ’s a’ faicinn nan aplacaidean a chleachdas iad airson postadh ach dh’fhaoidte gum b’ fheàrr leat seo a chumail falaichte. + reach: Ruigse + reach_hint_html: Stiùirich am bu mhiann leat gun lorg ’s gun lean daoine ùra thu gus nach bu mhiann. A bheil thu airson ’s gun nochd na postaichean agad air duilleag an rùrachaidh? No gum faic càch thu am measg nam molaidhean leantainn aca? An gabh thu ri luchd-leantainn ùr sam bith gu fèin-obrachail no an cùm thu fhèin smachd air gach neach fa leth? + search: Lorg + search_hint_html: Stiùirich an dòigh air an dèid do lorg. Am bu mhiann leat gun lorg daoine thu leis na phostaich thu gu poblach? Am bu mhiann leat gun lorg daoine taobh a-muigh Mastodon a’ phròifil agad nuair a bhios iad a lorg an lìn? Thoir an aire nach urrainn dhuinn gealladh le cinnt gun dèid am fiosrachadh poblach agad a dhùnadh a-mach gu tur às gach einnsean-luirg poblach. + title: Prìobhaideachd ’s ruigse privacy_policy: title: Poileasaidh prìobhaideachd reactions: @@ -1406,7 +1589,11 @@ gd: unrecognized_emoji: "– chan aithne dhuinn an Emoji seo" relationships: activity: Gnìomhachd a’ chunntais + confirm_follow_selected_followers: A bheil thu cinnteach gu bheil thu airson an luchd-leantainn a thagh thu a leantainn? + confirm_remove_selected_followers: A bheil thu cinnteach gu bheil thu airson an luchd-leantainn a thagh thu a thoirt air falbh? + confirm_remove_selected_follows: A bheil thu cinnteach nach eil thu airson an fheadhainn a thagh thu a leantainn tuilleadh? dormant: Na thàmh + follow_failure: Cha deach le leantainn cuid dhe na cunntasan a thagh thu. follow_selected_followers: Lean an luchd-leantainn a thagh thu followers: Luchd-leantainn following: A’ leantainn @@ -1446,6 +1633,7 @@ gd: electron: Electron firefox: Firefox generic: Brabhsair nach aithne dhuinn + huawei_browser: Brabhsair Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1455,6 +1643,7 @@ gd: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Brabhsair nach aithne dhuinn weibo: Weibo current_session: An seisean làithreach description: "%{browser} air %{platform}" @@ -1467,9 +1656,10 @@ gd: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: ùrlar nach aithne dhuinn + unknown_platform: Ùrlar nach aithne dhuinn windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1494,9 +1684,9 @@ gd: migrate: Imrich cunntais notifications: Brathan preferences: Roghainnean - profile: Pròifil + profile: Pròifil phoblach relationships: Dàimhean leantainn - statuses_cleanup: Sguabadh às fèin-obrachail phostaichean + statuses_cleanup: Sguabadh às phostaichean strikes: Rabhaidhean na maorsainneachd two_factor_authentication: Dearbhadh dà-cheumnach webauthn_authentication: Iuchraichean tèarainteachd @@ -1552,7 +1742,6 @@ gd: show_newer: Seall feadhainn as ùire show_older: Seall feadhainn as sine show_thread: Seall an snàithlean - sign_in_to_participate: Clàraich a-steach a ghabhail pàirt sa chòmhradh title: "%{name}: “%{quote}”" visibilities: direct: Dìreach @@ -1581,7 +1770,7 @@ gd: keep_polls_hint: Cha dèid gin dhe na cunntasan-bheachd agad a sguabadh às keep_self_bookmark: Cùm na chuir thu ris comharran-lìn keep_self_bookmark_hint: Cha dèid gin dhe na postaichean agad fhèin a chuir thu ris na comharran-lìn agad a sguabadh às - keep_self_fav: Cùm na chuir thu ris na h-annsachdan + keep_self_fav: Cùm na postaichean a chuir thu ris na h-annsachdan keep_self_fav_hint: Cha dèid gin dhe na postaichean agad fhèin a chuir thu ris na h-annsachdan agad a sguabadh às min_age: '1209600': 2 sheachdain @@ -1593,13 +1782,11 @@ gd: '63113904': 2 bhliadhna '7889238': 3 mìosan min_age_label: Stairsneach aoise - min_favs: Cùm na tha ’na annsachd aig co-dhiù - min_favs_hint: Cha dèid gin dhe na postaichean agad a sguabadh às a tha ’nan annsachd an àireamh de thursan seo air a char as lugha. Fàg seo bàn airson postaichean a sguabadh às ge b’ e co mheud turas a tha iad ’nan annsachd + min_favs: Cùm na postaichean a chaidh a chur ris na h-annsachdan co-dhiù + min_favs_hint: Cha dèid gin dhe na postaichean agad a sguabadh às a chaidh a chur ris na h-annsachdan an àireamh seo de thursan air a char as lugha. Fàg seo bàn airson na postaichean a sguabadh às ge b’ e co mheud neach a chuir ris na h-annsachdan iad min_reblogs: Cùm na tha ’ga bhrosnachadh le co-dhiù min_reblogs_hint: Cha dèid gin dhe na postaichean agad a sguabadh às a tha ’gam brosnachadh an àireamh de thursan seo air a char as lugha. Fàg seo bàn airson postaichean a sguabadh às ge b’ e co mheud turas a tha iad ’gam brosnachadh stream_entries: - pinned: Post prìnichte - reblogged: "’ga bhrosnachadh" sensitive_content: Susbaint fhrionasach strikes: errors: @@ -1615,6 +1802,11 @@ gd: default: "%d %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Chaidh am frithealaiche thar cuota cleachdadh seirbheis an eadar-theangachaidh. + too_many_requests: Rinneadh cus iarrtasan air seirbheis an eadar-theangachaidh o chionn goirid. two_factor_authentication: add: Cuir ris disable: Cuir an dearbhadh dà-cheumnach à comas @@ -1694,13 +1886,18 @@ gd: title: Fàilte air bòrd, %{name}! users: follow_limit_reached: Chan urrainn dhut còrr is %{limit} daoine a leantainn + go_to_sso_account_settings: Tadhail air roghainnean cunntas solaraiche na dearbh-aithne agad invalid_otp_token: Còd dà-cheumnach mì-dhligheach otp_lost_help_html: Ma chaill thu an t-inntrigeadh dhan dà chuid diubh, ’s urrainn dhut fios a chur gu %{email} seamless_external_login: Rinn thu clàradh a-steach le seirbheis on taobh a-muigh, mar sin chan eil roghainnean an fhacail-fhaire ’s a’ phuist-d ri làimh dhut. signed_in_as: 'Chlàraich thu a-steach mar:' verification: - explanation_html: '’S urrainn dhut dearbhadh gur e seilbheadair nan ceanglaichean ann am meata-dàta na pròifil agad a th’ annad. Airson sin a dhèanamh, feumaidh ceangal air ais dhan phròifil Mastodon a bhith aig an làrach-lìn cheangailte. Feumaidh buadh rel="me" a bhith aig a’ cheangal air ais. Chan eil e gu diofar dè an t-susbaint a tha ann an teacsa a’ cheangail. Seo ball-eisimpleir dhut:' + extra_instructions_html: Gliocas:Faodaidh an ceangal air an làrach-lìn agad a bhith do-fhaicsinneach. ’S e rel="me" a tha sa phàirt chudromach a bhacas riochd cuideigin eile air làraichean-lìn le susbaint air a gintinn o chleachdaiche. ’S urrainn dhut fiù taga link a chleachdadh ann am bann-cinn na duilleige seach a ach feumaidh sinn an HTML ruigsinn gun a bhith a’ ruith JavaScript. + here_is_how: Seo mar a nì thu e + hint_html: "Gheibh duine sam bith dearbhadh an aithne air Mastodon. Tha seo stèidhichte air stannardan-lìn fosgailte agus bidh e saor ’s an-asgaidh gu bràth. Chan fheum thu dad ach làrach-lìn phearsanta leis an aithnich daoine thu. Nuair a nì thu ceangal dhan làrach-lìn sin on phròifil agad, dearbhaidh sinn gu bheil an làrach-lìn a’ ceangal air ais dhan phròifil agad agus seallaidh sinn taisbeanair lèirsinneach oirre." + instructions_html: Dèan lethbhreac dhen chòd gu h-ìosal is cuir a-steach ann an HTML na làraich-lìn agad e. An uairsin, cuir seòladh na làraich-lìn agad ri fear dhe na raointean a bharrachd air a’ phròifil agad o thaba “Deasaich a’ phròifil” agus sàbhail na h-atharraichean. verification: Dearbhadh + verified_links: Na ceanglaichean dearbhte agad webauthn_credentials: add: Cuir iuchair tèarainteachd ùr ris create: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 6885000ac5..14f78e4615 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -71,7 +71,7 @@ gl: enabled: Activado enabled_msg: Desbloqueada a conta de %{username} followers: Seguidoras - follows: Segue + follows: Seguimentos header: Cabeceira inbox_url: URL da caixa de entrada invite_request_text: Razóns para unirte @@ -91,6 +91,7 @@ gl: moderation: active: Activa all: Todo + disabled: Desactivada pending: Pendente silenced: Limitada suspended: Suspendidos @@ -124,8 +125,8 @@ gl: removed_header_msg: Eliminada a imaxe de cabeceira de %{username} resend_confirmation: already_confirmed: Esta usuaria xa está confirmada - send: Reenviar o email de confirmación - success: Email de confirmación enviado de xeito correcto! + send: Reenviar ligazón de confirmación + success: Ligazón de confirmación enviada correctamente! reset: Restabelecer reset_password: Restabelecer contrasinal resubscribe: Resubscribir @@ -133,6 +134,7 @@ gl: search: Procurar search_same_email_domain: Outras usuarias co mesmo dominio de email search_same_ip: Outras usuarias co mesmo IP + security: Seguridade security_measures: only_password: Só contrasinal password_and_2fa: Contrasinal e 2FA @@ -307,6 +309,7 @@ gl: unpublish: Retirar publicación unpublished_msg: Anuncio desbotado de xeito correcto! updated_msg: Anuncio actualizado de xeito correcto! + critical_update_pending: Actualización crítica pendente custom_emojis: assign_category: Atribuír categoría by_domain: Dominio @@ -380,6 +383,15 @@ gl: undo: Eliminar da listaxe branca domain_blocks: add_new: Engadir novo bloqueo de dominio + confirm_suspension: + cancel: Cancelar + confirm: Suspender + permanent_action: Ao retirar a suspensión non restableces os datos ou a relación. + preamble_html: Vas suspender a %{domain} e os seus subdominios. + remove_all_data: Eliminarás do teu servidor todo o contido, multimedia e datos de perfil para as contas deste dominio. + stop_communication: O teu servidor deixará de comunicarse con estos servidores. + title: Confirma o bloqueo do dominio %{domain} + undo_relationships: Isto desfará as relacións de seguimento entre as contas destes servidores e o teu. created_msg: Estase a procesar o bloqueo do dominio destroyed_msg: Desfíxose o bloqueo de dominio domain: Dominio @@ -427,6 +439,7 @@ gl: resolve: Resolver dominio title: Nova entrada na listaxe negra de email no_email_domain_block_selected: Non se cambiou ningún bloqueo de dominio de email porque non se seleccionou ningún + not_permitted: Non permitido resolved_dns_records_hint_html: O nome de dominio resolve os seguintes rexistros MX, que son os últimos responsables da aceptación de emails. Bloqueando un dominio MX rexeitarás calquera enderezo de email que use este dominio MX, incluso se o nome de dominio visible é outro. Ten coidado de non bloquear os principais provedores. resolved_through_html: Resolto a través de %{domain} title: Listaxe negra de email @@ -441,7 +454,7 @@ gl: private_comment_description_html: 'Para axudarche a lembrar de onde veñen os bloqueos importados, imos crealos engadindo o seguinte comentario privado: %{comment}' private_comment_template: Importada desde %{source} o %{date} title: Importar bloqueos de dominio - invalid_domain_block: 'Un ou varios dominios non se bloquearon debido ao seguintes erros: %{error}' + invalid_domain_block: 'Un ou varios dominios non se bloquearon debido ao seguinte erro(s): %{error}' new: title: Importar bloqueos de dominio no_file: Ningún ficheiro seleccionado @@ -473,6 +486,7 @@ gl: content_policies: comment: Nota interna description_html: Podes definir políticas acerca do contido que serán aplicadas a tódalas contas deste dominio e tódolos seus subdominios. + limited_federation_mode_description_html: Podes elexir se permites ou non a federación con este dominio. policies: reject_media: Rexeitar multimedia reject_reports: Rexeitar denuncias @@ -585,11 +599,13 @@ gl: assign_to_self: Asignarme assigned: Moderador asignado by_target_domain: Dominio da conta denunciada + cancel: Cancelar category: Categoría category_description_html: A razón para denunciar esta conta ou contido será citada na comunicación coa conta denunciada comment: none: Ningún comment_description_html: 'Como información engadida, %{name} escribiu:' + confirm: Confirmar confirm_action: Confirma a acción de moderación contra @%{acct} created_at: Denunciado delete_and_resolve: Eliminar publicacións @@ -725,6 +741,9 @@ gl: branding: preamble: A personalización do teu servidor diferénciao doutros servidores da rede. A información podería mostrarse en diversos entornos, como a interface web de Mastodon, aplicacións nativas, vista previa das ligazóns noutras webs e apps de mensaxería, e similares. Debido a isto é recomendable que a información sexa clara, curta e concisa. title: Personalización + captcha_enabled: + desc_html: Ten dependencia de scripts externos desde hCaptcha, que podería ser un problema de seguridade e privacidade. Ademáis, pode diminuír a accesiblidade para algunhas persoas (principalmente as discapacitadas). Por estas razóns, considera medidas alternativas como o rexistro por convite e a aprobación manual das contas. + title: Pedirlle ás novas usuarias resolver un CAPTCHA para confirmar a súa conta content_retention: preamble: Controla como se gardan en Mastodon os contidos creados polas usuarias. title: Retención do contido @@ -752,10 +771,27 @@ gl: approved: Precisa aprobación para rexistrarse none: Rexistro pechado open: Rexistro aberto + security: + authorized_fetch: Require autenticación desde os servidores federados + authorized_fetch_hint: Ao requerir autenticación desde os servidores federados activas un reforzamento das políticas de bloqueo a nivel usuaria e nivel servidor. Este proceder ten un custo no rendemento, reducindo o alcance das túas respostas e podería introducir problemas de compatibilidade con algúns servizos federados. Ademais, non evitará que contas con tal propósito vexan as túas publicacións públicas e contas. + authorized_fetch_overridden_hint: Actualmente non podes cambiar este axuste porque está controlado por unha variable xeral do sistema. + federation_authentication: Reforzo da autenticación na federación title: Axustes do servidor site_uploads: delete: Eliminar o ficheiro subido destroyed_msg: Eliminado correctamente o subido! + software_updates: + critical_update: Crítica - actualiza axiña + description: Recomendamos manter actualizado o teu servidor Mastodon para beneficiarte dos últimos arranxos e características. A maiores, de cando en vez hai actualizacións para evitar problemas importantes de seguridade. Debido a isto, Mastodon comproba cada 30 minutos se hai actualizacións e avisarate seguindo as túas preferencias de notificación por correo electrónico. + documentation_link: Saber máis + release_notes: Notas da versión + title: Actualizacións dispoñibles + type: Tipo + types: + major: Versión principal + minor: Versión intermedia + patch: Versión de arranxos - solución de problemas e cambios simples + version: Versión statuses: account: Autoría application: Aplicación @@ -792,9 +828,24 @@ gl: suspend: "%{name} suspendeu a conta de %{target}" appeal_approved: Recurrida appeal_pending: Apelación pendente + appeal_rejected: Apelación rexeitada system_checks: database_schema_check: message_html: Existen migracións pendentes na base de datos. Bota man desta tarefa para facer que a aplicación funcione como se agarda dela + elasticsearch_health_red: + message_html: O grupo Elasticsearch non está ben (en vermello), as ferramentas de busca non están dispoñibles + elasticsearch_health_yellow: + message_html: O grupo Elasticsearch non está ben (en amarelo), deberías investigar a causa + elasticsearch_index_mismatch: + message_html: Os índices de mapeo de Elasticsearch están desactualizados. Executa tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ver a documentación + message_html: O teu grupo Elasticsearch ten máis dun nodo, pero Mastodon non está configurado para usalos. + elasticsearch_preset_single_node: + action: Ver a documentación + message_html: O teu grupo Elasticsearch só ten un nodo, ES_PRESET debería configurarse como single_node_cluster. + elasticsearch_reset_chewy: + message_html: O teu índice do sistema Elasticsearch está desactualizado debido a un cambio nos axustes. Executa tootctl search deploy --reset-chewy para actualizalo. elasticsearch_running_check: message_html: Non se puido conectar con Elasticsearch. Comproba que está funcionando, ou desactiva a busca por texto completo elasticsearch_version_check: @@ -805,6 +856,18 @@ gl: message_html: Non tes definidas regras para o servidor. sidekiq_process_check: message_html: Non hai procesos Sidekiq a funcionar para a cola(s) %{value}. Revisa a túa configuración para Sidekiq + software_version_critical_check: + action: Mira as actualizacións dispoñibles + message_html: Hai unha actualización crítica de Mastodon dispoñible, actualiza axiña. + software_version_patch_check: + action: Mira as actualizacións dispoñibles + message_html: Hai unha actualización de arranxo de problemas de Mastodon. + upload_check_privacy_error: + action: Mira aquí para máis información + message_html: "O teu servidor non está ben configurado. A privacidade das usuarias está en risco." + upload_check_privacy_error_object_storage: + action: Mira aquí para máis información + message_html: "A almacenaxe de obxectos está mal configurada. A privacidade das usuarias está en risco." tags: review: Estado de revisión updated_msg: Actualizaronse os axustes dos cancelos @@ -827,6 +890,7 @@ gl: other: Compartido por %{count} persoas na última semana title: Ligazóns en voga usage_comparison: Compartido %{today} veces hoxe, comparado con %{yesterday} onte + not_allowed_to_trend: Non permitido como tendencia only_allowed: Só as permitidas pending_review: Revisión pendente preview_card_providers: @@ -911,6 +975,9 @@ gl: body: "%{target} apelou a decisión de moderación de %{action_taken_by} o %{date}, de tipo %{type}. Escribiu:" next_steps: Podes aprobar o recurso e desfacer a decisión de moderación, ou ignoralo. subject: "%{username} fixo unha apelación á decisión de moderación en %{instance}" + new_critical_software_updates: + body: Publicáronse novas versións de Mastodon para arranxar problemas importantes, deberías actualizar axiña! + subject: Actualizacións críticas de Mastodon dispoñibles para %{instance}! new_pending_account: body: Abaixo están os detalles da conta. Podes aprobar ou rexeitar esta solicitude. subject: Hai unha conta nova para revisar en %{instance} (%{username}) @@ -918,6 +985,9 @@ gl: body: "%{reporter} informou sobre %{target}" body_remote: Alguén desde %{domain} informou sobre %{target} subject: Nova denuncia sobre %{instance} (#%{id}) + new_software_updates: + body: Publicáronse novas versións de Mastodon, convenche actualizar! + subject: Hai novas versións de Mastodon dispoñibles para %{instance}! new_trends: body: 'Os seguintes elementos precisan revisión antes de ser mostrados públicamente:' new_trending_links: @@ -947,24 +1017,28 @@ gl: guide_link: https://crowdin.com/project/mastodon guide_link_text: Todas podemos contribuír. sensitive_content: Contido sensible - toot_layout: Disposición da publicación application_mailer: notification_preferences: Cambiar os axustes de email salutation: "%{name}," settings: 'Mudar as preferencias de e-mail: %{link}' + unsubscribe: Anular subscrición view: 'Vista:' view_profile: Ver perfil view_status: Ver publicación applications: created: Creouse con éxito este aplicativo destroyed: Eliminouse con éxito o aplicativo + logout: Pechar sesión regenerate_token: Votar a xenerar o testemuño de acceso token_regenerated: Rexenerouse con éxito o testemuño de acceso warning: Ten moito tino con estos datos. Non os compartas nunca con ninguén! your_token: O seu testemuño de acceso auth: apply_for_account: Solicita unha conta - change_password: Contrasinal + captcha_confirmation: + help_html: Se tes problemas para resolver o CAPTCHA, podes contactar con nós no correo electrónico %{email} e axudarémosche. + hint_html: Unha cousa máis! Temos que confirmar que es un ser humano (para poder evitar contas de spam!). Resolve o CAPTCHA de aquí embaixo e preme en "Continuar". + title: Comprobación de seguridade confirmations: wrong_email_hint: Se o enderezo de email non é correcto, podes cambialo nos axustes da conta. delete_account: Eliminar conta @@ -973,7 +1047,7 @@ gl: prefix_invited_by_user: "@%{name} convídate a que te unas a este servidor Mastodon!" prefix_sign_up: Rexístrate agora en Mastodon! suffix: Ao abrir unha conta, poderás seguir a xente, actualizacións das publicacións e intercambiar mensaxes coas usuarias de calquera servidor de Mastodon e moito máis! - didnt_get_confirmation: Non recibiches as instruccións de confirmación? + didnt_get_confirmation: Non recibiches a ligazón de confirmación? dont_have_your_security_key: "¿Non tes a túa chave de seguridade?" forgot_password: Non lembras o contrasinal? invalid_reset_password_token: O token para restablecer o contrasinal non é válido ou caducou. Por favor solicita un novo. @@ -986,26 +1060,39 @@ gl: migrate_account_html: Se queres redirixir esta conta hacia outra diferente, podes facelo aquí. or_log_in_with: Ou accede con privacy_policy_agreement_html: Lin e acepto a política de privacidade + progress: + confirm: Confirmar email + details: Detalles + review: A nosa revisión + rules: Aceptar regras providers: cas: CAS saml: SAML register: Crear conta registration_closed: "%{instance} non está a aceptar novas usuarias" - resend_confirmation: Reenviar as intruccións de confirmación + resend_confirmation: Reenviar ligazón de confirmación reset_password: Restablecer contrasinal rules: + accept: Aceptar + back: Volver + invited_by: 'Podes unirte a %{domain} grazas ao convite que recibiches de parte de:' preamble: Son establecidas e aplicadas pola moderación de %{domain}. + preamble_invited: Antes de continuar adica un minuto a ler as regras básicas establecidas para %{domain}. title: Algunhas regras básicas. + title_invited: Convidáronte. security: Seguranza set_new_password: Estabelecer novo contrasinal setup: - email_below_hint_html: Se o enderezo inferior non é correcto, podes cambialo aquí e recibir un correo de confirmación. - email_settings_hint_html: Enviouse un correo de confirmación a %{email}. Se o enderezo non é correcto podes cambialo nos axustes da conta. - title: Axustes + email_below_hint_html: Mira no cartafol do spam, ou solicita outra. Podes cambiar o enderzo de correo se non é correcto. + email_settings_hint_html: Preme na ligazón que che enviamos para verificar %{email}. Agardamos por ti. + link_not_received: Non recibiches a ligazón? + new_confirmation_instructions_sent: Nuns minutos recibirás un novo correo electrónico coa ligazón de confirmación! + title: Mira a caixa de entrada sign_in: - preamble_html: Accede coas túas credenciais en %{domain}. Se a túa conta está nun servidor diferente, non podes acceder desde aquí. + preamble_html: Accede coas credenciais en %{domain}. Se a túa conta está noutro servidor non poderás acceder desde aquí. title: Accede a %{domain} sign_up: + manual_review: As novas contas en %{domain} son comprobadas manualmente pola moderación. Para axudarnos a xestionar o teu rexistro, escribe algo acerca de ti e por que queres unha conta en %{domain}. preamble: Cunha conta neste servidor Mastodon poderás seguir a calquera outra persoa na rede, independentemente de onde estivese hospedada esa conta. title: Imos crear a túa conta en %{domain}. status: @@ -1017,18 +1104,6 @@ gl: view_strikes: Ver avisos anteriores respecto da túa conta too_fast: Formulario enviado demasiado rápido, inténtao outra vez. use_security_key: Usa chave de seguridade - authorize_follow: - already_following: Xa está a seguir esta conta - already_requested: Xa tes enviada unha solicitude de seguimento a esa conta - error: Desgraciadamente, algo fallou ao buscar a conta remota - follow: Seguir - follow_request: 'Enviaches unha petición de seguimento a:' - following: 'Parabéns! Agora segues a:' - post_follow: - close: Ou, podes pechar esta ventá. - return: Mostrar o perfil da usuaria - web: Ir á web - title: Seguir %{acct} challenge: confirm: Continuar hint_html: "Nota: Non che pediremos o contrasinal na seguinte hora." @@ -1105,6 +1180,10 @@ gl: your_appeal_rejected: A apelación foi rexeitada domain_validator: invalid_domain: non é un nome de dominio válido + edit_profile: + basic_information: Información básica + hint_html: "Personaliza o que van ver no teu perfil público e ao lado das túas publicacións. As outras persoas estarán máis animadas a seguirte e interactuar contigo se engades algún dato sobre ti así como unha imaxe de perfil." + other: Outros errors: '400': A solicitude que enviou non é válida ou ten formato incorrecto. '403': Non ten permiso para ver esta páxina. @@ -1141,7 +1220,7 @@ gl: featured_tags: add_new: Engadir novo errors: - limit: Xa acadaches o número máximo de cancelos + limit: Xa sinalaches o número máximo de cancelos permitido hint_html: "¿Qué son os cancelos destacados? Móstranse destacados no teu perfil público e permítenlle a outras persoas ver os teus toots públicos nos que os utilizaches. Son unha ferramenta moi útil para facer seguimento de traballos creativos e proxectos a longo prazo." filters: contexts: @@ -1185,8 +1264,6 @@ gl: index: hint: Este filtro aplícase para seleccionar publicacións individuais independentemente doutros criterios. Podes engadir máis publicacións a este filtro desde a interface web. title: Publicacións filtradas - footer: - trending_now: Tendencia agora generic: all: Todo all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ gl: all_matching_items_selected_html: one: "%{count} elemento coincidente coa busca está seleccionado." other: Tódolos %{count} elementos coincidentes coa busca están seleccionados. + cancel: Cancelar changes_saved_msg: Cambios gardados correctamente!! + confirm: Confirmar copy: Copiar delete: Eliminar deselect: Desmarcar todo @@ -1209,24 +1288,62 @@ gl: validation_errors: one: Algo non está ben de todo! Por favor revise abaixo o erro other: Algo aínda non está ben! Por favor revise os %{count} erros abaixo - html_validator: - invalid_markup: 'contén cancelos HTML non válidas: %{error}' imports: errors: + empty: Ficheiro CSV de baleiro + incompatible_type: Non é compatible co tipo de importación seleccionado invalid_csv_file: 'Ficheiro CSV non válido. Erro: %{error}' over_rows_processing_limit: contén máis de %{count} filas + too_large: O ficheiro é demasiado grande + failures: Erros + imported: Importado + mismatched_types_warning: Semella que elexiches o tipo de ficheiro incorrecto para esta importación, compróbao. modes: merge: Fusionar merge_long: Manter os rexistros actuais e engadir novos overwrite: Sobreescribir overwrite_long: Sustituír rexistros actuais cos novos + overwrite_preambles: + blocking_html: Vas substituír a lista de bloqueos por %{total_items} contas desde %{filename}. + bookmarks_html: Vas substituír os marcadores por %{total_items} publicacións desde %{filename}. + domain_blocking_html: Vas substituír a lista de dominios bloqueados por %{total_items} dominios desde %{filename}. + following_html: Vas seguir estas %{total_items} contas desde %{filename} e deixar de seguir a todas as outras contas. + lists_html: Vas substituír as túas listas co contido de %{filename}. Vanse engadir %{total_items} contas ás novas listas. + muting_html: Vas substituír a lista de contas acaladas por %{total_items} contas desde %{filename}. + preambles: + blocking_html: Vas bloquear estas %{total_items} contas desde %{filename}. + bookmarks_html: Vas engadir %{total_items} publicacións desde %{filename} aos teus marcadores. + domain_blocking_html: Vas bloquear estes %{total_items} dominios desde %{filename}. + following_html: Vas seguir estas %{total_items} contas desde %{filename}. + lists_html: Vas engadir %{total_items} contas desde %{filename} ás túas listas. Crearánse novas listas se non hai listas ás que engadilas. + muting_html: Vas acalar estas %{total_items} contas desde %{filename}. preface: Podes importar os datos que exportaches doutro servidor, tales como a lista de usuarias que estás a seguir ou bloquear. + recent_imports: Importacións recentes + states: + finished: Completada + in_progress: En curso + scheduled: Programada + unconfirmed: Sen confirmar + status: Estado success: Os teus datos foron correctamente subidos e serán procesados ao momento + time_started: Iniciada o + titles: + blocking: Importando contas bloqueadas + bookmarks: Importando marcadores + domain_blocking: Importando dominios bloqueados + following: Importando contas seguidas + lists: Importación de listas + muting: Importando contas acaladas + type: Tipo de importación + type_groups: + constructive: Seguimentos e Marcadores + destructive: Bloqueadas e Acaladas types: blocking: Lista de bloqueo bookmarks: Marcadores domain_blocking: Lista de bloqueo de dominios following: Lista de seguimento + lists: Listas muting: Lista de usuarias acaladas upload: Subir invites: @@ -1253,7 +1370,7 @@ gl: title: Convidar xente lists: errors: - limit: Acadou o número máximo de listas + limit: Xa acadaches o número máximo de listas login_activities: authentication_methods: otp: app para autenticación con dous factores @@ -1265,6 +1382,21 @@ gl: failed_sign_in_html: Intento de acceso errado con %{method} desde %{ip} (%{browser}) successful_sign_in_html: Acceso correcto con %{method} desde %{ip} (%{browser}) title: Historial de autenticación + mail_subscriptions: + unsubscribe: + action: Si, retirar subscrición + complete: Subscrición anulada + confirmation_html: Tes a certeza de querer retirar a subscrición a Mastodon en %{domain} para recibir %{type} no teu correo electrónico en %{email}? Poderás volver a subscribirte desde os axustes de notificacións por correo. + emails: + notification_emails: + favourite: notificacións de favoritos + follow: notificacións de seguimentos + follow_request: notificacións de solicitudes de seguimento + mention: notificacións de mencións + reblog: notificacións de promocións + resubscribe_html: Se por un erro eliminaches a subscrición, podes volver a subscribirte desde os axustes de notificacións por correo electrónico. + success_html: Non vas recibir %{type} de Mastodon en %{domain} no teu enderezo %{email}. + title: Anular subscrición media_attachments: validations: images_and_video: Non podes anexar un vídeo a unha publicación que xa contén imaxes @@ -1344,6 +1476,7 @@ gl: update: subject: "%{name} editou unha publicación" notifications: + administration_emails: Notificacións de Admin por correo electrónico email_events: Eventos para os correos de notificación email_events_hint: 'Escolle os eventos sobre os que queres recibir notificacións:' other_settings: Outros axustes das notificacións @@ -1380,12 +1513,22 @@ gl: expired: A enquisa rematou invalid_choice: A opción de voto escollida non existe over_character_limit: non poden ter máis de %{max} caracteres cada unha + self_vote: Non podes votar nas túas enquisas too_few_options: debe ter máis de unha opción too_many_options: non pode haber máis de %{max} opcións preferences: other: Outro posting_defaults: Valores por omisión public_timelines: Cronoloxías públicas + privacy: + hint_html: "Personaliza o xeito no que queres que se atope o teu perfil e publicacións. Mastodon ten variedade de ferramentas para axudarche a acadar unha audiencia maior. Dedica un minuto a revisalas e confirma que se axustan ao teu caso persoal." + privacy: Privacidade + privacy_hint_html: Controla canto queres mostrar ás demais persoas. As usuarias descubren perfís interesantes e apps estupendas mirando a quen seguen outras persoas e vendo as apps desde as que publican, pero ti poderías querer non mostralas. + reach: Alcance + reach_hint_html: Indica o xeito en que queres que outras persoas poidan atoparte e seguirte. Queres aparecer na pantalla Descubrir? Queres que outras persoas poidan incluirte entre as súas recomendacións de seguimento? Queres aceptar os seguimentos automáticamente, ou ter control individual sobre as solicitudes? + search: Buscar + search_hint_html: Xestiona o xeito en que poden atoparte. Queres que te atopen a través do que publicaches de xeito público? Queres que as persoas de fóra de Mastodon atopen o teu perfil cando fan buscas na web? Por favor, ten en conta que a exclusión total de todos os buscadores non se pode garantir para a información pública. + title: Privacidade e alcance privacy_policy: title: Política de Privacidade reactions: @@ -1398,6 +1541,7 @@ gl: confirm_remove_selected_followers: Tes a certeza de querer deixar de seguir as seguidoras seleccionadas? confirm_remove_selected_follows: Tes a certeza de querer eliminar os seguimentos seleccionados? dormant: En repouso + follow_failure: Non puido seguir algunha das contas seleccionadas. follow_selected_followers: Seguir seguidoras seleccionadas followers: Seguidoras following: A Seguir @@ -1437,6 +1581,7 @@ gl: electron: Electron firefox: Firefox generic: Navegador descoñecido + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Navegador Nokia S40 Ovi @@ -1446,6 +1591,7 @@ gl: qq: Navegador QQ safari: Safari uc_browser: Navegador QQ + unknown_browser: Navegador descoñecido weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1458,9 +1604,10 @@ gl: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: plataforma descoñecida + unknown_platform: Plataforma descoñecida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1531,7 +1678,6 @@ gl: show_newer: Mostrar o máis novo show_older: Mostrar o máis vello show_thread: Amosar fío - sign_in_to_participate: Accede e participa na conversa title: '%{name}: "%{quote}"' visibilities: direct: Directa @@ -1573,12 +1719,10 @@ gl: '7889238': 3 meses min_age_label: Límite temporal min_favs: Manter as publicacións favoritas máis de - min_favs_hint: Non elimina ningunha das túas publicacións que recibiron máis desta cantidade de favorecementos. Deixa en branco para eliminar publicacións independentemente do número de favorecementos + min_favs_hint: Non elimina ningunha das túas publicacións que recibiron alomenos esta cantidade de favorecementos. Deixa en branco para eliminar publicacións independentemente do número de favorecementos min_reblogs: Manter publicacións promovidas máis de min_reblogs_hint: Non elimina ningunha das túas publicacións se foron promovidas máis deste número de veces. Deixa en branco para eliminar publicacións independentemente do seu número de promocións stream_entries: - pinned: Publicación fixada - reblogged: promoveu sensitive_content: Contido sensible strikes: errors: @@ -1594,6 +1738,11 @@ gl: default: "%d %b, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d de %b de %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Superouse a cota de uso do servizo de tradución para todo o servidor. + too_many_requests: Ultimamente houbo demasiadas solicitudes ao servizo de tradución. two_factor_authentication: add: Engadir disable: Deshabilitar @@ -1673,13 +1822,18 @@ gl: title: Benvida, %{name}! users: follow_limit_reached: Non pode seguir a máis de %{limit} persoas + go_to_sso_account_settings: Ir aos axustes da conta no teu provedor de identidade invalid_otp_token: O código do segundo factor non é válido otp_lost_help_html: Se perdes o acceso a ambos, podes contactar con %{email} seamless_external_login: Accedeches a través dun servizo externo, polo que os axustes de contrasinal e email non están dispoñibles. signed_in_as: 'Rexistrada como:' verification: - explanation_html: 'Podes validarte a ti mesma como a dona das ligazóns nos metadatos do teu perfil. Para esto, o sitio web ligado debe conter unha ligazón de retorno ao perfil de Mastodon. Esta ligazón de retorno ten que ter un atributo rel="me". O texto da ligazón non importa. Aquí tes un exemplo:' + extra_instructions_html: Truco: A ligazón pode estar agochada na túa páxina web. A parte importante é rel="me" que impide a suplantación en sitios web con contido creado polas usuarias. Incluso podes usar a etiqueta link na cabeceira da páxina en lugar de a, pero o HTML debe ser accesible sen precisar usar JavaScript. + here_is_how: Podes facelo así + hint_html: "É moi fácil verificar a túa identidade en Mastodon. Baseado en estándares web, gratuíto para sempre. O único que precisas é un sitio web persoal polo que a xente te recoñeza. Cando relacionas ese sitio web co teu perfil, nós comprobamos que esa web ten unha ligazón de volta ao teu perfil e mostraremos unha indicación visual nel." + instructions_html: Copia e pega o código inferior no HTML do teu sitio web. Despois engade o enderezo da túa web nun dos campos de datos extra do teu perfil dispoñibles na lapela "Editar perfil" e garda os cambios. verification: Validación + verified_links: As túas ligazóns verificadas webauthn_credentials: add: Engadir nova chave de seguridade create: diff --git a/config/locales/he.yml b/config/locales/he.yml index bad6fd6fd3..a7c702e979 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -95,6 +95,7 @@ he: moderation: active: פעילים all: הכל + disabled: מושבת pending: בהמתנה silenced: מוגבלים suspended: מושהים @@ -130,8 +131,8 @@ he: removed_header_msg: תמונת הראשה של %{username} הוסרה בהצלחה resend_confirmation: already_confirmed: משתמש זה כבר אושר - send: שלח מחדש דוא"ל אימות - success: הודעת האימייל נשלחה בהצלחה! + send: שלח מחדש קישור לאימות + success: קישור מאמת נשלח בהצלחה! reset: איפוס reset_password: איפוס סיסמה resubscribe: להרשם מחדש @@ -139,6 +140,7 @@ he: search: חיפוש search_same_email_domain: משתמשים אחרים מאותו דומיין דוא"ל search_same_ip: משתמשים אחרים מאותה כתובת IP + security: אבטחה security_measures: only_password: סיסמה בלבד password_and_2fa: סיסמה ואימות דו-שלבי @@ -313,6 +315,7 @@ he: unpublish: ביטול פרסום unpublished_msg: פרסום ההכרזה בוטל בהצלחה! updated_msg: ההכרזה עודכנה בהצלחה! + critical_update_pending: עידכון קריטי ממתין custom_emojis: assign_category: הקצאת קטגוריה by_domain: לפי קהילה @@ -394,6 +397,15 @@ he: undo: אסור מַאֲחָד (פדרציה) עם שם המתחם domain_blocks: add_new: הוספת חדש + confirm_suspension: + cancel: ביטול + confirm: השעייה + permanent_action: ביטול ההשעיה לא יגרום לשחזר מידע או יחסים. + preamble_html: יש לאשר את השעיית %{domain} ותתי-הכתובות של שם המתחם. + remove_all_data: פעולה זו תסיר כל תוכן, מדיה ומידע הפרופילים של שם המתחם הזה מהשרת שלך. + stop_communication: השרת שלך יפסיק לתקשר עם שרתים אלו. + title: נא לאשר חסימת מתחם של %{domain} + undo_relationships: הפעולה תבטל את כל יחסי העקיבה בין חשבונות מהשרתים האלו לבין שלך. created_msg: חסימת שרת בתהליך destroyed_msg: חסימת שרת בוטלה domain: שרת @@ -443,6 +455,7 @@ he: resolve: פתור דומיין title: חסימת דומיין דוא"ל no_email_domain_block_selected: לא בוצעו שינויים לחסימת דומייני דוא"ל שכן לא נבחרו דומיינים + not_permitted: נאסר resolved_dns_records_hint_html: שם הדומיין מוביל לדומייניי ה-MX הבאים, שהם בסופו של דבר אחראיים לקבלת דוא"ל. חסימת דומיין MX תוביל לחסימת הרשמות מכל כתובת דוא"ל שעושה שימוש בדומיין MX זה, אפילו אם הדומיין הגלוי שונה. יש להמנע מלחסום ספקי דוא"ל מובילים. resolved_through_html: נמצא דרך %{domain} title: דומייניי דוא"ל חסומים @@ -493,6 +506,7 @@ he: content_policies: comment: הערה פנימית description_html: ביכולתך להגדיר מדיניות תוכן שתופעל על כל החשבונות מדומיין זה ומתת-דומייניו. + limited_federation_mode_description_html: ניתן לבחור אם להרשות תקשורת הדדית עם שרת זה. policies: reject_media: דחיית מדיה reject_reports: דחיית דו"חות @@ -535,7 +549,7 @@ he: public_comment: תגובה פומבית purge: טיהור purge_description_html: אם יש יסוד להניח שדומיין זה מנותק לעד, ניתן למחוק את כל רשומות החשבונות והמידע המשוייך לדומיין זה משטח האפסון שלך. זה עשוי לקחת זמן מה. - title: שרתים מוכרים + title: שרתים בפדרציה total_blocked_by_us: חסום על ידינו total_followed_by_them: נעקב על ידם total_followed_by_us: נעקב על ידינו @@ -609,11 +623,13 @@ he: assign_to_self: הקצה אלי assigned: מנחה מוקצה by_target_domain: דומיין החשבון המדווח + cancel: ביטול category: קטגוריה category_description_html: הסיבה בגללה חשבון זה ו/או תוכנו דווחו תצוטט בתקשורת עם החשבון המדווח comment: none: ללא comment_description_html: 'על מנת לספק עוד מידע, %{name} כתב\ה:' + confirm: אישור confirm_action: נא לאשר פעולת משמעת לגבי חשבון %{acct} created_at: מדווח delete_and_resolve: מחיקת הודעות @@ -753,6 +769,9 @@ he: branding: preamble: המיתוג של השרת שלך מבדל אותו משרתים אחרים ברשת. המידע יכול להיות מוצג בסביבות שונות כגון מנשק הווב של מסטודון, יישומים מקומיים, בצפיה מקדימה של קישור או בתוך יישומוני הודעות וכולי. מסיבה זו מומלץ לשמור על המידע ברור, קצר וממצה. title: מיתוג + captcha_enabled: + desc_html: אפשרות זו ניסמכת על קטעי קוד חיצוניים של hCaptcha שעלולים להיות סיכון אבטחה ופרטיות. בנוסף, זה עשוי להפוך את תהליך ההרשמה לבלתי נגיש לא.נשים, במיוחד בעלות ובעלי מוגבלויות. מסיבות אלו, כדאי לשקול חלופות כמו אשרור מנהלים ידני או הרשמה רק על בסיס הזמנה. + title: לדרוש פתרון CAPTCHA כדי לאשרר למשתמשים את חשבונם content_retention: preamble: שליטה על דרך אחסון תוכן המשתמשים במסטודון. title: תקופת השמירה של תכנים @@ -780,10 +799,27 @@ he: approved: נדרש אישור הרשמה none: אף אחד לא יכול להרשם open: כל אחד יכול להרשם + security: + authorized_fetch: לדרוש הזדהות מול שרתים בפדרציה + authorized_fetch_hint: הדרישה להזדהות מול שרתים בפדרציה מאפשרת חסימה יותר יעילה ברמת המשתמש וברמת שרת. עם זאת, הדרישה באה עם מחיר של נפילת ביצועים, מקטינה את מעגל התפוצה של התשובות שלך, ועשויה ליצור אי תאימות מול שירותים אחרים בפדרציה. בנוסף, זה לא ימנע מצדדים החלטיים לקבל גישת קריאה להודעות ופרופילים ציבוריים. + authorized_fetch_overridden_hint: אין באפשרותך כרגע לשנות את ההגדרה כיוון שהערך נאכף על ידי משתנה סביבתי קודם במערכת ההפעלה. + federation_authentication: חיוב אימות פדרטיבי title: הגדרות שרת site_uploads: delete: מחיקת קובץ שהועלה destroyed_msg: העלאת אתר נמחקה בהצלחה! + software_updates: + critical_update: חשוב -- יש לעדכן במהירות + description: מומלץ לשמור את התקנת המסטודון שלך עדכנית כדי להרוויח מהיכולות והתיקונים האחרונים. למעלה מכך, לעיתים קריטי לעדכן את מסטודון בהקדם כדי להמנע מפרצות אבטחה. מסיבות אלו, השרת יבדוק כל 30 דקות, ויודיע לך לפי העדפות הדואל שלך. + documentation_link: למידע נוסף + release_notes: פרטי הגרסה + title: עדכונים זמינים + type: סוג + types: + major: שחרור משמעותי (Major release) + minor: שחרור משני (Minor release) + patch: עדכון טלאי — תיקוני שקצים ושינויים קלים + version: גרסה statuses: account: מחבר application: יישום @@ -820,9 +856,24 @@ he: suspend: "%{name} השעה/תה את חשבונו/ה של %{target}" appeal_approved: עורער appeal_pending: בהמתנה לערעור + appeal_rejected: הערעור נדחה system_checks: database_schema_check: message_html: נדרשות הגירות מבני נתונים. אנא הריצו אותן כדי להבטיח שהיישום מתנהג כצפוי + elasticsearch_health_red: + message_html: אשכול שירותי חיפוש Elasticsearch אינו זמין כעת (מצב אדום), אפשרויות חיפוש אינן זמינות כרגע + elasticsearch_health_yellow: + message_html: אשכול שירותי חיפוש Elasticsearch אינו כשיר כעת (מצב צהוב), מומלץ לבדוק מה סיבת הבעיה + elasticsearch_index_mismatch: + message_html: מיפוי האינדקסים של Elasticsearch אינו עדכני. יש להריץ tootctl search deploy --only=%{value} + elasticsearch_preset: + action: יש לבדוק בתיעוד + message_html: אשכול שירותי חיפוש Elasticsearch שלך מכיל יותר משרת אחד, אך מסטודון אינו מכוון לשימוש בכולם. + elasticsearch_preset_single_node: + action: יש לבדוק בתיעוד + message_html: אשכול שירותי חיפוש Elasticsearch שלך מכיל רק שרת אחד, ES_PRESET צריך להכיל את הערך single_node_cluster. + elasticsearch_reset_chewy: + message_html: מיפוי האינדקסים של Elasticsearch אינו עדכני עקב שינוי תצורה. יש להריץ tootctl search deploy --reset-chewy כדי לעדכנו. elasticsearch_running_check: message_html: לא ניתן להתחבר לחיפוש אלסטיק. בדקו בבקשה הוא רץ, או בטלו את חיפוש הטקסט המלא elasticsearch_version_check: @@ -833,6 +884,18 @@ he: message_html: לא הוגדרו שום כללי שרת. sidekiq_process_check: message_html: שום הליכי Sidekiq לא רצים עבור %{value} תור(ות). בחנו בבקשה את הגדרות Sidekiq + software_version_critical_check: + action: ראו עדכונים זמינים + message_html: יצא עדכון קריטי למסטודון, נא לעדכן את תוכנת מסטודון בהקדם האפשרי. + software_version_patch_check: + action: ראו עדכונים זמינים + message_html: יצא עדכון מסטודון המכיל תיקוני שקצים. + upload_check_privacy_error: + action: למידע נוסף + message_html: "שרת הווב שלך אינו מכוון כראוי. פרטיות המשתמשות והמשתמשים שלך בסכנה." + upload_check_privacy_error_object_storage: + action: למידע נוסף + message_html: "שרות אחסון הענן שלך אינו מוגדר כראוי. פרטיות המשתמשות והמשתמשים שלך בסכנה." tags: review: סקירת מצב updated_msg: הגדרות תגיות עודכנו בהצלחה @@ -857,6 +920,7 @@ he: two: הופץ על ידי %{count} אנשים בשבוע האחרון title: קישוריות חמות usage_comparison: הופץ %{today} פעמים היום, לעומת %{yesterday} אתמול + not_allowed_to_trend: לא מורשה להופיע כנושא חם only_allowed: רק כאלה שהותרו pending_review: בהמתנה לבדיקה preview_card_providers: @@ -947,6 +1011,9 @@ he: body: "%{target} מערערים על החלטת מנהלי הקהילה ב-%{action_taken_by} מתאריך %{date}, שהיה %{type}. הם כתבו:" next_steps: ניתן לאשר את הערער כדי להפוך את החלטת מנהלי הקהילה, או להתעלם ממנו. subject: "%{username} מערערים על החלטת מנהלי הקהילה במופע %{instance}" + new_critical_software_updates: + body: יצא עדכון קריטי למסטודון, נא לעדכן את תוכנת מסטודון בהקדם האפשרי! + subject: יצא עדכון קריטי למסטודון שעל %{instance}! new_pending_account: body: פרטי החשבון החדש מובאים להלן. ניתן לאשר או לדחות את הבקשה. subject: חשבון חדש מובא לסקירה ב-%{instance} (%{username}) @@ -954,6 +1021,9 @@ he: body: "%{reporter} דיווחו על %{target}" body_remote: מישהם מהמופע %{domain} דיווחו על %{target} subject: דו"ח חדש מהמופע %{instance} (#%{id}) + new_software_updates: + body: יצאו עדכוני גרסת מסטודון חדשים, כדאי לעדכן! + subject: יצאו עדכוני גרסת מסטודון חדשים בשביל %{instance}! new_trends: body: 'הפריטים הבאים זקוקים לסקירה לפני שניתן יהיה להציגם פומבית:' new_trending_links: @@ -983,24 +1053,28 @@ he: guide_link: https://crowdin.com/project/mastodon guide_link_text: כולם יכולים לתרום. sensitive_content: תוכן רגיש - toot_layout: פריסת הודעה application_mailer: notification_preferences: שינוי העדפות דוא"ל salutation: "%{name}," settings: 'שינוי הגדרות דוא"ל: %{link}' + unsubscribe: בטל מנוי view: 'תצוגה:' view_profile: צפיה בפרופיל view_status: הצגת הודעה applications: created: ישום נוצר בהצלחה destroyed: ישום נמחק בהצלחה + logout: יציאה regenerate_token: יצירת אסימון גישה מחדש token_regenerated: אסימון גישה יוצר מחדש בהצלחה warning: זהירות רבה נדרשת עם מידע זה. אין לחלוק אותו אף פעם עם אף אחד! your_token: אסימון הגישה שלך auth: apply_for_account: הגשת בקשה לחשבון - change_password: סיסמה + captcha_confirmation: + help_html: אם יש לך בעיה בפתרון הקאפצ'ה, יש לפנות אלינו בכתובת %{email} ונוכל לעזור. + hint_html: עוד דבר אחד, עלינו לאשרר שאת(ה) אנושיים (לצורך סינון ספאם). נא לפתור את הקאפצ'ה להלן וללחוץ "המשך". + title: בדיקות אבטחה confirmations: wrong_email_hint: אם כתובת הדואל הזו איננה נכונה, ניתן לשנות אותה בעמוד ההגדרות. delete_account: מחיקת חשבון @@ -1009,7 +1083,7 @@ he: prefix_invited_by_user: "@%{name} רוצה שתצטרף לשרת זה במסטודון!" prefix_sign_up: הרשם/י למסטודון היום! suffix: כבעל/ת חשבון, תוכל/י לעקוב אחרי אנשים, לפרסם עדכונים ולהחליף חצרוצים עם משתמשים מכל שרת מסטודון ועוד! - didnt_get_confirmation: לא התקבלו הוראות אימות? + didnt_get_confirmation: לא קיבלת את קישור האימות? dont_have_your_security_key: אין לך מפתח אבטחה? forgot_password: הנשתכחה סיסמתך? invalid_reset_password_token: טוקן איפוס הסיסמה אינו תקין או שפג תוקף. נא לבקש אחד חדש. @@ -1022,26 +1096,39 @@ he: migrate_account_html: אם ברצונך להכווין את החשבון לעבר חשבון אחר, ניתן להגדיר זאת כאן. or_log_in_with: או התחבר באמצעות privacy_policy_agreement_html: קראתי והסכמתי למדיניות הפרטיות + progress: + confirm: אימות כתובת הדואל + details: הפרטים שלך + review: הבדיקה שלנו + rules: הסכמה לתקנות providers: cas: CAS saml: SAML register: הרשמה registration_closed: "%{instance} לא מקבל חברים חדשים" - resend_confirmation: שלח הוראות אימות בשנית + resend_confirmation: שלח מחדש קישור לאימות reset_password: איפוס סיסמה rules: + accept: הסכמה + back: בחזרה + invited_by: 'ניתן להצטרף אל %{domain} הודות להזמנה מאת:' preamble: אלו נקבעים ונאכפים ע"י המנחים של %{domain}. + preamble_invited: לפני ההמשך יש להתחשב בחוקי המקום כפי שקבעו מנהלי הדיון על %{domain}. title: כמה חוקים בסיסיים. + title_invited: קיבלת הזמנה. security: אבטחה set_new_password: סיסמה חדשה setup: - email_below_hint_html: אם כתובת הדוא"ל להלן לא נכונה, ניתן לשנותה כאן ולקבל דוא"ל אישור חדש. - email_settings_hint_html: דוא"ל האישור נשלח ל-%{email}. אם כתובת הדוא"ל הזו לא נכונה, ניתן לשנותה בהגדרות החשבון. - title: הגדרות + email_below_hint_html: אנא בדקו בתיקיית הספאם, או בקשו קוד חדש. ניתן לתקן את הכתובת אם נפלה תקלדה. + email_settings_hint_html: לחצו על הקישור שנשלח כדי לאשר את הכתובת %{email}. אנו ממתינים פה. + link_not_received: לא קיבלת קישור? + new_confirmation_instructions_sent: אתם עומדים לקבל הודעת דואל חדשה עם קיש/ור אימות בדקות הקרובות! + title: בדוק/בדקי את תיבת הדואר הנכנס שלך sign_in: preamble_html: הכנס.י עם שם וסיסמא מאתר %{domain}. אם חשבונך מתארח בשרת אחר, לא ניתן להתחבר איתו פה. title: התחבר אל %{domain} sign_up: + manual_review: פתיחת חשבון אצל %{domain} עוברת בדיקה ידנית על ידי הצוות שלנו. כדי לסייע בתהליך הרישום שלכןם, כתבו לנו על עצמכןם ולמה אתןם רוצותים חשבון בשרת %{domain}. preamble: כיוון שמסטודון מבוזרת, תוכל/י להשתמש בחשבון שלך משרתי מסטודון או רשתות תואמות אחרות אם אין לך חשבון על שרת זה. title: הבה ניצור לך חשבון בשרת %{domain}. status: @@ -1053,18 +1140,6 @@ he: view_strikes: צפיה בעברות קודמות שנרשמו נגד חשבונך too_fast: הטופס הוגש מהר מדי, נסה/י שוב. use_security_key: שימוש במפתח אבטחה - authorize_follow: - already_following: את/ה כבר עוקב/ת אחרי חשבון זה - already_requested: כבר נשלחה בקשת מעקב לחשבון זה - error: למרבה הצער, היתה שגיאה בחיפוש החשבון המרוחק - follow: לעקוב - follow_request: 'שלחת בקשת מעקב ל:' - following: 'הצלחה! הינך עוקב עכשיו אחרי:' - post_follow: - close: או, פשוט לסגור חלון זה. - return: הצג את פרופיל המשתמש - web: מעבר לווב - title: לעקוב אחרי %{acct} challenge: confirm: המשך hint_html: "טיפ: לא נבקש את סיסמתך שוב בשעה הקרובה." @@ -1141,6 +1216,10 @@ he: your_appeal_rejected: ערעורך נדחה domain_validator: invalid_domain: הוא לא שם דומיין קביל + edit_profile: + basic_information: מידע בסיסי + hint_html: "התאמה אישית של מה שיראו אחרים בפרופיל הציבורי שלך וליד הודעותיך. אחרים עשויים יותר להחזיר עוקב וליצור אתך שיחה אם הפרופיל והתמונה יהיו מלאים." + other: אחר errors: '400': הבקשה שהגשת לא תקינה. '403': חסרות לך הרשאות לצפיה בעמוד זה. @@ -1150,7 +1229,7 @@ he: '422': content: בדיקת אבטחה נכשלה. החסמת עוגיותיך מפנינו? title: בדיקת בטיחות נכשלה - '429': הוחנק + '429': יותר מדי קריאות לשרת '500': content: אנו מצטערות, אבל משהו השתבש בצד שלנו. title: דף זה אינו נכון @@ -1177,7 +1256,7 @@ he: featured_tags: add_new: הוספת חדש errors: - limit: המספר המירבי של התגיות כבר מוצג + limit: הצגת כבר את המספר המירבי של תגיות נבחרות hint_html: "מהן תגיות נבחרות? הן מוצגות במובלט בפרופיל הפומבי שלך ומאפשר לאנשים לעיין בהודעות הפומביות שלך המסומנות בתגיות אלה. הן כלי אדיר למעקב אחר עבודות יצירה ופרוייקטים לטווח ארוך." filters: contexts: @@ -1227,8 +1306,6 @@ he: index: hint: סנן זה חל באופן של בחירת הודעות בודדות ללא תלות בקריטריונים אחרים. תוכלו להוסיף עוד הודעות לסנן זה ממנשק הווב. title: הודעות שסוננו - footer: - trending_now: נושאים חמים generic: all: הכל all_items_on_page_selected_html: @@ -1241,7 +1318,9 @@ he: one: נבחר פריט %{count} שתאם לחיפוש בעמוד זה. other: נבחרו %{count} פריטים שתאמו לחיפוש בעמוד זה. two: נבחרו %{count} פריטים שתאמו לחיפוש בעמוד זה. + cancel: ביטול changes_saved_msg: השינויים נשמרו בהצלחה! + confirm: אישור copy: להעתיק delete: למחוק deselect: בטל בחירה של הכל @@ -1259,24 +1338,62 @@ he: one: משהו עדיין לא בסדר! נא לעיין בשגיאה להלן other: משהו עדיין לא בסדר! נא לעיין ב-%{count} השגיאות להלן two: משהו עדיין לא בסדר! נא לעיין ב-%{count} השגיאות להלן - html_validator: - invalid_markup: 'מכיל קוד HTML לא תקין: %{error}' imports: errors: + empty: קובץ CSV ריק + incompatible_type: אין תאימות עם סוג היבוא שנבחר invalid_csv_file: 'קובץ CSV שבור. שגיאה: %{error}' over_rows_processing_limit: מכיל יותר מ-%{count} עמודות + too_large: קובץ גדול מדי + failures: כשלים + imported: יובא + mismatched_types_warning: נראה שבחרת את שיטת היבוא הלא נכונה לקובץ, בבקשה לוודא בשנית. modes: merge: מיזוג merge_long: שמירת רשומות קיימות והוספת חדשות overwrite: דריסה overwrite_long: החלף רשומות נוכחיות בחדשות + overwrite_preambles: + blocking_html: אתם עומדים להחליף את רשימת החסימות עד כדי %{total_items} חשבונות מהקובץ %{filename}. + bookmarks_html: אתם עומדים להחליף את רשימת הסימניות עד כדי %{total_items} הודעות מהקובץ %{filename}. + domain_blocking_html: אתם עומדים להחליף את רשימת חסימות השרתים עד כדי %{total_items} שרתים מהקובץ %{filename}. + following_html: אתם עומדים לעקוב עד כדי %{total_items} חשבונות מהקובץ %{filename} ובמקביל להפסיק מעקב אחרי כל משתמש אחר. + lists_html: הפעולה הבאה תחליף את רשימותיך בתוכן של %{filename}. עד %{total_items} חשבונות יתווספו לרשימות חדשות. + muting_html: אתם עומדים להחליף את רשימת ההשתקות עד כדי %{total_items} חשבונות מהקובץ %{filename}. + preambles: + blocking_html: אתם עומדים לחסום עד %{total_items} חשבונות מהקובץ %{filename}. + bookmarks_html: אתם עומדים להוסיף עד %{total_items} הודעות מהקובץ %{filename} לרשימת הסימניות שלכם. + domain_blocking_html: אתם עומדים לחסום עד כדי %{total_items} שרתים מהקובץ %{filename}. + following_html: אתם עומדים לעקוב אחרי עד %{total_items} חשבונות מהקובץ %{filename}. + lists_html: הפעולה הבאה תוסיף עד %{total_items} חשבונות מהקובץ %{filename} אל הרשימות שלך. רשימות חדשות יווצרו אם עוד לא קיימת רשימה להוסיף אליה. + muting_html: אתם עומדים להשתיק עד %{total_items} חשבונות מהקובץ %{filename}. preface: ניתן ליבא מידע מסויים כגון כל הנעקבים או המשתמשים החסומים לתוך חשבונך על שרת זה, מתוך קבצים שנוצרו על ידי יצוא משרת אחר כגון רשימת הנעקבים והחסומים שלך. + recent_imports: ייבואים אחרונים + states: + finished: הסתיים + in_progress: בתהליך + scheduled: מתוזמן + unconfirmed: לא מאושרת + status: מצב success: כל המידע יובא בהצלחה, ויעובד בזמן הקרוב + time_started: התחיל ב + titles: + blocking: מייבא חשבונות חסומים + bookmarks: מייבא סימניות + domain_blocking: מייבא שרתים חסומים + following: מייבא חשבונות נעקבים + lists: יבוא רשימות + muting: מייבא חשבונות מושתקים + type: סוג יבוא + type_groups: + constructive: עקיבות וסימניות + destructive: חסימות והשתקות types: blocking: רשימת חסימות bookmarks: סימניות domain_blocking: רשימת שמות מתחם חסומים following: רשימת נעקבים + lists: רשימות muting: רשימת השתקות upload: יבוא invites: @@ -1305,7 +1422,7 @@ he: title: הזמנת אנשים lists: errors: - limit: הגעת למספר הרשימות המירבי. + limit: הגעת למספר הרשימות המירבי login_activities: authentication_methods: otp: יישומון אימות דו-שלבי @@ -1317,6 +1434,21 @@ he: failed_sign_in_html: נסיון כניסה כושל בשיטת %{method} מכתובת %{ip} (%{browser}) successful_sign_in_html: נסיון כניסה מוצלח בשיטה %{method} מכתובת %{ip} (%{browser}) title: הסטוריית אימותים + mail_subscriptions: + unsubscribe: + action: כן, לבטל הרשמה + complete: הפסקת הרשמה + confirmation_html: יש לאשר את ביטול ההרשמה להודעות %{type} ממסטודון בשרת %{domain} לכתובת הדואל %{email}. תמיד אפשר להרשם מחדש בכיוונוני הודעות דואל. + emails: + notification_emails: + favourite: הודעות דואל לגבי חיבובים + follow: הודעות דואל לגבי עוקבים חדשים + follow_request: הודעות דואל לגבי בקשות מעקב + mention: הודעות דואל לגבי איזכורים + reblog: הודעות דואל לגבי הידהודים + resubscribe_html: אם ביטול ההרשמה היה בטעות, ניתן להרשם מחדש מתוך מסך הגדרות ההרשמה שלך. + success_html: לא יגיעו אליך יותר הודעות %{type} משרת מסטודון %{domain} לכתובת הדואל %{email}. + title: הפסקת הרשמה media_attachments: validations: images_and_video: לא ניתן להוסיף וידאו להודעה שכבר מכילה תמונות @@ -1396,6 +1528,7 @@ he: update: subject: "%{name} ערכו הודעה" notifications: + administration_emails: התראות לדוא"ל חשבון מנהל email_events: ארועים להתראות דוא"ל email_events_hint: 'בחר/י ארועים עבורים תרצה/י לקבל התראות:' other_settings: הגדרות התראות אחרות @@ -1432,12 +1565,22 @@ he: expired: סקר זה כבר הסתיים invalid_choice: ההצבעה שנבחרה אינה קיימת over_character_limit: לא יכולים להיות יותר מ-%{max} תוים כל אחד + self_vote: אין אפשרות להצביע במשאל שפרסמת בעצמך too_few_options: חייב להכיל יותר מפריט אחד too_many_options: לא יכול להכיל יותר מ-%{max} פריטים preferences: other: שונות posting_defaults: ברירות מחדל להודעות public_timelines: פידים פומביים + privacy: + hint_html: "ניתן להתאים את הצורה שבה תירצו שיראו את פרופיל המשתמש וההודעות שלכם. מגוון אפשרויות במסטודון יכולות לעזור לכם להיחשף לקהל רחב יותר כאשר תפעילו אותן. הקדישו רגע לבדוק את ההגדרות הללו כדי לוודא שהן מתאימות לכם." + privacy: פרטיות + privacy_hint_html: הגדירו כמה תרצו לחשוף עצמכם לאחרים. משתמשים מגלים משתמשים מעניינים ואפליקציות מגניבות על ידי דפדוף ב-"מעקבים" של משתמשים אחרים ורואים מאילו אפליקציות הם מפרסמים, אבל אולי תעדיפו להסתיר את המידע הזה מפני אחרים. + reach: מידת חשיפה + reach_hint_html: הגדר כמה אנשים חדשים אתה רוצה שיגלו עליך ויעקבו אחריך. האם אתה רוצה שהפוסטים שלך יופיעו בדף הבית של האתר? האם אתה רוצה שאנשים אחרים יראו את המשתמש שלך בהמלצות המעקב שלהם? האם אתה רוצה לאשר את כל העוקבים החדשים שלך באופן אוטומטי, או שאתה רוצה לאשר אותם באופן ידני? + search: חיפוש + search_hint_html: הגדירו כיצד תרצו שימצאו אתכם. האם תרצו שאנשים ימצאו אתכם דרך הפוסטים שהועלו? האם תרצו שאנשים מחוץ למסטודון ימצאו את הפרופיל על ידי חיפוש באינטרנט? אנא זכרו שלא ניתן להבטיח החרגה מוחלטת מכל מנועי החיפוש עבור מידע ציבורי. + title: פרטיות ומידת חשיפה privacy_policy: title: מדיניות פרטיות reactions: @@ -1450,6 +1593,7 @@ he: confirm_remove_selected_followers: האם את/ה בטוח/ה שברצונך להסיר את העוקבים שסומנו? confirm_remove_selected_follows: האם את/ה בטוח/ה שברצונך להסיר את הנעקבים שסומנו? dormant: רדומים + follow_failure: נכשלה העקיבה אחרי חלק מהחשבונות שבחרת. follow_selected_followers: עקוב אחר הנעקבים שנבחרו followers: עוקבים following: נעקבים @@ -1489,6 +1633,7 @@ he: electron: אלקטרון firefox: פיירפוקס generic: דפדפן לא ידוע + huawei_browser: דפדפן וואווי ie: אינטרנט אקספלורר micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1498,6 +1643,7 @@ he: qq: דפדפן QQ safari: ספארי uc_browser: דפדפן UC + unknown_browser: דפדפן לא מזוהה weibo: Weibo current_session: חיבור נוכחי description: "%{browser} על %{platform}" @@ -1510,9 +1656,10 @@ he: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: מערכת הפעלה KaiOS linux: לינוקס mac: macOS - other: סביבה לא ידועה + unknown_platform: פלטפורמה לא מזוהה windows: חלונות windows_mobile: חלונות מובייל windows_phone: טלפון חלונות @@ -1595,7 +1742,6 @@ he: show_newer: הצג חדשים יותר show_older: הצג ישנים יותר show_thread: הצג שרשור - sign_in_to_participate: הכנס כדי להשתתף בשיחה title: '%{name}: "%{quote}"' visibilities: direct: ישיר @@ -1637,12 +1783,10 @@ he: '7889238': 3 חודשים min_age_label: סף גיל min_favs: השאר הודעות מחובבות לפחות - min_favs_hint: לא מוחק מי מהודעותיך שקיבלו לפחות את המספר הזה של חיבובים. להשאיר ריק כדי למחוק הודעות ללא קשר למספר החיבובים שקיבלו + min_favs_hint: לא תימחקנה הודעות שלך שקיבלו לפחות מספר זה של חיבובים. אם יישאר ריק, הודעות תימחקנה ללא תלות במספר החיבובים שלהן. min_reblogs: שמור הודעות מהודהדות לפחות min_reblogs_hint: לא מוחק מי מהודעותיך שקיבלו לפחות את המספר הזה של הדהודים. להשאיר ריק כדי למחוק הודעות ללא קשר למספר ההדהודים שקיבלו stream_entries: - pinned: הודעה נעוצה - reblogged: הודהד sensitive_content: תוכן רגיש strikes: errors: @@ -1658,6 +1802,11 @@ he: default: "%d %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: השימוש בשירות התירגום בשרת זה עבר את המכסה שהוקצתה. + too_many_requests: לאחרונה היו יותר מדי פניות אל שירות התרגום. two_factor_authentication: add: הוספה disable: כיבוי @@ -1737,13 +1886,18 @@ he: title: ברוך/ה הבא/ה, %{name} ! users: follow_limit_reached: לא תוכל לעקוב אחר יותר מ %{limit} אנשים + go_to_sso_account_settings: מעבר לאפיוני החשבון שלך בשרת הזהות invalid_otp_token: קוד דו-שלבי שגוי otp_lost_help_html: אם איבדת גישה לשניהם, ניתן ליצור קשר ב-%{email} seamless_external_login: את.ה מחובר דרך שירות חיצוני, לכן אפשרויות הסיסמא והדוא"ל לא מאופשרות. signed_in_as: 'מחובר בתור:' verification: - explanation_html: 'ניתן לאמת את עצמך כבעלים של הקישורית במטא-נתונים של פרופילך. כדי לעשות זאת, האתר המקושר חייב להכיל קישורית חוזרת לפרופיל המסטודון שלך. הקישורית החוזרת חייבת להכיל תכונת rel="me". התוכן הטקסטואלי של הקישורית לא משנה. הנה דוגמא:' + extra_instructions_html: טיפ: הלינק באתר שלך יכול להיות מוסתר. החלק החשוב הוא rel="me" שמונע התחזות על אתרים עם תוכן משתמשים. ניתן גם ליצור תגית link בכותרת העמוד במקום קישור a אבל קוד ה־HTML חייב להופיע שם ללא הרצה של ג'אווהסקריפט. + here_is_how: זה נעשה כך + hint_html: "אשרור זהותך במסטודון הוא לטובת כולם. על בסיס תקני ווב פתוחים, חינם מעתה ולעד. כל שדרוש הוא אתר אישי שבו אנשים מזהים אותך דרכו. כשתקשרו מהאתר הזה לפרופיל שלך פה, אנו נבדוק באתר קישורים לפרופיל ונציין זאת בסימן בולט כזהות בדוקה." + instructions_html: יש להדביק את הקוד שלמטה אל האתר שלך. ואז להוסיף את כתובת האתר לאחד השדות הנוספים בפרופיל מתוך טאב "עריכת פרופיל" ולשמור את השינויים. verification: אימות + verified_links: קישוריך המאומתים webauthn_credentials: add: הוספת מפתח אבטחה חדש create: diff --git a/config/locales/hi.yml b/config/locales/hi.yml index 50fae82bd8..9b505e5f92 100644 --- a/config/locales/hi.yml +++ b/config/locales/hi.yml @@ -1,10 +1,52 @@ --- hi: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. + about: + contact_missing: सेट नहीं + contact_unavailable: लागू नहीं है + title: के बारे में + accounts: + follow: अनुसरे + following: फ़ॉलो कर रहे हैं + instance_actor_flash: यह खाता आभासी है जो सर्वर को दिखाने के लिये है और ये किसी व्यक्तिका प्रतिनिधित्व नहि करता। यह सिर्फ देखरेख के हेतु से कार्यरत है और इसको निलंबित करने कि आवश्यकता नहि है। + last_active: आखिरि बार इस वक्त सक्रिय थे + link_verified_on: इस लिंक का स्वामित्व %{date} को चेक किया गया था + nothing_here: यहां कुछ नहीं है + admin: + accounts: + approve: प्रमाणित करे + approved_msg: सफलता से %{username} का खाता खोलने का आवेदन प्रमाणित किया गया + are_you_sure: क्या आप निश्चित है? + avatar: छबि + ip: आई. पि. पता + location: + all: सभी + local: स्थानीय + remote: दूरस्थ + title: स्थान + login_status: प्रवेश कि स्थिति + moderation: + all: सभी + silenced: सीमित + search: खोजें + search_same_email_domain: यहि इ-मेइल डोमैन वाले अन्य सदस्य + silence: सीमा + silenced: सीमित + title: खाते + system_checks: + upload_check_privacy_error: + message_html: " आपके वेब सर्वर का कन्फिगरेशन सही नहीं है। उपयोगकर्ताओं की निजता खतरे में है। " + upload_check_privacy_error_object_storage: + action: अधिक जानकारी हेतु यहां क्लिक करें। + message_html: " आपके वेब सर्वर का कन्फिगरेशन सही नहीं है। उपयोगकर्ताओं की निजता खतरे में है। " + relationships: + follow_failure: चुने हुए अकाउंट्स में से कुछ को फ़ॉलो नहीं किया जा सकता + sessions: + browsers: + huawei_browser: हुआवे ब्राउज़र + unknown_browser: अनजान ब्राउज़र + platforms: + kai_os: काइ ओएस + unknown_platform: अनजान प्लेटफॉर्म + time: + formats: + with_time_zone: "%b %d, %Y, %H:%M %Z" diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 0563712266..aa7ee760ba 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -3,6 +3,7 @@ hr: about: about_mastodon_html: 'Društvena mreža budućnosti: bez oglasa, bez korporativnog nadzora, etički dizajn i decentralizacija! Budite u vlasništvu svojih podataka pomoću Mastodona!' contact_missing: Nije postavljeno + title: O aplikaciji accounts: follow: Prati following: Praćenih @@ -17,18 +18,26 @@ hr: accounts: approve: Odobri are_you_sure: Jeste li sigurni? + avatar: Avatar by_domain: Domena change_email: + changed_msg: E-pošta računa uspješno je promijenjena! current_email: Trenutna e-pošta label: Promijeni e-poštu new_email: Nova e-pošta submit: Promijeni e-poštu title: Promjena e-pošte za %{username} + change_role: + changed_msg: Uloga uspješno dodijeljena! + label: Promjeni ulogu confirm: Potvrdi confirmed: Potvrđeno confirming: Potvrđivanje + custom: Prilagođeno delete: Izbriši podatke deleted: Izbrisano + disable: Zamrzni + disable_two_factor_authentication: Onemogući 2FA display_name: Prikazano ime domain: Domena edit: Uredi @@ -53,19 +62,13 @@ hr: settings: 'Promijeni postavke e-pošte: %{link}' view: 'Vidi:' auth: - didnt_get_confirmation: Niste primili upute za potvrđivanje? forgot_password: Zaboravljena lozinka? login: Prijavi se logout: Odjavi se register: Registriraj se - resend_confirmation: Ponovo pošalji upute za potvrđivanje reset_password: Ponovno postavi lozinku security: Sigurnost set_new_password: Postavi novu lozinku - authorize_follow: - error: Nažalost, došlo je do greške tijekom traženja udaljenog računa - follow: Prati - title: Prati %{acct} datetime: distance_in_words: about_x_months: "%{count}mj" @@ -75,14 +78,6 @@ hr: less_than_x_seconds: Upravo sada over_x_years: "%{count}god" x_months: "%{count}mj" - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. exports: archive_takeout: date: Datum @@ -99,8 +94,6 @@ hr: title: Filteri new: title: Dodaj novi filter - footer: - trending_now: Popularno generic: all: Sve changes_saved_msg: Izmjene su uspješno sačuvane! @@ -167,8 +160,6 @@ hr: remote_follow: missing_resource: Nije moguće pronaći traženi URL preusmjeravanja za Vaš račun sessions: - platforms: - other: nepoznata platforma revoke: Opozovi revoke_success: Sesija je uspješno opozvana title: Sesije @@ -209,7 +200,6 @@ hr: public: Javno unlisted: Neprikazano stream_entries: - reblogged: boostano sensitive_content: Osjetljivi sadržaj two_factor_authentication: disable: Onemogući 2FA diff --git a/config/locales/hu.yml b/config/locales/hu.yml index a9315b1f24..f9eafb9081 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -91,6 +91,7 @@ hu: moderation: active: Aktív all: Összes + disabled: Letiltva pending: Függőben silenced: Korlátozott suspended: Felfüggesztve @@ -124,8 +125,8 @@ hu: removed_header_msg: A %{username} fiók fejlécét sikeresen töröltük resend_confirmation: already_confirmed: Ezt a felhasználót már megerősítették - send: Megerősítő e-mail újraküldése - success: A megerősítő e-mail sikeresen elküldve! + send: Megerősítő hivatkozás újraküldése + success: A megerősítő hivatkozás sikeresen elküldésre került! reset: Visszaállítás reset_password: Jelszó visszaállítása resubscribe: Feliratkozás ismét @@ -133,6 +134,7 @@ hu: search: Keresés search_same_email_domain: Felhasználók ugyanezzel az email domainnel search_same_ip: Más felhasználók ugyanezzel az IP-vel + security: Biztonság security_measures: only_password: Csak jelszó password_and_2fa: Jelszó és kétlépcsős hitelesítés @@ -307,6 +309,7 @@ hu: unpublish: Közzététel visszavonása unpublished_msg: A közlemény közzététele sikeresen visszavonva! updated_msg: A közlemény sikeresen frissítve! + critical_update_pending: Függőben levő kritikus frissítés custom_emojis: assign_category: Kategória hozzárendelése by_domain: Domain @@ -380,6 +383,15 @@ hu: undo: Eltávolítás az engedélyező-listáról domain_blocks: add_new: Új tiltott domain hozzáadása + confirm_suspension: + cancel: Mégsem + confirm: Felfüggesztés + permanent_action: A felfüggesztés visszavonása nem fogja az adatokat vagy kapcsolatokat visszaállítani. + preamble_html: A %{domain} domain és aldomainjeinek felfüggesztésére készülsz. + remove_all_data: A kiszolgálódról a domainhez tartozó fiókok minden tartalmát, médiáját, profiladatát el fogja távolítani. + stop_communication: A kiszolgálód nem fog kommunikálni ezekkel a kiszolgálókkal. + title: "%{domain} domain letiltásának megerősítése" + undo_relationships: Minden kapcsolatot megszüntet az ezen kiszolgálókon lévő fiókok és a te kiszolgálód fiókjai között. created_msg: A domain-tiltás feldolgozása folyamatban destroyed_msg: A domain tiltása feloldva domain: Domain @@ -427,6 +439,7 @@ hu: resolve: Domain feloldása title: Új e-mail domain tiltása no_email_domain_block_selected: Nem változott meg egy domain tiltás sem, mert semmi sem volt kiválasztva + not_permitted: Nem engedélyezett resolved_dns_records_hint_html: A domain név a következő MX domain-ekre oldódik fel, melyek valójában fogadják az e-mailt. Az MX domain letiltása minden olyan feliratkozást tiltani fog, melyben az e-mailcím ugyanazt az MX domaint használja, még akkor is, ha a látható domain név más. Légy óvatos, hogy ne tilts le nagy e-mail szolgáltatókat. resolved_through_html: Feloldva %{domain}-n keresztül title: Tiltott e-mail domainek @@ -473,6 +486,7 @@ hu: content_policies: comment: Belső megjegyzés description_html: Definiálhatsz tartalmi szabályokat, melyek ezen domain és minden aldomain fiókjára vonatkozni fognak. + limited_federation_mode_description_html: Eldöntheted, hogy engeded-e a föderációt ezzel a domainnel. policies: reject_media: Média elutasítása reject_reports: Bejelentések elutasítása @@ -585,11 +599,13 @@ hu: assign_to_self: Magamhoz rendelés assigned: Hozzárendelt moderátor by_target_domain: A bejelentett fiók domainje + cancel: Mégse category: Kategória category_description_html: A fiók vagy tartalom bejelentésének oka a jelentett fiókkal kapcsolatos kommunikációban idézve lesz comment: none: Egyik sem comment_description_html: 'Hogy további információkat adjon, %{name} ezt írta:' + confirm: Megerősítés confirm_action: Moderációs művelet jóváhagyása @%{acct} fiókon created_at: Jelentve delete_and_resolve: Bejegyzések törlése @@ -725,6 +741,9 @@ hu: branding: preamble: A kiszolgáló márkajelzése különbözteti meg a hálózat többi kiszolgálójától. Ez az információ számos környezetben megjelenhet, például a Mastodon webes felületén, natív alkalmazásokban, más weboldalakon és üzenetküldő alkalmazásokban megjelenő hivatkozások előnézetben stb. Ezért a legjobb, ha ez az információ világos, rövid és tömör. title: Branding + captcha_enabled: + desc_html: Ez hCaptcha-ból származó külső scripteket használ, mely biztonsági vagy adatvédelmi résnek bizonyulhat. Ezen kívül ez a regisztrációs folyamatot jelentősen megnehezítheti bizonyos (kifejezetten különleges szükségletű) emberek számára. Emiatt fontold meg más módszerek, mint pl. jóváhagyás-alapú vagy meghívásalapú regisztráció használatát. + title: Az új felhasználóknak egy CAPTCHA-t kell megoldaniuk, hogy megerősítsék a fiókjuk regisztrációját content_retention: preamble: Felhasználók által generált tartalom Mastodonon való tárolásának szabályozása. title: Tartalom megtartása @@ -752,10 +771,27 @@ hu: approved: A regisztráció engedélyhez kötött none: Senki sem regisztrálhat open: Bárki regisztrálhat - title: Kiszolgálóbeállítások + security: + authorized_fetch: Hitelesítés szükséges a föderációs kiszolgálóktól + authorized_fetch_hint: A föderációs szerverek hitelesítésének szükségessége lehetővé teszi mind a felhasználói mind a szerver szintű blokkok szigorúbb végrehajtását. Ez azonban a teljesítménybüntetés árán jár, csökkenti a válaszok elérhetőségét és kompatibilitási problémákat vethet fel egyes föderációs szolgáltatásokkal. Emellett ez nem akadályozza meg a dedikált szereplőket abban, hogy nyilvános bejegyzéseiket és fiókjaikat letöltsék. + authorized_fetch_overridden_hint: Jelenleg nem lehet ezt a beállítást megváltoztatni, mert azt egy környezeti változó felülbírálja. + federation_authentication: Föderációs hitelesítés kikényszerítése + title: Kiszolgáló-beállítások site_uploads: delete: Feltöltött fájl törlése destroyed_msg: Sikeresen töröltük a site feltöltését! + software_updates: + critical_update: Kritikus - frissíts gyorsan + description: Javasolt, hogy a Mastodon telepítésed naprakész legyen, hogy kihasználhasd a legújabb javításokat és funkciókat. Ezenkívül néha különösen fontos a Mastodon időben történő frissítése a biztonsági problémák elkerülése érdekében. Ezen okok miatt a Mastodon 30 percenként ellenőrzi a frissítéseket és az email értesítési preferenciáknak megfelelően értesítést küld. + documentation_link: További információ + release_notes: Kiadási megjegyzések + title: Elérhető frissítések + type: Típus + types: + major: Fő kiadás + minor: Kisebb kiadás + patch: Javító kiadás - hibajavítások és könnyen alkalmazható változtatások + version: Verzió statuses: account: Szerző application: Alkalmazás @@ -792,9 +828,24 @@ hu: suspend: "%{name} felfüggesztette %{target} fiókját" appeal_approved: Megfellebbezve appeal_pending: Fellebbezés folyamatban + appeal_rejected: Fellebbezés visszautasítva system_checks: database_schema_check: message_html: Vannak esedékes adatbázis migrációink. Kérlek, futtasd őket, hogy biztosítsd, hogy az alkalmazás megfelelően működjön + elasticsearch_health_red: + message_html: Az Elasticsearch klaszter egészségtelen (piros állapotú), a keresési funkciók nem érhetők el + elasticsearch_health_yellow: + message_html: Az Elasticsearch klaszter egészségtelen (sárga állapotú), érdemes megvizsgálni az okát + elasticsearch_index_mismatch: + message_html: Az Elasticsearch index leképezések elavultak. Futtasd le a tootctl search deploy --only=%{value} parancsot + elasticsearch_preset: + action: Dokumentáció megtekintése + message_html: Az Elasticsearch klaszter egynél több csomóponttal rendelkezik, de a Mastodon nincs beállítva ezek használatára. + elasticsearch_preset_single_node: + action: Dokumentácó megtekintése + message_html: Az Elasticsearch klaszterednek csak egy csomópontja van, az ES_PRESET értéket single_node_cluster értékre kell állítani. + elasticsearch_reset_chewy: + message_html: Az Elasticsearch rendszerindexed egy beállításmódosítás miatt elavult. A frissítéshez futtasd a tootctl search deploy --reset-chewy parancsot. elasticsearch_running_check: message_html: Nem sikerült az Elasticsearchhöz kapcsolódni. Ellenőrizze, hogy fut-e, vagy kapcsolja ki a teljes szöveges keresést. elasticsearch_version_check: @@ -805,6 +856,18 @@ hu: message_html: Még nem definiáltál egy szerver szabályt sem. sidekiq_process_check: message_html: Nincs Sidekiq folyamat, mely a %{value} sorhoz van rendelve. Kérlek, nézd át a Sidekiq beállításait + software_version_critical_check: + action: Elérhető frissítések megtekintése + message_html: Kritikus Mastodon frissítés érhető el, frissíts a lehető leggyorsabban. + software_version_patch_check: + action: Elérhető frissítések megtekintése + message_html: Egy hibajavító Mastodon-frissítés elérhető. + upload_check_privacy_error: + action: Itt találsz több információt + message_html: "A webkiszolgálód félre van konfigurálva. Kockázat merül fel a felhasználóid adatainak biztonságával kapcsolatban." + upload_check_privacy_error_object_storage: + action: Itt találsz több információt + message_html: "Az objektumtárolód félre van konfigurálva. Kockázat merül fel a felhasználóid adatainak biztonságával kapcsolatban." tags: review: Engedélyezés állapota updated_msg: A hashtag beállításokat sikeresen frissítettük @@ -827,6 +890,7 @@ hu: other: "%{count} ember osztotta meg a múlt héten" title: Felkapott hivatkozások usage_comparison: "%{today} alkalommal lett ma megosztva, a tegnapi %{yesterday} alkalomhoz képest" + not_allowed_to_trend: Nem engedélyezett a trendekben only_allowed: Csak engedélyezett pending_review: Áttekintésre vár preview_card_providers: @@ -844,8 +908,8 @@ hu: no_status_selected: Nem változott meg egy felkapott bejegyzés sem, mert semmi sem volt kiválasztva not_discoverable: A szerző nem járult hozzá, hogy mások rátalálhassanak shared_by: - one: Megosztva vagy kedvencnek jelölve egy alkalommal - other: Megosztva és kedvencnek jelölve %{friendly_count} alkalommal + one: Egy alkalommal megosztva és kedvencek közé helyezve + other: "%{friendly_count} alkalommal megosztva és kedvencek közé helyezve" title: Felkapott bejegyzések tags: current_score: 'Jelenlegi pontszám: %{score}' @@ -911,6 +975,9 @@ hu: body: "%{target} fellebbezi %{action_taken_by} moderátor %{date}-i, %{type} szóló döntését. Ezt írták:" next_steps: Jóváhagyhatod a fellebbezést, hogy semmissé tedd a moderátori döntést, vagy figyelmen kívül hagyhatod. subject: "%{username} fellebbez egy moderátori döntést a %{instance} szerveren" + new_critical_software_updates: + body: Megjelent a Mastodon új kritikus verziója, érdemes lehet a lehető leghamarabb frissíteni! + subject: A %{instance} kiszolgálóhoz kritikus Mastodon frissítések érhetőek el! new_pending_account: body: Az új fiók részletesen alább látható. Ezt a jelentkezést engedélyezheted vagy elutasíthatod. subject: Új fiók (%{username}) engedélyezésre vár a %{instance} szerveren @@ -918,6 +985,9 @@ hu: body: "%{reporter} jelentette: %{target}" body_remote: Valaki a %{domain} domainről jelentette %{target} subject: 'Új jelentés az alábbi szerveren: %{instance} (#%{id})' + new_software_updates: + body: Új Mastodon verziók jelentek meg, amelyeket érdemes frissíteni! + subject: Új Mastodon verziók érhetőek el a %{instance} kiszolgálóhoz! new_trends: body: 'A következő elemeket ellenőrizni kell, mielőtt nyilvánosan megjelennének:' new_trending_links: @@ -947,24 +1017,28 @@ hu: guide_link: https://crowdin.com/project/mastodon guide_link_text: Bárki közreműködhet. sensitive_content: Kényes tartalom - toot_layout: Bejegyzések elrendezése application_mailer: notification_preferences: E-mail beállítások módosítása salutation: "%{name}!" settings: 'E-mail beállítások módosítása: %{link}' + unsubscribe: Leiratkozás view: 'Megtekintés:' view_profile: Profil megtekintése view_status: Bejegyzés megtekintése applications: created: Alkalmazás sikeresen létrehozva destroyed: Alkalmazás sikeresen eltávolítva + logout: Kijelentkezés regenerate_token: Hozzáférési kulcs újragenerálása token_regenerated: Hozzáférési kulcs sikeresen újragenerálva warning: Ez érzékeny adat. Soha ne oszd meg másokkal! your_token: Hozzáférési kulcsod auth: apply_for_account: Fiók kérése - change_password: Jelszó + captcha_confirmation: + help_html: Ha problémáid vannak a CAPTCHA-val, kapcsolatba léphetsz velünk a %{email} címen és segítünk. + hint_html: Még egy dolog! Meg kell győződnünk róla, hogy tényleg valós személy vagy (így távol tarthatjuk a spam-et). Oldd meg az alábbi CAPTCHA-t és kattints a "Folytatás"-ra. + title: Biztonsági ellenőrzés confirmations: wrong_email_hint: Ha az emailcím nem helyes, a fiókbeállításokban megváltoztathatod. delete_account: Felhasználói fiók törlése @@ -973,7 +1047,7 @@ hu: prefix_invited_by_user: "@%{name} meghív téged, hogy csatlakozz ehhez a Mastodon kiszolgálóhoz." prefix_sign_up: Regisztrláj még ma a Mastodonra! suffix: Egy fiókkal követhetsz másokat, bejegyzéseket tehetsz közzé, eszmét cserélhetsz más Mastodon szerverek felhasználóival! - didnt_get_confirmation: Nem kaptad meg a megerősítési lépéseket? + didnt_get_confirmation: Nem kaptál visszaigazoló hivatkozást? dont_have_your_security_key: Nincs biztonsági kulcsod? forgot_password: Elfelejtetted a jelszavad? invalid_reset_password_token: A jelszó-visszaállítási kulcs nem megfelelő vagy lejárt. Kérlek generálj egy újat. @@ -986,26 +1060,39 @@ hu: migrate_account_html: Ha szeretnéd átirányítani ezt a fiókodat egy másikra, a beállításokat itt találod meg. or_log_in_with: Vagy jelentkezz be ezzel privacy_policy_agreement_html: Elolvastam és egyetértek az adatvédemi nyilatkozattal + progress: + confirm: E-mail-cím megerősítése + details: Saját adatok + review: A felülvizsgálatunk + rules: Szabályok elfogadása providers: cas: CAS saml: SAML register: Regisztráció registration_closed: "%{instance} nem fogad új tagokat" - resend_confirmation: Megerősítési lépések újraküldése + resend_confirmation: Megerősítő hivatkozás újraküldése reset_password: Jelszó visszaállítása rules: + accept: Elfogadás + back: Vissza + invited_by: 'Csatlakozhatsz a %{domain} kiszolgálóhoz, köszönhetően a meghívónak, melyet tőle kaptál:' preamble: Ezeket a(z) %{domain} moderátorai adjak meg és tartatják be. + preamble_invited: Mielőtt csatlakozol, kérlek vedd fontolóra a %{domain} moderátorai által állított szabályokat. title: Néhány alapszabály. + title_invited: Meghívtak. security: Biztonság set_new_password: Új jelszó beállítása setup: - email_below_hint_html: Ha az alábbi e-mail cím nem megfelelő, itt megváltoztathatod és kaphatsz egy új igazoló e-mailt. - email_settings_hint_html: A visszaigazoló e-mailt elküldtük ide %{email}. Ha az e-mail cím nem megfelelő, megváltoztathatod a fiókod beállításainál. - title: Beállítás + email_below_hint_html: Nézd meg a levélszemét mappát, vagy kérj egy újat. Módosíthatod az e-mail-címet, ha az hibás. + email_settings_hint_html: Kattints a hivatkozásra, melyet a(z) %{email} megerősítése céljából küldtünk. Addig várni fogunk. + link_not_received: Nem kaptad meg a hivatkozást? + new_confirmation_instructions_sent: Néhány perc múlva új e-mailt fogsz kapni a megerősítési hivatkozással. + title: Bejövő postaláda ellenőrzése sign_in: - preamble_html: Jelentkezz be a %{domain} fiókoddal. Ha másik kiszolgálón található a fiókod, akkor itt nem fogsz tudni belépni. - title: Jelentkezz be a %{domain}-ra + preamble_html: Jelentkezz be a %{domain} hitelesítéső adataiddal. Ha másik kiszolgálón található a fiókod, akkor itt nem fogsz tudni belépni. + title: 'Bejelentkezés ide: %{domain}' sign_up: + manual_review: A(z) %{domain} regisztrációi a moderátorok kézi felülvizsgálatán mennek át. Hogy segítsd a regisztráció feldolgozását, írj röviden magadról, és hogy miért szeretnél fiókot a(z) %{domain} oldalon. preamble: Egy fiókkal ezen a Mastodon kiszolgálón követhetsz bárkit a hálózaton, függetlenül attól, hogy az illető fiókja melyik kiszolgálón található. title: Állítsuk be a fiókod a %{domain} kiszolgálón. status: @@ -1017,18 +1104,6 @@ hu: view_strikes: Fiókod ellen felrótt korábbi vétségek megtekintése too_fast: Túl gyorsan küldted el az űrlapot, próbáld később. use_security_key: Biztonsági kulcs használata - authorize_follow: - already_following: Már követed ezt a felhasználót - already_requested: Már küldtél követési kérelmet ennek a fióknak - error: Hiba történt a távoli felhasználó keresésekor - follow: Követés - follow_request: 'Engedélyt kértél az alábbi felhasználó követésére:' - following: 'Siker! Mostantól követed az alábbi felhasználót:' - post_follow: - close: Akár be is zárhatod ezt az ablakot. - return: A felhasználó profiljának mutatása - web: Megtekintés a weben - title: "%{acct} követése" challenge: confirm: Folytatás hint_html: "Hasznos: Nem fogjuk megint a jelszavadat kérdezni a következő órában." @@ -1105,6 +1180,10 @@ hu: your_appeal_rejected: A fellebbezésedet visszautasították domain_validator: invalid_domain: nem egy valódi domain név + edit_profile: + basic_information: Általános információk + hint_html: "Tedd egyedivé, mi látnak mások a profilodon és a bejegyzéseid mellett. Mások nagyobb eséllyel követnek vissza és lépnek veled kapcsolatba, ha van kitöltött profilod és profilképed." + other: Egyéb errors: '400': A küldött kérés érvénytelen vagy hibás volt. '403': Nincs jogosultságod az oldal megtekintéséhez. @@ -1141,7 +1220,7 @@ hu: featured_tags: add_new: Új hozzáadása errors: - limit: Már kiemelted a maximálisan engedélyezett számú hashtaget + limit: Elérted a maximálisan kitűzhető hashtagek számát hint_html: "Mik a kiemelt hashtagek? Ezek állandóan megjelennek a nyilvános profilodon és lehetővé teszik, hogy mások kifejezetten az ezekhez tartozó bejegyzéseidet böngésszék. Jó eszköz ez kreatív munkák vagy hosszútávú projektek nyomonkövetésére." filters: contexts: @@ -1185,8 +1264,6 @@ hu: index: hint: Ez a szűrő egyedi bejegyzések kiválasztására vonatkozik a megadott kritériumoktól függetlenül. Újabb bejegyzéseket adhatsz hozzá ehhez a szűrőhöz a webes felületen keresztül. title: Megszűrt bejegyzések - footer: - trending_now: Most felkapott generic: all: Mind all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ hu: all_matching_items_selected_html: one: "%{count}, a keresésnek megfelelő elem kiválasztva." other: Mind a(z) %{count}, a keresésnek megfelelő elem kiválasztva. + cancel: Mégse changes_saved_msg: A változásokat elmentettük! + confirm: Megerősítés copy: Másolás delete: Törlés deselect: Összes kiválasztás megszüntetése @@ -1209,24 +1288,62 @@ hu: validation_errors: one: Valami nincs rendjén! Tekintsd meg a hibát lent other: Valami nincs rendjén! Tekintsd meg a(z) %{count} hibát lent - html_validator: - invalid_markup: 'hibás HTML leíró: %{error}' imports: errors: + empty: Üres CSV-fájl + incompatible_type: Nem kompatibilis a kiválasztott importálási típussal invalid_csv_file: 'Érvénytelen CSV-fájl. Hiba: %{error}' over_rows_processing_limit: több mint %{count} sort tartalmaz + too_large: A fájl túl nagy + failures: Hibák + imported: Importálva + mismatched_types_warning: Úgy tűnik, hogy rossz típust választottál az importáláshoz. Ellenőrizd még egyszer. modes: merge: Összefésülés merge_long: Megtartjuk a meglévő bejegyzéseket és hozzávesszük az újakat overwrite: Felülírás overwrite_long: Lecseréljük újakkal a jelenlegi bejegyzéseket + overwrite_preambles: + blocking_html: 'Arra készülsz, hogy lecseréld a letiltási listát legfeljebb %{total_items} fiókra a következőből: %{filename}.' + bookmarks_html: 'Arra készülsz, hogy lecseréld a könyvjelzőket legfeljebb %{total_items} bejegyzésre a következőből: %{filename}.' + domain_blocking_html: 'Arra készülsz, hogy lecseréld a domain letiltási listát legfeljebb %{total_items} domainre a következőből: %{filename}.' + following_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot kövess a következőből: %{filename}, és abbahagyd mindenki más követését.' + lists_html: Arra készülsz, hogy a listákat lecseréld a %{filename} tartalmával. Legfeljebb %{total_items} fiók kerül fel az új listákra. + muting_html: 'Arra készülsz, hogy lecseréld a némított fiókok listáját legfeljebb %{total_items} fiókra a következőből: %{filename}.' + preambles: + blocking_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot letilts a következőből: %{filename}.' + bookmarks_html: 'Arra készülsz, hogy legfeljebb %{total_items} bejegyzést adj hozzá a könyvjelzőkhöz a következőből: %{filename}.' + domain_blocking_html: 'Arra készülsz, hogy legfeljebb %{total_items} domaint letilts a következőből: %{filename}.' + following_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot kövess a következőből: %{filename}.' + lists_html: Arra készülsz, hogy legfeljebb %{total_items} fiókot hozzáadj a %{filename} fájlból a listákhoz. Új listák jönnek létre, ha nincs hozzáadható lista. + muting_html: 'Arra készülsz, hogy legfeljebb %{total_items} fiókot némíts a következőből: %{filename}.' preface: Itt importálhatod egy másik kiszolgálóról lementett adataidat, például követettjeid és letiltott felhasználóid listáját. + recent_imports: Legutóbbi importálások + states: + finished: Befejezve + in_progress: Folyamatban + scheduled: Időzítve + unconfirmed: Nem megerősítve + status: Állapot success: Adataidat sikeresen feltöltöttük és feldolgozásukat megkezdtük + time_started: 'Kezdés ideje:' + titles: + blocking: Letiltott fiókok importálása + bookmarks: Könyvjelzők importálása + domain_blocking: Letiltott domainek importálása + following: Követett fiókok importálása + lists: Listák importálása + muting: Némított fiókok importálása + type: Importálás típusa + type_groups: + constructive: Követések és könyvjelzők + destructive: Letiltások és némítások types: blocking: Letiltottak listája bookmarks: Könyvjelzők domain_blocking: Letiltott domainek listája following: Követettjeid listája + lists: Listák muting: Némított felhasználók listája upload: Feltöltés invites: @@ -1253,7 +1370,7 @@ hu: title: Meghívások lists: errors: - limit: Elérted a hozzáadható listák maximális számát + limit: Elérted a listák maximális számát login_activities: authentication_methods: otp: kétlépcsős azonosító alkalmazás @@ -1265,6 +1382,21 @@ hu: failed_sign_in_html: Bejelentkezés meghiúsult ezzel %{method} innen %{ip} (%{browser}) successful_sign_in_html: Sikeres bejelentkezés ezzel %{method} innen %{ip} (%{browser}) title: Hitelesítési történet + mail_subscriptions: + unsubscribe: + action: Igen, leiratkozás + complete: Leiratkozva + confirmation_html: Biztos vagy benne, hogy le szeretnél iratkozni arról, hogy %{type} típusú üzeneteket kapj a %{domain} Mastodon kiszolgálón a %{email} címedre? Bármikor újra feliratkozhatsz az email értesítések beállításainál. + emails: + notification_emails: + favourite: kedvencnek jelölésről email értesítő + follow: követésről email értesítő + follow_request: követési kérelemről email értesítő + mention: megemlítésről email értesítő + reblog: megtolásról email értesítő + resubscribe_html: Ha tévedésből iratkoztál le, újra feliratkozhatsz az email értesítések beállításainál. + success_html: Mostantól nem kapsz %{type} típusú üzeneket a %{domain} Mastodon kiszolgálón a %{email} címedre. + title: Leiratkozás media_attachments: validations: images_and_video: Nem csatolhatsz videót olyan bejegyzéshez, amelyhez már csatoltál képet @@ -1316,9 +1448,9 @@ hu: sign_up: subject: "%{name} feliratkozott" favourite: - body: 'A bejegyzésedet kedvencnek jelölte %{name}:' + body: 'A bejegyzésedet %{name} kedvencnek jelölte:' subject: "%{name} kedvencnek jelölte a bejegyzésedet" - title: Új kedvencnek jelölés + title: Új kedvenc follow: body: "%{name} mostantól követ téged!" subject: "%{name} mostantól követ téged" @@ -1344,6 +1476,7 @@ hu: update: subject: "%{name} szerkesztett egy bejegyzést" notifications: + administration_emails: Adminisztrátori e-mail-értesítések email_events: Események email értesítésekhez email_events_hint: 'Válaszd ki azokat az eseményeket, melyekről értesítést szeretnél:' other_settings: Értesítések egyéb beállításai @@ -1380,12 +1513,22 @@ hu: expired: A szavazásnak már vége invalid_choice: A kiválasztott szavazási lehetőség nem létezik over_character_limit: egyik sem lehet %{max} karakternél hosszabb + self_vote: Nem szavazhatsz a saját szavazásodon too_few_options: több, mint egy opciónak kell lennie too_many_options: nem lehet több, mint %{max} opció preferences: other: Egyéb posting_defaults: Bejegyzések alapértelmezései public_timelines: Nyilvános idővonalak + privacy: + hint_html: "Testreszabható a profil és a bejegyzések megjelenése. A Mastodon számos funkciója segíthet szélesebb közönség elérésében, ha engedélyezve van. Szánj egy percet a beállítások áttekintésére, hogy megbizonyosodj arról, hogy ezek megfelelnek a te felhasználási esetednek." + privacy: Adatvédelem + privacy_hint_html: Szabályozd, hogy mások számára miket szeretnél nyilvánosságra hozni. Az emberek érdekes profilokat és nagyszerű alkalmazásokat fedezhetnek fel, amikor böngésznek mások követései között és látják, hogy mely alkalmazásokból tesznek közzé bejegyzéseket, de az is lehet, hogy inkább elrejtenéd ezeket az infókat. + reach: Elérés + reach_hint_html: Szabályozd, hogy szeretnéd-e, hogy új emberek felfedezzenek és kövessenek. Szeretnéd, hogy a bejegyzéseid megjelenjenek a Felfedezés képernyőn? Szeretnéd, hogy mások is lássanak téged a követési ajánlataikban? Szeretnéd automatikusan elfogadni az összes új követőt vagy egyesével szabályozni mindegyiket? + search: Keresés + search_hint_html: Irányítsd, hogyan találjanak meg. Szeretnéd, hogy az emberek megtaláljanak az alapján, amiről nyilvános bejegyzést írtál? Szeretnéd, hogy a Mastodonon kívüli emberek megtalálják a profilodat, amikor az interneten keresnek? Ne feledd, hogy a nyilvános információk esetében nem garantálható az összes keresőmotorból való teljes kizárás. + title: Adatvédelem és elérés privacy_policy: title: Adatvédelmi irányelvek reactions: @@ -1398,6 +1541,7 @@ hu: confirm_remove_selected_followers: Biztos, hogy el szeretnéd távolítani a kiválasztott követőket? confirm_remove_selected_follows: Biztos, hogy el szeretnéd távolítani a kiválasztott követéseket? dormant: Elhagyott + follow_failure: Nem sikerült bekövetni néhányat a kiválasztott fiókok közül. follow_selected_followers: Kiválasztott követők bekövetése followers: Követők following: Követve @@ -1437,6 +1581,7 @@ hu: electron: Electron firefox: Firefox generic: Ismeretlen böngésző + huawei_browser: Huawei Böngésző ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Böngésző @@ -1446,6 +1591,7 @@ hu: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Ismeretlen böngésző weibo: Weibo current_session: Jelenlegi munkamenet description: "%{browser} az alábbi platformon: %{platform}" @@ -1458,9 +1604,10 @@ hu: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: ismeretlen platform + unknown_platform: Ismeretlen platform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1531,7 +1678,6 @@ hu: show_newer: Újabbak mutatása show_older: Régebbiek mutatása show_thread: Szál mutatása - sign_in_to_participate: Jelentkezz be, hogy részt vehess a beszélgetésben title: "%{name}: „%{quote}”" visibilities: direct: Közvetlen @@ -1573,12 +1719,10 @@ hu: '7889238': 3 hónap min_age_label: Korhatár min_favs: Bejegyzések megtartása, melyeket többször jelöltek kedvencnek, mint - min_favs_hint: Nem törli egyetlen olyan bejegyzésedet sem, melyeket ennél többször jelöltek kedvencnek. Hagyd üresen, hogy a kedvencnek jelölések számától függetlenül töröljük őket + min_favs_hint: Nem törli egyetlen olyan bejegyzésedet sem, melyeket legalább ennyiszer jelöltek kedvencnek. Hagyd üresen, hogy a kedvencnek jelölések számától függetlenül törölve legyenek. min_reblogs: Bejegyzések megtartása, melyeket többször toltak meg, mint min_reblogs_hint: Egyetlen olyan bejegyzésedet sem törli, melyet ennél többször toltak meg. Hagyd üresen, hogy a megtolások számától függetlenül töröljük a bejegyzéseket stream_entries: - pinned: Kitűzött bejegyzés - reblogged: megtolta sensitive_content: Kényes tartalom strikes: errors: @@ -1594,6 +1738,11 @@ hu: default: "%Y. %b %d., %H:%M" month: "%Y %b" time: "%H:%M" + with_time_zone: "%Y. %b %d., %H:%M" + translation: + errors: + quota_exceeded: A fordítási szolgáltatás szerver szintű felhasználási korlátját túlléptük. + too_many_requests: Az előzőekben túl sok kérés érkezett a fordítási szolgáltatáshoz. two_factor_authentication: add: Hozzáadás disable: Kikapcsolás @@ -1673,13 +1822,18 @@ hu: title: Üdv a fedélzeten, %{name}! users: follow_limit_reached: Nem követhetsz több, mint %{limit} embert + go_to_sso_account_settings: Ugrás az azonosítási szolgáltatód fiókbeállításaihoz invalid_otp_token: Érvénytelen ellenőrző kód otp_lost_help_html: Ha mindkettőt elvesztetted, kérhetsz segítséget itt %{email} seamless_external_login: Külső szolgáltatáson keresztül jelentkeztél be, így a jelszó és e-mail beállítások nem elérhetőek. signed_in_as: Bejelentkezve mint verification: - explanation_html: 'A profilodon hitelesítheted magad, mint az itt található linkek tulajdonosa. Ehhez a linkelt weboldalnak tartalmaznia kell egy linket vissza a Mastodon profilodra. Ennek tartalmaznia kell a rel="me" attribútumot. A link szövege bármi lehet. Itt egy példa:' + extra_instructions_html: Tipp: A hivatkozás a weboldaladon lehet láthatatlan. A fontos rész a rel="me", mely megakadályozza, hogy mások a nevedben lépjenek fel olyan oldalakon, ahol van felhasználók által előállított tartalom. A link tag-et az oldal fejlécében is használhatod az a tag helyett, de a HTML-nek elérhetőnek kell lennie JavaScript futtatása nélkül is. + here_is_how: Itt van, hogyan kell + hint_html: "A személyazonosságod ellenőrizhetősége a Mastodonon mindenki számára elérhető. Ez nyílt webes szabványok alapján, most és mindörökké szabadon és ingyenesen történik. Ehhez csak egy saját weboldalra van szükséged, mely alapján mások felismernek téged. Ha a profilodról erre a weboldalra hivatkozol, mi ellenőrizzük, hogy erről az oldalról visszahivatkozol-e a profilodra, és siker esetén erről vizuális jelzést is adunk a profilodon." + instructions_html: Az alábbi kódot másold be a weboldalad HTML kódjába. Ezután add hozzá a weboldalad címét a profilod egyik extra mezőjéhez a "Profil szerkesztése" fülön és mentsd a változásokat. verification: Hitelesítés + verified_links: Ellenőrzött hivatkozásaid webauthn_credentials: add: Biztonsági kulcs hozzáadása create: diff --git a/config/locales/hy.yml b/config/locales/hy.yml index de995c5b5e..f3a6392ff0 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -84,6 +84,7 @@ hy: active: Ակտիվ all: Բոլորը pending: Սպասում + silenced: Սահմանափակ suspended: Կասեցուած title: Մոդերացիա moderation_notes: Մոդերացիայի նշումներ @@ -108,8 +109,6 @@ hy: removed_header_msg: Յաջողութեամբ հեռացուեց %{username}֊ի գլխանկարը resend_confirmation: already_confirmed: Օգտատէրն արդէն հաստատուած է - send: Հաստատման իմակն ուղարկել կրկին - success: Հաստատման իմակը բարեյաջող ուղարկուեց reset: Վերականգնել reset_password: Վերականգնել գաղտանաբառը resubscribe: Կրկին բաժանորդագրուել @@ -464,39 +463,44 @@ hy: regenerate_token: Ստեղծել նոր հասանելիութեան կտրոն your_token: Քո մուտքի բանալին auth: - change_password: Գաղտնաբառ + apply_for_account: Ուղարկել delete_account: Ջնջել հաշիվը description: prefix_sign_up: Գրանցուի՛ր Մաստոդոնում հենց այսօր - didnt_get_confirmation: Չե՞ս ստացել հաստատման ուղեցոյց։ + didnt_get_confirmation: Չե՞ս ստացել հաստատման յղում dont_have_your_security_key: Չունե՞ս անվտանգութեան բանալի։ forgot_password: Մոռացե՞լ ես գաղտնաբառդ login: Մտնել logout: Դուրս գալ migrate_account: Տեղափոխուել այլ հաշիւ or_log_in_with: Կամ մուտք գործել օգտագործելով՝ + privacy_policy_agreement_html: Ես կարդացել եւ ընդունել եմ գաղնիութեան քաղաքականութիւնը + progress: + confirm: Փոստի հաստատում + details: Ձեր տուեալները + review: Վաւերացում + rules: Ընդունել կանոները register: Գրանցվել registration_closed: "%{instance}ը չի ընդունում նոր անդամներ" reset_password: Վերականգնել գաղտանաբառը + rules: + accept: Հաստատել + back: Վերադառնալ + preamble: Կանոնները սահմանում եւ կիրառում են %{domain}-ի մոդերատորները։ + title: Մի քանի հիմանական կանոններ։ security: Անվտանգություն set_new_password: Սահմանել նոր գաղտնաբառ - setup: - title: Կարգավորում + sign_in: + preamble_html: Մուտքագրէք %{domain}-ի ձեր տուեալները։ Եթե ձեր հաշիւը ուրիշ սպասարկիչի վրայ է, այտեղ մտնել չի ստացուի։ + title: Մտնել %{domain} + sign_up: + manual_review: Գրանցումները %{domain}-ում վաւերացնում են մոդերատորնրը։ Մեզ օգնելու համար մի փոքր պատմէք ձեր մասին եւ թե ինչու էք ուզում գրանցուել։ + preamble: Այս հանգոյցում հաշիւ ունենալով դուք կարող էք հերտեւել դաշնեզերքի ցանկացած օգտատիրոջ, անկախ նրանից թե որտեղ է նրա հաշիւը տեղակայուած։ + title: Ստեղծի՜ր հաշիւ %{domain}-ում status: account_status: Հաշուի կարգավիճակ pending: Դիմումը պէտք է քննուի մեր անձնակազմի կողմից, ինչը կարող է մի փոքր ժամանակ խլել։ Դիմումի հաստատուելու դէպքում, կտեղեկացնենք նամակով։ use_security_key: Օգտագործել անվտանգութեան բանալի - authorize_follow: - already_following: Դու արդէն հետեւում ես այս հաշուին - already_requested: Դու արդէն ուղարկել ես հետեւմանն յայտ այս հաշուին - follow: Հետևել - follow_request: Դու ուղարկել ես հետեւելու հայց՝ - following: Յաջողութի՜ւն։ Դու այժմ հետեւում ես․ - post_follow: - close: Կամ, կարող ես պարզապէս փակել այս պատուհանը։ - return: Ցուցադրել օգտատիրոջ էջը - web: Անցնել վէբին - title: Հետեւել %{acct} challenge: confirm: Շարունակել invalid_password: Անվաւեր ծածկագիր @@ -534,15 +538,10 @@ hy: domain_validator: invalid_domain: անվաւէր տիրոյթի անուն errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. '404': Էջը, որը փնտրում ես գոյութիւն չունի։ - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. '429': Չափազանց շատ հարցումներ '500': title: Էջը ճիշտ չէ - '503': The page could not be served due to a temporary server failure. existing_username_validator: not_found: չյաջողուեց գտնել այս ծածկագրով լոկալ օգտատիրոջ not_found_multiple: չյաջողուեց գտնել %{usernames} @@ -572,11 +571,10 @@ hy: index: delete: Ջնջել empty: Դու ֆիլտրեր չունես։ + expires_on: Լրանում է %{date}-ին title: Ֆիլտրեր new: title: Ավելացնել ֆիլտր - footer: - trending_now: Այժմ արդիական generic: all: Բոլորը changes_saved_msg: Փոփոխութիւնները յաջող պահուած են @@ -707,6 +705,10 @@ hy: other: Այլ posting_defaults: Կանխադիր կարգաւորումներ public_timelines: Հանրային հոսք + privacy: + search: Որոնել + privacy_policy: + title: Գաղտնիութեան քաղաքականութիւն reactions: errors: unrecognized_emoji: ճանաչուած էմոջի չէ @@ -758,7 +760,6 @@ hy: ios: iOS linux: Լինուքս mac: macOS - other: անհայտ հարթակ windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -811,7 +812,6 @@ hy: show_newer: Ցուցադրել նորերը show_older: Ցուցադրել հները show_thread: Բացել շղթան - sign_in_to_participate: Մուտք գործէք՝ զրոյցին միանալու համար title: '%{name}: "%{quote}"' visibilities: direct: Հասցէագրուած @@ -833,8 +833,6 @@ hy: '63113904': 2 տարի '7889238': 3 ամիս stream_entries: - pinned: Ամրացուած գրառում - reblogged: տարածուած sensitive_content: Կասկածելի բովանդակութիւն themes: contrast: Mastodon (բարձր կոնտրաստով) @@ -884,7 +882,6 @@ hy: invalid_otp_token: Անվաւեր 2F կոդ signed_in_as: Մոտք գործել որպէս․ verification: - explanation_html: Պիտակների յղումների հեղինակութիւնը կարելի է վաւերացնել։ Անհրաժեշտ է որ յղուած կայքը պարունակի յետադարձ յղում ձեր մաստադոնի էջին, որը պէտք է ունենայ rel="me" նիշքը։ Յղման բովանդակութիւնը կարևոր չէ։ Օրինակ՝ verification: Ստուգում webauthn_credentials: delete: Ջնջել diff --git a/config/locales/id.yml b/config/locales/id.yml index 10f7e6629b..0e8f2b9b05 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -121,8 +121,6 @@ id: removed_header_msg: Berhasil menghapus gambar header %{username} resend_confirmation: already_confirmed: Pengguna ini sudah dikonfirmasi - send: Kirim ulang email konfirmasi - success: Email konfirmasi berhasil dikirim! reset: Atur ulang reset_password: Reset kata sandi resubscribe: Langganan ulang @@ -712,7 +710,6 @@ id: approved: Persetujuan diperlukan untuk mendaftar none: Tidak ada yang dapat mendaftar open: Siapa pun dapat mendaftar - title: Pengaturan Server site_uploads: delete: Hapus berkas yang diunggah destroyed_msg: Situs yang diunggah berhasil dihapus! @@ -903,7 +900,6 @@ id: guide_link: https://crowdin.com/project/mastodon guide_link_text: Siapa saja bisa berkontribusi. sensitive_content: Konten sensitif - toot_layout: Tata letak kiriman application_mailer: notification_preferences: Ubah pilihan email salutation: "%{name}," @@ -920,14 +916,12 @@ id: your_token: Token akses Anda auth: apply_for_account: Permintaan akun - change_password: Kata sandi delete_account: Hapus akun delete_account_html: Jika Anda ingin menghapus akun Anda, Anda dapat memproses ini. Anda akan dikonfirmasi. description: prefix_invited_by_user: "@%{name} mengundang Anda untuk bergabung di server Mastodon ini!" prefix_sign_up: Daftar ke Mastodon hari ini! suffix: Dengan sebuah akun, Anda dapat mengikuti orang, mengirim pembaruan, dan bertukar pesan dengan pengguna dari server Mastodon mana pun dan lainnya! - didnt_get_confirmation: Tidak menerima petunjuk konfirmasi? dont_have_your_security_key: Tidak memiliki kunci keamanan? forgot_password: Lupa kata sandi? invalid_reset_password_token: Token reset kata sandi tidak valid atau kedaluwarsa. Silakan minta yang baru. @@ -945,17 +939,12 @@ id: saml: SAML register: Daftar registration_closed: "%{instance} tidak menerima anggota baru" - resend_confirmation: Kirim ulang email konfirmasi reset_password: Reset kata sandi rules: preamble: Ini diatur dan ditetapkan oleh moderator %{domain}. title: Beberapa aturan dasar. security: Identitas set_new_password: Tentukan kata sandi baru - setup: - email_below_hint_html: Jika alamat email di bawah tidak benar, Anda dapat menggantinya di sini dan menerima email konfirmasi baru. - email_settings_hint_html: Email konfirmasi telah dikirim ke %{email}. Jika alamat email tidak benar, Anda dapat mengubahnya di pengaturan akun. - title: Atur sign_in: title: Masuk ke %{domain} sign_up: @@ -970,18 +959,6 @@ id: view_strikes: Lihat hukuman lalu yang pernah terjadi kepada akun Anda too_fast: Formulir dikirim terlalu cepat, coba lagi. use_security_key: Gunakan kunci keamanan - authorize_follow: - already_following: Anda sudah mengikuti akun ini - already_requested: Anda sudah mengirimkan permintaan untuk mengikuti akun tersebut - error: Sayangnya, ada error saat melihat akun remote - follow: Ikuti - follow_request: 'Anda telah mengirim permintaan untuk mengikuti ke:' - following: 'Berhasil! Anda sekarang mengikuti:' - post_follow: - close: Atau Anda dapat menutup jendela ini. - return: Tampilkan profil pengguna - web: Ke web - title: Mengikuti %{acct} challenge: confirm: Lanjut hint_html: "Tip: Kami tidak akan meminta kata sandi Anda lagi untuk beberapa jam ke depan." @@ -1093,8 +1070,6 @@ id: storage: Penyimpanan media featured_tags: add_new: Tambah baru - errors: - limit: Anda sudah menampilkan tagar unggulan dengan jumlah maksimum hint_html: "Apa itu tagar yang diunggulkan? Mereka ditampilkan secara mencolok di profil publik Anda dan mengizinkan orang-orang untuk menjelajahi kiriman publik khususnya yang ada di bawah tagar tersebut. Mereka adalah alat yang bagus untuk melacak pekerjaan kreatif atau proyek jangka panjang." filters: contexts: @@ -1135,8 +1110,6 @@ id: index: hint: Saringan ini diterapkan ke beberapa kiriman individu tanpa memengaruhi oleh kriteria lain. Anda dapat menambahkan lebih banyak kiriman ke saringan ini dari antarmuka web. title: Kiriman yang disaring - footer: - trending_now: Sedang tren generic: all: Semua all_items_on_page_selected_html: @@ -1155,8 +1128,6 @@ id: today: hari ini validation_errors: other: Ada yang belum benar! Silakan tinjau %{count} kesalahan di bawah ini - html_validator: - invalid_markup: 'berisi markup HTML yang tidak valid: %{error}' imports: errors: invalid_csv_file: 'Berkas CVS tidak sah. Kesalahan: %{error}' @@ -1196,9 +1167,6 @@ id: expires_at: Kedaluwarsa uses: Penggunaan title: Undang orang - lists: - errors: - limit: Daftar Anda telah mencapai jumlah maksimum login_activities: authentication_methods: otp: aplikasi otentikasi dua-faktor @@ -1402,7 +1370,6 @@ id: ios: iOS linux: Linux mac: Mac - other: platform yang tidak diketahui windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1467,7 +1434,6 @@ id: show_newer: Tampilkan lebih baru show_older: Tampilkan lebih lama show_thread: Tampilkan utas - sign_in_to_participate: Masuk untuk mengikuti percakapan title: '%{name}: "%{quote}"' visibilities: direct: Langsung @@ -1509,12 +1475,9 @@ id: '7889238': 3 bulan min_age_label: Batas usia min_favs: Simpan kiriman favorit lebih dari - min_favs_hint: Tidak menghapus kiriman Anda yang mendapatkan sekian favorit. Kosongkan bila ingin menghapus kiriman tanpa peduli jumlah favoritnya min_reblogs: Simpan kiriman yang di-boost lebih dari min_reblogs_hint: Tidak menghapus kiriman Anda yang di-boost lebih dari sekian kali. Kosongkan bila ingin menghapus kiriman tanpa peduli jumlah boost-nya stream_entries: - pinned: Kiriman tersemat - reblogged: di-boost-kan sensitive_content: Konten sensitif strikes: errors: @@ -1614,7 +1577,6 @@ id: seamless_external_login: Anda masuk via layanan eksternal, sehingga pengaturan kata sandi dan email tidak tersedia. signed_in_as: 'Masuk sebagai:' verification: - explanation_html: 'Anda dapat memverifikasi diri Anda sebagai pemiliki tautan pada metadata profil. Situsweb yang ditautkan haruslah berisi tautan ke profil Mastodon Anda. Tautan tersebut harus memiliki atribut rel="me". Isi teks tautan tidaklah penting. Ini contohnya:' verification: Verifikasi webauthn_credentials: add: Tambahkan kunci keamanan baru diff --git a/config/locales/ig.yml b/config/locales/ig.yml index 6459396380..7c264f0d73 100644 --- a/config/locales/ig.yml +++ b/config/locales/ig.yml @@ -1,10 +1 @@ ---- ig: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/io.yml b/config/locales/io.yml index 808023e40d..d09dfed70b 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -122,8 +122,6 @@ io: removed_header_msg: Sucesoze efacis kapimajo di %{username} resend_confirmation: already_confirmed: Ca uzanto ja konfirmesis - send: Risendez konfirmretposto - success: Konfirmretposto sucesoze sendesas! reset: Richanjez reset_password: Richanjez pasvorto resubscribe: Riabonez @@ -700,7 +698,6 @@ io: approved: Aprobo bezonesas por registro none: Nulu povas registrar open: Irgu povas registrar - title: Servilopcioni site_uploads: delete: Efacez adchargita failo destroyed_msg: Sitadchargito sucesoze efacesis! @@ -882,7 +879,6 @@ io: guide_link: https://crowdin.com/project/mastodon guide_link_text: Omnu povas kontributar. sensitive_content: Sentoza kontenajo - toot_layout: Postostrukturo application_mailer: notification_preferences: Chanjez retpostopreferaji salutation: "%{name}," @@ -898,14 +894,12 @@ io: warning: Sorgemez per ca informi. Ne partigez kun irgu! your_token: Vua acesficho auth: - change_password: Pasvorto delete_account: Efacez konto delete_account_html: Se vu volas efacar vua konto, vu povas irar hike. Vu demandesos konfirmar. description: prefix_invited_by_user: "@%{name} invitas vu juntar ca servilo di Mastodon!" prefix_sign_up: Registrez che Mastodon hodie! suffix: Per konto, vu povos sequar personi, postigar novaji e interchanjar mesaji kun uzanti de irga servilo di Mastodon e pluse! - didnt_get_confirmation: Ka tu ne recevis la instrucioni por konfirmar? dont_have_your_security_key: Ka vu ne havas sekuresklefo? forgot_password: Pasvorto obliviita? invalid_reset_password_token: Pasvorto richanjoficho esas nevalida o expirita. Demandez novo. @@ -923,17 +917,12 @@ io: saml: SAML register: Membreskar registration_closed: "%{instance} ne aceptas nova membri" - resend_confirmation: Risendar la instrucioni por konfirmar reset_password: Chanjar la pasvorto rules: preamble: Co igesas e exekutesas da jereri di %{domain}. title: Kelka bazala reguli. security: Chanjar pasvorto set_new_password: Selektar nova pasvorto - setup: - email_below_hint_html: Se suba retpostoadreso esas nekorekta, vu povas chanjar hike e ganar nova konfirmretposto. - email_settings_hint_html: Konfirmretposto sendesis a %{email}. Se ta retpostoadreso ne esas korekta, vu povas chanjar en kontoopcioni. - title: Komencoprocedo sign_up: preamble: Per konto en ca servilo di Mastodon, on povas sequar irga persono en ca reto, ne ye ube ona konto hostagisas. title: Ni komencigez vu en %{domain}. @@ -946,18 +935,6 @@ io: view_strikes: Videz antea streki kontre vua konto too_fast: Formulario sendesis tro rapide, probez itere. use_security_key: Uzes sekuresklefo - authorize_follow: - already_following: Vu ja sequis ca konto - already_requested: Vu ja sendis sequodemando a ta konto - error: Regretinde, eventis eraro probante konsultar la fora konto - follow: Sequar - follow_request: 'Vu sendis sequodemando a:' - following: 'Suceso! Vu nun sequas:' - post_follow: - close: O, vu volas jus klozar ca panelo. - return: Montrez priflo de uzanti - web: Irez a interreto - title: Sequar %{acct} challenge: confirm: Durez hint_html: "Guidilo: Ni ne demandos vua pasvorto itere til 1 horo." @@ -1069,8 +1046,6 @@ io: storage: Konservado di kontenajo featured_tags: add_new: Insertez novo - errors: - limit: Vu ja estelis maxima hashtagi hint_html: "Quo esas estelita hashtagi? Ol montresas eminente che vua publika profilo e povigas personi vidar vua publika posti partikulare kun ta hashtagi. Oli esas bona utensilo por jeretar kreiva agaji e longa projetaji." filters: contexts: @@ -1114,8 +1089,6 @@ io: index: hint: Ca filtrilo aplikesas a selektita posti ne segun altra kriterio. Vu povas pozar plu multa posti a ca filtrilo de retintervizajo. title: Filtrita posti - footer: - trending_now: Nuna tendenco generic: all: Omna all_items_on_page_selected_html: @@ -1138,8 +1111,6 @@ io: validation_errors: one: Ulo ne eventis senprobleme! Voluntez konsultar la suba eror-raporto other: Ulo ne eventis senprobleme! Voluntez konsultar la suba %{count} eror-raporti - html_validator: - invalid_markup: 'kontenas nevalida kompozuro di HTML: %{error}' imports: errors: over_rows_processing_limit: kontenas plu kam %{count} horizontala lineo @@ -1179,9 +1150,6 @@ io: expires_at: Expiros uses: Uzi title: Invitez personi - lists: - errors: - limit: Vu astingas maxima listi login_activities: authentication_methods: otp: 2-faktoryurizessoftwaro @@ -1385,7 +1353,6 @@ io: ios: iOS linux: Linux mac: macOS - other: nesavata platformo windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1456,7 +1423,6 @@ io: show_newer: Montrez plu nova kozo show_older: Montrez plu olda kozo show_thread: Montrez postaro - sign_in_to_participate: Registrez por partoprenar en konverso title: '%{name}: "%{quote}"' visibilities: direct: Direta @@ -1498,12 +1464,9 @@ io: '7889238': 3 monati min_age_label: Oldeslimito min_favs: Retenez favorizita posti mine - min_favs_hint: Ne efacas irga vua posti quo ganis mine ca favorizquanto. Restez quale vakua por efacar posti sen suciar olia favorizquanto min_reblogs: Retenez bustita posti mine min_reblogs_hint: Ne efacas irga vua posti quo bustigesos mine ca foyoquanto. Restez quale vakua por efacar posti sen suciar olia foyoquanto stream_entries: - pinned: Pinglagita posto - reblogged: diskonocigita sensitive_content: Titiliva kontenajo strikes: errors: @@ -1603,7 +1566,6 @@ io: seamless_external_login: Vu enirar tra externa serveso, do pasvorto e retpostoopcioni ne esas disponebla. signed_in_as: 'Eniris quale:' verification: - explanation_html: 'Vu povas verifikar su kom proprietero di ligili en vua profilmetainformi. En ta kazo, ligita retsito mustas havar rel="me" atributo. Textokontenajo di ligilo ne esas importanta. Co esas exemplo:' verification: Verifikeso webauthn_credentials: add: Insertez nova sekuresklefo diff --git a/config/locales/is.yml b/config/locales/is.yml index e68bbb2f39..c3608a7359 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -91,6 +91,7 @@ is: moderation: active: Virkur all: Allt + disabled: Óvirkt pending: Í bið silenced: Takmarkað suspended: Í frysti @@ -124,8 +125,8 @@ is: removed_header_msg: Tókst að fjarlægja forsíðumynd notandans %{username} resend_confirmation: already_confirmed: Þessi notandi hefur þegar verið staðfestur - send: Senda staðfestingartölvupóst aftur - success: Það tókst að senda staðfestingartölvupóst! + send: Endursenda staðfestingartengil + success: Tókst að senda staðfestingartengil! reset: Endurstilla reset_password: Endurstilla lykilorð resubscribe: Gerast áskrifandi aftur @@ -133,6 +134,7 @@ is: search: Leita search_same_email_domain: Aðra notendur með sama tölvupóstlén search_same_ip: Aðrir notendur með sama IP-vistfang + security: Öryggi security_measures: only_password: Aðeins lykilorð password_and_2fa: Lykilorð og 2-þátta auðkenning @@ -307,6 +309,7 @@ is: unpublish: Taka úr birtingu unpublished_msg: Það tókst að taka auglýsinguna úr birtingu! updated_msg: Það tókst að uppfæra auglýsinguna! + critical_update_pending: Áríðandi uppfærsla í bið custom_emojis: assign_category: Úthluta flokki by_domain: Lén @@ -380,6 +383,15 @@ is: undo: Fjarlægja af lista yfir leyft domain_blocks: add_new: Bæta við nýrri útilokun á léni + confirm_suspension: + cancel: Hætta við + confirm: Setja í bið + permanent_action: Afturköllun biðstöðu mun ekki endurheimta nein gögn né vensl. + preamble_html: Þú ert við það að setja %{domain} í bið ásamt undirlénum. + remove_all_data: Þetta mun fjarlægja allt efni og notendaupplýsingar fyrir aðganga frá þessu léni af þínum vefþjóni. + stop_communication: Vefþjónnin þinn mun slíta samskiptum við þessa vefþjóna. + title: Staðfesta útilokun á léni fyrir %{domain} + undo_relationships: Þetta mun afturkalla öll fylgjendavensl milli aðganaga þessa vefþjóns og þíns. created_msg: Útilokun léns er núna í vinnslu destroyed_msg: Útilokun léns hefur verið aflétt domain: Lén @@ -427,6 +439,7 @@ is: resolve: Leysa lén title: Útiloka nýtt tölvupóstlén no_email_domain_block_selected: Engum útilokunum tölvupóstléna var breytt þar sem ekkert var valið + not_permitted: Ekki leyft resolved_dns_records_hint_html: Heiti lénsins vísar til eftirfarandi MX-léna, sem bera endanlega ábyrgð á að tölvupóstur skili sér. Útilokun á MX-léni mun koma í veg fyrir nýskráningar með hverju því tölvupóstfangi sem notar sama MX-lén, jafnvel þótt sýnilega lénsheitið sé frábrugðið. Farðu varlega svo þú útilokir ekki algengar tölvupóstþjónustur. resolved_through_html: Leyst í gegnum %{domain} title: Útilokuð tölvupóstlén @@ -473,6 +486,7 @@ is: content_policies: comment: Innri minnispunktur description_html: Þú getur skilgreint stefnu varðandi efni sem verður beitt á alla aðganga frá þessu léni og öllum undirlénum þess. + limited_federation_mode_description_html: Þú getur valið hvort leyfa eigi skýjasamband við þetta lén. policies: reject_media: Hafna myndefni reject_reports: Hafna kærum @@ -585,11 +599,13 @@ is: assign_to_self: Úthluta mér assigned: Úthlutaður umsjónarmaður by_target_domain: Lén kærða notandaaðgangsins + cancel: Hætta við category: Flokkur category_description_html: Ástæðan fyrir því að þessi notandaaðgangur og/eða efni hans var kært mun verða tiltekin í samskiptum við kærðan notandaaðgang comment: none: Ekkert comment_description_html: 'Til að gefa nánari upplýsingar skrifaði %{name}:' + confirm: Staðfesta confirm_action: Staðfesta umsjónaraðgerðir gagnvart @%{acct} created_at: Tilkynnt delete_and_resolve: Eyða færslum @@ -725,6 +741,11 @@ is: branding: preamble: Útlitsleg einkenni aðgreina netþjóninn þinn frá öðrum netþjónum á netkerfinu. Þessar upplýsingar geta birst á margvíslegum stöðum, eins og til dæmis í vefviðmóti Mastodon, einstökum forritum, í forskoðun tengla á öðrum vefsvæðum og innan samskiptaforrita, svo eitthvað sé talið. Þess vegna er vest að þessar upplýsingar séu skýrar, stuttar og tæmandi. title: Útlitsleg aðgreining + captcha_enabled: + desc_html: |- + Þetta stuðlast á utanaðkomandi forskriftum frá hCaptcha, sem gæti haft í för með sér öryggisveikleika og vegið að friðhelgi notenda. + Aukinheldur gæti þetta gert nýskráningarferlið óaðgengilegra sumum (sérstaklega fyrir fatlaða). Þess vegna er rétt að skoða aðra valmöguleika svo sem nýskráningar háðar samþykki eða boði. + title: Nýir notendur munu þurfa að standast Turing skynpróf til að staðfesta notendaaðganginn content_retention: preamble: Stýrðu hvernig efni frá notendum sé geymt í Mastodon. title: Geymsla efnis @@ -752,10 +773,27 @@ is: approved: Krafist er samþykkt nýskráningar none: Enginn getur nýskráð sig open: Allir geta nýskráð sig + security: + authorized_fetch: Krefjast auðkenningar frá netþjónum í skýjasambandi + authorized_fetch_hint: Að krefjast auðkenningar frá netþjónum í skýjasambandi kallar fram strangari útfærslu á útilokunum, bæði varðandi notendur og netþjóna. Hins vegar kemur þetta niður á afköstum, minnkar útbreiðslu á svörum þínum og gæti valdið samhæfnivandamálum við sumar sambandsþjónustur. Að auki kemur þetta ekki í veg fyrir að aðilar sem ætla sér að ná í opinberar færslur og notendaaðganga frá þér geri það. + authorized_fetch_overridden_hint: Þú getur eins og er ekki breytt þessari stillingu því hún er yfirtekin af umhverfisbreytu. + federation_authentication: Krafa um auðkenningu í skýjasambandi title: Stillingar netþjóns site_uploads: delete: Eyða innsendri skrá destroyed_msg: Það tókst að eyða innsendingu á vefsvæði! + software_updates: + critical_update: Áríðandi - uppfærðu eins fljótt og auðið er + description: Mælt er með því að þú haldir Mastodon-uppsetningunni þinni uppfærðri til að vera með nýjustu lagfæringar og eiginleika. Aukinheldur er mikilvægt að halda Mastodon uppfærðu til að komast hjá öryggisveilum. Af þessum ástæðum athugar Mastodon með uppfærslur á 30 mínútna fresti og mun gera þér viðvart í samræmi við stillingar þínar á tilkynningum í tölvupósti. + documentation_link: Kanna nánar + release_notes: Útgáfuupplýsingar + title: Tiltækar uppfærslur + type: Tegund + types: + major: Aðalútgáfa + minor: Aukaútgáfa + patch: Viðgerðauppfærsla - lagfæringar og ýmsar minniháttar breytingar + version: Útgáfa statuses: account: Höfundur application: Forrit @@ -792,9 +830,24 @@ is: suspend: "%{name} setti notandaaðganginn %{target} í frysti" appeal_approved: Áfrýjað appeal_pending: Áfrýjun í bið + appeal_rejected: Áfrýjun hafnað system_checks: database_schema_check: message_html: Það eru fyrirliggjandi yfirfærslur á gagnagrunnum. Keyrðu þær til að tryggja að forritið hegði sér eins og skyldi + elasticsearch_health_red: + message_html: Elasticsearch-klasinn er ekki í góðu standi (rauð staða), leitareiginleikar eru ekki tiltækir + elasticsearch_health_yellow: + message_html: Elasticsearch-klasinn er ekki í góðu standi (gul staða), þú gætir viljað rannsaka málið + elasticsearch_index_mismatch: + message_html: Elasticsearch atriðaskráningin er úrelt. Þú ættir að keyra tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Skoðaðu hjálparskjölin + message_html: Elasticsearch-klasinn þinn er með meira en einn hnút, en Mastodon er ekki sett upp til að nota þá. + elasticsearch_preset_single_node: + action: Skoðaðu hjálparskjölin + message_html: Elasticsearch-klasinn þinn er með aðeins einn hnút, ES_PRESET ætti að vera stillt á single_node_cluster. + elasticsearch_reset_chewy: + message_html: Elasticsearch-kerfisatriðaskráin þín er úrelt vegna breytinga á stillingum. Þú ættir að keyra tootctl search deploy --reset-chewy til að uppfæra hana. elasticsearch_running_check: message_html: Gat ekki tengst við Elasticsearch-leitina. Gakktu úr skugga um að hún sé í gangi, eða gerðu leit í öllum texta óvirka elasticsearch_version_check: @@ -805,6 +858,18 @@ is: message_html: Þú hefur ekki skilgreint neinar reglur fyrir netþjón. sidekiq_process_check: message_html: Ekkert Sidekiq-ferli er í gangi fyrir %{value} biðröð/biðraðir. Endilega athugaðu Sidekiq-uppsetninguna þína + software_version_critical_check: + action: Skoða tiltækar uppfærslur + message_html: Áríðandi uppfærsla Mastodon er tiltæk, uppfærðu eins fljótt og auðið er. + software_version_patch_check: + action: Skoða tiltækar uppfærslur + message_html: Uppfærsla með lagfæringum á Mastodon er tiltæk. + upload_check_privacy_error: + action: Skoðaðu hér til að fá frekari upplýsingar + message_html: "Vefþjónninn þinn er ekki rétt stilltur. Friðhelgi notendanna þinna gæti verið í hættu." + upload_check_privacy_error_object_storage: + action: Skoðaðu hér til að fá frekari upplýsingar + message_html: "Gagnageymslan þín er ekki rétt stillt. Friðhelgi notendanna þinna gæti verið í hættu." tags: review: Yfirfara stöðufærslu updated_msg: Það tókst að uppfæra stillingar myllumerkja @@ -827,6 +892,7 @@ is: other: Deilt af %{count} aðilum síðustu vikuna title: Vinsælir tenglar usage_comparison: Deilt %{today} sinnum í dag, samanborið við %{yesterday} í gær + not_allowed_to_trend: Ekki leyft að verða vinsælt only_allowed: Aðeins leyfð pending_review: Bíður eftir yfirlestri preview_card_providers: @@ -911,6 +977,9 @@ is: body: "%{target} er að áfrýja ákvörðun umsjónarmanns tekinni af %{action_taken_by} frá %{date}, sem var %{type}. Viðkomandi skrifaði:" next_steps: Þú getur samþykkt áfrýjunina til að afturkalla ákvörðun umsjónarmanns, eða hunsað hana. subject: "%{username} er að áfrýja ákvörðun umsjónarmanns tekinni á %{instance}" + new_critical_software_updates: + body: Nýjar áríðandi uppfærslur fyrir Mastodon hafa verið gefnar út, þú gætir viljað uppfæra eins fljótt og mögulegt er! + subject: Áríðandi Mastodon-uppfærslur eru tiltækar fyrir %{instance}! new_pending_account: body: Nákvæmari upplýsingar um nýja notandaaðganginn eru hér fyrir neðan. Þú getur samþykkt eða hafnað þessari umsókn. subject: Nýr notandaaðgangur er kominn til yfirferðar á %{instance} (%{username}) @@ -918,6 +987,9 @@ is: body: "%{reporter} hefur kært %{target}" body_remote: Einhver frá %{domain} hefur kært %{target} subject: Ný kæra vegna %{instance} (#%{id}) + new_software_updates: + body: Nýjar uppfærslur fyrir Mastodon hafa verið gefnar út, þú gætir viljað uppfæra! + subject: Nýjar Mastodon-uppfærslur eru tiltækar fyrir %{instance}! new_trends: body: 'Eftirfarandi atriði þarfnast yfirferðar áður en hægt er að birta þau opinberlega:' new_trending_links: @@ -947,24 +1019,30 @@ is: guide_link: https://crowdin.com/project/mastodon/is guide_link_text: Allir geta tekið þátt. sensitive_content: Viðkvæmt efni - toot_layout: Framsetning færslu application_mailer: notification_preferences: Breyta kjörstillingum tölvupósts salutation: "%{name}," settings: 'Breyta kjörstillingum tölvupósts: %{link}' + unsubscribe: Taka úr áskrift view: 'Skoða:' view_profile: Skoða notandasnið view_status: Skoða færslu applications: created: Það tókst að búa til forrit destroyed: Það tókst að eyða forriti + logout: Skrá út regenerate_token: Endurgera aðgangsteikn token_regenerated: Það tókst að endurgera aðgangsteiknið warning: Farðu mjög varlega með þessi gögn. Þú skalt aldrei deila þeim með neinum! your_token: Aðgangsteiknið þitt auth: apply_for_account: Biðja um notandaaðgang - change_password: Lykilorð + captcha_confirmation: + help_html: Ef þú átt í erfiðleikum með að leysa Turing skynpróf, geturðu hafst samband við okkur á netfanginu %{email} og við munum aðstoða þig. + hint_html: |- + Bara eitt enn! Við þurfum að ganga úr skugga um að þú sért mennskur (þetta er gert til að draga úr amapósti). + Leystu Turing skynprófið og smelltu á "Áfram". + title: Öryggisathugun confirmations: wrong_email_hint: Ef það tölvupóstfang er ekki rétt geturðu breytt því í stillingum notandaaðgangsins. delete_account: Eyða notandaaðgangi @@ -973,7 +1051,7 @@ is: prefix_invited_by_user: "@%{name} býður þér að taka þátt á þessum Mastodon-vefþjóni!" prefix_sign_up: Skráðu þig á Mastodon strax í dag! suffix: Með notandaaðgangi geturðu fylgst með fólki, sent inn færslur og skipst á skilaboðum við notendur á hvaða Mastodon-vefþjóni sem er, auk margs fleira! - didnt_get_confirmation: Fékkstu ekki leiðbeiningar um hvernig eigi að staðfesta aðganginn? + didnt_get_confirmation: Fékkstu ekki staðfestingartengil? dont_have_your_security_key: Ertu ekki með öryggislykilinn þinn? forgot_password: Gleymdirðu lykilorðinu? invalid_reset_password_token: Teikn fyrir endurstillingu lykilorðs er ógilt eða útrunnið. Biddu um nýtt teikn. @@ -986,26 +1064,39 @@ is: migrate_account_html: Ef þú vilt endurbeina þessum aðgangi á einhvern annan, geturðu stillt það hér. or_log_in_with: Eða skráðu inn með privacy_policy_agreement_html: Ég hef lesið og samþykkt persónuverndarstefnuna + progress: + confirm: Staðfesta tölvupóstfang + details: Nánari upplýsingar þínar + review: Yfirferð okkar + rules: Samþykkja reglur providers: cas: CAS saml: SAML register: Nýskrá registration_closed: "%{instance} samþykkir ekki nýja meðlimi" - resend_confirmation: Senda leiðbeiningar vegna staðfestingar aftur + resend_confirmation: Endursenda staðfestingartengil reset_password: Endursetja lykilorð rules: + accept: Samþykkja + back: Til baka + invited_by: 'Þú getur tekið þátt í %{domain} þökk sé boði sem þú fékkst frá:' preamble: Þær eru settar og þeim framfylgt af umsjónarmönnum %{domain}. + preamble_invited: Áður en haldið er lengra, vinsamlegast kynntu þér reglurnar sem stjórnendur %{domain} hafa sett. title: Nokkrar grunnreglur. + title_invited: Þér hefur verið boðið. security: Öryggi set_new_password: Stilla nýtt lykilorð setup: - email_below_hint_html: Ef tölvupóstfangið hér fyrir neðan er rangt, skaltu breyta því hér og fá nýjan staðfestingarpóst. - email_settings_hint_html: Staðfestingarpósturinn var sendur til %{email}. Ef það tölvupóstfang er ekki rétt geturðu breytt því í stillingum notandaaðgangsins. - title: Uppsetning + email_below_hint_html: Skoðaðu ruslpóstmöppuna þína, eða biddu um annan póst. Þú getur leiðrétt tölvupóstfangið þitt ef þörf er á. + email_settings_hint_html: Ýttu á tengilinn sem við sendum þér til að staðfesta %{email}. Við bíðum á meðan. + link_not_received: Fékkstu ekki neinn tengil? + new_confirmation_instructions_sent: Þú munt fá nýjan tölvupóst með staðfestingartengli innan skamms! + title: Athugaðu pósthólfið þitt sign_in: preamble_html: Skráðu þig inn með auðkennum þínum fyrir %{domain}. Ef aðgangurinn þinn er hýstur á öðrum netþjóni, muntu ekki geta skráð þig inn hér. title: Skrá inn á %{domain} sign_up: + manual_review: Nýskráningar á %{domain} fara í gegnum handvirka yfirferð hjá umsjónarfólkinu okkar. Til að flýta fyrir skráningarferlinu, ættirðu að skrifa smávegis um þig og ástæður þess að þú viljir skrá þig á %{domain}. preamble: Með notandaaðgangi á þessum Mastodon-þjóni geturðu fylgst með hverjum sem er á netkerfinu, sama hvar notandaaðgangurinn þeirra er hýstur. title: Förum núna að setja þig upp á %{domain}. status: @@ -1017,18 +1108,6 @@ is: view_strikes: Skoða fyrri bönn notandaaðgangsins þíns too_fast: Innfyllingarform sent inn of hratt, prófaðu aftur. use_security_key: Nota öryggislykil - authorize_follow: - already_following: Þú ert að þegar fylgjast með þessum aðgangi - already_requested: Þú ert þegar búin/n að senda fylgjendabeiðni á þennan notanda - error: Því miður, það kom upp villa við að fletta upp fjartengda notandaaðgangnum - follow: Fylgjast með - follow_request: 'Þú sendir beiðni um að fylgjast með til:' - following: 'Tókst! Þú ert núna að fylgjast með:' - post_follow: - close: Eða að þú getur lokað þessum glugga. - return: Birta notandasnið notandans - web: Fara á vefinn - title: Fylgjast með %{acct} challenge: confirm: Halda áfram hint_html: "Ábending: Við munum ekki spyrja þig um lykilorðið aftur næstu klukkustundina." @@ -1105,6 +1184,10 @@ is: your_appeal_rejected: Áfrýjun þinni hefur verið hafnað domain_validator: invalid_domain: er ekki leyfilegt nafn á léni + edit_profile: + basic_information: Grunnupplýsingar + hint_html: "Sérsníddu hvað fólk sér á opinbera notandasniðinu þínu og næst færslunum þínum. Annað fólk er líklegra til að fylgjast með þér og eiga í samskiptum við þig ef þú fyllir út notandasniðið og setur auðkennismynd." + other: Annað errors: '400': Beiðnin sem þú sendir er ógild eða rangt uppsett. '403': Þú hefur ekki heimildir til að skoða þessari síðu. @@ -1141,7 +1224,7 @@ is: featured_tags: add_new: Bæta við nýju errors: - limit: Þú ert þegar búin/n að gefa hámarksfjölda myllumerkja aukið vægi + limit: Þú hefur þegar gefið hámarksfjölda myllumerkja aukið vægi hint_html: "Hvað eru myllumerki með aukið vægi? Þau eru birt áberandi á opinbera notandasniðinu þínu og gera fólki kleift að fletta í gegnum opinberu færslurnar þínar sérstaklega undir þessum myllumerkjum. Þau eru frábær aðferð við að halda utan um skapandi vinnu eða langtíma verkefni." filters: contexts: @@ -1185,8 +1268,6 @@ is: index: hint: Þessi sía virkar til að velja stakar færslur án tillits til annarra skilyrða. Þú getur bætt fleiri færslum í þessa síu í vefviðmótinu. title: Síaðar færslur - footer: - trending_now: Í umræðunni núna generic: all: Allt all_items_on_page_selected_html: @@ -1195,7 +1276,9 @@ is: all_matching_items_selected_html: one: "%{count} atriði sem samsvarar leitinni þinni er valið." other: Öll %{count} atriðin sem samsvara leitinni þinni eru valin. + cancel: Hætta við changes_saved_msg: Það tókst að vista breytingarnar! + confirm: Staðfesta copy: Afrita delete: Eyða deselect: Afvelja allt @@ -1209,24 +1292,62 @@ is: validation_errors: one: Ennþá er ekk alvegi allt í lagi! Skoðaðu vel villuna hér fyrir neðan other: Ennþá er ekki alveg allt í lagi! Skoðaðu vel villurnar %{count} hér fyrir neðan - html_validator: - invalid_markup: 'inniheldur ógildar HTML-merkingar: %{error}' imports: errors: + empty: Tóm CSV-skrá + incompatible_type: Ekki samhæfanlegt valinni tegund innflutnings invalid_csv_file: 'Ógild CSV-skrá. Villa: %{error}' over_rows_processing_limit: inniheldur meira en %{count} raðir + too_large: Skráin er of stór + failures: Mistök + imported: Flutt inn + mismatched_types_warning: Það lítur út fyrir að þú hafir valið ranga tegund innflutnings, yfirfarðu upplýsingarnar. modes: merge: Sameina merge_long: Halda fyrirliggjandi færslum og bæta við nýjum overwrite: Skrifa yfir overwrite_long: Skipta út fyrirliggjandi færslum með þeim nýju + overwrite_preambles: + blocking_html: Þú er í þann mund að fara að skipta út útilokanalistanum þínum með allt að %{total_items} aðgöngum úr %{filename}. + bookmarks_html: Þú er í þann mund að fara að skipta út bókamerkjunum þínum með allt að %{total_items} færslum úr %{filename}. + domain_blocking_html: Þú er í þann mund að fara að skipta út listanum þínum yfir útilokuð lén með allt að %{total_items} lénum úr %{filename}. + following_html: Þú er í þann mund að fara að fylgjast með allt að %{total_items} aðgöngum úr %{filename} og hætta að fylgjast með öllum öðrum. + lists_html: Þú ert í þann mund að fara að skipta út listunum þínum með efninu úr %{filename}. Allt að %{total_items} aðgöngum verður bætt við nýju listana. + muting_html: Þú er í þann mund að fara að skipta út listanum þínum yfir útilokaða aðganga með allt að %{total_items} aðgöngum úr %{filename}. + preambles: + blocking_html: Þú er í þann mund að fara að útiloka allt að %{total_items} aðganga úr %{filename}. + bookmarks_html: Þú er í þann mund að fara að bæta við allt að %{total_items} færslum úr %{filename} við bókamerkin þín. + domain_blocking_html: Þú er í þann mund að fara að útiloka allt að %{total_items} lén úr %{filename}. + following_html: Þú er í þann mund að fara að fylgjast með allt að %{total_items} aðgöngum úr %{filename}. + lists_html: Þú ert í þann mund að fara að bæta við allt að %{total_items} aðgöngum úr %{filename} við listana þína. Nýir listar verða útbúnir ef ekki finnst neinn listi til að bæta í. + muting_html: Þú er í þann mund að fara að þagga allt að %{total_items} aðganga úr %{filename}. preface: Þú getur flutt inn gögn sem þú hefur flutt út frá öðrum vefþjóni, svo sem lista yfir fólk sem þú fylgist með eða útilokar. + recent_imports: Nýlega flutt inn + states: + finished: Lokið + in_progress: Í vinnslu + scheduled: Áætlað + unconfirmed: Óstaðfest + status: Staða success: Það tókst að senda inn gögnin þín og verður unnið með þau þegar færi gefst + time_started: Hófst + titles: + blocking: Flyt inn útilokaða aðganga + bookmarks: Flyt inn bókamerki + domain_blocking: Flyt inn útilokuð lén + following: Flyt inn aðganga sem fylgst er með + lists: Flytja inn lista + muting: Flyt inn þaggaða aðganga + type: Tegund innflutnings + type_groups: + constructive: Fylgst með og bókamerki + destructive: Útilokanir og þagganir types: blocking: Listi yfir útilokanir bookmarks: Bókamerki domain_blocking: Listi yfir útilokanir léna following: Listi yfir þá sem fylgst er með + lists: Listar muting: Listi yfir þagganir upload: Senda inn invites: @@ -1265,6 +1386,21 @@ is: failed_sign_in_html: Misheppnuð tilraun til innskráningar með %{method} frá %{ip} (%{browser}) successful_sign_in_html: Vel heppnuð tilraun til innskráningar með %{method} frá %{ip} (%{browser}) title: Auðkenningarferill + mail_subscriptions: + unsubscribe: + action: Já, hætta í áskrift + complete: Hætta í áskrift + confirmation_html: Ertu viss um að þú viljir hætta áskrift sendinga á %{type} fyrir Mastodon á %{domain} til póstfangsins þíns %{email}? Þú getur alltaf aftur gerst áskrifandi í stillingunum fyrir tilkynningar í tölvupósti. + emails: + notification_emails: + favourite: tilkynningum í tölvupósti um eftirlæti + follow: tilkynningum í tölvupósti um fylgjendur + follow_request: tilkynningum í tölvupósti um beiðnir um að fylgjast með + mention: tilkynningum í tölvupósti um tilvísanir + reblog: tilkynningum í tölvupósti um endurbirtingar + resubscribe_html: Ef þú hættir áskrift fyrir mistök, geturðu alltaf aftur gerst áskrifandi í stillingunum fyrir tilkynningar í tölvupósti. + success_html: Þú munt ekki lengur fá sendingar með %{type} fyrir Mastodon á %{domain} á póstfangið þitt %{email}. + title: Taka úr áskrift media_attachments: validations: images_and_video: Ekki er hægt að hengja myndskeið við færslu sem þegar inniheldur myndir @@ -1344,6 +1480,7 @@ is: update: subject: "%{name} breytti færslu" notifications: + administration_emails: Kerfisstjórnunartilkynningar í tölvupósti email_events: Atburðir fyrir tilkynningar í tölvupósti email_events_hint: 'Veldu þá atburði sem þú vilt fá tilkynningar í tölvupósti þegar þeir koma upp:' other_settings: Aðrar stillingar varðandi tilkynningar @@ -1380,12 +1517,22 @@ is: expired: Könnuninni er þegar lokið invalid_choice: Þessi valkostur er ekki til over_character_limit: geta ekki verið lengri en %{max} stafir hvert + self_vote: Þú getur ekki greitt atkvæði í þínum eigin könnunum too_few_options: verður að vera með fleiri en eitt atriði too_many_options: getur ekki innihaldið meira en %{max} atriði preferences: other: Annað posting_defaults: Sjálfgefin gildi við gerð færslna public_timelines: Opinberar tímalínur + privacy: + hint_html: "Sérsníddu hvernig þú vilt að finna megi notandasnið þitt og færslur. Ýmsir eiginleikar í Mastodon geta hjálpað þér að ná til breiðari áheyrendahóps, séu þeir virkjaðir. Taktu þér tíma til að yfirfara þessar stillingar svo að þær henti þér." + privacy: Gagnaleynd + privacy_hint_html: Stýrðu því hve miklar upplýsingar þú birtir sem gætu gagnast öðrum. Fólk uppgötvar áhugaverða notendur og sniðug forrit með því að skoða hvað annað fólk fylgist með og hvaða forrit það notar til að birta færslur, en hinsvegar er þér frjálst að halda þessu leyndu. + reach: Útbreiðsla + reach_hint_html: Stýrðu hvort annað fólk geti fundið þig og fylgst með þér. Viltu að færslur frá þér birtist á Kanna-skjánum? Viltu að annað fólk sjái þigþar sem mælt er með hverjum hægt sé að fylgjast með? Viltu samþykkja alla nýja fylgjendur sjálfkrafa, eða viltu stýra því fyrir hvern og einn? + search: Leit + search_hint_html: Stýrðu hvernig hægt sé að finna þig. Viltu að fólk finni þig út frá því sem þú hefur birt opinberlega? Viltu að fólk utan Mastodon geti fundið notandasniðið þitt þegar það leitar á vefnum? Athugaðu að ekki er hægt að tryggja algjöra útilokun frá öllum leitarvélum þegar um opinberlega birtar upplýsingar er að ræða. + title: Gagnaleynd og útbreiðsla privacy_policy: title: Persónuverndarstefna reactions: @@ -1398,6 +1545,7 @@ is: confirm_remove_selected_followers: Ertu viss um að þú viljir fjarlægja valda fylgjendur? confirm_remove_selected_follows: Ertu viss um að þú viljir fjarlægja valið sem fylgst er með? dormant: Sofandi + follow_failure: Gat ekki fylgst með sumum af völdu aðgöngunum. follow_selected_followers: Fylgjast með völdum fylgjendum followers: Fylgjendur following: Fylgist með @@ -1437,6 +1585,7 @@ is: electron: Electron firefox: Firefox generic: Óþekktur vafri + huawei_browser: Huawei-vafri ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi vafri @@ -1446,6 +1595,7 @@ is: qq: QQ vafri safari: Safari uc_browser: UC-vafrinn + unknown_browser: Óþekktur vafri weibo: Weibo current_session: Núverandi seta description: "%{browser} á %{platform}" @@ -1458,9 +1608,10 @@ is: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: óþekktu stýrikerfi + unknown_platform: Óþekkt stýrikerfi windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1531,7 +1682,6 @@ is: show_newer: Sýna nýrri show_older: Sýna eldri show_thread: Birta þráð - sign_in_to_participate: Skráðu þig inn til að taka þátt í samtalinu title: "%{name}: „%{quote}‟" visibilities: direct: Beint @@ -1577,8 +1727,6 @@ is: min_reblogs: Halda færslum sem eru endurbirtar oftar en min_reblogs_hint: Eyðir ekki þínum eigin færslum sem endurbirtar hafa verið þetta oft. Skildu þetta eftir autt til að eyða færslum burtséð frá fjölda endurbirtinga stream_entries: - pinned: Fest færsla - reblogged: endurbirt sensitive_content: Viðkvæmt efni strikes: errors: @@ -1594,6 +1742,11 @@ is: default: "%d. %b, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%e. %b. %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Notkunarkvóti þýðingaþjónustunnar fyrir netþjóninn er uppurinn. + too_many_requests: Það hafa verið of margar beiðnir á þýðingaþjónustuna að undanförnu. two_factor_authentication: add: Bæta við disable: Gera óvirkt @@ -1631,7 +1784,7 @@ is: subject: Skráð hefur verið inn á aðganginn þinn frá nýju IP-vistfangi title: Ný innskráning warning: - appeal: Ssenda inn áfrýjun + appeal: Senda inn áfrýjun appeal_description: Ef þú álítur að um mistök sé að ræða, geturðu sent áfrýjun til umsjónarmanna %{instance}. categories: spam: Ruslpóstur @@ -1673,13 +1826,18 @@ is: title: Velkomin/n um borð, %{name}! users: follow_limit_reached: Þú getur ekki fylgst með fleiri en %{limit} aðilum + go_to_sso_account_settings: Fara í stillingar aðgangsins hjá auðkennisveitunni þinni invalid_otp_token: Ógildur tveggja-þátta kóði otp_lost_help_html: Ef þú hefur misst aðganginn að hvoru tveggja, geturðu sett þig í samband við %{email} seamless_external_login: Innskráning þín er í gegnum utanaðkomandi þjónustu, þannig að stillingar fyrir lykilorð og tölvupóst eru ekki aðgengilegar. signed_in_as: 'Skráð inn sem:' verification: - explanation_html: 'Þú getur vottað að þú sért eigandi og ábyrgur fyrir tenglunum í lýsigögnum notandasniðsins þíns. Til að það virki, þurfa vefsvæðin sem vísað er í að innihalda tengil til baka í Mastodon-notandasniðið. Tengillinn sem vísar til baka verður að vera með rel="me" eigindi. Textinn í tenglinum skiptir ekki máli. Hérna er dæmi:' + extra_instructions_html: Ábending: Tengillinn á vefsvæðinu þínu má vera ósýnilegur. Mikilvægi hlutinn er rel="me" sem kemur í veg fyrir auðkennastuld á vefsvæðum með notenda-framleiddu efni. Þú getur meira að segja notað link einindi í haus síðunnar í stað a, en HTML-kóðinn verður að vera aðgengilegur án keyrslu JavaScript. + here_is_how: Svona gerum við það + hint_html: "Að sannreyna auðkenni þitt á Mastodon er fyrir alla. Byggt á opnum vefstöðlum, ókeypis núna og um ókomna tíð. Allt sem þú þarft er þitt eigið persónulegt vefsvæði sem aðrir geta notað til að þekkja þig. Þegar þú tengir á þetta vefsvæði úr notandasniðinu þínu, munum við athuga hvort vefsvæðið tengi til baka í notandasniðiið þitt og birtum þá sýnilegt merki um að svo sé." + instructions_html: Afritaðu og límdu kóðann hér fyrir neðan inn í HTML-kóða vefsvæðisins þíns. Bættu síðan slóð vefsvæðisins þíns inn í einn af auka-reitunum í flipanum "Breyta notandasniði" og vistaðu síðan breytingarnar. verification: Sannprófun + verified_links: Staðfestu tenglarnir þínir webauthn_credentials: add: Bæta við nýjum öryggislykli create: diff --git a/config/locales/it.yml b/config/locales/it.yml index d0c7168afd..2438e7e62a 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -91,6 +91,7 @@ it: moderation: active: Attivo all: Tutto + disabled: Disattivato pending: In sospeso silenced: Limitato suspended: Sospeso @@ -124,8 +125,8 @@ it: removed_header_msg: Immagine d'intestazione di %{username} rimossa correttamente resend_confirmation: already_confirmed: Questo utente è già confermato - send: Reinvia l'email di conferma - success: Email di conferma inviata correttamente! + send: Invia nuovamente il link di conferma + success: Link di conferma inviato con successo! reset: Ripristina reset_password: Ripristina la password resubscribe: Reiscriviti @@ -133,6 +134,7 @@ it: search: Cerca search_same_email_domain: Altri utenti con lo stesso dominio email search_same_ip: Altri utenti con lo stesso IP + security: Sicurezza security_measures: only_password: Solo password password_and_2fa: Password e A2F @@ -307,6 +309,7 @@ it: unpublish: Annulla la pubblicazione unpublished_msg: Annuncio ritirato! updated_msg: Annuncio aggiornato! + critical_update_pending: Aggiornamento critico in sospeso custom_emojis: assign_category: Assegna categoria by_domain: Dominio @@ -380,6 +383,15 @@ it: undo: Elimina dalla whitelist domain_blocks: add_new: Aggiungi nuovo + confirm_suspension: + cancel: Annulla + confirm: Sospendi + permanent_action: L'annullamento della sospensione non ripristinerà alcun dato o relazione. + preamble_html: Stai per sospendere %{domain} e i suoi sottodomini. + remove_all_data: Questa operazione rimuoverà dal tuo server tutti i contenuti, i file multimediali e i dati del profilo per gli account di questo dominio. + stop_communication: Il tuo server smetterà di comunicare con questi server. + title: Conferma il blocco del dominio per %{domain} + undo_relationships: Questo annullerà qualsiasi relazione di follow tra gli account di questi server e il tuo. created_msg: Il blocco del dominio sta venendo processato destroyed_msg: Il blocco del dominio è stato rimosso domain: Dominio @@ -427,6 +439,7 @@ it: resolve: Risolvi dominio title: Nuova voce della lista nera delle email no_email_domain_block_selected: Nessun blocco di dominio di posta elettronica è stato modificato in quanto nessuno è stato selezionato + not_permitted: Non consentito resolved_dns_records_hint_html: Il nome di dominio si risolve ai seguenti domini MX, che sono in ultima analisi responsabili per l'accettazione di e-mail. Il blocco di un dominio MX bloccherà le iscrizioni da qualsiasi indirizzo e-mail che utilizza lo stesso dominio MX, anche se il nome di dominio visibile è diverso. Fai attenzione a non bloccare i principali provider di posta elettronica. resolved_through_html: Risolto attraverso %{domain} title: Lista nera email @@ -473,6 +486,7 @@ it: content_policies: comment: Nota interna description_html: Puoi definire le politiche del contenuto che saranno applicate a tutti i profili da questo dominio e ognuno dei suoi sottodomini. + limited_federation_mode_description_html: Puoi scegliere se consentire la federazione con questo dominio. policies: reject_media: Rifiuta multimedia reject_reports: Rifiuta rapporti @@ -585,11 +599,13 @@ it: assign_to_self: Assegna a me assigned: Moderatore assegnato by_target_domain: Dominio dell'account segnalato + cancel: Annulla category: Categoria category_description_html: Il motivo per cui questo account e/o contenuto è stato segnalato sarà citato nella comunicazione con l'account segnalato comment: none: Nessuno comment_description_html: 'Per fornire ulteriori informazioni, %{name} ha scritto:' + confirm: Conferma confirm_action: Conferma l'azione di moderazione contro @%{acct} created_at: Segnalato delete_and_resolve: Cancella post @@ -725,6 +741,9 @@ it: branding: preamble: 'Il marchio del tuo server lo differenzia dagli altri server nella rete. Queste informazioni possono essere visualizzate in una varietà di ambienti, come: l''interfaccia web di Mastodon, le applicazioni native, nelle anteprime dei collegamenti su altri siti Web e all''interno delle app di messaggistica e così via. Per questo motivo, è meglio mantenere queste informazioni chiare, brevi e concise.' title: Marchio + captcha_enabled: + desc_html: Questo si basa su script esterni da hCaptcha, che possono rappresentare un problema di sicurezza e privacy. Inoltre, questo può rendere il processo di registrazione significativamente meno accessibile ad alcune persone (soprattutto disabili). Per questi motivi, prendi in considerazione misure alternative come la registrazione basata su approvazione o su invito. + title: Richiedi ai nuovi utenti di risolvere un CAPTCHA per confermare il loro account content_retention: preamble: Controlla come vengono memorizzati i contenuti generati dall'utente in Mastodon. title: Conservazione dei contenuti @@ -752,10 +771,27 @@ it: approved: Approvazione richiesta per le iscrizioni none: Nessuno può iscriversi open: Chiunque può iscriversi + security: + authorized_fetch: Richiede l'autenticazione dai server federati + authorized_fetch_hint: La richiesta di autenticazione da server federati consente un'applicazione più rigorosa dei blocchi sia a livello di utente che a livello di server. Tuttavia, ciò comporta una riduzione delle prestazioni, riduce la portata delle tue risposte e potrebbe introdurre problemi di compatibilità con alcuni servizi federati. Inoltre, ciò non impedirà agli attori dedicati di recuperare i tuoi post pubblici e account. + authorized_fetch_overridden_hint: Al momento non puoi modificare questa impostazione perché è sostituita da una variabile di ambiente. + federation_authentication: Applicazione dell'autenticazione della federazione title: Impostazioni del server site_uploads: delete: Cancella il file caricato destroyed_msg: Caricamento sito eliminato! + software_updates: + critical_update: 'Critico: ti preghiamo di aggiornare rapidamente' + description: Si consiglia di mantenere aggiornata la tua installazione di Mastodon, per beneficiare delle ultime correzioni e funzionalità. Inoltre, talvolta, è cruciale aggiornare Mastodon tempestivamente, per evitare i problemi di sicurezza. Per questo, Mastodon verifica la presenza di aggiornamenti ogni 30 minuti e ti notificherà a seconda delle tue preferenze di notifica via email. + documentation_link: Scopri di più + release_notes: Note di rilascio + title: Aggiornamenti disponibili + type: Tipo + types: + major: Rilascio principale + minor: Rilascio secondario + patch: 'Patch: correzioni di bug e modifiche facili da applicare' + version: Versione statuses: account: Autore application: Applicazione @@ -792,9 +828,24 @@ it: suspend: "%{name} ha sospeso l'account di %{target}" appeal_approved: Sottoposto ad appello appeal_pending: Appello in attesa + appeal_rejected: Appello respinto system_checks: database_schema_check: message_html: Ci sono migrazioni del database in attesa. Sei pregato di eseguirle per assicurarti che l'applicazione si comporti come previsto + elasticsearch_health_red: + message_html: Il cluster Elasticsearch non è integro (stato rosso), le funzionalità di ricerca non sono disponibili + elasticsearch_health_yellow: + message_html: Il cluster Elasticsearch non è integro (stato giallo), potresti voler indagare sul motivo + elasticsearch_index_mismatch: + message_html: Le mappature degli indici Elasticsearch sono obsolete. Si prega di eseguire tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Vedi la documentazione + message_html: Il tuo cluster Elasticsearch ha più di un nodo, ma Mastodon non è configurato per utilizzarli. + elasticsearch_preset_single_node: + action: Vedi la documentazione + message_html: Il tuo cluster Elasticsearch ha un solo nodo, ES_PRESET dovrebbe essere impostato su single_node_cluster. + elasticsearch_reset_chewy: + message_html: Il tuo sistema di indicizzazione Elasticsearch è obsoleto a causa di una modifica delle impostazioni. Si prega di eseguire tootctl search deploy --reset-chewy per aggiornarlo. elasticsearch_running_check: message_html: Impossibile connettersi a Elasticsearch. Verificare che sia in esecuzione o disabilitare la ricerca full-text elasticsearch_version_check: @@ -805,6 +856,18 @@ it: message_html: Non hai definito alcuna regola del server. sidekiq_process_check: message_html: Nessun processo di Sidekiq in esecuzione per le code di %{value}. Sei pregato di revisionare la tua configurazione di Sidekiq + software_version_critical_check: + action: Visualizza gli aggiornamenti disponibili + message_html: Un aggiornamento critico di Mastodon è disponibile, ti preghiamo di aggiornare il più rapidamente possibile. + software_version_patch_check: + action: Visualizza gli aggiornamenti disponibili + message_html: È disponibile un aggiornamento di correzione dei bug di Mastodon. + upload_check_privacy_error: + action: Controlla qui per maggiori informazioni + message_html: "Il tuo server web è mal configurato. La privacy dei tuoi utenti è a rischio." + upload_check_privacy_error_object_storage: + action: Controlla qui per maggiori informazioni + message_html: "La tua archiviazione oggetti è mal configurata. La privacy dei tuoi utenti è a rischio." tags: review: Esamina status updated_msg: Impostazioni hashtag aggiornate con successo @@ -827,6 +890,7 @@ it: other: Condiviso da %{count} persone nell'ultima settimana title: Link in tendenza usage_comparison: Condiviso %{today} volte oggi, rispetto a %{yesterday} ieri + not_allowed_to_trend: Non è consentito il trend only_allowed: Solo consentiti pending_review: Revisione in sospeso preview_card_providers: @@ -911,6 +975,9 @@ it: body: "%{target} sta facendo appello contro una decisione di moderazione di %{action_taken_by} da %{date}, che era %{type}. Ha scritto:" next_steps: Puoi approvare l'appello per annullare la decisione di moderazione, oppure ignorarlo. subject: "%{username} sta facendo appello contro una decisione di moderazione su %{instance}" + new_critical_software_updates: + body: Sono state rilasciate delle nuove versioni critiche di Mastodon, potresti volerlo aggiornare il prima possibile! + subject: Aggiornamenti critici di Mastodon disponibili per %{instance}! new_pending_account: body: I dettagli del nuovo account sono qui sotto. Puoi approvare o rifiutare questa richiesta. subject: Nuovo account pronto per la revisione su %{instance} (%{username}) @@ -918,6 +985,9 @@ it: body: "%{reporter} ha segnalato %{target}" body_remote: Qualcuno da %{domain} ha segnalato %{target} subject: Nuova segnalazione per %{instance} (#%{id}) + new_software_updates: + body: Sono state rilasciate delle nuove versioni di Mastodon, potresti volerlo aggiornare! + subject: Sono disponibili delle nuove versioni di Mastodon per %{instance}! new_trends: body: 'I seguenti elementi necessitano di un controllo prima che possano essere visualizzati pubblicamente:' new_trending_links: @@ -949,24 +1019,28 @@ it: guide_link: https://it.crowdin.com/project/mastodon guide_link_text: Tutti possono contribuire. sensitive_content: Contenuto sensibile - toot_layout: Layout dei toot application_mailer: notification_preferences: Cambia preferenze email salutation: "%{name}," settings: 'Cambia le impostazioni per le email: %{link}' + unsubscribe: Disiscriviti view: 'Guarda:' view_profile: Mostra profilo view_status: Mostra post applications: created: Applicazione creata con successo destroyed: Applicazione eliminata con successo + logout: Disconnettiti regenerate_token: Rigenera il token di accesso token_regenerated: Token di accesso rigenerato warning: Fa' molta attenzione con questi dati. Non fornirli mai a nessun altro! your_token: Il tuo token di accesso auth: apply_for_account: Richiedi un account - change_password: Password + captcha_confirmation: + help_html: Se hai problemi a risolvere il CAPTCHA, puoi metterti in contatto con noi tramite %{email} e ti possiamo aiutare. + hint_html: Solamente un'altra cosa! Dobbiamo confermare che tu sia un essere umano (così possiamo tenere fuori lo spam!). Risolvi il CAPTCHA sottostante e fai clic su "Continua". + title: Controllo di sicurezza confirmations: wrong_email_hint: Se l'indirizzo e-mail non è corretto, puoi modificarlo nelle impostazioni dell'account. delete_account: Elimina account @@ -975,7 +1049,7 @@ it: prefix_invited_by_user: "@%{name} ti invita a iscriverti a questo server Mastodon!" prefix_sign_up: Iscriviti oggi a Mastodon! suffix: Con un account, sarai in grado di seguire le persone, pubblicare aggiornamenti e scambiare messaggi con gli utenti da qualsiasi server di Mastodon e altro ancora! - didnt_get_confirmation: Non hai ricevuto le istruzioni di conferma? + didnt_get_confirmation: Non hai ricevuto un link di conferma? dont_have_your_security_key: Non hai la tua chiave di sicurezza? forgot_password: Hai dimenticato la tua password? invalid_reset_password_token: Il token di reimpostazione della password non è valido o è scaduto. Per favore richiedine uno nuovo. @@ -988,26 +1062,39 @@ it: migrate_account_html: Se vuoi che questo account sia reindirizzato a uno diverso, puoi configurarlo qui. or_log_in_with: Oppure accedi con privacy_policy_agreement_html: Ho letto e accetto l'informativa sulla privacy + progress: + confirm: Conferma l'e-mail + details: I tuoi dettagli + review: La nostra revisione + rules: Accetta le regole providers: cas: CAS saml: SAML register: Iscriviti registration_closed: "%{instance} non accetta nuovi membri" - resend_confirmation: Invia di nuovo le istruzioni di conferma + resend_confirmation: Invia nuovamente il link di conferma reset_password: Resetta la password rules: + accept: Accetta + back: Indietro + invited_by: 'Puoi unirti a %{domain} grazie all''invito che hai ricevuto da:' preamble: Questi sono impostati e applicati dai moderatori di %{domain}. + preamble_invited: Prima di procedere, si prega di considera le regole di base stabilite dai moderatori di %{domain}. title: Alcune regole di base. + title_invited: Sei stato/a invitato/a. security: Credenziali set_new_password: Imposta una nuova password setup: - email_below_hint_html: Se l'indirizzo e-mail sottostante non è corretto, puoi cambiarlo qui e ricevere una nuova e-mail di conferma. - email_settings_hint_html: L'email di conferma è stata inviata a %{email}. Se l'indirizzo e-mail non è corretto, puoi modificarlo nelle impostazioni dell'account. - title: Configurazione + email_below_hint_html: Controlla la tua cartella spam o richiedine un altro. Puoi correggere il tuo indirizzo e-mail, se fosse sbagliato. + email_settings_hint_html: Fai clic sul link che ti abbiamo inviato per verificare %{email}. Aspetteremo proprio qui. + link_not_received: Non hai ricevuto un link? + new_confirmation_instructions_sent: Riceverai una nuova e-mail con il link di conferma entro pochi minuti! + title: Controlla la tua posta in arrivo sign_in: preamble_html: Accedi con le tue credenziali %{domain}. Se il tuo account si trova su un server diverso, non potrai accedere qui. title: Accedi a %{domain} sign_up: + manual_review: Le registrazioni su %{domain} vengono sottoposte a revisione manuale da parte dei nostri moderatori. Per aiutarci a elaborare la tua registrazione, scrivi qualcosa su di te e sul motivo per cui desideri un account su %{domain}. preamble: Con un account su questo server Mastodon, sarai in grado di seguire qualsiasi altra persona sulla rete, indipendentemente da dove sia ospitato il suo account. title: Lascia che ti configuriamo su %{domain}. status: @@ -1019,18 +1106,6 @@ it: view_strikes: Visualizza le sanzioni precedenti prese nei confronti del tuo account too_fast: Modulo inviato troppo velocemente, riprova. use_security_key: Usa la chiave di sicurezza - authorize_follow: - already_following: Stai già seguendo questo account - already_requested: Hai già mandato una richiesta di seguire questo account - error: Sfortunatamente c'è stato un errore nel consultare l'account remoto - follow: Segui - follow_request: 'Hai mandato una richiesta di seguire:' - following: 'Accettato! Ora stai seguendo:' - post_follow: - close: Oppure puoi chiudere questa finestra. - return: Mostra il profilo dell'utente - web: Vai al web - title: Segui %{acct} challenge: confirm: Continua hint_html: "Suggerimento: Non ti chiederemo di nuovo la tua password per la prossima ora." @@ -1107,6 +1182,10 @@ it: your_appeal_rejected: Il tuo appello è stato respinto domain_validator: invalid_domain: non è un nome di dominio valido + edit_profile: + basic_information: Informazioni di base + hint_html: "Personalizza ciò che le persone vedono sul tuo profilo pubblico e accanto ai tuoi post. È più probabile che altre persone ti seguano e interagiscano con te quando hai un profilo compilato e un'immagine del profilo." + other: Altro errors: '400': La richiesta che hai inviato non è valida o non è corretta. '403': Non sei autorizzato a visualizzare questa pagina. @@ -1187,8 +1266,6 @@ it: index: hint: Questo filtro si applica a singoli post indipendentemente da altri criteri. Puoi aggiungere più post a questo filtro dall'interfaccia Web. title: Post filtrati - footer: - trending_now: Di tendenza ora generic: all: Tutto all_items_on_page_selected_html: @@ -1197,7 +1274,9 @@ it: all_matching_items_selected_html: one: "%{count} elemento corrispondente alla tua ricerca è selezionato." other: Tutti i %{count} elementi corrispondenti alla tua ricerca sono selezionati. + cancel: Annulla changes_saved_msg: Modifiche effettuate con successo! + confirm: Conferma copy: Copia delete: Cancella deselect: Deseleziona tutto @@ -1211,24 +1290,62 @@ it: validation_errors: one: Qualcosa ancora non va bene! Per favore, controlla l'errore qui sotto other: Qualcosa ancora non va bene! Per favore, controlla i %{count} errori qui sotto - html_validator: - invalid_markup: 'contiene markup HTML non valido: %{error}' imports: errors: + empty: File CSV vuoto + incompatible_type: Incompatibile con il tipo di importazione selezionato invalid_csv_file: 'File CSV non valido. Errore: %{error}' over_rows_processing_limit: contiene più di %{count} righe + too_large: Il file è troppo grande + failures: Fallimenti + imported: Importato + mismatched_types_warning: Sembra che tu abbia selezionato il tipo sbagliato per questa importazione, ricontrolla per favore. modes: merge: Fondi merge_long: Mantieni record esistenti e aggiungine di nuovi overwrite: Sovrascrivi overwrite_long: Sostituisci record attuali con quelli nuovi + overwrite_preambles: + blocking_html: Stai per sostituire la tua lista di blocchi con un massimo di %{total_items} account da %{filename}. + bookmarks_html: Stai per sostituire i tuoi segnalibri con un massimo di %{total_items} post da %{filename}. + domain_blocking_html: Stai per sostituire la tua lista di domini bloccati con un massimo di %{total_items} domini da %{filename}. + following_html: Stai per seguire fino a %{total_items} account da %{filename} e smettere di seguire chiunque altro. + lists_html: Stai per sostituire le tue liste con i contenuti di %{filename}. Fino a %{total_items} profili verranno aggiunti a nuove liste. + muting_html: Stai per sostituire la tua lista di account silenziati con un massimo di %{total_items} account da %{filename}. + preambles: + blocking_html: Stai per bloccare fino a %{total_items} account da %{filename}. + bookmarks_html: Stai per aggiungere fino a %{total_items} post da %{filename} ai tuoi segnalibri. + domain_blocking_html: Stai per bloccare fino a %{total_items} domini da %{filename}. + following_html: Stai per seguire fino a %{total_items} account da %{filename}. + lists_html: Stai per aggiungere fino a %{total_items} profili da %{filename} alla tue liste. Le nuove liste saranno create se non c'è una lista a cui aggiungere. + muting_html: Stai per silenziare fino a %{total_items} account da %{filename}. preface: Puoi importare alcune informazioni, come le persone che segui o hai bloccato su questo server, da file creati da un'esportazione su un altro server. + recent_imports: Importazioni recenti + states: + finished: Terminata + in_progress: In corso + scheduled: Programmata + unconfirmed: Non confermata + status: Stato success: Le tue impostazioni sono state importate correttamente e verranno applicate in breve tempo + time_started: Iniziata il + titles: + blocking: Importazione di account bloccati + bookmarks: Importazione dei segnalibri + domain_blocking: Importazione dei domini bloccati + following: Importazione degli account seguiti + lists: Importa elenchi + muting: Importazione degli account silenziati + type: Tipo d'importazione + type_groups: + constructive: Seguimenti e Segnalibri + destructive: Blocchi e silenzi types: blocking: Lista dei bloccati bookmarks: Segnalibri domain_blocking: Lista dei domini bloccati following: Lista dei seguiti + lists: Elenchi muting: Lista dei silenziati upload: Carica invites: @@ -1267,6 +1384,21 @@ it: failed_sign_in_html: Tentativo di accesso fallito con %{method} da %{ip} (%{browser}) successful_sign_in_html: Accesso riuscito con %{method} da %{ip} (%{browser}) title: Cronologia delle autenticazioni + mail_subscriptions: + unsubscribe: + action: Sì, annulla l'iscrizione + complete: Iscrizione annullata + confirmation_html: Sei sicuro di voler annullare l'iscrizione alla ricezione di %{type} per Mastodon su %{domain} alla tua e-mail a %{email}? Puoi sempre iscriverti di nuovo dalle tue impostazioni di notifica via email. + emails: + notification_emails: + favourite: e-mai di notifica per i post apprezzati + follow: e-mail di notifica per chi inizia a seguirti + follow_request: e-mail di notifica per la richiesta di seguirti + mention: e-mail di notifica per le menzioni + reblog: e-mail di notifica per le condivisioni + resubscribe_html: Se hai annullato l'iscrizione per errore, puoi iscriverti di nuovo dalle tue impostazioni di notifica via email. + success_html: Non riceverai più %{type} per Mastodon su %{domain} alla tua e-mail a %{email}. + title: Disiscriviti media_attachments: validations: images_and_video: Impossibile allegare video a un post che contiene già immagini @@ -1346,6 +1478,7 @@ it: update: subject: "%{name} ha modificato un post" notifications: + administration_emails: Notifiche email amministratore email_events: Eventi per notifiche via email email_events_hint: 'Seleziona gli eventi per i quali vuoi ricevere le notifiche:' other_settings: Altre impostazioni delle notifiche @@ -1382,12 +1515,22 @@ it: expired: Il sondaggio si è già concluso invalid_choice: L'opzione di voto scelta non esiste over_character_limit: non possono essere più lunghi di %{max} caratteri ciascuno + self_vote: Non puoi votare nei tuoi sondaggi too_few_options: deve avere più di un elemento too_many_options: non può contenere più di %{max} elementi preferences: other: Altro posting_defaults: Predefinite di pubblicazione public_timelines: Timeline pubbliche + privacy: + hint_html: "Personalizza il modo in cui vuoi che il tuo profilo e i tuoi post vengano trovati. Una varietà di funzionalità in Mastodon possono aiutarti a raggiungere un pubblico più ampio se abilitato. Prenditi un momento per rivedere queste impostazioni per assicurarti che si adattino al tuo caso d'uso." + privacy: Privacy + privacy_hint_html: Controlla quanto tu voglia mostrare a beneficio degli altri. Le persone scoprono profili interessanti e app fantastiche sfogliando il seguito di altre persone e vedendo da quali app pubblichino, ma potresti preferire tenerlo nascosto. + reach: Copertura + reach_hint_html: Controlla se vuoi essere scoperto e seguito da nuove persone. Vuoi che i tuoi post vengano visualizzati nella schermata Esplora? Vuoi che altre persone ti vedano tra i loro consigli di utenti da seguire? Vuoi accettare automaticamente tutti i nuovi seguaci o avere un controllo granulare su ciascuno di essi? + search: Cerca + search_hint_html: Controlla come vuoi essere trovato. Vuoi che le persone ti trovino in base a ciò che hai postato pubblicamente? Vuoi che le persone al di fuori di Mastodon trovino il tuo profilo durante la ricerca sul web? Si prega di notare che l'esclusione totale da tutti i motori di ricerca non può essere garantita per le informazioni pubbliche. + title: Privacy e copertura privacy_policy: title: Politica sulla privacy reactions: @@ -1400,6 +1543,7 @@ it: confirm_remove_selected_followers: Sei sicuro di voler rimuovere i follower selezionati? confirm_remove_selected_follows: Sei sicuro di voler rimuovere i follow selezionati? dormant: Dormiente + follow_failure: Impossibile seguire alcuni degli account selezionati. follow_selected_followers: Segui i seguaci selezionati followers: Seguaci following: Seguiti @@ -1439,6 +1583,7 @@ it: electron: Electron firefox: Firefox generic: Browser sconosciuto + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1448,6 +1593,7 @@ it: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Browser sconosciuto weibo: Weibo current_session: Sessione corrente description: "%{browser} su %{platform}" @@ -1460,9 +1606,10 @@ it: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: piattaforma sconosciuta + unknown_platform: Piattaforma sconosciuta windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1533,7 +1680,6 @@ it: show_newer: Mostra più nuovi show_older: Mostra più vecchi show_thread: Mostra thread - sign_in_to_participate: Accedi per partecipare alla conversazione title: '%{name}: "%{quote}"' visibilities: direct: Diretto @@ -1575,12 +1721,10 @@ it: '7889238': 3 mesi min_age_label: Soglia di età min_favs: Conserva i post preferiti più di - min_favs_hint: Non cancella nessuno dei tuoi post che ha ricevuto più di questo numero di preferiti. Lascia vuoto per cancellare i post indipendentemente dal loro numero di preferiti + min_favs_hint: Non cancella nessuno dei tuoi post che ha ricevuto almeno questo numero di preferiti. Lascia vuoto per cancellare i post indipendentemente dal loro numero di preferiti min_reblogs: Conserva i post condivisi più di min_reblogs_hint: Non cancella nessuno dei tuoi post che è stato condiviso più di questo numero di volte. Lascia vuoto per cancellare i post indipendentemente dal loro numero di condivisioni stream_entries: - pinned: Post fissato in cima - reblogged: condiviso sensitive_content: Materiale sensibile strikes: errors: @@ -1596,6 +1740,11 @@ it: default: "%d %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: La quota di utilizzo del server per il servizio di traduzione è stata superata. + too_many_requests: Ci sono state troppe richieste al servizio di traduzione di recente. two_factor_authentication: add: Aggiungi disable: Disabilita @@ -1675,13 +1824,18 @@ it: title: Benvenuto a bordo, %{name}! users: follow_limit_reached: Non puoi seguire più di %{limit} persone + go_to_sso_account_settings: Vai alle impostazioni dell'account del tuo provider di identità invalid_otp_token: Codice d'accesso non valido otp_lost_help_html: Se perdessi l'accesso ad entrambi, puoi entrare in contatto con %{email} seamless_external_login: Hai effettuato l'accesso tramite un servizio esterno, quindi le impostazioni di password e e-mail non sono disponibili. signed_in_as: 'Hai effettuato l''accesso come:' verification: - explanation_html: 'Puoi certificare te stesso come proprietario dei link nei metadati del tuo profilo. Per farlo, il sito a cui punta il link deve contenere un link che punta al tuo profilo Mastodon. Il link di ritorno deve avere l''attributo rel="me". Il testo del link non ha importanza. Ecco un esempio:' + extra_instructions_html: Suggerimento: il collegamento sul tuo sito web può essere invisibile. La parte importante è rel="me" che impedisce l'impersonificazione su siti web con contenuti generati dagli utenti. Puoi anche usare un tag link nell'intestazione della pagina invece di a, ma l'HTML deve essere accessibile senza eseguire JavaScript. + here_is_how: Ecco come + hint_html: "La verifica della tua identità su Mastodon è per tutti. Basata su standard web aperti, ora e per sempre gratis. Tutto ciò di cui hai bisogno è un sito web personale in cui le persone ti riconoscano. Quando ti colleghi a questo sito web dal tuo profilo, verificheremo che il sito web rimandi al tuo profilo e mostreremo un indicatore visivo su di esso." + instructions_html: Copia e incolla il codice qui sotto nell'HTML del tuo sito web. Quindi, aggiungi l'indirizzo del tuo sito web in uno dei campi aggiuntivi del tuo profilo dalla scheda "Modifica profilo" e salva le modifiche. verification: Verifica + verified_links: I tuoi collegamenti verificati webauthn_credentials: add: Aggiungi una nuova chiave di sicurezza create: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 288d56ca5b..6a72c1ca14 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -89,6 +89,7 @@ ja: moderation: active: アクティブ all: すべて + disabled: 無効化済み pending: 承認待ち silenced: 制限 suspended: 停止済み @@ -122,7 +123,7 @@ ja: resend_confirmation: already_confirmed: メールアドレスは確認済みです send: 確認メールを再送 - success: 確認メールを再送信しました! + success: 確認メールを再送信しました reset: リセット reset_password: パスワード再設定 resubscribe: 再講読 @@ -130,6 +131,7 @@ ja: search: 検索 search_same_email_domain: 同じドメインのメールアドレスを使用しているユーザー search_same_ip: 同じIPのユーザーを検索 + security: 認証方法 security_measures: only_password: パスワードのみ password_and_2fa: パスワードと二要素認証 @@ -304,6 +306,7 @@ ja: unpublish: 非公開にする unpublished_msg: お知らせを非掲載にしました updated_msg: お知らせを更新しました + critical_update_pending: 重要な更新が保留中です custom_emojis: assign_category: カテゴリーを割り当て by_domain: ドメイン @@ -373,6 +376,15 @@ ja: undo: 連合許可を外す domain_blocks: add_new: ドメインブロックを追加 + confirm_suspension: + cancel: キャンセル + confirm: 停止 + permanent_action: 失われたデータやフォロー関係は、停止を解除しても元に戻せません。 + preamble_html: "%{domain} と、そのサブドメインに「停止」の処置を行います。" + remove_all_data: この操作により、対象のドメインにあるアカウントからのコンテンツやメディア、プロフィール情報はすべて削除されます。 + stop_communication: 対象のサーバーとは通信を行わなくなります。 + title: "「%{domain}」ドメインブロックの確認" + undo_relationships: この操作により、このサーバーと対象サーバーのアカウント間のフォロー関係はすべて解除されます。 created_msg: ドメインブロック処理を完了しました destroyed_msg: ドメインブロックを外しました domain: ドメイン @@ -419,6 +431,7 @@ ja: resolve: ドメイン解決 title: 新規メールドメインブロック no_email_domain_block_selected: 何も選択されていないためメールドメインブロックを変更しませんでした + not_permitted: 権限がありません resolved_dns_records_hint_html: ドメイン名はDNSでMXドメインに名前解決され、最終的にメールを受け付ける役割を担います。目に見えるドメイン名が異なっていても、同じMXドメインを使用するメールアドレスからのアカウント登録がブロックされます。主要なメールプロバイダーをブロックしないように注意して下さい。 resolved_through_html: "%{domain}を通して解決しました" title: メールドメインブロック @@ -463,6 +476,7 @@ ja: content_policies: comment: 内部メモ description_html: このドメインとそのサブドメインのすべてのアカウントに適用されるコンテンツポリシーを定義できます。 + limited_federation_mode_description_html: このドメインとの連合を許可するかどうかを選択できます。 policies: reject_media: メディアを拒否する reject_reports: 通報を拒否 @@ -565,7 +579,7 @@ ja: other_description_html: アカウントの動作を制御するためのオプションや、報告されたアカウントへの通信をカスタマイズするためのオプションを確認してください。 resolve_description_html: 報告されたアカウントに対していかなる措置も取られず、ストライクも記録されず、報告は終了します。 silence_description_html: このアカウントは、すでにフォローしている人、または手動で検索した人にしか見えないため、リーチが極端に制限されます。いつでも元に戻すことができます。このアカウントに対するすべての通報をクローズします。 - suspend_description_html: アカウントとそのすべての内容にアクセスできなくなり、最終的に削除され、それとやり取りは不可能になります。 30日以内にリバーシブル。このアカウントに対するすべての通報をクローズします。 + suspend_description_html: アカウントとそのすべての内容にアクセスできなくなり、最終的に削除され、やり取りは不可能になります。 30日以内であれば元に戻すことができます。このアカウントに対するすべての通報をクローズします。 actions_description_html: このレポートを解決するために取るアクションを決定します。 報告されたアカウントに対して懲罰的な措置を取った場合、メール通知が送信されますがスパムカテゴリが選択されている場合を除きます。 actions_description_remote_html: この通報を解決するためのアクションを選択してください。これはあなたのサーバーがこのリモートアカウントと通信し、そのコンテンツを処理する時のみ影響します。 add_to_report: 通報にさらに追加 @@ -573,11 +587,13 @@ ja: assign_to_self: 担当になる assigned: 担当者 by_target_domain: ドメイン + cancel: キャンセル category: カテゴリー category_description_html: 選択した理由は通報されたアカウントへの連絡時に引用されます comment: none: なし comment_description_html: "%{name}からの詳細情報:" + confirm: 確認 confirm_action: "@%{acct} さんに対するアクション" created_at: 通報日時 delete_and_resolve: 投稿を削除 @@ -612,12 +628,12 @@ ja: action_preambles: delete_html: "@%{acct}さんの投稿を削除します。この操作は:" mark_as_sensitive_html: "@%{acct}さんの投稿を閲覧注意としてマークします。この操作は:" - silence_html: "@%{acct}さんのアカウントを制限します。この操作は:" - suspend_html: "@%{acct}さんのアカウントを停止します。この操作は:" + silence_html: "@%{acct}さんのアカウントを制限 (サイレンス) します。この操作は:" + suspend_html: "@%{acct}さんのアカウントを停止 (サスペンド) します。この操作は:" actions: delete_html: 当該の投稿を削除します mark_as_sensitive_html: 当該の投稿に含まれるメディアを閲覧注意にします - silence_html: プロフィールとコンテンツを、すでにフォローしている人や、意図的にプロフィールにアクセスする人にのみ表示することで、@%{acct}さんのリーチを厳しく制限します + silence_html: "@%{acct}さんのプロフィールとコンテンツの表示範囲をフォロー中の人や意図的にプロフィールにアクセスした人のみに制限することで、アカウントを発見されにくくします" suspend_html: "@%{acct}さんのアカウントが凍結され、プロフィールとコンテンツへのアクセス、および投稿ができなくなります" close_report: '通報 #%{id} を解決済みにします' close_reports_html: "@%{acct}さんに対するすべての通報を解決済みにします" @@ -711,6 +727,9 @@ ja: branding: preamble: サーバーのブランディングは、ネットワーク上の他のサーバーと区別するためのものです。この情報は、Mastodon の Web インターフェース、ネイティブアプリケーション、他の Web サイトやメッセージングアプリのリンクプレビューなど、様々な所で表示される可能性があります。このため、明確で短く、簡潔に記載することをおすすめします。 title: ブランディング + captcha_enabled: + desc_html: この機能は hCaptcha による外部スクリプトを使用しますが、hCaptcha にはセキュリティとプライバシーの懸念が考えられます。また、CAPTCHAにより新規登録のアクセシビリティが大幅に損なわれる可能性があり、身体および精神障害者においては特に顕著です。以上の理由から、承認制や招待制を基本とするなど、代わりの登録手順を提供することを検討してください。 + title: 新規ユーザーのアカウント確認にCHAPCHAを要求する content_retention: preamble: ユーザーが生成したコンテンツがどのように Mastodon に保存されるかを管理します。 title: コンテンツの保持 @@ -738,10 +757,27 @@ ja: approved: 登録には承認が必要 none: 誰にも許可しない open: 誰でも登録可 + security: + authorized_fetch: 連合サーバーによる署名なしでの情報取得を拒否する + authorized_fetch_hint: ほかの連合サーバーから受け付けるリクエストに署名を必須にすることで、ユーザーによるブロックおよびドメインブロック両方の効果をより強力にします。ただし連合の処理コストが増えてパフォーマンス面で不利になるほか、このサーバーから送られた反応が届く範囲が狭まったり、連合における互換性の問題を招く可能性もあります。また、この機能は公開投稿やプロフィールへのアクセスをブロックした相手から完全に遮断できるものではありません。 + authorized_fetch_overridden_hint: この設定は環境変数で指定されているため、ここでは変更できません。 + federation_authentication: 連合に署名を必須にする title: サーバー設定 site_uploads: delete: ファイルを削除 destroyed_msg: ファイルを削除しました! + software_updates: + critical_update: "※緊急 (速やかに適用してください)" + description: Mastodonサーバーはいつでも最新の状態を保ち、新しい機能や修正を利用できるようにしておくことをおすすめします。またセキュリティの問題が発生した場合は、速やかにMastodonをアップデートすることが大切です。Mastodonは30分おきにアップデートを確認し、通知設定に応じて新しいアップデートをメールで通知します。 + documentation_link: もっと見る + release_notes: リリースノート + title: 利用可能なアップデート + type: アップデートの種別 + types: + major: メジャーリリース + minor: マイナーリリース + patch: パッチ (バグ修正のみ) + version: バージョン statuses: account: 作成者 application: アプリ @@ -778,9 +814,24 @@ ja: suspend: "%{name}さんが%{target}さんのアカウントを停止しました" appeal_approved: 抗議済み appeal_pending: 保留中の抗議 + appeal_rejected: 却下済みの抗議 system_checks: database_schema_check: message_html: 未実行のデータベースマイグレーションがあります。実行して正常に動作するようにしてください。 + elasticsearch_health_red: + message_html: 'Elasticsearchクラスターに異常があります(status: red)。検索機能が利用できなくなっています' + elasticsearch_health_yellow: + message_html: 'Elasticsearchクラスターに異常があります(status: yellow)。必要に応じて対策を実施してください' + elasticsearch_index_mismatch: + message_html: Elasticsearchのインデックスのマッピング定義が古くなっています。tootctl search deploy --only=%{value} を実行してインデックスを更新してください + elasticsearch_preset: + action: 詳細情報 + message_html: Elasticsearchクラスターはマルチノード構成になっていますが、Mastodonがマルチノード構成向けに設定されていません。 + elasticsearch_preset_single_node: + action: 詳細情報 + message_html: Elasticsearchクラスターはシングルノード構成になっています。ES_PRESETsingle_node_cluster に設定してください。 + elasticsearch_reset_chewy: + message_html: 設定が変更されたため、Elasticsearchのシステムインデックスが古くなっています。tootctl search deploy --reset-chewy を実行してインデックスを更新してください elasticsearch_running_check: message_html: Elasticsearchに接続できませんでした。Elasticsearchが実行されていることを確認するか、全文検索を無効にしてください。 elasticsearch_version_check: @@ -791,6 +842,18 @@ ja: message_html: サーバーのルールを定義していません。 sidekiq_process_check: message_html: "%{value}キューに対応するSidekiqプロセスがありません。Sidekiqの設定を確認してください。" + software_version_critical_check: + action: 利用可能な更新を見る + message_html: 緊急のMastodonアップデートがあります。速やかに適用してください。 + software_version_patch_check: + action: 詳細 + message_html: Mastodonのバグ修正アップデートが利用可能です。 + upload_check_privacy_error: + action: ここを開いて詳細を確認してください + message_html: "Web サーバーが正しく設定されていません。ユーザーのプライバシーが危険な状態になっています。" + upload_check_privacy_error_object_storage: + action: ここを開いて詳細を確認してください + message_html: "オブジェクトストレージが正しく設定されていません。ユーザーのプライバシーが危険な状態になっています。" tags: review: 審査状況 updated_msg: ハッシュタグ設定が更新されました @@ -812,6 +875,7 @@ ja: other: 週間%{count}人に共有されました title: トレンドリンク usage_comparison: 今日は%{today}回、昨日は%{yesterday}回共有されました + not_allowed_to_trend: 未許可のトレンド only_allowed: 許可済み pending_review: 保留中 preview_card_providers: @@ -829,7 +893,7 @@ ja: no_status_selected: 何も選択されていないため、変更されていません not_discoverable: 投稿者は発見可能であることに同意していません shared_by: - other: "%{friendly_count} 回の共有、お気に入り" + other: "%{friendly_count}回の共有、お気に入り" title: トレンド投稿 tags: current_score: 現在のスコア %{score} @@ -893,6 +957,9 @@ ja: body: "%{target} は %{date} に行われた %{action_taken_by} による %{type} のモデレーション判定に不服を申し立てています。内容は次の通りです:" next_steps: モデレーションの決定を取り消すために申し立てを承認するか、無視することができます。 subject: "%{instance}で%{username}さんからモデレーションへの申し立てが届きました。" + new_critical_software_updates: + body: 重要な修正を含むMastodonのアップデートがリリースされています。早急にアップデートを行ってください。 + subject: 緊急のMastodonアップデートがあります[%{instance}] new_pending_account: body: 新しいアカウントの詳細は以下の通りです。この申請を承認または却下することができます。 subject: "%{instance}で新しいアカウント (%{username}) が承認待ちです" @@ -900,6 +967,9 @@ ja: body: "%{reporter}さんが%{target}さんを通報しました" body_remote: "%{domain}の誰かが%{target}さんを通報しました" subject: "%{instance}の新しい通報 (#%{id})" + new_software_updates: + body: Mastodonの新しいアップデートがリリースされました。 + subject: Mastodonのアップデートがあります[%{instance}] new_trends: body: 以下の項目は、公開する前に審査が必要です。 new_trending_links: @@ -929,24 +999,28 @@ ja: guide_link: https://ja.crowdin.com/project/mastodon guide_link_text: 誰でも参加することができます。 sensitive_content: 閲覧注意コンテンツ - toot_layout: 投稿のレイアウト application_mailer: notification_preferences: メール設定の変更 salutation: "%{name}さん" settings: 'メール設定の変更: %{link}' + unsubscribe: 購読解除 view: 'リンク:' view_profile: プロフィールを表示 view_status: 投稿を表示 applications: created: アプリが作成されました destroyed: アプリが削除されました + logout: ログアウト regenerate_token: アクセストークンの再生成 token_regenerated: アクセストークンが再生成されました warning: このデータは気をつけて取り扱ってください。他の人と共有しないでください! your_token: アクセストークン auth: apply_for_account: アカウントのリクエスト - change_password: パスワード + captcha_confirmation: + help_html: CAPTCHAの解決に問題がある場合は、 %{email} までお問い合わせください。お手伝いいたします。 + hint_html: もう一つだけ!あなたが人間であることを確認する必要があります(スパムを防ぐためです!)。 以下のCAPTCHAを解き、「続ける」をクリックします。 + title: セキュリティチェック confirmations: wrong_email_hint: メールアドレスが正しくない場合は、アカウント設定で変更できます。 delete_account: アカウントの削除 @@ -955,7 +1029,7 @@ ja: prefix_invited_by_user: "@%{name}さんがあなたをこのMastodonサーバーに招待しました" prefix_sign_up: 今すぐMastodonを始めよう! suffix: アカウントがあれば、どんなMastodon互換サーバーのユーザーでもフォローしたりメッセージをやり取りできるようになります! - didnt_get_confirmation: 確認メールを受信できませんか? + didnt_get_confirmation: 確認メールを受信できない場合は dont_have_your_security_key: セキュリティキーを持っていませんか? forgot_password: パスワードをお忘れですか? invalid_reset_password_token: パスワードリセットトークンが正しくないか期限切れです。もう一度リクエストしてください。 @@ -968,26 +1042,39 @@ ja: migrate_account_html: 引っ越し先を明記したい場合はこちらで設定できます。 or_log_in_with: または次のサービスでログイン privacy_policy_agreement_html: プライバシーポリシーを読み、同意します + progress: + confirm: メールアドレスの確認 + details: ユーザー情報 + review: 承認 + rules: ルール providers: cas: CAS saml: SAML register: 登録する registration_closed: "%{instance}は現在、新規登録停止中です" - resend_confirmation: 確認メールを再送する + resend_confirmation: 確認メールを再送 reset_password: パスワードを再発行 rules: + accept: 同意する + back: 戻る + invited_by: '以下のユーザーから %{domain} への招待を受けました:' preamble: これらは %{domain} モデレータによって設定され、実施されます。 + preamble_invited: 次に進む前に、 %{domain} のモデレーターが定めたルールを確認してください。 title: いくつかのルールがあります。 + title_invited: このサーバーに招待されています。 security: セキュリティ set_new_password: 新しいパスワード setup: - email_below_hint_html: 下記のメールアドレスが間違っている場合、ここで変更することで新たに確認メールを受信できます。 - email_settings_hint_html: 確認用のメールを%{email}に送信しました。メールアドレスが正しくない場合、以下より変更することができます。 - title: セットアップ + email_below_hint_html: 確認メールが迷惑メールフォルダに振り分けられていないか確認してください。メールアドレスを間違えた場合は、ここでメールアドレスの変更と確認メールの再送ができます。 + email_settings_hint_html: メールに記載のリンクを開いて %{email} を確認してください。 + link_not_received: 確認メールを受信できない場合は + new_confirmation_instructions_sent: 確認用のリンクを記載した新しいメールを送信しました + title: 確認メールを送信しました sign_in: preamble_html: "%{domain} の資格情報でサインインします。 あなたのアカウントが別のサーバーでホストされている場合は、ここでログインすることはできません。" title: "%{domain}にログイン" sign_up: + manual_review: "%{domain} への登録にはモデレーターによる承認が必要です。審査の参考になるように、簡単な自己紹介や %{domain} に登録したい理由などを記入してください。" preamble: この Mastodon サーバーのアカウントがあれば、ネットワーク上の他の人のアカウントがどこでホストされているかに関係なく、その人をフォローすることができます。 title: さあ %{domain} でセットアップしましょう. status: @@ -999,18 +1086,6 @@ ja: view_strikes: 過去のストライクを表示 too_fast: フォームの送信が速すぎます。もう一度やり直してください。 use_security_key: セキュリティキーを使用 - authorize_follow: - already_following: あなたは既にこのアカウントをフォローしています - already_requested: 既にこのアカウントへフォローリクエストを送信しています - error: 残念ながら、リモートアカウント情報の取得中にエラーが発生しました - follow: フォロー - follow_request: 'あなたは以下のアカウントにフォローリクエストを送信しました:' - following: '成功! あなたは現在以下のアカウントをフォローしています:' - post_follow: - close: またはこのウィンドウを閉じます。 - return: ユーザーのプロフィールを見る - web: Webを開く - title: "%{acct}さんをフォロー" challenge: confirm: 続ける hint_html: 以後1時間はパスワードの再入力を求めません @@ -1087,6 +1162,10 @@ ja: your_appeal_rejected: 申し立ては拒否されました domain_validator: invalid_domain: は無効なドメイン名です + edit_profile: + basic_information: 基本情報 + hint_html: "アカウントのトップページや投稿の隣に表示される公開情報です。プロフィールとアイコンを設定することで、ほかのユーザーは親しみやすく、またフォローしやすくなります。" + other: その他 errors: '400': 送信されたリクエストは無効であるか、または不正なフォーマットです。 '403': このページを表示する権限がありません。 @@ -1123,12 +1202,12 @@ ja: featured_tags: add_new: 追加 errors: - limit: 注目のハッシュタグの上限に達しました + limit: すでに注目のハッシュタグの上限数に達しています hint_html: "注目のハッシュタグとは? プロフィールページに目立つ形で表示され、そのハッシュタグのついたあなたの公開投稿だけを抽出して閲覧できるようにします。クリエイティブな仕事や長期的なプロジェクトを追うのに優れた機能です。" filters: contexts: account: プロフィール - home: ホームタイムライン + home: ホームおよびリスト notifications: 通知 public: 公開タイムライン thread: 会話 @@ -1164,15 +1243,15 @@ ja: index: hint: このフィルターは、他の条件に関係なく個々の投稿を選択する場合に適用されます。Webインターフェースからこのフィルターにさらに投稿を追加できます。 title: フィルターされた投稿 - footer: - trending_now: トレンドタグ generic: all: すべて all_items_on_page_selected_html: other: このページの %{count} 件すべてが選択されています。 all_matching_items_selected_html: other: 検索条件に一致する %{count} 件すべてが選択されています。 + cancel: キャンセル changes_saved_msg: 正常に変更されました! + confirm: 続ける copy: コピー delete: 削除 deselect: 選択解除 @@ -1184,24 +1263,62 @@ ja: today: 今日 validation_errors: other: エラーが発生しました! 以下の%{count}件のエラーを確認してください - html_validator: - invalid_markup: '無効なHTMLマークアップが含まれています: %{error}' imports: errors: + empty: CSVファイルの内容がありません + incompatible_type: 選択したインポート項目とファイルの内容が異なります invalid_csv_file: '無効なCSVファイルです。エラー: %{error}' over_rows_processing_limit: "%{count}行以上" + too_large: ファイルが大きすぎます + failures: 失敗 + imported: インポート済み + mismatched_types_warning: インポート項目と異なるファイルを選択している可能性があります。続ける前にファイルの内容をもう一度確認してください。 modes: merge: 統合 merge_long: 現在のレコードを保持したまま新しいものを追加します overwrite: 上書き overwrite_long: 現在のレコードを新しいもので置き換えます + overwrite_preambles: + blocking_html: "%{filename}%{total_items}個のアカウントブロックしたアカウントリストを置き換えます。" + bookmarks_html: "%{filename}%{total_items}件の投稿ブックマークの一覧を置き換えます。" + domain_blocking_html: "%{filename}%{total_items}個のドメイン非表示にしたドメインリストを置き換えます。" + following_html: "%{filename}%{total_items}個のアカウントフォローします。また、この中に含まれていないアカウントのフォローを解除します。" + lists_html: "作成済みのリスト%{filename}の内容で置き換えます%{total_items}個のアカウントが新しいリストに追加されます。" + muting_html: "%{filename}%{total_items}個のアカウントミュートしたアカウントリストを置き換えます。" + preambles: + blocking_html: "%{filename}%{total_items}個のアカウントブロックします。" + bookmarks_html: "%{filename}%{total_items}件の投稿ブックマークに追加します。" + domain_blocking_html: "%{filename}%{total_items}個のドメイン非表示にします。" + following_html: "%{filename}%{total_items}個のアカウントフォローします。" + lists_html: "%{filename}%{total_items}個のアカウントリストに追加します。追加先のリストがない場合は新しく作成されます。" + muting_html: "%{filename}%{total_items}個のアカウントミュートします。" preface: 他のサーバーでエクスポートされたファイルから、フォロー/ブロックした情報をこのサーバー上のアカウントにインポートできます。 + recent_imports: 最近のインポート + states: + finished: 完了 + in_progress: 処理中 + scheduled: スケジュール済み + unconfirmed: 確認が必要です + status: 状態 success: ファイルは正常にアップロードされ、現在処理中です。しばらくしてから確認してください + time_started: 開始日時 + titles: + blocking: ブロックのインポート + bookmarks: ブックマークのインポート + domain_blocking: ドメイン非表示のインポート + following: フォローのインポート + lists: リストのインポート + muting: ミュートのインポート + type: インポートする項目 + type_groups: + constructive: フォロー・ブックマーク + destructive: ブロック・ミュート types: blocking: ブロックしたアカウントリスト bookmarks: ブックマーク domain_blocking: 非表示にしたドメインリスト following: フォロー中のアカウントリスト + lists: リスト muting: ミュートしたアカウントリスト upload: アップロード invites: @@ -1227,7 +1344,7 @@ ja: title: 新規ユーザーの招待 lists: errors: - limit: リストの上限に達しました + limit: リストの上限数に達しています login_activities: authentication_methods: otp: 二要素認証アプリ @@ -1239,6 +1356,21 @@ ja: failed_sign_in_html: "%{ip} (%{browser}) から%{method}を利用したサインインに失敗しました。" successful_sign_in_html: "%{ip} (%{browser}) から%{method}を利用したサインインに成功しました" title: 認証履歴 + mail_subscriptions: + unsubscribe: + action: 購読を解除する + complete: 購読を解除しました + confirmation_html: '%{domain} の Mastodon による %{email} への%{type}を購読解除しますか? 再購読が必要になった場合はメール通知の設定からいつでも再開できます。' + emails: + notification_emails: + favourite: お気に入り登録の通知メール + follow: フォロー通知メール + follow_request: フォローリクエスト通知メール + mention: 返信の通知メール + reblog: ブーストの通知メール + resubscribe_html: 間違って配信を停止した場合は、 メール通知設定から再登録できます。 + success_html: "%{domain} の Mastodon から %{email} への%{type}の配信が停止されました。" + title: 購読の解除 media_attachments: validations: images_and_video: 既に画像が追加されているため、動画を追加することはできません @@ -1318,6 +1450,7 @@ ja: update: subject: "%{name}さんが投稿を更新しました" notifications: + administration_emails: 管理にかかわるメール通知 email_events: メールによる通知 email_events_hint: '受信する通知を選択:' other_settings: その他の通知設定 @@ -1354,12 +1487,22 @@ ja: expired: アンケートは既に終了しました invalid_choice: 選択された項目は存在しません over_character_limit: は%{max}文字より長くすることはできません + self_vote: 自分のアンケートには解答できません too_few_options: は複数必要です too_many_options: は%{max}個までです preferences: other: その他 posting_defaults: デフォルトの投稿設定 public_timelines: 公開タイムライン + privacy: + hint_html: "プロフィールの見えかたや、ほかのユーザーからの見つかりやすさを設定します。Mastodonには自分のアカウントのことをより多くの人に知ってもらうためのさまざまな機能があり、有効・無効をそれぞれ切り換えられます。使いかたや好みに合わせて調節しましょう。" + privacy: プライバシー + privacy_hint_html: 自分に関する情報をどの程度開示するかについての設定項目です。ユーザーはほかのアカウントのフォロー一覧を見て興味のあるアカウントを探したり、投稿元のアプリ名を見て自分が使いたいアプリの参考にすることがあります。希望に応じて、これらを見られないようにできます。 + reach: つながりやすさ + reach_hint_html: ほかのユーザーからの見つかりやすさと、フォローされる方法についての設定項目です。「エクスプローラー」やおすすめのユーザーに掲載するか、また新しいフォロワーをどのように受け入れるかをここで変更できます。 + search: 被検索性 + search_hint_html: 検索での見つかりやすさに関する設定項目です。公開投稿を検索できるようにするかや、Mastodonの外からweb検索でたどり着けるようにするかをここで変更できます。ただし検索エンジンのなかには、この設定に従わずに公開されている情報を利用するものがあるかもしれません。 + title: プライバシーとつながりやすさ privacy_policy: title: プライバシーポリシー reactions: @@ -1372,6 +1515,7 @@ ja: confirm_remove_selected_followers: 選択したフォロワーを削除してもよろしいですか? confirm_remove_selected_follows: 選択したフォローを削除してもよろしいですか? dormant: 非アクティブ + follow_failure: 選択したアカウントの一部をフォローできませんでした。 follow_selected_followers: 選択したフォロワーをフォロー followers: フォロワー following: フォロー中 @@ -1411,6 +1555,7 @@ ja: electron: Electron firefox: Firefox generic: 不明なブラウザ + huawei_browser: Huaweiブラウザ ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1420,6 +1565,7 @@ ja: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: 不明なブラウザ weibo: Weibo current_session: 現在のセッション description: "%{platform}上の%{browser}" @@ -1432,9 +1578,10 @@ ja: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: 不明なプラットフォーム + unknown_platform: 不明なプラットフォーム windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1499,7 +1646,6 @@ ja: show_newer: 新しいものを表示 show_older: 古いものを表示 show_thread: スレッドを表示 - sign_in_to_participate: ログインして会話に参加 title: '%{name}: "%{quote}"' visibilities: direct: ダイレクト @@ -1541,12 +1687,10 @@ ja: '7889238': 3ヶ月 min_age_label: 投稿を保持する期間 min_favs: お気に入りの基準値 - min_favs_hint: この数以上、お気に入りされた投稿を削除せずに残します。空白にしておくと、お気に入りに登録された数に関わらず投稿を削除します。 + min_favs_hint: この数以上、お気に入り登録された投稿を削除せずに残します。空白にしておくと、お気に入りの数に関わらず投稿を削除します。 min_reblogs: ブーストの基準値 min_reblogs_hint: この数以上、ブーストされた投稿を削除せずに残します。空白にしておくと、ブーストされた数に関わらず投稿を削除します。 stream_entries: - pinned: 固定された投稿 - reblogged: さんがブースト sensitive_content: 閲覧注意 strikes: errors: @@ -1562,6 +1706,11 @@ ja: default: "%Y年%m月%d日 %H:%M" month: "%Y年 %b" time: "%H:%M" + with_time_zone: "%Y年%m月%d日 %H:%M %Z" + translation: + errors: + quota_exceeded: このサーバーは翻訳サービスの利用制限に達しました。 + too_many_requests: 大量のリクエストのため、翻訳サービスの利用が一時的に制限されています。 two_factor_authentication: add: 追加 disable: 無効化 @@ -1643,13 +1792,18 @@ ja: title: ようこそ、%{name}さん! users: follow_limit_reached: あなたは現在 %{limit}人以上フォローできません + go_to_sso_account_settings: 外部サービスアカウントの設定はこちらで行ってください invalid_otp_token: 二要素認証コードが間違っています otp_lost_help_html: どちらも使用できない場合、%{email}に連絡を取ると解決できるかもしれません seamless_external_login: あなたは外部サービスを介してログインしているため、パスワードとメールアドレスの設定は利用できません。 signed_in_as: '下記でログイン中:' verification: - explanation_html: プロフィール内のリンクの所有者であることを認証することができます。そのためにはリンクされたウェブサイトにMastodonプロフィールへのリンクが含まれている必要があります。リンクにはrel="me"属性を必ず与えなければなりません。リンクのテキストについては重要ではありません。以下は例です: + extra_instructions_html: ワンポイント: webサイト上のプロフィールへのリンクは表示上見えなくてもかまいません。重要な部分は rel="me" で、これはユーザーが自由にリンクを作成可能なサイトを悪用してなりすまされるのを防ぐための情報です。a タグを配置する代わりに link タグをHTMLヘッダーに挿入することでも認証が可能です。ただし、HTMLにはJavaScriptを使わなくてもアクセスできるようにしてください。 + here_is_how: 認証方法 + hint_html: "Mastodonの本人認証はすべてのユーザーが自由に利用できます。この機能はweb標準に基づいており、将来にわたり無料です。必要なものは自分のものと認知されている個人サイトだけです。プロフィールからwebサイトにリンクし、webサイトからもプロフィールへ相互にリンクすると、Mastodonがそれを検証し、認証済みであることを表示します。" + instructions_html: 以下のコードをコピーしてwebサイトのHTMLに貼り付けます。次に「プロフィールを編集」タブから、「プロフィール補足情報」のいずれかの欄にwebサイトのURLを記入し、「変更を保存」をクリックしてください。 verification: 認証 + verified_links: 確認済みリンク webauthn_credentials: add: セキュリティキーを追加 create: diff --git a/config/locales/ka.yml b/config/locales/ka.yml index ff08987d9a..d67f432688 100644 --- a/config/locales/ka.yml +++ b/config/locales/ka.yml @@ -69,8 +69,6 @@ ka: remove_avatar: გააუქმე ავატარი resend_confirmation: already_confirmed: ეს მომხმარებელი უკვე დამოწმებულია - send: დამოწმების ინსტრუქციების გადაგზავნა - success: დამოწმების ინსტრუქციები წარმატებით გაიგზავნა! reset: გადატვირთვა reset_password: პაროლის გადატვირთვა resubscribe: ხელახალი გამოწერა @@ -218,10 +216,8 @@ ka: warning: იყავით ძალიან ფრთხილად ამ მონაცემთან. არასდროს გააზიაროთ ეს! your_token: თქვენი წვდომის ტოკენი auth: - change_password: პაროლი delete_account: ანგარიშის გაუქმება delete_account_html: თუ გსურთ გააუქმოთ თქვენი ანგარიში, შეგიძლიათ გააგრძელოთ აქ. საჭირო იქნება დამოწმება. - didnt_get_confirmation: არ მოგსვლიათ დამოწმების ინსტრუქციები? forgot_password: დაგავიწყდათ პაროლი? invalid_reset_password_token: პაროლის გადატვირთვის ტოკენი არასწორია ან ვადაგასული. გთხოვთ მოითხოვეთ ახალი. login: შესვლა @@ -233,21 +229,9 @@ ka: cas: ქეს saml: სამლ register: რეგისტრაცია - resend_confirmation: დამოწმების ინსტრუქციების ხელახალი გამოგზავნა reset_password: პაროლის გადატვირთვა security: უსაფრთხოება set_new_password: ახალი პაროლის დაყენება - authorize_follow: - already_following: უკვე მიჰყვებით ამ ანგარიშს - error: სამწუხაროთ, დისტანციური სერვერის წაკითხვამ გამოიწვია შეცდომა - follow: გაყევი - follow_request: 'დადევნების მოთხონვა გაეგზავნა:' - following: 'წარმატება! ახლა მიჰყვებით:' - post_follow: - close: ან შეგიძლიათ დახუროთ ეს ფანჯარა. - return: მომხმარებლის პროფილის ჩვენება - web: ვებზე გადასვლა - title: გაყევი %{acct}-ს datetime: distance_in_words: about_x_hours: "%{count}სთ" @@ -267,10 +251,8 @@ ka: proceed: ანგარიშის გაუქმება success_msg: თქვენი ანგარიში წარმატებით გაუქმდა errors: - '400': The request you submitted was invalid or malformed. '403': ამ გვერდის ხილვის უფლება არ გაქვთ. '404': გვერდი რომელსაც ეძებთ არ არსებობს. - '406': This page is not available in the requested format. '410': გვერდი რომელსაც ეძებდით აღარ არსებობს. '422': content: უსაფრთხოების ვერიფიკაცია ვერ მოხერხდა. ბლოკავთ ქუქის? @@ -279,7 +261,6 @@ ka: '500': content: ბოდიში, ჩვენ მხარეს რაღაც არია. title: გვერდი არაა სწორი - '503': The page could not be served due to a temporary server failure. noscript_html: მასტოდონ ვებ-აპლიკაციის გამოყენებისთვის, გთხოვთ ჩართოთ ჯავასკრიპტი. სხვა შემთხვევაში, მასტოდონის თქვენი პატფორმისთვის სცადეთ გამოიყენოთ ერთ-ერთი მშობლიური აპლიკაცია. exports: archive_takeout: @@ -344,9 +325,6 @@ ka: expires_at: ვადა გასდის uses: მოხმარება title: მოიწვიეთ ხალხი - lists: - errors: - limit: მიაღწიეთ სიების მაქსიმალურ ოდენობას media_attachments: validations: images_and_video: ვიდეოს დართვა სტატუსზე, რომელიც უკვე მოიცავს სურათებს, ვერ მოხერხდება @@ -394,8 +372,6 @@ ka: prev: წინა preferences: other: სხვა - posting_defaults: Posting defaults - public_timelines: Public timelines remote_follow: missing_resource: საჭირო გადამისამართების ურლ თქვენი ანგარიშისთვის ვერ მოიძებნა sessions: @@ -428,7 +404,6 @@ ka: ios: აი-ოსი linux: ლინუქსი mac: მაკი - other: ამოუცნობი პლატფორმა windows: ვინდოუსი windows_mobile: ვინდოუს მობაილი windows_phone: ვინდოუს ფოუნი @@ -468,7 +443,6 @@ ka: ownership: სხვისი ტუტი ვერ აიპინება reblog: ბუსტი ვერ აიპინება show_more: მეტის ჩვენება - sign_in_to_participate: საუბარში მონაწილეობისთვის გაიარეთ ავტორიზაცია visibilities: private: მხოლოდ-მიმდევრები private_long: აჩვენე მხოლოდ მიმდევრებს @@ -477,8 +451,6 @@ ka: unlisted: ჩამოუთვლელი unlisted_long: ხედავს ყველა, მაგრამ არ ჩანს საჯარო თაიმლაინებში stream_entries: - pinned: აპინული ტუტი - reblogged: გაზრდილი sensitive_content: მგრძნობიარე კონტენტი themes: contrast: მაღალი კონტრასტი diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 7f77b2be78..eeb8f16ae4 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -95,14 +95,13 @@ kab: remove_header: Kkes tacacit resend_confirmation: already_confirmed: Amseqdac-agi yettwasentem yakan - send: Azen tikelt-nniḍen imayl n usentem - success: Imayl n usentem yettwazen mebla ugur! reset: Wennez reset_password: Beddel awal uffir resubscribe: Ales ajerred search: Nadi search_same_email_domain: Iseqdacen-nniḍen s yiwet n taɣult n yimayl search_same_ip: Imseqdacen-nniḍen s tansa IP am tinn-ik + security: Taɣellist security_measures: only_password: Awal uffir kan password_and_2fa: Awal uffir d 2FA @@ -255,6 +254,8 @@ kab: undo: Kkes seg tebdart tamellalt domain_blocks: add_new: Rni iḥder amaynut n taɣult + confirm_suspension: + cancel: Sefsex domain: Taγult export: Sifeḍ import: Kter @@ -285,6 +286,7 @@ kab: instances: back_to_all: Akk back_to_limited: Ɣur-s talast + back_to_warning: Γur-wat by_domain: Taγult content_policies: policy: Tasertit @@ -355,6 +357,7 @@ kab: category: Taggayt comment: none: Ula yiwen + confirm: Sentem mark_as_resolved: Creḍ-it yefra mark_as_unresolved: Creḍ-it ur yefra ara notes: @@ -403,13 +406,13 @@ kab: modes: none: Yiwen·t ur yzmir ad izeddi open: Zemren akk ad jerden - title: Iɣewwaṛen n uqeddac site_uploads: delete: Kkes afaylu yulin statuses: application: Asnas back_to_account: Tuγalin γer usebter n umiḍan deleted: Yettwakkes + favourites: Imenyafen language: Tutlayt media: title: Taγwalt @@ -440,10 +443,11 @@ kab: view_profile: Ssken-d amaɣnu view_status: Ssken-d tasuffiɣt applications: + logout: Ffeɣ token_regenerated: Ajuṭu n unekcum yettusirew i tikkelt-nniḍen akken iwata your_token: Ajiṭun-ik·im n unekcum auth: - change_password: Awal uffir + apply_for_account: Suter amiḍan delete_account: Kkes amiḍan description: prefix_invited_by_user: "@%{name} inced-ik·ikem ad ternuḍ ɣer uqeddac-a n Mastodon!" @@ -460,21 +464,13 @@ kab: register: Jerred registration_closed: "%{instance} ur yeqbil ara imttekkiyen imaynuten" reset_password: Wennez awal uffir + rules: + back: Tuɣalin security: Taγellist set_new_password: Egr-d awal uffir amaynut - setup: - title: Sbadu status: account_status: Addad n umiḍan use_security_key: Seqdec tasarut n teɣlist - authorize_follow: - already_following: Teṭafareḍ ya kan amiḍan-a - follow: Ḍfeṛ - following: 'Igerrez! Aqlik teṭafareḍ tura:' - post_follow: - return: Ssken-d amaɣnu n useqdac - web: Ddu γer Web - title: Ḍfeṛ %{acct} challenge: confirm: Kemmel invalid_password: Yir awal uffir @@ -503,15 +499,8 @@ kab: username_available: Isem-ik·im n useqdac ad yuɣal yella i tikkelt-nniḍen username_unavailable: Isem-ik·im n useqdac ad yeqqim ulac-it errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests '500': title: Asebter-ayi d arameγtu - '503': The page could not be served due to a temporary server failure. existing_username_validator: not_found_multiple: ur yezmir ara ad yaf %{usernames} exports: @@ -543,8 +532,6 @@ kab: back_to_filter: Tuɣalin ɣer umsizdeg batch: remove: Kkes seg umsizdeg - footer: - trending_now: Ayen mucaɛen tura generic: all: Akk changes_saved_msg: Ttwaskelsen ibelliden-ik·im akken ilaq! @@ -629,8 +616,6 @@ kab: prev: Win iɛeddan preferences: other: Wiyaḍ - posting_defaults: Posting defaults - public_timelines: Public timelines privacy_policy: title: Tasertit tabaḍnit relationships: @@ -673,7 +658,6 @@ kab: ios: iOS linux: Linux mac: macOS - other: anagraw arussin windows: Windows windows_mobile: Windows Mobile windows_phone: Tiliγri Windows Phone @@ -723,7 +707,6 @@ kab: show_more: Ssken-d ugar show_newer: Ssken-d timaynutin show_thread: Ssken-d lxiḍ - sign_in_to_participate: Qqen i waken ad tzeddiḍ deg udiwenni title: '%{name} : "%{quote}"' visibilities: direct: Usrid @@ -743,7 +726,6 @@ kab: '63113904': 2 n yiseggasen '7889238': 3 n wayyuren stream_entries: - pinned: Tijewwiqt yettwasentḍen sensitive_content: Agbur amḥulfu themes: contrast: Maṣṭudun (agnil awriran) diff --git a/config/locales/kk.yml b/config/locales/kk.yml index 4c71895880..98fe37f296 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -93,8 +93,6 @@ kk: remove_header: Мұқаба суретін өшір resend_confirmation: already_confirmed: Қолданушы құпталған - send: Құптау хатын қайтадан жібер - success: Құптау хаты сәтті жіберілді! reset: Қалпына келтіру reset_password: Құпиясөзді қалпына келтіру resubscribe: Resubscribе @@ -322,7 +320,6 @@ kk: confirmation_dialogs: Пікірталас диалогтары discovery: Пікірталас sensitive_content: Нәзік контент - toot_layout: Жазба формасы application_mailer: notification_preferences: Change e-mail prеferences settings: 'Change e-mail preferеnces: %{link}' @@ -337,14 +334,12 @@ kk: warning: Be very carеful with this data. Never share it with anyone! your_token: Your access tokеn auth: - change_password: Құпиясөз delete_account: Аккаунт өшіру delete_account_html: Аккаунтыңызды жойғыңыз келсе, мына жерді басыңыз. Сізден растау сұралатын болады. description: prefix_invited_by_user: "@%{name} сізді Желіге қосылуға шақырады!" prefix_sign_up: Желіге бүгін қосылыңыз! suffix: Аккаунтыңызбен сіз кез-келген Mastodon серверінен және желідегі басқа адамдарды оқып, пост жаза аласыз және хат алмаса аласыз! - didnt_get_confirmation: Растау хаты келмеді ме? forgot_password: Құпиясөзіңізді ұмытып қалдыңыз ба? invalid_reset_password_token: Құпиясөз қайтып алу қолжетімді емес немесе мерзімі аяқталған. Қайтадан сұратыңыз. login: Кіру @@ -357,30 +352,14 @@ kk: saml: SАML register: Тіркелу registration_closed: "%{instance} жаңа мүшелер қабылдамайды" - resend_confirmation: Растау нұсқаулықтарын жіберу reset_password: Құпиясөзді қалпына келтіру security: Қауіпсіздік set_new_password: Жаңа құпиясөз қою - setup: - email_below_hint_html: Егер төмендегі электрондық пошта мекенжайы дұрыс болмаса, оны осында өзгертіп, жаңа растау электрондық хатын ала аласыз. - email_settings_hint_html: Растау хаты %{email} адресіне жіберілді. Егер бұл электрондық пошта мекенжайы дұрыс болмаса, оны аккаунт параметрлерінде өзгертуге болады. - title: Баптау status: account_status: Аккаунт статусы confirming: Электрондық поштаны растау аяқталуын күтуде. pending: Сіздің өтінішіңіз біздің қызметкерлеріміздің қарауында. Бұл біраз уақыт алуы мүмкін. Өтінішіңіз мақұлданса, сізге электрондық пошта хабарламасы келеді. redirecting_to: Сіздің есептік жазбаңыз белсенді емес, себебі ол %{acct} жүйесіне қайта бағытталуда. - authorize_follow: - already_following: Бұл аккаунтқа жазылғансыз - error: Өкінішке орай, қашықтағы тіркелгіні іздеуде қате пайда болды - follow: Жазылу - follow_request: 'Сіз жазылуға өтініш жібердіңіз:' - following: 'Керемет! Сіз енді жазылдыңыз:' - post_follow: - close: Немесе терезені жаба салыңыз. - return: Қолданушы профилін көрсет - web: Вебте ашу - title: Жазылу %{acct} challenge: confirm: Жалғастыру hint_html: " Кеңес: біз келесі сағат ішінде сізден құпия сөзді қайта сұрамаймыз." @@ -453,8 +432,6 @@ kk: storage: Медиа жинақ featured_tags: add_new: Жаңасын қосу - errors: - limit: Хэштег лимитинен асып кеттіңіз hint_html: " Ерекшеліктері бар хэштегтер дегеніміз не? Олар жалпыға қол жетімді профильде көрсетіледі және адамдарға сіздің жалпы хабарламаларыңызды сол хэштегтердің астына қарауға мүмкіндік береді. Олар шығармашылық жұмыстарды немесе ұзақ мерзімді жобаларды бақылаудың тамаша құралы." filters: contexts: @@ -472,8 +449,6 @@ kk: title: Фильтрлер new: title: Жаңа фильтр қосу - footer: - trending_now: Бүгінгі трендтер generic: all: Барлығы changes_saved_msg: Өзгерістер сәтті сақталды! @@ -483,8 +458,6 @@ kk: validation_errors: one: Бір нәрсе дұрыс емес! Төмендегі қатені қараңыз other: Бір нәрсе дұрыс емес! Төмендегі %{count} қатені қараңыз - html_validator: - invalid_markup: 'жарамсыз HTML код: %{error}' imports: modes: merge: Біріктіру @@ -521,9 +494,6 @@ kk: expires_at: Аяқталу мерзімі uses: Қолданыс title: Адам шақыру - lists: - errors: - limit: Сіз тізімдердің максимум мөлшеріне жеттіңіз media_attachments: validations: images_and_video: Жазбаға видео қоса алмайсыз, тек сурет қосуға болады @@ -653,7 +623,6 @@ kk: ios: iОS linux: Lіnux mac: Mаc - other: белгісіз платформа windows: Windоws windows_mobile: Windows Mоbile windows_phone: Windоws Phone @@ -710,7 +679,6 @@ kk: vote: Дауыс беру show_more: Тағы әкел show_thread: Тақырыпты көрсет - sign_in_to_participate: Сұхбатқа қатысу үшін кіріңіз visibilities: private: Тек оқырмандарға private_long: Тек оқырмандарға ғана көрінеді @@ -719,8 +687,6 @@ kk: unlisted: Тізімге енбеген unlisted_long: Бәрі көре алады, бірақ ашық тізімдерге ене алмайды stream_entries: - pinned: Жабыстырылған жазба - reblogged: бөлісті sensitive_content: Нәзік мазмұн tags: does_not_match_previous_name: алдыңғы атқа сәйкес келмейді @@ -768,5 +734,4 @@ kk: seamless_external_login: Сыртқы сервис арқылы кіріпсіз, сондықтан құпиясөз және электрондық пошта параметрлері қол жетімді емес. signed_in_as: 'Былай кірдіңіз:' verification: - explanation_html: 'Өзіңіздің профиль метадеректеріңіздегі сілтемелердің иесі ретінде өзіңізді тексере аласыз. Ол үшін байланыстырылған веб-сайтта Mastodon профиліне сілтеме болуы керек. Сілтемеде rel = «me» атрибуты болуы керек. Сілтеме мәтінінің мазмұны маңызды емес. Міне мысал:' verification: Растау diff --git a/config/locales/kn.yml b/config/locales/kn.yml index 998f613ef7..d094088d88 100644 --- a/config/locales/kn.yml +++ b/config/locales/kn.yml @@ -1,10 +1 @@ ---- kn: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/ko.yml b/config/locales/ko.yml index a216953e3e..ff337cc6ca 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1,7 +1,7 @@ --- ko: about: - about_mastodon_html: 마스토돈은 오픈 소스 기반의 소셜 네트워크 서비스 입니다. 상용 플랫폼의 대체로서 분산형 구조를 채택해, 여러분의 대화가 한 회사에 독점되는 것을 방지합니다. 신뢰할 수 있는 인스턴스를 선택하세요 — 어떤 인스턴스를 고르더라도, 누구와도 대화할 수 있습니다. 누구나 자신만의 마스토돈 인스턴스를 만들 수 있으며, 아주 매끄럽게 소셜 네트워크에 참가할 수 있습니다. + about_mastodon_html: '미래의 소셜 네트워크: 광고 없음, 기업 감시 없음, 윤리적 설계, 탈중앙화! 여러분만의 데이터를 Mastodon으로 소유하세요!' contact_missing: 미설정 contact_unavailable: 없음 hosted_on: "%{domain}에서 호스팅 되는 마스토돈" @@ -37,17 +37,17 @@ ko: by_domain: 도메인 change_email: changed_msg: 이메일이 성공적으로 변경되었습니다! - current_email: 현재 이메일 주소 - label: 이메일 주소 변경 - new_email: 새 이메일 주소 - submit: 이메일 주소 변경 - title: "%{username}의 이메일 주소 변경" + current_email: 현재 이메일 + label: 이메일 바꾸기 + new_email: 새 이메일 + submit: 이메일 바꾸기 + title: "%{username}의 이메일 바꾸기" change_role: changed_msg: 역할이 성공적으로 변경되었습니다! label: 역할 변경 no_role: 역할 없음 title: "%{username}의 역할 변경" - confirm: 확정 + confirm: 신원 확인 confirmed: 확인됨 confirming: 확인 중 custom: 사용자 지정 @@ -61,7 +61,7 @@ ko: disabled: 비활성화됨 display_name: 표시되는 이름 domain: 도메인 - edit: 편집 + edit: 수정 email: 이메일 email_status: 이메일 상태 enable: 활성화 @@ -83,15 +83,16 @@ ko: title: 위치 login_status: 로그인 상태 media_attachments: 첨부된 미디어 - memorialize: 추모비로 전환 - memorialized: 추모비화 됨 - memorialized_msg: 성공적으로 %{username}를 추모비 계정으로 전환하였습니다 + memorialize: 고인의 계정으로 전환 + memorialized: 고인의 계정으로 바꿈 + memorialized_msg: 성공적으로 %{username}를 고인의 계정으로 전환하였습니다 moderation: - active: 활동 + active: 활성 all: 전체 + disabled: 비활성 pending: 대기 중 silenced: 제한됨 - suspended: 정지 중 + suspended: 정지 title: 중재 moderation_notes: 중재 참고사항 most_recent_activity: 최근 활동 @@ -121,8 +122,8 @@ ko: removed_header_msg: 성공적으로 %{username}의 헤더 이미지를 삭제하였습니다 resend_confirmation: already_confirmed: 이 사용자는 이미 확인되었습니다 - send: 확인 메일 다시 보내기 - success: 확인 이메일이 전송되었습니다! + send: 확인 링크 다시 보내기 + success: 확인 링크를 잘 보냈습니다! reset: 초기화 reset_password: 암호 초기화 resubscribe: 다시 구독 @@ -130,6 +131,7 @@ ko: search: 검색 search_same_email_domain: 같은 이메일 도메인을 가진 다른 사용자들 search_same_ip: 같은 IP의 다른 사용자들 + security: 보안 security_measures: only_password: 암호만 password_and_2fa: 암호와 2단계 인증 @@ -149,7 +151,7 @@ ko: suspension_irreversible: 이 계정의 데이터는 복구할 수 없도록 삭제되었습니다. 계정을 정지 해제함으로서 계정을 다시 사용 가능하게 할 수 있지만 이전에 삭제한 어떤 데이터도 복구되지 않습니다. suspension_reversible_hint_html: 계정이 정지되었습니다, 그리고 %{date}에 데이터가 완전히 삭제될 것입니다. 그 때까지는 어떤 안 좋은 효과 없이 계정이 복구 될 수 있습니다. 만약 지금 당장 계정의 모든 데이터를 삭제하고 싶다면, 아래에서 행할 수 있습니다. title: 계정 - unblock_email: 이메일 주소 차단 해제 + unblock_email: 이메일 차단 해제하기 unblocked_email_msg: "%{username}의 이메일 주소를 성공적으로 차단 해제했습니다" unconfirmed_email: 확인되지 않은 이메일 주소 undo_sensitized: 민감함으로 설정 취소 @@ -200,7 +202,7 @@ ko: enable_custom_emoji: 커스텀 에모지 활성화 enable_sign_in_token_auth_user: 사용자에 대한 이메일 토큰 인증 활성화 enable_user: 사용자 활성화 - memorialize_account: 추모계정으로 전환 + memorialize_account: 고인의 계정으로 전환 promote_user: 사용자 승급 reject_appeal: 이의 제기 거절 reject_user: 사용자 거부 @@ -225,11 +227,11 @@ ko: update_user_role: 역할 수정 actions: approve_appeal_html: "%{name} 님이 %{target}의 중재 결정에 대한 이의 제기를 승인했습니다" - approve_user_html: "%{name} 님이 %{target}의 가입을 승인했습니다" + approve_user_html: "%{name} 님이 %{target} 님의 가입을 승인했습니다" assigned_to_self_report_html: "%{name} 님이 신고 %{target}을 자신에게 할당했습니다" - change_email_user_html: "%{name} 님이 사용자 %{target}의 이메일 주소를 변경했습니다" + change_email_user_html: "%{name} 님이 사용자 %{target} 님의 이메일 주소를 변경했습니다" change_role_user_html: "%{name} 님이 %{target} 님의 역할을 수정했습니다" - confirm_user_html: "%{name} 님이 사용자 %{target}의 이메일 주소를 승인했습니다" + confirm_user_html: "%{name} 님이 사용자 %{target} 님의 이메일 주소를 승인했습니다" create_account_warning_html: "%{name} 님이 %{target}에게 경고를 보냈습니다" create_announcement_html: "%{name} 님이 새 공지 %{target}을 만들었습니다" create_canonical_email_block_html: "%{name} 님이 %{target} 해시를 가진 이메일을 차단했습니다" @@ -252,22 +254,22 @@ ko: destroy_status_html: "%{name} 님이 %{target} 님의 게시물을 삭제했습니다" destroy_unavailable_domain_html: "%{name} 님이 도메인 %{target}에 대한 전달을 재개" destroy_user_role_html: "%{name} 님이 %{target} 역할을 삭제했습니다" - disable_2fa_user_html: "%{name} 님이 사용자 %{target}의 2FA를 비활성화 했습니다" + disable_2fa_user_html: "%{name} 님이 사용자 %{target} 님의 2단계 인증을 비활성화 했습니다" disable_custom_emoji_html: "%{name} 님이 에모지 %{target}를 비활성화했습니다" disable_sign_in_token_auth_user_html: "%{name} 님이 %{target} 님의 이메일 토큰 인증을 비활성화했습니다" disable_user_html: "%{name} 님이 사용자 %{target}의 로그인을 비활성화했습니다" enable_custom_emoji_html: "%{name} 님이 에모지 %{target}를 활성화했습니다" enable_sign_in_token_auth_user_html: "%{name} 님이 %{target} 님의 이메일 토큰 인증을 활성화했습니다" enable_user_html: "%{name} 님이 사용자 %{target}의 로그인을 활성화했습니다" - memorialize_account_html: "%{name} 님이 %{target}의 계정을 추모비 페이지로 전환했습니다" + memorialize_account_html: "%{name} 님이 %{target}의 계정을 고인의 계정 페이지로 전환했습니다" promote_user_html: "%{name} 님이 사용자 %{target}를 승급시켰습니다" reject_appeal_html: "%{name} 님이 %{target}의 중재 결정에 대한 이의 제기를 거절했습니다" - reject_user_html: "%{name} 님이 %{target}의 가입을 거부했습니다" - remove_avatar_user_html: "%{name} 님이 %{target}의 아바타를 지웠습니다" + reject_user_html: "%{name} 님이 %{target} 님의 가입을 거부했습니다" + remove_avatar_user_html: "%{name} 님이 %{target} 님의 아바타를 지웠습니다" reopen_report_html: "%{name} 님이 신고 %{target}을 다시 열었습니다" resend_user_html: "%{name} 님이 %{target} 님에 대한 확인 메일을 다시 보냈습니다" reset_password_user_html: "%{name} 님이 사용자 %{target}의 암호를 초기화했습니다" - resolve_report_html: "%{name} 님이 신고 %{target}를 처리됨으로 변경하였습니다" + resolve_report_html: "%{name} 님이 %{target}번 신고를 해결로 변경하였습니다" sensitive_account_html: "%{name} 님이 %{target}의 미디어를 민감함으로 표시했습니다" silence_account_html: "%{name} 님이 %{target}의 계정을 제한시켰습니다" suspend_account_html: "%{name} 님이 %{target}의 계정을 정지시켰습니다" @@ -286,7 +288,7 @@ ko: empty: 로그를 찾을 수 없습니다 filter_by_action: 행동으로 거르기 filter_by_user: 사용자로 거르기 - title: 감사 기록 + title: 감사 로그 announcements: destroyed_msg: 공지가 성공적으로 삭제되었습니다! edit: @@ -304,6 +306,7 @@ ko: unpublish: 게시 취소 unpublished_msg: 공지가 성공적으로 발행 취소되었습니다! updated_msg: 공지가 성공적으로 업데이트되었습니다! + critical_update_pending: 긴급 업데이트 보류 중 custom_emojis: assign_category: 분류 지정 by_domain: 도메인 @@ -342,7 +345,7 @@ ko: active_users: 활성 사용자 interactions: 상호 작용 media_storage: 미디어 저장소 - new_users: 새로운 사용자 + new_users: 새 사용자 opened_reports: 신고 열림 pending_appeals_html: other: "%{count}개의 대기 중인 이의 제기" @@ -352,7 +355,7 @@ ko: other: "%{count}개의 대기 중인 해시태그" pending_users_html: other: "%{count}명의 대기 중인 사용자" - resolved_reports: 신고 해결됨 + resolved_reports: 해결된 신고 software: 소프트웨어 sources: 가입 출처 space: 디스크 사용량 @@ -373,6 +376,15 @@ ko: undo: 허용 목록에서 제외 domain_blocks: add_new: 도메인 차단 추가하기 + confirm_suspension: + cancel: 취소 + confirm: 정지 + permanent_action: 정지를 취소한다고 해서 데이터나 관계가 돌아오진 않습니다. + preamble_html: "%{domain}과 서브도메인들을 차단하려고 합니다." + remove_all_data: 이 동작은 이 도메인의 모든 콘텐츠, 미디어, 프로필 데이터를 서버에서 지울 것입니다. + stop_communication: 이 서버들과의 교신이 중지될 것입니다. + title: "%{domain} 도메인 차단 확인" + undo_relationships: 이 동작은 이 서버 계정들과 저 서버 계정들 사이의 팔로우 관계들을 취소할 것입니다. created_msg: 도메인 차단 처리를 완료했습니다 destroyed_msg: 도메인 차단이 해제되었습니다 domain: 도메인 @@ -407,20 +419,21 @@ ko: undo: 도메인 차단 취소 view: 도메인 차단 보기 email_domain_blocks: - add_new: 새로 추가 + add_new: 새로 추가하기 attempts_over_week: other: 지난 주 동안 %{count}건의 가입 시도가 있었습니다 created_msg: 이메일 도메인 차단 규칙을 생성했습니다 - delete: 삭제 + delete: 삭제하기 dns: types: mx: MX 레코드 domain: 도메인 new: - create: 차단 규칙 생성 + create: 도메인 추가하기 resolve: 도메인 검사 title: 새 이메일 도메인 차단 no_email_domain_block_selected: 아무 것도 선택 되지 않아 어떤 이메일 도메인 차단도 변경되지 않았습니다 + not_permitted: 허용하지 않음 resolved_dns_records_hint_html: 도메인 네임은 다음의 MX 도메인으로 연결되어 있으며, 이메일을 받는데 필수적입니다. MX 도메인을 차단하면 같은 MX 도메인을 사용하는 어떤 이메일이라도 가입할 수 없게 되며, 보여지는 도메인이 다르더라도 적용됩니다. 주요 이메일 제공자를 차단하지 않도록 조심하세요. resolved_through_html: "%{domain}을 통해 리졸빙됨" title: Email 도메인 차단 @@ -465,6 +478,7 @@ ko: content_policies: comment: 내부 참고사항 description_html: 이 도메인과 하위 도메인의 모든 계정에 적용될 콘텐츠 정책을 정의할 수 있습니다. + limited_federation_mode_description_html: 이 도메인의 연합을 허용할지 선택할 수 있습니다. policies: reject_media: 미디어 거부 reject_reports: 신고 거부 @@ -498,7 +512,7 @@ ko: other: "%{count} 개의 알려진 계정" moderation: all: 모두 - limited: 제한됨 + limited: 제한 title: 중재 private_comment: 비공개 주석 public_comment: 공개 주석 @@ -559,7 +573,7 @@ ko: account: notes: other: "%{count} 개의 참고사항" - action_log: 감사 기록 + action_log: 감사 로그 action_taken_by: 신고 처리자 actions: delete_description_html: 신고된 게시물은 삭제될 것이며 이 처벌기록은 같은 계정의 향후 규정 위반에 대해 참고사항으로 쓰일 수 있도록 저장됩니다. @@ -575,17 +589,19 @@ ko: assign_to_self: 나에게 할당하기 assigned: 할당된 중재자 by_target_domain: 신고된 계정의 도메인 + cancel: 취소 category: 카테고리 category_description_html: 이 계정 또는 게시물이 신고된 이유는 신고된 계정과의 의사소통 과정에 인용됩니다 comment: none: 없음 comment_description_html: '더 많은 정보를 위해, %{name} 님이 작성했습니다:' + confirm: 확정 confirm_action: "@%{acct}에 취할 중재 결정에 대한 확인" created_at: 신고 시각 delete_and_resolve: 게시물 삭제 forwarded: 전달됨 forwarded_to: "%{domain}에게 전달됨" - mark_as_resolved: 해결 완료 처리 + mark_as_resolved: 해결로 표시 mark_as_sensitive: 민감함으로 설정 mark_as_unresolved: 미해결로 표시 no_one_assigned: 아무도 없음 @@ -604,7 +620,7 @@ ko: report: '신고 #%{id}' reported_account: 신고 대상 계정 reported_by: 신고자 - resolved: 해결됨 + resolved: 해결 resolved_msg: 신고를 잘 해결했습니다! skip_to_actions: 작업으로 건너뛰기 status: 상태 @@ -697,7 +713,7 @@ ko: rules: add_new: 규칙 추가 delete: 삭제 - description_html: 대부분의 경우 사람들이 이용약관을 반드시 읽고 동의하도록 하지만, 보통의 사람들은 문제가 일어나기 전까지는 읽지 않습니다. 여러분의 서버 규칙을 목록으로 정리해서 한 번에 읽기 쉽게 만드세요. 규칙 각각을 짧고 단순하게 만들고, 하나를 여러 개로 쪼개지도 마세요. + description_html: 대부분의 사람들은 서비스 약관을 읽고 동의한다고 밝힙니다만, 대개 문제가 발생하기 전까지는 약관을 자세히 읽어보지 않습니다. 서버의 운영원칙을 단일한 글머리 기호 목록으로 제공하여 한 눈에 쉽게 확인할 수 있도록 하세요. 각 규칙을 짧고 간결하게 유지하되, 많은 항목으로 나누지 않도록 하세요. edit: 규칙 수정 empty: 아직 정의된 서버 규칙이 없습니다. title: 서버 규칙 @@ -713,6 +729,9 @@ ko: branding: preamble: 이 서버의 브랜딩은 네트워크의 다른 서버와 차별점을 부여합니다. 이 정보는 여러 환경에서 보여질 수 있는데, 예를 들면 마스토돈 인터페이스, 네이티브 앱, 다른 웹사이트나 메시지 앱에서 보이는 링크 미리보기, 기타 등등이 있습니다. 이러한 이유로 인해, 이 정보를 명확하고 짧고 간결하게 유지하는 것이 가장 좋습니다. title: 브랜딩 + captcha_enabled: + desc_html: 이것은 hCaptcha의 외부 스크립트에 의존합니다, 이것은 개인정보 보호에 위협을 가할 수도 있습니다. 추가적으로, 이것은 몇몇 사람들(특히나 장애인들)에게 가입 절차의 접근성을 심각하게 떨어트릴 수 있습니다. 이러한 이유로, 대체제로 승인 전용이나 초대제를 통한 가입을 고려해보세요. + title: 새로운 사용자가 계정 확인을 위해서는 CAPTCHA를 풀어야 하도록 합니다 content_retention: preamble: 마스토돈에 저장된 사용자 콘텐츠를 어떻게 다룰지 제어합니다. title: 콘텐츠 보존기한 @@ -733,17 +752,34 @@ ko: disabled: 아무에게도 안 함 users: 로그인 한 사용자에게 registrations: - preamble: 누가 이 서버에 계정을 만들 수 있는 지 제어합니다. + preamble: 누가 이 서버에 계정을 만들 수 있는지 제어합니다. title: 가입 registrations_mode: modes: approved: 가입하려면 승인이 필요함 none: 아무도 가입 할 수 없음 open: 누구나 가입 할 수 있음 + security: + authorized_fetch: 연합된 서버들에게서 인증 필수 + authorized_fetch_hint: 연합된 서버들에게서 인증을 요구하는 것은 사용자 레벨과 서버 레벨의 차단은 좀 더 확실하게 해줍니다. 한편으로는 성능적인 페널티, 답글의 전달 범위 감소, 몇몇 연합된 서비스들과의 호환성 문제가 있을 가능성이 있습니다. 추가적으로 이 기능은 전용 액터가 공개돤 게시물이나 계정을 페치하는 것은 막지 않습니다. + authorized_fetch_overridden_hint: 현재 이 값은 환경변수에 의해 설정되어 있기에 설정을 변경할 수 없습니다. + federation_authentication: 연합 인증 필수 title: 서버 설정 site_uploads: delete: 업로드한 파일 삭제 destroyed_msg: 사이트 업로드를 성공적으로 삭제했습니다! + software_updates: + critical_update: 긴급 — 빠른 업데이트 요망 + description: 최신 수정 사항과 기능을 활용하기 위해 Mastodon 설치를 최신 상태로 유지하기를 권장합니다. 더욱이, 때로는 보안 문제를 피하기 위해 Mastodon을 적절한 시점에 긴급 업데이트해야 하는 경우도 있습니다. 따라서 Mastodon은 30분마다 업데이트를 확인하며, 이메일 알림 환경설정에 따라 사용자에게 알려드립니다. + documentation_link: 더 알아보기 + release_notes: 릴리스 노트 + title: 사용 가능한 업데이트 + type: 유형 + types: + major: 메이저 릴리스 + minor: 마이너 릴리스 + patch: 패치 릴리스 — 버그픽스 그리고 변경점의 빠른 적용 + version: 버전 statuses: account: 작성자 application: 애플리케이션 @@ -780,9 +816,24 @@ ko: suspend: "%{name} 님이 %{target}의 계정을 정지시켰습니다" appeal_approved: 이의제기됨 appeal_pending: 이의제기 대기중 + appeal_rejected: 이의 제기 거절됨 system_checks: database_schema_check: message_html: 대기 중인 데이터베이스 마이그레이션이 있습니다. 애플리케이션이 예상대로 동작할 수 있도록 마이그레이션을 실행해 주세요 + elasticsearch_health_red: + message_html: Elasticsearch 클러스터가 비정상(red)상태입니다. 검색 기능이 동작하지 않습니다 + elasticsearch_health_yellow: + message_html: Elasticsearch 클러스터가 비정상(yellow)상태입니다. 이유를 조사할 필요가 있습니다 + elasticsearch_index_mismatch: + message_html: Elasticsearch 인덱스 매핑이 업데이트되지 않았습니다. tootctl search deploy --only=%{value} 명령을 실행해주세요 + elasticsearch_preset: + action: 문서 참조 + message_html: Elasticsearch 클러스터가 여러 대의 노드를 사용하지만 마스토돈이 그것을 사용하도록 설정되지 않았습니다. + elasticsearch_preset_single_node: + action: 문서 참조 + message_html: Elasticsearch 클러스터가 한 대의 노드만 사용하고 있습니다. ES_PRESETsingle_node_cluster로 설정되어야 합니다. + elasticsearch_reset_chewy: + message_html: 설정 변경으로 인해 Elasticsearch 시스템 인덱스가 최신상태가 아닙니다. tootctl search deploy --reset-chewy 명령으로 업데이트 하세요. elasticsearch_running_check: message_html: Elasticsearch에 연결할 수 없습니다. 실행중인지 확인하거나, 전문검색을 비활성화하세요 elasticsearch_version_check: @@ -790,9 +841,21 @@ ko: version_comparison: Elasticsearch %{required_version}버전이 필요하지만 %{running_version}버전이 실행 중입니다. rules_check: action: 서버 규칙 관리 - message_html: 아직 서버규칙을 정하지 않았습니다. + message_html: 아직 서버 규칙을 정하지 않았습니다. sidekiq_process_check: message_html: "%{value} 큐에 대한 사이드킥 프로세스가 발견되지 않았습니다. 사이드킥 설정을 검토해주세요" + software_version_critical_check: + action: 사용 가능한 업데이트 보기 + message_html: 긴급 마스토돈 업데이트가 있으니, 가능한 서둘러 업데이트 해주세요. + software_version_patch_check: + action: 사용 가능한 업데이트 보기 + message_html: 마스토돈 버그픽스 업데이트가 있습니다. + upload_check_privacy_error: + action: 더 많은 정보를 보려면 여기를 확인하세요. + message_html: "웹서버가 잘못 설정되어있습니다. 사용자의 개인정보가 위험한 상태입니다." + upload_check_privacy_error_object_storage: + action: 더 많은 정보를 보려면 여기를 확인하세요 + message_html: "오브젝트 스토리지가 잘못 설정되어 있습니다. 사용자의 개인정보가 위험한 상태입니다." tags: review: 심사 상태 updated_msg: 해시태그 설정이 성공적으로 갱신되었습니다 @@ -802,11 +865,11 @@ ko: approved: 승인됨 disallow: 거부 links: - allow: 링크 허용하기 - allow_provider: 출처 허용하기 + allow: 링크 허용 + allow_provider: 발행처 허용 description_html: 현재 서버에서 게시물을 볼 수 있는 계정에서 많이 공유되고 있는 링크들입니다. 사용자가 세상 돌아가는 상황을 파악하는 데 도움이 됩니다. 출처를 승인할 때까지 링크는 공개적으로 게시되지 않습니다. 각각의 링크를 개별적으로 허용하거나 거부할 수도 있습니다. - disallow: 링크 거부하기 - disallow_provider: 출처 거부하기 + disallow: 링크 거부 + disallow_provider: 발행처 비허용 no_link_selected: 아무 것도 선택 되지 않아 어떤 링크도 바뀌지 않았습니다 publishers: no_publisher_selected: 아무 것도 선택 되지 않아 어떤 게시자도 바뀌지 않았습니다 @@ -814,20 +877,21 @@ ko: other: 지난 주 동안 %{count} 명의 사람들이 공유했습니다 title: 유행하는 링크 usage_comparison: 오늘은 %{today}회 공유되었고, 어제는 %{yesterday}회 공유되었습니다 + not_allowed_to_trend: 트렌드에 오를 수 없음 only_allowed: 허용된 것만 pending_review: 심사 대기 preview_card_providers: - allowed: 이 출처의 링크는 유행 목록에 실릴 수 있습니다 + allowed: 이 발행처의 링크는 유행록에 실릴 수 있음 description_html: 당신의 서버에서 많은 링크가 공유되고 있는 도메인들입니다. 링크의 도메인이 승인되기 전까지는 링크들은 공개적으로 트렌드에 게시되지 않습니다. 당신의 승인(또는 거절)은 서브도메인까지 확장됩니다. - rejected: 이 출처의 링크는 유행 목록에 실릴 수 없습니다 - title: 출처 + rejected: 이 발행처의 링크는 유행록에 실리지 않음 + title: 발행처 rejected: 거부됨 statuses: allow: 게시물 허용 allow_account: 작성자 허용 - description_html: 당신의 서버가 알기로 현재 많은 수의 공유와 좋아요가 되고 있는 게시물들입니다. 새로운 사용자나 돌아오는 사용자들이 팔로우 할 사람들을 찾는 데 도움이 될 수 있습니다. 작성자를 승인하고, 작성자가 그들의 계정이 다른 계정에게 탐색되도록 설정하지 않는 한 게시물들은 공개적으로 표시되지 않습니다. 또한 각각의 게시물을 별개로 거절할 수도 있습니다. + description_html: 여러분의 서버가 알기로 현재 많은 수의 공유와 좋아요가 되고 있는 게시물들입니다. 새로운 사용자나 돌아오는 사용자들이 팔로우 할 사람들을 찾는 데 도움이 될 수 있습니다. 작성자를 승인하고, 작성자가 그들의 계정이 다른 계정에게 탐색되도록 설정하지 않는 한 게시물들은 공개적으로 표시되지 않습니다. 또한 각각의 게시물을 별개로 거절할 수도 있습니다. disallow: 게시물 비허용 - disallow_account: 작성자 불허 + disallow_account: 작성자 비허용 no_status_selected: 아무 것도 선택 되지 않아 어떤 유행중인 게시물도 바뀌지 않았습니다 not_discoverable: 작성자가 발견되기를 원치 않습니다 shared_by: @@ -895,6 +959,9 @@ ko: body: "%{target} 님이 %{action_taken_by} 님에 의해 %{date}에 결정된 중재 결정에 대한 이의를 제기했습니다, 결정된 사항은 %{type}이었습니다. 작성내용은 다음과 같습니다:" next_steps: 중재 결정사항을 되돌리기 위해서 상소를 승인하거나, 무시할 수 있습니다. subject: "%{username} 님이 %{instance}에서 발생한 중재 결정에 대해 소명을 제출했습니다" + new_critical_software_updates: + body: 마스토돈의 긴급 업데이트가 릴리스 되었으니, 가능한 서둘러 업데이트를 바랍니다! + subject: "%{instance}에 대해 긴급 업데이트가 있습니다!" new_pending_account: body: 아래에 새 계정에 대한 상세정보가 있습니다. 이 가입을 승인하거나 거부할 수 있습니다. subject: "%{instance}의 새 계정(%{username})에 대한 심사가 대기중입니다" @@ -902,6 +969,9 @@ ko: body: "%{reporter} 님이 %{target}를 신고했습니다" body_remote: "%{domain}의 누군가가 %{target}을 신고했습니다" subject: "%{instance} 에 새 신고 등록됨 (#%{id})" + new_software_updates: + body: 새 마스토돈 버전이 릴리스되었습니다. 업데이트 할 수 있습니다! + subject: "%{instance}에 대해 새 마스토돈 버전이 사용 가능합니다!" new_trends: body: '아래에 있는 항목들은 공개적으로 보여지기 전에 검토를 거쳐야 합니다:' new_trending_links: @@ -931,24 +1001,28 @@ ko: guide_link: https://crowdin.com/project/mastodon guide_link_text: 누구나 기여할 수 있습니다. sensitive_content: 민감한 내용 - toot_layout: 게시물 레이아웃 application_mailer: notification_preferences: 메일 설정 변경 salutation: "%{name} 님," settings: '메일 설정을 변경: %{link}' + unsubscribe: 구독 해제 view: '보기:' view_profile: 프로필 보기 view_status: 게시물 보기 applications: created: 애플리케이션이 성공적으로 생성되었습니다 destroyed: 애플리케이션이 성공적으로 삭제되었습니다 + logout: 로그아웃 regenerate_token: 토큰 재생성 token_regenerated: 액세스 토큰이 성공적으로 재생성되었습니다 warning: 이 데이터를 조심히 다뤄 주세요. 다른 사람들과 절대로 공유하지 마세요! your_token: 액세스 토큰 auth: apply_for_account: 가입 요청하기 - change_password: 암호 + captcha_confirmation: + help_html: 만약 CAPTCHA를 푸는데 문제가 생겼다면 %{email}을 통해 연락을 주시면 도와드릴 수 있습니다. + hint_html: 하나만 더! 당신이 사람인지 확인이 필요합니다 (스팸 계정을 거르기 위해서 필요한 과정입니다). 아래에 있는 CAPTCHA를 풀고 "계속"을 누르세요 + title: 보안 체크 confirmations: wrong_email_hint: 만약 이메일 주소가 올바르지 않다면, 계정 설정에서 수정할 수 있습니다. delete_account: 계정 삭제 @@ -957,7 +1031,7 @@ ko: prefix_invited_by_user: "@%{name}님이 마스토돈 서버에 초대했습니다!" prefix_sign_up: 마스토돈에 가입하세요! suffix: 계정 하나로 사람들을 팔로우 하고, 게시물을 작성하며 마스토돈을 포함한 다른 어떤 서버의 사용자와도 메시지를 주고 받을 수 있습니다! - didnt_get_confirmation: 확인 메일을 받지 못하셨습니까? + didnt_get_confirmation: 확인 링크를 못 받았나요? dont_have_your_security_key: 보안 키가 없습니까? forgot_password: 암호를 잊었나요? invalid_reset_password_token: 암호 리셋 토큰이 올바르지 못하거나 기간이 만료되었습니다. 다시 요청해주세요. @@ -969,27 +1043,40 @@ ko: migrate_account: 계정 옮기기 migrate_account_html: 이 계정을 다른 계정으로 리디렉션 하길 원하는 경우 여기에서 설정할 수 있습니다. or_log_in_with: 다른 방법으로 로그인 하려면 - privacy_policy_agreement_html: 개인정보 보호정책을 읽었고 동의합니다 + privacy_policy_agreement_html: 개인정보처리방침을 읽고 동의합니다 + progress: + confirm: 이메일 확인하기 + details: 세부사항 + review: 심사 결과 + rules: 규정을 수락합니다. providers: cas: CAS saml: SAML register: 등록하기 registration_closed: "%{instance}는 새로운 가입을 받지 않고 있습니다" - resend_confirmation: 확인 메일을 다시 보내기 + resend_confirmation: 확인 링크 다시 보내기 reset_password: 암호 재설정 rules: + accept: 수락 + back: 뒤로가기 + invited_by: '당신이 받은 초대장 덕분에 %{domain}에 가입할 수 있습니다:' preamble: 다음은 %{domain}의 중재자들에 의해 설정되고 적용되는 규칙들입니다. + preamble_invited: 계속하기 전에, %{domain}의 중재자들이 정해놓은 규칙들을 검토해주세요. title: 몇 개의 규칙이 있습니다. + title_invited: 초대를 받았습니다. security: 보안 - set_new_password: 새 암호 + set_new_password: 새 암호 설정 setup: - email_below_hint_html: 아래의 이메일 계정이 올바르지 않을 경우, 여기서 변경하고 새 확인 메일을 받을 수 있습니다. - email_settings_hint_html: 확인 메일이 %{email}로 보내졌습니다. 이메일 주소가 올바르지 않은 경우, 계정 설정에서 변경하세요. - title: 설정 + email_below_hint_html: 스팸 폴더를 체크해보거나, 이메일 주소를 틀렸을 수 있으니 새 확인 링크를 요청해보세요. + email_settings_hint_html: "%{email}을 인증하기 위해 우리가 보낸 링크를 누르세요. 여기서 기다리겠습니다." + link_not_received: 링크를 못 받으셨나요? + new_confirmation_instructions_sent: 확인 링크가 담긴 이메일이 몇 분 안에 도착할것입니다! + title: 수신함 확인하기 sign_in: preamble_html: "%{domain}의 계정 정보를 이용해 로그인 하세요. 만약 내 계정이 다른 서버에 존재한다면, 여기서는 로그인 할 수 없습니다." title: "%{domain}에 로그인" sign_up: + manual_review: "%{domain} 가입은 중재자들의 심사를 거쳐 진행됩니다. 가입 절차를 원활하게 하기 위해, 간단한 자기소개와 왜 %{domain}에 계정을 만들려고 하는지 적어주세요." preamble: 이 마스토돈 서버의 계정을 통해, 네트워크에 속한 다른 사람들을, 그들이 어떤 서버에 있든 팔로우 할 수 있습니다. title: "%{domain}에 가입하기 위한 정보들을 입력하세요." status: @@ -1001,23 +1088,11 @@ ko: view_strikes: 내 계정에 대한 과거 중재 기록 보기 too_fast: 너무 빠르게 양식이 제출되었습니다, 다시 시도하세요. use_security_key: 보안 키 사용 - authorize_follow: - already_following: 이미 이 계정을 팔로우 하고 있습니다 - already_requested: 이미 이 계정에게 팔로우 요청을 보냈습니다 - error: 리모트 계정을 확인하는 도중 오류가 발생했습니다 - follow: 팔로우 - follow_request: '당신은 다음 계정에 팔로우 신청을 했습니다:' - following: '성공! 당신은 다음 계정을 팔로우 하고 있습니다:' - post_follow: - close: 혹은, 그저 이 창을 닫을 수도 있습니다. - return: 사용자 프로필 보기 - web: 웹으로 가기 - title: "%{acct} 를 팔로우" challenge: confirm: 계속 hint_html: "팁: 한 시간 동안 다시 암호를 묻지 않을 것입니다." invalid_password: 잘못된 암호 - prompt: 계속하려면 암호 확인 + prompt: 계속하려면 암호를 확인하세요 crypto: errors: invalid_key: 유효하지 않은 Ed25519 또는 Curve25519 키 @@ -1025,11 +1100,11 @@ ko: date: formats: default: "%Y-%m-%d" - with_month_name: "%Y년 %B %d일" + with_month_name: "%Y년 %f월 %e일" datetime: distance_in_words: about_x_hours: "%{count}시간" - about_x_months: "%{count}월" + about_x_months: "%{count} 개월" about_x_years: "%{count}년" almost_x_years: "%{count}년" half_a_minute: 지금 @@ -1038,7 +1113,7 @@ ko: over_x_years: "%{count}년" x_days: "%{count}일" x_minutes: "%{count}분" - x_months: "%{count}월" + x_months: "%{count} 개월" x_seconds: "%{count}초" deletes: challenge_not_passed: 입력한 정보가 올바르지 않습니다 @@ -1054,7 +1129,7 @@ ko: email_contact_html: 아직 도착하지 않았다면, %{email}에 메일을 보내 도움을 요청할 수 있습니다 email_reconfirmation_html: 아직 확인 메일이 도착하지 않은 경우, 다시 요청할 수 있습니다 irreversible: 계정을 복구하거나 다시 사용할 수 없게 됩니다 - more_details_html: 더 자세한 정보는, 개인정보 정책을 참고하세요. + more_details_html: 더 자세한 정보는, 개인정보처리방침을 참고하세요. username_available: 당신의 계정명은 다시 사용할 수 있게 됩니다 username_unavailable: 당신의 계정명은 앞으로 사용할 수 없습니다 disputes: @@ -1063,7 +1138,7 @@ ko: appeal: 이의제기 appeal_approved: 이 중재기록은 소명이 받아들여졌으며 더이상 유효하지 않습니다 appeal_rejected: 소명이 기각되었습니다 - appeal_submitted_at: 이의제기 접수됨 + appeal_submitted_at: 이의제기 제출일 appealed_msg: 당신의 이의제기가 접수되었습니다. 만약 승인된다면, 알림을 받게 될 것입니다. appeals: submit: 이의 제출 @@ -1075,7 +1150,7 @@ ko: reject_appeal: 이의 제기 거절 status: '게시물 #%{id}' status_removed: 게시물이 이미 시스템에서 지워졌습니다 - title: "%{action} (%{date}에)" + title: "%{action}: %{date}" title_actions: delete_statuses: 게시물 삭제 disable: 계정 동결 @@ -1084,20 +1159,24 @@ ko: sensitive: 계정을 민감함으로 표시 silence: 계정의 제한 suspend: 계정 정지 - your_appeal_approved: 당신의 소명이 받아들여졌습니다 + your_appeal_approved: 소명이 받아들여졌습니다 your_appeal_pending: 소명을 제출했습니다 - your_appeal_rejected: 당신의 소명이 기각되었습니다 + your_appeal_rejected: 소명이 기각되었습니다 domain_validator: invalid_domain: 올바른 도메인 네임이 아닙니다 + edit_profile: + basic_information: 기본 정보 + hint_html: "내 공개 프로필과 게시물 옆에 보이는 부분을 꾸미세요. 다른 사람들은 프로필 내용과 사진이 채워진 계정과 더 상호작용하고 팔로우를 하고 싶어합니다." + other: 기타 errors: '400': 제출한 요청이 올바르지 않습니다. '403': 이 페이지를 표시할 권한이 없습니다. '404': 찾으려는 페이지가 존재하지 않습니다. '406': 이 페이지는 요청한 자료형으로 제공되지 않습니다. - '410': 당신이 보려는 페이지는 더이상 여기에 존재하지 않습니다. + '410': 찾는 페이지가 더 이상 존재하지 않습니다. '422': - content: 보안 인증에 실패했습니다. 쿠키를 차단하고 있진 않습니까? - title: 보안 인증 실패 + content: 보안 검증에 실패했습니다. 쿠키를 차단했나요? + title: 보안 검증 실패 '429': 요청 횟수 제한에 도달했습니다 '500': content: 죄송합니다, 뭔가 잘못 되었습니다. @@ -1112,7 +1191,7 @@ ko: date: 날짜 download: 아카이브 다운로드 hint_html: 당신의 게시물과 업로드 된 미디어의 아카이브를 요청할 수 있습니다. 내보내지는 데이터는 ActivityPub 포맷입니다. 호환 되는 모든 소프트웨어에서 읽을 수 있습니다. 7일마다 새로운 아카이브를 요청할 수 있습니다. - in_progress: 당신의 아카이브를 컴파일 중입니다… + in_progress: 아카이브를 컴파일 중... request: 아카이브 요청하기 size: 크기 blocks: 차단 @@ -1125,12 +1204,12 @@ ko: featured_tags: add_new: 추가 errors: - limit: 이미 추천 해시태그의 개수가 최대입니다 - hint_html: "추천 해시태그가 무엇이죠? 당신의 공개 프로필 페이지에 눈에 띄게 표현 되며 사람들이 그 해시태그를 포함한 당신의 글을 찾아 볼 수 있도록 합니다. 창작활동이나 긴 기간을 가지는 프로젝트를 쭉 따라가기에 좋은 도구입니다." + limit: 추천 해시태그 최대 개수를 초과합니다 + hint_html: "내 가장 중요한 해시태그들을 프로필에서 추천하세요. 내 창작물이나 오래 걸리는 프로젝트를 따라가기 위한 도구이며 추천 해시태그는 내 프로필에 잘 보이게 표시되고 내 게시물에 대한 빠른 접근을 가능하게 합니다." filters: contexts: account: 프로필 - home: 홈 타임라인 + home: 홈 & 리스트 notifications: 알림 public: 퍼블릭 타임라인 thread: 대화 @@ -1139,7 +1218,7 @@ ko: keywords: 키워드 statuses: 개별 게시물 statuses_hint_html: 이 필터는 아래의 키워드에 매칭되는지 여부와 관계 없이 몇몇개의 게시물들에 별개로 적용되었습니다. 검토하거나 필터에서 삭제하세요 - title: 필터 편집 + title: 필터 수정 errors: deprecated_api_multiple_keywords: 이 파라미터들은 하나를 초과하는 필터 키워드에 적용되기 때문에 이 응용프로그램에서 수정될 수 없습니다. 더 최신의 응용프로그램이나 웹 인터페이스를 사용하세요. invalid_context: 컨텍스트가 없거나 올바르지 않습니다 @@ -1166,45 +1245,83 @@ ko: index: hint: 이 필터는 다른 기준에 관계 없이 선택된 개별적인 게시물들에 적용됩니다. 웹 인터페이스에서 더 많은 게시물들을 이 필터에 추가할 수 있습니다. title: 필터링된 게시물 - footer: - trending_now: 지금 유행 중 generic: all: 모두 all_items_on_page_selected_html: other: 현재 페이지에서 %{count}개의 항목이 선택되었습니다 all_matching_items_selected_html: other: 검색에 잡힌 %{count}개의 항목이 모두 선택되었습니다 + cancel: 취소 changes_saved_msg: 정상적으로 변경되었습니다! + confirm: 확인 copy: 복사 delete: 삭제 deselect: 전체 선택 해제 none: 없음 - order_by: 순서 + order_by: 정렬 save_changes: 변경 사항을 저장 select_all_matching_items: other: 검색에 잡힌 %{count}개의 항목을 모두 선택하기 today: 오늘 validation_errors: other: 오류가 발생했습니다. 아래 %{count}개 오류를 확인해 주십시오 - html_validator: - invalid_markup: '올바르지 않은 HTML 마크업을 포함하고 있습니다: %{error}' imports: errors: + empty: 빈 CSV 파일 + incompatible_type: 호환되지 않는 가져오기 유형을 선택함 invalid_csv_file: '올바르지 않은 CSV 파일입니다. 오류: %{error}' over_rows_processing_limit: "%{count}개 이상의 열을 포함합니다" + too_large: 파일이 너무 큼 + failures: 실패 + imported: 가져옴 + mismatched_types_warning: 가져오기할 때 잘못된 유형을 선택했을 수 있으니, 꼭 두 번 체크해주세요. modes: merge: 병합 merge_long: 기존 것을 그대로 둔 채 새로 추가 overwrite: 덮어쓰기 overwrite_long: 기존 것을 모두 지우고 새로 추가 + overwrite_preambles: + blocking_html: 나의 차단 목록%{filename}에서 가져온 %{total_items} 개의 계정으로 덮어 씌우려고 합니다. + bookmarks_html: 나의 북마크%{filename}에서 가져온 %{total_items} 개의 게시물로 덮어 씌우려고 합니다. + domain_blocking_html: 나의 도메인 차단 목록%{filename}에서 가져온 %{total_items} 개의 도메인으로 덮어 씌우려고 합니다. + following_html: "%{filename}에서 가져온 %{total_items} 개의 계정팔로우하고 나머지 계정을 팔로우 해제하려고 합니다." + lists_html: 나의 리스트%{filename}에서 가져온 %{total_items} 개의 계정으로 덮어 씌우려고 합니다. + muting_html: 나의 뮤트한 계정 목록%{filename}에서 가져온 %{total_items} 개의 계정으로 덮어 씌우려고 합니다. + preambles: + blocking_html: "%{filename}에서 가져온 %{total_items}개의 계정을 차단하려고 합니다." + bookmarks_html: "%{filename}에서 가져온 %{total_items}개의 게시물을 북마크에 추가하려고 합니다." + domain_blocking_html: "%{filename}에서 가져온 %{total_items}개의 도메인을 차단하려고 합니다." + following_html: "%{filename}에서 가져온 %{total_items}개의 계정을 팔로우하려고 합니다." + lists_html: "%{filename}에서 가져온 %{total_items}개의 계정을 내 리스트에 추가하려고 합니다. 추가할 리스트가 존재하지 않으면 새로 생성될 것입니다." + muting_html: "%{filename}에서 가져온 %{total_items}개의 계정을 뮤트하려고 합니다." preface: 다른 서버에서 내보내기 한 파일에서 팔로우 / 차단 정보를 이 계정으로 불러올 수 있습니다. + recent_imports: 최근의 가져오기 + states: + finished: 끝냄 + in_progress: 진행 중 + scheduled: 예약됨 + unconfirmed: 미확인 + status: 상태 success: 파일이 정상적으로 업로드되었으며, 현재 처리 중입니다 + time_started: 시작 시각 + titles: + blocking: 차단한 계정 가져오는 중 + bookmarks: 북마크 가져오는 중 + domain_blocking: 차단한 도메인 가져오는 중 + following: 팔로우한 계정 가져오는 중 + lists: 리스트 가져오기 + muting: 뮤트한 계정 가져오는 중 + type: 가져오기 유형 + type_groups: + constructive: 팔로우 & 북마크 + destructive: 차단 & 뮤트 types: blocking: 차단한 계정 목록 bookmarks: 북마크 domain_blocking: 도메인 차단 목록 - following: 팔로우 중인 계정 목록 - muting: 뮤트 중인 계정 목록 + following: 팔로잉 목록 + lists: 리스트 + muting: 뮤트한 계정 목록 upload: 업로드 invites: delete: 비활성화 @@ -1214,10 +1331,10 @@ ko: '21600': 6 시간 '3600': 1 시간 '43200': 12 시간 - '604800': 1주일 - '86400': 하루 + '604800': 1 주 + '86400': 1 일 expires_in_prompt: 영원히 - generate: 생성 + generate: 초대 링크 생성하기 invited_by: '당신을 초대한 사람:' max_uses: other: "%{count}회" @@ -1225,11 +1342,11 @@ ko: prompt: 이 서버에 대한 초대 링크를 만들고 공유합니다 table: expires_at: 만료 - uses: 사용됨 - title: 초대 + uses: 이용 수 + title: 초대하기 lists: errors: - limit: 리스트 최대치에 도달했습니다 + limit: 리스트 최대 개수를 초과합니다 login_activities: authentication_methods: otp: 2단계 인증 앱 @@ -1241,14 +1358,29 @@ ko: failed_sign_in_html: 실패한 로그인 시도 %{method} %{ip} (%{browser}) successful_sign_in_html: 성공한 로그인 시도 %{method} %{ip} (%{browser}) title: 인증 이력 + mail_subscriptions: + unsubscribe: + action: 네, 구독 취소합니다 + complete: 구독 취소됨 + confirmation_html: 정말로 %{domain}에서 %{email}로 보내는 마스토돈의 %{type}에 대한 구독을 취소하시겠습니까? 언제든지 이메일 알림 설정에서 다시 구독할 수 있습니다. + emails: + notification_emails: + favourite: 좋아요 알림 이메일 + follow: 팔로우 알림 이메일 + follow_request: 팔로우 요청 알림 이메일 + mention: 멘션 알림 이메일 + reblog: 부스트 알림 이메일 + resubscribe_html: 만약 실수로 구독 취소를 했다면 이메일 알림 설정에서 다시 구독할 수 있습니다. + success_html: 이제 더이상 %{domain}에서 %{email}로 마스토돈의 %{type} 알림을 보내지 않습니다. + title: 구독 취소 media_attachments: validations: - images_and_video: 이미 사진이 첨부된 게시물엔 동영상을 첨부 할 수 없습니다 + images_and_video: 이미 사진이 첨부된 게시물엔 동영상을 첨부할 수 없습니다. not_ready: 처리가 끝나지 않은 파일은 첨부할 수 없습니다. 잠시 후에 다시 시도해 주세요! too_many: 최대 4개까지 첨부할 수 있습니다 migrations: acct: 새 계정의 username@domain - cancel: 리디렉션 취소 + cancel: 리디렉트 취소하기 cancel_explanation: 리다이렉트를 취소하면 현재 계정이 다시 활성화 됩니다, 새 계정으로 이동한 팔로워를 되찾을 수는 없습니다. cancelled_msg: 리다이렉트를 성공적으로 취소했습니다. errors: @@ -1274,14 +1406,14 @@ ko: cooldown: 이주 뒤에는 새로운 이주를 하지 못하는 휴식기간이 존재합니다 disabled_account: 이 계정은 완전한 사용이 불가능하게 됩니다. 하지만, 데이터 내보내기나 재활성화를 위해 접근할 수 있습니다. followers: 이 행동은 현재 계정의 모든 팔로워를 새 계정으로 이동시킵니다 - only_redirect_html: 대신, 프로필에 리디렉션만 표시할 수 있습니다. + only_redirect_html: 대신, 프로필에 리디렉션만 표시할 수도 있습니다. other_data: 다른 어떤 데이터도 자동적으로 옮겨지지 않을 것입니다 redirect: 현재 계정 프로필은 리다이렉트 알림과 함께 업데이트 되며 검색에서 제외 됩니다 moderation: title: 중재 move_handler: - carry_blocks_over_text: 이 사용자는 당신이 차단한 %{acct}로부터 이주 했습니다. - carry_mutes_over_text: 이 사용자는 당신이 뮤트한 %{acct}로부터 이주 했습니다. + carry_blocks_over_text: 이 사용자는 예전에 차단한 %{acct}에서 이주 했습니다. + carry_mutes_over_text: 이 사용자는 예전에 뮤트한 %{acct}에서 이주 했습니다. copy_account_note_text: '이 사용자는 %{acct}로부터 이동하였습니다. 당신의 이전 노트는 이렇습니다:' navigation: toggle_menu: 토글 메뉴 @@ -1306,11 +1438,11 @@ ko: title: 새 팔로우 요청 mention: action: 답장 - body: "%{name} 님이 나를 언급했습니다:" - subject: "%{name} 님이 나를 언급했습니다" + body: "%{name} 님이 나를 멘션했습니다:" + subject: "%{name} 님의 멘션" title: 새 답글 poll: - subject: "%{name}의 투표가 종료되었습니다" + subject: "%{name}의 설문이 종료됨" reblog: body: '당신의 게시물을 %{name} 님이 부스트 했습니다:' subject: "%{name} 님이 내 게시물을 부스트 했습니다" @@ -1320,6 +1452,7 @@ ko: update: subject: "%{name} 님이 게시물을 수정했습니다" notifications: + administration_emails: 관리자 이메일 알림 email_events: 이메일 알림에 대한 이벤트 email_events_hint: '알림 받을 이벤트를 선택해주세요:' other_settings: 기타 알림 설정 @@ -1349,21 +1482,31 @@ ko: truncate: "…" polls: errors: - already_voted: 이미 투표에 참여하셨습니다 - duplicate_options: 중복된 항목이 있습니다 - duration_too_long: 너무 먼 미래입니다 - duration_too_short: 너무 가깝습니다 - expired: 투표가 이미 끝났습니다 - invalid_choice: 선택한 투표 항목이 존재하지 않습니다 - over_character_limit: 각각 %{max} 글자를 넘을 수 없습니다 - too_few_options: 한가지 이상의 항목을 포함해야 합니다 + already_voted: 이미 참여한 설문 + duplicate_options: 중복된 항목 있음 + duration_too_long: 지나치게 먼 미래 + duration_too_short: 너무 짧음 + expired: 이미 종료된 설문 + invalid_choice: 선택한 투표 항목이 존재하지 않음 + over_character_limit: 각 문자가 %{max} 보다 짧아야 함 + self_vote: 자신이 만든 설문에는 투표할 수 없음 + too_few_options: 둘 이상의 항목이 있어야 함 too_many_options: 항목은 %{max}개를 넘을 수 없습니다 preferences: other: 기타 posting_defaults: 게시물 기본설정 public_timelines: 공개 타임라인 + privacy: + hint_html: "내 프로필과 게시물이 어떻게 발견될지를 제어합니다. 활성화 하면 마스토돈의 다양한 기능들이 내가 더 많은 사람에게 도달할 수 있도록 도와줍니다. 이 설정이 내 용도에 맞는지 잠시 검토하세요." + privacy: 개인정보 + privacy_hint_html: 다른 이들을 위해 노출할 수 있는 정보의 양을 조절합니다. 누군가는 다른 이들의 팔로우를 둘러보고 어떤 앱에서 게시물을 올렸는지 살피면서 흥미로운 프로필과 멋진 앱을 발견할 수 있지만, 누군가는 이를 숨기고 싶을 수도 있겠죠. + reach: 도달 + reach_hint_html: 새로운 사람들이 나를 발견하고 팔로우하도록 허용할지 여부를 제어합니다. 둘러보기 화면에 게시물이 표시되기를 바라나요? 다른 사람들의 팔로우 추천에 표시되기를 바라나요? 모든 새 팔로워를 자동으로 수락하거나 각 팔로워를 세세하게 제어할까요? + search: 검색 + search_hint_html: 내가 어떻게 발견될지를 제어합니다. 내가 공개적으로 게시한 것들로 인해 사람들이 날 발견하길 원하나요? 마스토돈 바깥의 사람들이 웹에서 검색을 통해 내 프로필을 발견하길 원하나요? 공개적인 정보에 대해서 모든 검색엔진의 검색결과에서 제외하는 것은 보장할 수 없다는 점에 주의해주세요. + title: 개인정보와 도달 privacy_policy: - title: 개인정보 정책 + title: 개인정보처리방침 reactions: errors: limit_reached: 리액션 갯수 제한에 도달했습니다 @@ -1374,12 +1517,13 @@ ko: confirm_remove_selected_followers: 정말로 선택된 팔로워들을 삭제하시겠습니까? confirm_remove_selected_follows: 정말로 선택된 팔로우를 끊으시겠습니까? dormant: 휴면 + follow_failure: 선택한 계정 중 몇몇은 팔로우 할 수 없었습니다. follow_selected_followers: 선택한 팔로워들을 팔로우 followers: 팔로워 following: 팔로잉 - invited: 초대됨 - last_active: 마지막 활동 - most_recent: 가장 최근 + invited: 초대함 + last_active: 최근 활동 + most_recent: 최신 moved: 이동함 mutual: 상호 팔로우 primary: 주 계정 @@ -1403,7 +1547,7 @@ ko: over_total_limit: 예약 게시물 제한 %{limit}을 초과합니다 too_soon: 예약 날짜는 미래여야 합니다 sessions: - activity: 마지막 활동 + activity: 최근 활동 browser: 브라우저 browsers: alipay: 알리페이 @@ -1413,6 +1557,7 @@ ko: electron: 일렉트론 firefox: 파이어폭스 generic: 알 수 없는 브라우저 + huawei_browser: 화웨이 브라우저 ie: 인터넷 익스플로러 micro_messenger: 마이크로메신저 nokia: Nokia S40 Ovi 브라우저 @@ -1422,6 +1567,7 @@ ko: qq: QQ 브라우저 safari: 사파리 uc_browser: UC 브라우저 + unknown_browser: 알 수 없는 브라우저 weibo: 웨이보 current_session: 현재 세션 description: "%{platform}의 %{browser}" @@ -1434,14 +1580,15 @@ ko: chrome_os: 크롬OS firefox_os: 파이어폭스OS ios: iOS + kai_os: KaiOS linux: 리눅스 mac: macOS - other: 알 수 없는 플랫폼 + unknown_platform: 알 수 없는 플랫폼 windows: 윈도우 windows_mobile: 윈도우 모바일 windows_phone: 윈도우 폰 revoke: 삭제 - revoke_success: 세션이 성공적으로 삭제되었습니다 + revoke_success: 세션을 성공적으로 취소하였습니다 title: 세션 view_authentication_history: 내 계정에 대한 인증 이력 보기 settings: @@ -1449,19 +1596,19 @@ ko: account_settings: 계정 설정 aliases: 계정 별명 appearance: 외관 - authorized_apps: 인증된 애플리케이션 + authorized_apps: 승인된 애플리케이션 back: 마스토돈으로 돌아가기 delete: 계정 삭제 development: 개발 - edit_profile: 프로필 편집 + edit_profile: 프로필 수정 export: 데이터 내보내기 featured_tags: 추천 해시태그 import: 데이터 가져오기 - import_and_export: 가져오기 / 내보내기 + import_and_export: 가져오기 & 내보내기 migrate: 계정 이동 notifications: 알림 - preferences: 사용자 설정 - profile: 프로필 + preferences: 환경설정 + profile: 공개 프로필 relationships: 팔로잉과 팔로워 statuses_cleanup: 게시물 자동 삭제 strikes: 중재 기록 @@ -1501,7 +1648,6 @@ ko: show_newer: 새로운 것 표시 show_older: 오래된 것 표시 show_thread: 글타래 보기 - sign_in_to_participate: 로그인 하여 이 대화에 참여하기 title: '%{name}: "%{quote}"' visibilities: direct: 다이렉트 @@ -1526,8 +1672,8 @@ ko: keep_media_hint: 미디어가 첨부된 게시물을 삭제하지 않습니다 keep_pinned: 고정된 게시물 유지 keep_pinned_hint: 고정 게시물을 삭제하지 않습니다 - keep_polls: 투표 유지 - keep_polls_hint: 투표를 삭제하지 않습니다 + keep_polls: 설문 유지 + keep_polls_hint: 설문을 삭제하지 않았음 keep_self_bookmark: 북마크한 게시물 유지 keep_self_bookmark_hint: 북마크한 본인의 게시물을 삭제하지 않습니다 keep_self_fav: 마음에 들어한 게시물 유지 @@ -1538,7 +1684,7 @@ ko: '2629746': 1 개월 '31556952': 1 년 '5259492': 2 개월 - '604800': 1주일 + '604800': 1 주 '63113904': 2 년 '7889238': 3 개월 min_age_label: 기한 @@ -1547,9 +1693,7 @@ ko: min_reblogs: 해당 횟수 이상 부스트된 게시물 유지 min_reblogs_hint: 이 횟수 이상의 부스트가 된 게시물은 삭제하지 않습니다. 부스트 수와 관계없이 게시물을 지우고 싶다면 공백으로 두세요 stream_entries: - pinned: 고정된 게시물 - reblogged: 님이 부스트 했습니다 - sensitive_content: 민감한 콘텐츠 + sensitive_content: 민감한 내용 strikes: errors: too_late: 이의를 제기하기에 너무 늦었습니다 @@ -1561,20 +1705,25 @@ ko: mastodon-light: 마스토돈 (밝음) time: formats: - default: "%Y년 %m월 %d일 %H:%M" - month: "%Y년 %b" + default: "%Y-%m-%d %H:%M" + month: "%Y년 %f월" time: "%H:%M" + with_time_zone: "%Y-%m-%d %H:%M %Z" + translation: + errors: + quota_exceeded: 서버 전체의 번역 서비스 사용량 제한에 도달했습니다. + too_many_requests: 최근 번역 서비스에 요청이 너무 많았습니다. two_factor_authentication: add: 추가 disable: 비활성화 disabled_success: 2단계 인증이 비활성화 되었습니다. - edit: 편집 + edit: 수정 enabled: 2단계 인증이 활성화 되어 있습니다 enabled_success: 2단계 인증이 활성화 되었습니다 generate_recovery_codes: 복구 코드 생성 lost_recovery_codes: 복구 코드를 사용하면 휴대전화를 분실한 경우에도 계정에 접근할 수 있게 됩니다. 복구 코드를 분실한 경우에도 여기서 다시 생성할 수 있지만, 예전 복구 코드는 비활성화 됩니다. methods: 2단계 인증 - otp: 인증 앱 + otp: 인증 애플리케이션 recovery_codes: 복구 코드 recovery_codes_regenerated: 복구 코드가 다시 생성되었습니다 recovery_instructions_html: 휴대전화를 분실한 경우, 아래 복구 코드 중 하나를 사용해 계정에 접근할 수 있습니다. 복구 코드는 안전하게 보관해 주십시오. 이 코드를 인쇄해 중요한 서류와 함께 보관하는 것도 좋습니다. @@ -1583,16 +1732,16 @@ ko: appeal_approved: action: 내 계정으로 가기 explanation: "%{strike_date}에 일어난 중재결정에 대한 소명을 %{appeal_date}에 작성했으며 승낙되었습니다. 당신의 계정은 정상적인 상태로 돌아왔습니다." - subject: "%{date}에 작성한 소명이 승인되었습니다" + subject: 귀하가 %{date}에 작성한 소명이 승낙되었습니다 title: 소명이 받아들여짐 appeal_rejected: - explanation: "%{strike_date}에 일어난 중재결정에 대한 소명을 %{appeal_date}에 작성했지만 거절되었습니다." - subject: "%{date}에 작성한 소명이 거절되었습니다" + explanation: "%{strike_date}에 일어난 중재결정에 대한 소명을 %{appeal_date}에 작성했지만 반려되었습니다." + subject: "%{date}에 작성한 소명이 반려되었습니다." title: 이의 제기가 거절되었습니다 backup_ready: - explanation: 당신이 요청한 계정의 풀 백업이 이제 다운로드 가능합니다! - subject: 당신의 아카이브를 다운로드 가능합니다 - title: 아카이브 테이크 아웃 + explanation: 마스토돈 계정의 전체 백업을 요청하셨지요. 이제 다운로드할 수 있습니다! + subject: 아카이브를 다운로드할 수 있습니다 + title: 아카이브 테이크아웃 suspicious_sign_in: change_password: 암호 변경 details: '로그인에 대한 상세 정보입니다:' @@ -1608,11 +1757,11 @@ ko: violation: 콘텐츠가 다음의 커뮤니티 규정을 위반합니다 explanation: delete_statuses: 귀하의 게시물 중 일부가 하나 이상의 커뮤니티 가이드라인을 위반한 것으로 확인되어 %{instance}의 중재자에 의해 삭제되었습니다. - disable: 당신은 더이상 당신의 계정을 사용할 수 없습니다, 하지만 프로필과 다른 데이터들은 여전히 그대로 남아있습니다. 당신의 데이터에 대한 백업을 요청하거나, 계정 설정을 변경 또는 계정을 삭제할 수 있습니다. + disable: 귀하의 계정은 이제 이용할 수 없습니다만, 프로필과 다른 데이터들은 여전히 그대로 남아있습니다. 귀하의 데이터 백업을 요청하거나, 계정의 설정을 변경 또는 삭제할 수 있습니다. mark_statuses_as_sensitive: 당신의 몇몇 게시물들은 %{instance}의 중재자에 의해 민감함으로 설정되었습니다. 이것은 사람들이 미리보기를 보기 전에 미디어를 한번 눌러야 함을 의미합니다. 당신은 스스로도 자신의 게시물을 작성할 때 미디어를 민감함으로 설정할 수 있습니다. sensitive: 지금부터는, 당신이 업로드한 미디어 파일들은 민감함 표시가 뜨게 되고 클릭해야만 볼 수 있다는 경고문 뒤에 가려지게 됩니다. silence: 당신은 여전히 당신의 계정을 사용할 수 있지만 당신을 팔로우 하고 있는 사람들만 당신의 게시물을 볼 수 있으며, 여러가지 탐색 기능에서 제외됩니다. 하지만, 여전히 다른 사람들은 수동으로 당신을 팔로우 할 수 있습니다. - suspend: 당신은 더이상 당신의 계정을 사용할 수 없으며, 프로필과 데이터는 접근 불가능하게 됩니다. 데이터가 완전히 삭제되기 전인 30일동안은 여전히 백업을 요청하기 위해 로그인 할 수 있습니다, 하지만 계정 정지를 회피하는 것을 방지하기 위하여 몇 가지 정보는 유지됩니다. + suspend: 귀하의 계정은 이제 이용할 수 없으며, 프로필과 그 밖의 데이터에 접근할 수 없습니다. 귀하는 데이터가 완전히 삭제되기 전인 30일 간 여전히 백업을 요청하기 위해 로그인 할 수 있습니다만, 저희는 계정 정지의 회피 수단을 방지하기 위해 몇 기본 자료를 유지합니다. reason: '사유:' statuses: '인용된 게시물:' subject: @@ -1633,7 +1782,7 @@ ko: suspend: 계정 정지 됨 welcome: edit_profile_action: 프로필 설정 - edit_profile_step: 프로필 사진을 업로드하고, 사람들에게 표시 될 이름을 바꾸는 것 등으로 당신의 프로필을 커스텀 할 수 있습니다. 사람들이 당신을 팔로우 하기 전에 리뷰를 거치게 할 수도 있습니다. + edit_profile_step: 프로필 사진을 업로드하거나 사람들에게 표시할 이름을 바꾸는 것 등으로 자신의 프로필을 커스텀 할 수 있습니다. 새로운 팔로워를 검토 후에 허용하도록 할 수도 있습니다. explanation: 시작하기 전에 몇가지 팁들을 준비했습니다 final_action: 포스팅 시작하기 final_step: '게시물을 올리세요! 팔로워가 없더라도, 공개 게시물들은 다른 사람에게 보여질 수 있습니다, 예를 들자면 로컬이나 연합 타임라인 등이 있습니다. 사람들에게 자신을 소개하고 싶다면 #툿친소 해시태그를 이용해보세요.' @@ -1643,13 +1792,18 @@ ko: title: 환영합니다 %{name} 님! users: follow_limit_reached: 당신은 %{limit}명의 사람을 넘어서 팔로우 할 수 없습니다 + go_to_sso_account_settings: ID 공급자의 계정 설정으로 이동 invalid_otp_token: 2단계 인증 코드가 올바르지 않습니다 otp_lost_help_html: 만약 양쪽 모두를 잃어버렸다면 %{email}을 통해 복구할 수 있습니다 seamless_external_login: 외부 서비스를 이용해 로그인했으므로 이메일과 암호는 설정할 수 없습니다. signed_in_as: '다음과 같이 로그인 중:' verification: - explanation_html: '당신은 프로필 메타데이터의 링크 소유자임을 검증할 수 있습니다. 이것을 하기 위해서는, 링크 된 웹사이트에서 당신의 마스토돈 프로필을 역으로 링크해야 합니다. 역링크는 반드시 rel="me" 속성을 가지고 있어야 합니다. 링크의 텍스트는 상관이 없습니다. 여기 예시가 있습니다:' + extra_instructions_html: 팁: 웹사이트에 안 보이는 링크로 삽입할 수 있습니다. 중요한 것은 나를 도용하는 것을 방지하는 rel="me" 부분입니다. 심지어 a 대신 link태그를 페이지 헤더에 넣는 것으로 대체할 수도 있습니다. 하지만 HTML 코드는 자바스크립트 실행 없이 접근이 가능해야 합니다. + here_is_how: 사용방법 + hint_html: "내 신분을 모두에게 증명하세요. 영원히 무료로 쓸 수 있는 웹 표준을 기반으로 합니다. 나를 확인할 수 있는 개인 웹사이트가 필요한 전부입니다. 이 웹사이트 링크를 프로필에 추가하면 우리는 그 웹사이트가 이 계정으로 역링크를 걸었는지 확인하고 프로필에 잘 보이는 마크를 보여줄 것입니다." + instructions_html: 웹사이트에 아래 코드를 복사해 붙여 넣으세요. 그리고 "프로필 수정" 탭에서 그 웹사이트 주소를 프로필의 추가 필드 중 하나에 넣고 변경사항을 저장하세요. verification: 검증 + verified_links: 인증된 링크들 webauthn_credentials: add: 보안 키 추가 create: diff --git a/config/locales/ku.yml b/config/locales/ku.yml index 0990d97682..58c1885dfe 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -124,8 +124,6 @@ ku: removed_header_msg: Wêneyê dîwar ê %{username} bi awayekî serkeftî hate rakirin resend_confirmation: already_confirmed: Ev bikarhêner jixwe hatiye pejirandin - send: E-nameya pejirandinê dîsa bişîne - success: E-nameya pejirandinê bi awayekî serkeftî hate şandin! reset: Ji nû ve saz bike reset_password: Borînpeyvê ji nû ve saz bike resubscribe: Dîsa beşdar bibe @@ -727,7 +725,6 @@ ku: approved: Ji bo têketinê erêkirin pêwîste none: Kesek nikare tomar bibe open: Herkes dikare tomar bibe - title: Sazkariyên rajekarê site_uploads: delete: Pela barkirî jê bibe destroyed_msg: Barkirina malperê bi serkeftî hate jêbirin! @@ -922,7 +919,6 @@ ku: guide_link: https://crowdin.com/project/mastodon guide_link_text: Herkes dikare beşdar bibe. sensitive_content: Naveroka hestiyarî - toot_layout: Xêzkirina şandîya application_mailer: notification_preferences: Sazkariyên e-nameyê biguherîne salutation: "%{name}," @@ -939,14 +935,12 @@ ku: your_token: Nîşana gihîştinê te auth: apply_for_account: Ajimêrekê bixwaze - change_password: Borînpeyv delete_account: Ajimêr jê bibe delete_account_html: Ku tu dixwazî ajimêra xwe jê bibe, tu dikarî li vir bidomîne. Ji te tê xwestin ku were pejirandin. description: prefix_invited_by_user: "@%{name} te vedixwîne ku tu beşdarî vê rajekara Mastodon-ê bibî!" prefix_sign_up: Îro li Mastodonê tomar bibe! suffix: Bi ajimêrekê, tu yê karibî kesan bişopînî, rojanekirinan bişînî û bi bikarhênerên ji her rajekarê Mastodon re peyaman bişînî û bêtir! - didnt_get_confirmation: Te rêwerzên pejirandinê wernegirt? dont_have_your_security_key: Kilîda te ya ewlehiyê tune ye? forgot_password: Te borînpeyva xwe ji bîr kir? invalid_reset_password_token: Ji nû ve sazkirina borînpeyvê nederbasdar e an jî qediya ye. Jkx daxwaza yeka nû bike. @@ -964,17 +958,12 @@ ku: saml: SAML register: Tomar bibe registration_closed: "%{instance} endamên nû napejirîne" - resend_confirmation: Rêwerên pejirandinê ji nû ve bişîne reset_password: Borînpeyvê ji nû ve saz bike rules: preamble: Ev rêzik ji aliyê çavdêrên %{domain} ve tên sazkirin. title: Hinek rêzikên bingehîn. security: Ewlehî set_new_password: Borînpeyveke nû ji nû ve saz bike - setup: - email_below_hint_html: Ku navnîşana e-nameya jêrîn ne rast be, tu dikarî wê li vir biguherîne û e-nameyeke pejirandinê ya nû bistîne. - email_settings_hint_html: E-nameya pejirandinê ji %{email} re hate şandin. Ku ew navnîşana e-nameyê ne rast be, tu dikarî wê di sazkariyên ajimêr de biguherîne. - title: Damezirandin sign_in: preamble_html: Têketinê bike bi riya %{domain} xwe. Ku ajimêrê te li ser rajekareke cuda hatiye pêşkêşkirin, tu yê nikaribû têketinê bikî vir. title: Têkeve %{domain} @@ -990,18 +979,6 @@ ku: view_strikes: Binpêkirinên berê yên dijî ajimêrê xwe bibîne too_fast: Form pir zû hat şandin, dîsa biceribîne. use_security_key: Kilîteke ewlehiyê bi kar bîne - authorize_follow: - already_following: Jixwe tu vê ajimêrê dişopînî - already_requested: Jixwe te ji vê ajimêrê re daxwazîya şopandinê şandi bû - error: Mixabin, dema ajimêr hat gerandin çewtiyek çêbû - follow: Bişopîne - follow_request: 'Te ji vê kesê re daxwazîya şopandinê şand:' - following: 'Serkeftin! Tu êdî dikarî bişopînî:' - post_follow: - close: An jî, tu dikarî tenê ev çarçoveyê bigirî. - return: Profîla vê bikarhênerê nîşan bike - web: Biçe tevneyê - title: "%{acct} bişopîne" challenge: confirm: Bidomîne hint_html: "Nîşe:Ji bo demjimêreke din em ê borînpeyva te careke din ji te nexwazin." @@ -1113,8 +1090,6 @@ ku: storage: Bîrdanaka medyayê featured_tags: add_new: Yeka nû tevlî bike - errors: - limit: Te jixwe berê pirtirîn hashtag destnîşan kiriye hint_html: " Hashtagên destnîşankirî çi ne? Ew bi eşkere li ser profîla te ya gelemperî têne xuyakirin û dihêlin ku mirov bi taybetî di binê wan hashtagan de li şandiyên te yên gelemperî bigere. Ew ji bo şopandina karên afirîner an projeyên demdirêj amûrek girîng in." filters: contexts: @@ -1158,8 +1133,6 @@ ku: index: hint: Ev parzûn bêyî pîvanên din ji bo hilbijartina şandiyên kesane tê sepandin. Tu dikarî ji navrûya tevnê bêtir şandiyan tevlî vê parzûnê bikî. title: Şandiyên parzûnkirî - footer: - trending_now: Niha rojevê de generic: all: Hemû all_items_on_page_selected_html: @@ -1182,8 +1155,6 @@ ku: validation_errors: one: Tiştek hîn ne rast e! Ji kerema xwe çewtiya li jêr di ber çavan re derbas bike other: Tiştek hîn ne rast e! Ji kerema xwe %{count} çewtî li jêr di ber çavan re derbas bike - html_validator: - invalid_markup: 'di nav de nîşana HTML a nederbasdar heye: %{error}' imports: errors: invalid_csv_file: 'Pelê CSV nederbasdar e. Çewtî: %{error}' @@ -1224,9 +1195,6 @@ ku: expires_at: Diqede uses: Bikaranîn title: Mirovan vexwîne - lists: - errors: - limit: Tu gihîştî hejmara rêzika a herî zêde login_activities: authentication_methods: otp: sepandina rastandina du-gavî @@ -1430,7 +1398,6 @@ ku: ios: iOS linux: Linux mac: macOS - other: platforma nenas windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1501,7 +1468,6 @@ ku: show_newer: Nûtirîn nîşan bide show_older: Kevntirîn nîşan bide show_thread: Mijarê nîşan bide - sign_in_to_participate: Ji bo tevlî sohbetê bibî xwe tomar bike title: "%{name}%{quote}" visibilities: direct: Rasterast @@ -1543,12 +1509,9 @@ ku: '7889238': 3 meh min_age_label: Şêmûga demê min_favs: Peyamên ku ji wê zêdetir hatine ecibandin veşêre - min_favs_hint: Şandî ku ji evqas hezkirin wergirtibe nayê jêbirin. Vala bihêle da ku şandiyan jê bibî tevlî ku çiqas hezkirin wergirtibe min_reblogs: Şandiyên ku bêtir hatine bilindkirin veşêre min_reblogs_hint: Şandî ku ji ji vê hejmarê bêtir bilindkirin wergirtibe nayê jêbirin. Vala bihêle da ku şandiyan jê bibî tevlî ku çiqas hezkirin wergirtibe stream_entries: - pinned: Şandiya derzîkirî - reblogged: bilindkirî sensitive_content: Naveroka hestiyarî strikes: errors: @@ -1648,7 +1611,6 @@ ku: seamless_external_login: Te bi rajekarke biyanî re têketina xwe kir, ji ber vê yekê borînpeyv û e-name nayê bikaranîn. signed_in_as: 'Têketin wekî:' verification: - explanation_html: 'Tu dikarî xwe wekî xwediyê girêdanên li daneyê meta profîla xwe piştrast bikî. Ji bo vê, hewceye girêda malperê di nav profîla te ya mastodonê de girêdanekî paş hebe. Girêdana paşhewceye taybetîyek rel="me"hebe. Naveroka nivîsa girêdanê ne girîng e. Ev jî mînakek e:' verification: Piştrastkirin webauthn_credentials: add: Kilîteke ewlehiyê nû tevlî bike diff --git a/config/locales/kw.yml b/config/locales/kw.yml index 4085046cf6..b7731ca1a3 100644 --- a/config/locales/kw.yml +++ b/config/locales/kw.yml @@ -5,13 +5,5 @@ kw: email: Ebost followers: Holyoryon title: Akontow - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. settings: account: Akont diff --git a/config/locales/la.yml b/config/locales/la.yml index 244938ef6b..3a7ba0d445 100644 --- a/config/locales/la.yml +++ b/config/locales/la.yml @@ -1,10 +1 @@ ---- la: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 28c9419591..cc00ed7e05 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -3,9 +3,16 @@ lt: about: about_mastodon_html: Mastodon, tai socialinis tinklas pagrįstas atviro kodo programavimu, ir atvirais web protokolais. Visiškai nemokamas. Ši sistema decantrilizuota kaip jūsų elektroninis paštas. contact_missing: Nenustatyta + contact_unavailable: Nėra duomenų hosted_on: Mastodon palaikomas naudojantis %{domain} talpinimu + title: Apie accounts: follow: Sekti + followers: + few: Sekėjai + many: Sekėjai + one: Sekėjas + other: Sekėjai following: Sekami last_active: paskutinį kartą aktyvus link_verified_on: Nuorodos nuosavybė paskutinį kartą tikrinta %{date} @@ -22,6 +29,7 @@ lt: created_msg: Moderavimo žinutė sėkimngai sukurta! destroyed_msg: Moderacijos žinutė sėkmingai ištrinta! accounts: + approve: Patvirtinti are_you_sure: Ar esate įsitikinęs? avatar: Profilio nuotrauka by_domain: Domenas @@ -51,6 +59,7 @@ lt: header: Antraštė inbox_url: Gautųjų URL invited_by: Pakvietė + ip: IP joined: Prisijungė location: all: Visi @@ -80,12 +89,11 @@ lt: remove_header: Panaikinti antraštę resend_confirmation: already_confirmed: Šis vartotojas jau patvirtintas - send: Dar kartą išsiųsti patvirtinimo žinutę - success: Patvirtinimo laiškas sėkmingai išsiųstas! reset: Iš naujo reset_password: Atkurti slaptažodį resubscribe: Per prenumeruoti search: Ieškoti + sensitized: Pažymėti kaip jautrią informaciją shared_inbox_url: Bendroji gautųjų URL show: created_reports: Parašyti raportai @@ -256,10 +264,8 @@ lt: warning: Būkite atsargūs su šia informacija. Niekada jos nesidalinkite! your_token: Jūsų prieigos žetonas auth: - change_password: Slaptažodis delete_account: Ištrinti paskyrą delete_account_html: Jeigu norite ištrinti savo paskyrą, galite eiti čia. Jūsų prašys patvirtinti pasirinkimą. - didnt_get_confirmation: Negavote patvirtinimo instrukcijų? forgot_password: Pamiršote slaptažodį? invalid_reset_password_token: Slaptažodžio atkūrimo žetonas netinkamas arba jo galiojimo laikas pasibaigęs. Prašykite naujo žetono. login: Prisijungti @@ -268,21 +274,9 @@ lt: migrate_account_html: Jeigu norite nukreipti šią paskyrą į kita, galite tai konfiguruoti čia. or_log_in_with: Arba prisijungti su register: Užsiregistruoti - resend_confirmation: Išsiųsti dar kartą patvirtinimo instrukcijas reset_password: Atstatyti slaptažodį security: Apsauga set_new_password: Nustatyti naują slaptažodį - authorize_follow: - already_following: Jūs jau sekate šią paskyrą - error: Dėja, aptikta klaida ieškant tolimosios paskyros - follow: Sekti - follow_request: 'Jūs išsiuntėte sekimo prašymą:' - following: 'Puiku! Jūs pradėjote sekti:' - post_follow: - close: Arba, Jūs galite uždaryti šį langą. - return: Rodyti vartotojo paskyrą - web: Eiti į - title: Sekti %{acct} datetime: distance_in_words: about_x_hours: "%{count} val" @@ -302,10 +296,8 @@ lt: proceed: Ištrinti paskyrą success_msg: Jūsų paskyra sėkmingai ištrinta errors: - '400': The request you submitted was invalid or malformed. '403': Jūs neturie prieigos matyti šiam puslapiui. '404': Puslapis nerastas. - '406': This page is not available in the requested format. '410': Puslapis neegzistuoja. '422': content: Apsaugos patvirtinmas klaidingas. Ar jūs blokuojate sausainius? @@ -314,7 +306,6 @@ lt: '500': content: Atsiprašome, tačiau mūsų pusėje įvyko klaida. title: Netinkamas puslapis - '503': The page could not be served due to a temporary server failure. noscript_html: Kad naudotumėtės Mastodon web aplikacija, prašome įsijungti JavaScript. Alternatyviai, pabandykite viena iš vietinių aplikacijų Mastodon savo platformai. exports: archive_takeout: @@ -331,8 +322,6 @@ lt: storage: Medijos sandėlis featured_tags: add_new: Pridėti naują - errors: - limit: Jūs jau naudojate maksimalų galimą saitažodžių(#) kiekį filters: contexts: home: Namų laiko juosta @@ -385,9 +374,6 @@ lt: expires_at: Pasibaigia uses: Naudojimai title: Pakviesti žmones - lists: - errors: - limit: Jūs pasieketė maksimalų sąrašų skaičių media_attachments: validations: images_and_video: Negalima pridėti video prie statuso, kuris jau turi nuotrauką @@ -426,8 +412,6 @@ lt: prev: Ankstesnis preferences: other: Kita - posting_defaults: Posting defaults - public_timelines: Public timelines remote_follow: missing_resource: Jūsų paskyros nukreipimo URL nerasta scheduled_statuses: @@ -442,8 +426,6 @@ lt: current_session: Dabartinė sesija description: "%{browser} ant %{platform}" explanation: Čia rodomos web naršyklės prijungtos prie Jūsų Mastodon paskyros. - platforms: - other: nežinoma platforma revoke: Atšaukti revoke_success: Sesija sėkmingai atšaukta title: Sesijos @@ -472,7 +454,6 @@ lt: ownership: Kitų vartotojų toot'ai negali būti prisegti reblog: Pakeltos žinutės negali būti prisegtos show_more: Daugiau - sign_in_to_participate: Prisijunkite jeigu norite dalyvauti pokalbyje visibilities: private: Tik sekėjams private_long: Rodyti tik sekėjams @@ -481,8 +462,6 @@ lt: unlisted: Neįtrauktas į sąrašus unlisted_long: Matyti gali visi, tačiau nėra įtraukta į viešas laiko juostas stream_entries: - pinned: Prisegtas toot'as - reblogged: pakeltas sensitive_content: Jautrus turinys themes: contrast: Mastodon (Didelio Kontrasto) @@ -528,5 +507,4 @@ lt: seamless_external_login: Jūs esate prisijungę per išorini įrenginį, todėl slaptąžodis ir el pašto nustatymai neprieinami. signed_in_as: 'Prisijungta kaip:' verification: - explanation_html: 'Jūs galite patvirtinti savę kaip savininką nuorodų savo profilio meta duomenyse. Kad tai padarytumėte, susieta svetainė privalo turėti nuorodą atgal į Jūsų Mastodon profilį. Nuoroda atgal privalo turėti rel="me" savybę. Teksto turinys nuorodoje nesvarbus. Štai pavyzdys:' verification: Patvirtinimas diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 31e1ba77fb..28a1a33dcb 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -93,6 +93,7 @@ lv: moderation: active: Aktīvie all: Visi + disabled: Atspējots pending: Gaida silenced: Ierobežotie suspended: Apturētie @@ -127,8 +128,8 @@ lv: removed_header_msg: Veiksmīgi noņemts %{username} galvenes attēls resend_confirmation: already_confirmed: Šis lietotājs jau ir apstiprināts - send: Atkārtoti nosūtīt apstiprinājuma e-pastu - success: Apstiprinājuma e-pasts veiksmīgi nosūtīts! + send: Atkārtoti nosūtīt apstiprinājuma saiti + success: Apstiprinājuma saite veiksmīgi nosūtīta! reset: Atiestatīt reset_password: Atiestatīt paroli resubscribe: Pieteikties vēlreiz @@ -136,6 +137,7 @@ lv: search: Meklēt search_same_email_domain: Citi lietotāji ar tādu pašu e-pasta domēnu search_same_ip: Citi lietotāji ar tādu pašu IP + security: Drošība security_measures: only_password: Tikai parole password_and_2fa: Parole un 2FA @@ -310,6 +312,7 @@ lv: unpublish: Atcelt publicēšanu unpublished_msg: Paziņojuma publicēšana veiksmīgi atcelta! updated_msg: Paziņojums ir veiksmīgi atjaunināts! + critical_update_pending: Gaida kritisko atjauninājumu custom_emojis: assign_category: Piešķirt kategoriju by_domain: Domēns @@ -387,6 +390,15 @@ lv: undo: Aizliegt federāciju ar domēnu domain_blocks: add_new: Pievienot jaunu domēna bloku + confirm_suspension: + cancel: Atcelt + confirm: Apturēt + permanent_action: Apturēšanas atsaukšana neatjaunos nekādus datus vai attiecības. + preamble_html: Tu gatavojies apturēt domēna %{domain} un tā apakšdomēnu darbību. + remove_all_data: Tādējādi no tava servera tiks noņemts viss šī domēna kontu saturs, multivide un profila dati. + stop_communication: Jūsu serveris pārtrauks sazināties ar šiem serveriem. + title: Apstiprināt domēna %{domain} bloķēšanu + undo_relationships: Tādējādi tiks atsauktas jebkuras sekošanas attiecības starp šo un tavu serveru kontiem. created_msg: Domēna bloķēšana tagad tiek apstrādāta destroyed_msg: Domēna bloķēšana ir atsaukta domain: Domēns @@ -435,6 +447,7 @@ lv: resolve: Atrisināt domēnu title: Bloķēt jaunu e-pasta domēnu no_email_domain_block_selected: Neviens e-pasta domēna bloks netika mainīts, jo neviens netika atlasīts + not_permitted: Nav atļauta resolved_dns_records_hint_html: Domēna nosaukums tiek izmantots tālāk norādītajos MX domēnos, kas galu galā ir atbildīgi par e-pasta pieņemšanu. Bloķējot MX domēnu, tiks bloķēta reģistrēšanās no jebkuras e-pasta adreses, kas izmanto vienu un to pašu MX domēnu, pat ja redzamais domēna nosaukums atšķiras. Esi uzmanīgs, lai nebloķētu lielākos e-pasta pakalpojumu sniedzējus. resolved_through_html: Atrisināts, izmantojot %{domain} title: Bloķētie e-pasta domēni @@ -447,7 +460,7 @@ lv: description_html: Tu gatavojies importēt domēna bloku sarakstu. Lūdzu, ļoti rūpīgi pārskati šo sarakstu, it īpaši, ja tu pats neesi to veidojis. existing_relationships_warning: Esošās sekošanas attiecības private_comment_description_html: 'Lai palīdzētu tev izsekot, no kurienes nāk importētie bloki, tiks izveidoti importētie bloki ar šādu privātu komentāru: %{comment}' - private_comment_template: Importēts no %{source} %{date} + private_comment_template: Importēt no %{source} %{date} title: Importēt bloķētos domēnus invalid_domain_block: 'Viens vai vairāki domēna bloķi tika izlaisti šādas kļūdas(-u) dēļ: %{error}' new: @@ -483,6 +496,7 @@ lv: content_policies: comment: Iekšējā piezīme description_html: Tu vari definēt satura politikas, kas tiks piemērotas visiem kontiem no šī domēna un jebkura tā apakšdomēna. + limited_federation_mode_description_html: Tu vari izvēlēties, vai atļaut federāciju ar šo domēnu. policies: reject_media: Noraidīt multividi reject_reports: Noraidīt ziņojumus @@ -597,11 +611,13 @@ lv: assign_to_self: Piešķirt man assigned: Piešķirtais moderators by_target_domain: Ziņotā konta domēns + cancel: Atcelt category: Kategorija category_description_html: Iemesls kāpēc šis konts un / vai saturs tika ziņots, tiks minēts saziņā ar paziņoto kontu comment: none: Neviens comment_description_html: 'Lai sniegtu vairāk informācijas, %{name} rakstīja:' + confirm: Apstiprināt confirm_action: Apstipriniet regulēšanas darbību pret @%{acct} created_at: Ziņoti delete_and_resolve: Izdzēst rakstus @@ -706,7 +722,7 @@ lv: manage_settings: Pārvaldīt Iestatījumus manage_settings_description: Ļauj lietotājiem mainīt vietnes iestatījumus manage_taxonomies: Pārvaldīt Taksonomijas - manage_taxonomies_description: Ļauj lietotājiem pārskatīt aktuālo saturu un atjaunināt atsauces iestatījumus + manage_taxonomies_description: Ļauj lietotājiem pārskatīt aktuālāko saturu un atjaunināt atsauces iestatījumus manage_user_access: Pārvaldīt Lietotāju Piekļuves manage_user_access_description: Ļauj lietotājiem atspējot citu lietotāju divu faktoru autentifikāciju, mainīt savu e-pasta adresi un atiestatīt paroli manage_users: Pārvaldīt Lietotājus @@ -739,6 +755,9 @@ lv: branding: preamble: Tava servera zīmols to atšķir no citiem tīkla serveriem. Šī informācija var tikt parādīta dažādās vidēs, piemēram, Mastodon tīmekļa saskarnē, vietējās lietojumprogrammās, saišu priekšskatījumos citās vietnēs un ziņojumapmaiņas lietotnēs un tā tālāk. Šī iemesla dēļ vislabāk ir saglabāt šo informāciju skaidru, īsu un kodolīgu. title: Zīmola veidošana + captcha_enabled: + desc_html: Tas balstās uz ārējiem skriptiem no hCaptcha, kas var radīt bažas par drošību un privātumu. Turklāt tas var padarīt reģistrācijas procesu ievērojami mazāk pieejamu dažiem cilvēkiem (īpaši invalīdiem). Šo iemeslu dēļ, lūdzu, apsver alternatīvus pasākumus, piemēram, reģistrāciju, kas balstīta uz apstiprinājumu vai uzaicinājumu. + title: Pieprasīt jaunajiem lietotājiem atrisināt CAPTCHA, lai apstiprinātu savu kontu content_retention: preamble: Kontrolē, kā Mastodon tiek glabāts lietotāju ģenerēts saturs. title: Satura saglabāšana @@ -766,10 +785,27 @@ lv: approved: Reģistrācijai nepieciešams apstiprinājums none: Neviens nevar reģistrēties open: Jebkurš var reģistrēties - title: Servera Iestatījumi + security: + authorized_fetch: Pieprasīt autentifikāciju no federētajiem serveriem + authorized_fetch_hint: Pieprasot autentifikāciju no federētajiem serveriem, tiek nodrošināta stingrāka gan lietotāja līmeņa, gan servera līmeņa bloku izpilde. Tomēr tas ir saistīts ar izpildes sodu, samazina tavu atbilžu sasniedzamību un var radīt saderības problēmas ar dažiem federētajiem pakalpojumiem. Turklāt tas netraucēs īpašiem dalībniekiem ienest tavas publiskās ziņas un kontus. + authorized_fetch_overridden_hint: Tu pašlaik nevari mainīt šo iestatījumu, jo to aizstāj vides mainīgais. + federation_authentication: Federācijas autentifikācijas izpilde + title: Servera iestatījumi site_uploads: delete: Dzēst augšupielādēto failu destroyed_msg: Vietnes augšupielāde ir veiksmīgi izdzēsta! + software_updates: + critical_update: Kritiski - lūdzu, ātri atjaunini + description: Ieteicams uzturēt savu Mastodon instalāciju atjauninātu, lai gūtu labumu no jaunākajiem labojumiem un funkcijām. Turklāt dažreiz ir ļoti svarīgi atjaunināt Mastodon savlaicīgi, lai izvairītos no drošības problēmām. Šo iemeslu dēļ Mastodon pārbauda atjauninājumus ik pēc 30 minūtēm un informēs tevi atbilstoši tavu e-pasta paziņojumu iestatījumiem. + documentation_link: Uzzināt vairāk + release_notes: Laidiena piezīmes + title: Pieejamie atjauninājumi + type: Veids + types: + major: Galvenais laidiens + minor: Neliels laidiens + patch: Ielāpa laidiens - kļūdu labojumi un viegli piemērojamas izmaiņas + version: Versija statuses: account: Autors application: Lietotne @@ -792,7 +828,7 @@ lv: reblogs: Reblogi status_changed: Ziņa mainīta title: Konta ziņas - trending: Tendences + trending: Populārākie visibility: Redzamība with_media: Ar multividi strikes: @@ -806,9 +842,24 @@ lv: suspend: "%{name} apturēja %{target} kontu" appeal_approved: Pārsūdzēts appeal_pending: Apelācija tiek izskatīta + appeal_rejected: Apelācija noraidīta system_checks: database_schema_check: message_html: Notiek datubāzu migrācijas. Lūdzu, palaid tās, lai nodrošinātu, ka lietojumprogramma darbojas, kā paredzēts + elasticsearch_health_red: + message_html: Elasticsearch klasteris ir neveselīgs (sarkans statuss), meklēšanas līdzekļi nav pieejami + elasticsearch_health_yellow: + message_html: Elasticsearch klasteris ir neveselīgs (dzeltens statuss), tu varētu vēlēties meklēt iemeslu + elasticsearch_index_mismatch: + message_html: Elasticsearch indeksa kartējumi ir novecojuši. Lūdzu, palaid tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Skatīt dokumentāciju + message_html: Tavam Elasticsearch klasterim ir vairāk nekā viens mezgls, taču Mastodon nav konfigurēts to lietošanai. + elasticsearch_preset_single_node: + action: Skatīt dokumentāciju + message_html: Tavam Elasticsearch klasterim ir tikai viens mezgls, ES_PRESET ir jāiestata uz single_node_cluster. + elasticsearch_reset_chewy: + message_html: Tavas Elasticsearch sistēmas indekss ir novecojis iestatījuma izmaiņu dēļ. Lūdzu, palaid tootctl search deploy --reset-chewy, lai to atjauninātu. elasticsearch_running_check: message_html: Nevarēja izveidot savienojumu ar Elasticsearch. Lūdzu, pārbaudi, vai tā darbojas, vai atspējo pilna teksta meklēšanu elasticsearch_version_check: @@ -819,6 +870,18 @@ lv: message_html: Tu neesi definējis nevienu servera nosacījumu. sidekiq_process_check: message_html: Rindā(s) %{value} nedarbojas neviens Sidekiq process. Lūdzu, pārskati savu Sidekiq konfigurāciju + software_version_critical_check: + action: Skatīt pieejamos atjauninājumus + message_html: Ir pieejams kritisks Mastodon atjauninājums. Lūdzu, atjaunini to pēc iespējas ātrāk. + software_version_patch_check: + action: Skatīt pieejamos atjauninājumus + message_html: Ir pieejams Mastodon kļūdu labojums. + upload_check_privacy_error: + action: Pārbaudi šeit, lai iegūtu plašāku informāciju + message_html: "Tavs tīmekļa serveris ir nepareizi konfigurēts. Tavu lietotāju privātums ir apdraudēts." + upload_check_privacy_error_object_storage: + action: Pārbaudi šeit, lai iegūtu plašāku informāciju + message_html: "Tava objektu krātuve ir nepareizi konfigurēta. Tavu lietotāju privātums ir apdraudēts." tags: review: Pārskatīt statusu updated_msg: Tēmtura iestatījumi ir veiksmīgi atjaunināti @@ -842,6 +905,7 @@ lv: zero: Pēdējās nedēļas laikā kopīgoja %{count} personas title: Populārākās saites usage_comparison: Šodien kopīgots %{today} reizes, salīdzinot ar %{yesterday} vakar + not_allowed_to_trend: Popularizešana nav atļauta only_allowed: Tikai atļautās pending_review: Gaida pārskatīšanu preview_card_providers: @@ -888,7 +952,7 @@ lv: other: Pēdējās nedēļas laikā izmantoja %{count} personas zero: Pēdējās nedēļas laikā izmantoja %{count} personas title: Tendences - trending: Tendences + trending: Populārākie warning_presets: add_new: Pievienot jaunu delete: Dzēst @@ -929,6 +993,9 @@ lv: body: "%{target} pārsūdzēja %{action_taken_by} moderēšanas lēmumu no %{date}, kas bija %{type}. Viņi rakstīja:" next_steps: Varat apstiprināt apelāciju, lai atsauktu regulēšanas lēmumu, vai ignorēt to. subject: "%{username} pārsūdz moderēšanas lēmumu par %{instance}" + new_critical_software_updates: + body: Ir izlaistas jaunas Mastodon svarīgās versijas, iespējams, vēlēsies to atjaunināt pēc iespējas ātrāk! + subject: "%{instance} ir pieejami svarīgi Mastodon atjauninājumi!" new_pending_account: body: Sīkāka informācija par jauno kontu ir sniegta zemāk. Tu vari apstiprināt vai noraidīt šo pieteikumu. subject: Jauns konts pārskatīšanai %{instance} (%{username}) @@ -936,6 +1003,9 @@ lv: body: "%{reporter} ziņoja par %{target}" body_remote: Kāds no %{domain} ziņoja par %{target} subject: Jauns ziņojums par %{instance} (#%{id}) + new_software_updates: + body: Ir izlaistas jaunas Mastodon versijas, iespējams, vēlēsies atjaunināt! + subject: "%{instance} ir pieejamas jaunas Mastodon versijas!" new_trends: body: 'Tālāk norādītie vienumi ir jāpārskata, lai tos varētu parādīt publiski:' new_trending_links: @@ -965,24 +1035,28 @@ lv: guide_link: https://crowdin.com/project/mastodon guide_link_text: Ikviens var piedalīties. sensitive_content: Sensitīvs saturs - toot_layout: Ziņas izskats application_mailer: notification_preferences: Mainīt e-pasta uztādījumus salutation: "%{name}," settings: 'Mainīt e-pasta uztādījumus: %{link}' + unsubscribe: Atcelt abonēšanu view: 'Skatījums:' view_profile: Skatīt profilu view_status: Skatīt ziņu applications: created: Lietojumprogramma ir veiksmīgi izveidota destroyed: Lietojumprogramma ir veiksmīgi dzēsta + logout: Iziet regenerate_token: Atjaunot piekļuves marķieri token_regenerated: Piekļuves marķieris veiksmīgi atjaunots warning: Esi ļoti uzmanīgs ar šiem datiem. Nekad nedalies ne ar vienu ar tiem! your_token: Tavs piekļuves marķieris auth: apply_for_account: Pieprasīt kontu - change_password: Parole + captcha_confirmation: + help_html: Ja tev ir problēmas ar CAPTCHA risināšanu, vari sazināties ar mums, izmantojot %{email}, un mēs varam tev palīdzēt. + hint_html: Vēl tikai viena lieta! Mums ir jāapstiprina, ka tu esi cilvēks (tas ir tāpēc, lai mēs varētu nepieļaut surogātpasta izsūtīšanu!). Atrisini tālāk norādīto CAPTCHA un noklikšķini uz "Turpināt". + title: Drošības pārbaude confirmations: wrong_email_hint: Ja šī e-pasta adrese nav pareiza, varat to mainīt konta iestatījumos. delete_account: Dzēst kontu @@ -991,7 +1065,7 @@ lv: prefix_invited_by_user: "@%{name} aicina tevi pievienoties šim Mastodon serverim!" prefix_sign_up: Reģistrējies Mastodon jau šodien! suffix: Izmantojot kontu, tu varēsi sekot cilvēkiem, publicēt atjauninājumus un apmainīties ar ziņojumiem ar lietotājiem no jebkura Mastodon servera un daudz ko citu! - didnt_get_confirmation: Vai nesaņēmi apstiprināšanas norādījumus? + didnt_get_confirmation: Vai nesaņēmi apstiprinājuma saiti? dont_have_your_security_key: Vai tev nav drošības atslēgas? forgot_password: Aizmirsi paroli? invalid_reset_password_token: Paroles atiestatīšanas pilnvara nav derīga, vai tai ir beidzies derīgums. Lūdzu, pieprasi jaunu. @@ -1004,26 +1078,39 @@ lv: migrate_account_html: Ja vēlies novirzīt šo kontu uz citu, tu vari to konfigurēt šeit. or_log_in_with: Vai piesakies ar privacy_policy_agreement_html: Esmu izlasījis un piekrītu privātuma politikai + progress: + confirm: Apstiprināt e-pastu + details: Tavi dati + review: Mūsu apskats + rules: Pieņemt noteikumus providers: cas: CAS saml: SAML register: Reģistrēties registration_closed: "%{instance} nepieņem jaunus dalībniekus" - resend_confirmation: Atkārtoti nosūtīt apstiprinājuma norādījumus + resend_confirmation: Atkārtoti nosūtīt apstiprinājuma saiti reset_password: Atiestatīt paroli rules: + accept: Pieņemt + back: Atpakaļ + invited_by: 'Tu vari pievienoties %{domain}, pateicoties uzaicinājumam, ko saņēmi no:' preamble: Tos iestata un ievieš %{domain} moderatori. + preamble_invited: Pirms turpināt, lūdzu, apsver galvenos noteikumus, ko noteikuši %{domain} moderatori. title: Daži pamatnoteikumi. + title_invited: Tu esi uzaicināts. security: Drošība set_new_password: Iestatīt jaunu paroli setup: - email_below_hint_html: Ja zemāk norādītā e-pasta adrese ir nepareiza, vari to nomainīt šeit un saņemt jaunu apstiprinājuma e-pastu. - email_settings_hint_html: Apstiprinājuma e-pasts tika nosūtīts uz %{email}. Ja šī e-pasta adrese nav pareiza, vari to nomainīt konta iestatījumos. - title: Iestatīt + email_below_hint_html: Pārbaudi savu surogātpasta mapi vai pieprasiet citu. Tu vari labot savu e-pasta adresi, ja tā ir nepareiza. + email_settings_hint_html: Noklikšķini uz saites, kuru mēs tev nosūtījām, lai apstiprinātu %{email}. Mēs tepat pagaidīsim. + link_not_received: Vai nesaņēmi sati? + new_confirmation_instructions_sent: Pēc dažām minūtēm saņemsi jaunu e-pastu ar apstiprinājuma saiti! + title: Pārbaudi savu iesūtni sign_in: - preamble_html: Pierakstieties ar saviem %{domain} akreditācijas datiem. Ja jūsu konts ir mitināts citā serverī, jūs nevarēsit pieteikties šeit. + preamble_html: Piesakies ar saviem %{domain} akreditācijas datiem. Ja tavs konts ir mitināts citā serverī, tu nevarēsi pieteikties šeit. title: Pierakstīties %{domain} sign_up: + manual_review: Reģistrācijas domēnā %{domain} manuāli pārbauda mūsu moderatori. Lai palīdzētu mums apstrādāt tavu reģistrāciju, uzraksti mazliet par sevi un to, kāpēc vēlies kontu %{domain}. preamble: Izmantojot kontu šajā Mastodon serverī, tu varēsi sekot jebkurai citai personai tīklā neatkarīgi no tā, kur tiek mitināts viņas konts. title: Atļauj tevi iestatīt %{domain}. status: @@ -1035,18 +1122,6 @@ lv: view_strikes: Skati iepriekšējos brīdinājumus par savu kontu too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz. use_security_key: Lietot drošības atslēgu - authorize_follow: - already_following: Tu jau seko šim kontam - already_requested: Tu jau esi nosūtījis sekošanas pieteikumu šim kontam - error: Diemžēl, meklējot attālināto kontu, radās kļūda - follow: Sekot - follow_request: 'Tu esi nosūtījis sekošanas pieteikumu:' - following: 'Veiksmīgi! Tu tagad seko:' - post_follow: - close: Vai vienkārši aizver šo logu. - return: Parādīt lietotāja profilu - web: Doties uz tīmekli - title: Seko %{acct} challenge: confirm: Turpināt hint_html: "Padoms: Nākamās stundas laikā mēs tev vairs neprasīsim paroli." @@ -1123,6 +1198,10 @@ lv: your_appeal_rejected: Jūsu apelācija ir noraidīta domain_validator: invalid_domain: nav derīgs domēna nosaukums + edit_profile: + basic_information: Pamata informācija + hint_html: "Pielāgo to, ko cilvēki redz tavā publiskajā profilā un blakus tavām ziņām. Citas personas, visticamāk, sekos tev un sazināsies ar tevi, ja tev būs aizpildīts profils un profila attēls." + other: Cits errors: '400': Tevis iesniegtais pieprasījums bija nederīgs vai nepareizi izveidots. '403': Tev nav atļauts aplūkot šo lapu. @@ -1206,8 +1285,6 @@ lv: index: hint: Šis filtrs attiecas uz atsevišķu ziņu atlasi neatkarīgi no citiem kritērijiem. Šim filtram tu vari pievienot vairāk ziņu, izmantojot tīmekļa saskarni. title: Filtrētās ziņas - footer: - trending_now: Šobrīd tendences generic: all: Visi all_items_on_page_selected_html: @@ -1218,7 +1295,9 @@ lv: one: Atlasīts %{count} vienums, kas atbilst tavam meklēšanas vaicājumam. other: Atlasīti visi %{count} vienumi, kas atbilst tavam meklēšanas vaicājumam. zero: Atlasīts %{count} vienumu, kas atbilst tavam meklēšanas vaicājumam. + cancel: Atcelt changes_saved_msg: Izmaiņas veiksmīgi saglabātas! + confirm: Apstiprināt copy: Kopēt delete: Dzēst deselect: Atcelt visu atlasi @@ -1234,24 +1313,62 @@ lv: one: Kaut kas vēl nav īsti kārtībā! Lūdzu, pārskati zemāk norādīto kļūdu other: Kaut kas vēl nav īsti kārtībā! Lūdzu, pārskati %{count} kļūdas zemāk zero: "%{count} kļūdu" - html_validator: - invalid_markup: 'satur nederīgu HTML marķējumu: %{error}' imports: errors: + empty: Tukšs CSV fails + incompatible_type: Nesavietojams ar izvēlēto importēšanas veidu invalid_csv_file: 'Nederīgs CSV fails. Kļūda: %{error}' over_rows_processing_limit: satur vairāk, nekā %{count} rindas + too_large: Fails ir pārāk liels + failures: Kļūmes + imported: Importēti + mismatched_types_warning: Šķiet, ka šim importam esi izvēlējies nepareizu veidu. Lūdzu, pārbaudi vēlreiz. modes: merge: Apvienot merge_long: Saglabāt esošos ierakstus un pievienot jaunus overwrite: Pārrakstīt overwrite_long: Nomainīt pašreizējos ierakstus ar jauniem + overwrite_preambles: + blocking_html: Tu gatavojies aizstāt savu bloķēto sarakstu ar līdz pat %{total_items} kontiem no %{filename}. + bookmarks_html: Tu gatavojies aizstāt savas bloķētās izlases ar līdz pat %{total_items} ziņām no %{filename}. + domain_blocking_html: Tu gatavojies aizstāt savu bloķēto domēnu sarakstu ar līdz pat %{total_items} domēniem no %{filename}. + following_html: Tu gatavojies sekot līdz pat %{total_items} kontiem no %{filename} un pārtrauksi sekot citiem. + lists_html: Tu gatavojies aizstāt savus sarakstus ar %{filename} saturu. Līdz %{total_items} kontiem tiks pievienoti jauni saraksti. + muting_html: Tu gatavojies aizstāt savu noklusināto kontu sarakstu ar līdz pat %{total_items} kontiem no %{filename}. + preambles: + blocking_html: Tu gatavojies bloķēt līdz pat %{total_items} kontiem no %{filename}. + bookmarks_html: Tu gatavojies pievienot līdz pat %{total_items} ziņām no %{filename} savām grāmatzīmēm. + domain_blocking_html: Tu gatavojies bloķēt līdz pat %{total_items} domēniem no %{filename}. + following_html: Tu gatavojies sekot līdz pat %{total_items} kontiem no %{filename}. + lists_html: Tu gatavojies pievienot līdz pat %{total_items} kontiem no %{filename} saviem sarakstiem. Jauni saraksti tiks izveidoti, ja nav saraksta, ko pievienot. + muting_html: Tu gatavojies noklusināt līdz pat %{total_items} kontiem no %{filename}. preface: Tu vari importēt datus, kurus esi eksportējis no cita servera, piemēram, to personu sarakstu, kurām tu seko vai kuras bloķē. + recent_imports: Nesen importēts + states: + finished: Pabeigts + in_progress: Procesā + scheduled: Ieplānots + unconfirmed: Neapstiprināti + status: Statuss success: Tavi dati tika veiksmīgi augšupielādēti un tiks apstrādāti noteiktajā laikā + time_started: Sākuma laiks + titles: + blocking: Importē bloķētos kontus + bookmarks: Importē grāmatzīmes + domain_blocking: Importē bloķētos domēnus + following: Importē sekotos kontus + lists: Importē sarakstus + muting: Importē noklusinātos kontus + type: Importa veids + type_groups: + constructive: Seko un Grāmatzīmes + destructive: Bloķētie un noklusinātie types: blocking: Bloķēšanas saraksts bookmarks: Grāmatzīmes domain_blocking: Bloķēto domēnu saraksts - following: Sekojamo lietotāju saraksts + following: Turpmākais saraksts + lists: Saraksti muting: Apklusināto lietotāju saraksts upload: Augšupielādēt invites: @@ -1279,7 +1396,7 @@ lv: title: Uzaicināt cilvēkus lists: errors: - limit: Esi sasniedzis maksimālo sarakstu skaitu + limit: Jūs esat sasniedzis maksimālo sarakstu skaitu login_activities: authentication_methods: otp: divfaktoru autentifikācijas lietotne @@ -1291,6 +1408,21 @@ lv: failed_sign_in_html: Neizdevies pierakstīšanās mēģinājums ar %{method} no %{ip} (%{browser}) successful_sign_in_html: Veiksmīga pierakstīšanās ar %{method} no %{ip} (%{browser}) title: Autentifikācijas vēsture + mail_subscriptions: + unsubscribe: + action: Jā, atcelt abonēšanu + complete: Anulēts + confirmation_html: Vai tiešām vēlies atteikties no %{type} saņemšanas Mastodon vietnē %{domain} uz savu e-pastu %{email}? Tu vienmēr vari atkārtot abonēšanu, izmantojot e-pasta paziņojumu iestatījumus. + emails: + notification_emails: + favourite: iecienītākie paziņojuma e-pasti + follow: sekot paziņojuma e-pastiem + follow_request: sekot pieprasījuma e-pastiem + mention: pieminēt paziņojumu e-pastus + reblog: izcelt paziņojumu e-pastus + resubscribe_html: Ja anulē abonementu kļūdas dēļ, tu vari atkārtoti abonēt, izmantojot e-pasta paziņojumu iestatījumus. + success_html: Tu vairs nesaņemsi %{type} par Mastodon %{domain} uz tavu e-pastu %{email}. + title: Atcelt abonēšanu media_attachments: validations: images_and_video: Nevar pievienot videoklipu tādai ziņai, kura jau satur attēlus @@ -1344,7 +1476,7 @@ lv: favourite: body: 'Tavu ziņu izlasei pievienoja %{name}:' subject: "%{name} pievienoja tavu ziņu izlasei" - title: Jauns izcēlums + title: Jauna izlase follow: body: "%{name} tagad tev seko!" subject: "%{name} tagad tev seko" @@ -1370,6 +1502,7 @@ lv: update: subject: "%{name} rediģējis rakstu" notifications: + administration_emails: Administrators e-pasta paziņojumi email_events: E-pasta paziņojumu notikumi email_events_hint: 'Atlasi notikumus, par kuriem vēlies saņemt paziņojumus:' other_settings: Citu paziņojumu iestatījumi @@ -1406,12 +1539,22 @@ lv: expired: Aptauja jau ir beigusies invalid_choice: Izvēlētā balsošanas iespēja nepastāv over_character_limit: katrs nedrīkst būt garāks par %{max} rakstzīmēm + self_vote: Tu nevari balsot pats savā aptaujā too_few_options: jābūt vairāk nekā vienam vienumam too_many_options: nevar saturēt vairāk par %{max} vienumiem preferences: other: Citi posting_defaults: Publicēšanas noklusējuma iestatījumi public_timelines: Publiskās ziņu lentas + privacy: + hint_html: "Pielāgo, kā vēlies atrast savu profilu un ziņas. Dažādas Mastodon funkcijas var palīdzēt sasniegt plašāku auditoriju, ja tās ir iespējotas. Velti laiku, lai pārskatītu šos iestatījumus, lai pārliecinātos, ka tie atbilst tavam lietošanas gadījumam." + privacy: Privātums + privacy_hint_html: Kontrolē, cik daudz vēlies izpaust citu labā. Cilvēki atklāj interesantus profilus un lieliskas lietotnes, pārlūkojot citu cilvēku sekotājus un redzot, no kurām lietotnēm viņi izliek ziņas, taču tu, iespējams, vēlēsies to slēpt. + reach: Sasniedzamība + reach_hint_html: Kontrolē, vai vēlies, lai tevi atklātu un sekotu jauni cilvēki. Vai vēlies, lai tavas ziņas tiktu parādītas ekrānā Izpēte? Vai vēlies, lai citi cilvēki tevi redzētu savos ieteikumos? Vai vēlies automātiski pieņemt visus jaunos sekotājus vai arī tev ir pilnīga kontrole pār katru? + search: Meklēt + search_hint_html: Kontrolē, kā vēlies tikt atrasts. Vai vēlies, lai cilvēki tevi atrod pēc tā, ko esi publiski publicējis? Vai vēlies, lai cilvēki ārpus Mastodon atrastu tavu profilu, meklējot tīmeklī? Lūdzu, ņem vērā, ka nevar garantēt publiskas informācijas pilnīgu izslēgšanu no visām meklētājprogrammām. + title: Privātums un sasniedzamība privacy_policy: title: Privātuma Politika reactions: @@ -1424,6 +1567,7 @@ lv: confirm_remove_selected_followers: Vai tiešām vēlies noņemt atlasītos sekotājus? confirm_remove_selected_follows: Vai tiešām vēlies noņemt atlasītos sekojumus? dormant: Snaudošie + follow_failure: Nevarēja sekot dažiem atlasītajiem kontiem. follow_selected_followers: Sekot atlasītajiem sekotājiem followers: Sekotāji following: Seko @@ -1463,6 +1607,7 @@ lv: electron: Electron firefox: Firefox generic: Nezināms pārlūks + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1472,6 +1617,7 @@ lv: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Nezināms Pārlūks weibo: Weibo current_session: Pašreizējā sesija description: "%{browser} uz %{platform}" @@ -1484,9 +1630,10 @@ lv: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: nezināma platforma + unknown_platform: Nezināma Platforma windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1563,7 +1710,6 @@ lv: show_newer: Nekad nerādīt show_older: Rādīt senākus show_thread: Rādīt tematu - sign_in_to_participate: Lai piedalītos sarunā, pieraksties title: "%{name}: “%{quote}”" visibilities: direct: Tiešs @@ -1605,12 +1751,10 @@ lv: '7889238': 3 mēneši min_age_label: Vecuma slieksnis min_favs: Saglabāt ziņas izlsasē vismaz - min_favs_hint: Nedzēš nevienu tavu ziņu, kas ir saņēmusi vismaz tik daudz izlases. Atstāj tukšu, lai dzēstu ziņas neatkarīgi no to izlases skaita + min_favs_hint: Nedzēš nevienu jūsu ziņu, kas ir saņēmusi vismaz tik daudz izcēlumu. Atstājiet tukšu, lai dzēstu ziņas neatkarīgi no to izcēlumu skaita min_reblogs: Saglabāt ziņas izceltas vismaz min_reblogs_hint: Neizdzēš nevienu no tavām ziņām, kas ir izceltas vismaz tik reižu. Atstāj tukšu, lai dzēstu ziņas neatkarīgi no to izcēlumu skaita stream_entries: - pinned: Piespraustā ziņa - reblogged: izceltie sensitive_content: Sensitīvs saturs strikes: errors: @@ -1626,6 +1770,11 @@ lv: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Ir pārsniegta tulkošanas pakalpojuma izmantošanas kvota visā serverī. + too_many_requests: Pēdējā laikā tulkošanas pakalpojumā ir saņemts pārāk daudz pieprasījumu. two_factor_authentication: add: Pievienot disable: Atspējot 2FA @@ -1705,13 +1854,18 @@ lv: title: Laipni lūgts uz borta, %{name}! users: follow_limit_reached: Tu nevari sekot vairāk par %{limit} cilvēkiem + go_to_sso_account_settings: Dodies uz sava identitātes nodrošinātāja konta iestatījumiem invalid_otp_token: Nederīgs divfaktora kods otp_lost_help_html: Ja esi zaudējis piekļuvi abiem, tu vari sazināties ar %{email} seamless_external_login: Tu esi pieteicies, izmantojot ārēju pakalpojumu, tāpēc paroles un e-pasta iestatījumi nav pieejami. signed_in_as: 'Pierakstījies kā:' verification: - explanation_html: 'Tu vari apstiprināt sevi kā sava profila metadatos esošo saišu īpašnieku. Lai to izdarītu, saistītajā vietnē ir jābūt saitei uz tavu Mastodon profilu. Atpakaļsaitē jābūt atribūtam rel="me". Saites teksta saturam nav nozīmes. Šeit ir piemērs:' + extra_instructions_html: Padoms. saite tavā vietnē var būt neredzama. Svarīga daļa ir rel="me", kas novērš uzdošanos vietnēs ar lietotāju ģenerētu saturu. Tu vari pat lapas galvenē izmantot tagu link, nevis a, taču HTML ir jābūt pieejamam, neizpildot JavaScript. + here_is_how: Lūk, kā + hint_html: "Ikviens var apliecināt savu identitāti Mastodon. Pamatojoties uz atvērtiem tīmekļa standartiem, tagad un uz visiem laikiem bez maksas. Viss, kas tev nepieciešams, ir personīga vietne, pēc kuras cilvēki tevi atpazīst. Kad no sava profila izveidosi saiti uz šo vietni, mēs pārbaudīsim, vai vietne novirza atpakaļ uz tavu profilu, un tajā tiks parādīts vizuāls indikators." + instructions_html: Nokopē un ielīmē tālāk norādīto kodu savas vietnes HTML. Pēc tam pievieno savas vietnes adresi vienā no papildu laukiem savā profilā no cilnes "Rediģēt profilu" un saglabā izmaiņas. verification: Pārbaude + verified_links: Tavas verifikācijas saites webauthn_credentials: add: Pievienot jaunu drošības atslēgu create: diff --git a/config/locales/mk.yml b/config/locales/mk.yml index 9504dc972e..8b9144a988 100644 --- a/config/locales/mk.yml +++ b/config/locales/mk.yml @@ -1,10 +1 @@ ---- mk: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/ml.yml b/config/locales/ml.yml index ae39911456..5f8de52987 100644 --- a/config/locales/ml.yml +++ b/config/locales/ml.yml @@ -48,9 +48,6 @@ ml: all: എല്ലാം suspended: താൽക്കാലികമായി നിർത്തി title: മധ്യസ്ഥന്‍ - resend_confirmation: - send: സ്ഥിരീകരണ ഇമെയിൽ വീണ്ടും അയയ്ക്കുക - success: സ്ഥിരീകരണ ഇമെയിൽ വിജയകരമായി അയച്ചു! reset: പുനഃക്രമീകരിക്കുക reset_password: പാസ്‌വേഡ് പുനഃക്രമീകരിക്കുക search: തിരയുക @@ -79,16 +76,6 @@ ml: invites: filter: all: എല്ലാം - authorize_follow: - following: 'വിജയകരം! നിങ്ങൾ ഇപ്പോൾ പിന്തുടരുന്നു:' - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. filters: contexts: notifications: അറിയിപ്പുകൾ diff --git a/config/locales/mr.yml b/config/locales/mr.yml index 161e5e5717..fe1639c6a3 100644 --- a/config/locales/mr.yml +++ b/config/locales/mr.yml @@ -1,10 +1 @@ ---- mr: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 1fc856c64f..6d1ededbc4 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -89,6 +89,7 @@ ms: moderation: active: Aktif all: Semua + disabled: Dimatikan pending: Menunggu silenced: Terhad suspended: Digantungkan @@ -113,14 +114,16 @@ ms: redownloaded_msg: Berjaya segarkan semula profil %{username} daripada asalnya reject: Tolak rejected_msg: Berjaya menolak permohonan pendaftaran %{username} + remote_suspension_irreversible: Data akaun ini telah dipadamkan secara tidak dapat dipulihkan. + remote_suspension_reversible_hint_html: Akaun telah digantung pada server mereka dan data akan dialih keluar sepenuhnya pada %{date}. Sehingga itu, server jauh boleh memulihkan akaun ini tanpa sebarang kesan buruk. Jika anda ingin mengalih keluar semua data akaun dengan segera, anda boleh berbuat demikian di bawah. remove_avatar: Buang avatar remove_header: Buang pengepala removed_avatar_msg: Berjaya membuang imej avatar %{username} removed_header_msg: Berjaya membuang imej pengepala %{username} resend_confirmation: already_confirmed: Pengguna ini telah disahkan - send: Hantar semula e-mel pengesahan - success: E-mel pengesahan telah berjaya dihantar! + send: Hantar semula pautan pengesahan + success: Pautan pengesahan berjaya dihantar! reset: Tetapkan semula reset_password: Tetapkan semula kata laluan resubscribe: Langgan semula @@ -128,6 +131,7 @@ ms: search: Cari search_same_email_domain: Pengguna lain dengan domain e-mel yang sama search_same_ip: Pengguna lain dengan alamat IP yang sama + security: Keselamatan security_measures: only_password: Kata laluan sahaja password_and_2fa: Kata laluan dan 2FA @@ -371,6 +375,15 @@ ms: undo: Buang kebenaran persekutuan dengan domain domain_blocks: add_new: Tambah penyekatan domain baharu + confirm_suspension: + cancel: Batal + confirm: Gantung + permanent_action: Membuat asal penggantungan tidak akan memulihkan sebarang data atau perhubungan. + preamble_html: Anda akan menggantung %{domain} dan subdomainnya. + remove_all_data: Ini akan mengalih keluar semua kandungan, media dan data profil untuk akaun domain ini daripada sever anda. + stop_communication: Server anda akan berhenti berkomunikasi dengan server ini. + title: Sahkan blok domain untuk %{domain} + undo_relationships: Ini akan membuat asal sebarang hubungan ikut antara akaun server ini dan akaun anda. created_msg: Sekatan domain sedang diproses destroyed_msg: Sekatan domain telah diundurkan domain: Domain @@ -383,6 +396,7 @@ ms: create: Cipta sekatan hint: Sekatan domain tidak akan menghindarkan penciptaan entri akaun dalam pangkalan data, tetapi akan dikenakan kaedah penyederhanaan khusus tertentu pada akaun-akaun tersebut secara retroaktif dan automatik. severity: + desc_html: "Had akan menjadikan siaran daripada akaun di domain ini tidak kelihatan kepada sesiapa sahaja yang tidak mengikutinya. Tangguhkan akan mengalih keluar semua kandungan, media dan data profil untuk akaun domain ini daripada server anda. Gunakan Tiada jika anda hanya mahu menolak fail media." noop: Tiada silence: Hadkan suspend: Gantungkan @@ -416,6 +430,8 @@ ms: resolve: Menyelesaikan domain title: Sekat domain e-mel baharu no_email_domain_block_selected: Tiada sekatan domain e-mel diubah kerana tiada yang dipilih + not_permitted: Tidak dibenarkan + resolved_dns_records_hint_html: Nama domain diselesaikan kepada domain MX berikut, yang akhirnya bertanggungjawab untuk menerima e-mel. Menyekat domain MX akan menyekat pendaftaran daripada mana-mana alamat e-mel yang menggunakan domain MX yang sama, walaupun nama domain yang kelihatan berbeza. Berhati-hati untuk tidak menyekat penyedia e-mel utama. resolved_through_html: Diselesaikan melalui %{domain} title: Domain e-mel disekat export_domain_allows: @@ -424,7 +440,14 @@ ms: no_file: Tiada fail dipilih export_domain_blocks: import: + description_html: Anda akan mengimport senarai blok domain. Sila semak senarai ini dengan teliti, terutamanya jika anda belum mengarang senarai ini sendiri. existing_relationships_warning: Hubungan ikut sedia ada + private_comment_description_html: 'Untuk membantu anda menjejak dari mana datangnya blok yang diimport, blok yang diimport akan dibuat dengan ulasan peribadi berikut: %{comment}' + private_comment_template: Diimport daripada %{source} pada %{date} + title: Import blok domain + invalid_domain_block: 'Satu atau lebih blok domain telah dilangkau kerana ralat berikut: %{error}' + new: + title: Import blok domain no_file: Tiada fail yang dipilih follow_recommendations: description_html: "Saranan ikutan membantu pengguna baharu mencari kandungan menarik dengan cepat. Apabila pengguna belum cukup berinteraksi dengan akaun lain untuk membentuk saranan ikutan tersendiri, akaun-akaun inilah yang akan disarankan. Ia dinilai semula setiap hari dari gabungan keterlibatan tertinggi terkini dan juga jumlah pengikut tempatan tertinggi mengikut bahasa masing-masing." @@ -436,6 +459,12 @@ ms: unsuppress: Tetap semula saranan ikutan instances: availability: + description_html: + other: Jika penghantaran ke domain gagal %{count} hari tanpa berjaya, tiada percubaan penghantaran selanjutnya akan dibuat melainkan penghantaran dari domain diterima. + failure_threshold_reached: Ambang kegagalan dicapai pada %{date}. + failures_recorded: + other: Percubaan gagal pada %{count} hari. + no_failures_recorded: Tiada kegagalan dalam rekod. title: Ketersediaan warning: Percubaan terakhir untuk menyambung ke pelayan ini tidak berjaya back_to_all: Semua @@ -445,8 +474,13 @@ ms: confirm_purge: Adakah anda pasti mahu menghapuskan senarai ini secara kekal daripada domain ini? content_policies: comment: Catatan dalaman + description_html: Anda boleh menentukan dasar kandungan yang akan digunakan pada semua akaun daripada domain ini dan mana-mana subdomainnya. + limited_federation_mode_description_html: Anda boleh memilih sama ada untuk membenarkan persekutuan dengan domain ini. policies: + reject_media: Tolak media + reject_reports: Tolak laporan silence: Hadkan + suspend: Gantung policy: Dasar reason: Sebab awam title: Dasar kandungan @@ -456,6 +490,7 @@ ms: instance_followers_measure: pengikut kami di situ instance_follows_measure: pengikut mereka di sini instance_languages_dimension: Bahasa teratas + instance_media_attachments_measure: lampiran media yang disimpan instance_reports_measure: laporan mengenai mereka instance_statuses_measure: Hantaran yang disimpan delivery: @@ -468,19 +503,25 @@ ms: delivery_available: Penghantaran tersedia delivery_error_days: Hari ralat penghantaran delivery_error_hint: Jika penghantaran tidak berjaya selama %{count} hari, ia akan ditanda sebagai tidak boleh dihantar. + destroyed_msg: Data daripada %{domain} kini beratur untuk pemadaman segera. empty: Tiada domain dijumpai. + known_accounts: + other: "%{count} akaun dikenali" moderation: all: Semua limited: Terhad title: Penyederhanaan private_comment: Ulasan peribadi public_comment: Ulasan awam + purge: Singkir + purge_description_html: Jika anda percaya domain ini berada di luar talian selama-lamanya, anda boleh memadamkan semua rekod akaun dan data yang berkaitan daripada domain ini daripada storan anda. Ini mungkin mengambil sedikit masa. title: Persekutuan total_blocked_by_us: Disekati kami total_followed_by_them: Diikuti mereka total_followed_by_us: Diikuti kami total_reported: Laporan tentang mereka total_storage: Lampiran media + totals_time_period_hint_html: Jumlah yang dipaparkan di bawah termasuk data untuk sepanjang masa. invites: deactivate_all: Nyahaktifkan semua filter: @@ -534,15 +575,25 @@ ms: actions: delete_description_html: Hantaran yang dilaporkan akan dihapuskan dan pelanggaran itu akan direkodkan bagi membantu anda menguruskan pelanggaran pada akaun yang sama di masa akan datang. mark_as_sensitive_description_html: Media di dalam hantaran yang dilaporkan akan ditandakan sebagai sensitif dan pelanggaran itu akan direkodkan bagi membantu anda menguruskan pelanggaran pada akaun yang sama di masa akan datang. + other_description_html: Lihat lebih banyak pilihan untuk mengawal tingkah laku akaun dan menyesuaikan komunikasi ke akaun yang dilaporkan. resolve_description_html: Tiada tindakan akan diambil terhadap akaun yang dilaporkan, tiada pelanggaran direkodkan dan laporan akan ditutup. + silence_description_html: Akaun itu akan kelihatan hanya kepada mereka yang telah mengikutinya atau mencarinya secara manual, mengehadkan capaiannya dengan teruk. Sentiasa boleh dikembalikan. Menutup semua laporan terhadap akaun ini. + suspend_description_html: Akaun dan semua kandungannya akan tidak boleh diakses dan akhirnya dipadamkan, dan berinteraksi dengannya adalah mustahil. Boleh diterbalikkan dalam masa 30 hari. Menutup semua laporan terhadap akaun ini. + actions_description_html: Tentukan tindakan yang perlu diambil untuk menyelesaikan laporan ini. Jika anda mengambil tindakan menghukum terhadap akaun yang dilaporkan, pemberitahuan e-mel akan dihantar kepada mereka, kecuali apabila kategori Spam dipilih. + actions_description_remote_html: Tentukan tindakan yang perlu diambil untuk menyelesaikan laporan ini. Ini hanya akan menjejaskan cara serveranda berkomunikasi dengan akaun jauh ini dan mengendalikan kandungannya. add_to_report: Tambahkan lebih banyak pada laporan are_you_sure: Adakah anda pasti? assign_to_self: Menugaskan kepada saya assigned: Penyederhana yang ditugaskan by_target_domain: Domain bagi akaun yang dilaporkan + cancel: Batal category: Kumpulan + category_description_html: Sebab akaun dan/atau kandungan ini dilaporkan akan disebut dalam komunikasi dengan akaun yang dilaporkan comment: none: Tiada + comment_description_html: 'Untuk memberikan maklumat lanjut, %{name} menulis:' + confirm: Konfirm + confirm_action: Sahkan tindakan penyederhanaan terhadap @%{acct} created_at: Dilaporkan delete_and_resolve: Padam hantaran forwarded: Dipanjangkan @@ -558,6 +609,10 @@ ms: delete: Padam placeholder: Terangkan tindakan apa yang telah diambil, atau sebarang kemas kini lain yang berkaitan... title: Catatan + notes_description_html: Lihat dan tinggalkan nota kepada moderator lain dan diri masa depan anda + processed_msg: 'Laporan #%{id} berjaya diproses' + quick_actions_description_html: 'Ambil tindakan pantas atau tatal ke bawah untuk melihat kandungan yang dilaporkan:' + remote_user_placeholder: pengguna jauh dari %{instance} reopen: Buka semula laporan report: 'Laporan #%{id}' reported_account: Akaun yang dilaporkan @@ -567,9 +622,29 @@ ms: skip_to_actions: Langkau ke tindakan status: Status statuses: Kandungan yang dilaporkan + statuses_description_html: Kandungan yang menyinggung perasaan akan disebut dalam komunikasi dengan akaun yang dilaporkan + summary: + action_preambles: + delete_html: 'Anda akan mengalih keluar beberapa siaran @%{acct}. Ini akan:' + mark_as_sensitive_html: 'Anda akan menandai beberapa siaran @%{acct} sebagai sensitif. Ini akan:' + silence_html: 'Anda akan menghadkan akaun @%{acct}. Ini akan:' + suspend_html: 'Anda akan menggantung akaun @%{acct}. Ini akan:' + actions: + delete_html: Alih keluar pos yang menyinggung perasaan + mark_as_sensitive_html: Tandai media pos yang menyinggung perasaan sebagai sensitif + silence_html: Hadkan capaian @%{acct} dengan ketat dengan menjadikan profil dan kandungan mereka hanya kelihatan kepada orang yang sudah mengikuti mereka atau melihat profil itu secara manual + suspend_html: Gantung @%{acct}, menjadikan profil dan kandungan mereka tidak boleh diakses dan mustahil untuk berinteraksi dengannya + close_report: 'Tandai laporan #%{id} sebagai diselesaikan' + close_reports_html: Tandai semua laporan terhadap @%{acct} sebagai telah diselesaikan + delete_data_html: Padamkan profil dan kandungan @%{acct} 30 hari dari sekarang melainkan mereka dibatalkan penggantungan buat sementara waktu + preview_preamble_html: "@%{acct} akan menerima amaran dengan kandungan berikut:" + record_strike_html: Rakam bantahan terhadap @%{acct} untuk membantu anda mempertingkatkan tentang pelanggaran akaun ini pada masa hadapan + send_email_html: Hantar @%{acct} e-mel amaran + warning_placeholder: Penaakulan tambahan pilihan untuk tindakan penyederhanaan. target_origin: Asalan akaun yang dilaporkan title: Laporan unassign: Nyahtugaskan + unknown_action_msg: 'Tindakan tidak diketahui: %{action}' unresolved: Nyahselesaikan updated_at: Dikemaskini view_profile: Lihat profil @@ -584,12 +659,15 @@ ms: moderation: Penyederhanaan special: Khas delete: Padam + description_html: Dengan peranan pengguna, anda boleh menyesuaikan fungsi dan kawasan Mastodon yang boleh diakses oleh pengguna anda. edit: Sunting peranan '%{name}' everyone: Kebenaran lalai + everyone_full_description_html: Ini ialah peranan asas yang mempengaruhi semua pengguna, walaupun mereka yang tidak mempunyai peranan yang ditetapkan. Semua peranan lain mewarisi kebenaran daripadanya. permissions_count: other: "%{count} kebenaran" privileges: administrator: Pentadbir + administrator_description: Users with this permission will bypass every permission delete_user_data: Padamkan Data Pengguna delete_user_data_description: Membenarkan pengguna menghapuskan data pengguna lain tanpa bertangguh invite_users: Mengundang pengguna @@ -646,12 +724,24 @@ ms: preamble: Menyesuaikan antara muka web Mastodon. title: Penampilan branding: + preamble: Penjenamaan server anda membezakannya daripada server lain dalam rangkaian. Maklumat ini mungkin dipaparkan merentasi pelbagai persekitaran, seperti antara muka web Mastodon, aplikasi asli, dalam pratonton pautan di tapak web lain dan dalam aplikasi pemesejan, dan sebagainya. Atas sebab ini, adalah lebih baik untuk memastikan maklumat ini jelas, pendek dan padat. title: Penjenamaan + captcha_enabled: + desc_html: Ini bergantung pada skrip luaran daripada hCaptcha, yang mungkin menjadi kebimbangan keselamatan dan privasi. Selain itu, ini boleh menjadikan proses pendaftaran menjadi kurang dapat diakses oleh sesetengah orang (terutamanya orang kurang upaya). Atas sebab ini, sila pertimbangkan langkah alternatif seperti pendaftaran berasaskan kelulusan atau jemputan. + title: Memerlukan pengguna baharu menyelesaikan CAPTCHA untuk mengesahkan akaun mereka content_retention: + preamble: Kawal cara kandungan yang dijana pengguna disimpan dalam Mastodon. title: Pengekalan kandungan + default_noindex: + desc_html: Mempengaruhi semua pengguna yang tidak menukar tetapan ini sendiri + title: Tarik pengguna keluar daripada pengindeksan enjin carian secara lalai discovery: + follow_recommendations: Ikut cadangan + preamble: Memaparkan kandungan yang menarik adalah penting dalam memasukkan pengguna baharu yang mungkin tidak mengenali sesiapa Mastodon. Kawal cara pelbagai ciri penemuan berfungsi pada server anda. profile_directory: Direktori profil public_timelines: Garis masa awam + publish_discovered_servers: Terbitkan pelayan yang ditemui + publish_statistics: Terbitkan statistik title: Penemuan trends: Sohor kini domain_blocks: @@ -666,15 +756,22 @@ ms: approved: Kelulusan diperlukan untuk pendaftaran none: Tiada siapa boleh mendaftar open: Sesiapapun boleh mendaftar - title: Tetapan Pelayan + title: Tetapan server site_uploads: delete: Hapuskan fail yang dimuat naik destroyed_msg: Muat naik tapak berjaya dihapuskan! statuses: account: Penulis + application: Aplikasi + back_to_account: Kembali ke halaman akaun + back_to_report: Kembali ke halaman laporan + batch: + remove_from_report: Alih keluar daripada laporan + report: Laporan deleted: Dipadamkan favourites: Gemaran history: Sejarah versi + in_reply_to: Membalas kepada language: Bahasa media: title: Media @@ -686,6 +783,8 @@ ms: status_changed: Hantaran diubah title: Hantaran akaun trending: Sohor kini + visibility: Visibiliti + with_media: Dengan media strikes: actions: delete_statuses: "%{name} memadam hantaran %{target}" @@ -697,25 +796,80 @@ ms: suspend: "%{name} telah menggantungkan akaun %{target}" appeal_approved: Dirayu appeal_pending: Rayuan yang belum selesai + appeal_rejected: Rayuan ditolak + system_checks: + database_schema_check: + message_html: Terdapat migrasi pangkalan data yang belum selesai. Sila jalankannya untuk memastikan aplikasi berfungsi seperti yang diharapkan + elasticsearch_health_red: + message_html: Kelompok Elasticsearch tidak sihat (status merah), ciri carian tidak tersedia + elasticsearch_health_yellow: + message_html: Kelompok Elasticsearch tidak sihat (status kuning), anda mungkin ingin menyiasat sebabnya + elasticsearch_index_mismatch: + message_html: Pemetaan indeks Elasticsearch sudah lapuk. Sila jalankan tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Lihat dokumentasi + message_html: Kelompok Elasticsearch anda mempunyai lebih daripada satu nod, tetapi Mastodon tidak dikonfigurasikan untuk menggunakannya. + elasticsearch_preset_single_node: + action: Lihat dokumentasi + message_html: Kelompok Elasticsearch anda hanya mempunyai satu nod, ES_PRESET hendaklah ditetapkan kepada single_node_cluster. + elasticsearch_reset_chewy: + message_html: Indeks sistem Elasticsearch anda sudah lapuk kerana perubahan tetapan. Sila jalankan tootctl search deploy --reset-chewy untuk mengemas kininya. + elasticsearch_running_check: + message_html: Tidak dapat menyambung ke Elasticsearch. Sila semak sama ada ia sedang berjalan atau lumpuhkan carian teks penuh + elasticsearch_version_check: + message_html: 'Versi Elasticsearch tidak serasi: %{value}' + version_comparison: Elasticsearch %{running_version} sedang berjalan manakala %{required_version} diperlukan + rules_check: + action: Urus peraturan server + message_html: Anda belum menentukan sebarang peraturan server. + sidekiq_process_check: + message_html: Tiada proses Sidekiq berjalan untuk baris gilir %{value}. Sila semak konfigurasi Sidekiq anda + upload_check_privacy_error: + action: Semak di sini untuk maklumat lanjut + message_html: "Server web anda salah konfigurasi. Privasi pengguna anda berisiko" + upload_check_privacy_error_object_storage: + action: Semak di sini untuk maklumat lanjut + message_html: "Ruang objek anda salah konfigurasi. Privasi pengguna anda berisiko" tags: review: Semak status + updated_msg: Tetapan hashtag berjaya dikemas kini title: Pentadbiran trends: allow: Izin approved: Diluluskan + disallow: Tidak membenarkan links: allow: Membenarkan pautan allow_provider: Membenarkan penerbit + description_html: Ini ialah pautan yang sedang banyak dikongsi oleh akaun tempat server anda melihat siaran daripadanya. Ia boleh membantu pengguna anda mengetahui perkara yang berlaku di dunia. Tiada pautan dipaparkan secara terbuka sehingga anda meluluskan penerbit. Anda juga boleh membenarkan atau menolak pautan individu. + disallow: Tidak membenarkan pautan + disallow_provider: Tolak penerbit + no_link_selected: Tiada pautan ditukar kerana tiada pautan dipilih + publishers: + no_publisher_selected: Tiada penerbit ditukar kerana tiada penerbit dipilih + shared_by_over_week: + other: Dikongsi oleh %{count} orang sepanjang minggu lepas title: Pautan yang sedang sohor kini + usage_comparison: Dikongsi %{today} kali hari ini, berbanding %{yesterday} semalam + not_allowed_to_trend: Tidak dibenarkan menjadi trend + only_allowed: Hanya dibenarkan + pending_review: Menunggu semak semula preview_card_providers: + allowed: Pautan daripada penerbit ini boleh mengikut aliran + description_html: Ini adalah domain dari mana pautan sering dikongsi pada server anda. Pautan tidak akan menjadi aliran secara terbuka melainkan domain pautan itu diluluskan. Kelulusan (atau penolakan) anda dilanjutkan kepada subdomain. rejected: Pautan daripada penerbit ini tidak akan menjadi sohor kini title: Penerbit rejected: Ditolak statuses: allow: Izinkan hantaran allow_account: Izinkan penulis + description_html: Ini adalah post yang server anda tahu tentang yang sedang dikongsi dan menjadi kegemaran ramai pada masa ini. Ia boleh membantu pengguna baharu dan kembali anda mencari lebih ramai orang untuk diikuti. Tiada pos dipaparkan secara terbuka sehingga anda meluluskan pengarang dan pengarang membenarkan akaun mereka dicadangkan kepada orang lain. Anda juga boleh membenarkan atau menolak pos individu. disallow: Tidak membenarkan hantaran disallow_account: Tidak membenarkan penulis + no_status_selected: Tiada pos sohor kini ditukar kerana tiada yang dipilih + not_discoverable: Pengarang tidak mengikut serta untuk dapat ditemui + shared_by: + other: Dikongsi dan digemari %{friendly_count} kali title: Hantaran hangat tags: current_score: Markah semasa %{score} @@ -725,69 +879,227 @@ ms: tag_servers_dimension: Pelayan teratas tag_servers_measure: pelayan lain tag_uses_measure: penggunaan keseluruhan + description_html: Ini adalah hashtag yang kini muncul dalam banyak pos yang server anda lihat. Ia boleh membantu pengguna anda mengetahui perkara yang paling ramai dibincangkan pada masa ini. Tiada hashtag dipaparkan secara terbuka sehingga anda meluluskannya. listable: Boleh dicadangkan + no_tag_selected: Tiada tag ditukar kerana tiada yang dipilih + not_listable: Tidak akan dicadangkan + not_trendable: Tidak akan muncul di bawah sohor kini not_usable: Tidak boleh digunakan peaked_on_and_decaying: Di atas pada %{date}, kini menurun title: Tanda pagar sedang sohor kini trendable: Boleh muncul di bawah sohor kini trending_rank: 'Sohor kini #%{rank}' usable: Boleh digunakan + usage_comparison: Digunakan %{today} kali hari ini, berbanding %{yesterday} semalam + used_by_over_week: + other: Digunakan oleh %{count} orang sepanjang minggu lepas title: Sohor kini trending: Sohor kini warning_presets: + add_new: Tambah baharu delete: Padam + edit_preset: Edit pratetap amaran + empty: Anda belum menentukan sebarang pratetap amaran lagi. + title: Urus pratetap amaran webhooks: + add_new: Tambah titik akhir delete: Padam + description_html: "Webhook membolehkan Mastodon menolak pemberitahuan masa nyata tentang acara yang dipilih ke aplikasi anda sendiri, supaya aplikasi anda boleh mencetuskan reaksi secara automatik." + disable: Lumpuhkan + disabled: Dilumpuhkan + edit: Edit titik akhir + empty: You don't have any webhook endpoints configured yet. enable: Dayakan enabled: Aktif + enabled_events: + other: "%{count} acara yang didayakan" + events: Acara + new: Webhook baru + rotate_secret: Putar rahsia + secret: Menandatangani rahsia + status: Status + title: Webhook + webhook: Webhook admin_mailer: new_appeal: actions: + delete_statuses: untuk memadamkan pos mereka + disable: untuk membekukan akaun mereka + mark_statuses_as_sensitive: untuk menandakan pos mereka sebagai sensitif + none: amaran + sensitive: untuk menandakan akaun mereka sebagai sensitif silence: untuk mengehadkan akaun mereka + suspend: untuk menggantung akaun mereka + body: "%{target} sedang merayu keputusan penyederhanaan sebanyak %{action_taken_by} dari %{date}, iaitu %{type}. Mereka tulis:" + next_steps: Anda boleh meluluskan rayuan untuk membuat asal keputusan penyederhanaan atau mengabaikannya. + subject: "%{username} sedang merayu keputusan penyederhanaan pada %{instance}" + new_pending_account: + body: Butiran akaun baharu ada di bawah. Anda boleh meluluskan atau menolak aplikasi ini. + subject: Akaun baharu disediakan untuk semakan pada %{instance} (%{username}) + new_report: + body: "%{reporter} telah melaporkan %{target}" + body_remote: Seseorang daripada %{domain} telah melaporkan %{target} + subject: Laporan baharu untuk %{instance} (#%{id}) + new_trends: + body: 'Item berikut memerlukan semakan sebelum boleh dipaparkan secara terbuka:' + new_trending_links: + title: Pautan sohor kini + new_trending_statuses: + title: Pos sohor kini + new_trending_tags: + no_approved_tags: Pada masa ini tiada hashtag sohor kini yang diluluskan. + requirements: 'Mana-mana calon ini boleh melepasi hashtag arah aliran #%{rank} yang diluluskan, yang pada masa ini ialah #%{lowest_tag_name} dengan markah %{lowest_tag_score}.' + title: Hashtag sohor kini + subject: Trend baharu untuk kesemakan pada %{instance} + aliases: + add_new: Buat alias + created_msg: Berjaya mencipta alias baharu. Anda kini boleh memulakan perpindahan daripada akaun lama. + deleted_msg: Berjaya mengalih keluar alias. Beralih dari akaun itu ke akaun ini tidak akan dapat dilakukan lagi. + empty: Anda tidak mempunyai alias. + hint_html: Jika anda ingin beralih dari akaun lain ke akaun ini, di sini anda boleh membuat alias, yang diperlukan sebelum anda boleh meneruskan dengan memindahkan pengikut dari akaun lama ke akaun ini. Tindakan ini dengan sendirinya tidak berbahaya dan boleh diterbalikkan. Penghijrahan akaun dimulakan daripada akaun lama. + remove: Nyahpaut alias appearance: + advanced_web_interface: Antara muka web lanjutan + advanced_web_interface_hint: 'Jika anda ingin menggunakan keseluruhan lebar skrin anda, antara muka web lanjutan membolehkan anda mengkonfigurasi banyak lajur berbeza untuk melihat seberapa banyak maklumat pada masa yang sama seperti yang anda mahu: Laman Utama, pemberitahuan, garis masa bersekutu, sebarang bilangan senarai dan hashteg.' + animations_and_accessibility: Animasi dan kebolehaksesan + confirmation_dialogs: Dialog pengesahan + discovery: Penemuan localization: + body: Mastodon diterjemahkan oleh sukarelawan. + guide_link: https://crowdin.com/project/mastodon guide_link_text: Sesiapa sahaja boleh memberi sumbangan. sensitive_content: Kandungan sensitif application_mailer: notification_preferences: Tukar keutamaan e-mel + salutation: "%{name}," + settings: 'Tukar pilihan e-mel: %{link}' + unsubscribe: Nyahlanggan view: 'Lihat:' view_profile: Lihat profil view_status: Lihat hantaran + applications: + created: Aplikasi berjaya dibuat + destroyed: Aplikasi berjaya dipadamkan + logout: Log keluar + regenerate_token: Menjana semula token akses + token_regenerated: Token akses berjaya dijana semula + warning: Berhati-hati dengan data ini. Jangan sekali-kali berkongsi dengan sesiapa pun! + your_token: Token akses anda auth: - change_password: Kata laluan + apply_for_account: Minta akaun + captcha_confirmation: + help_html: Jika anda menghadapi masalah menyelesaikan CAPTCHA, anda boleh menghubungi kami melalui %{email} dan kami boleh membantu anda. + hint_html: Hanya satu perkara lagi! Kami perlu mengesahkan anda seorang manusia (ini supaya kami dapat mengelakkan spam!). Selesaikan CAPTCHA di bawah dan klik "Teruskan". + title: Pemeriksaan keselamatan + confirmations: + wrong_email_hint: Jika alamat e-mel itu tidak betul, anda boleh menukarnya dalam tetapan akaun. delete_account: Padam akaun + delete_account_html: Jika anda ingin memadamkan akaun anda, anda boleh teruskan ke sini. Anda akan diminta untuk pengesahan. description: + prefix_invited_by_user: "@%{name} menjemput anda untuk menyertai server Mastodon ini!" prefix_sign_up: Daftar pada Mastodon hari ini! + suffix: Dengan akaun, anda akan dapat mengikuti orang, menyiarkan kemas kini dan bertukar-tukar mesej dengan pengguna dari mana-mana server Mastodon dan banyak lagi! + didnt_get_confirmation: Tidak menerima pautan pengesahan? + dont_have_your_security_key: Tiada kunci keselamatan anda? forgot_password: Terlupa kata laluan anda? + invalid_reset_password_token: Token tetapan semula kata laluan tidak sah atau tamat tempoh. Sila minta yang baharu. + link_to_otp: Masukkan kod dua faktor dari telefon anda atau kod pemulihan + link_to_webauth: Gunakan peranti kunci keselamatan anda log_in_with: Daftar masuk dengan login: Daftar masuk logout: Daftar keluar migrate_account: Pindah kepada akaun lain + migrate_account_html: Jika anda ingin mengubah hala akaun ini kepada akaun lain, anda boleh konfigurasikannya di sini. or_log_in_with: Atau daftar masuk dengan + privacy_policy_agreement_html: Saya telah membaca dan bersetuju menerima dasar privasi + progress: + confirm: Sahkan E-mel + details: Maklumat anda + review: Ulasan kami + rules: Terima peraturan + providers: + cas: CAS + saml: SAML register: Daftar registration_closed: "%{instance} tidak menerima ahli-ahli baru" + resend_confirmation: Hantar semula pautan pengesahan + reset_password: Tetapkan semula kata laluan + rules: + accept: Terima + back: Kembali + invited_by: 'Anda boleh menyertai %{domain} terima kasih kepada jemputan yang anda terima daripada:' + preamble: Ini ditetapkan dan dikuatkuasakan oleh penyederhana %{domain}. + preamble_invited: Sebelum anda meneruskan, sila pertimbangkan peraturan asas yang ditetapkan oleh penyederhana %{domain}. + title: Beberapa peraturan asas. + title_invited: Anda telah dijemput. security: Keselamatan + set_new_password: Tetapkan kata laluan baharu + setup: + email_below_hint_html: Semak folder spam anda atau minta folder lain. Anda boleh membetulkan alamat e-mel anda jika ia salah. + email_settings_hint_html: Klik pautan yang kami hantar kepada anda untuk mengesahkan %{email}. Kami akan tunggu di sini. + link_not_received: Tidak mendapat pautan? + new_confirmation_instructions_sent: Anda akan menerima e-mel baharu dengan pautan pengesahan dalam beberapa minit! + title: Semak peti masuk anda + sign_in: + preamble_html: Log masuk dengan bukti kelayakan %{domain} anda. Jika akaun anda dihoskan pada server lain, anda tidak akan dapat log masuk di sini. + title: Log masuk ke %{domain} + sign_up: + manual_review: Pendaftaran pada %{domain} melalui semakan manual oleh penyederhana kami. Untuk membantu kami memproses pendaftaran anda, tulis sedikit tentang diri anda dan sebab anda mahukan akaun di %{domain}. + preamble: Dengan akaun pada server Mastodon ini, anda akan dapat mengikuti mana-mana orang lain di rangkaian, tidak kira di mana akaun mereka dihoskan. + title: Mari sediakan anda pada %{domain}. status: account_status: Status akaun + confirming: Menunggu pengesahan e-mel untuk diselesaikan. + functional: Akaun anda beroperasi sepenuhnya. + pending: Permohonan anda sedang menunggu semakan oleh kakitangan kami. Ini mungkin mengambil sedikit masa. Anda akan menerima e-mel sekiranya permohonan anda diluluskan. + redirecting_to: Akaun anda tidak aktif kerana ia sedang mengubah hala ke %{acct}. view_strikes: Lihat pelanggaran yang lepas terhadap akaun anda + too_fast: Borang diserahkan terlalu cepat, cuba lagi. use_security_key: Gunakan kunci keselamatan - authorize_follow: - follow: Ikut - follow_request: 'Anda telah menghantar permintaan mengikut kepada:' - post_follow: - close: Atau anda boleh tutup tetingkap ini. - return: Tunjukkan profil pengguna - web: Pergi ke web - title: Ikuti %{acct} challenge: confirm: Teruskan + hint_html: "Petua: Kami tidak akan meminta kata laluan anda lagi untuk sejam berikutnya." invalid_password: Kata laluan tidak sah prompt: Sahkan kata laluan untuk teruskan + crypto: + errors: + invalid_key: bukan kunci Ed25519 atau Curve25519 yang sah + invalid_signature: bukan tandatangan Ed25519 yang sah + date: + formats: + default: "%b %d, %Y" + with_month_name: "%B %d, %Y" datetime: distance_in_words: + about_x_hours: "%{count}j" + about_x_months: "%{count}bln" + about_x_years: "%{count}thn" + almost_x_years: "%{count}thn" half_a_minute: Sebentar tadi + less_than_x_minutes: "%{count}m" + less_than_x_seconds: Baru sahaja + over_x_years: "%{count}thn" + x_days: "%{count}h" + x_minutes: "%{count}m" + x_months: "%{count}bln" + x_seconds: "%{count}s" deletes: + challenge_not_passed: Maklumat yang anda masukkan tidak betul + confirm_password: Masukkan kata laluan semasa anda untuk mengesahkan identiti anda + confirm_username: Masukkan nama pengguna anda untuk mengesahkan prosedur proceed: Padam akaun + success_msg: Akaun anda telah berjaya dipadamkan + warning: + before: 'Sebelum meneruskan, sila baca nota ini dengan teliti:' + caches: Kandungan yang telah dicache oleh server lain mungkin berterusan + data_removal: Pos anda dan data lain akan dialih keluar secara kekal + email_change_html: Anda boleh menukar alamat e-mel anda tanpa memadamkan akaun anda + email_contact_html: Jika ia masih tidak sampai, anda boleh menghantar e-mel kepada %{email} untuk mendapatkan bantuan + email_reconfirmation_html: Jika anda tidak menerima e-mel pengesahan, anda boleh memintanya semula + irreversible: Anda tidak akan dapat memulihkan atau mengaktifkan semula akaun anda + more_details_html: Untuk butiran lanjut, lihat dasar privasi. + username_available: Nama pengguna anda akan tersedia semula + username_unavailable: Nama pengguna anda akan kekal tidak tersedia disputes: strikes: action_taken: Tindakan diambil @@ -818,6 +1130,12 @@ ms: your_appeal_approved: Rayuan anda telah diluluskan your_appeal_pending: Anda telah menghantar rayuan your_appeal_rejected: Rayuan anda telah ditolak + domain_validator: + invalid_domain: bukan nama domain yang sah + edit_profile: + basic_information: Maklumat Asas + hint_html: "Sesuaikan perkara yang orang lihat pada profil awam anda dan di sebelah siaran anda. Orang lain lebih berkemungkinan mengikuti anda kembali dan berinteraksi dengan anda apabila anda mempunyai profil dan gambar profil yang telah diisi." + other: Lain-lain errors: '400': Permintaan yang anda serahkan tidak sah atau salah bentuk. '403': Anda tidak mempunyai kebenaran untuk melihat halaman ini. @@ -825,47 +1143,150 @@ ms: '406': Halaman ini tidak tersedia dalam format yang diminta. '410': Halaman yang anda cari tidak wujud di sini lagi. '422': + content: Pengesahan keselamatan gagal. Adakah anda menyekat kuki? title: Pengesahan keselamatan gagal '429': Terlalu banyak permintaan + '500': + content: Kami minta maaf, tetapi ada masalah di pihak kami. + title: Halaman ini tidak betul '503': Halaman tidak dapat disampaikan kerana kegagalan pelayan sementara. + noscript_html: Untuk menggunakan aplikasi web Mastodon, sila dayakan JavaScript. Sebagai alternatif, cuba salah satu apl asli untuk Mastodon untuk platform anda. + existing_username_validator: + not_found: tidak dapat mencari pengguna tempatan dengan nama pengguna itu + not_found_multiple: tidak dapat mencari %{usernames} exports: archive_takeout: + date: Tarikh + download: Muat turun arkib anda + hint_html: Anda boleh meminta arkib pos dan media yang dimuat naik anda. Data yang dieksport akan berada dalam format ActivityPub, boleh dibaca oleh mana-mana perisian yang mematuhi. Anda boleh meminta arkib setiap 7 hari. in_progress: Mengkompil arkib anda... request: Minta arkib anda + size: Saiz + blocks: Blok anda + bookmarks: Penanda buku csv: CSV domain_blocks: Domain disekat lists: Senarai + mutes: Awak bisu + storage: Storan Media + featured_tags: + add_new: Tambah baharu + errors: + limit: Anda telah memaparkan bilangan maksimum hashtag + hint_html: "Tampilkan hashtag paling penting anda pada profil anda. Alat yang hebat untuk menjejaki karya kreatif dan projek jangka panjang anda, hashtag yang ditampilkan dipaparkan dengan jelas pada profil anda dan membenarkan akses pantas kepada pos anda sendiri." filters: contexts: account: Profil + home: Rumah dan senarai notifications: Pemberitahuan + public: Garis masa awam + thread: Perbualan edit: add_keyword: Tambah kata kunci keywords: Kata kunci + statuses: Pos individu + statuses_hint_html: Penapis ini digunakan untuk memilih pos individu tanpa mengira sama ada ia sepadan dengan kata kunci di bawah. Semak atau alih keluar siaran daripada penapis. title: Sunting penapis + errors: + deprecated_api_multiple_keywords: Parameter ini tidak boleh ditukar daripada aplikasi ini kerana ia digunakan pada lebih daripada satu kata kunci penapis. Gunakan aplikasi yang lebih terkini atau antara muka web. + invalid_context: Tiada atau konteks tidak sah dibekalkan index: + contexts: Penapis dalam %{contexts} + delete: Padam empty: Anda tiada penapis. + expires_in: Tamat tempoh dalam %{distance} + expires_on: Tamat tempoh pada %{date} keywords: other: "%{count} kata kunci" statuses: other: "%{count} hantaran" + statuses_long: + other: "%{count} pos individu disembunyikan" title: Penapis new: save: Simpan penapis baru title: Tambah penapis baru statuses: back_to_filter: Balik kepada penapis + batch: + remove: Alih keluar daripada penapis index: + hint: Penapis ini digunakan untuk memilih pos individu tanpa mengira kriteria lain. Anda boleh menambah lebih banyak siaran pada penapis ini daripada antara muka web. title: Hantaran ditapis generic: all: Semua + cancel: Batal + changes_saved_msg: Perubahan berjaya disimpan! + confirm: Konfirm copy: Salin delete: Padam deselect: Nyahpilih semua none: Tiada + order_by: Disusun mengikut + save_changes: Simpan perubahan + today: hari ini + validation_errors: + other: Ada yang belum betul! Sila semak %{count} ralat di bawah imports: + errors: + empty: Fail CSV kosong + incompatible_type: Tidak serasi dengan jenis import yang dipilih + invalid_csv_file: 'Fail CSV tidak sah. Ralat: %{error}' + over_rows_processing_limit: mengandungi lebih daripada %{count} baris + too_large: Fail terlalu besar + failures: Kegagalan + imported: Diimport + mismatched_types_warning: Nampaknya anda mungkin telah memilih jenis yang salah untuk import ini, sila semak semula. + modes: + merge: Gabung + merge_long: Simpan rekod sedia ada dan tambah rekod baharu + overwrite: Tulis ganti + overwrite_long: Gantikan rekod semasa dengan yang baharu + overwrite_preambles: + blocking_html: Anda akan menggantikan senarai blok anda dengan sehingga %{total_items} akaun daripada %{filename}. + bookmarks_html: Anda akan menggantikan penanda halaman anda dengan sehingga %{total_items} siaran daripada %{filename}. + domain_blocking_html: Anda akan menggantikan senarai blok domain anda dengan sehingga %{total_items} domain daripada %{filename}. + following_html: Anda akan mengikuti sehingga %{total_items} akaun daripada %{filename} dan berhenti mengikuti orang lain. + lists_html: Anda akan menggantikan senarai anda dengan kandungan %{filename}. Sehingga %{total_items} akaun akan ditambahkan pada senarai baharu. + muting_html: Anda akan menggantikan senarai akaun yang diredamkan dengan sehingga %{total_items} akaun daripada %{filename}. + preambles: + blocking_html: Anda akan menyekat sehingga %{total_items} akaun daripada %{filename}. + bookmarks_html: Anda akan menambah sehingga %{total_items} pos daripada %{filename} ke penanda halaman anda. + domain_blocking_html: Anda akan menyekat sehingga %{total_items} domain daripada %{filename}. + following_html: Anda akan mengikuti sehingga %{total_items} akaun daripada %{filename}. + lists_html: Anda akan menambah sehingga %{total_items} akaun daripada %{filename} ke senarai anda. Senarai baharu akan dibuat jika tiada senarai untuk ditambah. + muting_html: Anda akan membisukan sehingga %{total_items} akaun daripada %{filename}. + preface: Anda boleh mengimport data yang telah anda eksport dari server lain, seperti senarai orang yang anda ikuti atau sekat. + recent_imports: Import terkini + states: + finished: Selesai + in_progress: Dalam proses + scheduled: Dijadualkan + unconfirmed: Tidak disahkan + status: Status + success: Data anda telah berjaya dimuat naik dan akan diproses dalam masa yang ditetapkan + time_started: Mula pada + titles: + blocking: Mengimport akaun yang disekat + bookmarks: Mengimport penanda halaman + domain_blocking: Mengimport domain yang disekat + following: Mengimport akaun diikuti + lists: Mengimport senarai + muting: Mengimport akaun diredam + type: Jenis import + type_groups: + constructive: Ikutan & Penanda Halaman + types: + blocking: Senarai menyekat + bookmarks: Penanda buku + domain_blocking: Senarai sekatan domain + following: Senarai berikut + lists: Senarai + muting: Senyapkan senarai upload: Muat naik invites: + delete: Nyahaktifkan + expired: Tamat tempoh expires_in: '1800': 30 minit '21600': 6 jam @@ -874,35 +1295,215 @@ ms: '604800': Seminggu '86400': Sehari expires_in_prompt: Jangan + generate: Hasilkan pautan jemputan + invited_by: 'Anda telah dijemput oleh:' + max_uses_prompt: Tiada had + prompt: Jana dan kongsi pautan dengan orang lain untuk memberikan akses kepada server ini + table: + expires_at: Tamat Tempoh + uses: Kegunaan + title: Jemput orang + lists: + errors: + limit: Anda telah mencapai bilangan maksimum senarai login_activities: authentication_methods: + otp: aplikasi pengesahan dua faktor password: kata laluan sign_in_token: e-mel kod keselamatan webauthn: kunci keselamatan + description_html: Jika anda melihat aktiviti yang anda tidak kenali, pertimbangkan untuk menukar kata laluan anda dan dayakan pengesahan dua faktor. + empty: Tiada sejarah pengesahan tersedia + failed_sign_in_html: Percubaan log masuk gagal dengan %{method} daripada %{ip} (%{browser}) + successful_sign_in_html: Log masuk yang berjaya dengan %{method} daripada %{ip} (%{browser}) + title: Sejarah pengesahan + mail_subscriptions: + unsubscribe: + action: Ya, nyahlanggan + complete: Menyahlanggan + confirmation_html: Adakah anda pasti mahu berhenti melanggan daripada menerima %{type} untuk Mastodon pada %{domain} ke e-mel anda di %{email}? Anda sentiasa boleh melanggan semula daripada tetapan pemberitahuan e-mel anda. + emails: + notification_emails: + favourite: e-mel pemberitahuan kegemaran + follow: ikuti e-mel notifikasi + follow_request: ikuti e-mel permintaan + mention: menyebut e-mel pemberitahuan + reblog: meningkatkan e-mel notifikasi + resubscribe_html: Jika anda tersilap menyahlanggan, anda boleh melanggan semula daripada tetapan pemberitahuan e-mel anda. + success_html: Anda tidak lagi akan menerima %{type} untuk Mastodon pada %{domain} ke e-mel anda di %{email}. + title: Hentikan langganan + media_attachments: + validations: + images_and_video: Tidak boleh melampirkan video pada pos yang sudah mengandungi imej + not_ready: Tidak boleh melampirkan fail yang belum selesai diproses. Cuba lagi sebentar lagi! + too_many: Tidak boleh melampirkan lebih daripada 4 fail migrations: acct: Dipindah ke + cancel: Batalkan ubah hala + cancel_explanation: Membatalkan ubah hala akan mengaktifkan semula akaun semasa anda, tetapi tidak akan mengembalikan pengikut yang telah dialihkan ke akaun tersebut. + cancelled_msg: Berjaya membatalkan ubah hala. + errors: + already_moved: ialah akaun yang sama yang telah anda pindahkan + missing_also_known_as: bukan alias untuk akaun ini + move_to_self: tidak boleh menjadi akaun semasa + not_found: tidak dapat dicarikan + followers_count: Pengikut semasa bergerak + incoming_migrations: Beralih dari akaun lain + incoming_migrations_html: Untuk beralih dari akaun lain ke akaun ini, mula-mula anda perlu membuat alias akaun. + moved_msg: Akaun anda kini mengubah hala ke %{acct} dan pengikut anda sedang dialihkan. + not_redirecting: Akaun anda tidak mengubah hala ke mana-mana akaun lain pada masa ini. + on_cooldown: Anda telah memindahkan akaun anda baru-baru ini. Fungsi ini akan tersedia semula dalam %{count} hari. + past_migrations: Penghijrahan yang lalu proceed_with_move: Pindah pengikut + redirected_msg: Akaun anda kini mengubah hala ke %{acct}. + redirecting_to: Akaun anda mengubah hala ke %{acct}. + set_redirect: Tetapkan ubah hala + warning: + backreference_required: Akaun baharu mesti terlebih dahulu dikonfigurasikan untuk merujuk semula akaun ini + before: 'Sebelum meneruskan, sila baca nota ini dengan teliti:' + cooldown: Selepas berpindah terdapat tempoh menunggu di mana anda tidak akan dapat bergerak lagi + 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 + move_handler: + carry_blocks_over_text: Pengguna ini berpindah dari %{acct}, yang telah anda sekat. + carry_mutes_over_text: Pengguna ini berpindah dari %{acct}, yang telah anda redamkan. + copy_account_note_text: 'Pengguna ini berpindah dari %{acct}, berikut ialah nota anda yang terdahulu tentang mereka:' + navigation: + toggle_menu: Togol menu notification_mailer: + admin: + report: + subject: "%{name} menyerahkan laporan" + sign_up: + subject: "%{name} telah mendaftar" + favourite: + body: 'Pos anda telah digemari oleh %{name}:' + subject: "%{name} menggemari siaran anda" + title: Kegemaran baru follow: + body: "%{name} kini mengikuti anda!" + subject: "%{name} kini mengikuti anda" title: Pengikut baru follow_request: + action: Urus permintaan ikut + body: "%{name} telah meminta untuk mengikuti anda" + subject: 'Pengikut belum selesai: %{name}' title: Permintaan ikutan baru mention: action: Balas + body: 'Anda telah disebut oleh %{name} dalam:' + subject: Anda telah disebut oleh %{name} + title: Sebutan baru + poll: + subject: Tinjauan pendapat oleh %{name} telah tamat + reblog: + body: 'Siaran anda telah dirangsang oleh %{name}:' + subject: "%{name} meningkatkan siaran anda" + title: Rangsangan baru + status: + subject: "%{name} baru sahaja diposkan" update: subject: "%{name} telah menyunting satu hantaran" + notifications: + administration_emails: Notifikasi e-mel pentadbir + email_events: Acara untuk pemberitahuan e-mel + email_events_hint: 'Pilih acara yang ingin anda terima pemberitahuan:' + other_settings: Tetapan notifikasi lain + number: + human: + decimal_units: + format: "%n%u" + units: + billion: B + million: J + quadrillion: Q + thousand: K + trillion: T + otp_authentication: + code_hint: Masukkan kod yang dijana oleh apl pengesah anda untuk mengesahkan + description_html: Jika anda mendayakan pengesahan dua faktor menggunakan apl pengesah, log masuk memerlukan anda untuk memiliki telefon anda, yang akan menjana token untuk anda masukkan. + enable: Dayakan + instructions_html: "Imbas kod QR ini ke dalam Google Authenticator atau apl TOTP serupa pada telefon anda. Mulai sekarang, aplikasi itu akan menjana token yang perlu anda masukkan semasa log masuk." + manual_instructions: 'Jika anda tidak dapat mengimbas kod QR dan perlu memasukkannya secara manual, berikut ialah rahsia teks biasa:' + setup: Sediakan + wrong_code: Kod yang dimasukkan adalah tidak sah! Adakah masa server dan masa peranti betul? + pagination: + newer: Lebih baharu + next: Seterusnya + older: Lebih lama + prev: Sebelum ini + truncate: "…" + polls: + errors: + already_voted: Anda telah pun mengundi pada tinjauan pendapat ini + duplicate_options: mengandungi item pendua + duration_too_long: terlalu jauh ke masa hadapan + duration_too_short: terlalu cepat + expired: Undian telah pun tamat + invalid_choice: Pilihan undi yang dipilih tidak wujud + over_character_limit: tidak boleh lebih panjang daripada %{max} aksara setiap satu + self_vote: Anda tidak boleh mengundi dalam tinjauan pendapat anda sendiri + too_few_options: mesti mempunyai lebih daripada satu item + too_many_options: tidak boleh mengandungi lebih daripada %{max} item + preferences: + other: Lain-lain + posting_defaults: Penyiaran lalai + public_timelines: Garis masa awam + privacy: + hint_html: "Sesuaikan cara anda mahu profil anda dan pos anda ditemui. Pelbagai ciri dalam Mastodon boleh membantu anda menjangkau khalayak yang lebih luas apabila didayakan. Luangkan sedikit masa untuk menyemak tetapan ini untuk memastikan ia sesuai dengan kes penggunaan anda." + privacy: Privasi + privacy_hint_html: Kawal berapa banyak yang anda ingin dedahkan untuk manfaat orang lain. Orang ramai menemui profil menarik dan apl hebat dengan menyemak imbas ikutan orang lain dan melihat apl mana yang mereka siarkan, tetapi anda mungkin lebih suka menyembunyikannya. + reach: Tercapai + reach_hint_html: Kawal sama ada anda ingin ditemui dan diikuti oleh orang baharu. Adakah anda mahu pos anda dipaparkan pada skrin Teroka? Adakah anda mahu orang lain melihat anda dalam pengesyoran ikutan mereka? Adakah anda mahu menerima semua pengikut baharu secara automatik atau mempunyai kawalan terperinci ke atas setiap pengikut? + search: Cari + search_hint_html: Kawal cara anda ingin ditemui. Adakah anda mahu orang mencari anda melalui perkara yang anda siarkan secara terbuka? Adakah anda mahu orang di luar Mastodon mencari profil anda semasa mencari di web? Harap maklum bahawa jumlah pengecualian daripada semua enjin carian tidak boleh dijamin untuk maklumat awam. + title: Privasi dan capaian privacy_policy: title: Dasar Privasi + reactions: + errors: + limit_reached: Had tindak balas yang berbeza dicapai + unrecognized_emoji: bukan emoji yang diiktiraf relationships: + activity: Aktiviti akaun + confirm_follow_selected_followers: Adakah anda pasti mahu mengikuti pengikut yang dipilih? + confirm_remove_selected_followers: Adakah anda pasti mahu mengalih keluar pengikut yang dipilih? + confirm_remove_selected_follows: Adakah anda pasti mahu mengalih keluar mengikuti yang dipilih? + dormant: Tidak aktif + follow_failure: Tidak dapat mengikuti beberapa akaun yang dipilih. follow_selected_followers: Ikut pengikut yang dipilih followers: Pengikut following: Ikutan + invited: Dijemput last_active: Terakhir aktif most_recent: Terkini + moved: Dipindah + mutual: Saling setuju + primary: Utama relationship: Hubungan + remove_selected_domains: Alih keluar semua pengikut daripada domain yang dipilih + remove_selected_followers: Alih keluar pengikut yang dipilih + remove_selected_follows: Nyahikut pengguna yang dipilih status: Status akaun + remote_follow: + missing_resource: Tidak dapat mencari URL ubah hala yang diperlukan untuk akaun anda + reports: + errors: + invalid_rules: tidak merujuk peraturan yang sah rss: content_warning: 'Amaran kandungan:' + descriptions: + account: Pos awam daripada @%{acct} + tag: 'Siaran awam ditandakan #%{hashtag}' + scheduled_statuses: + over_daily_limit: Anda telah melebihi had %{limit} pos berjadual untuk hari ini + over_total_limit: Anda telah melebihi had %{limit} pos berjadual + too_soon: Tarikh yang dijadualkan mestilah pada masa hadapan sessions: activity: Aktiviti terakhir browser: Pelayar @@ -910,28 +1511,59 @@ ms: alipay: Alipay blackberry: BlackBerry chrome: Chrome + edge: Microsoft Edge + electron: Electron + firefox: Firefox + generic: Pelayar yang tidak diketahui + huawei_browser: Pelayar Huawei + ie: Internet Explorer + micro_messenger: MicroMessenger + nokia: Pelayar Nokia S40 Ovi opera: Opera otter: Otter + phantom_js: PhantomJS + qq: Pelayar QQ safari: Safari + uc_browser: Pelayar UC + unknown_browser: Pelayar yang tidak diketahui + weibo: Weibo current_session: Sesi sekarang description: "%{browser} pada %{platform}" explanation: Pelayar-pelayar web berikut sedang didaftar masuk pada akaun Mastodon anda. ip: IP platforms: + adobe_air: Adobe Air android: Android + blackberry: BlackBerry + chrome_os: ChromeOS + firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux - other: platform tidak dikenali + mac: macOS + unknown_platform: Platform yang tidak diketahui + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone + revoke: Batalkan + revoke_success: Sesi berjaya dibatalkan title: Sesi + view_authentication_history: Lihat sejarah pengesahan akaun anda settings: account: Akaun account_settings: Tetapan akaun + aliases: Alias ​​akaun + appearance: Penampilan + authorized_apps: Apl yang dibenarkan + back: Kembali ke Mastodon delete: Pemadaman akaun + development: Pembangunan edit_profile: Sunting profil export: Eksport data featured_tags: Tanda pagar terpilih import: Import import_and_export: Import dan eksport + migrate: Penghijrahan akaun notifications: Pemberitahuan preferences: Keutamaan profile: Profil @@ -941,22 +1573,65 @@ ms: two_factor_authentication: Pengesahan Dua Faktor webauthn_authentication: Kunci keselamatan statuses: + attached: + audio: + other: "%{count} audio" + description: 'Dilampirkan: %{attached}' + image: + other: "%{count} imej" + video: + other: "%{count} video" + boosted_from_html: Dirangsang daripada %{acct_link} content_warning: 'Amaran kandungan: %{warning}' default_language: Sama dengan bahasa antara muka + disallowed_hashtags: + other: 'mengandungi hashtag yang tidak dibenarkan: %{tags}' edited_at_html: Disunting %{date} + errors: + in_reply_not_found: Pos yang anda cuba balas nampaknya tidak wujud. + open_in_web: Buka dalam web + over_character_limit: had aksara %{max} melebihi + pin_errors: + direct: Pos yang hanya boleh dilihat oleh pengguna yang disebut tidak boleh disematkan + limit: Anda telah menyematkan bilangan maksimum pos + ownership: Siaran orang lain tidak boleh disematkan + reblog: Rangsangan tidak boleh disematkan poll: + total_people: + other: "%{count} orang" + total_votes: + other: "%{count} undi" vote: Undi - sign_in_to_participate: Daftar masuk untuk menyertai perbualan + show_more: Tunjuk lebih banyak + show_newer: Tunjuk lebih baharu + show_older: Tunjuk lebih tua + show_thread: Tunjuk bebenang + title: '%{name}: "%{quote}"' visibilities: direct: Terus private: Pengikut sahaja + private_long: Hanya tunjukkan kepada pengikut public: Awam public_long: Semua orang boleh melihat unlisted: Tidak tersenarai + unlisted_long: Semua orang boleh melihat, tetapi tidak disenaraikan pada garis masa awam statuses_cleanup: enabled: Padam hantaran lama secara automatik + enabled_hint: Memadamkan pos anda secara automatik setelah mereka mencapai ambang umur yang ditentukan, melainkan ia sepadan dengan salah satu pengecualian di bawah + exceptions: Pengecualian + explanation: Oleh kerana pemadaman pos adalah operasi yang mahal, ini dilakukan perlahan-lahan dari semasa ke semasa apabila server tidak sibuk. Atas sebab ini, pos anda mungkin dipadamkan seketika selepas ia mencapai ambang umur. + ignore_favs: Abaikan kegemaran + ignore_reblogs: Abaikan rangsangan + interaction_exceptions: Pengecualian berdasarkan interaksi + interaction_exceptions_explanation: Sila ambil perhatian bahawa tiada jaminan untuk pos dipadamkan jika ia berada di bawah ambang kegemaran atau tingkatkan selepas sekali melepasinya. + keep_direct: Simpan mesej langsung + keep_direct_hint: Tidak memadamkan sebarang mesej langsung anda + keep_media: Simpan siaran dengan lampiran media + keep_media_hint: Tidak memadamkan mana-mana pos anda yang mempunyai lampiran media keep_pinned: Simpan hantaran disemat keep_pinned_hint: Tidak memadamkan mana-mana hantaran yang anda sematkan + keep_polls: Kekalkan tinjauan pendapat + keep_polls_hint: Tidak memadamkan mana-mana tinjauan pendapat anda keep_self_bookmark: Simpan hantaran yang anda menandabuku keep_self_bookmark_hint: Tidak memadamkan hantaran anda jika anda sudah menandabukunya keep_self_fav: Simpan hantaran yang anda gemarkan @@ -970,40 +1645,136 @@ ms: '604800': Seminggu '63113904': 2 tahun '7889238': 3 bulan + min_age_label: Ambang umur min_favs: Simpan hantaran digemarkan sekurang-kurangnya - min_favs_hint: Tidak memadamkan mana-mana hantaran anda yang telah menerima sekurang-kurangnya jumlah gemaran ini. Biarkan kosong untuk memadamkan hantaran tanpa mengira nombor gemaran + min_favs_hint: Tidak memadamkan mana-mana pos anda yang telah menerima sekurang-kurangnya bilangan kegemaran ini. Biarkan kosong untuk memadamkan pos tanpa mengira bilangan kegemaran mereka + min_reblogs: Pastikan pos dipertingkatkan sekurang-kurangnya + min_reblogs_hint: Tidak memadamkan mana-mana pos anda yang telah dirangsang sekurang-kurangnya bilangan kali ini. Biarkan kosong untuk memadamkan pos tanpa mengira bilangan rangsangannya stream_entries: - pinned: Hantaran disemat sensitive_content: Kandungan sensitif strikes: errors: too_late: Rayuan pelanggaran ini sudah terlalu lambat + tags: + does_not_match_previous_name: tidak sepadan dengan nama sebelumnya + themes: + contrast: Mastodon (Kontras tinggi) + default: Mastodon (Gelap) + mastodon-light: Mastodon (Cahaya) + time: + formats: + default: "%b %d, %Y, %H:%M" + month: "%b %Y" + time: "%H:%M" + translation: + errors: + quota_exceeded: Kuota penggunaan seluruh server untuk perkhidmatan terjemahan telah melebihi. + too_many_requests: Terdapat terlalu banyak permintaan kepada perkhidmatan terjemahan baru-baru ini. two_factor_authentication: add: Tambah disable: Nyahdayakan 2FA + disabled_success: Pengesahan dua faktor berjaya dilumpuhkan edit: Sunting + enabled: Pengesahan dua faktor didayakan + enabled_success: Pengesahan dua faktor berjaya didayakan + generate_recovery_codes: Pengesahan dua faktor berjaya didayakan + lost_recovery_codes: Kod pemulihan membolehkan anda mendapatkan semula akses kepada akaun anda jika anda kehilangan telefon anda. Jika anda telah kehilangan kod pemulihan anda, anda boleh menjana semula kod tersebut di sini. Kod pemulihan lama anda akan menjadi tidak sah. methods: Kaedah dua faktor otp: App pengesahan + recovery_codes: Kod pemulihan sandaran + recovery_codes_regenerated: Kod pemulihan berjaya dijana semula + recovery_instructions_html: Jika anda pernah kehilangan akses kepada telefon anda, anda boleh menggunakan salah satu kod pemulihan di bawah untuk mendapatkan semula akses kepada akaun anda. Pastikan kod pemulihan selamat. Sebagai contoh, anda boleh mencetaknya dan menyimpannya bersama dokumen penting lain. + webauthn: Kunci keselamatan user_mailer: appeal_approved: action: Pergi ke akaun anda explanation: Rayuan pelanggaran yang dikemukakan pada %{appeal_date} terhadap akaun anda pada %{strike_date} telah diluluskan. Akaun anda kini dalam kedudukan yang baik. + subject: Rayuan anda dari %{date} telah diluluskan title: Rayuan diluluskan appeal_rejected: explanation: Rayuan pelanggaran yang dikemukakan pada %{appeal_date} terhadap akaun anda pada %{strike_date} telah ditolak. + subject: Rayuan anda dari %{date} telah ditolak title: Rayuan ditolak + backup_ready: + explanation: Anda meminta sandaran penuh akaun Mastodon anda. Ia kini sedia untuk dimuat turun! + subject: Arkib anda sedia untuk dimuat turun + title: Arkibkan bawa pulang suspicious_sign_in: + change_password: tukar kata laluan anda + details: 'Berikut ialah butiran log masuk:' + explanation: Kami telah mengesan log masuk ke akaun anda daripada alamat IP baharu. + further_actions_html: Jika ini bukan anda, kami mengesyorkan agar anda %{action} dengan segera dan dayakan pengesahan dua faktor untuk memastikan akaun anda selamat. + subject: Akaun anda telah diakses daripada alamat IP baharu title: Daftar masuk baru + warning: + appeal: Hantar rayuan + appeal_description: Jika anda percaya ini adalah satu kesilapan, anda boleh menyerahkan rayuan kepada kakitangan %{instance}. + categories: + spam: Spam + violation: Kandungan melanggar garis panduan komuniti berikut + explanation: + delete_statuses: Sesetengah pos anda didapati melanggar satu atau lebih garis panduan komuniti dan kemudiannya telah dialih keluar oleh penyederhana %{instance}. + disable: Anda tidak lagi boleh menggunakan akaun anda, tetapi profil anda dan data lain kekal utuh. Anda boleh meminta sandaran data anda, menukar tetapan akaun atau memadam akaun anda. + mark_statuses_as_sensitive: Sesetengah pos anda telah ditandakan sebagai sensitif oleh penyederhana %{instance}. Ini bermakna orang ramai perlu mengetik media dalam pos sebelum pratonton dipaparkan. Anda boleh menandai media sebagai sensitif sendiri apabila menyiarkan pada masa hadapan. + sensitive: Mulai sekarang, semua fail media anda yang dimuat naik akan ditandakan sebagai sensitif dan tersembunyi di sebalik amaran klik lalu. + silence: Anda masih boleh menggunakan akaun anda tetapi hanya orang yang sudah mengikuti anda akan melihat pos anda pada server ini dan anda mungkin dikecualikan daripada pelbagai ciri penemuan. Walau bagaimanapun, orang lain mungkin masih mengikuti anda secara manual. + suspend: Anda tidak lagi boleh menggunakan akaun anda dan profil anda serta data lain tidak lagi boleh diakses. Anda masih boleh log masuk untuk meminta sandaran data anda sehingga data dialih keluar sepenuhnya dalam masa kira-kira 30 hari, tetapi kami akan mengekalkan beberapa data asas untuk menghalang anda daripada mengelak daripada penggantungan. + reason: 'Sebab:' + statuses: 'Catatan yang dipetik:' + subject: + delete_statuses: Pos anda pada %{acct} telah dialih keluar + disable: Akaun %{acct} anda telah dibekukan + mark_statuses_as_sensitive: Pos anda pada %{acct} telah ditandakan sebagai sensitif + none: Amaran untuk %{acct} + sensitive: Pos anda di %{acct} akan ditandakan sebagai sensitif mulai sekarang + silence: Akaun %{acct} anda telah dihadkan + suspend: Akaun %{acct} anda telah digantung + title: + delete_statuses: Pos dialih keluar + disable: Akaun dibekukan + mark_statuses_as_sensitive: Pos ditandakan sebagai sensitif + none: Amaran + sensitive: Akaun ditandakan sebagai sensitif + silence: Akaun terhad + suspend: Akaun digantung welcome: + edit_profile_action: Sediakan profil + edit_profile_step: Anda boleh menyesuaikan profil anda dengan memuat naik gambar profil, menukar nama paparan anda dan banyak lagi. Anda boleh ikut serta untuk menyemak pengikut baharu sebelum mereka dibenarkan mengikuti anda. + explanation: Berikut ialah beberapa petua untuk anda bermula + final_action: Mula menyiarkan + final_step: 'Mula menyiarkan! Walaupun tanpa pengikut, pos awam anda mungkin dilihat oleh orang lain, contohnya pada garis masa tempatan atau dalam hashtag. Anda mungkin ingin memperkenalkan diri anda pada hashtag #introductions.' + full_handle: Pemegang penuh anda + full_handle_hint: Inilah yang anda akan beritahu rakan anda supaya mereka boleh menghantar mesej atau mengikuti anda dari server lain. subject: Selamat datang kepada Mastodon title: Selamat datang, %{name}! users: follow_limit_reached: Anda tidak boleh mengikut lebih daripada %{limit} orang + go_to_sso_account_settings: Pergi ke tetapan akaun pembekal identiti anda + invalid_otp_token: Kod dua faktor tidak sah + otp_lost_help_html: Jika anda kehilangan akses kepada kedua-duanya, anda boleh menghubungi %{email} + seamless_external_login: Anda telah log masuk melalui perkhidmatan luaran, jadi kata laluan dan tetapan e-mel tidak tersedia. signed_in_as: 'Didaftar masuk sebagai:' verification: + extra_instructions_html: Petua: Pautan di tapak web anda mungkin tidak kelihatan. Bahagian penting ialah rel="me" yang menghalang penyamaran pada tapak web dengan kandungan yang dijana pengguna. Anda juga boleh menggunakan tag link dalam pengepala halaman dan bukannya a, tetapi HTML mesti boleh diakses tanpa melaksanakan JavaScript. + here_is_how: Ini caranya + hint_html: "Mengesahkan identiti anda di Mastodon adalah untuk semua orang. Berdasarkan standard web terbuka, percuma kini dan selamanya. Apa yang anda perlukan ialah tapak web peribadi yang orang mengenali anda. Apabila anda memaut ke tapak web ini dari profil anda, kami akan menyemak sama ada tapak web tersebut memaut kembali ke profil anda dan menunjukkan penunjuk visual padanya." + instructions_html: Salin dan tampal kod di bawah ke dalam HTML tapak web anda. Kemudian tambahkan alamat tapak web anda ke dalam salah satu medan tambahan pada profil anda daripada tab "Edit profil" dan simpan perubahan. verification: Pengesahan + verified_links: Pautan anda yang disahkan webauthn_credentials: + add: Tambahkan kunci keselamatan baharu + create: + error: Terdapat masalah menambah kunci keselamatan anda. Sila cuba lagi. + success: Kunci keselamatan anda telah berjaya ditambahkan. + delete: Padam + delete_confirmation: Adakah anda pasti mahu memadamkan kunci keselamatan ini? + description_html: Jika anda mendayakan pengesahan kunci keselamatan, log masuk memerlukan anda menggunakan salah satu kunci keselamatan anda. + destroy: + error: Terdapat masalah memadamkan kunci keselamatan anda. Sila cuba lagi. + success: Kunci keselamatan anda telah berjaya dipadamkan. invalid_credential: Kunci keselamatan tidak sah + nickname_hint: Masukkan nama panggilan kunci keselamatan baharu anda + not_enabled: Anda belum mendayakan WebAuthn lagi not_supported: Pelayan ini tidak menyokong kunci keselamatan otp_required: Untuk menggunakan kunci keselamatan, sila mengaktifkan pengesahan dua faktor dahulu. registered_on: Didaftar pada %{date} diff --git a/config/locales/my.yml b/config/locales/my.yml index 0a0826a65b..8e01e82afe 100644 --- a/config/locales/my.yml +++ b/config/locales/my.yml @@ -1,18 +1,37 @@ --- my: about: + about_mastodon_html: အနာဂတ်အတွက်လူမှုကွန်ရက် - ကြော်ငြာများမရှိခြင်း၊ အဖွဲ့သားများအား စောင့်ကြည့်မှုမရှိခြင်း၊ ကျင့်ဝတ်ပိုင်းဆိုင်ရာစိတ်ချရခြင်းနှင့် ဗဟိုချုပ်ကိုင်မှုမရှိခြင်း၊ သင့်အချက်အလက်များကို သင်ကိုယ်တိုင် ပိုင်ဆိုင်သော Mastodon! + contact_missing: မသတ်မှတ်ထား + contact_unavailable: မရှိ + hosted_on: "%{domain} မှ လက်ခံဆောင်ရွက်ထားသော Mastodon" title: အကြောင်း accounts: follow: စောင့်ကြည့်မယ် followers: other: စောင့်ကြည့်သူ following: စောင့်ကြည့်နေသည် + instance_actor_flash: ဤအကောင့်သည် ဆာဗာကို ကိုယ်စားပြုသည့် အကောင့်တခုသာဖြစ်ပြီး မည်သည့်အသုံးပြုသူမှမဟုတ်ပါ။ ၎င်းကို Federation ရည်ရွယ်ချက်များအတွက် အသုံးပြုသည့်အတွက် ပိတ်ပင် ဆိုင်းငံ့ခြင်း မပြုသင့်ပါ။ last_active: နောက်ဆုံးအသုံးပြုခဲ့သည့်အချိန် + link_verified_on: ဤလင့်ခ်၏ ပိုင်ဆိုင်မှုကို %{date} တွင် စစ်ဆေးခဲ့သည် + nothing_here: ဒီနေရာတွင် ဘာမှ မရှိပါ! + pin_errors: + following: သင်ထောက်ခံလိုသော လူကို စောင့်ကြည့်ပြီးသားဖြစ်ရပါမည် posts: - other: ပို့စ်တင်မယ် + other: ပို့စ် posts_tab_heading: ပို့စ်များ admin: + account_actions: + action: ဆောင်ရွက်ရန် + title: "%{acct} စိစစ်မှုလုပ်ဆောင်ရန်" + account_moderation_notes: + create: မှတ်စု သိမ်း + created_msg: စိစစ်ခြင်းမှတ်စုကို ဖန်တီးပြီးပါပြီ။ + destroyed_msg: စိစစ်ခြင်းမှတ်စုကို ဖျက်ပစ်လိုက်ပါပြီ။ accounts: + add_email_domain_block: ဒိုမိန်းကိုပိတ်မည် + approve: အတည်ပြုပါ + approved_msg: "%{username} ၏ စာရင်းသွင်းခြင်းကို အတည်ပြုပြီးပါပြီ" are_you_sure: သေချာပါသလား။ avatar: ကိုယ်စားပြုရုပ်ပုံ by_domain: ဒိုမိန်း @@ -23,212 +42,1043 @@ my: new_email: အီးမေးလ်အသစ် submit: အီးမေးလ်ပြောင်းပါ။ title: "%{username} အတွက် အီးမေးလ်ပြောင်းပါ" + change_role: + changed_msg: အခန်းကဏ္ဍကို ပြောင်းလဲပြီးပါပြီ။ + label: အခန်းကဏ္ဍ ပြောင်းလဲရန် + no_role: အခန်းကဏ္ဍမရှိ + title: "%{username} အတွက် အခန်းကဏ္ဍပြောင်းပါ" confirm: အတည်ပြု confirmed: အတည်ပြုပြီးပါပြီ confirming: အတည်ပြုနေသည် custom: စိတ်ကြိုက် delete: အချက်အလက်များဖျက်ပါ deleted: ဖျက်ပြီးပါပြီ + demote: အဆင့်လျော့မည် + destroyed_msg: "%{username} ၏ အချက်အလက်ကို မကြာမီ ဖျက်ပါမည်" + disable: ရပ်တန့် + disable_sign_in_token_auth: အီးမေးတိုကင် အထောက်အထားပြခြင်းကို ပိတ်ပါ disable_two_factor_authentication: 2FA ကို ပိတ်ပါ + disabled: အကောင့်ပိတ်သိမ်းထားသည် + display_name: ဖော်ပြမည့်အမည် domain: ဒိုမိန်း edit: ပြင်ဆင်ရန် email: အီးမေးလ် + email_status: အီးမေးလ်အခြေအနေ + enable: မပိတ်သိမ်းထားသော + enable_sign_in_token_auth: အီးမေးတိုကင် စစ်မှန်ကြောင်းအတည်ပြုချက်ကို ဖွင့်ပါ enabled: ဖွင့်ထားသည် + enabled_msg: "%{username} ၏ အကောင့်ကို ပိတ်သိမ်းထားသည်" followers: စောင့်ကြည့်သူများ + follows: စောင့်ကြည့်မယ် + header: မျက်နှာဖုံးပုံ + inbox_url: Inbox URL + invite_request_text: ပါဝင်ရခြင်း အကြောင်းအရင်း + invited_by: ဖိတ်ခေါ်ထားသည် ip: IP + joined: စတင်ဝင်ရောက်သည့်နေ့ location: all: အားလုံး + local: ပြည်တွင်း remote: အဝေးမှ title: တည်နေရာ login_status: အကောင့်ဝင်ရောက်မှုအခြေအနေ media_attachments: မီဒီယာ ပူးတွဲချက်များ + memorialize: အမှတ်တရအဖြစ် ပြောင်းပါ + memorialized: အမှတ်တရ + memorialized_msg: "%{username} ကို အမှတ်တရအကောင့်အဖြစ် ပြောင်းလဲခဲ့သည်" moderation: + active: လက်ရှိအသုံးပြုလျက်ရှိခြင်း all: အားလုံး + disabled: ပိတ်ထားသည် + pending: ဆိုင်းငံ့ထားခြင်း + silenced: ကန့်သတ်ထားသော + suspended: ရပ်ဆိုင်းထားခြင်း + title: စိစစ်ခြင်း + moderation_notes: စိစစ်ခြင်းဆိုင်ရာမှတ်စုများ + most_recent_activity: နောက်ဆုံးအသုံးပြုခဲ့သည့်အချိန် + most_recent_ip: အသုံးပြုလေ့ရှိသည့် IP လိပ်စာ + no_account_selected: မည်သည့်အကောင့်ကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + no_limits_imposed: ကန့်သတ်ချက် မရှိပါ။ + no_role_assigned: တာဝန်ပေးအပ်ထားခြင်း မရှိပါ + not_subscribed: စာရင်းသွင်းထားခြင်းမရှိပါ + pending: ဆိုင်းငံ့ထားသော သုံးသပ်ချက် + perform_full_suspension: ရပ်ဆိုင်းရန် + previous_strikes: ယခင်လုပ်ဆောင်ချက်များ + previous_strikes_description_html: + other: ဤအကောင့်တွင် လုပ်ဆောင်ချက်%{count} ရှိသည်။ + promote: အထောက်အကူ + protocol: လုပ်ထုံးလုပ်နည်း public: အများမြင် + push_subscription_expires: PuSH စာရင်းသွင်းမှုမှာ သက်တမ်းကုန်ဆုံးသွားပါပြီ + redownload: ပရိုဖိုင်ကို ပြန်လည်စတင်ရန် + redownloaded_msg: မူလမှစ၍ %{username} ၏ ပရိုဖိုင်ကို ပြန်လည်စတင်ပြီးပါပြီ reject: ဖယ်ရှားပါ + rejected_msg: "%{username} ၏ အကောင့်ဖွင့်အက်ပလီကေးရှင်းကို ဖယ်ရှားလိုက်ပါပြီ" + remote_suspension_irreversible: ဤအကောင့်၏အချက်အလက်ကို လုံးဝ ဖျက်လိုက်ပါပြီ။ + remote_suspension_reversible_hint_html: အကောင့်ကို ၎င်းတို့၏ဆာဗာတွင် ဆိုင်းငံ့ထားပြီး အချက်အလက်ကို %{date} နေ့တွင် လုံးဝဖယ်ရှားလိုက်ပါမည်။ ထိုအချိန်အထိ အဝေးမှထိန်းချုပ်နိုင်သောဆာဗာက ဤအကောင့်ကို ပြန်လည်ရယူနိုင်သည်။ အကောင့်အချက်အလက်အားလုံးကို ချက်ချင်းဖယ်ရှားလိုပါက အောက်ပါအတိုင်း ပြုလုပ်နိုင်ပါသည်။ remove_avatar: ကိုယ်စားပြုရုပ်ပုံကို ဖယ်ရှားပါ + remove_header: မျက်နှာဖုံးပုံ ဖယ်ရှားရန် + removed_avatar_msg: "%{username} ၏ ကိုယ်စားပြုရုပ်ပုံအား ဖယ်ရှားပြီးပါပြီ" + removed_header_msg: "%{username} ၏ မျက်နှာဖုံးပုံအား ဖယ်ရှားပြီးပါပြီ" + resend_confirmation: + already_confirmed: ဤအသုံးပြုသူကို အတည်ပြုပြီးပါပြီ + send: အတည်ပြုချက်လင့်ခ်ကို ပြန်လည်ပေးပို့ပါ + success: အတည်ပြုချက်လင့်ခ် ပို့ပြီးပါပြီ။ reset: ပြန်သတ်မှတ်မည် + reset_password: လျှို့ဝှတ်နံပါတ်အားပြန်သတ်မှတ်မည် + resubscribe: ပြန်လည်စာရင်းသွင်းပါ + role: အခန်းကဏ္ဍ search: ရှာရန် + search_same_email_domain: အီးမေးလ်ဒိုမိန်းတူညီသည့် အခြားအသုံးပြုသူများ + search_same_ip: IP တူတူ အသုံးပြုသော အခြားသူများ + security: လုံခြုံရေး security_measures: only_password: စကားဝှက်ဖြင့်သာ password_and_2fa: စကားဝှက်နှင့် 2FA + sensitive: သတိပြုရန် + sensitized: သတိထားရသည်ဟု အမှတ်အသားပြုထားပါ + shared_inbox_url: inbox URL ကို မျှဝေခဲ့သည် + show: + created_reports: ဆောင်ရွက်ခဲ့ပြီးသောအစီရင်ခံစာများ + targeted_reports: အခြားသူများမှဆောင်ရွက်ခဲ့သော အစီရင်ခံစာများ silence: ကန့်သတ် silenced: ကန့်သတ်ထားသည် statuses: ပို့စ်များ + strikes: ယခင်လုပ်ဆောင်ချက်များ subscribe: စာရင်းသွင်းပါ suspend: ရပ်ဆိုင်းပါ suspended: ရပ်ဆိုင်းထားသည် + suspension_irreversible: ဤအကောင့်၏ဒေတာကို နောက်ပြန်မဆုတ်ဘဲ ဖျက်လိုက်ပါပြီ။ ၎င်းကိုအသုံးပြုနိုင်စေရန် အကောင့်အား ဆိုင်းငံ့ထားနိုင်သော်လည်း ၎င်းတွင် ယခင်ကရှိထားသည့် မည်သည့်ဒေတာကိုမှ ပြန်လည်ရယူမည်မဟုတ်ပါ။ + suspension_reversible_hint_html: အကောင့်ကို ဆိုင်းငံ့ထားပြီး၊ ဒေတာကို %{date} တွင် အပြည့်အဝ ဖယ်ရှားပါမည်။ ထိုအချိန်အထိ မည်သည့်ဆိုးကျိုးများမရှိဘဲ အကောင့်ကို ပြန်လည်ရယူနိုင်သည်။ အကောင့်၏ဒေတာအားလုံးကို ချက်ချင်းဖယ်ရှားလိုပါက အောက်ပါအတိုင်း ပြုလုပ်နိုင်ပါသည်။ title: အကောင့်များ + unblock_email: အီးမေးလ်ကိုပြန်ဖွင့်မည် + unblocked_email_msg: " %{username} အီးမေးလ်ကိုပြန်ဖွင့်လိုက်ပါပြီ" + unconfirmed_email: အတည်မပြုရသေးသော အီးမေးလ် + undo_sensitized: သတိပြုရန်အား ပြန်ဖြုတ်ရန် + undo_silenced: ကန့်သတ်ချက်မလုပ်တော့ပါ + undo_suspension: ပိတ်ခြင်းကိုပြန်ဖွင့်မည် + unsilenced_msg: "%{username} ၏ အကောင့်၏ ကန့်သတ်ချက်ကို အောင်မြင်စွာ ပယ်ဖျက်ခဲ့သည်။" unsubscribe: စာရင်းမှထွက်ရန် unsuspended_msg: "%{username} ၏ အကောင့်ကို ရပ်ဆိုင်းလိုက်ပါပြီ" username: အသုံးပြုသူအမည် + view_domain: ဒိုမိန်းအတွက် အကျဉ်းချုပ်ကို ကြည့်ပါ + warn: သတိပေးရန် web: ဝဘ် + whitelisted: ဖက်ဒီကို ခွင့်ပြုခဲ့သည် action_logs: action_types: + approve_appeal: အယူခံကို အတည်ပြုပါ + approve_user: အသုံးပြုသူကို အတည်ပြုရန် + assigned_to_self_report: မှတ်တမ်းကိုတစ်ယောက်ယောက်အားလုပ်ခိုင်းမည် + change_email_user: အသုံးပြုသူအတွက် အီးမေးလ်ပြောင်းရန် + change_role_user: အသုံးပြုသူ၏ အခန်းကဏ္ဍကို ပြောင်းလဲရန် + confirm_user: အသုံးပြုသူကို လက်ခံရန် + create_account_warning: သတိပေးချက်ဖန်တီးပါ create_announcement: ကြေညာချက်ဖန်တီးပါ + create_canonical_email_block: အီးမေးလ်ပိတ်ပင်ခြင်းအား ဖန်တီးရန် create_custom_emoji: စိတ်ကြိုက်အီမိုဂျီ ဖန်တီးပါ + create_domain_allow: ဒိုမိန်းခွင့်ပြုခြင်းကို ဖန်တီးရန် + create_domain_block: ဒိုမိန်းပိတ်ပင်ခြင်းအား ဖန်တီးရန် + create_email_domain_block: အီးမေးလ်ဒိုမိန်းပိတ်ပင်ခြင်းအား ဖန်တီးရန် + create_ip_block: IP စည်းမျဉ်း ဖန်တီးရန် + create_unavailable_domain: အသုံးမပြုနိုင်သောဒိုမိန်းကို ဖန်တီးပါ + create_user_role: အခန်းကဏ္ဍဖန်တီးပါ + demote_user: အသုံးပြုသူကိုအဆင့်လျော့ချမည် + destroy_announcement: ကြေညာချက်ကို ဖျက်ပါ + destroy_canonical_email_block: အီးမေးလ်ပိတ်ပင်ခြင်းအား ဖျက်ရန် + destroy_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ဖျက်ရန် + destroy_domain_allow: ဒိုမိန်းခွင့်ပြုခြင်းကို ဖျက်ရန် + destroy_domain_block: ဒိုမိန်းပိတ်ပင်ခြင်းအား ဖျက်ရန် + destroy_email_domain_block: အီးမေးလ်ဒိုမိန်းပိတ်ပင်ခြင်းအား ဖျက်ရန် + destroy_instance: ဒိုမိန်းကို ဖယ်ရှားပါ + destroy_ip_block: IP စည်းမျဉ်းကို ဖျက်ပါ destroy_status: Post ကို ဖျက်ပါ + destroy_unavailable_domain: အသုံးမပြုနိုင်သောဒိုမိန်းကို ဖျက်ပါ + destroy_user_role: အခန်းကဏ္ဍကို ဖျက်ပါ disable_2fa_user: 2FA ကို ပိတ်ပါ disable_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ပိတ်ပါ + disable_sign_in_token_auth_user: အသုံးပြုသူအတွက် အီးမေးလ်တိုကင် အထောက်အထားပြခြင်းကို ပိတ်ထားသည် + disable_user: အသုံးပြုသူကို ပိတ်ပါ + enable_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ဖွင့်ပါ + enable_sign_in_token_auth_user: အသုံးပြုသူအတွက် အီးမေးလ်တိုကင် အထောက်အထားပြခြင်းကို ဖွင့်ထားသည် + enable_user: အသုံးပြုသူကို ဖွင့်ပါ + memorialize_account: အမှတ်တရအကောင့် + promote_user: အသုံးပြုသူ မြှင့်တင်ရန် + reject_appeal: အယူခံဝင်မှုကို ငြင်းပယ်ပါ + reject_user: အသုံးပြုသူ ဖယ်ရှားရန် remove_avatar_user: ကိုယ်စားပြုရုပ်ပုံကို ဖယ်ရှားပါ + reopen_report: အစီရင်ခံစာပြန်ဖွင့်ရန် + resend_user: အတည်ပြုရန် မေးလ်ကို ပြန်ပို့ပေးရန် + reset_password_user: စကားဝှက်ကို ပြန်လည်ရယူမည် + resolve_report: အစီရင်ခံစာကို ဖြေရှင်းရန် + sensitive_account: Force-Sensitive အကောင့် silence_account: အကောင့် ကန့်သတ်ပါ suspend_account: အကောင့် ရပ်ဆိုင်းပါ + unassigned_report: အစီရင်ခံစာ ဖြုတ်ရန် + unblock_email_account: အီးမေးလ်လိပ်စာ ပြန်ဖွင့်ရန် + unsensitive_account: Force-Sensitive Account မဟုတ်တော့ပါ + unsilence_account: ကန့်သတ်အကောင့်ကို မလုပ်တော့ပါ + unsuspend_account: အကောင့်ကို ရပ်ဆိုင်းပါ။ + update_announcement: ကြေညာချက်ပြင်ဆင်ရန် + update_custom_emoji: စိတ်ကြိုက်အီမိုဂျီကို ပြင်ဆင်ရန် + update_domain_block: ဒိုမိန်းပိတ်ပင်ခြင်းအား ပြင်ဆင်ရန် + update_ip_block: IP စည်းမျဉ်း ပြင်ဆင်ရန် update_status: ပို့စ်ပြင်ဆင်ရန် + update_user_role: အခန်းကဏ္ဍပြင်ဆင်ရန် + actions: + approve_appeal_html: "%{name} က %{target} မှ စိစစ်ဆုံးဖြတ်ချက်အယူခံဝင်ခြင်းကို အတည်ပြုခဲ့သည်" + approve_user_html: " %{name} က %{target} မှ အကောင့်ဖွင့်ခြင်းကို အတည်ပြုထားသည်" + assigned_to_self_report_html: "%{name} က အစီရင်ခံစာ %{target} များကို ၎င်းတို့ထံ ပေးအပ်ခဲ့သည်" + change_email_user_html: "%{name} က အသုံးပြုသူ %{target} ၏ အီးမေးလ်လိပ်စာကို ပြောင်းခဲ့သည်" + change_role_user_html: "%{name} က %{target} ၏ အခန်းကဏ္ဍကို ပြောင်းခဲ့သည်" + confirm_user_html: "%{name} က အသုံးပြုသူ %{target} ၏ အီးမေးလ်လိပ်စာကို အတည်ပြုခဲ့သည်" + create_account_warning_html: "%{name} က %{target} သို့ သတိပေးချက်တစ်ခု ပေးပို့ခဲ့သည်" + create_announcement_html: "%{name} က ကြေညာချက်အသစ် %{target} ကို ဖန်တီးခဲ့သည်" + create_canonical_email_block_html: "%{name} က ဟက်ရှ် %{target} ဖြင့် အီးမေးလ်ကို ပိတ်ပင်ထားသည်" + create_custom_emoji_html: "%{name} က အီမိုဂျီ %{target} အသစ်ကို ပြင်ဆင်ခဲ့သည်" + create_domain_allow_html: "%{name} က ဒိုမိန်း %{target} ဖြင့် ဖက်ဒီကို ခွင့်ပြုခဲ့သည်" + create_domain_block_html: "%{name} က ဒိုမိန်း %{target} ကို ပိတ်ပင်ထားသည်" + create_email_domain_block_html: "%{name} က အီးမေးလ်ဒိုမိန်း %{target} ကို ပိတ်ပင်ထားသည်" + create_ip_block_html: "%{name} က IP %{target} အတွက် စည်းမျဉ်းကို ဖန်တီးထားသည်" + create_unavailable_domain_html: "%{name} က ဒိုမိန်း %{target} သို့ ပေးပို့မှုကို ရပ်လိုက်သည်" + create_user_role_html: "%{name} က %{target} အခန်းကဏ္ဍကို ဖန်တီးပြီးပါပြီ" + demote_user_html: "%{name} က အသုံးပြုသူ %{target} ကို ဖြုတ်ပြီးပါပြီ" + destroy_announcement_html: "%{name} က ကြေညာချက် %{target} ကို ဖျက်လိုက်သည်" + destroy_canonical_email_block_html: ဟက်ရှ် %{target} ဖြင့် %{name} အီးမေးလ်ပိတ်သိမ်းထားခြင်းကို ဖယ်ရှားပြီးပါပြီ + destroy_custom_emoji_html: "%{name} ဖျက်လိုက်သော အီမိုဂျီ %{target}" + destroy_domain_allow_html: "%{name} က ဒိုမိန်း %{target} ဖြင့် ဖက်ဒီကို ခွင့်မပြုခဲ့ပါ" + destroy_domain_block_html: "%{name} မှ ပြန်ဖွင့်လိုက်သော ဒိုမိန်း %{target}" + destroy_email_domain_block_html: "%{name} က အီးမေးလ်ဒိုမိန်း %{target} ကို ပြန်ဖွင့်ထားသည်" + destroy_instance_html: "%{name} က ဒိုမိန်း %{target} ကို ဖယ်ရှားခဲ့သည်" + destroy_ip_block_html: "%{name} က IP %{target} အတွက် စည်းမျဉ်းကို ဖျက်ထားသည်" + destroy_status_html: "%{name} က %{target} မှ တင်ထားသောပို့စ်ကို ဖယ်ရှားခဲ့သည်" + destroy_unavailable_domain_html: "%{name} က ဒိုမိန်း %{target} သို့ ပေးပို့မှုကို ပြန်လည်စတင်ခဲ့သည်" + destroy_user_role_html: "%{name} ဖျက်ထားသော အခန်းကဏ္ဍ %{target} " + disable_2fa_user_html: "%{name} က အသုံးပြုသူ %{target} အတွက် နှစ်ဆင့်ခံလုံခြုံရေးလိုအပ်ချက်ကို ပိတ်ထားသည်" + disable_custom_emoji_html: "%{name} ပိတ်ထားသောအီမိုဂျီ %{target}" + disable_sign_in_token_auth_user_html: "%{name} က %{target} အတွက် အီးမေးလ်တိုကင် အထောက်အထားပြခြင်းကို ပိတ်ထားသည်" + disable_user_html: "%{name} က အသုံးပြုသူ %{target} အတွက် အကောင့်ဝင်ခြင်းကို ပိတ်ထားသည်" + enable_custom_emoji_html: "%{name} ဖွင့်ထားသည့် အီမိုဂျီ %{target}" + enable_sign_in_token_auth_user_html: "%{name} က %{target} အတွက် အီးမေးလ်တိုကင် အထောက်အထားပြခြင်းကို ဖွင့်ထားသည်" + enable_user_html: "%{name} က အသုံးပြုသူ %{target} အတွက် အကောင့်ဝင်ခြင်းကို ဖွင့်ထားသည်" + memorialize_account_html: "%{name} က %{target} ၏ အကောင့်ကို အမှတ်တရ စာမျက်နှာအဖြစ် ပြောင်းလဲခဲ့သည်" + promote_user_html: "%{name} က အသုံးပြုသူ %{target} ကို ထောက်ခံခဲ့သည်" + reject_appeal_html: "%{name} က %{target} မှ အယူခံဝင်မှု ဆုံးဖြတ်ချက် စိစစ်ခြင်းကို ပယ်ချခဲ့သည်" + reject_user_html: "%{name} က %{target} မှတစ်ဆင့် အကောင့်ဖွင့်ခြင်းကို ပယ်ချခဲ့သည်" + remove_avatar_user_html: "%{name} က %{target} ၏ ကိုယ်စားပြုရုပ်ပုံကို ဖယ်ရှားခဲ့သည်" + reopen_report_html: "%{name} က အစီရင်ခံစာ %{target} ကို ပြန်ဖွင့်ခဲ့သည်" + resend_user_html: "%{name} က %{target} အတွက် အတည်ပြုချက်အီးမေးလ်ကို ပြန်ပို့ခဲ့သည်" + reset_password_user_html: "%{name} က အသုံးပြုသူ %{target} ၏ စကားဝှက်ကို ပြန်လည်သတ်မှတ်ခဲ့သည်" + resolve_report_html: "%{name} က အစီရင်ခံစာ %{target} ကို ဖြေရှင်းထားသည်" + sensitive_account_html: "%{name} က %{target} ၏ မီဒီယာကို သတိထားရသောမီဒီယာအဖြစ် အမှတ်အသားပြုထားသည်" + silence_account_html: "%{name} က %{target} ၏ အကောင့်ကို ကန့်သတ်ထားသည်" + suspend_account_html: "%{name} က %{target} ၏ အကောင့်ကို ဆိုင်းငံ့ထားသည်" + unassigned_report_html: "%{name} က အစီရင်ခံစာ %{target} ကို ဖြုတ်ထားသည်" + unblock_email_account_html: "%{name} က %{target} ၏ အီးမေးလ်လိပ်စာကို ပြန်ဖွင့်ခဲ့သည်" + unsensitive_account_html: "%{name} က %{target} ၏ မီဒီယာကို သတိထားရသောမီဒီယာအဖြစ် အမှတ်အသားပြုထားခြင်းမရှိပါ" + unsilence_account_html: "%{target} ၏ အကောင့်၏ %{name} ကန့်သတ်ချက် မရှိပါ။" + unsuspend_account_html: "%{name} က %{target} ၏ အကောင့်ကို ဆိုင်းငံ့ထားသည်" + update_announcement_html: "%{name} က ကြေညာချက် %{target} ကို ပြင်ဆင်ခဲ့သည်" + update_custom_emoji_html: "%{name} က အီမိုဂျီ %{target} ကို ပြင်ဆင်ခဲ့သည်" + update_domain_block_html: "%{name} က %{target} အတွက် ဒိုမိန်းပိတ်ပင်ခြင်းကို ပြင်ဆင်ခဲ့သည်" + update_ip_block_html: "%{name} မှ IP %{target} အတွက် စည်းမျဉ်း ပြောင်းထားသည်" + update_status_html: "%{name} က %{target} တင်ထားသောပို့စ်ကို ပြင်ဆင်ခဲ့သည်" + update_user_role_html: "%{name} က %{target} အခန်းကဏ္ဍကို ပြောင်းလဲခဲ့ပါသည်" deleted_account: အကောင့်ဖျက်ပြီးပါပြီ + empty: မှတ်တမ်းများ မတွေ့ပါ။ + filter_by_action: လုပ်ဆောင်ချက်အလိုက် စစ်ထုတ်ရန် + filter_by_user: အသုံးပြုသူအလိုက် စစ်ထုတ်ရန် + title: မှတ်တမ်းများစစ်ဆေးခြင်း announcements: destroyed_msg: ကြေညာချက် ဖျက်ပြီးပါပြီ edit: title: ကြေညာချက် ပြင်ဆင်ရန် empty: ကြေညာချက်များမတွေ့ပါ + live: လက်ရှိ new: create: ကြေညာချက်ဖန်တီးပါ title: ကြေညာချက်အသစ် publish: ပို့စ်တင်မည် + published_msg: ကြေညာချက်တင်ပြီးပါပြီ။ + scheduled_for: "%{time} အတွက် စီစဉ်ထားသည်" + scheduled_msg: ကြေညာချက်ထုတ်ပြန်ရန် စီစဉ်ထားသည်။ title: ကြေညာချက်များ unpublish: ပြန်ဖြုတ်ပါ unpublished_msg: ကြေညာချက်ကို ဖြုတ်ပြီးပါပြီ updated_msg: ကြေညာချက်ကို ပြင်ဆင်ပြီးပါပြီ။ + critical_update_pending: အရေးကြီးသောအပ်ဒိတ်ကို ဆိုင်းငံ့ထားသည် custom_emojis: + assign_category: အမျိုးအစားသတ်မှတ်ရန် by_domain: ဒိုမိန်း + copied_msg: အီမိုဂျီ၏စက်အတွင်းကူးထားသည်များကို အောင်မြင်စွာ ဖန်တီးခဲ့သည်။ copy: ကူးယူပါ + copy_failed_msg: အီမိုဂျီ၏စက်အတွင်းမကူးနိုင်ပါ + create_new_category: အမျိုးအစားအသစ်ဖန်တီးရန် + created_msg: အီမိုဂျီ ဖန်တီးပြီးပါပြီ။ delete: ဖျက်ပါ + destroyed_msg: အီမိုဂျီ ဖျက်ပစ်လိုက်ပါပြီ။ disable: ပိတ်ပါ disabled: ပိတ်ပြီးပါပြီ + disabled_msg: ထိုအီမိုဂျီကို ပိတ်ပြီးပါပြီ emoji: အီမိုဂျီ enable: ဖွင့်ပါ enabled: ဖွင့်ထားသည် + enabled_msg: ထိုအီမိုဂျီကို ဖွင့်ပြီးပါပြီ image_hint: PNG သို့မဟုတ် GIF %{size} အထိ list: စာရင်း listed: စာရင်းသွင်းထားသည် new: title: စိတ်ကြိုက်အီမိုဂျီအသစ် ထည့်ပါ + no_emoji_selected: မည်သည့်အီမိုဂျီကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + not_permitted: ဤလုပ်ဆောင်ချက်ကို ဆောင်ရွက်ရန် သင့်ကို ခွင့်မပြုပါ။ + overwrite: ထပ်ရေးရန် + shortcode: တိုတိုကုတ် + shortcode_hint: အက္ခရာဂဏန်းများနှင့် underscore များဖြင့် အနည်းဆုံး စာလုံး ၂ လုံးရှိရပါမည် title: စိတ်ကြိုက်အီမိုဂျီများ + uncategorized: အမျိုးအစားခွဲခြားထားခြင်းမရှိပါ + unlist: စာရင်းမသွင်းထားပါ unlisted: စာရင်းမသွင်းထားပါ update_failed_msg: ထိုအီမိုဂျီကို ပြင်ဆင်၍မရပါ updated_msg: အီမိုဂျီကို ပြင်ဆင်ပြီးပါပြီ။ + upload: တင္ရန် dashboard: + active_users: လက်ရှိအသုံးပြုသူများ + interactions: အပြန်အလှန်ဆက်သွယ်မှုများ + media_storage: မီဒီယာသိုလှောင်မှု new_users: အသုံးပြုသူအသစ်များ + opened_reports: မှတ်တမ်းများကိုဖွင့်လှစ်ခဲ့သည် + pending_appeals_html: + other: "%{count} အယူခံဝင်မှုကို ဆိုင်းငံ့ထားခြင်း" + pending_reports_html: + other: "%{count} မှတ်တမ်းဆောင်ရွက်ဆဲ" + pending_tags_html: + other: "%{count} hashtag ဆောင်ရွက်ဆဲ" + pending_users_html: + other: "%{count} ဆိုင်းငံ့အသုံးပြုသူ" + resolved_reports: မှတ်တမ်းများဖြေရှင်းခဲ့သည် + software: ဆော့ဖ်ဝဲလ် + sources: အကောင့်ဖွင့်ခြင်းဆိုင်ရာ သတင်းရင်းမြစ်များ + space: နေရာလွတ်အသုံးပြုမှု + title: ဒက်ရှ်ဘုတ်မြင်ကွင်း + top_languages: လက်ရှိအသုံးများလျက်ရှိသည့် ဘာသာစကား + top_servers: လက်ရှိအသုံးများလျက်ရှိသည့် ဆာဗာများ website: ဝဘ်ဆိုဒ် + disputes: + appeals: + empty: အယူခံဝင်ထားခြင်းမရှိပါ။ + title: အယူခံဝင်ထားခြင်းများ + domain_allows: + add_new: ဒိုမိန်းဖြင့် ဖက်ဒီကို ခွင့်ပြုရန် + created_msg: ဒိုမိန်းကို ဖက်ဒီအတွက် ခွင့်ပြုပြီးပါပြီ + destroyed_msg: ဒိုမိန်းအား ဖက်ဒီမှ ခွင့်မပြုပါ + export: ထုတ်ယူခြင်း + import: ထည့်သွင်းခြင်း + undo: ဒိုမိန်းဖြင့် ဖက်ဒီကို ခွင့်မပြုပါ domain_blocks: + add_new: ဒိုမိန်းပိတ်ပင်ခြင်းအသစ် ထည့်ပါ + confirm_suspension: + cancel: ပယ်ဖျက် + confirm: ရပ်ဆိုင်းရန် + permanent_action: ဆိုင်းငံ့စနစ်ပယ်ဖျက်ခြင်းသည် အချက်အလက် သို့မဟုတ် ဆက်ဆံရေးကို ပြန်လည်ရရှိမည်မဟုတ်ပါ။ + preamble_html: သင်သည် %{domain} နှင့် ၎င်း၏ ဒိုမိန်းခွဲများကို ရပ်ဆိုင်းတော့မည်ဖြစ်သည်။ + remove_all_data: "၎င်းက ဤဒိုမိန်းအကောင့်များအတွက် အကြောင်းအရာ၊ မီဒီယာနှင့် ပရိုဖိုင်အချက်အလက်အားလုံးကို သင့်ဆာဗာမှ ဖယ်ရှားမည်ဖြစ်သည်။" + stop_communication: သင့်ဆာဗာမှ ဤဆာဗာများနှင့် ဆက်သွယ်ခြင်းကို ရပ်သွားပါမည်။ + title: "%{domain} အတွက် ဒိုမိန်းပိတ်ဆို့ခြင်းကို အတည်ပြုပါ" + undo_relationships: "၎င်းသည် ဤဆာဗာများနှင့် သင့်အကောင့်များကြားတွင် လိုက်နာရမည့် ဆက်ဆံရေးကို ပြန်ပြင်လိုက်ပါမည်။" + created_msg: ဒိုမိန်းပိတ်ပင်ခြင်းကို ယခုလုပ်ဆောင်နေပါသည် + destroyed_msg: ဒိုမိန်းပိတ်ဆို့ခြင်းကို ပြန်ပြင်လိုက်ပါပြီ။ domain: ဒိုမိန်း + edit: ဒိုမိန်းပိတ်ပင်ခြင်းကို ပြင်ဆင်ရန် + existing_domain_block: "%{name} အပေါ် ပိုမိုတင်းကျပ်သောကန့်သတ်ချက်များကို ချမှတ်ထားပြီးဖြစ်သည်။" + existing_domain_block_html: '%{name} အပေါ် ပိုမိုတင်းကျပ်သော ကန့်သတ်ချက်များကို ချမှတ်ထားပြီး ၎င်းကို ပြန်ဖွင့်ရန် လိုအပ်ပါသည်။' + export: ထုတ်ယူခြင်း + import: ထည့်သွင်းခြင်း new: + create: ပိတ်ပင်ခြင်း ဖန်တီးရန် + hint: ဒိုမိန်းပိတ်ဆို့ခြင်းသည် ဒေတာဘေ့စ်အတွင်း အကောင့်ထည့်သွင်းမှုများကို မတားဆီးသော်လည်း ထိုအကောင့်များအတွက် တိကျစွာစိစစ်ခြင်းနည်းလမ်းများကို အလိုအလျောက်ပြန်လည်အသုံးချမည်ဖြစ်သည်။ severity: + desc_html: "ကန့်သတ်ချက် သည် ဤဒိုမိန်းရှိ အကောင့်များမှ ပို့စ်များကို ၎င်းတို့ကို မလိုက်ကြည့်သူတိုင်းကို မမြင်နိုင်စေမည်ဖြစ်သည်။ ဆိုင်းငံ့ထားရန် သည် ဤဒိုမိန်းအကောင့်များအတွက် အကြောင်းအရာ၊ မီဒီယာနှင့် ပရိုဖိုင်ဒေတာအားလုံးကို သင့်ဆာဗာမှ ဖယ်ရှားပါမည်။ မီဒီယာဖိုင်များကို ငြင်းပယ်လိုပါက None ကို အသုံးပြုပါ။" + noop: တစ်ခုမျှမရှိ silence: ကန့်သတ် suspend: ရပ်ဆိုင်းပါ + title: ဒိုမိန်းပိတ်ပင်ထားခြင်းအသစ် + no_domain_block_selected: မည်သည့်ဒိုမိန်းပိတ်ပင်ထားခြင်းကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + not_permitted: ဤလုပ်ဆောင်ချက်ကို ဆောင်ရွက်ရန် သင့်ကို ခွင့်မပြုပါ။ + obfuscate: မှတ်ရခက်သောဒိုမိန်းအမည် + obfuscate_hint: ဒိုမိန်းကန့်သတ်ချက်များစာရင်းကို ဖွင့်ထားပါက စာရင်းရှိ ဒိုမိန်းအမည်များမှာ ရှုပ်ထွေးစေနိုင်ပါသည်။ private_comment: သီးသန့်မှတ်ချက် + private_comment_hint: စိစစ်သူများ၏အတွင်းပိုင်းအသုံးပြုမှုအတွက် ဤဒိုမိန်းကန့်သတ်ချက်ဆိုင်ရာမှတ်ချက်။ + public_comment: အများမြင်မှတ်ချက် + public_comment_hint: ဒိုမိန်းကန့်သတ်ချက်များစာရင်းကို ကြော်ငြာထားပါက အများသူငှာအတွက် ဤဒိုမိန်းကန့်သတ်ချက်နှင့်ပတ်သက်၍ ရေးသားပေးထားရန်။ + reject_media: မီဒီယာဖိုင်များကို ဖယ်ရှားပါ + reject_media_hint: စက်တွင်းသိမ်းဆည်းထားသည့် မီဒီယာဖိုင်များကို ဖယ်ရှားပြီး ဒေါင်းလုဒ်လုပ်ခွင့် မရှိပါ။ ဆိုင်းငံ့ခြင်းများအတွက် မသက်ဆိုင်ပါ။ + reject_reports: မှတ်တမ်းများ ဖယ်ရှားရန် + reject_reports_hint: ဤဒိုမိန်းမှလာသော မှတ်တမ်းအားလုံးကို လျစ်လျူရှုပါ။ ဆိုင်းငံ့ခြင်းများအတွက် မသက်ဆိုင်ပါ။ + undo: ဒိုမိန်းပိတ်ပင်ခြင်းကို ပြန်ဖျက်ရန် + view: ဒိုမိန်းပိတ်ပင်ခြင်းကို ကြည့်ရန် email_domain_blocks: + add_new: အသစ် ထည့်ပါ + attempts_over_week: + other: ပြီးခဲ့သည့် ရက်သတ္တပတ်အတွင်း %{count} ကြိုးပမ်းမှု + created_msg: အီးမေးလ်ဒိုမိန်းကို ပိတ်ပင်နိုင်ခဲ့ပါသည် delete: ဖျက်ပါ + dns: + types: + mx: MX မှတ်တမ်း domain: ဒိုမိန်း new: create: ဒိုမိန်းထည့်ပါ + resolve: ဒိုမိန်းကို ဖြေရှင်းရန် + title: အီးမေးလ်ဒိုမိန်းအသစ်ကို ပိတ်ရန် + no_email_domain_block_selected: မည်သည့်အီးမေးလ်ဒိုမိန်းပိတ်ပင်ခြင်းကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + not_permitted: ခွင့်ပြုထားခြင်းမရှိပါ + resolved_dns_records_hint_html: ဒိုမိန်းအမည်သည် အီးမေးလ်လက်ခံခြင်းအတွက် နောက်ဆုံးတွင် တာဝန်ရှိသည့် အောက်ပါ MX ဒိုမိန်းများသို့ ဖြေရှင်းပေးသည်။ MX ဒိုမိန်းကို ပိတ်ဆို့ခြင်းသည် တူညီသော MX ဒိုမိန်းကို အသုံးပြုသည့် မည်သည့်အီးမေးလ်လိပ်စာမှ အကောင့်ဖွင့်ခြင်းများကို ပိတ်ဆို့စေမည်၊ မြင်နိုင်သောဒိုမိန်းအမည်သည် ကွဲပြားသော်လည်း၊ အဓိက အီးမေးလ်ဝန်ဆောင်မှုပေးသူများကို မပိတ်ဆို့ရန် သတိထားပါ။ + resolved_through_html: "%{domain} မှတစ်ဆင့် ဖြေရှင်းခဲ့သည်" + title: ပိတ်ပင်ထားသော အီးမေးလ်ဒိုမိန်းများ export_domain_allows: + new: + title: ဒိုမိန်းတင်သွင်းခွင့်ပြုသည် no_file: ဖိုင်ရွေးထားခြင်းမရှိပါ။ export_domain_blocks: + import: + description_html: ဒိုမိန်းပိတ်ဆို့စာရင်း ထည့်သွင်းပါမည်။ ဤစာရင်းကို သင်ကိုယ်တိုင် မရေးသားထားပါက ပြန်လည်သုံးသပ်ရန်လိုပါသည်။ + existing_relationships_warning: လက်ရှိစောင့်ကြည့်သူများနှင့် ဆက်ဆံရေး + private_comment_description_html: ထည့်သွင်းထားသော ဒိုမိန်းပိတ်ဆို့စာရင်းများအား ကြည့်ရှုရန်အတွက် ပိတ်ဆို့စာရင်းများကို အောက်ပါသီးသန့်မှတ်ချက်ဖြင့် ဖန်တီးပါမည် - %{comment} + private_comment_template: "%{date} တွင် %{source} မှ ထည့်သွင်းခဲ့သည်" + title: ဒိုမိန်းပိတ်ပင်ထားမှုများကို ထည့်သွင်းရန် + invalid_domain_block: အောက်ပါအမှား(များ)ကြောင့် တစ်ခု သို့မဟုတ် တစ်ခုထက်ပိုသော ဒိုမိန်းပိတ်ပင်ထားမှုများကို ကျော်သွားခဲ့သည် - %{error} + new: + title: ဒိုမိန်းပိတ်ပင်ထားမှုများကို ထည့်သွင်းရန် no_file: ဖိုင်ရွေးထားခြင်းမရှိပါ follow_recommendations: + description_html: "အကြံပြုချက်များကို အသုံးပြုသူအသစ်များက လိုက်နာခြင်းဖြင့် စိတ်ဝင်စားစရာအကြောင်းအရာများကို လျင်မြန်စွာရှာဖွေနိုင်စေပါမည်။ အသုံးပြုသူတစ်ဦးက စိတ်ကြိုက်ပြင်ဆင်ထားသည့် အကြံပြုချက်များလိုက်နာရန်အတွက် အခြားသူများနှင့် လုံလောက်သောအပြန်အလှန်တုံ့ပြန်ခြင်းမရှိပါက ယင်းအစား ဤအကောင့်များကို အကြံပြုလိုပါသည်။ ၎င်းအကောင့်များကို မကြာသေးမီက ထိတွေ့ဆက်ဆံမှုအများဆုံးနှင့် အသုံးပြုထားသည့်ဘာသာစကားမှတစ်ဆင့် ဒေသတွင်းစောင့်ကြည့်သူဦးရေ အများဆုံးရှိသော အကောင့်များကိုအခြေခံ၍ နေ့စဉ် တွက်ချက်ထားခြင်းဖြစ်ပါသည်။" language: ဘာသာစကားအတွက် + status: အခြေအနေ + suppress: လိုက်နာရမည့်အကြံပြုချက်များကို ထိန်းချုပ်ပါ + suppressed: ဖျောက်ထားသော + title: အကြံပြုချက်များကို စောင့်ကြည့်ပါ + unsuppress: အကြံပြုချက်စောင့်ကြည့်ခြင်းအား ပြန်လည်ရယူပါ instances: + availability: + description_html: + other: ဒိုမိန်းသို့ ပေးပို့ခြင်း မအောင်မြင်ဘဲ %{count} ရက် မအောင်မြင်ပါက၊ ဒိုမိန်းထံပေးပို့ခြင်း မှ မရရှိပါက နောက်ထပ်ပေးပို့ရန် ကြိုးပမ်းမှုများ ပြုလုပ်မည်မဟုတ်ပါ။ + failure_threshold_reached: "%{date} နေ့ တွင် မအောင်မြင်ခဲ့ပါ။" + failures_recorded: + other: "%{count} ရက်နေ့တွင် ကြိုးစားမှု မအောင်မြင်ပါ။" + no_failures_recorded: မှတ်တမ်းမရှိပါ။ + title: ရရှိနိုင်မှု + warning: ဤဆာဗာအသုံးပြုနိုင်ရန် နောက်ဆုံးကြိုးပမ်းမှုမှာ မအောင်မြင်ခဲ့ပါ back_to_all: အားလုံး back_to_limited: ကန့်သတ်ထားသည် + back_to_warning: သတိပေးချက် + by_domain: ဒိုမိန်း + confirm_purge: ဤဒိုမိန်းမှ အချက်အလက်များကို အပြီးတိုင်ဖျက်လိုသည်မှာ သေချာပါသလား။ content_policies: + comment: အတွင်းပိုင်းမှတ်ချက် + description_html: ဤဒိုမိန်းနှင့် ဒိုမိန်းခွဲများမှ အကောင့်အားလုံးအတွက် အသုံးချမည့် အကြောင်းအရာမူဝါဒများကို သတ်မှတ်နိုင်သည်။ + limited_federation_mode_description_html: ဤဒိုမိန်းဖြင့် ဖက်ဒီကို ခွင့်ပြုမလား။ policies: + reject_media: မီဒီယာဖယ်ရှားရန် + reject_reports: အစီရင်ခံစာများ ဖယ်ရှားရန် silence: ကန့်သတ် + suspend: ရပ်ဆိုင်းပါ policy: မူဝါဒ + reason: မူဝါဒဆိုင်ရာအကြောင်းအရာများ + title: အကြောင်းအရာမူဝါဒများ dashboard: + instance_accounts_dimension: အများဆုံးစောင့်ကြည့်ထားသည့်အကောင့်များ + instance_accounts_measure: သိမ်းဆည်းထားသော အကောင့်များ instance_followers_measure: ကျွန်ုပ်တို့၏စောင့်ကြည့်သူများ အဲ့ဒီနေရာမှာပါ instance_follows_measure: သူတို့၏စောင့်ကြည့်သူများ ဒီနေရာမှာပါ + instance_languages_dimension: အသုံးများသည့်ဘာသာစကားများ + instance_media_attachments_measure: သိမ်းဆည်းထားသော မီဒီယာပူးတွဲဖိုင်များ + instance_reports_measure: "၎င်းတို့နှင့်ဆိုင်သော အစီရင်ခံစာများ" + instance_statuses_measure: သိမ်းဆည်းထားသောပို့စ်များ delivery: all: အားလုံး + clear: ပေးပို့မှု အမှားအယွင်းများကို ရှင်းလင်းပါ + failing: မအောင်မြင်ခြင်း + restart: ပေးပို့မှုကို ပြန်လည်စတင်ရန် + stop: ပေးပို့မှုကို ရပ်ရန် + unavailable: မရရှိနိုင်ပါ + delivery_available: ပေးပို့နိုင်ပါပြီ + delivery_error_days: ပေးပို့မှု မှားယွင်းသည့်ရက်များ + delivery_error_hint: "%{count} ရက်အတွင်း မပေးပို့နိုင်ပါက ၎င်းကို ပေးပို့မရနိုင်ဟု အလိုအလျောက် အမှတ်အသားပြုပါမည်။" + destroyed_msg: "%{domain} မှ အချက်အလက်များကို မကြာမီ ဖျက်ပါမည်။" + empty: ဒိုမိန်းများ မတွေ့ပါ။ + known_accounts: + other: လူသိများသော အကောင့် %{count} ခု moderation: all: အားလုံး limited: ကန့်သတ်ထားသော + title: စိစစ်ခြင်း private_comment: သီးသန့်မှတ်ချက် public_comment: အများမြင်မှတ်ချက် + purge: ဖျက် + purge_description_html: ဤဒိုမိန်းသည် အော့ဖ်လိုင်းဖြစ်နေပါက သင့်သိုလှောင်မှုမှ အကောင့်မှတ်တမ်းများနှင့် ဆက်စပ်အချက်အလက်အားလုံးကို ဖျက်နိုင်သည်။ အချိန်အနည်းငယ် ကြာနိုင်ပါသည်။ + title: ဖက်ဒီ + total_blocked_by_us: ကျွန်ုပ်တို့မှ ပိတ်ပင်ထားခြင်း + total_followed_by_them: "၎င်းတို့မှ စောင့်ကြည့်ခဲ့သည်" + total_followed_by_us: ကျွန်ုပ်တို့မှ စောင့်ကြည့်ခဲ့သည် + total_reported: "၎င်းတို့နှင့်ဆိုင်သော အစီရင်ခံစာများ" total_storage: မီဒီယာ ပူးတွဲချက်များ + totals_time_period_hint_html: အောက်တွင်ဖော်ပြထားသော စုစုပေါင်းမှာ အချိန်တိုင်းအတွက် အချက်အလက်များဖြစ်သည်။ invites: + deactivate_all: အားလုံးပယ်ဖျက်ရန် filter: all: အားလုံး available: ရရှိနိုင်သော + expired: သက်တမ်းကုန်သွားပါပြီ + title: စစ်ထုတ်ခြင်း + title: ဖိတ်ခေါ်ခြင်း ip_blocks: + add_new: စည်းမျဉ်းဖန်တီးပါ + created_msg: IP စည်းမျဉ်းအသစ် ထည့်သွင်းပြီးပါပြီ delete: ဖျက်ပါ expires_in: - '1209600': 2 weeks - '15778476': 6 months - '2629746': 1 month - '31556952': 1 year - '86400': 1 day + '1209600': ၂ ပတ် + '15778476': ၆ လ + '2629746': ၁ လ + '31556952': ၁ နှစ် + '86400': ၁ ရက် '94670856': ၃ နှစ် + new: + title: IP စည်းမျဉ်းအသစ်ဖန်တီးပါ + no_ip_block_selected: မည်သည့် IP စည်းမျဉ်းကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ title: IP စည်းမျဉ်းများ + relationships: + title: "%{acct} နှင့် ပတ်သက်မှု" relays: + add_new: relay အသစ်ထည့်ပါ delete: ဖျက်ပါ + description_html: စာရင်းသွင်းပြီး ထုတ်ဝေသည့် ဆာဗာများအကြား အများသူငှာ ပို့စ်များ အများအပြားကို ဖလှယ်ပေးသည့် ကြားခံဆာဗာတစ်ခုဖြစ်သည်။ ၎င်းသည် အသေးစားနှင့် အလတ်စား ဆာဗာများမှ အကြောင်းအရာများကို ရှာဖွေတွေ့ရှိရန် ကူညီပေးနိုင်သည်၊ ၎င်းသည် ဒေသဆိုင်ရာအသုံးပြုသူများသည် အဝေးထိန်းဆာဗာများပေါ်တွင် အခြားလူများကို ကိုယ်တိုင်လိုက်လျှောက်ရန် လိုအပ်မည်ဖြစ်သည်။ disable: ပိတ်ပါ disabled: ပိတ်ထားသည် enable: ဖွင့်ပါ + enable_hint: တစ်ကြိမ်ဖွင့်ပြီးသည်နှင့် သင့်ဆာဗာသည် ဤထပ်ဆင့်လွှင့်မှုမှ အများမြင်ပို့စ်များအားလုံးကို စာရင်းသွင်းလိုက်မည်ဖြစ်ပြီး ဤဆာဗာ၏ အများမြင်ပို့စ်များကို ၎င်းထံ စတင်ပေးပို့မည်ဖြစ်သည်။ enabled: ဖွင့်ထားသည် + inbox_url: ထပ်ဆင့်ပေးပို့မည့် URL + pending: ထပ်ဆင့်အတည်ပြုချက်ကို စောင့်ဆိုင်းနေခြင်း + save_and_enable: သိမ်းပြီး ဖွင့်ရန် + setup: ထပ်ဆင့်ချိတ်ဆက်မှုစနစ် ထည့်သွင်းပါ + signatures_not_enabled: လုံခြုံရေးမုဒ် သို့မဟုတ် ကန့်သတ်ဖက်ဒီမုဒ်ကို ဖွင့်ထားစဉ် ထပ်ဆင့်ပို့ထားမှုများမှာ မှန်ကန်စွာ အလုပ်မလုပ်နိုင်တော့ပါ + status: အခြေအနေ + title: ထပ်ဆင့်ပေးပို့ခြင်းများ + report_notes: + created_msg: မှတ်တမ်းမှတ်စုကို ဖန်တီးပြီးပါပြီ။ + destroyed_msg: မှတ်တမ်းမှတ်စုကို ဖျက်ပြီးပါပြီ။ reports: + account: + notes: + other: "%{count} မှတ်စု" + action_log: မှတ်တမ်းများစစ်ဆေးခြင်း + action_taken_by: ဆောင်ရွက်ခဲ့ပါသည် + actions: + delete_description_html: အစီရင်ခံထားသော ပို့စ်များကို ဖျက်လိုက်မည်ဖြစ်ပြီး အကောင့်တစ်ခုတည်းမှ နောင်လာမည့် ချိုးဖောက်မှုများအပေါ် အရှိန်မြှင့်ကူညီရန် သတိပေးချက်တစ်ခု မှတ်တမ်းတင်ပါမည်။ + mark_as_sensitive_description_html: တိုင်ကြားထားသည့်ပို့စ်များရှိ မီဒီယာအား သတိထားရသောမီဒီယာအဖြစ် သတ်မှတ်ပြီး အကောင့်တူဖြင့် နောင် ချိုးဖောက်မှုများရှိပါက သတိပေးချက်တစ်ခုဖြင့် သင့်အတွက် မှတ်တမ်းပြုလုပ်ပေးထားပါမည်။ + other_description_html: အကောင့်ထိန်းချုပ်ရန်နှင့် တိုင်ကြားထားသည့်သို့ ဆက်သွယ်မှုကို စိတ်ကြိုက်ပြင်ဆင်ရန်တို့အတွက် နောက်ထပ်ရွေးချယ်စရာများကို ကြည့်ပါ။ + resolve_description_html: တိုင်ကြားထားသည့်အကောင့်ကို အရေးယူမည်မဟုတ်ပါ၊ လုပ်ဆောင်ချက်ကို မှတ်တမ်းတင်ထားခြင်းမရှိသည့်အပြင် တိုင်ကြားထားမှုကိုလည်း ရုပ်သိမ်းပါမည်။ + silence_description_html: အကောင့်ကို စောင့်ကြည့်ထားသူများ သို့မဟုတ် ရှာဖွေသူများသာ မြင်နိုင်မည်ဖြစ်ပါသည်။ အကောင့်တွေ့ရှိမှုအား ကန့်သတ်ထားသော်လည်း ပြန်ပြောင်းဆောင်ရွက်နိုင်ပါသည်။ ဤအကောင့်နှင့်ပတ်သက်သည့် မှတ်တမ်းအားလုံးကို ပိတ်ပါမည်။ + suspend_description_html: အကောင့်နှင့် ၎င်း၏အကြောင်းအရာအားလုံးမှာ သုံးခွင့်မရတော့သဖြင့် နောက်ဆုံးတွင် ဖျက်ပစ်မည်ဖြစ်ပါသည်။ ၎င်းနှင့် အပြန်အလှန်မတုံ့ပြန်နိုင်တော့သော်လည်း ရက် ၃၀ အတွင်း ပြန်ယူ၍ရနိုင်ပါသည်။ ဤအကောင့်နှင့်ပတ်သက်သည့် မှတ်တမ်းအားလုံးကို ပိတ်ပါမည်။ + actions_description_html: ဤမှတ်တမ်းဖြေရှင်းရန်အတွက် မည်သည့်လုပ်ဆောင်ချက် ဆောင်ရွက်မည်ကို ဆုံးဖြတ်ပါ။ တိုင်ကြားထားသောအကောင့်ကို ဆောင်ရွက်လိုပါက Spam မရွေးချယ်ဘဲ အီးမေးလ်အကြောင်းကြားစာ ပေးပို့ရပါမည်။ + actions_description_remote_html: ဤမှတ်တမ်းဖြေရှင်းရန်အတွက် မည်သည့်လုပ်ဆောင်ချက် ဆောင်ရွက်မည်ကို ဆုံးဖြတ်ပါ။ သင်၏ ဆာဗာသည် အဝေးမှထိန်းချုပ်ထားသောအကောင့်နှင့် ဆက်သွယ်ပြီး အကြောင်းအရာကိုင်တွယ်ပုံပေါ်မှာသာ သက်ရောက်မှုရှိမည်ဖြစ်သည်။ + add_to_report: အစီရင်ခံစာထပ်ထည့်ရန် + are_you_sure: သေချာပါသလား။ + assign_to_self: ကျွန်ုပ်ကို တာဝန်ပေးရန် + assigned: စိစစ်သူကို တာဝန်ပေးရန် + by_target_domain: တိုင်ကြားထားသော အကောင့်၏ ဒိုမိန်း + cancel: ပယ်ဖျက်မည် + category: အမျိုးအစား + category_description_html: ဤအကောင့်နှင့်/သို့မဟုတ် အကြောင်းအရာကို အစီရင်ခံထားသည့် အကြောင်းရင်းကို အစီရင်ခံထားသည့်အကောင့်နှင့် ဆက်သွယ်မှုတွင် ကိုးကားပါမည်။ + comment: + none: တစ်ခုမျှမရှိ + comment_description_html: "%{name} က နောက်ထပ်အချက်အလက်များ ပံ့ပိုးပေးနိုင်ရန်အတွက် ရေးသားခဲ့သည် -" + confirm: အတည်ပြုမည် + confirm_action: "@%{acct} ကို စိစစ်အကဲဖြတ်ခြင်းအား အတည်ပြုပါ" + created_at: အကြောင်းကြားပြီးပါပြီ delete_and_resolve: ပို့စ်များကို ဖျက်ပါ - view_profile: ပရိုဖိုင်ကိုကြည့်ရန် + forwarded: ထပ်ဆင့်ပို့ပြီးပါပြီ + forwarded_to: "%{domain} သို့ ထပ်ဆင့်ပို့ထားသည်" + mark_as_resolved: ဖြေရှင်းပြီးကြောင်း အမှတ်အသားပြုပါ + mark_as_sensitive: သတိထားရသည်ဟု အမှတ်အသားပြုပါ + mark_as_unresolved: မဖြေရှင်းရသေးကြောင်း အမှတ်အသားပြုပါ + no_one_assigned: တစ်ယောက်မျှမရှိပါ + notes: + create: မှတ်စုထည့်ရန် + create_and_resolve: မှတ်စုဖြင့် ဖြေရှင်းပါ + create_and_unresolve: မှတ်စုဖြင့် ပြန်ဖွင့်ရန် + delete: ဖျက်ပါ + placeholder: မည်သည့်လုပ်ဆောင်ချက်များ ဆောင်ရွက်ခဲ့သည်ကို ဖော်ပြပါ သို့မဟုတ် အခြားဆက်စပ် အပ်ဒိတ်များကို ဖော်ပြပါ ... + title: မှတ်စုများ + notes_description_html: အခြားစိစစ်သူများနှင့် ကိုယ်တိုင်အတွက် မှတ်စုများ ထားခဲ့ပါ + processed_msg: 'အကြောင်းကြားမှု #%{id} ကို ဆောင်ရွက်ပြီးပါပြီ' + quick_actions_description_html: တိုင်ကြားထားသောအကြောင်းအရာများကြည့်ရှုရန်အတွက် လုပ်ဆောင်ချက်တစ်ခု ဆောင်ရွက်ပါ သို့မဟုတ် Scroll ဆွဲ၍ ကြည့်ပါ - + remote_user_placeholder: "%{instance} မှ အဝေးကနေအသုံးပြုသူ" + reopen: အစီရင်ခံစာပြန်ဖွင့်ရန် + report: "#%{id} အစီရင်ခံရန်" + reported_account: တိုင်ကြားထားသောအကောင့် + reported_by: မှ တိုင်ကြားထားသည် + resolved: ဖြေရှင်းပြီးပါပြီ + resolved_msg: မှတ်တမ်းကို ဖြေရှင်းပြီးပါပြီ။ + skip_to_actions: လုပ်ဆောင်ချက်များသို့ ကျော်သွားရန် + status: အခြေအနေ + statuses: တိုင်ကြားထားသောအကြောင်းအရာ + statuses_description_html: စိတ်အ​နှောင့်အယှက်ဖြစ်​စေ​သောအကြောင်းအရာများကို အစီရင်ခံထားသောအကောင့်နှင့် ဆက်သွယ်ပြီး အ​ရေးယူ​ဆောင်ရွက်ပါမည် + summary: + action_preambles: + delete_html: သင်သည် @%{acct} ၏ ပို့စ်အချို့ကို ဖယ်ရှား တော့မည်ဖြစ်သည်။ ၎င်းတို့မှာ - + mark_as_sensitive_html: သင်သည် @%{acct} ၏ ပို့စ်အချို့ကို သတိထားရသောပို့စ်များ အဖြစ် အမှတ်အသားပြုတော့မည်ဖြစ်သည်။ ၎င်းတို့မှာ - + silence_html: သင်သည် @%{acct} ၏ အကောင့်ကို ကန့်သတ် တော့မည်ဖြစ်သည်။ ၎င်းမှာ - + suspend_html: သင်သည် @%{acct} ၏ အကောင့်ကို ဆိုင်းငံ့ တော့မည်ဖြစ်သည်။ ၎င်းမှာ - + actions: + delete_html: စိတ်အနှောင့်အယှက်ဖြစ်စေသောပို့စ်များကို ဖယ်ရှားပါ + mark_as_sensitive_html: စိတ်အနှောင့်အယှက်ဖြစ်စေသောပို့စ်များ၏ မီဒီယာကို သတိထားရသောမီဒီယာအဖြစ် အမှတ်အသားပြုပါ + silence_html: "၎င်းတို့၏ ပရိုဖိုင်နှင့် အကြောင်းအရာများကို ၎င်းတို့ကိုစောင့်ကြည့်နေသူများသာ မြင်နိုင်စေခြင်း သို့မဟုတ် ပရိုဖိုင်ကြည့်ရှုခြင်းဖြင့် @%{acct} အကောင့်ရောက်ရှိမှုကို ကန့်သတ်ပါ" + suspend_html: "@%{acct} ကို ဆိုင်းငံ့ထားသောကြောင့် ပရိုဖိုင်နှင့် အကြောင်းအရာများအား ဝင်ရောက်ခွင့်မရှိတော့သဖြင့် အပြန်အလှန် တုံ့ပြန်၍ မရတော့ခြင်း" + close_report: 'တိုင်ကြားစာ #%{id} ကို ဖြေရှင်းပြီးကြောင်း အမှတ်အသားပြုပါ' + close_reports_html: "@%{acct} နှင့်ပတ်သက်သည့် အစီရင်ခံစာအားလုံး ကို ဖြေရှင်းပြီးကြောင်း အမှတ်အသားပြုပါ" + delete_data_html: "@%{acct} ၏ ပရိုဖိုင်နှင့် အကြောင်းအရာများကို ဆိုင်းငံ့ထားခြင်းမရှိပါက ယခုမှ ရက်ပေါင်း ၃၀ အတွင်း ဖျက်ရန်" + preview_preamble_html: "@%{acct} သည် အောက်ပါအကြောင်းအရာများကြောင့် သတိပေးချက်ကို လက်ခံရရှိပါမည် -" + record_strike_html: ဤအကောင့်မှ နောင်လာမည့် ချိုးဖောက်မှုများအတွက် အရေးယူနိုင်ရန် @%{acct} သတိပေးချက်တစ်ခု မှတ်တမ်းယူထားပါ + send_email_html: သတိပေးချက် အီးမေးလ်တစ်စောင် @%{acct} ပေးပို့ပါ + warning_placeholder: စိစစ်ခြင်းအတွက် ရွေးချယ်နိုင်သော ထပ်လောင်းအကြောင်းပြချက်။ + target_origin: တိုင်ကြားထားသောအကောင့်၏ မူလအစ + title: မှတ်တမ်းများ + unassign: တာဝန်မှဖြုတ်ရန် + unknown_action_msg: အမည်မသိလုပ်ဆောင်ချက်- %{action} + unresolved: မဖြေရှင်းရသေးပါ + updated_at: ပြင်ဆင်ပြီးပါပြီ + view_profile: ပရိုဖိုင်ကြည့်ရန် roles: + add_new: အခန်းကဏ္ဍထည့်ပါ + assigned_users: + other: "%{count} အသုံးပြုသူ" categories: + administration: စီမံခန့်ခွဲခြင်း devops: DevOps + invites: ဖိတ်ခေါ်ခြင်း + moderation: စိစစ်ခြင်း + special: အထူး delete: ဖျက်ပါ + description_html: "အသုံးပြုသူအခန်းကဏ္ဍများဖြင့် Mastodon အသုံးပြုသူများ၏ မည်သည့်လုပ်ဆောင်ချက်များနှင့် နေရာများကိုမဆို သင် စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါသည်။" + edit: "'%{name} ၏ အခန်းကဏ္ဍကို ပြင်ဆင်ရန်" + everyone: မူလသတ်မှတ်ထားသည့် ခွင့်ပြုချက်များ + everyone_full_description_html: ဤသည်မှာ အခန်းကဏ္ဍတာဝန်ပေးထားခြင်းမရှိသော အသုံးပြုသူအားလုံး အပေါ် သက်ရောက်သည့် အခြေခံအခန်းကဏ္ဍ ပင်ဖြစ်သည်။ အခြားကဏ္ဍများအားလုံးမှာ ၎င်းထံမှ ခွင့်ပြုချက်များ ယူရပါသည်။ permissions_count: other: "%{count} ခွင့်ပြုချက်" privileges: + administrator: စီမံသူ + administrator_description: ဤခွင့်ပြုချက် အသုံးပြုသူများအနေဖြင့် ခွင့်ပြုချက်တိုင်းကို ကျော်သွားနိုင်ပါမည် + delete_user_data: အသုံးပြုသူ၏အချက်အလက်ကို ဖျက်ပါ + delete_user_data_description: အခြားအသုံးပြုသူများ၏ အချက်အလက်များကို နှောင့်နှေးခြင်းမရှိဘဲ အသုံးပြုသူများအား ဖျက်ခွင့်ပြုသည် + invite_users: အသုံးပြုသူများကို ဖိတ်ခေါ်ရန် + invite_users_description: ဆာဗာသို့ လူသစ်များဖိတ်ခေါ်ရန်အတွက် အသုံးပြုသူအား ခွင့်ပြုရန် manage_announcements: ကြေညာချက်များကို စီမံပါ + manage_announcements_description: ဆာဗာပေါ်တွင် ကြေညာချက်များစီမံရန်အတွက် အသုံးပြုသူအား ခွင့်ပြုရန် + manage_appeals: အယူခံဝင်ထားခြင်းများကို စီမံပါ + manage_appeals_description: စိစစ်အရေးယူမှုများအပေါ် အယူခံဝင်မှုများ ပြန်လည်သုံးသပ်ရန်အတွက် အသုံးပြုသူများအား ခွင့်ပြုရန် + manage_blocks: ပိတ်ပင်ထားမှုများကို စီမံပါ + manage_blocks_description: အသုံးပြုသူများအား အီးမေးလ်ဝန်ဆောင်မှုပေးသူများနှင့် IP လိပ်စာများကို ပိတ်ဆို့ရန် ခွင့်ပြုသည် + manage_custom_emojis: စိတ်ကြိုက်အီမိုဂျီများကို ပြင်ဆင်ရန် + manage_custom_emojis_description: အသုံးပြုသူများအား ဆာဗာပေါ်တွင် စိတ်ကြိုက်အီမိုဂျီများကို စီမံခန့်ခွဲရန် ခွင့်ပြုသည်။ + manage_federation: ဖက်ဒီကို စီမံပါ + manage_federation_description: အသုံးပြုသူများအား အခြားဒိုမိန်းများနှင့် ပိတ်ပင်ခြင်း၊ ဖက်ဒီခွင့်ပြုခြင်းနှင့် ပေးပို့နိုင်မှုကို ထိန်းချုပ်ခြင်းတို့ကို ခွင့်ပြုသည်။ + manage_invites: ဖိတ်ခေါ်ခြင်းကို စီမံရန် + manage_invites_description: အသုံးပြုသူများအား ဖိတ်ခေါ်ထားသည့်လင့်များကို ရှာဖွေကြည့်ရှုပြီး ပိတ်ရန် ခွင့်ပြုသည် + manage_reports: အစီရင်ခံစာများကို စီမံပါ + manage_reports_description: အသုံးပြုသူများအား အစီရင်ခံစာများကို ပြန်လည်သုံးသပ်ရန်နှင့် ၎င်းတို့နှင့် ဆန့်ကျင်သည့် စိစစ်အရေးယူမှုများကို လုပ်ဆောင်ရန် ခွင့်ပြုသည် + manage_roles: အခန်းကဏ္ဍများကို စီမံပါ + manage_roles_description: အသုံးပြုသူများအား ၎င်းတို့၏အောက်တွင်ရှိသော အခန်းကဏ္ဍများကို စီမံခန့်ခွဲရန်နှင့် သတ်မှတ်ရန် ခွင့်ပြုထားသည် + manage_rules: စည်းမျဉ်းများကို စီမံပါ + manage_rules_description: အသုံးပြုသူများအား ဆာဗာစည်းမျဉ်းများကို ပြောင်းလဲခွင့် ပြုထားသည် manage_settings: သတ်မှတ်ချက်များကို စီမံပါ + manage_settings_description: အသုံးပြုသူများကို ဆိုက်သတ်မှတ်ချက်များ ပြောင်းလဲခွင့် ပြုရန် + manage_taxonomies: အမျိုးအစားခွဲခြားပါ + manage_taxonomies_description: ခေတ်စားနေသော အကြောင်းအရာများကို ပြန်လည်သုံးသပ်ရန်နှင့် hashtag သတ်မှတ်ချက်များကို ပြင်ဆင်ရန်အတွက် အသုံးပြုသူများကို ခွင့်ပြုသည် + manage_user_access: အသုံးပြုသူဝင်ရောက်မှုကို စီမံပါ + manage_user_access_description: အသုံးပြုသူများကို အခြားအသုံးပြုသူများ၏ နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို ပိတ်ရန်၊ ၎င်းတို့၏ အီးမေးလ်လိပ်စာကို ပြောင်းလဲရန်နှင့် စကားဝှက်ကို ပြန်လည်သတ်မှတ်ရန် ခွင့်ပြုသည် manage_users: အသုံးပြုသူများကို စီမံပါ + manage_users_description: အသုံးပြုသူများအား အခြားအသုံးပြုသူများ၏ အသေးစိတ်အချက်အလက်များကို ကြည့်ရှုနိုင်ပြီး ၎င်းတို့နှင့် ဆန့်ကျင်သည့် စိစစ်အရေးယူမှုများကို လုပ်ဆောင်ခွင့်ပြုသည် + manage_webhooks: Webhooks ကို စီမံပါ + manage_webhooks_description: စီမံခန့်ခွဲရေးဆိုင်ရာ ဖြစ်ရပ်များအတွက် အသုံးပြုသူများအား webhook စနစ်ထည့်သွင်းရန် ခွင့်ပြုထားသည် + view_audit_log: စာရင်းမှတ်တမ်းကို ကြည့်ရန် + view_audit_log_description: အသုံးပြုသူများကို ဆာဗာပေါ်တွင် စီမံခန့်ခွဲရေးဆိုင်ရာ လုပ်ဆောင်ချက်မှတ်တမ်းကို ကြည့်ရှုခွင့်ပြုသည်။ + view_dashboard: ဒက်ရှ်ဘုတ်မြင်ကွင်းကို ကြည့်ရန် + view_dashboard_description: အသုံးပြုသူများကို ဒက်ရှ်ဘုတ်မြင်ကွင်းနှင့် အမျိုးမျိုးသော ဆိုဒ်နှင့်ဆိုင်သောဂဏန်းများအား ဝင်ရောက်ကြည့်ရှုခွင့်ပြုသည် view_devops: DevOps + view_devops_description: အသုံးပြုသူများကို Sidekiq နှင့် pgHero ဒက်ရှ်ဘုတ်မြင်ကွင်းများသို့ ဝင်ရောက်ခွင့်ပြုသည် + title: အခန်းကဏ္ဍများ rules: + add_new: စည်းမျဉ်းထည့်ပါ delete: ဖျက်ပါ + description_html: စည်းမျဉ်းများဖတ်ရှုပြီး သဘောတူသည်ဟု အများစုကဆိုကြသော်လည်း များသောအားဖြင့် ပြဿနာပေါ်ပေါက်လာသည်အထိ မဖတ်ကြပါ။ သင့်ဆာဗာစည်းမျဉ်းများကို flat bullet point စာရင်းတွင် ထည့်သွင်းခြင်းဖြင့် ကြည့်ရှု၍ ပိုမိုလွယ်ကူအောင် ဆောင်ရွက်ပါ။ စည်းမျဉ်းတစ်ခုချင်းစီကို တိုတိုနှင့် ရိုးရိုးရှင်းရှင်းထားပြီး ၎င်းတို့ကို သီးခြားခွဲထွက်မသွားစေရန် လုပ်ဆောင်ပါ။ + edit: စည်းမျဉ်းကို ပြင်ဆင်မည် + empty: ဆာဗာစည်းမျဉ်းများကို မသတ်မှတ်ရသေးပါ။ title: ဆာဗာစည်းမျဉ်းများ settings: about: + manage_rules: ဆာဗာစည်းမျဉ်းများကို စီမံရန် + preamble: ဆာဗာလည်ပတ်မှု၊ စိစစ်မှု၊၊ ငွေကြေးထောက်ပံ့မှုတို့အကြောင်း အသေးစိတ်အချက်အလက်များ ပေးပါ။ + rules_hint: အသုံးပြုသူများ လိုက်နာရမည့် စည်းမျဉ်းများအတွက် သီးခြားနေရာတစ်ခု ရှိပါသည်။ title: အကြောင်း + appearance: + preamble: Mastodon ၏ ဝဘ်ပုံစံကို စိတ်ကြိုက်ပြင်ဆင်ပါ။ + title: ပုံပန်းသဏ္ဌာန် + branding: + preamble: သင့်ဆာဗာအကြောင်းကို ကွန်ရက်အတွင်းရှိ အခြားဆာဗာများနှင့် ကွဲပြားစေရန်ဆောင်ရွက်ပါ။ Mastodon ၏ ဝဘ်အင်တာဖေ့စ်၊ မူရင်းအက်လီကေးရှင်းများ၊ အခြားဝဘ်ဆိုက်များပေါ်ရှိ လင့်ခ်အစမ်းကြည့်ရှုခြင်းများနှင့် မက်ဆေ့ခ်ျပေးပို့ခြင်းအက်ပ်များအတွင်း အစရှိသည့် အမျိုးမျိုးတွင် ဤအချက်အလက်များကို ပြသနိုင်ပါသည်။ ထို့ကြောင့် ဤအချက်အလက်များကို တိုတောင်းရှင်းလင်းစွာ ရေးသင့်ပါသည်။ + title: ခေါင်းစဉ်တပ်ခြင်း + captcha_enabled: + desc_html: "၎င်းသည် လုံခြုံရေးနှင့် ကိုယ်ရေးကိုယ်တာဆိုင်ရာ hCaptcha မှ ပြင်ပ script များအပေါ်တွင် မူတည်ပါသည်။ ထို့ပြင် မှတ်ပုံတင်ခြင်းလုပ်ငန်းစဉ်ကို အချို့သော သူများ (အထူးသဖြင့် မသန်စွမ်းသူများ) အတွက် သက်ရောက်မှုအားနည်းနေပါသည်။။ ဤအကြောင်းများကြောင့် ခွင့်ပြုချက်အခြေခံ သို့မဟုတ် ဖိတ်ခေါ်မှုအခြေခံ မှတ်ပုံတင်ခြင်းကဲ့သို့သော အခြားအစီအမံများကို ထည့်သွင်းစဉ်းစားသင့်ပါသည်။" + title: "၎င်းတို့၏အကောင့်ကိုအတည်ပြုရန်အတွက် CAPTCHA ဖြေရှင်းရန် အသုံးပြုသူအသစ်များ လိုအပ်သည်" + content_retention: + preamble: Mastodon တွင် အသုံးပြုသူဖန်တီးထားသော အကြောင်းအရာများ မည်သို့သိမ်းဆည်းမည်ကို ထိန်းချုပ်ပါ။ + title: အကြောင်းအရာ ဆက်လက်ရှိနေခြင်း + default_noindex: + desc_html: ဤသတ်မှတ်ချက်ကို ကိုယ်တိုင်မပြောင်းရသေးသော အသုံးပြုသူအားလုံးအပေါ် သက်ရောက်မှုရှိသည် + title: ပုံမှန်အားဖြင့် ရှာဖွေမှုအညွှန်းကိန်းမှ သုံးစွဲသူများကို ဖယ်ထုတ်ပါ + discovery: + follow_recommendations: အကြံပြုချက်များကို စောင့်ကြည့်ပါ + preamble: စိတ်ဝင်စားစရာကောင်းသော အကြောင်းအရာများပြထားခြင်းမှာ Mastodon ကို မသိသေးသော သုံးစွဲသူအသစ်များအတွက် အရေးပါပါသည်။ သင့်ဆာဗာတွင် မည်သည့်ရှာဖွေတွေ့ရှိမှုအကြောင်းအရာများ ပြထားမည်ကို ထိန်းချုပ်ပါ။ + profile_directory: ပရိုဖိုင်လမ်းညွှန် + public_timelines: အများမြင်စာမျက်နှာ + publish_discovered_servers: ရှာဖွေတွေ့ရှိထားသော ဆာဗာများကို ထုတ်ပြန်ပါ + publish_statistics: စာရင်းဇယားထုတ်ပြန်မည် + title: ရှာဖွေတွေ့ရှိမှု + trends: လက်ရှိခေတ်စားမှုများ + domain_blocks: + all: လူတိုင်း + disabled: မည်သူ့ကိုမျှ + users: အကောင့်ဝင်ထားသော ပြည်တွင်းအသုံးပြုသူများအတွက် + registrations: + preamble: သင့်ဆာဗာတွင် အကောင့်တစ်ခုမည်သူဖန်တီးနိုင်သည်ကို ထိန်းချုပ်ပါ။ + title: စာရင်းသွင်းထားခြင်းများ + registrations_mode: + modes: + approved: အကောင့်ဖွင့်ရန်အတွက် အတည်ပြုချက် လိုအပ်ပါသည် + none: မည်သူမျှ အကောင့်ဖွင့်၍မရပါ + open: မည်သူမဆို အကောင့်ဖွင့်နိုင်ပါသည် + security: + authorized_fetch: ဖက်ဒီဆာဗာများမှ စစ်မှန်ကြောင်းအထောက်အထားပြရန် လိုအပ်သည်။ + title: ဆာဗာသတ်မှတ်ချက်များ + site_uploads: + delete: တင်ထားသောဖိုင်ဖျက်ရန် + destroyed_msg: ဆိုက်အပ်လုဒ်ကို အောင်မြင်စွာ ဖျက်လိုက်ပါပြီ။ + software_updates: + critical_update: အရေးကြီးသည် — ကျေးဇူးပြု၍ မြန်မြန်အပ်ဒိတ်လုပ်ပါ + documentation_link: ပိုမိုသိရှိရန် + release_notes: ထုတ်ဝေမှုမှတ်စုများ + title: ရရှိနိုင်သော အပ်ဒိတ်များ + type: အမျိုးအစား + types: + major: အဓိကထုတ်ဝေမှု + version: ဗားရှင်း statuses: account: ရေးသားသူ + application: အက်ပလီကေးရှင်း back_to_account: အကောင့်စာမျက်နှာသို့ ပြန်သွားရန် + back_to_report: အစီရင်ခံစာ စာမျက်နှာသို့ ပြန်သွားရန် + batch: + remove_from_report: တိုင်ကြားစာမှ ဖယ်ရှားပါ + report: တိုင်ကြားစာ deleted: ဖျက်ပြီးပါပြီ + favourites: အကြိုက်ဆုံးများ + history: ဗားရှင်းမှတ်တမ်း + in_reply_to: ထံ အကြောင်းပြန်ကြားခြင်း language: ဘာသာစကား media: title: မီဒီယာ + metadata: Metadata + no_status_selected: မည်သည့်ပို့စ်ကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + open: ပို့စ်ဖွင့်ရန် + original_status: မူရင်းပို့စ် + reblogs: Reblog များ + status_changed: ပို့စ်ပြောင်းပြီးပါပြီ + title: အကောင့်ပို့စ်များ + trending: လက်ရှိခေတ်စားနေခြင်း + visibility: မြင်နိုင်မှု + with_media: မီဒီယာနှင့်အတူ + strikes: + actions: + delete_statuses: "%{name} မှ %{target} ၏ ပို့စ်များကို ဖျက်ခဲ့သည်" + disable: "%{name} က %{target} ၏ အကောင့်ကို ရပ်ထားသည်" + mark_statuses_as_sensitive: "%{name} က %{target} ၏ ပို့စ်များကို သတိထားရသောပို့စ်များအဖြစ် အမှတ်အသားပြုထားသည်" + none: "%{name} မှ %{target} သို့ သတိပေးချက်တစ်ခု ပေးပို့ခဲ့သည်" + sensitive: "%{name} က %{target} ၏ အကောင့်ကို သတိထားရသောအကောင့်အဖြစ် အမှတ်အသားပြုထားသည်" + silence: "%{name} က %{target} ၏ အကောင့်ကို ကန့်သတ်ထားသည်" + suspend: "%{name} က %{target} ၏ အကောင့်ကို ဆိုင်းငံ့ထားသည်" + appeal_approved: အတည်ပြုခဲ့ပြီး + appeal_pending: အတည်ပြုမှုဆိုင်းငံ့ထားခြင်း + appeal_rejected: တင်ပြခြင်းကို ပယ်ချခဲ့သည် + system_checks: + database_schema_check: + message_html: ဆိုင်းငံ့ထားသော ဒေတာဘေ့စ် ပြောင်းရွှေ့မှုများ ရှိပါသည်။ အပလီကေးရှင်းသည် မျှော်လင့်ထားသည့်အတိုင်း လုပ်ဆောင်ကြောင်း သေချာစေရန် ၎င်းတို့ကို လုပ်ဆောင်ပါ။ + elasticsearch_preset: + action: စာရွက်စာတမ်းများကို ကြည့်ပါ + elasticsearch_preset_single_node: + action: စာရွက်စာတမ်းများကို ကြည့်ပါ + elasticsearch_running_check: + message_html: Elasticsearch သို့ ချိတ်ဆက်၍မရပါ။ ၎င်းသည် အလုပ်လုပ်နေသလား၊ သို့မဟုတ် စာသားအပြည့်အစုံရှာဖွေမှုကို ပိတ်ပါ။ + elasticsearch_version_check: + message_html: သဟဇာတမဖြစ်သော Elasticsearch ဗားရှင်း- %{value} + version_comparison: Elasticsearch %{running_version} သည် %{required_version} လိုအပ်နေချိန်တွင် လုပ်ဆောင်နေသည် + rules_check: + action: ဆာဗာစည်းမျဉ်းများကို စီမံရန် + message_html: သင်သည် မည်သည့်ဆာဗာစည်းမျဉ်းများကိုမျှ မသတ်မှတ်ထားပါ။ + sidekiq_process_check: + message_html: "%{value} တန်းစီ(s) အတွက် Sidekiq လုပ်ငန်းစဉ် မရှိပါ။ သင်၏ Sidekiq ဖွဲ့စည်းမှုကို ပြန်လည်သုံးသပ်ပါ။" + software_version_critical_check: + action: ရရှိနိုင်သော အပ်ဒိတ်များကြည့်ပါ + message_html: Mastodon အပ်ဒိတ်ရနိုင်သည်၊ ကျေးဇူးပြု၍ မြန်မြန် အပ်ဒိတ်လုပ်ပါ။ + software_version_patch_check: + action: ရရှိနိုင်သော အပ်ဒိတ်များကြည့်ပါ + message_html: ပြင်ဆင်ပြီးသော Mastodon အပ်ဒိတ် ရနိုင်ပါသည် + upload_check_privacy_error: + action: နောက်ထပ်အချက်အလက်များအတွက် ဤနေရာတွင် ကြည့်ပါ + message_html: "သင်၏ဝဘ်ဆာဗာကို မှားယွင်းစွာပြုလုပ်ထားသည်။ သင့်အသုံးပြုသူများ၏ လျှို့ဝှက်ချက်များသည် အန္တရာယ်ရှိသည်။" + upload_check_privacy_error_object_storage: + action: နောက်ထပ်အချက်အလက်များအတွက် ဤနေရာတွင် ကြည့်ပါ + message_html: "သင်၏ Object သိုလှောင်မှုအား မှားယွင်းစွာ စီစဉ်သတ်မှတ်ထားပါသည်။ သင့်အသုံးပြုသူများ၏ လျှို့ဝှက်ချက်များသည် အန္တရာယ်ရှိသည်။" + tags: + review: အခြေအနေသုံးသပ်ရန် + updated_msg: ဟက်ရှ်တဂျ်သတ်မှတ်ချက်များကို အပ်ဒိတ်လုပ်ပြီးပါပြီ + title: စီမံခန့်ခွဲခြင်း trends: allow: ခွင့်ပြု + approved: အတည်ပြုပြီးပါပြီ disallow: ခွင့်မပြု + links: + allow: လင့်ခ်ကို ခွင့်ပြုရန် + allow_provider: ပို့စ်တင်သူကိုခွင့်ပြုရန် + description_html: "၎င်းတို့သည် သင့်ဆာဗာမှ ပို့စ်များကို မြင်သည့် အကောင့်များမှ လောလောဆယ်တွင် အများအပြားမျှဝေနေသည့် လင့်ခ်များဖြစ်သည်။ ၎င်းသည် သင့်အသုံးပြုသူများအား ကမ္ဘာပေါ်တွင် ဖြစ်ပျက်နေသည့်အရာများကို ရှာဖွေရန် ကူညီပေးနိုင်ပါသည်။ ထုတ်ဝေသူအား သင်အတည်မပြုမချင်း လင့်ခ်များကို လူသိရှင်ကြားပြသခြင်းမရှိပါ။ တစ်ဦးချင်း လင့်ခ်များကို သင် ခွင့်ပြုနိုင်သည် သို့မဟုတ် ငြင်းပယ်နိုင်သည်။" + disallow: လင့်ခ်ကို ခွင့်မပြုရန် + disallow_provider: ပို့စ်တင်သူကို ခွင့်မပြုရန် + no_link_selected: မည်သည့်လင့်ခ်ကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + publishers: + no_publisher_selected: မည်သည့်ပို့စ်တင်သူကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + shared_by_over_week: + other: ပြီးခဲ့သည့်အပတ်တွင် လူ %{count} ဦး မှ မျှဝေခဲ့သည် + title: လက်ရှိခေတ်စားနေသော လင့်များ + usage_comparison: မနေ့က %{yesterday} နှင့် နှိုင်းယှဉ်၍ ယနေ့ %{today} ကြိမ် မျှဝေခဲ့သည် + not_allowed_to_trend: ခေတ်စားနေသည့်အကြောင်းအရာပြုလုပ်ရန် ခွင့်မပြုပါ + only_allowed: သာခွင့်ပြုသည် + pending_review: ဆိုင်းငံ့ထားသော သုံးသပ်ချက် + preview_card_providers: + allowed: ဤပို့စ်တင်သူထံမှ လင့်ခ်များ ခေတ်စားနိုင်သည် + description_html: "၎င်းတို့သည် သင့်ဆာဗာပေါ်တွင် မကြာခဏ လင့်ခ်များကို မျှဝေလေ့ရှိသည့် ဒိုမိန်းများဖြစ်သည်။ လင့်ခ်၏ဒိုမိန်းကို အတည်ပြုမထားပါက လင့်ခ်များသည် လူသိရှင်ကြား လမ်းကြောင်းပေါ်ရှိလိမ့်မည်မဟုတ်ပါ။ သင့်ခွင့်ပြုချက် (သို့မဟုတ် ငြင်းပယ်ခြင်း) သည် ဒိုမိန်းခွဲများသို့ အကျုံးဝင်ပါသည်။" + rejected: ဤထုတ်ဝေသူထံမှ လင့်ခ်များ ခေတ်စားလာမည်မဟုတ်ပါ။ + title: ပို့စ်တင်သူများ + rejected: ဖယ်ရှားပြီးပါပြီ + statuses: + allow: ပို့စ်တင်ခွင့်ပြုရန် + allow_account: ပို့စ်တင်သူကို ခွင့်ပြုပါ + description_html: ဤအရာများသည် သင့်ဆာဗာမှ သိရှိထားသည့် ပို့စ်များဖြစ်ပြီး လက်ရှိတွင် မျှဝေလျက်ရှိပြီး ယခုအချိန်တွင် လူကြိုက်များသော ပို့စ်များဖြစ်သည်။ ၎င်းသည် သင်၏အသစ်နှင့် ပြန်လာသောအသုံးပြုသူများကို လိုက်ကြည့်ရန် နောက်ထပ်လူများကို ရှာဖွေရန် ကူညီပေးနိုင်သည်။ စာရေးဆရာကို သင်အတည်ပြုသည့်တိုင်အောင် မည်သည့်ပို့စ်ကိုမျှ လူသိရှင်ကြားမပြသဘဲ၊ စာရေးသူက ၎င်းတို့၏အကောင့်ကို အခြားသူများထံ အကြံပြုခွင့်ပြုသည်။ တစ်ဦးချင်း ပို့စ်များကို ခွင့်ပြုနိုင်သည် သို့မဟုတ် ငြင်းပယ်နိုင်သည်။ + disallow: ပို့စ်ကို တင်ခွင့်မပြုရန် + disallow_account: ပို့စ်တင်သူကို ခွင့်မပြုပါနဲ့ + no_status_selected: မည်သည့်ခေတ်စားနေသောပို့စ်ကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + not_discoverable: စာရေးသူသည် ရှာဖွေတွေ့ရှိနိုင်မှုကို ရွေးချယ်မထားပါ။ + shared_by: + other: မျှဝေမှုနှင့် နှစ်သက်မှု %{friendly_count} ကြိမ် + title: လက်ရှိခေတ်စားနေသော ပို့စ်များ tags: + current_score: "%{score} လက်ရှိရမှတ်" + dashboard: + tag_accounts_measure: အများဆုံးအသုံပြုမှုများ + tag_languages_dimension: အသုံးများသည့်ဘာသာစကားများ + tag_servers_dimension: အသုံးများသည့်ဆာဗာများ + tag_servers_measure: မတူညီသောဆာဗာများ + tag_uses_measure: စုစုပေါင်းအသုံးပြုမှု + description_html: "၎င်းတို့သည် သင့်ဆာဗာမြင်နေရသည့် ပို့စ်အများအပြားတွင် လက်ရှိမြင်နေရသည့် hashtag များဖြစ်သည်။ ၎င်းသည် သင့်အသုံးပြုသူများအား ယခုအချိန်တွင် လူအများပြောနေသည့်အရာများကို သိရှိနိုင်ရန် ကူညီပေးနိုင်ပါသည်။ ၎င်းတို့ကို သင်အတည်မပြုမချင်း hashtags များကို လူသိရှင်ကြား ပြသမည်မဟုတ်ပါ။" + listable: အကြံပြုနိုင်ပါသည် + no_tag_selected: မည်သည့်တဂျ်ကိုမျှ ရွေးချယ်ထားခြင်းမရှိသောကြောင့် ပြောင်းလဲခြင်းမရှိပါ + not_listable: အကြံပြုမည်မဟုတ်ပါ + not_trendable: လက်ရှိခေတ်စားနေသာပို့စ်များအောက်တွင် ပေါ်လာမည်မဟုတ်ပါ not_usable: အသုံးမပြုနိုင်ပါ + peaked_on_and_decaying: "%{date} ရက်တွင် ခေတ်စားခဲ့သော်လည်း ယခု ခေတ်မစားတော့ပါ" + title: လက်ရှိခေတ်စားနေသော hashtag များ + trendable: လက်ရှိခေတ်စားနေသာပို့စ်များအောက်တွင် ပေါ်လာမည် + trending_rank: "#%{rank} ခေတ်စားနေခြင်း" usable: အသုံးပြုနိုင်သည် + usage_comparison: မနေ့က %{yesterday} နှင့် နှိုင်းယှဉ်လျှင် ယနေ့ %{today} ကြိမ် အသုံးပြုခဲ့သည် + used_by_over_week: + other: ပြီးခဲ့သည့် ရက်သတ္တပတ်အတွင်း လူ %{count} ဦး အသုံးပြုခဲ့သည်။ + title: လက်ရှိခေတ်စားမှုများ + trending: လက်ရှိခေတ်စားနေခြင်း warning_presets: add_new: အသစ်ထည့်ပါ delete: ဖျက်ပါ + edit_preset: ကြိုသတိပေးချက်ကို ပြင်ဆင်ပါ + empty: ကြိုသတိပေးချက်များကို မသတ်မှတ်ရသေးပါ။ + title: ကြိုသတိပေးချက်များကို စီမံပါ webhooks: + add_new: ဆုံးမှတ် ထည့်ပါ delete: ဖျက်ပါ + description_html: "webhook သည် Mastodon အား ရွေးချယ်ထားသော အစီအစဉ်များအကြောင်း သင့်ကိုယ်ပိုင်အက်ပ်လီကေးရှင်းသို့ အချိန်နှင့်တစ်ပြေးညီ အသိပေးချက်များကို တွန်းပို့နိုင်သည်၊ ထို့ကြောင့် သင့်အပလီကေးရှင်းသည် တုံ့ပြန်မှုများကို အလိုအလျောက်စတင်နိုင်သည်။" + disable: ပိတ်ပါ + disabled: ပိတ်ထားသည် + edit: ဆုံးမှတ် ပြင်ဆင်ပါ + empty: မည်သည့် webhook endpoints မှ မစီစဉ်ရသေးပါ။ enable: ဖွင့်ပါ + enabled: လက်ရှိ + enabled_events: + other: ဖွင့်ထားသောအစီအစဉ်များ %{count} ခု + events: ပွဲအစီအစဉ်များ + new: webhook အသစ် + rotate_secret: Rotate secret ထားပါ + secret: လျှို့ဝှက်လက်မှတ်ထိုးခြင်း + status: အခြေအနေ + title: Webhook များ + webhook: Webhook + admin_mailer: + new_appeal: + actions: + delete_statuses: "၎င်းတို့၏ ပို့စ်များကို ဖျက်ရန်" + disable: "၎င်းတို့အကောင့်များအား ရပ်ထားရန်" + mark_statuses_as_sensitive: "၎င်းတို့၏ ပို့စ်များကို သတိထားရသော ပို့စ်များအဖြစ် အမှတ်အသားပြုရန်" + none: သတိပေးချက် + sensitive: "၎င်းတို့၏ အကောင့်များကို သတိထားရသော အကောင့်များအဖြစ် အမှတ်အသားပြုရန်" + silence: "၎င်းတို့၏ ပို့စ်များကို ကန့်သတ်ရန်" + suspend: "၎င်းတို့၏ အကောင့်ကို ရပ်ဆိုင်းရန်" + body: "%{target} သည် %{type} ဖြစ်သည့် %{date} တွင် %{action_taken_by} ဖြင့် စိစစ်မှုတစ်ခုအား အယူခံဝင်နေပါသည်။ သူတို့ရေးသားခဲ့သည် -" + next_steps: စိစစ်ဆုံးဖြတ်ချက်ပြန်ဖျက်ရန်အတွက် တင်ပြနိုင်သည် သို့မဟုတ် ၎င်းကို လျစ်လျူရှုနိုင်သည်။ + subject: "%{username} က %{instance} တွင် စိစစ်ဆုံးဖြတ်ချက်ကို တင်ပြနေသည်" + new_critical_software_updates: + body: Mastodon ၏ ဗားရှင်းအသစ်များကို ထုတ်ဝေလိုက်ပါပြီ၊ အမြန်ဆုံး အပ်ဒိတ်လုပ်နိုင်ပါသည်။ + subject: Mastodon အပ်ဒိတ်များကို %{instance} အတွက် ရနိုင်ပါသည်။ + new_pending_account: + body: အကောင့်သစ်၏အသေးစိတ်ကို အောက်တွင်ဖော်ပြထားသည်။ ၎င်းကို အတည်ပြုနိုင်သည် သို့မဟုတ် ငြင်းပယ်နိုင်သည်။ + subject: " (%{username}) %{instance} ပေါ်ရှိ ပြန်လည်သုံးသပ်ရမည့် အကောင့်သစ်" + new_report: + body: "%{reporter} က %{target} ကို တိုင်ကြားခဲ့သည်" + body_remote: "%{domain} မှ တစ်စုံတစ်ယောက်က %{target} ကို တိုင်ကြားခဲ့သည်" + subject: "%{instance} (#%{id}) အတွက် တိုင်ကြားစာအသစ်" + new_software_updates: + body: Mastodon ဗားရှင်းအသစ်များ ထွက်ရှိပြီးပါပြီ၊ သင် update လုပ်နိုင်ပါပြီ။ + subject: Mastodon ဗားရှင်းအသစ်များကို %{instance} အတွက် ရနိုင်ပါသည် + new_trends: + body: အောက်ပါအရာများကို အများကိုမပြမီ ပြန်လည်သုံးသပ်ရန် လိုအပ်သည် - + new_trending_links: + title: လက်ရှိခေတ်စားနေသော လင့်များ + new_trending_statuses: + title: လက်ရှိခေတ်စားနေသော ပို့စ်များ + new_trending_tags: + no_approved_tags: လက်ရှိတွင် အတည်ပြုထားသော ခေတ်စားနေသည့် hashtag များမရှိပါ။ + requirements: 'ဤလူများမှာ %{lowest_tag_score} ရမှတ်ဖြင့် လက်ရှိ #%{lowest_tag_name} ဖြစ်သည့် ခေတ်စားနေသော hashtag #%{rank} ကို ကျော်သွားနိုင်သည်။' + title: လက်ရှိခေတ်စားနေသော hashtag များ + subject: "%{instance} တွင် ပြန်လည်သုံးသပ်ရမည့် ခေတ်စားနေသောပို့စ်အသစ်များ" + aliases: + add_new: နာမည်တူတစ်ခု ဖန်တီးမည် + created_msg: နာမည်တူတစ်ခုကို ဖန်တီးပြီးပါပြီ။ အကောင့်ဟောင်းမှ စတင်ရွှေ့နိုင်ပါပြီ။ + deleted_msg: နာမည်တူကို ဖယ်ရှားထားပြီးပါပြီ။ ထိုအကောင့်မှ ဤအကောင့်သို့ပြောင်းရန် မဖြစ်နိုင်တော့ပါ။ + empty: သင့်တွင် နာမည်တူများ မရှိပါ။ + hint_html: အခြားအကောင့်မှ ဤအကောင့်သို့ ပြောင်းရွှေ့လိုပါက ဤနေရာတွင် အကောင့်ဟောင်းမှ စောင့်ကြည့်သူများကို ဤအကောင့်သို့ မရွှေ့မီ လိုအပ်သော အမည်တစ်ခု ဖန်တီးနိုင်ပါသည်။ ဤလုပ်ဆောင်ချက်မှာ အန္တရာယ်ကင်းပြီး ပြန်ပြောင်းလုပ်ဆောင်နိုင်ပါသည်အကောင့်ပြောင်းရွှေ့ခြင်းကို အကောင့်ဟောင်းမှ စတင်လုပ်ဆောင်ပါသည်။ + remove: နာမည်တူများကို လင့်ခ်ဖြုတ်ပါ appearance: + advanced_web_interface: အဆင့်မြင့်ဝဘ်ပုံစံ + advanced_web_interface_hint: အဆင့်မြင့်ဝဘ်အင်တာဖေ့စ်သည် မျက်နှာပြင်အကျယ်တစ်ခုလုံးကို သင် အသုံးပြုလိုပါက သင်အလိုရှိသည့်အတိုင်း အချက်အလက်များကို တစ်ပြိုင်နက်ကြည့်ရှုရန် ကော်လံများစွာဖြင့် ပြသနိုင်သည် - ပင်မစာမျက်နှာ၊ အကြောင်းကြားချက်များ၊ ဖက်ဒီစာမျက်နှာ၊ စာရင်းအရေအတွက်နှင့် hashtags မှန်သမျှကို ချိန်ညှိဖော်ပြနိုင်သည်။ + animations_and_accessibility: လှုပ်ရှားမှုဆိုင်ရာများ + confirmation_dialogs: အတည်ပြုချက် ဒိုင်ယာလော့ခ်များ + discovery: ရှာဖွေတွေ့ရှိမှု localization: + body: Mastodon ကို စေတနာ့ဝန်ထမ်းများမှ ဘာသာပြန်ထားပါသည်။ + guide_link: https://crowdin.com/project/mastodon guide_link_text: လူတိုင်းပါဝင်ကူညီနိုင်ပါတယ်။ + sensitive_content: သတိထားရသော အကြောင်းအရာ application_mailer: + notification_preferences: အီးမေးလ် သတ်မှတ်ချက်များကို ပြောင်းပါ + salutation: "%{name}" + settings: အီးမေးလ် သတ်မှတ်ချက်များကို ပြောင်းပါ - %{link} + unsubscribe: စာရင်းမှထွက်ရန် + view: ကြည့်ရှုရန် - view_profile: ပရိုဖိုင်ကိုကြည့်ရန် view_status: ပို့စ်ကိုကြည့်ရန် - auth: - change_password: စကားဝှက် - delete_account: အကောင့်ဖျက်ပါ + applications: + created: အက်ပလီကေးရှင်းကို ဖန်တီးပြီးပါပြီ + destroyed: အက်ပလီကေးရှင်းကို ဖျက်ပြီးပါပြီ logout: ထွက်မယ် + regenerate_token: ဝင်ရောက်ခွင့် တိုကင်ကို ပြန်ထုတ်ပါ + token_regenerated: အသုံးပြုခွင့်တိုကင်ကို ပြန်လည်ထုတ်ပေးသည် + warning: ဤအချက်အလက်ကို သတိထားပါ။ မည်သူ့ကိုမျှ မမျှဝေပါနှင့်။ + your_token: သင့် အသုံးပြုခွင့်တိုကင် + auth: + apply_for_account: အကောင့်တစ်ခုတောင်းဆိုပါ + captcha_confirmation: + help_html: CAPTCHA ဖြေရှင်းရာတွင် ပြဿနာများရှိပါက %{email} မှတစ်ဆင့် ကျွန်ုပ်တို့ထံ ဆက်သွယ်နိုင်ပြီး သင့်အား ကျွန်ုပ်တို့ ကူညီနိုင်ပါသည်။ + hint_html: နောက်ထပ်တစ်ခုသာ။ သင်သည် လူသားဖြစ်ကြောင်း ကျွန်ုပ်တို့ အတည်ပြုရန် လိုအပ်ပါသည် (စပမ်းများကို ရှောင်ရှားနိုင်စေရန် အတွက်ဖြစ်ပါသည်။) အောက်ပါ CAPTCHA ကိုဖြေရှင်းပြီး "Continue" ကို နှိပ်ပါ။ + title: လုံခြုံရေးစစ်ဆေးမှု + confirmations: + wrong_email_hint: ထိုအီးမေးလ်လိပ်စာ မမှန်ပါက အကောင့်သတ်မှတ်ချက်များတွင် ပြောင်းလဲနိုင်သည်။ + delete_account: အကောင့်ဖျက်ပါ + delete_account_html: သင့်အကောင့်ဖျက်လိုပါကဤနေရာတွင် ဆက်လက်လုပ်ဆောင်နိုင်သည်။ အတည်ပြုချက်တောင်းပါမည်။ + description: + prefix_invited_by_user: "@%{name} က Mastodon ၏ ဆာဗာတွင် ပါဝင်ရန် သင့်ကို ဖိတ်ခေါ်ထားသည်။" + prefix_sign_up: ယနေ့တွင် Mastodon ၌ စာရင်းသွင်းလိုက်ပါ။ + suffix: အကောင့်တစ်ခုဖြင့် မည်သည့် Mastodon ဆာဗာများမှ အသုံးပြုသူများနှင့်မဆို စောင့်ကြည့်နိုင်၊ ပို့စ်အသစ်များ တင်နိုင်ပြီး မက်ဆေ့ချ်များ ပေးပို့နိုင်ပါသည်။ + didnt_get_confirmation: အတည်ပြုချက်လင့်ခ်ကို မရရှိခဲ့ဘူးလား။ + dont_have_your_security_key: သင့်တွင် လုံခြုံရေးကီး မရှိဘူးလား။ + forgot_password: သင့်စကားဝှက် မေ့နေပါသလား။ + invalid_reset_password_token: စကားဝှက်ပြန်လည်သတ်မှတ်ခြင်းတိုကင်မှာ မမှန်ကန်ပါ သို့မဟုတ် သက်တမ်းကုန်သွားပါသည်။ အသစ်တစ်ခုတောင်းဆိုပါ။ + link_to_otp: သင့်ဖုန်းမှ နှစ်ဆင့်ခံလုံခြုံရေးကုဒ် သို့မဟုတ် ပြန်လည်ရယူရေးကုဒ် ထည့်ပါ + link_to_webauth: လုံခြုံရေးကီး အသုံးပြုပါ + log_in_with: ဖြင့် ဝင်ရောက်ပါ + login: အကောင့်ဝင်ရန် + logout: ထွက်မယ် + migrate_account: အခြားအကောင့်တစ်ခုသို့ ရွှေ့ရန် + migrate_account_html: ဤအကောင့်ကို အခြားအကောင့်သို့ ပြန်ညွှန်းလိုပါက ဤနေရာတွင် စီစဉ်သတ်မှတ်နိုင်သည်။ + or_log_in_with: သို့မဟုတ် အကောင့်ဖြင့် ဝင်ရောက်ပါ + privacy_policy_agreement_html: ကိုယ်ရေးအချက်အလက်မူဝါဒ ကို ဖတ်ပြီး သဘောတူလိုက်ပါပြီ + progress: + confirm: အီးမေးလ် အတည်ပြုရန် + details: သင့်အသေးစိတ်အချက်အလက်များ + review: ကျွန်ုပ်တို့၏သုံးသပ်ချက် + rules: စည်းကမ်းများကို လက်ခံပါ providers: cas: CAS saml: SAML + register: အကောင့်ဖွင့်ရန် + registration_closed: "%{instance} သည် အဖွဲ့ဝင်အသစ်များကို လက်ခံထားခြင်းမရှိပါ" + resend_confirmation: အတည်ပြုချက်လင့်ခ်ကို ပြန်လည်ပေးပို့ပါ + reset_password: စကားဝှက် ပြန်လည်သတ်မှတ်ပါ + rules: + accept: လက်ခံပါ + back: နောက်သို့ + invited_by: သင်လက်ခံရရှိသော ဖိတ်ကြားချက်ကြောင့် %{domain} သို့ ပါဝင်နိုင်သည်- + preamble: "၎င်းတို့ကို %{domain} စိစစ်သူများမှ အတည်ပြုပါသည်။" + preamble_invited: ဆက်လက်မလုပ်ဆောင်မီ ကျေးဇူးပြု၍ %{domain} ၏ ကြီးကြပ်သူများမှ သတ်မှတ်သော မြေပြင်စည်းမျဉ်းများကို သုံးသပ်ပါ။ + title: အခြေခံစည်းမျဉ်းအချို့ + title_invited: သင့်ကို ဖိတ်ခေါ်ထားပြီးဖြစ်သည်။ + security: လုံခြုံရေး set_new_password: စကားဝှက်အသစ် သတ်မှတ်ပါ။ + setup: + email_below_hint_html: သင်၏ Spam ဖိုင်တွဲကို စစ်ဆေးပါ၊ သို့မဟုတ် အခြားတစ်ခုကို တောင်းဆိုပါ။ သင့်အီးမေးလ်လိပ်စာမှားနေပါက သင်ပြင်ပေးနိုင်ပါသည်။ + email_settings_hint_html: "%{email} အတည်ပြုရန် သင့်ထံပေးပို့သော လင့်ခ်ကို နှိပ်ပါ။ စောင့်နေပါမည်။" + link_not_received: လင့်ခ် မရခဲ့ဘူးလား။ + new_confirmation_instructions_sent: မိနစ်အနည်းငယ်အတွင်း အတည်ပြုချက်လင့်ခ်ပါရှိသော အီးမေးလ်အသစ်ကို သင်ရရှိမည်ဖြစ်သည်။ + title: သင့်ဝင်စာပုံးကို စစ်ဆေးပါ + sign_in: + preamble_html: သင်၏ %{domain} အထောက်အထားများဖြင့် ဝင်ရောက်ပါ။ သင့်အကောင့်ကို အခြားဆာဗာတစ်ခုတွင် ဖွင့်ထားပါက ဤနေရာ၌ အကောင့်ဝင်ရောက်နိုင်မည်မဟုတ်ပါ။ + title: "%{domain} သို့ အကောင့်ဝင်ရန်" + sign_up: + manual_review: "%{domain} ၌ အကောင့်ဖွင့်ခြင်းများတွင် ကျွန်ုပ်တို့၏ ကြီးကြပ်သူများမှ ကိုယ်တိုင်သုံးသပ် လုပ်ဆောင်လျက်ရှိပါသည်။ သင့်အကြောင်းနှင့် %{domain} တွင် အကောင့်ဖွင့်လိုသည့်အကြောင်း အနည်းငယ်ရေးသားခြင်းဖြင့် သင့်အကောင့်စာရင်းသွင်းခြင်းမှာ ကျွန်ုပ်တို့ကို အကူအညီဖြစ်စေပါသည်။" + preamble: ဤ Mastodon အကောင့်တစ်ခုဖြင့် သင်သည် ကွန်ရက်ပေါ်ရှိ အခြားမည်သူ့မဆို မည်သည့်ဆာဗာတွင်ရှိစေကာမူ သင်စောင့်ကြည့်နိုင်မည်ဖြစ်ပါသည်။ + title: "%{domain} တွင် ထည့်သွင်းရန်။" status: account_status: အကောင့်အခြေအနေ - authorize_follow: - follow: စောင့်ကြည့်မယ် - follow_request: သင်သည် စောင့်ကြည့်မည် တောင်းဆိုချက်တစ်ခု ပေးပို့ထားသည်- - post_follow: - web: ဝဘ်သို့ သွားပါ - title: "%{acct} ကို စောင့်ကြည့်မယ်" + confirming: အီးမေးလ်အတည်ပြုချက် အပြီးသတ်ရန် စောင့်ဆိုင်းခြင်း + functional: သင့်အကောင့်မှာ အပြည့်အဝလုပ်ဆောင်နေပါပြီ။ + pending: သင့်အက်ပလီကေးရှင်းကို ကျွန်ုပ်တို့၏ဝန်ထမ်းများမှ ပြန်လည်သုံးသပ်နေပါသည်။ အချိန်အနည်းငယ်ကြာနိုင်ပါသည်။ သင့်အက်ပလီကေးရှင်းကို အတည်ပြုပြီးပါက အီးမေးလ်တစ်စောင် သင် လက်ခံရရှိမည်ဖြစ်သည်။ + redirecting_to: သင့်အကောင့်မှာ လက်ရှိတွင် %{acct} သို့ ပြန်ညွှန်းနေသောကြောင့် သုံးစွဲ၍မရပါ။ + view_strikes: သင့်အကောင့်ကို ဆန့်ကျင်သည့် ယခင်ကလုပ်ဆောင်ချက်များကို ကြည့်ပါ + too_fast: ဖောင်တင်သည်မှာ မြန်နေပါသည်။ ထပ်စမ်းကြည့်ပါ။ + use_security_key: လုံခြုံရေးကီးကို သုံးပါ challenge: confirm: ဆက်လုပ်မည် + hint_html: "အကြံပြုချက် - နောက်နာရီများတွင် သင့်စကားဝှက်ကို ထပ်မံတောင်းဆိုမည်မဟုတ်ပါ။" invalid_password: စကားဝှက် မမှန်ပါ + prompt: ဆက်လက်လုပ်ဆောင်ရန်အတွက် စကားဝှက်အတည်ပြုပါ + crypto: + errors: + invalid_key: မှန်ကန်သော Ed25519 သို့မဟုတ် Curve25519 ကီး မဟုတ်ပါ။ + invalid_signature: မှန်ကန်သော Ed25519 လက်မှတ်မဟုတ်ပါ date: formats: default: "%b %d, %Y" @@ -240,6 +1090,7 @@ my: about_x_years: "%{count}y" almost_x_years: "%{count}y" half_a_minute: အခုလေးတင် + less_than_x_minutes: "%{count}m" less_than_x_seconds: အခုလေးတင် over_x_years: "%{count}y" x_days: "%{count}y" @@ -247,39 +1098,216 @@ my: x_months: "%{count}mo" x_seconds: "%{count}s" deletes: + challenge_not_passed: သင်ထည့်လိုက်သော အချက်အလက်မှာ မမှန်ပါ + confirm_password: အထောက်အထားကိုအတည်ပြုရန်အတွက် သင့်လက်ရှိစကားဝှက်ကို ထည့်ပါ + confirm_username: လုပ်ငန်းစဉ်ကို အတည်ပြုရန်အတွက် သင့်အသုံးပြုသူအမည်ကို ထည့်သွင်းပါ proceed: အကောင့်ဖျက်ပါ success_msg: သင့်အကောင့်ကို အောင်မြင်စွာ ဖျက်လိုက်ပါပြီ + warning: + before: ရှေ့မဆက်မီ ဤမှတ်စုများကို သေချာဖတ်ပါ - + caches: အခြားဆာဗာများမှ ကက်ရှ်လုပ်ထားသော အကြောင်းအရာမှာ ဆက်ရှိနေနိုင်သည် + data_removal: သင့်ပို့စ်များနှင့် အခြားအချက်အလက်များကို အပြီးတိုင် ဖယ်ရှားပါမည် + email_change_html: သင့်အကောင့်မဖျက်ဘဲ သင့်အီးမေးလ်လိပ်စာကို ပြောင်းလဲနိုင်သည် + email_contact_html: မရောက်သေးပါက အကူအညီအတွက် %{email} သို့ အီးမေးလ်ပို့နိုင်ပါသည် + email_reconfirmation_html: အတည်ပြုချက်အီးမေးလ် လက်ခံမရရှိပါက ထပ်မံတောင်းဆိုနိုင်သည် + irreversible: အကောင့်ကို ပြန်လည်ရယူရန် သို့မဟုတ် ပြန်လည်အသုံးပြုရန် မဖြစ်နိုင်တော့ပါ + more_details_html: အသေးစိတ်အချက်အလက်များအတွက်၊ ကိုယ်ရေးကိုယ်တာမူဝါဒ ကို ကြည့်ပါ။ + username_available: သင့်အသုံးပြုသူအမည်ကို ပြန်လည်ရရှိနိုင်ပါမည် + username_unavailable: သင့်အသုံးပြုသူအမည်မှာ မရရှိနိုင်တော့ပါ disputes: strikes: + action_taken: ဆောင်ရွက်ခဲ့သည် + appeal: အယူခံဝင်ခြင်း + appeal_approved: ဤသတိပေးချက်ကို အယူခံဝင်ခဲ့ပြီးဖြစ်၍ အကျုံးမဝင်တော့ပါ။ + appeal_rejected: တင်သွင်းခြင်းကို ပယ်ချလိုက်သည် + appeal_submitted_at: အယူခံဝင်မှုကို တင်သွင်းပြီးချိန် + appealed_msg: အယူခံဝင်မှုကို တင်သွင်းပြီးဖြစ်သည်။ အတည်ပြုပြီးပါက အကြောင်းကြားပါမည်။ + appeals: + submit: အယူခံဝင်ခွင့်ပြုရန် + approve_appeal: တင်သွင်းခြင်းကို အတည်ပြုပါ + associated_report: ဆက်စပ်အစီရင်ခံစာ + created_at: ရက်စွဲ + description_html: ဤအရာများမှာ သင့်အကောင့်နှင့် %{instance} မှ သင့်ထံပေးပို့ထားသော သတိပေးချက်များကို ဆန့်ကျင်သည့် လုပ်ဆောင်ချက်များဖြစ်သည်။ + recipient: လိပ်မူထားသည် + reject_appeal: တင်သွင်းခြင်းကို ပယ်ချပါ status: "#%{id} ပို့စ်" + status_removed: ပို့စ်ကို စနစ်မှ ဖယ်ရှားပြီးဖြစ်သည် title: "%{date} မှ %{action}" + title_actions: + delete_statuses: ပို့စ်ဖယ်ရှားခြင်း + disable: အကောင့်ပိတ်သိမ်းခြင်း + mark_statuses_as_sensitive: သတိထားရသောပို့စ်များအဖြစ် အမှတ်အသားပြုခြင်း + none: သတိပေးချက် + sensitive: သတိထားရသောအကောင့်အဖြစ် အမှတ်အသားပြုခြင်း + silence: အကောင့်ကန့်သတ်ချက် + suspend: အကောင့်ပိတ်ခြင်း + your_appeal_approved: သင့်တင်သွင်းခြင်းကို အတည်ပြုပြီးပါပြီ + your_appeal_pending: အယူခံဝင်ရန် တင်သွင်းထားသည် + your_appeal_rejected: အယူခံဝင်မှုကို ပယ်ချလိုက်သည် + domain_validator: + invalid_domain: တရားဝင်ဒိုမိန်းအမည်မဟုတ်ပါ + edit_profile: + basic_information: အခြေခံသတင်းအချက်အလက် + hint_html: "သင်၏ အများမြင်ပရိုဖိုင်နှင့် သင့်ပို့စ်များဘေးရှိ တွေ့မြင်ရသည့်အရာကို စိတ်ကြိုက်ပြင်ဆင်ပါ။ သင့်တွင် ပရိုဖိုင်နှင့် ပရိုဖိုင်ပုံတစ်ခု ဖြည့်သွင်းထားပါက အခြားသူများအနေဖြင့် သင်နှင့် အပြန်အလှန် တုံ့ပြန်နိုင်ခြေပိုများပါသည်။" + other: အခြား errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. + '400': သင်တင်ပြသော တောင်းဆိုချက်မှာ မမှန်ကန်ပါ သို့မဟုတ် ပုံစံမမှန်ပါ။ + '403': ဤစာမျက်နှာကြည့်ရှုရန် သင့်တွင် ခွင့်ပြုချက်မရှိပါ။ + '404': သင်ရှာဖွေနေသော စာမျက်နှာသည် ဤနေရာတွင် မရှိပါ။ + '406': ဤစာမျက်နှာကို တောင်းဆိုထားသော ပုံစံဖြင့် မရရှိနိုင်ပါ။ + '410': သင်ရှာဖွေနေသည့် စာမျက်နှာသည် ဤနေရာတွင် မရှိတော့ပါ။ + '422': + content: လုံခြုံရေး အတည်ပြုခြင်း မအောင်မြင်ပါ။ သင်သည် ကွတ်ကီးများကို ပိတ်ပင်ထားပါသလား။ + title: လုံခြုံရေး အတည်ပြုခြင်း မအောင်မြင်ပါ + '429': တောင်းဆိုမှု များနေပါသည် + '500': + content: စိတ်မကောင်းပါ။ အဆုံးတွင် တစ်ခုမှားယွင်းသွားပါသည်။ + title: ဤစာမျက်နှာမှာ မမှန်ကန်ပါ + '503': ယာယီဆာဗာချို့ယွင်းမှုကြောင့် စာမျက်နှာကို ကြည့်ရှု၍မရပါ။ + noscript_html: Mastodon ဝဘ်အက်ပလီကေးရှင်းအသုံးပြုရန်အတွက် JavaScript ကို ဖွင့်ပါ။ တစ်နည်းအားဖြင့် သင့် Mastodon ပလက်ဖောင်းအတွက် မူရင်းအက်ပ်များ ထဲမှ တစ်ခုကို စမ်းကြည့်ပါ။ + existing_username_validator: + not_found: ထိုအသုံးပြုသူအမည်ဖြင့် ပြည်တွင်းအသုံးပြုသူကို ရှာမတွေ့ပါ + not_found_multiple: "%{usernames} ကို ရှာမတွေ့ပါ" exports: archive_takeout: date: ရက်စွဲ + download: သင်၏မှတ်တမ်းကို ဒေါင်းလုဒ်လုပ်ပါ + hint_html: သင့် ပို့စ်များနှင့် အပ်လုဒ်လုပ်ထားသော မီဒီယာဖိုင် မှတ်တမ်းတို့ကို တောင်းဆိုနိုင်သည်။ ထုတ်ယူထားသောအချက်အလက်မှာ ActivityPub ပုံစံဖြစ်ပြီး ကိုက်ညီသည့်မည်သည့်ဆော့ဖ်ဝဲလ်ဖြင့်မဆို ဖတ်နိုင်မည်ဖြစ်သည်။ သင်သည် ၇ ရက်ပြည့်တိုင်း မှတ်တမ်းတစ်ခု တောင်းဆိုနိုင်သည်။ + in_progress: သင့်မှတ်တမ်းကို ပြုစုနေသည်... + request: မှတ်တမ်း တောင်းဆိုရန် size: အရွယ်အစား + blocks: သင်ပိတ်ပင်ထားသည့်လူများစာရင်း + bookmarks: မှတ်ထားသည်များ csv: CSV + domain_blocks: ဒိုမိန်းပိတ်ပင်ထားမှုများ lists: စာရင်းများ + mutes: အသံပိတ် + storage: မီဒီယာသိုလှောင်မှု featured_tags: add_new: အသစ် ထည့်ပါ + errors: + limit: ဟက်ရှ်တဂ်အရေအတွက် အများဆုံးကို ဖော်ပြပြီးဖြစ်သည် + hint_html: " hashtags ဆိုသည်မှာ အဘယ်နည်း။ ၎င်းတို့ကို သင်၏ အများမြင်ပရိုဖိုင်တွင် ပြသထားပြီး ထို hashtags များအောက်တွင် လူများအား သင်၏ အများမြင်ပို့စ်များကို ကြည့်ရှုရန်ခွင့်ပြုထားသည်။ ၎င်းတို့သည် ဖန်တီးမှုလက်ရာများ သို့မဟုတ် ရေရှည်စီမံကိန်းများ ခြေရာခံရန်အတွက် အသုံးဝင်ပါသည်။" filters: contexts: + account: ပရိုဖိုင်များ + home: ပင်မနှင့် စာရင်းများ notifications: အကြောင်းကြားချက်များ + public: အများမြင်စာမျက်နှာ + thread: စကားဝိုင်းများ + edit: + add_keyword: အဓိကစကားလုံး ထည့်ပါ + keywords: အဓိကစကားလုံးများ + statuses: တစ်ဦးချင်းတင်ထားသောပို့စ်များ + statuses_hint_html: ဤစစ်ထုတ်မှုမှာ အောက်ပါအဓိကစာလုံးများနှင့် ကိုက်ညီမှုရှိသည်ဖြစ်စေ၊ မရှိသည်ဖြစ်စေ ရွေးချယ်ထားသော ပို့စ်တစ်ခုချင်းစီအတွက် အကျုံးဝင်ပါသည်။ စစ်ထုတ်မှုမှ ပို့စ်များကို ပြန်လည်သုံးသပ်ခြင်း သို့မဟုတ် ဖယ်ရှားခြင်း။ + title: စစ်ထုတ်ခြင်းကို ပြင်ဆင်ရန် + errors: + deprecated_api_multiple_keywords: ဤအချက်အလက်များမှာ စစ်ထုတ်ထားသည့်အဓိကစာလုံးတစ်ခုထက် ပို၍သက်ဆိုင်သောကြောင့် ဤအက်ပလီကေးရှင်းမှပြောင်း၍မရပါ။ မကြာသေးမီကအသုံးပြုထားသော အက်ပလီကေးရှင်း သို့မဟုတ် ဝဘ်အင်တာဖေ့စ်ကို အသုံးပြုပါ။ + invalid_context: ပံ့ပိုးထား​သော အ​​ကြောင်းအရာ မရှိခြင်း သို့မဟုတ် မမှန်ကန်ခြင်း index: + contexts: "%{contexts} ရှိ စစ်ထုတ်ထားမှုများ" delete: ဖျက်ပါ + empty: သင့်တွင် စစ်ထုတ်ထားခြင်းများ မရှိပါ။ + expires_in: "%{distance} တွင် သက်တမ်းကုန်မည်" + expires_on: "%{date} ရက်နေ့တွင် သက်တမ်းကုန်မည်" + keywords: + other: "%{count} အဓိကစကားလုံး" statuses: other: "%{count} ပို့စ်" + statuses_long: + other: တစ်ဦးချင်းပို့စ် %{count} များ ကို ဖျောက်ထားသည် + title: စစ်ထုတ်ခြင်းများ + new: + save: စစ်ထုတ်မှုအသစ် သိမ်းပါ + title: စစ်ထုတ်မှုအသစ် ထည့်ပါ + statuses: + back_to_filter: စစ်ထုတ်ခြင်းသို့ ပြန်သွားရန် + batch: + remove: စစ်ထုတ်ခြင်းမှ ဖယ်ရှားရန် + index: + hint: ဤစစ်ထုတ်မှုမှာ အခြားသတ်မှတ်ချက်များနှင့်မသက်ဆိုင်ဘဲ တစ်ဦးချင်းပို့စ်များအတွက်သာ အကျုံးဝင်ပါသည်။ ဝဘ်အင်တာဖေ့စ်မှတစ်ဆင့် ဤစစ်ထုတ်မှုတွင် နောက်ထပ်ပို့စ်များ သင်ထပ်ထည့်နိုင်ပါသည်။ + title: စစ်ထုတ်ထားသော ပို့စ်များ generic: all: အားလုံး + all_items_on_page_selected_html: + other: ဤစာမျက်နှာရှိ %{count} အိုက်တမ်များအားလုံးကို ရွေးချယ်ထားသည်။ + all_matching_items_selected_html: + other: သင့်ရှာဖွေမှုနှင့် ကိုက်ညီသည့် %{count} အိုက်တမ်အားလုံးကို ရွေးချယ်ထားသည်။ + cancel: ပယ်ဖျက် + changes_saved_msg: အပြောင်းအလဲများကို သိမ်းဆည်းပြီးပါပြီ။ + confirm: အတည်ပြု + copy: ကူးယူပါ + delete: ဖျက်ပါ + deselect: အားလုံး ရွေးထားခြင်းကို ဖျက်မည် + none: တစ်ခုမျှ + order_by: စီထားသည် + save_changes: ပြောင်းလဲမှုများကို သိမ်းဆည်းပါ + select_all_matching_items: + other: သင့်ရှာဖွေမှုနှင့် ကိုက်ညီသည့် %{count} ခု အားလုံးကို ရွေးပါ။ today: ယနေ့ + validation_errors: + other: မမှန်သေးပါ။ ကျေးဇူးပြု၍ အောက်ပါ %{count} အမှားများကို ပြန်လည်သုံးသပ်ပါ + imports: + errors: + empty: CSV ဖိုင်အလွတ် + incompatible_type: ရွေးချယ်ထားသော ထည့်သွင်းထားသည့်အမျိုးအစားနှင့် ကိုက်ညီမှုမရှိပါ + invalid_csv_file: မမှန်ကန်သော CSV ဖိုင်။ အမှား - %{error} + over_rows_processing_limit: "%{count} တန်းထက် ပိုနေပါသည်" + too_large: ဖိုင်ဆိုဒ်ကြီးနေပါသည် + failures: မအောင်မြင် + imported: ထည့်သွင်းခြင်း + mismatched_types_warning: ဤထည့်သွင်းမှုအတွက် မှားယွင်းသောအမျိုးအစားကို သင်ရွေးချယ်ထားပုံပေါ်သည်၊ ကျေးဇူးပြု၍ ထပ်မံစစ်ဆေးပါ။ + modes: + merge: ပေါင်း + merge_long: ရှိပြီးသားမှတ်တမ်းများ သိမ်းဆည်းပြီး အသစ်များ ထပ်ထည့်ပါ + overwrite: ထပ်ရေးရန် + overwrite_long: လက်ရှိမှတ်တမ်းများကို အသစ်များဖြင့် အစားထိုးပါ + overwrite_preambles: + blocking_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ သင့်ပိတ်ဆို့စာရင်းကို အစားထိုးပါတော့မည်။ + bookmarks_html: သင်သည် %{filename} မှ %{total_items} ပို့စ်များ အထိ သင့် bookmark များကို အစားထိုးပါတော့မည်။ + domain_blocking_html: သင်သည် %{filename} မှ %{total_items} ဒိုမိန်းများ ဖြင့် သင်၏ ဒိုမိန်းပိတ်ဆို့စာရင်းကို အစားထိုးပါတော့မည်။ + following_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ စောင့်ကြည့် ပြီး အခြားမည်သူ့ကိုမျှ စောင့်မကြည့်တော့ပါ ။ + lists_html: သင်သည် %{filename} ၏ အကြောင်းအရာများဖြင့် သင့်စာရင်းများကို အစားထိုး ပါတော့မည်။ %{total_items} အကောင့်များအထိ စာရင်းအသစ်များသို့ ပေါင်းထည့်ပါမည်။ + muting_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ ဖြင့် အသံပိတ်ထားသော သင့်အကောင့်များစာရင်းကို အစားထိုးပါတော့မည်။ + preambles: + blocking_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ ပိတ်ဆို့ပါတော့မည်။ + bookmarks_html: သင်သည် %{filename} မှ %{total_items} ပို့စ်များ အထိ သင့် Bookmark များ သို့ ပေါင်းထည့်တော့မည်။ + domain_blocking_html: သင်သည် %{filename} မှ %{total_items} ဒိုမိန်းများ အထိ ပိတ်ဆို့ပါတော့မည်။ + following_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ စောင့်ကြည့် ပါတော့မည်။ + lists_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ ကို သင့် စာရင်းများ သို့ ပေါင်းထည့်ပါတော့မည်။ ထည့်ရန်စာရင်းမရှိပါက စာရင်းအသစ်များကို ဖန်တီးပါမည်။ + muting_html: သင်သည် %{filename} မှ %{total_items} အကောင့်များ အထိ အသံတိတ်ပါတော့မည်။ + preface: သင်စောင့်ကြည့်နေသည့်လူများစာရင်း သို့မဟုတ် ပိတ်ပင်ထားသည့်စာရင်းကဲ့သို့သော အခြားဆာဗာတစ်ခုမှ သင်ထုတ်ယူထားသည့်အချက်အလက်များကို ပြန်လည်ထည့်သွင်းနိုင်သည်။ + recent_imports: လတ်တလောထည့်သွင်းမှုများ + states: + finished: ပြီးစီးပြီး + in_progress: လုပ်ဆောင်နေသည် + scheduled: စီစဉ်ထားသည် + unconfirmed: အတည်မပြုနိုင်ပါ + status: အခြေအနေ + success: သင့်အချက်အလက်ကို အပ်လုဒ်လုပ်ပြီး သတ်မှတ်ချိန်အတွင်း ဆောင်ရွက်ပါမည် + time_started: တွင် စတင်ခဲ့သည် + titles: + blocking: ပိတ်ထားသောအကောင့်များ ထည့်သွင်းခြင်း + bookmarks: Bookmark များ ထည့်သွင်းခြင်း + domain_blocking: ပိတ်ထားသောဒိုမိန်းများ ထည့်သွင်းခြင်း + following: စောင့်ကြည့်ထားသောအကောင့်များထည့်သွင်းခြင်း + lists: စာရင်းများထည့်ခြင်း + muting: အသံတိတ်အကောင့်များထည့်သွင်းခြင်း + type: ထည့်သွင်းမှုအမျိုးအစား + type_groups: + constructive: စောင့်ကြည့်မှုများ & Bookmark များ + destructive: ပိတ်ဆို့ခြင်းနှင့် အသံများပိတ်ထားခြင်း + types: + blocking: ပိတ်ပင်ထားသည့်စာရင်း + bookmarks: Bookmarks + domain_blocking: ဒိုမိန်းပိတ်ပင်ထားသည့်စာရင်း + following: စောင့်ကြည့်စာရင်း + lists: စာရင်းများ + muting: ပိတ်ထားသောစာရင်း + upload: တင္ရန် invites: + delete: အကောင့်ပိတ်ရန် + expired: သက်တမ်းကုန်သွားပါပြီ expires_in: '1800': ၃၀ မိနစ် '21600': ၆ နာရီ @@ -287,24 +1315,129 @@ my: '43200': ၁၂ နာရီ '604800': ၁ ပတ် '86400': ၁ ရက် + expires_in_prompt: ဘယ်တော့မှ + generate: ဖိတ်ကြားချက်လင့်ခ် ဖန်တီးပါ + invited_by: သင့်ကို ဖိတ်ခေါ်ထားသည် - + max_uses: + other: "%{count} အသုံးပြုမှုများ" + max_uses_prompt: အကန့်အသတ်မဲ့ + prompt: ဤဆာဗာသို့ ဝင်ရောက်ရန်အတွက် လင့်ခ်များဖန်တီးပြီး အခြားသူများကို မျှဝေပါ + table: + expires_at: သက်တမ်းကုန်သည် + uses: အသုံးပြုမှုများ + title: ဖိတ်ခေါ်ရန် + lists: + errors: + limit: သင်သည် အများဆုံးစာရင်း အရေအတွက်သို့ ရောက်ရှိသွားပါပြီ login_activities: authentication_methods: otp: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်အက်ပ် password: စကားဝှက် + sign_in_token: အီးမေးလ်လုံခြုံရေးကုဒ် + webauthn: လုံခြုံရေးကီးများ + description_html: သင်မပြုလုပ်သည့် လုပ်ဆောင်ချက်တွေ့ရှိပါက သင့်စကားဝှက်ကို ပြောင်းလဲပြီး နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို အသုံးပြုသင့်ပါသည်။ + empty: စစ်မှန်ကြောင်းအထောက်အထားမရရှိနိုင်ပါ + failed_sign_in_html: "%{ip} (%{browser}) မှ %{method} ဖြင့် အကောင့်ဝင်ရောက်ခြင်း မအောင်မြင်ပါ" + successful_sign_in_html: "%{ip} (%{browser}) မှ %{method} ဖြင့် အကောင့်ဝင်၍ရပါပြီ" + title: အထောက်အထားမှတ်တမ်း + mail_subscriptions: + unsubscribe: + action: ဟုတ်ကဲ့၊ စာရင်းမှ ဖြုတ်လိုက်ပါပြီ + complete: စာရင်းမှထွက်ရန် + confirmation_html: Mastodon %{domain} ရှိ သင့်အီးမေးလ် %{email} တွင် %{type} ကို လက်ခံရယူခြင်းမှ ရပ်ဆိုင်းလိုသည်မှာ သေချာပါသလား။ သင်၏ အီးမေးလ် အကြောင်းကြားခြင်းသတ်မှတ်ချက်များ မှ အမြဲတမ်း ပြန်လည်စာရင်းသွင်းနိုင်ပါသည်။ + emails: + notification_emails: + favourite: favorite အသိပေးချက် အီးမေးလ်များ + follow: စောင့်ကြည့်ရန်အတွက် အသိပေးချက်အီးမေးလ်များ + follow_request: စောင့်ကြည့်တောင်းဆိုမှု အီးမေးလ်များ + mention: ဖော်ပြအသိပေးချက်အီးမေးလ်များ + reblog: boost အသိပေးချက်အီးမေးလ်များ + resubscribe_html: အကယ်၍ သင်သည် မှားယွင်းစွာဖြင့် စာရင်းသွင်းမှုမှ ပယ်ဖျက်ခဲ့လျှင် သင်၏ အီးမေးလ် အကြောင်းကြားခြင်းသတ်မှတ်ချက်များ မှ ပြန်လည်စာရင်းသွင်းနိုင်သည်။ + success_html: Mastodon %{domain} ရှိ သင့်အီးမေးလ် %{email} တွင် %{type} ကို ရရှိတော့မည်မဟုတ်ပါ။ + title: စာရင်းမှထွက်ရန် media_attachments: validations: images_and_video: ရုပ်ပုံပါရှိပြီးသားပို့စ်တွင် ဗီဒီယို ပူးတွဲ၍မရပါ + not_ready: မပြီးသေးသောဖိုင်များကို ပူးတွဲ၍မရပါ။ ခဏအကြာတွင် ထပ်စမ်းကြည့်ပါ။ + too_many: ဖိုင် ၄ ဖိုင်ထက် ပို၍တွဲမရပါ migrations: + acct: သို့ ပြောင်းရွှေ့ရန် + cancel: ပြန်ညွှန်းခြင်းကို ပယ်ဖျက်ရန် + cancel_explanation: ပြန်ညွှန်းခြင်းပယ်ဖျက်ခြင်းဖြင့် သင့်လက်ရှိအကောင့်မှာ ပြန်လည်အသုံးပြု၍ရမည်ဖြစ်သော်လည်း ထိုအကောင့်သို့ ပြောင်းရွှေ့ထားသော စောင့်ကြည့်သူများကို ပြန်လည်ရရှိတော့မည်မဟုတ်ပါ။ + cancelled_msg: ပြန်ညွှန်းခြင်းကို ပယ်ဖျက်ပြီးပါပြီ။ errors: + already_moved: သင်ပြောင်းရွှေ့ပြီးသော အကောင့်နှင့် တူညီပါသည် + missing_also_known_as: ဤအကောင့်၏ အမည်တူမဟုတ်ပါ + move_to_self: လက်ရှိအကောင့်မဖြစ်နိုင်ပါ not_found: ရှာမတွေ့ပါ + on_cooldown: သင် cooldown အခြေအနေတွင် ရှိနေပါသည် + followers_count: ပြောင်းရွှေ့ချိန်၌ စောင့်ကြည့်သူများအရေအတွက် + incoming_migrations: အခြားအကောင့်တစ်ခုမှ ပြောင်းရွှေ့ခြင်း + incoming_migrations_html: အခြားအကောင့်မှ ဤအကောင့်သို့ ရွှေ့ရန် ဦးစွာ သင်သည် အကောင့်အမည်တူတစ်ခု ဖန်တီးရန် လိုအပ်ပါသည်။ + moved_msg: သင့်အကောင့်မှာ ယခု %{acct} သို့ ပြန်ညွှန်းနေပြီး စောင့်ကြည့်သူများကို ရွှေ့ပြောင်းနေလျက်ရှိပါသည်။ + not_redirecting: သင့်အကောင့်သည် လက်ရှိတွင် အခြားအကောင့်တစ်ခုသို့ ပြန်ညွှန်းနေခြင်းမဟုတ်ပါ။ + on_cooldown: မကြာသေးမီက သင့်အကောင့်ကို ပြောင်းရွှေ့ခဲ့သည်။ ဤလုပ်ဆောင်ချက်ကို %{count} ရက်များတွင် ထပ်မံရရှိနိုင်ပါမည်။ + past_migrations: ယခင်ရွှေ့ပြောင်းမှုများ + proceed_with_move: စောင့်ကြည့်သူများကို ရွှေ့ရန် + redirected_msg: သင့်အကောင့်သည် %{acct} သို့ ယခုပြန်ညွှန်းနေပါသည်။ + redirecting_to: သင့်အကောင့်က %{acct} သို့ ပြန်ညွှန်းနေသည်။ + set_redirect: ပြန်ညွှန်းသတ်မှတ်ပါ + warning: + backreference_required: အကောင့်အသစ်က ဤအကောင့်ကို ပြန်ကိုးကားရန်အတွက် ဦးစွာ ပြင်ဆင်သတ်မှတ်ရပါမည် + before: ဆက်လက်မလုပ်ဆောင်မီ ဤမှတ်စုများကို သေချာဖတ်ပါ - + cooldown: ရွှေ့ပြီးပါက နောက်တစ်ကြိမ် ထပ်ရွှေ့ရန် အချိန်စောင့်ရပါမည် + disabled_account: နောက်ပိုင်းတွင် သင့်လက်ရှိအကောင့်အား အပြည့်အဝအသုံးပြုနိုင်တော့မည်မဟုတ်သော်လည်း အချက်အလက်ထုတ်ယူခြင်းနှင့် ပြန်လည်အတည်ပြုခြင်းတို့ကို ဆောင်ရွက်နိုင်မည်ဖြစ်သည်။ + followers: ဤလုပ်ဆောင်ချက်မှာ စောင့်ကြည့်သူအားလုံးကို လက်ရှိအကောင့်မှ အကောင့်အသစ်သို့ ရွှေ့ပြောင်းခြင်းဖြစ်သည် + only_redirect_html: တနည်းအားဖြင့် သင်သည် သင့်ပရိုဖိုင်ပေါ်တွင် ပြန်ညွှန်းခြင်းကိုသာ ပြုလုပ်နိုင်သည်။ + other_data: အခြားအချက်အလက်များကို အလိုအလျောက်ရွှေ့မည်မဟုတ်ပါ + redirect: သင့်လက်ရှိအကောင့်၏ပရိုဖိုင်ကို ပြန်လည်ညွှန်းပေးသည့်အသိပေးချက်ဖြင့် ပြင်ဆင်ပေးမည်ဖြစ်ပြီး ရှာဖွေမှုများမှ ဖယ်ထုတ်ပေးမည်ဖြစ်သည် + moderation: + title: စိစစ်ခြင်း + move_handler: + carry_blocks_over_text: ဤအသုံးပြုသူသည် သင်ပိတ်ဆို့ထားသော %{acct} မှ ပြောင်းရွှေ့ခဲ့သည်။ + carry_mutes_over_text: ဤအသုံးပြုသူသည် သင်အသံပိတ်ထားသော %{acct} မှ ပြောင်းရွှေ့ခဲ့သည်။ + copy_account_note_text: ဤအသုံးပြုသူသည် %{acct} မှ ပြောင်းရွှေ့ခဲ့သည်။ ဤသည်မှာ ၎င်းတို့နှင့်ပတ်သက်သော ယခင်မှတ်စုများဖြစ်သည် - + navigation: + toggle_menu: မီနူးပြောင်းရန် notification_mailer: + admin: + report: + subject: "%{name} က တိုင်ကြားစာတစ်စောင် ပို့ခဲ့သည်" + sign_up: + subject: "%{name} က အကောင့်ဖွင့်ထားသည်" + favourite: + body: "%{name} က နှစ်သက်ခဲ့သော သင့်ပို့စ် -" + subject: "%{name} က သင့်ပို့စ်ကို နှစ်သက်ခဲ့သည်" + title: နှစ်သက်မှုအသစ်တစ်ခု follow: + body: "%{name} မှ ယခု သင့်နောက်သို့ စောင့်ကည့်နေပါသည်။" + subject: "%{name} မှ ယခု သင့်နောက်သို့ စောင့်ကည့်နေပါသည်။" title: စောင့်ကြည့်သူအသစ် + follow_request: + action: စောင့်ကြည့်ရန်တောင်းဆိုမှုများကို ပြင်ဆင်ရန် + body: "%{name} က သင့်ကို စောင့်ကြည့်ရန် တောင်းဆိုထားသည်" + subject: ဆိုင်းငံ့ထားသော စောင့်ကြည့်သူ - %{name} + title: စောင့်ကြည့်ခွင့်ပြုရန် တောင်းဆိုမှုအသစ် mention: action: စာပြန်ရန် + body: သင့်ကို %{name} မှ ဖော်ပြခဲ့သည်- subject: သင့်ကို %{name} မှ ဖော်ပြခဲ့သည် + title: ဖော်ပြမှုအသစ် + poll: + subject: "%{name} ၏ စစ်တမ်းတစ်ခု ပြီးသွားပါပြီ" + reblog: + body: "%{name} က သင့်ပို့စ်ကို Boost လုပ်ခဲ့သည် -" + subject: "%{name} က သင့်ပို့စ်ကို Boost လုပ်ခဲ့သည်" + title: Boost အသစ် status: subject: "%{name} က အခုလေးတင် ပို့စ်တင်လိုက်ပါပြီ" + update: + subject: "%{name} က ပို့စ်တစ်ခုကို ပြင်ဆင်ခဲ့သည်" + notifications: + administration_emails: စီမံခန့်ခွဲသူ အီးမေးလ် အသိပေးချက်များ + email_events: အီးမေးလ်သတိပေးချက်များအတွက်အကြောင်းအရာများ + email_events_hint: အသိပေးချက်များရယူမည့် အစီအစဉ်များကို ရွေးပါ - + other_settings: အခြားအသိပေးချက်များ၏ သတ်မှတ်ချက်များ number: human: decimal_units: @@ -315,23 +1448,215 @@ my: quadrillion: Q thousand: K trillion: T + otp_authentication: + code_hint: အတည်ပြုရန်အတွက် အထောက်အထားစိစစ်အက်ပ်မှ ထုတ်ပေးသည့်ကုဒ်ကို ထည့်သွင်းပါ + description_html: အထောက်အထားစိစစ်ခြင်းအက်ပ်ကို အသုံးပြု၍ နှစ်ဆင့်ခံလုံခြုံရေးစနစ် ဖွင့်ထားပါက အကောင့်ဝင်ရောက်ရန် သင့်ဖုန်းလက်ဝယ်ရှိရန် လိုအပ်မည်ဖြစ်ပြီး ၎င်းသည် သင်ဝင်ရောက်ရန်အတွက် တိုကင်များထုတ်ပေးမည်ဖြစ်သည်။ + enable: ဖွင့်ပါ + instructions_html: "ဤ QR ကုဒ်ကို Google Authenticator သို့မဟုတ် အလားတူ TOTP အက်ပ်ဖြင့် စကင်န်ဖတ်ပါ။ ယခုအချိန်မှစ၍ ထိုအက်ပ်သည် သင် အကောင့်ဝင်ရောက်သည့်အခါတိုင်း ထည့်သွင်းရမည့်တိုကင်များ ထုတ်ပေးမည်ဖြစ်သည်။" + manual_instructions: QR ကုဒ်စကင်န်ဖတ်၍မရပါက ကိုယ်တိုင်ရိုက်ထည့်ရန်လိုအပ်ပြီး ဤနေရာသည် စာရွက်အလွတ်နေရာဖြစ်သည်။ + setup: သတ်မှတ်ရန် + wrong_code: ထည့်သွင်းထားသောကုဒ်သည် မမှန်ကန်ပါ။ ဆာဗာအချိန်နှင့် စက်အချိန်မှာ မှန်ကန်ပါသလား။ + pagination: + newer: ပိုသစ်သော + next: ရှေ့သို့ + older: ပိုဟောင်းသော + prev: ရှေ့သို့ + truncate: "…" + polls: + errors: + already_voted: ဤစစ်တမ်းတွင် သင်ပါဝင်ပြီးဖြစ်သည် + duplicate_options: ထပ်တူညီသောအရာများပါဝင်နေသည် + duration_too_long: အလှမ်းဝေးလွန်းတယ် + duration_too_short: စောလွန်းတယ် + expired: စစ်တမ်းပြီးဆုံးသွားပါပြီ + invalid_choice: သင်ရွေးချယ်လိုသောအရာမှာ စစ်တမ်းတွင်မပါဝင်ပါ + over_character_limit: သတ်မှတ်ထားသောစာလုံးအရေအတွက် %{max} ထက်ပိုနေသည် + self_vote: သင့်ကိုယ်ပိုင်ဆန္ဒမဲများတွင် သင် မဲပေး၍ မရပါ + too_few_options: တစ်ခုထက်ပိုနေသည် + too_many_options: သတ်မှတ်ထားသောအရေအတွက် %{max} ကိုကျော်လွန်နေသည် + preferences: + other: အခြား + posting_defaults: ပို့စ်တင်ရာတွင် သတ်မှတ်ချက်များ + public_timelines: အများမြင်စာမျက်နှာ + privacy: + hint_html: "သင့်ပရိုဖိုင်နှင့် သင့်ပို့စ်များကို ရှာဖွေလိုသည့်ပုံစံကို စိတ်ကြိုက်ပြင်ဆင်ပါ။ Mastodon ရှိ အင်္ဂါရပ်များစွာကို ဖွင့်ထားသည့်အခါ ပိုမိုကျယ်ပြန့်သော ပရိသတ်ထံ သင်ရောက်ရှိစေရန် ကူညီပေးနိုင်ပါသည်။ သင့်အသုံးပြုမှုကိစ္စနှင့် ကိုက်ညီကြောင်း သေချာစေရန်အတွက် ဤသတ်မှတ်ချက်များကို ပြန်လည်သုံးသပ်သင့်ပါသည်။" + privacy: ကိုယ်ရေးအချက်အလက် + reach: Reach + search: ရှာရန် + title: ကိုယ်ရေးအချက်အလက်နှင့် reach privacy_policy: title: ကိုယ်ရေးအချက်အလက်မူဝါဒ + reactions: + errors: + limit_reached: မတူညီသော တုံ့ပြန်မှုများ၏ ကန့်သတ်ချက်သို့ ရောက်ရှိခဲ့သည်။ + unrecognized_emoji: အသိအမှတ်ပြုထားသော အီမိုဂျီမဟုတ်ပါ relationships: + activity: အကောင့်လုပ်ဆောင်ချက် + confirm_follow_selected_followers: ရွေးချယ်စောင့်ကြည့်သူများကို စောင့်ကြည့်လိုသည်မှာ သေချာပါသလား။ + confirm_remove_selected_followers: ရွေးချယ်စောင့်ကြည့်သူများကို ဖယ်ရှားလိုသည်မှာ သေချာပါသလား။ + confirm_remove_selected_follows: ရွေးချယ်စောင့်ကြည့်သူများကို ဖယ်ရှားလိုသည်မှာ သေချာပါသလား။ + dormant: Dormant + follow_failure: ရွေးချယ်ထားသော အကောင့်အချို့ကို စောင့်ကြည့်၍ရမည်မဟုတ်ပါ။ + follow_selected_followers: ရွေးချယ်စောင့်ကြည့်သူများကို စောင့်ကြည့်ပါ followers: စောင့်ကြည့်သူများ following: စောင့်ကြည့်နေသည် + invited: ဖိတ်ခေါ်ထားပြီး + last_active: နောက်ဆုံးအသုံးပြုခဲ့သည့်အချိန် + most_recent: မကြာသေးမီက + moved: ရွှေ့ပြီးပါပြီ mutual: အပြန်အလှန်စောင့်ကြည့်ထားခြင်း + primary: ဦးစားပေး + relationship: တော်စပ်ပုံ + remove_selected_domains: ရွေးချယ်ထားသော ဒိုမိန်းများမှ စောင့်ကြည့်သူအားလုံးကို ဖယ်ရှားပါ + remove_selected_followers: ရွေးချယ်ထားသော စောင့်ကြည့်သူများကို ဖယ်ရှားပါ + remove_selected_follows: ရွေးချယ်ထားသော အသုံးပြုသူများကို စောင့်ကြည့်ခြင်းမှ ဖြုတ်ပါ + status: အကောင့်အခြေအနေ + remote_follow: + missing_resource: သင့်အကောင့်အတွက် လိုအပ်သော ပြန်ညွှန်းမည့် URL ကို ရှာမတွေ့ပါ + reports: + errors: + invalid_rules: မှန်ကန်သောစည်းမျဉ်းများကို ကိုးကားထားခြင်း မရှိပါ + rss: + content_warning: 'အကြောင်းအရာသတိပေးချက် - ' + descriptions: + account: "@%{acct} မှ အများမြင်ပို့စ်များ" + tag: "#%{hashtag} ကို တဂ်ထားသော အများမြင်ပို့စ်များ" + scheduled_statuses: + over_daily_limit: ယနေ့အတွက် စီစဉ်ထားသည့် ပို့စ်များ၏ ကန့်သတ်ချက် %{limit} ကို ကျော်လွန်သွားပါပြီ + over_total_limit: စီစဉ်ထားသည့် ပို့စ်များ၏ ကန့်သတ်ချက် %{limit} ကို ကျော်လွန်သွားပါပြီ + too_soon: စီစဉ်ထားသောရက်စွဲမှာ အနာဂတ်အတွက်ဖြစ်သည် sessions: + activity: နောက်ဆုံးလုပ်ဆောင်ချက် + browser: ဘရောက်ဇာ + browsers: + alipay: Alipay + blackberry: BlackBerry + chrome: Chrome + edge: Microsoft Edge + electron: အီလက်ထရွန် + firefox: Firefox + generic: အမည်မသိဘရောက်ဆာ + huawei_browser: Huawei Browser + ie: Internet Explorer + micro_messenger: MicroMessenger + nokia: Nokia S40 Ovi Browser + opera: Opera + otter: Otter + phantom_js: PhantomJS + qq: QQ Browser + safari: Safari + uc_browser: UC Browser + unknown_browser: အမည်မသိဘရောက်ဆာ + weibo: Weibo + current_session: လက်ရှိဆက်ရှင် + description: "%{platform} ပေါ်ရှိ %{browser}" + explanation: ဤသည်မှာ သင်၏ Mastodon အကောင့်သို့ လက်ရှိဝင်ရောက်ထားသည့် ဝဘ်ဘရောက်ဆာများဖြစ်သည်။ + ip: IP platforms: + adobe_air: Adobe Air + android: Android + blackberry: BlackBerry + chrome_os: ChromeOS + firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS + unknown_platform: အမည်မသိ Platform + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone + revoke: ပြန်ရုပ်သိမ်းရန် + revoke_success: ဆက်ရှင်ကို ရုပ်သိမ်းလိုက်ပါပြီ + title: ဆက်ရှင်များ + view_authentication_history: သင့်အကောင့်၏ စစ်မှန်ကြောင်းအထောက်အထားပြမှုကို ကြည့်ပါ settings: + account: အကောင့် + account_settings: အကောင့်သတ်မှတ်ချက်များ + aliases: အကောင့်အမည်တူများ + appearance: ပုံပန်းသဏ္ဌာန် + authorized_apps: ခွင့်ပြုထားသောအက်ပ်များ + back: Mastodon သို့ ပြန်သွားရန် + delete: အကောင့်ဖျက်သိမ်းခြင်း + development: Development edit_profile: ပရိုဖိုင်ပြင်ဆင်ရန် + export: အချက်အလက်ထုတ်ယူခြင်း + featured_tags: အသားပေးဖော်ပြထားသည့် ဟက်ရှ်တဂျ်များ + import: ထည့်သွင်းခြင်း + import_and_export: ထည့်သွင်းခြင်းနှင့် ထုတ်ယူခြင်း + migrate: အကောင့်ပြောင်းရွှေ့ခြင်း + notifications: အသိပေးချက်များ + preferences: သတ်မှတ်ချက်များ + profile: ပရိုဖိုင် + relationships: စောင့်ကြည့်သူများနှင့် စောင့်ကြည့်စာရင်း + statuses_cleanup: အလိုအလျောက်ပို့စ်ဖျက်ခြင်း + strikes: စိစစ်လုပ်ဆောင်ချက်များ + two_factor_authentication: နှစ်ဆင့်ခံလုံခြုံရေးစနစ် + webauthn_authentication: လုံခြုံရေးကီးများ statuses: + attached: + audio: + other: "%{count} အသံ" + description: ပူးတွဲပါ- %{attached} + image: + other: "%{count} ပုံ" + video: + other: "%{count} ဗီဒီယို" + boosted_from_html: "%{acct_link} မှ Boost လုပ်ခဲ့သည်" + content_warning: အကြောင်းအရာသတိပေးချက် - %{warning} + default_language: လက်ရှိသုံးနေသောဘာသာစကားအတိုင်း ပြပေးပါမည် + disallowed_hashtags: + other: ခွင့်မပြုထားသော hashtags များပါရှိသည် - %{tags} + edited_at_html: "%{date} ကို ပြင်ဆင်ပြီးပါပြီ" + errors: + in_reply_not_found: သင် စာပြန်နေသည့်ပို့စ်မှာ မရှိတော့ပါ။ + open_in_web: ဝဘ်တွင် ဖွင့်ပါ + over_character_limit: စာလုံးကန့်သတ်ချက် %{max} ကို ကျော်လွန်သွားပါပြီ + pin_errors: + direct: အမည်ဖော်ပြထားသည့် ပို့စ်များကို ပင်တွဲ၍မရပါ + limit: သင်သည် ပို့စ်အရေအတွက်အများဆုံးကို ပင်တွဲထားပြီးဖြစ်သည် + ownership: အခြားသူ၏ပို့စ်ကို ပင်တွဲ၍မရပါ + reblog: Boost လုပ်ထားသောပို့စ်ကို ပင်ထား၍မရပါ + poll: + total_people: + other: "%{count} ယောက်" + total_votes: + other: မဲအရေအတွက် %{count} မဲ + vote: မဲပေးမည် + show_more: ပိုမိုပြရန် + show_newer: ပို့စ်အသစ်များပြရန် + show_older: ပို့စ်အဟောင်းများပြရန် + show_thread: Thread ကို ပြပါ + title: '%{name}: "%{quote}"' visibilities: + direct: တိုက်ရိုက် + private: စောင့်ကြည့်သူများသာ + private_long: စောင့်ကြည့်သူများကိုသာ ပြရန် public: အများမြင် + public_long: လူတိုင်းမြင်နိုင်ပါသည် + unlisted: စာရင်းမသွင်းထားပါ + unlisted_long: လူတိုင်းမြင်နိုင်သော်လည်း အများမြင်မည့်စာမျက်နှာများတွင် စာရင်းမသွင်းထားပါ။ statuses_cleanup: + enabled: ပို့စ်အဟောင်းများကို အလိုအလျောက် ဖျက်ပါ + enabled_hint: အောက်ပါခြွင်းချက်များထဲမှ တစ်ခုနှင့် မကိုက်ညီပါက သတ်မှတ်ထားသည့်ကာလအပိုင်းအခြားသို့ ရောက်သည်နှင့် သင့်ပို့စ်များကို အလိုအလျောက် ဖျက်ပါမည် + exceptions: ခြွင်းချက်များ + explanation: ပို့စ်များကို ဖျက်ခြင်းသည် စျေးကြီးသော လုပ်ဆောင်မှုတစ်ခုဖြစ်သောကြောင့်၊ ဆာဗာမှမဟုတ်ရင် အလုပ်ရှုပ်နေချိန်တွင် အချိန်ကြာလာသည်နှင့်အမျှ ၎င်းကို ဖြည်းဖြည်းချင်း လုပ်ဆောင်ပါသည်။ ထို့ကြောင့်၊ သင့်ပို့စ်များသည် အချိန်သတ်မှတ်ချက်သို့ရောက်ရှိပြီးနောက် ခဏအကြာတွင် ဖျက်လိုက်နိုင်ပါသည်။ + ignore_favs: နှစ်သက်မှုများကို လျစ်လျူရှုပါ + ignore_reblogs: Boost များကို လျစ်လျူရှုပါ + interaction_exceptions: အပြန်အလှန်တုံ့ပြန်မှုများအပေါ်အခြေခံသည့် ခြွင်းချက်များ + interaction_exceptions_explanation: ပို့စ်များသည် အကြိုက်ဆုံးအဆင့်အောက်သို့ရောက်သွားပါက သို့မဟုတ် ၎င်းတို့ကို တစ်ကြိမ်ကျော်ပြီးပါက ဖျက်ပစ်ရန် အာမခံချက်မရှိကြောင်း သတိပြုပါ။ + keep_direct: တိုက်ရိုက်မက်ဆေ့ချ်များကို သိမ်းထားပါ + keep_direct_hint: တိုက်ရိုက်စကားပြောထားသည်များကို မဖျက်ပါနှင့် + keep_media: မီဒီယာဖိုင်များပါသောပို့စ်များကို သိမ်းဆည်းပါ + keep_media_hint: မီဒီယာဖိုင်များပါသောပို့စ်များကို မဖျက်ပါနှင့် + keep_pinned: ပင်ထိုးထားသော ပို့စ်များကို သိမ်းထားပါ + keep_pinned_hint: ပင်ထိုးထားသော ပို့စ်များကို မဖျက်ပါ + keep_polls: စစ်တမ်းကိုဆက်လက်ထားမည် + keep_polls_hint: သင့်မှတ်တမ်းတစ်ခုမှ မပျက်ပါ + keep_self_bookmark: မှတ်ထားသောပို့စ်များကို သိမ်းဆည်းပါ + keep_self_bookmark_hint: မှတ်ထားပြီးသော ပို့စ်များကို မဖျက်ပါနှင့် + keep_self_fav: သင်နှစ်သက်ခဲ့သောပို့စ်များကို သိမ်းထားပါ + keep_self_fav_hint: နှစ်သက်ထားပြီးသော ပို့စ်များကို မဖျက်ပါနှင့် min_age: '1209600': ၂ ပတ် '15778476': ၆ လ @@ -341,11 +1666,137 @@ my: '604800': ၁ ပတ် '63113904': ၂ နှစ် '7889238': ၃ လ + min_age_label: ကာလအပိုင်းအခြား + min_favs: အနည်းဆုံးအားဖြင့် နှစ်သက်သည့်ပို့စ်များကို သိမ်းဆည်းပါ + min_favs_hint: အနည်းဆုံး ဤအကြိုက်ဆုံးအရေအတွက်ကို လက်ခံရရှိထားသည့် သင့်ပို့စ်များကို မဖျက်ပါ။ ပို့စ်များကို ၎င်းတို့၏ စိတ်ကြိုက်အရေအတွက်မခွဲခြားဘဲ ဖျက်ရန် ချန်ထားပါ။ + min_reblogs: အနည်းဆုံးအားဖြင့် Boost လုပ်ထားသည့်ပို့စ်များကို သိမ်းဆည်းပါ + min_reblogs_hint: အနည်းဆုံး ဤအကြိမ်အရေအတွက်ကို မြှင့်တင်ထားသည့် သင့်ပို့စ်များကို မဖျက်ပါ။ ၎င်းတို့၏ မြှင့်တင်မှုအရေအတွက်ကို မခွဲခြားဘဲ ပို့စ်များကို ဖျက်ရန် ချန်ထားပါ + stream_entries: + sensitive_content: သတိထားရသော အကြောင်းအရာ + strikes: + errors: + too_late: ဤလုပ်ဆောင်ချက်တင်ပြရန် နောက်ကျသွားပါပြီ + tags: + does_not_match_previous_name: ယခင်အမည်နှင့် မကိုက်ညီပါ + themes: + contrast: Mastodon (စာသားအလင်းပုံစံ) + default: Mastodon (အနက်နောက်ခံပုံစံ) + mastodon-light: Mastodon (အလင်းနောက်ခံပုံစံ) time: formats: + default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: ဘာသာပြန်ဝန်ဆောင်မှုအတွက် ဆာဗာတစ်ခုလုံးအသုံးပြုမှုခွဲတမ်းကို ကျော်လွန်သွားပါပြီ။ + too_many_requests: မကြာသေးမီက ဘာသာပြန်ဝန်ဆောင်မှုသို့ တောင်းဆိုမှု အများအပြားရှိခဲ့သည်။ two_factor_authentication: + add: ထည့်ရန် disable: 2FA ကို ပိတ်ပါ + disabled_success: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို ပိတ်ပြီးပါပြီ + edit: ပြင်ဆင်ရန် enabled: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို ဖွင့်ထားသည် enabled_success: နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ကို ဖွင့်ပြီးပါပြီ + generate_recovery_codes: ပြန်လည်ရယူရေးကုဒ်များ ဖန်တီးပါ + lost_recovery_codes: သင့်ဖုန်းပျောက်ဆုံးသွားပါက ပြန်လည်ရယူခြင်းကုဒ်များသည် သင့်အကောင့်သို့ ပြန်လည်ဝင်ရောက်ခွင့်ရရှိစေမည်ဖြစ်သည်။ သင်၏ ပြန်လည်ရယူရေးကုဒ်များ ပျောက်ဆုံးသွားပါက ၎င်းတို့ကို ဤနေရာတွင် ပြန်လည်ထုတ်ပေးနိုင်ပါသည်။ သင်၏ ပြန်လည်ရယူရေး ကုဒ်ဟောင်းများ ပျက်သွားပါမည်။ + methods: နှစ်ဆင့်ခံလုံခြုံရေးနည်းလမ်းများ + otp: Authenticator အက်ပ် + recovery_codes: အရန်ပြန်လည်ရယူရေးကုဒ်များ + recovery_codes_regenerated: ပြန်လည်ရယူရေးကုဒ်များကို ပြန်ထုတ်ပေးပြီးပါပြီ + recovery_instructions_html: သင့်ဖုန်းသို့ ဝင်ရောက်သုံးစွဲခွင့် ဆုံးရှုံးခဲ့ဖူးပါက၊ သင့်အကောင့်သို့ ပြန်လည်ဝင်ရောက်ခွင့်ရရန် အောက်ပါ ပြန်လည်ရယူရေးကုဒ်များထဲမှ တစ်ခုကို အသုံးပြုနိုင်ပါသည်။ ပြန်လည်ရယူရေးကုဒ်များကို လုံခြုံအောင်ထားပါ။ ဥပမာအားဖြင့်၊ သင်သည် ၎င်းတို့ကို ပရင့်ထုတ်ပြီး အခြားအရေးကြီးစာရွက်စာတမ်းများဖြင့် သိမ်းဆည်းနိုင်သည်။ + webauthn: လုံခြုံရေးကီးများ + user_mailer: + appeal_approved: + action: သင့်အကောင့်သို့ သွားပါ + explanation: "%{appeal_date} တွင် သင်တင်သွင်းခဲ့သည့် %{strike_date} တွင် သင့်အကောင့်ကို ဆန့်ကျင်သည့် တိုင်ချက်၏ အယူခံဝင်မှုကို အတည်ပြုပြီးဖြစ်သည်။ သင့်အကောင့်သည် ကောင်းမွန်သောအနေအထားတွင် ရှိနေပြန်သည်။" + subject: "%{date} တွင် သင့်အယူခံဝင်ချက်ကို အတည်ပြုပြီးပါပြီ" + title: အယူခံဝင်သည် + appeal_rejected: + explanation: "%{appeal_date} တွင် သင်တင်သွင်းခဲ့သည့် %{strike_date} တွင် သင့်အကောင့်ကို ဆန့်ကျင်သည့် တိုင်ချက်၏ အယူခံဝင်မှုကို ပယ်ချခဲ့သည်။" + subject: "%{date} တွင် သင့်တင်ပြချက်ကို ပယ်ချခဲ့သည်" + title: အယူခံကို ပယ်ချခဲ့သည် + backup_ready: + explanation: သင့် Mastodon အကောင့် အရန်ကူးယူရန် တောင်းဆိုပြီးဖြစ်သည်။ ယခု ဒေါင်းလုဒ်လုပ်နိုင်ပါပြီ။ + subject: သင့်မှတ်တမ်း ဒေါင်းလုဒ်ဆွဲရန် အသင့်ဖြစ်ပါပြီ + title: မှတ်တမ်းသိမ်းရန် + suspicious_sign_in: + change_password: သင်၏ စကားဝှက်ပြောင်းလဲပါ + details: ဤသည်မှာ အကောင့်ဝင်ရောက်ခြင်းအတွက် အသေးစိတ်အချက်များဖြစ်သည် - + explanation: IP လိပ်စာအသစ်တစ်ခုမှနေ၍ သင့်အကောင့်ဝင်ရောက်သည်ကို တွေ့ရှိခဲ့ပါသည်။ + further_actions_html: သင် မဟုတ်ပါက သင့်အကောင့်လုံခြုံစေရန်အတွက် %{action} ကို ချက်ချင်းဆောင်ရွက်ပြီး နှစ်ဆင့်ခံလုံခြုံရေးစနစ်ဖွင့်ထားရန် အကြံပြုပါသည်။ + subject: သင့်အကောင့်ကို IP လိပ်စာအသစ်တစ်ခုမှ ဝင်ရောက်အသုံးပြုလျက်ရှိသည် + title: အကောင့်ဝင်ရောက်မှုအသစ် + warning: + appeal: အယူခံတင်သွင်းပါ + appeal_description: အမှားအယွင်းတစ်ခုဟု သင်ယုံကြည်ပါက %{instance} ဝန်ထမ်းများထံ တင်ပြနိုင်သည်။ + categories: + spam: Spam + violation: အကြောင်းအရာသည် အောက်ပါကွန်မြူနတီလမ်းညွှန်ချက်များကို ချိုးဖောက်သည်။ + explanation: + delete_statuses: သင့်ပို့စ်အချို့သည် တစ်ခု သို့မဟုတ် တစ်ခုထက်ပိုသော ကွန်မြူနတီလမ်းညွှန်ချက်များကို ချိုးဖောက်ကြောင်း တွေ့ရှိပြီး %{instance} ၏ ကြီးကြပ်သူများမှ ဖယ်ရှားလိုက်ပါသည်။ + disable: သင့်အကောင့်ကို အသုံးမပြုနိုင်တော့သော်လည်း သင့်ပရိုဖိုင်နှင့် အခြားအချက်အလက်များမှာ ကျန်ရှိနေမည်ဖြစ်သည်။ သင့်အချက်အလက်ကို မိတ္တူကူးရန်၊ အကောင့်သတ်မှတ်ချက်များကို ပြောင်းလဲရန် သို့မဟုတ် သင့်အကောင့်ဖျက်သိမ်းရန်တို့အတွက် အရန်သိမ်းဆည်းမှုအား သင် တောင်းဆိုနိုင်သည်။ + mark_statuses_as_sensitive: သင့်ပို့စ်အချို့ကို %{instance} ၏ စိစစ်သူများမှ သတိထားရသောပို့စ်များအဖြစ် အမှတ်အသားပြုထားသည်။ ဆိုလိုသည်မှာ လူများသည် အစမ်းကြည့်ခြင်းမပြသမီ ပို့စ်များရှိ မီဒီယာကိုနှိပ်ရန် လိုအပ်မည်ဖြစ်ပါသည်။ နောင်တွင် ပို့စ်တင်သည့်အခါ သင်ကိုယ်တိုင် သတိထားရသောမီဒီယာအဖြစ် သတ်မှတ်နိုင်သည်။ + sensitive: ယခုအချိန်မှစ၍ သင် အပ်လုဒ်လုပ်ထားသော မီဒီယာဖိုင်များအားလုံးကို သတိထားရသောမီဒီယာအဖြစ် အမှတ်အသားပြုပြီး ကလစ်နှိပ်၍သတိပေးချက်နောက်တွင် ဖျောက်ထားပါမည်။ + silence: သင့်အကောင့်ကို ဆက်လက်အသုံးပြုနိုင်သော်လည်း သင့်စောင့်ကြည့်သူများသာ ဤဆာဗာတွင် သင့်ပို့စ်များကို မြင်နိုင်မည်ဖြစ်ပြီး အကြောင်းအရာခေါင်းစဉ်အမျိုးမျိုးမှ သင့်ကို ဖယ်ထုတ်ထားနိုင်သည်။ သို့သော် အခြားသူများက သင့်ကို စောင့်ကြည့်နေနိုင်ပါသေးသည်။ + suspend: သင့်အကောင့်ကို အသုံးမပြုနိုင်တော့သည့်အပြင် ပရိုဖိုင်နှင့် အခြားအချက်အလက်များကိုလည်း အသုံးပြု၍မရတော့ပါ။ သင့်အချက်အလက်ကို ရက်ပေါင်း ၃၀ ခန့်အတွင်း အပြည့်အဝ မဖယ်ရှားမချင်း အချက်အလက်များ အရန်ကူးယူရန်အတွက် အကောင့်သို့ ဝင်ရောက်နိုင်ပါသေးသည်။ သို့သော် အကောင့်ရပ်ဆိုင်းထားမှုရှောင်လွှဲခြင်းမှ ကာကွယ်ရန်အတွက် အခြေခံအချက်အလက်အချို့ကို ကျွန်ုပ်တို့ ထိန်းသိမ်းထားရပါမည်။ + reason: အကြောင်းပြချက် - + statuses: ကိုးကားထားသောပို့စ်များ - + subject: + delete_statuses: "%{acct} ရှိ သင့်ပို့စ်များကို ဖယ်ရှားလိုက်ပါပြီ" + disable: သင့်အကောင့် %{acct} ကို ပိတ်သိမ်းထားသည် + mark_statuses_as_sensitive: "%{acct} ရှိ သင့်ပို့စ်များကို သတိထားရသောပို့စ်များအဖြစ် အမှတ်အသားပြုထားသည်" + none: "%{acct} အတွက် သတိပေးချက်" + sensitive: "%{acct} ရှိ သင့်ပို့စ်များကို ယခုမှစပြီး သတိထားရသောပို့စ်များအဖြစ် အမှတ်အသားပြုပါမည်" + silence: သင့်အကောင့် %{acct} ကို ကန့်သတ်ထားသည် + suspend: သင့်အကောင့် %{acct} ကို ဆိုင်းငံ့ထားသည် + title: + delete_statuses: ပို့စ်များကို ဖယ်ရှားခဲ့သည် + disable: အကောင့်ပိတ်သွားပါပြီ။ + mark_statuses_as_sensitive: သတိထားရသောပို့စ်များအဖြစ် အမှတ်အသားပြုပါ + none: သတိပေးချက် + sensitive: သတိထားရသောအကောင့်အဖြစ် အမှတ်အသားပြုပါ + silence: အကောင့်ကန့်သတ်ထားသည် + suspend: အကောင့်ရပ်ဆိုင်းထားသည် + welcome: + edit_profile_action: ပရိုဖိုင်ထည့်သွင်းရန် + edit_profile_step: ပရိုဖိုင်ဓာတ်ပုံတစ်ပုံ တင်ခြင်း၊ ဖော်ပြမည့်အမည် ပြောင်းလဲခြင်းနှင့် အခြားအရာများပြုလုပ်ခြင်းတို့ဖြင့် သင့်ပရိုဖိုင်ကို စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါသည်။ စောင့်ကြည့်သူအသစ်များ သင့်ကိုစောင့်ကြည့်ခွင့်မပြုမီ ပြန်လည်သုံးသပ်ရန်အတွက် ဆုံးဖြတ်နိုင်ပါသည်။ + explanation: ဤသည်မှာ သင် စတင်အသုံးပြုနိုင်ရန်အတွက် အကြံပြုချက်အချို့ဖြစ်ပါသည် + final_action: ပို့စ် တင်ရန် + final_step: 'ပို့စ်စပြီး တင်နိုင်ပါပြီ။ စောင့်ကြည့်သူများမရှိသေးသော်လည်း သင့်အများမြင်ပို့စ်များကို ဒေသတွင်းစာမျက်နှာ သို့မဟုတ် ဟက်ရှ်တက်စာမျက်နှာတို့တွင် အခြားသူများက မြင်နိုင်ပါသည်။ #introductions ဟက်ရှ်တက်ဖြင့် သင့်ကိုယ်သင် မိတ်ဆက်နိုင်ပါသည်။' + full_handle: ကိုယ်တိုင်ထိန်းချုပ်နိုင်သည် + full_handle_hint: ဤသည်မှာ သင့်သူငယ်ချင်းများကို အခြားဆာဗာတစ်ခုမှ မက်ဆေ့ချ်ပို့နိုင်ကြောင်း သို့မဟုတ် စောင့်ကြည့်နိုင်ကြောင်း အသိပေးပါမည်။ + subject: Mastodon မှ လှိုက်လှဲစွာကြိုဆိုပါသည်။ + title: "%{name} က ကြိုဆိုပါတယ်။" + users: + follow_limit_reached: လူ %{limit} ထက် ပိုပြီး စောင့်ကြည့်၍မရပါ + go_to_sso_account_settings: အထောက်အထားပေးသူ၏အကောင့်သတ်မှတ်ချက်များသို့ သွားပါ + invalid_otp_token: မမှန်ကန်သော နှစ်ဆင့်ခံလုံခြုံရေးကုဒ် + otp_lost_help_html: နှစ်ခုစလုံးကို ဝင်ရောက်ခွင့် ဆုံးရှုံးသွားပါက %{email} နှင့် ဆက်သွယ်နိုင်ပါသည် + seamless_external_login: ပြင်ပဝန်ဆောင်မှုမှတစ်ဆင့် အကောင့်ဝင်ထားသောကြောင့် စကားဝှက်နှင့် အီးမေးလ်သတ်မှတ်ချက်များကို မရနိုင်ပါ။ + signed_in_as: အဖြစ် အကောင့်ဝင်ခဲ့သည် - + verification: + extra_instructions_html: အကြံပြုချက်- သင့်ဝဘ်ဆိုက်ရှိ လင့်ခ်ကို မမြင်နိုင်ပါ။ အရေးကြီးသော အပိုင်းမှာ rel="me" သည် အသုံးပြုသူဖန်တီးထားသော အကြောင်းအရာများဖြင့် ဝဘ်ဆိုက်များတွင် အယောင်ဆောင်ခြင်းကို တားဆီးပေးသည်။ a အစား စာမျက်နှာ၏ ခေါင်းစီးတွင် link တဂ်ကိုပင် သုံးနိုင်သော်လည်း HTML ကို JavaScript မလုပ်ဆောင်ဘဲ အသုံးပြုနိုင်ရပါမည်။ + here_is_how: ဘယ်လိုလဲ + hint_html: "Mastodon တွင် သင့်အထောက်အထားအတည်ပြုခြင်းသည် လူတိုင်းအတွက်ဖြစ်သည်။ ပွင့်လင်းသော ဝဘ်စံနှုန်းများကို အခြေခံ၍ ယခုနှင့် ထာဝရ အခမဲ့အသုံးပြုနိုင်ပါသည်။ သင်လိုအပ်သမျှမှာ သင့်အား လူများက အသိအမှတ်ပြုသည့် ကိုယ်ပိုင်ဝဘ်ဆိုဒ်တစ်ခုဖြစ်သည်။ သင့်ပရိုဖိုင်မှ ဤဝဘ်ဆိုက်သို့ လင့်ခ်ချိတ်သောအခါ ဝဘ်ဆိုဒ်သည် သင့်ပရိုဖိုင်သို့ လင့်ခ်ချိတ်ကြောင်း စစ်ဆေးပြီး ၎င်းတွင် မြင်သာသော အညွှန်းကို ပြသပါမည်။" + instructions_html: သင့်ဝဘ်ဆိုဒ်ရှိ HTML တွင် အောက်ပါကုဒ်ကို ကူးယူပြီး ထည့်ပါ။ ထို့နောက် "ပရိုဖိုင်တည်းဖြတ်ရန်" တက်ဘ်မှ သင့်ပရိုဖိုင်ရှိ အပိုအကွက်များထဲမှ တစ်ခုထဲသို့ သင့်ဝဘ်ဆိုက်လိပ်စာကို ထည့်ကာ အပြောင်းအလဲများကို သိမ်းဆည်းပါ။ + verification: စိစစ်ခြင်း + verified_links: အတည်ပြုထားသောလင့်ခ်များ + webauthn_credentials: + add: လုံခြုံရေးကီးအသစ်ထည့်ပါ + create: + error: သင့်လုံခြုံရေးကီးထည့်ရာတွင် ပြဿနာရှိနေသည်။ ထပ်စမ်းကြည့်ပါ။ + success: လုံခြုံရေးကီး ထည့်ပြီးပါပြီ။ + delete: ဖျက်ရန် + delete_confirmation: လုံခြုံရေးကီးဖျက်ရန် သေချာပါသလား။ + description_html: "လုံခြုံရေးကီးအထောက်အထားစိစစ်ခြင်းကို ဖွင့်ထားပါက လုံခြုံရေးကီးများထဲမှ တစ်ခုကို အကောင့်ဝင်ရောက်ရန်အတွက် အသုံးပြုရန်လိုအပ်ပါသည်" + destroy: + error: သင့်လုံခြုံရေးကီးကို ဖျက်ရာတွင် ပြဿနာရှိနေသည်။ ထပ်စမ်းကြည့်ပါ။ + success: လုံခြုံရေးကီး ဖျက်ပြီးပါပြီ။ + invalid_credential: လုံခြုံရေးကီးမမှန်ကန်ပါ + nickname_hint: သင့်လုံခြုံရေးကီးအသစ်၏ အမည်ပြောင်ကို ထည့်ပါ။ + not_enabled: WebAuthn ကို သင် မဖွင့်ရသေးပါ + not_supported: ဤဘရောက်ဆာသည် လုံခြုံရေးကီးများကို မပံ့ပိုးပါ + otp_required: လုံခြုံရေးကီးများကို အသုံးပြုရန်အတွက် နှစ်ဆင့်ခံလုံခြုံရေးစနစ်စိစစ်ခြင်းကို ဦးစွာဖွင့်ပါ။ + registered_on: "%{date} တွင် စာရင်းသွင်းထားသည်" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index d293f75395..3e9d502ae9 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1,7 +1,7 @@ --- nl: about: - about_mastodon_html: 'Het sociale netwerk van de toekomst: geen advertenties, geen bedrijven die meekijken, ethisch ontworpen, en gedecentraliseerd! Wees eigenaar van jouw eigen gegevens met Mastodon!' + about_mastodon_html: 'Het sociale netwerk van de toekomst: geen reclame, geen meekijkende bedrijven, ethisch ontwerp, en gedecentraliseerd! Met Mastodon ben je baas over je eigen gegevens!' contact_missing: Niet ingesteld contact_unavailable: n.v.t hosted_on: Mastodon op %{domain} @@ -71,7 +71,7 @@ nl: enabled: Ingeschakeld enabled_msg: Het ontdooien van het account van %{username} is geslaagd followers: Volgers - follows: Volgt + follows: Gevolgde accounts header: Omslagfoto inbox_url: Inbox-URL invite_request_text: Redenen om te registreren @@ -91,6 +91,7 @@ nl: moderation: active: Actief all: Alles + disabled: Uitgeschakeld pending: In afwachting silenced: Beperkt suspended: Opgeschort @@ -124,8 +125,8 @@ nl: removed_header_msg: Het verwijderen van de omslagfoto van %{username} is geslaagd resend_confirmation: already_confirmed: Deze gebruiker is al bevestigd - send: Bevestigingsmail opnieuw verzenden - success: Bevestigingsmail succesvol verzonden! + send: Bevestigingslink opnieuw verzenden + success: Bevestigingslink succesvol verzonden! reset: Opnieuw reset_password: Wachtwoord opnieuw instellen resubscribe: Opnieuw abonneren @@ -133,6 +134,7 @@ nl: search: Zoeken search_same_email_domain: Andere gebruikers met hetzelfde e-maildomein search_same_ip: Andere gebruikers met hetzelfde IP-adres + security: Beveiliging security_measures: only_password: Alleen wachtwoord password_and_2fa: Wachtwoord en tweestapsverificatie @@ -307,6 +309,7 @@ nl: unpublish: Uitschakelen unpublished_msg: Ongedaan maken van gepubliceerde mededeling geslaagd! updated_msg: Bijwerken van mededeling geslaagd! + critical_update_pending: Kritieke update in behandeling custom_emojis: assign_category: Categorie toewijzen by_domain: Domein @@ -380,6 +383,15 @@ nl: undo: Federatie met domein afkeuren domain_blocks: add_new: Nieuwe domeinblokkade toevoegen + confirm_suspension: + cancel: Annuleren + confirm: Opschorten + permanent_action: De schorsing ongedaan maken zal geen gegevens of volgrelaties herstellen. + preamble_html: Je staat op het punt om %{domain} en subdomeinen op te schorten. + remove_all_data: Dit verwijdert alle inhoud, media en profielgegevens van de accounts van dit domein van jouw server. + stop_communication: Jouw server zal niet langer met deze servers communiceren. + title: Domeinblokkade voor %{domain} bevestigen + undo_relationships: Dit zal elke volgrelatie tussen de accounts van deze servers en die van jou ongedaan maken. created_msg: Domeinblokkade wordt nu verwerkt destroyed_msg: Domeinblokkade is ongedaan gemaakt domain: Domein @@ -427,6 +439,7 @@ nl: resolve: Domein opzoeken title: Nieuw e-maildomein blokkeren no_email_domain_block_selected: Er werden geen e-maildomeinblokkades gewijzigd, omdat er geen enkele werd geselecteerd + not_permitted: Niet toegestaan resolved_dns_records_hint_html: De domeinnaam slaat op de volgende MX-domeinen die uiteindelijk verantwoordelijk zijn voor het accepteren van e-mail. Het blokkeren van een MX-domein blokkeert aanmeldingen van elk e-mailadres dat hetzelfde MX-domein gebruikt, zelfs als de zichtbare domeinnaam anders is. Pas op dat u geen grote e-mailproviders blokkeert. resolved_through_html: Geblokkeerd via %{domain} title: Geblokkeerde e-maildomeinen @@ -473,6 +486,7 @@ nl: content_policies: comment: Interne reden description_html: Je kunt het beleid bepalen dat op de accounts van dit domein en alle subdomeinen van toepassing is. + limited_federation_mode_description_html: Je kunt kiezen of je federatie met dit domein wilt toestaan. policies: reject_media: Mediabestanden weigeren reject_reports: Rapportages weigeren @@ -585,11 +599,13 @@ nl: assign_to_self: Aan mij toewijzen assigned: Toegewezen moderator by_target_domain: Domein van gerapporteerde account + cancel: Annuleren category: Category category_description_html: De reden waarom dit account en/of inhoud werd gerapporteerd wordt aan het gerapporteerde account medegedeeld comment: none: Geen comment_description_html: 'Om meer informatie te verstrekken, schreef %{name}:' + confirm: Bevestigen confirm_action: Bevestig moderatiemaatregel tegen @%{acct} created_at: Gerapporteerd op delete_and_resolve: Bericht verwijderen @@ -725,6 +741,9 @@ nl: branding: preamble: De branding van jouw server laat zien hoe het met andere servers in het netwerk verschilt. Deze informatie wordt op verschillende plekken getoond, zoals in de webomgeving van Mastodon, in mobiele apps, in voorvertoningen op andere websites en berichten-apps, enz. Daarom is het belangrijk om de informatie helder, kort en beknopt te houden. title: Branding + captcha_enabled: + desc_html: Dit is afhankelijk van externe scripts van hCaptcha, wat veiligheids- en privacyrisico's met zich mee kan brengen. Bovendien kan dit het registratieproces aanzienlijk minder toegankelijk maken voor sommige (vooral gehandicapte) mensen. Om deze redenen kun je het beste alternatieve maatregelen overwegen, zoals registratie op basis van goedkeuring of op uitnodiging. + title: Nieuwe gebruikers dienen een CAPTCHA op te lossen om hun account te bevestigen content_retention: preamble: Toezicht houden op hoe berichten en media van gebruikers op Mastodon worden bewaard. title: Bewaartermijn berichten @@ -752,10 +771,27 @@ nl: approved: Goedkeuring vereist om te kunnen registreren none: Niemand kan zich registreren open: Iedereen kan zich registreren + security: + authorized_fetch: Verificatie van gefedeerde servers vereisen + authorized_fetch_hint: Verificatie vereisen van gefedereerde servers maakt een striktere handhaving van blokkades op gebruikersniveau en serverniveau mogelijk. Dit gaat echter ten koste van de prestaties, vermindert het bereik van je reacties en kan compatibiliteitsproblemen met sommige gefedereerde services opleveren. Bovendien zal dit niet voorkomen dat personen met slechte bedoelingen je openbare berichten en accounts kunnen ophalen. + authorized_fetch_overridden_hint: Je kunt momenteel deze instelling niet wijzigen, omdat deze is overschreven door een omgevingsvariabele. + federation_authentication: Afgedwongen federatie-verificatie title: Serverinstellingen site_uploads: delete: Geüpload bestand verwijderen destroyed_msg: Verwijderen website-upload geslaagd! + software_updates: + critical_update: Kritiek — update snel + description: Het wordt aanbevolen om je Mastodon-installatie up-to-date te houden om gebruik te kunnen maken van de nieuwste oplossingen en functies. Bovendien is het soms cruciaal om Mastodon tijdig bij te werken om veiligheidsproblemen te voorkomen. Om deze redenen controleert Mastodon elke 30 minuten updates en brengt je hiervan op de hoogte volgens jouw voorkeuren voor e-mailmeldingen. + documentation_link: Meer leren + release_notes: Release-opmerkingen + title: Beschikbare updates + type: Type + types: + major: Grote release + minor: Kleine release + patch: Patchrelease - bugfixes en eenvoudig toe te passen wijzigingen + version: Versie statuses: account: Account application: Toepassing @@ -792,9 +828,24 @@ nl: suspend: "%{name} schortte het account %{target} op" appeal_approved: Bezwaar ingediend appeal_pending: Bezwaar in behandeling + appeal_rejected: Bezwaar afgewezen system_checks: database_schema_check: message_html: Niet alle databasemigraties zijn voltooid. Je moet deze uitvoeren om er voor te zorgen dat de applicatie blijft werken zoals het hoort + elasticsearch_health_red: + message_html: Elasticsearch-cluster is ongezond (rode status), zoekfuncties zijn niet beschikbaar + elasticsearch_health_yellow: + message_html: Elasticsearch-cluster is ongezond (gele status), misschien wil je de reden onderzoeken + elasticsearch_index_mismatch: + message_html: Elasticsearch-indextoewijzingen zijn verouderd. Voer tootctl search deploy --only=%{value} uit + elasticsearch_preset: + action: Zie documentatie + message_html: Jouw Elasticsearch-cluster heeft meer dan één node, maar Mastodon is niet geconfigureerd om ze te gebruiken. + elasticsearch_preset_single_node: + action: Zie documentatie + message_html: Jouw Elasticsearch-cluster heeft slechts één node, ES_PRESET moet worden ingesteld op single_node_cluster. + elasticsearch_reset_chewy: + message_html: Jouw Elasticsearch-systeemindex is verouderd vanwege een instellingswijziging. Voer tootctl search deploy --reset-chewy uit om het bij te werken. elasticsearch_running_check: message_html: Kon geen verbinding maken met Elasticsearch. Controleer dat Elasticsearch wordt uitgevoerd of schakel full-text-zoeken uit elasticsearch_version_check: @@ -805,6 +856,18 @@ nl: message_html: Je hebt voor deze server geen regels opgesteld. sidekiq_process_check: message_html: Er draait geen Sidekiqproces voor de wachtrij(en) %{value}. Controleer je Sidekiqconfiguratie + software_version_critical_check: + action: Bekijk de beschikbare updates + message_html: Er is een kritieke update voor Mastodon beschikbaar. Update zo snel mogelijk. + software_version_patch_check: + action: Beschikbare updates bekijken + message_html: Er is een Mastodon-update voor een bugfix beschikbaar. + upload_check_privacy_error: + action: Klik hier voor meer informatie + message_html: "Jouw webserver is verkeerd geconfigureerd. De privacy van je gebruikers is in gevaar." + upload_check_privacy_error_object_storage: + action: Klik hier voor meer informatie + message_html: "Jouw objectopslag is verkeerd geconfigureerd. De privacy van je gebruikers is in gevaar." tags: review: Status beoordelen updated_msg: Instellingen hashtag succesvol bijgewerkt @@ -827,6 +890,7 @@ nl: other: Deze week door %{count} mensen gedeeld title: Trending links usage_comparison: Vandaag %{today} keer gedeeld, vergeleken met %{yesterday} keer gisteren + not_allowed_to_trend: Trending worden niet toegestaan only_allowed: Alleen goedgekeurde pending_review: In afwachting van beoordeling preview_card_providers: @@ -911,6 +975,9 @@ nl: body: "%{target} maakt bezwaar tegen een moderatiemaatregel door %{action_taken_by} op %{date}, betreffende %{type}. De gebruiker schrijft:" next_steps: Je kunt het bezwaar goedkeuren om daarmee de moderatiemaatregel ongedaan te maken, of je kunt het verwerpen. subject: "%{username} maakt bezwaar tegen een moderatiemaatregel op %{instance}" + new_critical_software_updates: + body: Nieuwe kritische versies van Mastodon zijn vrijgegeven. Je zou zo snel mogelijk moeten bijwerken! + subject: Kritieke Mastodon-updates zijn beschikbaar voor %{instance}! new_pending_account: body: Zie hieronder de details van het nieuwe account. Je kunt de aanvraag goedkeuren of afwijzen. subject: Er dient een nieuw account op %{instance} te worden beoordeeld (%{username}) @@ -918,6 +985,9 @@ nl: body: "%{reporter} heeft %{target} gerapporteerd" body_remote: Iemand van %{domain} heeft %{target} gerapporteerd subject: Nieuwe rapportage op %{instance} (#%{id}) + new_software_updates: + body: Nieuwe versies van Mastodon zijn vrijgegeven. Je wilt misschien bijwerken! + subject: Nieuwe versies van Mastodon zijn beschikbaar voor %{instance}! new_trends: body: 'De volgende items moeten worden beoordeeld voordat ze openbaar kunnen worden getoond:' new_trending_links: @@ -947,24 +1017,28 @@ nl: guide_link: https://crowdin.com/project/mastodon/nl guide_link_text: Iedereen kan bijdragen. sensitive_content: Gevoelige inhoud - toot_layout: Lay-out van berichten application_mailer: notification_preferences: E-mailvoorkeuren wijzigen salutation: "%{name}," settings: 'E-mailvoorkeuren wijzigen: %{link}' + unsubscribe: Afmelden view: 'Bekijk:' view_profile: Profiel bekijken view_status: Bericht bekijken applications: created: Aanmaken toepassing geslaagd destroyed: Verwijderen toepassing geslaagd + logout: Uitloggen regenerate_token: Toegangscode opnieuw aanmaken token_regenerated: Opnieuw aanmaken toegangscode geslaagd warning: Wees voorzichtig met deze gegevens. Deel het nooit met iemand anders! your_token: Jouw toegangscode auth: apply_for_account: Account aanvragen - change_password: Wachtwoord + captcha_confirmation: + help_html: Als je problemen ondervindt bij het oplossen van de CAPTCHA, kun je contact met ons opnemen via %{email}, zodat we je kunnen assisteren. + hint_html: Nog maar één ding! Je moet bevestigen dat je een mens bent (dit is om de spam buiten de deur te houden!). Los de onderstaande CAPTCHA op en klik op "Doorgaan". + title: Veiligheidscontrole confirmations: wrong_email_hint: Als dat e-mailadres niet correct is, kun je het wijzigen in je accountinstellingen. delete_account: Account verwijderen @@ -973,7 +1047,7 @@ nl: prefix_invited_by_user: "@%{name} nodigt je hierbij uit om een account aan te maken op deze Mastodonserver!" prefix_sign_up: Registreer je vandaag nog op Mastodon! suffix: Met een account ben je in staat om mensen te volgen, berichten te plaatsen en uit te wisselen met mensen die zich op andere Mastodonservers bevinden en meer! - didnt_get_confirmation: Geen bevestigingsinstructies ontvangen? + didnt_get_confirmation: Geen bevestigingslink ontvangen? dont_have_your_security_key: Heb je jouw beveiligingssleutel niet bij de hand? forgot_password: Wachtwoord vergeten? invalid_reset_password_token: De code om jouw wachtwoord opnieuw in te stellen is verlopen. Vraag een nieuwe aan. @@ -986,26 +1060,39 @@ nl: migrate_account_html: Wanneer je dit account naar een ander account wilt doorverwijzen, kun je dit hier instellen. or_log_in_with: Of inloggen met privacy_policy_agreement_html: Ik heb het privacybeleid gelezen en ga daarmee akkoord + progress: + confirm: E-mail bevestigen + details: Jouw gegevens + review: Onze beoordeling + rules: Regels accepteren providers: cas: CAS saml: SAML register: Registreren registration_closed: "%{instance} laat geen nieuwe gebruikers toe" - resend_confirmation: Verstuur de bevestigingsinstructies nogmaals + resend_confirmation: Bevestigingslink opnieuw verzenden reset_password: Wachtwoord opnieuw instellen rules: + accept: Accepteren + back: Terug + invited_by: 'Je kunt je registreren op %{domain} dankzij de uitnodiging die je hebt ontvangen van:' preamble: Deze zijn vastgesteld en worden gehandhaafd door de moderatoren van %{domain}. + preamble_invited: Voordat je verder gaat, moet je eerst kennisnemen van de basisregels die door de moderatoren van %{domain} zijn vastgesteld. title: Enkele basisregels. + title_invited: Je bent uitgenodigd. security: Beveiliging set_new_password: Nieuw wachtwoord instellen setup: - email_below_hint_html: Wanneer onderstaand e-mailadres niet klopt, kun je dat hier veranderen. Je ontvangt dan hierna een bevestigingsmail. - email_settings_hint_html: De bevestigingsmail is verzonden naar %{email}. Wanneer dat e-mailadres niet klopt, kun je dat veranderen in je accountinstellingen. - title: Instellen + email_below_hint_html: Controleer je map met spam, of vraag een nieuwe bevestigingslink aan. Je kan je e-mailadres corrigeren als het verkeerd is. + email_settings_hint_html: Klik op de link die we je hebben gestuurd om %{email} te verifiëren. We wachten wel even. + link_not_received: Geen link ontvangen? + new_confirmation_instructions_sent: Je ontvangt binnen enkele minuten een nieuwe e-mail met de bevestigingslink! + title: Kijk in je mailbox sign_in: preamble_html: Log in met de inloggegevens van %{domain}. Als jouw account zich op een andere server bevindt, kun je hier niet inloggen. title: Inloggen op %{domain} sign_up: + manual_review: Inschrijvingen op %{domain} worden handmatig door onze moderatoren beoordeeld. Schrijf wat over jezelf en waarom je een account op %{domain} wilt. Hiermee help je ons om de aanvraag van jouw account goed te kunnen verwerken. preamble: Je kunt met een Mastodon-account iedereen in het netwerk volgen, ongeacht waar deze persoon een account heeft. title: Laten we je account op %{domain} instellen. status: @@ -1017,18 +1104,6 @@ nl: view_strikes: Bekijk de eerder door moderatoren vastgestelde overtredingen die je hebt gemaakt too_fast: Formulier is te snel ingediend. Probeer het nogmaals. use_security_key: Beveiligingssleutel gebruiken - authorize_follow: - already_following: Je volgt dit account al - already_requested: Je hebt al een volgverzoek naar dat account verstuurd - error: Helaas, er is een fout opgetreden bij het opzoeken van de externe account - follow: Volgen - follow_request: 'Jij hebt een volgverzoek ingediend bij:' - following: 'Succes! Jij volgt nu:' - post_follow: - close: Of je kunt dit venster gewoon sluiten. - return: Profiel van deze gebruiker tonen - web: Ga naar de webapp - title: Volg %{acct} challenge: confirm: Doorgaan hint_html: "Tip: We vragen jou het komende uur niet meer naar jouw wachtwoord." @@ -1105,6 +1180,10 @@ nl: your_appeal_rejected: Jouw bezwaar is afgewezen domain_validator: invalid_domain: is een ongeldige domeinnaam + edit_profile: + basic_information: Algemene informatie + hint_html: "Pas aan wat mensen op jouw openbare profiel en naast je berichten zien. Andere mensen zullen je eerder volgen en met je communiceren wanneer je profiel is ingevuld en je een profielfoto hebt." + other: Overige errors: '400': De aanvraag die je hebt ingediend was ongeldig of foutief. '403': Jij hebt geen toestemming om deze pagina te bekijken. @@ -1131,18 +1210,18 @@ nl: in_progress: Jouw archief wordt samengesteld... request: Jouw archief opvragen size: Omvang - blocks: Jij blokkeert + blocks: Geblokkeerde accounts bookmarks: Bladwijzers csv: CSV - domain_blocks: Domeinblokkades + domain_blocks: Geblokkeerde domeinen lists: Lijsten - mutes: Jij negeert - storage: Mediaopslag + mutes: Genegeerde accounts + storage: Mediabestanden featured_tags: add_new: Nieuwe toevoegen errors: - limit: Je hebt al het maximaal aantal hashtags uitgelicht - hint_html: "Wat zijn uitgelichte hashtags? Deze worden prominent op jouw openbare profiel getoond en stelt mensen in staat om jouw openbare berichten per hashtag te bekijken. Het zijn een goed hulpmiddel om creatieve werkzaamheden of langetermijnprojecten bij te houden." + limit: Je hebt al het maximale aantal hashtags uitgelicht + hint_html: "Toon je belangrijkste hashtags op je profiel Deze worden prominent op je openbare profiel getoond en stelt mensen in staat om je openbare berichten per hashtag te bekijken. Het is een goed hulpmiddel om creatieve werkzaamheden of langetermijnprojecten bij te houden." filters: contexts: account: Profielen @@ -1185,8 +1264,6 @@ nl: index: hint: Dit filter is van toepassing om individuele berichten te selecteren, ongeacht andere criteria. Je kunt in de webomgeving meer berichten aan dit filter toevoegen. title: Gefilterde berichten - footer: - trending_now: Trends generic: all: Alles all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ nl: all_matching_items_selected_html: one: "%{count} item dat met jouw zoekopdracht overeenkomt is geselecteerd." other: Alle %{count} items die met jouw zoekopdracht overeenkomen zijn geselecteerd. + cancel: Annuleren changes_saved_msg: Wijzigingen succesvol opgeslagen! + confirm: Bevestigen copy: Kopiëren delete: Verwijderen deselect: Alles deselecteren @@ -1209,25 +1288,63 @@ nl: validation_errors: one: Er is iets niet helemaal goed! Bekijk onderstaande fout other: Er is iets niet helemaal goed! Bekijk onderstaande %{count} fouten - html_validator: - invalid_markup: 'bevat ongeldige HTML-opmaak: %{error}' imports: errors: + empty: Leeg CSV-bestand + incompatible_type: Incompatibel met het geselecteerde importtype invalid_csv_file: 'Ongeldig CSV-bestand. Fout: %{error}' over_rows_processing_limit: bevat meer dan %{count} rijen + too_large: Bestand is te groot + failures: Fouten + imported: Geïmporteerd + mismatched_types_warning: Het lijkt erop dat je het verkeerde type hebt gekozen voor deze import. Gelieve dit na te kijken. modes: merge: Samenvoegen merge_long: Bestaande gegevens behouden en nieuwe toevoegen overwrite: Overschrijven overwrite_long: Huidige gegevens met de nieuwe gegevens vervangen + overwrite_preambles: + blocking_html: Je staat op het punt jouw lijst met geblokkeerde accounts te vervangen door %{total_items} accounts vanuit %{filename}. + bookmarks_html: Je staat op het punt jouw bladwijzers te vervangen door %{total_items} berichten vanuit %{filename}. + domain_blocking_html: Je staat op het punt jouw lijst met geblokkeerde domeinen te vervangen door %{total_items} domeinen vanuit %{filename}. + following_html: Je staat op het punt om %{total_items} accounts te volgen vanuit %{filename} en te stoppen met het volgen van alle andere accounts. + lists_html: Je staat op het punt je lijsten te vervangen door inhoud van %{filename}. Tot %{total_items} accounts zullen aan nieuwe lijsten worden toegevoegd. + muting_html: Je staat op het punt jouw lijst met genegeerde accounts te vervangen door %{total_items} accounts vanuit %{filename}. + preambles: + blocking_html: Je staat op het punt om %{total_items} accounts te blokkeren vanuit %{filename}. + bookmarks_html: Je staat op het punt om %{total_items} berichten aan je bladwijzers toe te voegen vanuit %{filename}. + domain_blocking_html: Je staat op het punt om %{total_items} accounts te negeren vanuit %{filename}. + following_html: Je staat op het punt om %{total_items} accounts te volgen vanuit %{filename}. + lists_html: Je staat op het punt om tot %{total_items} accounts van %{filename} toe te voegen aan je lijsten. Nieuwe lijsten worden aangemaakt als er geen lijst is om aan toe te voegen. + muting_html: Je staat op het punt om %{total_items} accounts te negeren vanuit %{filename}. preface: Je kunt bepaalde gegevens, zoals de mensen die jij volgt of hebt geblokkeerd, naar jouw account op deze server importeren. Je moet deze gegevens wel eerst op de oorspronkelijke server exporteren. + recent_imports: Recent geïmporteerd + states: + finished: Voltooid + in_progress: Bezig… + scheduled: Ingepland + unconfirmed: Onbevestigd + status: Status success: Jouw gegevens zijn succesvol geüpload en worden binnenkort verwerkt + time_started: Begonnen om + titles: + blocking: Geblokkeerde accounts importeren + bookmarks: Bladwijzers importeren + domain_blocking: Geblokkeerde domeinen importeren + following: Gevolgde accounts importeren + lists: Lijsten importeren + muting: Genegeerde accounts importeren + type: Importtype + type_groups: + constructive: Gevolgde accounts en bladwijzers + destructive: Geblokkeerde accounts/domeinen en genegeerde accounts types: - blocking: Blokkeerlijst + blocking: Geblokkeerde accounts bookmarks: Bladwijzers - domain_blocking: Lijst met genegeerde servers - following: Volglijst - muting: Negeerlijst + domain_blocking: Geblokkeerde domeinen + following: Gevolgde accounts + lists: Lijsten + muting: Genegeerde accounts upload: Uploaden invites: delete: Deactiveren @@ -1253,7 +1370,7 @@ nl: title: Mensen uitnodigen lists: errors: - limit: Je hebt het maximaal aantal lijsten bereikt + limit: Je hebt het maximum aantal lijsten bereikt login_activities: authentication_methods: otp: tweestapsverificatie-app @@ -1265,6 +1382,21 @@ nl: failed_sign_in_html: Mislukte inlogpoging met %{method} van %{ip} (%{browser}) successful_sign_in_html: Succesvol ingelogd met %{method} van %{ip} (%{browser}) title: Inloggeschiedenis + mail_subscriptions: + unsubscribe: + action: Ja, afmelden + complete: Afgemeld + confirmation_html: Weet je zeker dat je je wilt afmelden voor het ontvangen van %{type} van Mastodon op %{domain} op je e-mailadres %{email}? Je kunt je altijd opnieuw abonneren in jouw instellingen voor e-mailmeldingen. + emails: + notification_emails: + favourite: e-mailmeldingen voor favorieten + follow: e-mailmeldingen voor nieuwe volgers + follow_request: e-mailmeldingen voor volgverzoeken + mention: e-mailmeldingen voor vermeldingen + reblog: e-mailmeldingen voor boosts + resubscribe_html: Als je je per ongeluk hebt afgemeld, kun je je opnieuw abonneren in jouw instellingen voor e-mailmeldingen. + success_html: Je ontvangt niet langer %{type} van Mastodon op %{domain} op je e-mailadres %{email}. + title: Afmelden media_attachments: validations: images_and_video: Een video kan niet aan een bericht met afbeeldingen worden gekoppeld @@ -1334,7 +1466,7 @@ nl: subject: Jij bent vermeld door %{name} title: Nieuwe vermelding poll: - subject: Een poll van %{name} is beëindigd + subject: Een peiling van %{name} is beëindigd reblog: body: 'Jouw bericht werd door %{name} geboost:' subject: "%{name} boostte jouw bericht" @@ -1344,6 +1476,7 @@ nl: update: subject: "%{name} bewerkte een bericht" notifications: + administration_emails: E-mailmeldingen beheerder email_events: E-mailmeldingen voor gebeurtenissen email_events_hint: 'Selecteer gebeurtenissen waarvoor je meldingen wilt ontvangen:' other_settings: Andere meldingsinstellingen @@ -1373,19 +1506,29 @@ nl: truncate: "…" polls: errors: - already_voted: Je hebt al op deze poll gestemd + already_voted: Je hebt al aan deze peiling deelgenomen duplicate_options: bevat dubbele items duration_too_long: ligt te ver in de toekomst duration_too_short: is te kort van duur - expired: De poll is al beëindigd - invalid_choice: De gekozen poll-optie bestaat niet + expired: De peiling is al beëindigd + invalid_choice: De gekozen peiling-optie bestaat niet over_character_limit: kan stuk voor stuk niet langer zijn dan %{max} tekens + self_vote: Je kunt niet op eigen peilingen stemmen too_few_options: moet meer dan één item bevatten too_many_options: kan niet meer dan %{max} items bevatten preferences: other: Overig posting_defaults: Standaardinstellingen voor berichten public_timelines: Openbare tijdlijnen + privacy: + hint_html: "Hoe wil je dat jouw profiel en berichten kunnen worden gevonden? Een verscheidenheid aan functies in Mastodon kunnen je helpen om een groter publiek te bereiken als ze zijn ingeschakeld. Neem rustig de tijd om deze instellingen te bekijken, om er zo zeker van te zijn dat ze aan jouw wensen voldoen." + privacy: Privacy + privacy_hint_html: Hoeveel informatie wil je aan andere gebruikers kwijt? Mensen ontdekken interessante accounts en coole apps door te bekijken welke accounts jij volgt en door te bekijken welke app jij gebruikt voor het plaatsen van berichten. Het kan achter zo zijn dat je dit liever verborgen houdt. + reach: Bereik + reach_hint_html: Wil je door nieuwe mensen worden ontdekt en gevolgd? Wil je dat jouw berichten op de pagina Verkennen worden getoond? Wil je aan andere mensen worden aanbevolen en in de gebruikersgids staan? Wil je nieuwe volgers automatisch accepteren of wil je die handmatig kunnen goedkeuren? + search: Zoeken + search_hint_html: Hoe wil je worden gevonden? Wil je dat mensen jou kunnen vinden via jouw openbare berichten? Wil je dat mensen buiten Mastodon jouw profiel kunnen vinden wanneer ze op het web zoeken? Vergeet echter niet dat jouw openbare berichten en profiel nooit volledig beschermd kunnen worden tegen zoekmachines. + title: Privacy en bereik privacy_policy: title: Privacybeleid reactions: @@ -1398,6 +1541,7 @@ nl: confirm_remove_selected_followers: Weet je zeker dat je de geselecteerde volgers wilt verwijderen? confirm_remove_selected_follows: Weet je zeker dat je de geselecteerde gevolgde accounts wilt verwijderen? dormant: Sluimerend + follow_failure: Kan sommige van de geselecteerde accounts niet volgen. follow_selected_followers: Geselecteerde volgers volgen followers: Volgers following: Volgend @@ -1437,6 +1581,7 @@ nl: electron: Electron firefox: Firefox generic: Onbekende webbrowser + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1446,6 +1591,7 @@ nl: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Onbekende browser weibo: Weibo current_session: Huidige sessie description: "%{browser} op %{platform}" @@ -1458,9 +1604,10 @@ nl: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: Onbekend platform + unknown_platform: Onbekend platform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1485,7 +1632,7 @@ nl: migrate: Accountmigratie notifications: Meldingen preferences: Voorkeuren - profile: Profiel + profile: Openbaar profiel relationships: Volgers en gevolgde accounts statuses_cleanup: Automatisch berichten verwijderen strikes: Vastgestelde overtredingen @@ -1531,10 +1678,9 @@ nl: show_newer: Nieuwere tonen show_older: Oudere tonen show_thread: Gesprek tonen - sign_in_to_participate: Meld je aan om aan dit gesprek mee te doen title: '%{name}: "%{quote}"' visibilities: - direct: Direct + direct: Privébericht private: Alleen volgers private_long: Alleen aan jouw volgers tonen public: Openbaar @@ -1550,14 +1696,14 @@ nl: ignore_reblogs: Boosts negeren interaction_exceptions: Uitzonderingen op basis van interacties interaction_exceptions_explanation: Merk op dat er geen garantie is dat berichten worden verwijderd, wanneer eenmaal het aantal favorieten of boosts boven de ingestelde grenswaarde zijn geweest. - keep_direct: Directe berichten behouden - keep_direct_hint: Verwijdert geen enkel directe bericht van jou + keep_direct: Privéberichten behouden + keep_direct_hint: Verwijdert geen enkel privébericht van jou keep_media: Berichten met mediabijlagen behouden keep_media_hint: Verwijdert geen enkel bericht met mediabijlagen keep_pinned: Vastgemaakte berichten behouden keep_pinned_hint: Verwijdert geen enkel vastgezet bericht van jou - keep_polls: Polls behouden - keep_polls_hint: Geen enkele poll van jou wordt verwijderd + keep_polls: Peilingen behouden + keep_polls_hint: Geen enkele peiling van jou wordt verwijderd keep_self_bookmark: Bladwijzers behouden keep_self_bookmark_hint: Eigen berichten die je aan je bladwijzers hebt toegevoegd worden niet verwijderd keep_self_fav: Favorieten behouden @@ -1577,8 +1723,6 @@ nl: min_reblogs: Berichten die minstens zoveel keer zijn geboost behouden min_reblogs_hint: Verwijdert geen berichten die tenminste zoveel keer zijn geboost. Laat leeg om berichten ongeacht het aantal boosts te verwijderen stream_entries: - pinned: Vastgemaakt bericht - reblogged: boostte sensitive_content: Gevoelige inhoud strikes: errors: @@ -1594,6 +1738,11 @@ nl: default: "%d %B %Y om %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Het gebruikersquotum voor de vertaaldienst is overschreden. + too_many_requests: Er zijn de laatste tijd te veel verzoeken ingediend bij de vertaaldienst. two_factor_authentication: add: Toevoegen disable: Tweestapsverificatie uitschakelen @@ -1673,13 +1822,18 @@ nl: title: Welkom aan boord %{name}! users: follow_limit_reached: Je kunt niet meer dan %{limit} accounts volgen + go_to_sso_account_settings: Ga naar de accountinstellingen van je identiteitsprovider invalid_otp_token: Ongeldige tweestaps-toegangscode otp_lost_help_html: Als je toegang tot beiden kwijt bent geraakt, neem dan contact op via %{email} seamless_external_login: Je bent ingelogd via een externe dienst, daarom zijn wachtwoorden en e-mailinstellingen niet beschikbaar. signed_in_as: 'Ingelogd als:' verification: - explanation_html: 'Je kunt jezelf verifiëren als de eigenaar van de links in de metadata van jouw profiel. Hiervoor moet op de gelinkte website een link terug naar jouw Mastodonprofiel staan. Deze link moet het rel="me"-attribuut bevatten. De omschrijving van de link maakt niet uit. Hier is een voorbeeld:' + extra_instructions_html: Tip: De link op je website kan onzichtbaar zijn. Het belangrijke onderdeel is rel="me" dat impersonatie op websites met user-generated content voorkomt. Je kunt zelfs een link-tag gebruiken in de header van de pagina in plaats van a, maar de HTML moet ook zonder JavaScript toegankelijk zijn. + here_is_how: Zo werkt het + hint_html: "Verificatie van je identiteit op Mastodon is voor iedereen. Het is gebaseerd op open webstandaarden, en is en blijft altijd gratis. Alles wat nodig is is een persoonlijke website waar mensen je aan kunnen herkennen. Wanneer je vanuit jouw profiel naar deze website linkt, zullen wij controleren of de website naar jouw profiel teruglinkt en daar een visuele indicator van tonen." + instructions_html: Kopieer en plak de onderstaande code in de HTML van je website. Voeg vervolgens het adres van je website toe aan een van de extra velden op je profiel op het tabblad "Profiel bewerken" en sla de wijzigingen op. verification: Verificatie + verified_links: Jouw geverifieerde links webauthn_credentials: add: Nieuwe beveiligingssleutel toevoegen create: diff --git a/config/locales/nn.yml b/config/locales/nn.yml index c7797627f0..9f34e56216 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -91,6 +91,7 @@ nn: moderation: active: Aktiv all: Alle + disabled: Skrudd av pending: Ventar på svar silenced: Avgrensa suspended: Utvist @@ -124,8 +125,8 @@ nn: removed_header_msg: Fjerna %{username} sitt toppbilete resend_confirmation: already_confirmed: Denne brukaren er allereie stadfesta - send: Send stadfestings-e-posten på nytt - success: Stadfestings-e-post send! + send: Send stadfestingslenka på nytt + success: Stadfestingslenka er send! reset: Attstill reset_password: Attstill passord resubscribe: Ting på nytt @@ -133,6 +134,7 @@ nn: search: Søk search_same_email_domain: Andre brukarar med same e-postdomene search_same_ip: Andre brukarar med same IP + security: Tryggleik security_measures: only_password: Kun passord password_and_2fa: Passord og 2FA @@ -307,6 +309,7 @@ nn: unpublish: Avpubliser unpublished_msg: Kunngjøring upublisert! updated_msg: Kunngjøringen er oppdatert! + critical_update_pending: Kritisk oppdatering ventar custom_emojis: assign_category: Vel kategori by_domain: Domene @@ -350,6 +353,12 @@ nn: pending_appeals_html: one: "%{count} ventande ankar" other: "%{count} ventande klagar" + pending_reports_html: + one: "%{count} ventande rapportar" + other: "%{count} ventande rapportar" + pending_tags_html: + one: "%{count} ventande emneknaggar" + other: "%{count} ventande emneknaggar" pending_users_html: one: "%{count} ventande brukarar" other: "%{count} ventande brukarar" @@ -374,6 +383,15 @@ nn: undo: Fjern frå kvitliste domain_blocks: add_new: Lag ny + confirm_suspension: + cancel: Avbryt + confirm: Suspender + permanent_action: Å oppheve suspensjonen vil ikkje gjenopprette data eller koplingar. + preamble_html: Du er i ferd med å suspendera %{domain} inkludert underdomener. + remove_all_data: Dette vil fjerna alt innhald, media og profildata for kontoar som tilhøyrer dette domenet frå din tenar. + stop_communication: Tenaren din vil slutta å kommunisera med desse tenarane. + title: Stadfest domeneblokkering for %{domain} + undo_relationships: Dette vil oppheve alle følgar-relasjonar mellom kontoane dine og kontoar på desse tenerane. created_msg: Domeneblokkering blir nå behandlet destroyed_msg: Domeneblokkering har nå blitt angret domain: Domene @@ -421,6 +439,7 @@ nn: resolve: Løs domene title: Ny blokkeringsoppføring av e-postdomene no_email_domain_block_selected: Blokkering av e-post-domener vart ikkje endra sidan ingen var valde + not_permitted: Ikkje tillate resolved_dns_records_hint_html: Domenenamnet gjer oppslag til desse MX-domenene som til sist er ansvarlige for å motta e-post. Blokkering av eit MX-domene vil blokkere registreringar frå alle e-postadresser som bruker same MX-domene, sjølv om det synlige domenenavnet skulle vera noko anna. Pass på så du ikkje blokkerer dei store e-postleverandørane. resolved_through_html: Løyst gjennom %{domain} title: Blokkerte e-postadresser @@ -435,6 +454,7 @@ nn: private_comment_description_html: 'For å hjelpa deg med å halda oversikt over kvar importerte blokkeringar kjem frå, vil dei bli oppretta med fylgjande private kommentar: %{comment}' private_comment_template: Importert frå %{source} den %{date} title: Importer domeneblokkeringar + invalid_domain_block: 'Hoppa over ei eller fleire domeneblokker på grunn av fylgjande feil: %{error}' new: title: Importer domeneblokkeringar no_file: Inga fil vald @@ -466,6 +486,7 @@ nn: content_policies: comment: Internt notat description_html: Du kan definere innholdsregler som vil bli brukt på alle kontoer fra dette domenet og hvilket som helst av underdomenene. + limited_federation_mode_description_html: Du kan velja om du vil tillata føderering med dette domenet. policies: reject_media: Avvis media reject_reports: Avvis rapporter @@ -569,17 +590,23 @@ nn: mark_as_sensitive_description_html: Mediene i dei rapporterte innlegga vil verte markerte som ømtolege, og ein merknad vil verte lagra for å hjelpe deg å eskalera ved framtidige regelbrot frå same konto. other_description_html: Sjå fleire alternativ når det gjeld kontroll av kontoåtferd og tilpassing av kommunikasjonen til den rapporterte kontoen. resolve_description_html: Ingen handling utføres mot den rapporterte kontoen, ingen advarsel gis, og rapporten lukkes. + silence_description_html: Profilen vil berre vera synleg for dei som allereie fylgjer han eller søkjer han opp manuelt, noko som gjev profilen mykje mindre rekkjevidd. Du kan oppheva stenginga seinare. Dette avsluttar alle rapportar om brukarkontoen. + suspend_description_html: Brukarkontoen og alt innhaldet vil bli utilgjengeleg og til slutt sletta, og det vil vera uråd å samhandla med brukaren. Du kan angra dette innan 30 dagar. Dette avsluttar alle rapportar om kontoen. actions_description_html: Avgjer kva som skal gjerast med denne rapporteringa. Dersom du utfører straffetiltak mot den rapporterte kontoen, vil dei motta ein e-post – så sant du ikkje har valt kategorien Spam. + actions_description_remote_html: Avgjer kva du vil gjera for å løysa denne rapporten. Dette påverkar berre korleis tenaren din kommuniserer med kontoen på ein annan tenar, og korleis tenaren din handterer innhald derifrå. add_to_report: Legg til i rapporten are_you_sure: Er du sikker? assign_to_self: Tilegn til meg assigned: Tilsett moderator by_target_domain: Domenet av rapportert bruker + cancel: Avbryt category: Kategori category_description_html: Årsaka til at kontoen og/eller innhaldet vart rapportert vil bli inkludert i kommunikasjonen med den rapporterte kontoen comment: none: Ingen comment_description_html: 'For å gje meir informasjon, skreiv %{name}:' + confirm: Stadfest + confirm_action: Stadfest at du vil moderera brukarkontoen @%{acct} created_at: Rapportert delete_and_resolve: Slett innlegg forwarded: Videresendt @@ -596,6 +623,7 @@ nn: placeholder: Beskriv hvilke handlinger som har blitt tatt, eller andre relaterte oppdateringer... title: Merknad notes_description_html: Sjå og skriv merknadar til andre moderatorar og ditt framtidige sjølv + processed_msg: 'Du har handsama rapport #%{id}' quick_actions_description_html: 'Utfør ei handling eller bla ned for å sjå det rapporterte innhaldet:' remote_user_placeholder: den eksterne brukaren frå %{instance} reopen: Opn rapport igjen @@ -608,9 +636,28 @@ nn: status: Status statuses: Rapportert innhold statuses_description_html: Støytande innhald vil bli inkludert i kommunikasjonen med den rapporterte kontoen + summary: + action_preambles: + delete_html: 'Du er i ferd med å fjerna nokre av innlegga til @%{acct}. Det vil:' + mark_as_sensitive_html: 'Du er i ferd med å markera nokre av innlegga til @%{acct} som sensitive. Dette vil:' + silence_html: 'Du er i ferd med å avgrensa kontoen til @%{acct}. Dette vil:' + suspend_html: 'Du er i ferd med å stenga kontoen til @%{acct}. Dette vil:' + actions: + delete_html: Fjerna dei påtala innlegga + mark_as_sensitive_html: Markera dei påtala mediefilene som sensitive + silence_html: Sterkt avgrensa korleis @%{acct} kan samhandla ved å gjera brukarprofilen og innhaldet synleg berre for folk som allereie fylgjer brukarkontoen eller søkjer han opp manuelt + suspend_html: Stengja brukarkontoen til @%{acct}, slik at brukarprofilen og innhaldet blir utilgjengeleg og umogleg å samhandla med + close_report: Marker rapport nr. %{id} som løyst + close_reports_html: Marker alle rapportane om @%{acct} som løyste + delete_data_html: Slett brukarprofilen og innhaldet til@%{acct} om 30 dagar frå no med mindre brukarkontoen blir opna att + preview_preamble_html: "@%{acct} vil få ei åtvaring med dette innhaldet:" + record_strike_html: Noter at ei handling er gjort mot @%{acct} for å hjelpa deg å handtera framtidige overtramp frå denne brukarkontoen + send_email_html: Send ein åtvaringsepost til @%{acct} + warning_placeholder: Eventuelle fleire grunnar for å modereringshandlinga. target_origin: Opprinnelse for innrapportert konto title: Rapportar unassign: Avset + unknown_action_msg: 'Ukjend handling: %{action}' unresolved: Uløyst updated_at: Oppdatert view_profile: Vis profil @@ -694,6 +741,9 @@ nn: branding: preamble: Profileringa av tenaren din skil den frå andre tenarar i nettverket. Informasjonen kan bli vist ulike stadar, til dømes i Mastodon sitt web-grensesnitt, i eigne applikasjonar, i førehandsvisningar på andre nettsider, i meldingsappar og så bortetter. På grunn av dette er det best å halde informasjonen enkel, kort og treffande. title: Profilering + captcha_enabled: + desc_html: Dette baserer seg på eksterne skript frå hCaptcha, noko som kan vera eit tryggleiks- og personvernsproblem. I tillegg kan dette gjera registreringsprosessen monaleg mindre tilgjengeleg (særleg for folk med nedsett funksjonsevne). Dette gjer at du bør du vurdera alternative tiltak, som til dømes godkjennings- eller invitasjonsbasert registrering. + title: Krev at nye brukarar løyser ein CAPTCHA for å bekrefte kontoen sin content_retention: preamble: Styr korleis brukargenerert innhald blir lagra i Mastodon. title: Bevaring av innhald @@ -705,6 +755,8 @@ nn: preamble: Å framheva interessant innhald er vitalt i mottakinga av nye brukarar som ikkje nødvendigvis kjenner nokon på Mastodon. Kontroller korleis oppdagingsfunksjonane på tenaren din fungerar. profile_directory: Profilkatalog public_timelines: Offentlege tidsliner + publish_discovered_servers: Publiser oppdaga tenarar + publish_statistics: Publiser statistikk title: Oppdaging trends: Trender domain_blocks: @@ -719,10 +771,27 @@ nn: approved: Godkjenning kreves for påmelding none: Ingen kan melda seg inn open: Kven som helst kan melda seg inn - title: Serverinnstillinger + security: + authorized_fetch: Krev autentisering frå fødererte tenarar + authorized_fetch_hint: Krav om autentisering frå fødererte tenarar gjer det mogleg med strengare handheving av blokkering, både på brukar- og tenar-nivå. Likevel, dette har ein kostnad når det gjeld yting, reduserer rekkevidda til svara dine og kan medføra kompabilitetsproblem med enkelte fødererte tenester. Dette vil heller ikkje hindra dei som verkeleg vil i å henta dei offentlege innlegga eller kontoane dine. + authorized_fetch_overridden_hint: Du kan ikkje endre denne innstillinga no, fordi den er overstyrt av ein miljøvariabel. + federation_authentication: Krav om autentisering ved føderering + title: Tenarinstillingar site_uploads: delete: Slett opplasta fil destroyed_msg: Vellukka sletting av sideopplasting! + software_updates: + critical_update: Kritisk – gjer vel og oppdater snart + description: Det er anbefalt å halda Mastodon-installasjonen oppdatert for å dra nytte av nye feilrettingar og funksjonar. Dessutan er det av og til kritisk å oppdatera Mastodon til rett tid for å ungå sikkerheitsproblem. På grunn av dette vil Mastodon sjå etter oppdateringar kvart 30. minutt og halda deg orientert etter innstillingane du har sett for e-postvarsling. + documentation_link: Lær meir + release_notes: Oppdateringsnotat + title: Tilgjengelege oppdateringar + type: Type + types: + major: Stor oppdatering + minor: Mindre oppdatering + patch: Lita oppdatering – feilrettingar og endringar som er lette å leggja til + version: Versjon statuses: account: Forfatter application: Applikasjon @@ -759,9 +828,24 @@ nn: suspend: "%{name} utviste %{target} sin konto" appeal_approved: Klage tatt til følge appeal_pending: Klage behandles + appeal_rejected: Anken er avvist system_checks: database_schema_check: message_html: Det venter på databaseoverføringer. Vennligst kjør disse for å sikre at applikasjonen oppfører seg som forventet + elasticsearch_health_red: + message_html: Elasticsearch-klynga er usunn (raud status), og søkjefunksjonane er utilgjengelege + elasticsearch_health_yellow: + message_html: Elasticsearch-klyna er usunn (gul status), så du bør undersøkja kvifor + elasticsearch_index_mismatch: + message_html: Indekskarta for Elasticsearch er utdaterte. Køyr tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Sjå dokumentasjonen + message_html: Elasticsearch-klynga di har meir enn ein node, men Mastodon er ikkje sett opp til å bruka dei. + elasticsearch_preset_single_node: + action: Sjå dokumentasjonen + message_html: Elasticsearch-klynga di har berre ein node. ES_PRESET bør vera single_node_cluster. + elasticsearch_reset_chewy: + message_html: Elasticsearch-systemindeksen er utdatert på grunn av ei endra innstilling. Køyr tootctl search deploy --reset-chewy for å oppdatera indeksen. elasticsearch_running_check: message_html: Kunne ikke koble til Elasticsearch. Kontroller at den kjører, eller deaktiver fulltekstsøk elasticsearch_version_check: @@ -772,6 +856,18 @@ nn: message_html: Du har ikke definert noen serverregler. sidekiq_process_check: message_html: Ingen Sidekiq-prosess kjører for %{value} køen(e). Vennligst se gjennom Sidekiq-konfigurasjonen din + software_version_critical_check: + action: Sjå tilgjengelege oppdateringar + message_html: Ei kritisk oppdatering til Mastodon er tilgjengeleg. Oppdater så snart som mogleg. + software_version_patch_check: + action: Sjå tilgjengelege oppdateringar + message_html: Ei feilretting for Mastodon er tilgjengeleg. + upload_check_privacy_error: + action: Sjekk her for meir informasjon + message_html: "Vevtenaren din er sett opp feil. Personvernet til brukarane din er i fare." + upload_check_privacy_error_object_storage: + action: Sjekk her for meir informasjon + message_html: "Objektlagringa di er sett opp feil. Personvernet til brukarane dine er i fare." tags: review: Sjå gjennom status updated_msg: Emneknagginnstillingane er oppdaterte @@ -794,6 +890,7 @@ nn: other: Delt av %{count} personer i løpet av den siste uken title: Populære lenkjer usage_comparison: Delt %{today} ganger i dag, sammenlignet med %{yesterday} i går + not_allowed_to_trend: Har ikkje lov å trenda only_allowed: Kun tillatne pending_review: Avventer gjennomgang preview_card_providers: @@ -820,12 +917,13 @@ nn: tag_accounts_measure: unike bruksområder tag_languages_dimension: Mest brukte språk tag_servers_dimension: Mest brukte servere - tag_servers_measure: forskjellige servere - tag_uses_measure: samlet bruk + tag_servers_measure: ulike tenarar + tag_uses_measure: brukarar totalt description_html: Dette er emneknagger som for øyeblikket vises i mange innlegg som serveren din ser. Det kan hjelpe dine brukere med å finne ut hva folk snakker mest om i øyeblikket. Ingen emneknagger vises offentlig før du godkjenner dem. listable: Kan bli foreslått + no_tag_selected: Ingen merkelappar vart endra fordi ingen var valde not_listable: Vil ikke bli foreslått - not_trendable: Kunne ikke vises under trender + not_trendable: Kjem ikkje til å syna under trendar not_usable: Kan ikke brukes peaked_on_and_decaying: Nådde toppen %{date}, nå på vei ned title: Populære emneknagger @@ -874,6 +972,12 @@ nn: sensitive: å merke kontoen sin som følsom silence: for å begrense deres konto suspend: for å suspendere kontoen deres + body: "%{target} ankar på ei modereringsavgjerd av %{action_taken_by} den %{date}, som var %{type}. Dei skreiv:" + next_steps: Du kan godkjenna anken for å endra modereringsavgjerda, eller du kan oversjå anken. + subject: "%{username} ankar ei modereringsavgjer på %{instance}" + new_critical_software_updates: + body: Nye kritiske versjonar av Mastodon er tilgjengeleg. Du vil kanskje oppdatera så snart som mogleg! + subject: Kritiske Mastodon-oppdateringar er tilgjengeleg for %{instance}! new_pending_account: body: Detaljer om den nye kontoen er nedenfor. Du kan godkjenne eller avvise denne søknaden. subject: Ny konto opp til vurdering på %{instance} (%{username}) @@ -881,14 +985,20 @@ nn: body: "%{reporter} har rapportert %{target}" body_remote: Nokon frå %{domain} har meldt %{target} subject: Ny rapport for %{instance} (#%{id}) + new_software_updates: + body: Nye versjonar av Mastodon er tilgjengeleg, du vil kanskje oppdatera! + subject: Nye versjonar av Mastodon er tilgjengeleg for %{instance}! new_trends: + body: 'Du må sjå gjennom desse elementa før dei kan visast offentleg:' new_trending_links: title: Populære lenker new_trending_statuses: title: Populære innlegg new_trending_tags: - title: Populære emneknagger - subject: Ny trender for gjennomsyn av %{instance} + no_approved_tags: Det er ingen godkjende populære emneknaggar no. + requirements: 'Alle desse kandidatane kan stiga høgare enn den godkjende populære emneknaggen #%{rank}, som er #%{lowest_tag_name} med ei plassering på %{lowest_tag_score}.' + title: Populære emneknaggar + subject: Nye trendar å sjå gjennom på %{instance} aliases: add_new: Lag psevdonym created_msg: Laga eit nytt kallenamn. No kan du setja i gang med flyttinga frå den gamle kontoen. @@ -907,31 +1017,37 @@ nn: guide_link: https://crowdin.com/project/mastodon guide_link_text: Alle kan bidra. sensitive_content: Ømtolig innhald - toot_layout: Tutoppsett application_mailer: notification_preferences: Endr e-post-innstillingane - salutation: "%{name}," + salutation: Hei %{name}, settings: 'Endr e-post-innstillingar: %{link}' + unsubscribe: Meld av view: 'Sjå:' view_profile: Sjå profil view_status: Sjå status applications: created: Søknad laga destroyed: Søknad sletta + logout: Logg ut regenerate_token: Lag tilgangsnykel på nytt token_regenerated: Tilgangsnykel laga på nytt warning: Ver varsam med dette datumet. Aldri del det med nokon! your_token: Tilgangsnykelen din auth: apply_for_account: Søk om ein konto - change_password: Passord + captcha_confirmation: + help_html: Om du har problem med å løyse CAPTCHA, kan kontakte oss på %{email} og vi kan hjelpe deg. + hint_html: Berre ein ting til! Vi må bekrefte at du er et menneske (så vi kan halde spam ute!). Løys CAPTCHA-en nedanfor og klikk "Fortsett". + title: Sikkerheitssjekk + confirmations: + wrong_email_hint: Viss epostadressa er feil, kan du endra ho i kontoinnstillingane. delete_account: Slett konto delete_account_html: Om du vil sletta kontoen din, kan du gå hit. Du vert spurd etter stadfesting. description: prefix_invited_by_user: "@%{name} spør deg om å verta med i ein Mastodon-tenar!" prefix_sign_up: Meld deg på Mastodon i dag! suffix: Med ein konto kan du fylgja folk, skriva innlegg og veksla meldingar med brukarar frå kva som helst annan Mastodon-tenar og meir! - didnt_get_confirmation: Fekk du ikkje stadfestingsinstruksjonar? + didnt_get_confirmation: Fekk du ikkje stadfestingslenka? dont_have_your_security_key: Har du ikke sikkerhetsnøkkelen din? forgot_password: Har du gløymt passordet ditt? invalid_reset_password_token: Tilgangsnykelen er ugyldig eller utgått. Ver venleg å beda om ein ny ein. @@ -944,26 +1060,39 @@ nn: migrate_account_html: Om du vil visa denne kontoen til ein anna, kan du skipe det her. or_log_in_with: Eller logg inn med privacy_policy_agreement_html: Jeg har lest og godtar retningslinjer for personvern + progress: + confirm: Stadfest e-postadressa + details: Opplysingane dine + review: Vår gjennomgang + rules: Godta reglane providers: cas: CAS saml: SAML register: Registrer deg registration_closed: "%{instance} tek ikkje imot nye medlemmar" - resend_confirmation: Send stadfestingsinstruksjonar på nytt + resend_confirmation: Send stadfestingslenka på nytt reset_password: Attstill passord rules: + accept: Godkjenn + back: Attende + invited_by: 'Du kan bli med i %{domain} takka vere invitasjonen du har fått frå:' preamble: Disse angis og håndheves av %{domain}-moderatorene. + preamble_invited: Før du held fram, ver snill og sjå gjennom reglane bestemt av moderatorane av %{domain}. title: Noen grunnregler. + title_invited: Du har blitt invitert. security: Tryggleik set_new_password: Lag nytt passord setup: - email_below_hint_html: Om e-posten nedfor ikkje er rett, kan du endra han her og få ein ny stadfestings-e-post. - email_settings_hint_html: Stadfestings-e-posten vart send til %{email}. Om den e-postadressa ikkje er rett, kan du byta adresse i kontoinnstillingane. - title: Oppsett + email_below_hint_html: Sjekk søppelpostmappa di, eller be om ein ny. Du kan endra epostadressa di dersom ho er feil. + email_settings_hint_html: Klikk lenka me sende deg for å stadfesta %{email}. Me sit her og ventar. + link_not_received: Fekk du ikkje lenka? + new_confirmation_instructions_sent: Du burde få ein ny epost med stadfestingslenke innan nokre minutt! + title: Sjekk innboksen din sign_in: preamble_html: Logg inn med brukaropplysningar for %{domain}. Dersom kontoen din er registrert på ein annan tenar vil du ikkje kunne logga inn her. title: Logg inn på %{domain} sign_up: + manual_review: Når du lagar ein konto på %{domain}, vil moderatorane våre gå gjennom påmeldinga di manuelt. For å hjelpa oss med påmeldinga di, er det fint om du skriv litt om deg sjølv og kvifor du vil ha ein konto på %{domain}. preamble: Med en konto på denne Mastodon-tjeneren vil du kunne følge andre personer på nettverket, uansett hvor kontoen deres holder til. title: La oss få deg satt i gang på %{domain}. status: @@ -975,18 +1104,6 @@ nn: view_strikes: Vis tidligere advarsler mot kontoen din too_fast: Skjemaet ble sendt inn for raskt, prøv på nytt. use_security_key: Bruk sikkerhetsnøkkel - authorize_follow: - already_following: Du fylgjer allereie denne kontoen - already_requested: Du har allereie sendt ein fylgjespurnad til den kontoen - error: Uheldigvis skjedde det en feil da vi prøvde å få tak i en bruker fra en annen instans - follow: Fylg - follow_request: 'Du har sendt ein fylgjeførespurnad til:' - following: 'Suksess! No fylgjer du:' - post_follow: - close: Eller så kan du berre lukka att dette vindauget. - return: Vis brukarprofilen - web: Gå til nettet - title: Fylg %{acct} challenge: confirm: Hald fram hint_html: "Tips: Vi skal ikkje spørja deg om passordet ditt igjen i laupet av den neste timen." @@ -1063,6 +1180,10 @@ nn: your_appeal_rejected: Din klage har blitt avvist domain_validator: invalid_domain: er ikkje eit gangbart domenenamn + edit_profile: + basic_information: Grunnleggande informasjon + hint_html: "Tilpass kva folk ser på den offentlege profilen din og ved sida av innlegga dine. Andre vil i større grad fylgja og samhandla med deg når du har eit profilbilete og har fyllt ut profilen din." + other: Anna errors: '400': Søknaden du sende var ugyldig eller sett opp feil. '403': Du har ikkje løyve til å sjå denne sida. @@ -1099,7 +1220,7 @@ nn: featured_tags: add_new: Legg til ny errors: - limit: Du har allereie så mange emneknaggar som det går an å ha + limit: Du har allereie framheva så mange emneknaggar som det går an å gjera hint_html: "Hva er utvalgte emneknagger? De vises frem tydelig på din offentlige profil, og lar folk bla i dine offentlige innlegg som spesifikt har de emneknaggene. De er et bra verktøy for å holde styr på kreative verk eller langtidsprosjekter." filters: contexts: @@ -1110,79 +1231,119 @@ nn: thread: Samtalar edit: add_keyword: Legg til stikkord - keywords: Nøkkelord + keywords: Stikkord statuses: Individuelle innlegg + statuses_hint_html: Dette filteret gjeld for utvalde, individuelle innlegg, uansett om dei passar til stikkorda under. Sjå gjennom eller fjern innlegg frå filteret. title: Endr filter errors: + deprecated_api_multiple_keywords: Du kan ikkje endra desse parametrane frå dette programmet fordi dei gjeld for meir enn eitt filterord. Bruk eit nyare program, eller nettsida. invalid_context: Ingen eller ugild kontekst gjeve index: - contexts: Filtre i %{contexts} + contexts: Filter i %{contexts} delete: Slett empty: Du har ingen filtre. - expires_in: Utløper om %{distance} - expires_on: Utløper den %{date} + expires_in: Går ut om %{distance} + expires_on: Går ut %{date} keywords: - one: "%{count} nøkkelord" - other: "%{count} nøkkelorder" + one: "%{count} stikkord" + other: "%{count} stikkord" statuses: one: "%{count} innlegg" - other: "%{count} innlegger" + other: "%{count} innlegg" statuses_long: - one: "%{count} enkeltinnlegg skjult" - other: "%{count} individuelle innlegger skjult" + one: "%{count} individuelt innlegg er gøymd" + other: "%{count} individuelle innlegg er gøymde" title: Filter new: save: Lagre nytt filter title: Legg til nytt filter statuses: - back_to_filter: Tilbake til filter + back_to_filter: Tilbake til filteret batch: - remove: Fjern fra filter + remove: Fjern frå filteret index: - hint: Dette filteret gjelder for å velge individuelle innlegg uavhengig av andre kriterier. Du kan legge til flere innlegg til dette filteret fra webgrensesnittet. + hint: Dette filteret gjeld for utvalde, individuelle innlegg, uavhengig av andre kriterium. Du kan leggja til fleire innlegg til dette filteret frå nettsida. title: Filtrerte innlegg - footer: - trending_now: Populært no generic: all: Alle all_items_on_page_selected_html: - one: "%{count} element på denne siden er valgt." - other: Alle %{count} elementer på denne siden er valgt. + one: Du har valt %{count} element på denne sida. + other: Du har valt %{count} element på denne sida. all_matching_items_selected_html: - one: "%{count} element som matcher søket ditt er valgt." - other: Alle %{count} elementer som matcher søket velges. + one: "%{count} element som passar til søket ditt er vald." + other: Du har valt %{count} element som passar til søket ditt. + cancel: Avbryt changes_saved_msg: Alle endringane vart lagra! + confirm: Stadfest copy: Kopier delete: Slett - deselect: Fjern all merking + deselect: Vel ingen none: Ingen order_by: Sorter etter save_changes: Lagr endringar select_all_matching_items: - one: Velg %{count} element som samsvarer med søket ditt. - other: Velg alle %{count} elementer som samsvarer med søket ditt. + one: Vel %{count} element som passar til søket ditt. + other: Vel %{count} element som passar til søket ditt. today: i dag validation_errors: one: Noe er ikke helt riktig ennå. Vennligst se etter en gang til other: Noe er ikke helt riktig ennå. Det er ennå %{count} feil å rette på - html_validator: - invalid_markup: 'rommar ugild HTML-kode: %{error}' imports: errors: + empty: Tom CSV-fil + incompatible_type: Ikkje kompatibel med importtypen du valde invalid_csv_file: 'Ugyldig CSV-fil. Feil: %{error}' over_rows_processing_limit: inneholder flere enn %{count} rader + too_large: Fila er for stor + failures: Feil + imported: Importert + mismatched_types_warning: Det ser ut som du har valt feil type for denne importen. Sjekk ein gong til. modes: merge: Set saman merge_long: Hald på eksisterande data og legg til nye overwrite: Skriv over - overwrite_long: Erstatt gjeldende med de nye + overwrite_long: Byt ut dei noverande oppføringane med dei nye + overwrite_preambles: + blocking_html: Du skal til å byta ut blokkeringslista di med opp til %{total_items} brukarkontoar frå %{filename}. + bookmarks_html: Du skal til å byta ut bokmerka dine med opp til %{total_items} innlegg frå %{filename}. + domain_blocking_html: Du skal til å byta ut domeneblokkeringslista di med opp til %{total_items} domene frå %{filename}. + following_html: Du skal til å fylgja opp til %{total_items} brukarkontoar frå %{filename} og slutta å fylgja alle andre. + lists_html: Du er i ferd med å erstatta listene dine med innhaldet i %{filename}. Opptil %{total_items} kontoar vil bli lagt til i nye lister. + muting_html: Du skal til å byta ut lista di over dempa brukarkontoar med opp til %{total_items} brukarkontoar frå %{filename}. + preambles: + blocking_html: Du skal til å blokkera opp til %{total_items} brukarkontoar frå %{filename}. + bookmarks_html: Du skal til å leggja til opp til %{total_items} innlegg frå %{filename} til bokmerka dine. + domain_blocking_html: Du skal til å blokkera opp til %{total_items} domene frå %{filename}. + following_html: Du skal til å fylgja opp til %{total_items} brukarkontoar frå %{filename}. + lists_html: Du er i ferd med å leggja til opptil %{total_items} kontoar frå %{filename} til i listene dine. Nye lister vil blir oppretta om ingen lister finst frå før. + muting_html: Du skal til å dempa opp til %{total_items} brukarkontoar frå %{filename}. preface: Du kan henta inn data som du har eksportert frå ein annan tenar, som t.d. ei liste over folka du fylgjer eller blokkerer. + recent_imports: Siste importar + states: + finished: Ferdig + in_progress: Pågår + scheduled: Planlagt + unconfirmed: Ikkje stadfesta + status: Status success: Dataa dine vart lasta opp og vert no handsama så fort som mogeleg + time_started: Starta + titles: + blocking: Importerer blokkerte brukarkontoar + bookmarks: Importerer bokmerke + domain_blocking: Importerer blokkerte domene + following: Importerer fylgde brukarkontoar + lists: Importerer lister + muting: Importerer dempa brukarkontoar + type: Type import + type_groups: + constructive: Fylgjer og bokmerke + destructive: Blokkeringar og dempingar types: blocking: Blokkeringsliste bookmarks: Bokmerker domain_blocking: Liste over blokkerte domene following: Fylgjeliste + lists: Lister muting: Dempeliste upload: Last opp invites: @@ -1214,13 +1375,28 @@ nn: authentication_methods: otp: to-faktor autentiseringsapp password: passord - sign_in_token: e-post sikkerhetskode + sign_in_token: tryggingskode på epost webauthn: sikkerhetsnøkler description_html: Hvis du ser aktivitet som du ikke gjenkjenner, bør du vurdere å endre passordet ditt og aktivere to-trinnsinnlogging. empty: Ingen innloggingshistorikk er tilgjengelig failed_sign_in_html: Mislykket innloggingsforsøk med %{method} fra %{ip} (%{browser}) successful_sign_in_html: Vellykket innlogging med %{method} fra %{ip} (%{browser}) title: Autentiseringshistorikk + mail_subscriptions: + unsubscribe: + action: Ja, meld av + complete: Meldt av + confirmation_html: Er du sikker på at du ikkje lenger ynskjer å motta %{type} frå Mastodon på %{domain} til e-posten din %{email}? Du kan alltids gjera om på dette i innstillingar for e-postvarsling. + emails: + notification_emails: + favourite: e-postar om favorittmarkeringar + follow: e-postar om nye fylgjarar + follow_request: e-postar om fylgjeførespurnadar + mention: e-postar om nemningar + reblog: e-postar om framhevingar + resubscribe_html: Om du har avslutta avslutta abonnementet ved ein feil, kan du abonnera på nytt i innstillingar for e-postvarsling. + success_html: Du vil ikkje lenger motta %{type} frå Mastodon på %{domain} til din e-post %{email}. + title: Meld av media_attachments: validations: images_and_video: Kan ikkje leggja ved video til status som allereie inneheld bilete @@ -1264,7 +1440,7 @@ nn: carry_mutes_over_text: Denne brukeren flyttet fra %{acct}, som du hadde dempet. copy_account_note_text: 'Denne brukeren flyttet fra %{acct}, her var dine tidligere notater om dem:' navigation: - toggle_menu: Vis/Skjul meny + toggle_menu: Vis/gøym menyen notification_mailer: admin: report: @@ -1290,7 +1466,7 @@ nn: subject: Du vart nemnd av %{name} title: Ny nemning poll: - subject: En avstemming av %{name} er avsluttet + subject: Meiningsmålinga frå %{name} er avslutta reblog: body: 'Statusen din vart framheva av %{name}:' subject: "%{name} framheva statusen din" @@ -1300,6 +1476,7 @@ nn: update: subject: "%{name} redigerte et innlegg" notifications: + administration_emails: Administrator sine epost-varsler email_events: E-postvarslinger for hendelser email_events_hint: 'Velg hendelser som du vil motta varslinger for:' other_settings: Andre varslingsinnstillinger @@ -1336,12 +1513,22 @@ nn: expired: Denne rundspørjinga er allereie ferdig invalid_choice: Det valgte stemmealternativet eksisterer ikke over_character_limit: kan ikkje vera lengre enn %{max} teikn kvar + self_vote: Du kan ikkje stemme i di eiga avstemming too_few_options: må ha meir enn eitt element too_many_options: kan ikkje ha meir enn %{max} element preferences: other: Anna posting_defaults: Innleggsstandarder public_timelines: Offentlege tidsliner + privacy: + hint_html: "Tilpass korleis du vil at andre skal finna profilen og innlegga dine. Mastodon har fleire funksjonar du kan ta i bruk for å få kontakt med eit større publikum. Sjå gjerne gjennom innstillingane slik at du er sikker på at dei passar til deg og din bruk." + privacy: Personvern + privacy_hint_html: Ha kontroll over kor mykje du vil dela. Folk finn interessante profilar og fine appar ved å sjå gjennom kva andre fylgjer og kva appar dei legg ut innlegg med, men det kan henda du vil gøyma desse opplysingane. + reach: Nå andre + reach_hint_html: Hald styring med om du vil at andre skal kunna oppdaga og fylgja deg. Vil du at innlegga dine skal stå på Utforsk-sida? Vil du at andre skal sjå deg i tilrådingane for kven dei skal fylgja? Vil du ta imot nye fylgjarar automatisk, eller vil du kontrollera kvar einskild fylgjar? + search: Søk + search_hint_html: Kontroller korleis du vil at folk skal finna deg. Vil du at folk skal finna deg ut frå dei offentlege innlegga dine? Vil du at folk utanfor Mastodon skal kunna finna profilen din når dei søkjer på nettet? Ver merksam på at det er uråd å garantera heilt for at søkjemotorar ikkje finn deg. + title: Personvern og rekkjevidd privacy_policy: title: Retningslinjer for personvern reactions: @@ -1354,6 +1541,7 @@ nn: confirm_remove_selected_followers: Er du sikker på at du ynskjer å fjerna dei valde fylgjarane? confirm_remove_selected_follows: Er du sikker på at du ynskjer å fjerna det valde følgjet? dormant: I dvale + follow_failure: Greidde ikkje fylgja alle kontoane du valde. follow_selected_followers: Følg valgte tilhengere followers: Følgere following: Følginger @@ -1374,7 +1562,7 @@ nn: errors: invalid_rules: refererer ikke til gyldige regler rss: - content_warning: 'Innholdsadvarsel:' + content_warning: 'Innhaldsvarsel:' descriptions: account: Offentlige innlegg fra @%{acct} tag: 'Offentlige innlegg merket med #%{hashtag}' @@ -1393,6 +1581,7 @@ nn: electron: Electron firefox: Firefox generic: Ukjend lesar + huawei_browser: Huawei-nettlesaren ie: Internet Explorer micro_messenger: Micromessenger nokia: Nokia S40 Ovi-lesar @@ -1402,6 +1591,7 @@ nn: qq: QQ-lesar safari: Safari uc_browser: QQ-lesar + unknown_browser: Ukjend nettlesar weibo: Weibo current_session: Noverande økt description: "%{browser} på %{platform}" @@ -1414,9 +1604,10 @@ nn: chrome_os: ChromeOS firefox_os: Firefox OS ios: IOS + kai_os: KaiOS linux: Linux mac: Mac - other: ukjend plattform + unknown_platform: Ukjend plattform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1456,6 +1647,9 @@ nn: image: one: "%{count} bilete" other: "%{count} bilete" + video: + one: "%{count} video" + other: "%{count} videoar" boosted_from_html: Framheva av %{acct_link} content_warning: 'Innhaldsåtvaring: %{warning}' default_language: Samme språk som brukergrensesnittet @@ -1473,6 +1667,9 @@ nn: ownership: Du kan ikkje festa andre sine tut reblog: Ei framheving kan ikkje festast poll: + total_people: + one: "%{count} person" + other: "%{count} folk" total_votes: one: "%{count} røyst" other: "%{count} røyster" @@ -1481,7 +1678,6 @@ nn: show_newer: Vis nyere show_older: Vis eldre show_thread: Vis tråden - sign_in_to_participate: Logg inn for å verta med i samtalen title: "%{name}: «%{quote}»" visibilities: direct: Direkte @@ -1523,12 +1719,10 @@ nn: '7889238': 3 månader min_age_label: Aldersterskel min_favs: Behold innlegg som er favorittmarkert av minst - min_favs_hint: Sletter ingen av dine innlegg som har mottatt minst dette antalet favorittmerkingar. Lat vere blank for å slette innlegg uavhengig av antal favorittmerkingar + min_favs_hint: Slettar ingen av innlegga dine som har fått minst så mange favorittar. La det stå tomt for å sletta innlegga uansett kor mange favorittar dei har fått min_reblogs: Behold innlegg fremhevet av minst min_reblogs_hint: Sletter ikke noen av dine innlegg som har blitt fremhevet minst dette antall ganger. La stå tom for å slette innlegg uavhengig av antall fremhevinger stream_entries: - pinned: Festa tut - reblogged: framheva sensitive_content: Ømtolig innhald strikes: errors: @@ -1544,6 +1738,11 @@ nn: default: "%d.%b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d. %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Tenaren si kvote for omsetjingstenesta er brukt opp. + too_many_requests: Det har vore for mange førespurnader til omsetjingstenesta i det siste. two_factor_authentication: add: Legg til disable: Slå av @@ -1623,13 +1822,18 @@ nn: title: Velkomen om bord, %{name}! users: follow_limit_reached: Du kan ikkje fylgja fleire enn %{limit} folk + go_to_sso_account_settings: Gå til kontoinnstillingane hjå identitetsleverandøren din invalid_otp_token: Ugyldig tostegskode otp_lost_help_html: Hvis du mistet tilgangen til begge deler, kan du komme i kontakt med %{email} seamless_external_login: Du er logga inn gjennom eit eksternt reiskap, so passord og e-postinstillingar er ikkje tilgjengelege. signed_in_as: 'Logga inn som:' verification: - explanation_html: 'Du kan bekrefte at du selv er eieren av lenkene i din profilmetadata. For å gjøre det, må det tillenkede nettstedet inneholde en lenke som fører tilbake til Mastodon-profilen din. Lenken tilbake ha en rel="me"-attributt. Tekstinnholdet til lenken er irrelevant. Her er et eksempel:' + extra_instructions_html: Tips: Linken på nettsida di kan vera usynleg. Den viktige delen er rel="me", som på nettstader med brukargenerert innhald vil hindra at andre kan låst som dei er deg. Du kan til og med bruka link i staden for a i toppteksten til sida, men HTML-koden må vera tilgjengeleg utan å måtte køyra JavaScript. + here_is_how: Slik gjer du + hint_html: "Stadfesting av eigen identitet på Mastodon er for alle. Basert på opne nettstandardar, gratis no og for alltid. Alt du treng er ei personleg nettside der folk kjenner deg att. Om du lagar ein link som peikar på denne nettsida frå profilen din, vil profilen din få ein synleg indikator i dei tilfella der nettsida har ein link som peikar attende på profilen." + instructions_html: Kopier og lim inn i koden nedanfor i HTML-koden for nettsida di. Legg deretter adressa til nettsida di til i ei av ekstrafelta på profilen din frå fana "Rediger profil" og lagre endringane. verification: Stadfesting + verified_links: Dine verifiserte lenker webauthn_credentials: add: Legg til ny sikkerhetsnøkkel create: diff --git a/config/locales/no.yml b/config/locales/no.yml index 7b6560547c..dc8151d552 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -91,6 +91,7 @@ moderation: active: Aktive all: Alle + disabled: Deaktivert pending: Avventer silenced: Begrenset suspended: Utvist @@ -124,8 +125,8 @@ removed_header_msg: Fjernet %{username} sin topptekst bilde resend_confirmation: already_confirmed: Denne brukeren er allerede bekreftet - send: Send bekreftelses-epost på nytt - success: Bekreftelses e-post er vellykket sendt! + send: Send bekreftelseslenken på nytt + success: Bekreftelseslenken ble sendt! reset: Tilbakestill reset_password: Nullstill passord resubscribe: Abonner på nytt @@ -133,6 +134,7 @@ search: Søk search_same_email_domain: Andre brukere med samme E-postdomene search_same_ip: Andre brukere med den samme IP-en + security: Sikkerhet security_measures: only_password: Bare passord password_and_2fa: Passord og 2FA @@ -307,6 +309,7 @@ unpublish: Avpubliser unpublished_msg: Kunngjøring upublisert! updated_msg: Kunngjøringen er oppdatert! + critical_update_pending: Kritisk oppdatering avventer custom_emojis: assign_category: Tilegn kategori by_domain: Domene @@ -380,6 +383,15 @@ undo: Fjern fra hvitelisten domain_blocks: add_new: Lag ny + confirm_suspension: + cancel: Avbryt + confirm: Suspender + permanent_action: Å oppheve suspensjonen vil ikke gjenopprette noe data eller koblinger. + preamble_html: Du er i ferd med å suspendere %{domain} og dens underdomener. + remove_all_data: Dette vil fjerne alt innhold, medier og profildata for domenets kontoer på serveren din. + stop_communication: Serveren din vil slutte å kommunisere med disse serverne. + title: Bekreft domeneblokkering for %{domain} + undo_relationships: Dette vil angre ethvert følgeforhold mellom kontoene til disse serverne og dine. created_msg: Domeneblokkering blir nå behandlet destroyed_msg: Domeneblokkering har nå blitt angret domain: Domene @@ -427,6 +439,7 @@ resolve: Løs domene title: Ny blokkeringsoppføring av e-postdomene no_email_domain_block_selected: Ingen e-postdomeneblokker ble endret da ingen ble valgt + not_permitted: Ikke tillatt resolved_dns_records_hint_html: Domenenavnet løser seg til følgende MX-domener som er til slutt ansvarlige for å motta e-post. Blokkering av et MX-domene vil blokkere signaler fra en hvilken som helst e-postadresse som bruker samme MX-domene, selv om det synlige domenenavnet er annerledes. Vær forsiktig så du ikke blokkerer store e-posttilbydere. resolved_through_html: Løst gjennom %{domain} title: Blokkering av e-postdomene @@ -441,6 +454,7 @@ private_comment_description_html: 'For å hjelpe deg med å holde oversikt over hvor importerte blokkeringer kommer fra, vil de bli opprettet med følgende private kommentar: %{comment}' private_comment_template: Importert fra %{source} den %{date} title: Importer domeneblokkeringer + invalid_domain_block: 'En eller flere domeneblokker ble hoppet over på grunn av følgende feil(er): %{error}' new: title: Importer domeneblokkeringer no_file: Ingen fil valgt @@ -472,6 +486,7 @@ content_policies: comment: Internt notat description_html: Du kan definere innholdsregler som vil bli brukt på alle kontoer fra dette domenet og hvilket som helst av underdomenene. + limited_federation_mode_description_html: Du kan velge om føderasjon med dette domenet tillates. policies: reject_media: Avvis media reject_reports: Avvis rapporter @@ -575,17 +590,23 @@ mark_as_sensitive_description_html: Mediene i de rapporterte innleggene vil bli merket som følsomme, og en advarsel vil bli notert for å hjelpe deg eskalere ved fremtidige overtredelser fra samme konto. other_description_html: Se flere alternativer for å kontrollere kontoens atferd og tilpasse kommunikasjonen til den oppgitte kontoen. resolve_description_html: Ingen handling utføres mot den rapporterte kontoen, ingen advarsel gis, og rapporten lukkes. + silence_description_html: Profilen vil kun være synlig for dem som allerede følger den eller manuelt slår den opp, noe som sterkt begrenser dens rekkevidde. Kan alltid tilbakestilles. Lukker alle rapporter mot denne kontoen. + suspend_description_html: Kontoen og alt dens innhold vil være utilgjengelig og til slutt slettet, og det vil ikke være mulig å bruke den. Reversibel innen 30 dager. Lukker alle rapporter mot denne kontoen. actions_description_html: Velg hvilke tiltak som skal treffes for å løse denne rapporten. Dersom du tar noen entydige tiltak mot den oppgitte kontoen, blir det sendt en e-post til dem, unntatt når Søppelpost -kategorien er valgt. + actions_description_remote_html: Velg hvilke tiltak som skal treffes for å løse denne rapporten. Dette påvirker bare hvordan din server kommuniserer med denne eksterne kontoen og håndterer innholdet. add_to_report: Legg til mer i rapporten are_you_sure: Er du sikker? assign_to_self: Tilegn til meg assigned: Tilegnet moderator by_target_domain: Domenet av rapportert bruker + cancel: Avbryt category: Kategori category_description_html: Årsaken til at denne kontoen og/eller innholdet er blitt rapportert vil bli henvist i forbindelse med den rapporterte kontoen comment: none: Ingen comment_description_html: 'For å gi mer informasjon, %{name} skrev:' + confirm: Bekreft + confirm_action: Bekreft moderasjonshandling mot @%{acct} created_at: Rapportert delete_and_resolve: Slettede innlegg forwarded: Videresendt @@ -602,6 +623,7 @@ placeholder: Beskriv hvilke handlinger som har blitt tatt, eller andre relaterte oppdateringer... title: Notater notes_description_html: Se og skriv notater til andre moderatorer og deg selv i fremtiden + processed_msg: 'Rapport #%{id} er behandlet' quick_actions_description_html: 'Ta en rask handling eller bla ned for å se rapportert innhold:' remote_user_placeholder: ekstern bruker fra %{instance} reopen: Gjenåpne rapporten @@ -614,9 +636,28 @@ status: Status statuses: Rapportert innhold statuses_description_html: Innholdet som tilbys, vil bli nevnt i forbindelse med den rapporterte kontoen + summary: + action_preambles: + delete_html: 'Du er i ferd med å fjerne noe av @%{acct} sine innlegg. Dette vil:' + mark_as_sensitive_html: 'Du er i ferd med å markere noen av @%{acct} sine innlegg som sensitivt. Dette vil:' + silence_html: 'Du er i ferd med å avgrense @%{acct} sin konto. Dette vil:' + suspend_html: 'Du er i ferd med å stoppe @%{acct} sin konto. Dette vil:' + actions: + delete_html: Fjerne fornærmede innlegg + mark_as_sensitive_html: Merk fornærmede innlegg medier som sensitivt + silence_html: Sterkt begrense @%{acct}ved å gjøre deres profil og innhold kun synlig for personer som allerede følger dem, eller manuelt ser etter den + suspend_html: Suspender @%{acct}, og gjøre profilen og innholdet utilgjengelig og umulig å samhandle med + close_report: 'Marker rapport #%{id} som løst' + close_reports_html: Merk alle rapporter mot @%{acct} som løst + delete_data_html: Slett @%{acct} sin profil og innhold 30 dager fra nå med mindre de blir suspendert i mellomtiden + preview_preamble_html: "@%{acct} vil motta en advarsel med følgende innhold:" + record_strike_html: Ta opp en streik mot @%{acct} for å hjelpe deg med å eskalere fremtidige brudd fra denne kontoen + send_email_html: Send @%{acct} en advarsels e-post + warning_placeholder: Valgfritt ytterligere resonnement for moderasjonstiltaket. target_origin: Opprinnelse for innrapportert konto title: Rapporter unassign: Fjern tilegning + unknown_action_msg: 'Ukjent handling: %{action}' unresolved: Uløst updated_at: Oppdatert view_profile: Vis profil @@ -648,7 +689,10 @@ invite_users_description: Lar brukere invitere nye personer til serveren manage_announcements: Behandle Kunngjøringer manage_announcements_description: Lar brukere endre kunngjøringer på serveren + manage_appeals: Behandle klager + manage_appeals_description: Lar brukere gjennomgå klager mot modereringsaktiviteter manage_blocks: Behandle Blokker + manage_blocks_description: Lar brukere blokkere e-postleverandører og IP-adresser manage_custom_emojis: Administrer egendefinerte Emojier manage_custom_emojis_description: Lar brukere endre egendefinert emojis på serveren manage_federation: Administrer Føderasjon @@ -658,15 +702,21 @@ manage_reports: Administrer Rapporter manage_reports_description: Lar brukere se på rapporter og utføre moderasjonshandlinger mot dem manage_roles: Behandle Roller + manage_roles_description: Lar brukere administrere og tildele roller under sine rettigheter manage_rules: Administrer Regler manage_rules_description: La brukere endre serverregler manage_settings: Administrer Innstillinger manage_settings_description: La brukere endre sideinnstillinger + manage_taxonomies: Administrer taksonomier + manage_taxonomies_description: Lar brukere gjennomgå populære innhold og oppdatere emneknagg innstillinger manage_user_access: Administrer Brukertilgang manage_user_access_description: Lar brukere deaktivere andre brukeres 2-trinnsinnlogging, endre sin e-postadresse, og tilbakestille passordet deres manage_users: Behandle Brukere manage_users_description: Lar brukere se detaljer om andre brukere og utføre moderasjonshandlinger mot dem manage_webhooks: Administrer Webhooks + manage_webhooks_description: Lar brukere sette opp webhooks for administrative hendelser + view_audit_log: Vis overvåkingslogg + view_audit_log_description: La brukere se en logg over administrative handlinger på serveren view_dashboard: Vis dashbord view_dashboard_description: Gir brukere tilgang til dashbordet og ulike metrikker view_devops: DevOps @@ -689,15 +739,24 @@ preamble: Tilpass Mastodons webgrensesnitt. title: Utseende branding: + preamble: Serverens merkevarebygging skiller den fra andre servere i nettverket. Denne informasjonen kan vises på tvers av en rekke miljøer, for eksempel Mastodons webgrensesnitt, native applikasjoner, i forhåndsvisning av lenker på andre nettsteder og i meldingsapper, osv. Av denne grunn er det best å holde denne informasjonen klar, kort og kortfattet. title: Merkevare + captcha_enabled: + desc_html: Dette er avhengig av eksterne skript fra hCaptcha, som kan være et sikkerhets- og personvernproblem. I tillegg kan dette gjøre registreringsprosessen betydelig mindre tilgjengelig for noen (spesielt funksjonshemmede) personer. Av disse grunnene bør du vurdere alternative tiltak som godkjenningsbasert eller invitasjonsbasert registrering. + title: Krev at nye brukere løser en CAPTCHA for å bekrefte kontoen sin content_retention: preamble: Kontroller hvordan brukergenerert innhold lagres i Mastodon. + title: Oppbevaring av innhold default_noindex: desc_html: Påvirker alle brukerne som ikke selv har justert denne innstillingen title: Ikke la brukere indekseres av søkemotorer som standard discovery: follow_recommendations: Følg anbefalinger + preamble: Å fremheve interessant innhold er viktig i ombordstigning av nye brukere som kanskje ikke kjenner noen Mastodon. Kontroller hvordan ulike oppdagelsesfunksjoner fungerer på serveren. + profile_directory: Profilkatalog public_timelines: Offentlige tidslinjer + publish_discovered_servers: Publiser liste over oppdagede servere + publish_statistics: Publiser statistikk title: Oppdagelse trends: Trender domain_blocks: @@ -716,6 +775,18 @@ site_uploads: delete: Slett den opplastede filen destroyed_msg: Vellykket sletting av sideopplasting! + software_updates: + critical_update: Kritisk — vennligst oppdater raskt + description: "Det anbefales å holde Mastodon-installasjonen oppdatert for å dra nytte av nye rettelser og funksjoner. Dessuten er det av og til viktig å oppdatere Mastodon raskt for å unngå sikkerhetsproblemer. Derfor sjekker Mastodon om det finnes oppdateringer \nhvert 30. minutt, og varsler deg i henhold til dine valg for e-postvarsling." + documentation_link: Finn ut mer + release_notes: Informasjon om utgivelsen + title: Tilgjengelige oppdateringer + type: Type + types: + major: Stor oppdatering + minor: Mindre oppdatering + patch: Liten oppdatering – feilrettinger og endringer som er lette å legge til + version: Versjon statuses: account: Forfatter application: Applikasjon @@ -752,9 +823,24 @@ suspend: "%{name} suspenderte %{target}s konto" appeal_approved: Klage tatt til følge appeal_pending: Klage behandles + appeal_rejected: Anke avvist system_checks: database_schema_check: message_html: Det venter på databaseoverføringer. Vennligst kjør disse for å sikre at applikasjonen oppfører seg som forventet + elasticsearch_health_red: + message_html: Elasticsearch klyngen er usunn (rød status), søkefunksjoner er utilgjengelige + elasticsearch_health_yellow: + message_html: Elasticsearch klyngen er usunn (gul status), du bør vurdere å undersøke årsaken + elasticsearch_index_mismatch: + message_html: Elasticsearch indeksen ("index mappings") er utdatert. Vennligst kjør tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Se dokumentasjon + message_html: Din Elasticsearch-klynge har mer enn en node, men Mastodon er ikke konfigurert til å bruke dem. + elasticsearch_preset_single_node: + action: Se dokumentasjon + message_html: Din Elasticsearch-klynge har bare en node, ES_PRESET bør settes til single_node_cluster. + elasticsearch_reset_chewy: + message_html: Din Elasticsearch systemindeks er utdatert på grunn av en forandring i innstillingene. Vennligst kjør tootctl search deploy --reset-chewy for å oppdatere den. elasticsearch_running_check: message_html: Kunne ikke koble til Elasticsearch. Kontroller at den kjører, eller deaktiver fulltekstsøk elasticsearch_version_check: @@ -765,6 +851,18 @@ message_html: Du har ikke definert noen serverregler. sidekiq_process_check: message_html: Ingen Sidekiq-prosess kjører for %{value} køen(e). Vennligst se gjennom Sidekiq-konfigurasjonen din + software_version_critical_check: + action: Se tilgjengelige oppdateringer + message_html: En kritisk oppdatering av Mastodon er tilgjengelig. Vennligst oppdater så raskt som mulig. + software_version_patch_check: + action: Se tilgjengelige oppdateringer + message_html: En oppdatering av Mastodon som inneholder feilrettinger er tilgjengelig. + upload_check_privacy_error: + action: Sjekk her for mer informasjon + message_html: "Webserveren din er feilkonfigurert. Personvernet til brukerne dine er i fare." + upload_check_privacy_error_object_storage: + action: Sjekk her for mer informasjon + message_html: "Objektlagringen din er feilkonfigurert. Personvernet til brukerne dine er i fare." tags: review: Gjennomgangsstatus updated_msg: Emneknagg innstillinger vellykket oppdatert @@ -787,10 +885,12 @@ other: Delt av %{count} personer i løpet av den siste uken title: Populære lenker usage_comparison: Delt %{today} ganger i dag, sammenlignet med %{yesterday} i går + not_allowed_to_trend: Ikke tillatt å trende only_allowed: Kun tillatte pending_review: Avventer gjennomgang preview_card_providers: allowed: Lenker fra denne utgiveren kan "trende" + description_html: Lenker deles på serveren din, fra disse domenene. Lenker vil ikke trende offentlig med mindre domenet til lenken er godkjent. Din godkjenning (eller avvisning) gjelder også underdomener. rejected: Lenker fra denne utgiveren vil ikke "trende" title: Utgivere rejected: Avvist @@ -800,6 +900,11 @@ description_html: Dette er innlegg som serveren din vet om at de blir delt og favorisert for øyeblikket. Dette kan hjelpe dine nye og returnerede brukere med å finne flere å følge. Ingen innlegg vises offentlig før du godkjenner forfatteren, og forfatteren tillater at kontoen deres foreslås til andre. Du kan også tillate eller avvise individuelle innlegg. disallow: Ikke tillat innlegg disallow_account: Forby forfatter + no_status_selected: Ingen populære innlegg ble endret da ingen ble valgt + not_discoverable: Forfatter har valgt å ikke være synlig + shared_by: + one: Delt eller lagt til som favoritt én gang + other: Delt og favorittmarkert %{friendly_count} ganger title: Populære innlegg tags: current_score: Gjeldende poengsum %{score} @@ -811,10 +916,16 @@ tag_uses_measure: samlet bruk description_html: Dette er emneknagger som for øyeblikket vises i mange innlegg som serveren din ser. Det kan hjelpe dine brukere med å finne ut hva folk snakker mest om i øyeblikket. Ingen emneknagger vises offentlig før du godkjenner dem. listable: Kan bli foreslått + no_tag_selected: Ingen emneknagger ble endret da ingen ble valgt not_listable: Vil ikke bli foreslått not_trendable: Kunne ikke vises under trender not_usable: Kan ikke brukes + peaked_on_and_decaying: Høyeste på %{date}, nå faller + title: Populære emneknagger + trendable: Kan vises under populært + trending_rank: 'Populært #%{rank}' usable: Kan brukes + usage_comparison: Brukt %{today} ganger i dag, sammenlignet med %{yesterday} i går used_by_over_week: one: Brukt av en person i løpet av siste uke other: Brukes av %{count} personer i løpet av den siste uken @@ -840,7 +951,12 @@ one: 1 aktivert hendelse other: "%{count} aktiverte hendelser" events: Hendelser + new: Ny webhook + rotate_secret: Roter hemmelighet (secret) + secret: Signeringshemmelighet (signing secret) status: Status + title: Webhooks + webhook: Webhook admin_mailer: new_appeal: actions: @@ -851,6 +967,12 @@ sensitive: å merke kontoen sin som følsom silence: for å begrense deres konto suspend: for å avslutte kontoen + body: "%{target} klager på en moderasjonsbeslutning av %{action_taken_by} fra %{date}, noe som var %{type}. De skrev:" + next_steps: Du kan godkjenne klagen for å angre på moderasjonsvedtaket eller ignorere det. + subject: "%{username} klager på en moderasjonsbeslutning for %{instance}" + new_critical_software_updates: + body: Nye kritiske versjoner av Mastodon har blitt utgitt, det kan være fordelaktig å oppdatere så snart som mulig! + subject: Kritiske Mastodon-oppdateringer er tilgjengelige for %{instance}! new_pending_account: body: Detaljer om den nye kontoen er nedenfor. Du kan godkjenne eller avvise denne søknaden. subject: Ny konto opp til vurdering på %{instance} (%{username}) @@ -858,12 +980,18 @@ body: "%{reporter} har rapportert %{target}" body_remote: Noen fra %{domain} har rapportert %{target} subject: Ny rapport for %{instance} (#%{id}) + new_software_updates: + body: Nye versjoner av Mastodoner har blitt utgitt, du ønsker kanskje å oppdatere! + subject: Nye versjoner av Mastodon er tilgjengelige for %{instance}! new_trends: + body: 'Følgende elementer trenger en gjennomgang før de kan vises offentlig:' new_trending_links: title: Populære lenker new_trending_statuses: title: Populære innlegg new_trending_tags: + no_approved_tags: Det er for øyeblikket ingen godkjente populære emneknagger. + requirements: 'Enhver av disse kandidatene kan overgå #%{rank} godkjent populære emneknagger, som for øyeblikket er #%{lowest_tag_name} med en poengsum på %{lowest_tag_score}.' title: Populære emneknagger subject: Ny trender for gjennomsyn av %{instance} aliases: @@ -884,31 +1012,37 @@ guide_link: https://crowdin.com/project/mastodon guide_link_text: Alle kan bidra. sensitive_content: Følsomt innhold - toot_layout: Innleggsoppsett application_mailer: notification_preferences: Endre E-postinnstillingene salutation: "%{name}," settings: 'Endre foretrukne e-postinnstillinger: %{link}' + unsubscribe: Avslutt abonnement view: 'Se:' view_profile: Vis Profil view_status: Vis innlegg applications: created: Søknaden ble vellykket oppretttet destroyed: Søknaden ble vellykket slettet + logout: Logg ut regenerate_token: Regenerer tilgangsnøkkel token_regenerated: Tilgangsnøkkel vellykket regenerert warning: Vær veldig forsiktig med denne data. Aldri del den med noen! your_token: Din tilgangsnøkkel auth: apply_for_account: Be om en konto - change_password: Passord + captcha_confirmation: + help_html: Hvis du har problemer med å løse CAPTCHA, kan du komme i kontakt med oss via %{email} og vi kan hjelpe deg. + hint_html: Bare en ting til! Vi må bekrefte at du er et menneske (dette er slik at vi kan holde spam ute!). Løs CAPTCHA nedenfor og klikk "Fortsett". + title: Sikkerhetskontroll + confirmations: + wrong_email_hint: Hvis e-postadressen ikke er riktig, kan du endre den i kontoinnstillingene. delete_account: Slett konto delete_account_html: Hvis du ønsker å slette kontoen din, kan du gå hit. Du vil bli spurt om bekreftelse. description: prefix_invited_by_user: "@%{name} inviterer deg til å bli med på denne serveren til Mastodon!" prefix_sign_up: Registrer deg på Mastodon i dag! suffix: Med en konto, vil kunne følge folk, skrive innlegg, og utveksle meldinger med brukere fra enhver Mastodon-tjener, og mer til! - didnt_get_confirmation: Mottok du ikke instruksjoner om bekreftelse? + didnt_get_confirmation: Mottok du ikke en bekreftelseslenke? dont_have_your_security_key: Har du ikke sikkerhetsnøkkelen din? forgot_password: Har du glemt passordet ditt? invalid_reset_password_token: Tilbakestillingsnøkkelen for passord er ugyldig eller utløpt. Vennligst be om en ny. @@ -921,26 +1055,39 @@ migrate_account_html: Hvis du ønsker å henvise denne kontoen til en annen, kan du konfigurere det her. or_log_in_with: Eller logg inn med privacy_policy_agreement_html: Jeg har lest og godtar retningslinjer for personvern + progress: + confirm: Bekreft e-postadresse + details: Dine opplysninger + review: Vår gjennomgang + rules: Godta regler providers: cas: CAS saml: SAML register: Meld deg på registration_closed: "%{instance} tar ikke imot nye medlemmer" - resend_confirmation: Send bekreftelsesinstruksjoner på nytt + resend_confirmation: Send bekreftelseslenke på nytt reset_password: Tilbakestill passord rules: + accept: Godta + back: Tilbake + invited_by: 'Du kan bli med %{domain} takket være invitasjonen du fikk fra:' preamble: Disse angis og håndheves av %{domain}-moderatorene. + preamble_invited: Før du fortsetter, vennligst gå gjennom reglene som er satt av moderatorene av %{domain}. title: Noen grunnregler. + title_invited: Du har blitt invitert. security: Sikkerhet set_new_password: Angi nytt passord setup: - email_below_hint_html: Dersom E-postadressen nedenfor er feil, kan du endre det her og motta en ny bekreftelses-E-post. - email_settings_hint_html: Bekreftelses-E-posten ble sendt til %{email}. Dersom den E-postadressen ikke var riktig, kan du endre den i kontoinnstillingene. - title: Innstillinger + email_below_hint_html: Sjekk søppelpostmappen din, eller be om en ny. Du kan korrigere e-postadressen din hvis den er feil. + email_settings_hint_html: Klikk på lenken vi sendte deg for å bekrefte %{email}. Vi venter her. + link_not_received: Fikk du ikke lenken? + new_confirmation_instructions_sent: Du vil motta en ny e-post med bekreftelseslenken om noen minutter! + title: Sjekk innboksen din sign_in: preamble_html: Logg inn med ditt %{domain} brukeropplysninger. Hvis kontoen din er plassert på en annen server, vil du ikke kunne logge inn her. title: Logg inn på %{domain} sign_up: + manual_review: Registreringer på %{domain} krever manuell gjennomgang av moderatorene våre. For å hjelpe oss med å behandle registreringen din, skriv litt om deg selv og hvorfor du vil ha en konto på %{domain}. preamble: Med en konto på denne Mastodon-tjeneren vil du kunne følge andre personer på nettverket, uansett hvor kontoen deres holder til. title: La oss få deg satt i gang på %{domain}. status: @@ -952,18 +1099,6 @@ view_strikes: Vis tidligere advarsler mot kontoen din too_fast: Skjemaet ble sendt inn for raskt, prøv på nytt. use_security_key: Bruk sikkerhetsnøkkel - authorize_follow: - already_following: Du følger allerede denne kontoen - already_requested: Du har allerede sendt en følgeforespørsel til denne kontoen - error: Dessverre oppstod det en feil da vi prøvde å få tak i brukeren fra tjeneren - follow: Følg - follow_request: 'Du har sendt en følgeforespørsel til:' - following: 'Suksess! Nå følger du:' - post_follow: - close: Eller så kan du lukke dette vinduet. - return: Gå tilbake til brukerens profil - web: Gå til nettsiden - title: Følg %{acct} challenge: confirm: Fortsett hint_html: "Tips: Vi ber deg ikke om passordet ditt igjen i løpet av neste time." @@ -1040,6 +1175,10 @@ your_appeal_rejected: Din klage har blitt avvist domain_validator: invalid_domain: er ikke et gyldig domenenavn + edit_profile: + basic_information: Grunnleggende informasjon + hint_html: "Tilpass hva folk ser på din offentlige profil og ved siden av dine innlegg. Det er mer sannsynlig at andre mennesker følger deg tilbake og samhandler med deg når du har fylt ut en profil og et profilbilde." + other: Annet errors: '400': Forespørselen du sendte inn var ugyldig eller feil. '403': Du har ikke tillatelse til å vise denne siden. @@ -1076,7 +1215,7 @@ featured_tags: add_new: Legg til ny errors: - limit: Du har allerede fremhevet det maksimale antal hashtags + limit: Du har allerede fremhevet det maksimale antall emneknagger hint_html: "Hva er utvalgte emneknagger? De vises frem tydelig på din offentlige profil, og lar folk bla i dine offentlige innlegg som spesifikt har de emneknaggene. De er et bra verktøy for å holde styr på kreative verk eller langtidsprosjekter." filters: contexts: @@ -1089,7 +1228,11 @@ add_keyword: Legg til stikkord keywords: Nøkkelord statuses: Individuelle innlegg + statuses_hint_html: Dette filteret gjelder for utvalgte enkeltinnlegg, uavhengig av om de samsvarer med søkeordene nedenfor.Se gjennom eller fjern innlegg fra filteret.. title: Rediger filter + errors: + deprecated_api_multiple_keywords: Disse parameterne kan ikke endres fra dette programmet fordi de gjelder for mer enn ett filternøkkelord. Bruk et nyere program eller webgrensesnittet. + invalid_context: Ingen eller ugyldig kontekst angitt index: contexts: Filtre i %{contexts} delete: Slett @@ -1116,8 +1259,6 @@ index: hint: Dette filteret gjelder for å velge individuelle innlegg uavhengig av andre kriterier. Du kan legge til flere innlegg til dette filteret fra webgrensesnittet. title: Filtrerte innlegg - footer: - trending_now: Trender nå generic: all: Alle all_items_on_page_selected_html: @@ -1126,7 +1267,9 @@ all_matching_items_selected_html: one: "%{count} element som matcher søket ditt er valgt." other: Alle %{count} elementer som matcher søket velges. + cancel: Avbryt changes_saved_msg: Vellykket lagring av endringer! + confirm: Bekreft copy: Kopier delete: Slett deselect: Fjern all merking @@ -1140,24 +1283,62 @@ validation_errors: one: Noe er ikke helt riktig ennå. Vennligst se etter en gang til other: Noe er ikke helt riktig ennå. Det er ennå %{count} feil å rette på - html_validator: - invalid_markup: 'inneholder ugyldig HTML-markør: %{error}' imports: errors: + empty: Tom CSV-fil + incompatible_type: Ikke kompatibel med den valgte importtypen invalid_csv_file: 'Ugyldig CSV-fil. Feil: %{error}' over_rows_processing_limit: inneholder flere enn %{count} rader + too_large: Filen er for stor + failures: Feil + imported: Importert + mismatched_types_warning: Det ser ut til at du har valgt feil importtype, vennligst dobbeltsjekk. modes: merge: Slå sammen merge_long: Behold eksisterende og legg til nye overwrite: Overskriv overwrite_long: Erstatt gjeldende med de nye + overwrite_preambles: + blocking_html: Du er i ferd med å erstatte din blokkeringsliste med inntil %{total_items} kontoer fra %{filename}. + bookmarks_html: Du er i ferd med å erstatte dine bokmerker med inntil %{total_items} innlegg fra %{filename}. + domain_blocking_html: Du er i ferd med å erstatte din domene-blokkeringsliste med inntil %{total_items} domener fra %{filename}. + following_html: Du er i ferd med å følge inntil %{total_items} kontoer fra %{filename} og slutte å følge alle andre. + lists_html: Du er i ferd med å erstatte dine lister med innholdet i %{filename}. Inntil %{total_items} kontoer legges til i nye lister. + muting_html: Du er i ferd med å erstatte listen over dempede kontoer med inntil %{total_items} kontoer fra %{filename}. + preambles: + blocking_html: Du er i ferd med å blokkere inntil %{total_items} kontoer fra %{filename}. + bookmarks_html: Du er i ferd med å legge til inntil %{total_items} innlegg fra %{filename} til dine bokmerker. + domain_blocking_html: Du er i ferd med å blokkere inntil %{total_items} domener fra %{filename}. + following_html: Du er i ferd med å følge inntil %{total_items} kontoer fra %{filename}. + lists_html: Du er i ferd med å legge inntil %{total_items} kontoer fra %{filename} til dine lister. Nye lister vil bli opprettet hvis det ikke finnes noen liste å legge til. + muting_html: Du er i ferd med å dempe inntil %{total_items} kontoer fra %{filename}. preface: Du kan importere data om brukere du følger eller blokkerer til kontoen din på denne instansen med eksportfiler fra andre instanser. + recent_imports: Siste importer + states: + finished: Fullført + in_progress: Pågående + scheduled: Planlagt + unconfirmed: Ubekreftet + status: Status success: Dine data ble mottatt og vil bli behandlet så fort som mulig + time_started: Startet + titles: + blocking: Importerer blokkerte kontoer + bookmarks: Importerer bokmerker + domain_blocking: Importerer blokkerte domener + following: Importerer fulgte kontoer + lists: Importerer lister + muting: Importerer dempede kontoer + type: Type import + type_groups: + constructive: Følginger og bokmerker + destructive: Blokkeringer og dempinger types: blocking: Blokkeringsliste bookmarks: Bokmerker domain_blocking: Domeneblokkeringsliste following: Følgeliste + lists: Lister muting: Dempeliste upload: Opplastning invites: @@ -1184,7 +1365,7 @@ title: Inviter personer lists: errors: - limit: Du har nådd det maksimale antall lister + limit: Du har nådd den øvre grensen for antall lister login_activities: authentication_methods: otp: to-faktor autentiseringsapp @@ -1196,6 +1377,21 @@ failed_sign_in_html: Mislykket innloggingsforsøk med %{method} fra %{ip} (%{browser}) successful_sign_in_html: Vellykket innlogging med %{method} fra %{ip} (%{browser}) title: Autentiseringshistorikk + mail_subscriptions: + unsubscribe: + action: Ja, avslutt abonnement + complete: Abonnement avsluttet + confirmation_html: Er du sikker på at du vil slutte å motta %{type} fra Mastodon %{domain} i e-posten din på %{email}? Du kan når som helst gjenoppta i innstillinger for e-postvarsling. + emails: + notification_emails: + favourite: e-poster om favorittmarkeringer + follow: e-poster om følgere + follow_request: e-poster om følgeforespørsler + mention: e-poster om nevninger + reblog: e-poster om fremhevinger + resubscribe_html: Hvis du har avsluttet abonnementet ved en feiltakelse, kan du abonnere på nytt i innstillinger for e-postvarsling. + success_html: Du vil ikke lenger motta %{type} fra Mastodon på %{domain} i e-posten din på %{email}. + title: Avslutt abonnement media_attachments: validations: images_and_video: Kan ikke legge ved video på en status som allerede inneholder bilder @@ -1275,6 +1471,7 @@ update: subject: "%{name} redigerte et innlegg" notifications: + administration_emails: Administrators e-postvarslinger email_events: E-postvarslinger for hendelser email_events_hint: 'Velg hendelser som du vil motta varslinger for:' other_settings: Andre varslingsinnstillinger @@ -1311,12 +1508,22 @@ expired: Denne avstemningen er allerede ferdig invalid_choice: Det valgte stemmealternativet eksisterer ikke over_character_limit: kan ikke være lengre enn %{max} tegn hver + self_vote: Du kan ikke stemme i dine egne avstemninger too_few_options: må ha mer enn én gjenstand too_many_options: kan ikke ha mer enn %{max} gjenstander preferences: other: Annet posting_defaults: Innleggsstandarder public_timelines: Offentlige tidslinjer + privacy: + hint_html: "Tilpass hvordan du vil at din profil og dine innlegg skal bli funnet. En rekke funksjoner i Mastodon kan hjelpe deg med å nå et bredere publikum når de aktiverte. Ta deg et øyeblikk til å vurdere disse innstillingene for å forsikre deg om at de passer deg og ditt bruk." + privacy: Personvern + privacy_hint_html: Kontrollér hvor mye du ønsker å dele til fordel for andre. Folk oppdager interessante profiler og kule app'er ved å bla gjennom andres følgere og ved å se hvilke app'er de bruker, men du kan velge å holde det skjult. + reach: Rekkevidde + reach_hint_html: Kontrollér om du ønsker å kunne bli oppdaget og fulgt av nye personer. Vil du at dine innlegg vises på Utforsk-siden? Vil du at andre personer skal kunne se deg i sine følgeranbefalinger? Vil du akseptere alle nye følgere automatisk, eller godkjenne hver enkelt? + search: Søk + search_hint_html: Kontrollér hvordan du ønsker å bli oppdaget. Vil du at folk skal kunne finne deg basert på dine offentlige innlegg? Vil du at personer utenfor Mastodon skal kunne finne din profil når de søker på nettet? Vennligst husk at en total utestengelse fra alle søkemotorer ikke kan garanteres for offentlig informasjon. + title: Personvern og rekkevidde privacy_policy: title: Retningslinjer for personvern reactions: @@ -1325,7 +1532,11 @@ unrecognized_emoji: er ikke en gjenkjent emoji relationships: activity: Kontoaktivitet + confirm_follow_selected_followers: Er du sikker på at du vil følge valgte følgere? + confirm_remove_selected_followers: Er du sikker på at du vil fjerne valgte følgere? + confirm_remove_selected_follows: Er du sikker på at du vil fjerne valgte følginger? dormant: Dormende + follow_failure: Kunne ikke følge noen av de valgte kontoene. follow_selected_followers: Følg valgte tilhengere followers: Følgere following: Følginger @@ -1365,6 +1576,7 @@ electron: Electron firefox: Firefox generic: Ukjent nettleser + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi-nettleser @@ -1374,6 +1586,7 @@ qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Ukjent Nettleser weibo: Weibo current_session: Nåværende økt description: "%{browser} på %{platform}" @@ -1386,9 +1599,10 @@ chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: ukjent plattform + unknown_platform: Ukjent plattform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1459,7 +1673,6 @@ show_newer: Vis nyere show_older: Vis eldre show_thread: Vis tråden - sign_in_to_participate: Logg på for å delta i samtalen title: "%{name}: «%{quote}»" visibilities: direct: Direkte @@ -1505,8 +1718,6 @@ min_reblogs: Behold innlegg fremhevet av minst min_reblogs_hint: Sletter ikke noen av dine innlegg som har blitt fremhevet minst dette antall ganger. La stå tom for å slette innlegg uavhengig av antall fremhevinger stream_entries: - pinned: Festet innlegg - reblogged: fremhevet sensitive_content: Følsomt innhold strikes: errors: @@ -1522,6 +1733,7 @@ default: "%-d. %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%-d. %b %Y, %H:%M %Z" two_factor_authentication: add: Legg til disable: Skru av @@ -1601,13 +1813,18 @@ title: Velkommen ombord, %{name}! users: follow_limit_reached: Du kan ikke følge mer enn %{limit} personer + go_to_sso_account_settings: Gå til din identitetsleverandørs kontoinnstillinger invalid_otp_token: Ugyldig to-faktorkode otp_lost_help_html: Hvis du mistet tilgangen til begge deler, kan du komme i kontakt med %{email} seamless_external_login: Du er logget inn via en ekstern tjeneste, så passord og e-post innstillinger er ikke tilgjengelige. signed_in_as: 'Innlogget som:' verification: - explanation_html: 'Du kan bekrefte at du selv er eieren av lenkene i din profilmetadata. For å gjøre det, må det tillenkede nettstedet inneholde en lenke som fører tilbake til Mastodon-profilen din. Lenken tilbake ha en rel="me"-attributt. Tekstinnholdet til lenken er irrelevant. Her er et eksempel:' + extra_instructions_html: Tips: Lenken på din nettside kan være usynlig. Den viktige delen er rel="me" som sikrer at nettsteder med brukergenerert innhold ikke kan utgi seg for å være deg. Du kan til og med bruke en link lenke i sidens topptekst i stedet for a, men HTML-koden må være tilgjengelig uten å kjøre JavaScript. + here_is_how: Slik gjør du + hint_html: "Verifisering av identiteten din på Mastodon er for alle. Basert på åpne nettstandarder, gratis nå og for alltid. Alt du trenger er en personlig nettside som gjør at folk kjenner deg igjen. Når du lenker til dette nettstedet fra din profil, vil vi sjekke at nettstedet lenker tilbake til profilen din og viser dette på profilen din." + instructions_html: Kopier og lim inn koden nedenfor i HTML til ditt nettsted. Deretter legger du til adressen til nettstedet ditt i et av ekstrafeltene på profilen din fra fanen "Rediger profil" og lagre endringer. verification: Bekreftelse + verified_links: Dine bekreftede lenker webauthn_credentials: add: Legg til ny sikkerhetsnøkkel create: diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 7af4a339da..8145002e56 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -105,14 +105,13 @@ oc: remove_header: Levar la bandièra resend_confirmation: already_confirmed: Aqueste utilizaire es ja confirmat - send: Tornar mandar lo corrièl de confirmacion - success: Corrièl de confirmacion corrèctament mandat ! reset: Reïnicializar reset_password: Reïnicializar lo senhal resubscribe: Se tornar abonar role: Ròtle search: Cercar search_same_ip: Autres utilizaires amb la meteissa IP + security: Seguretat security_measures: only_password: Sonque senhal password_and_2fa: Senhal e 2FA @@ -397,7 +396,6 @@ oc: approved: Validacion necessària per s’inscriure none: Degun pòt pas se marcar open: Tot lo monde se pòt marcar - title: Paramètres del servidor site_uploads: delete: Suprimir lo fichièr enviat statuses: @@ -461,7 +459,6 @@ oc: body: Mastodon es traduch per de benevòls. guide_link_text: Tot lo monde pòt contribuïr. sensitive_content: Contengut sensible - toot_layout: Disposicion del tut application_mailer: notification_preferences: Cambiar las preferéncias de corrièl salutation: "%{name}," @@ -477,13 +474,11 @@ oc: warning: Mèfi ! Agachatz de partejar aquela donada amb degun ! your_token: Vòstre geton d’accès auth: - change_password: Senhal delete_account: Suprimir lo compte delete_account_html: Se volètz suprimir vòstre compte, podètz o far aquí. Vos demandarem que confirmetz. description: prefix_invited_by_user: "@%{name} vos convida a rejónher aqueste servidor Mastodon !" prefix_sign_up: Marcatz-vos a Mostodon uèi ! - didnt_get_confirmation: Avètz pas recebut las instruccions de confirmacion ? forgot_password: Senhal oblidat ? invalid_reset_password_token: Lo geton de reïnicializacion es invalid o acabat. Tornatz demandar un geton se vos plai. link_to_webauth: Utilizar un aparelh de claus de seguretat @@ -499,29 +494,15 @@ oc: saml: SAML register: Se marcar registration_closed: "%{instance} accepta pas de nòus membres" - resend_confirmation: Tornar mandar las instruccions de confirmacion reset_password: Reïnicializar lo senhal rules: title: Unas règlas de basa. security: Seguretat set_new_password: Picar un nòu senhal - setup: - title: Configuracion status: account_status: Estat del compte functional: Vòstre compte es complètament foncional. use_security_key: Utilizar clau de seguretat - authorize_follow: - already_following: Seguètz ja aqueste compte - error: O planhèm, i a agut una error al moment de cercar lo compte - follow: Sègre - follow_request: 'Avètz demandat de sègre :' - following: 'Felicitacion ! Seguètz ara :' - post_follow: - close: O podètz tampar aquesta fenèstra. - return: Veire lo perfil a la persona - web: Tornar a l’interfàcia Web - title: Sègre %{acct} challenge: confirm: Contunhar hint_html: "Asutúcia : vos demandarem pas vòstre senhal de nòu d’aquí unas oras." @@ -566,7 +547,6 @@ oc: domain_validator: invalid_domain: es pas un nom de domeni valid errors: - '400': The request you submitted was invalid or malformed. '403': Avètz pas l’autorizacion de veire aquesta pagina. '404': La pagina que cercatz existís pas aquí. '406': La pagina es pas disponibla dins lo format demandat. @@ -578,7 +558,6 @@ oc: '500': content: Un quicomet a pas foncionat coma caliá. title: Aquesta pagina es pas corrècta - '503': The page could not be served due to a temporary server failure. noscript_html: Per utilizar l’aplicacion web de Mastodon, mercés d’activar JavaScript. O podètz utilizar una aplicacion per vòstra plataforma coma alernativa. existing_username_validator: not_found: impossible de trobar un utilizaire local amb aqueste nom d’utilizaire @@ -600,8 +579,6 @@ oc: storage: Mèdias gardats featured_tags: add_new: Ajustar una etiqueta nòva - errors: - limit: Avètz ja utilizat lo maximum d’etiquetas filters: contexts: account: Perfils @@ -629,8 +606,6 @@ oc: title: Filtres new: title: Ajustar un nòu filtre - footer: - trending_now: Tendéncia del moment generic: all: Tot changes_saved_msg: Cambiaments ben realizats ! @@ -642,8 +617,6 @@ oc: validation_errors: one: I a quicòm que truca ! Mercés de corregir l’error çai-jos other: I a quicòm que truca ! Mercés de corregir las %{count} errors çai-jos - html_validator: - invalid_markup: 'conten un balisatge HTML invalid : %{error}' imports: modes: merge: Fondre @@ -681,9 +654,6 @@ oc: expires_at: Expirats uses: Usatges title: Convidar de monde - lists: - errors: - limit: Avètz atengut lo maximum de listas login_activities: authentication_methods: password: senhal @@ -839,7 +809,6 @@ oc: ios: iOS linux: Linux mac: Mac - other: plataforma desconeguda windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -907,7 +876,6 @@ oc: show_newer: Veire mai recents show_older: Veire mai ancians show_thread: Mostrar lo fil - sign_in_to_participate: Inscrivètz-vos per participar a la conversacion title: '%{name} : "%{quote}"' visibilities: direct: Dirècte @@ -947,12 +915,9 @@ oc: '7889238': 3 meses min_age_label: Sulhet d’ancianetat min_favs: Gardar al mens las publicacion en favorit - min_favs_hint: Suprimís pas las publicacions qu’an recebut al mens aquesta quantitat de favorits. Daissar blanc per suprimir las publicacion quina quantitat de favorits qu’ajan min_reblogs: Gardar las publicacions partejadas al mens min_reblogs_hint: Suprimís pas vòstras publicacions qu’an agut aqueste nombre de partiment. Daissar blanc per suprimir las publicacions sens far cas als partiments stream_entries: - pinned: Tut penjat - reblogged: a partejat sensitive_content: Contengut sensible tags: does_not_match_previous_name: correspond pas al nom precedent @@ -1015,7 +980,6 @@ oc: seamless_external_login: Sètz connectat via un servici extèrn, los paramètres de senhal e de corrièl son doncas pas disponibles. signed_in_as: 'Session a :' verification: - explanation_html: 'Podètz verificar vosautres meteisses coma proprietari dels ligams per las metadonadas de vòstre perfil. Per aquò far, lo site Web ligat deu conténer un ligam cap a vòstre perfil Mastodon. Lo ligam deu aver un atribut rel="me". Lo contengut tèxte del ligam impòrta pas. Vaquí un exemple :' verification: Verificacion webauthn_credentials: add: Apondre una clau de seguretat novèla diff --git a/config/locales/pa.yml b/config/locales/pa.yml index 1a91937967..bb8a6c834d 100644 --- a/config/locales/pa.yml +++ b/config/locales/pa.yml @@ -1,10 +1 @@ ---- pa: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/pl.yml b/config/locales/pl.yml index f2c1ccdae2..3f585863a4 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -95,6 +95,7 @@ pl: moderation: active: Aktywne all: Wszystkie + disabled: Wyłączone pending: Oczekujące silenced: Ograniczone suspended: Zawieszone @@ -130,8 +131,8 @@ pl: removed_header_msg: Pomyślnie usunięto obraz nagłówka %{username} resend_confirmation: already_confirmed: To konto zostało już potwierdzone - send: Wyślij ponownie e-mail z potwierdzeniem - success: E-mail z potwierdzeniem został wysłany! + send: Wyślij ponownie link potwierdzający + success: Link potwierdzający został pomyślnie wysłany! reset: Resetuj reset_password: Resetuj hasło resubscribe: Ponów subskrypcję @@ -139,6 +140,7 @@ pl: search: Szukaj search_same_email_domain: Inni użytkownicy z tym samym e-mail w tej domenie search_same_ip: Inni użytkownicy z tym samym IP + security: Bezpieczeństwo security_measures: only_password: Tylko hasło password_and_2fa: Hasło i 2FA @@ -146,7 +148,7 @@ pl: sensitized: Oznaczono jako wrażliwe shared_inbox_url: Adres udostępnianej skrzynki show: - created_reports: Zgłoszenia tego użytkownika + created_reports: Zgłoszeń targeted_reports: Zgłoszenia dotyczące tego użytkownika silence: Wycisz silenced: Wyciszono @@ -313,6 +315,7 @@ pl: unpublish: Cofnij publikację unpublished_msg: Pomyślnie wycofano publikację ogłoszenia! updated_msg: Pomyślnie zaktualizowano ogłoszenie! + critical_update_pending: Czeka krytyczna aktualizacja custom_emojis: assign_category: Ustaw kategorię by_domain: Domeny @@ -361,7 +364,7 @@ pl: pending_reports_html: few: "%{count} oczekujące raporty" many: "%{count} oczekujących raportów" - one: "%{count} oczekujący raport" + one: "%{count} oczekujące zgłoszenie" other: "%{count} oczekujących raportów" pending_tags_html: few: "%{count} oczekujące hashtagi" @@ -394,6 +397,15 @@ pl: undo: Usuń z białej listy domain_blocks: add_new: Dodaj nową + confirm_suspension: + cancel: Anuluj + confirm: Zawieś + permanent_action: Cofnięcie zawieszenia nie przywróci żadnych danych ani związków. + preamble_html: Zamierzasz zawiesić %{domain} wraz z subdomenami. + remove_all_data: Usunie to wszystkie treści, media, i dane profilów kont tej domeny z twojego serwera. + stop_communication: Twój serwer przestanie komunikować się z tymi serwerami. + title: Potwierdź blokadę domeny %{domain} + undo_relationships: To usunie wszystkie związki obserwowania między kontami na tych serwerach i twoim. created_msg: Blokada domen jest przetwarzana destroyed_msg: Blokada domeny nie może zostać odwrócona domain: Domena @@ -443,6 +455,7 @@ pl: resolve: Rozwiąż domenę title: Nowa blokada domeny e-mail no_email_domain_block_selected: Żadne blokady domeny e-mail nie zostały zmienione, ponieważ żadne z nich nie zostały wybrane + not_permitted: Brak uprawnień resolved_dns_records_hint_html: Nazwa domeny rozwiązuje się do następujących domen MX, które są ostatecznie odpowiedzialne za przyjmowanie wiadomości e-mail. Blokowanie domeny MX spowoduje zablokowanie rejestracji z dowolnego adresu e-mail, który używa tej samej domeny MX, nawet jeśli widoczna nazwa domeny jest inna. Uważaj, aby nie blokować głównych dostawców poczty elektronicznej. resolved_through_html: Rozwiązano przez %{domain} title: Blokowanie domen e-mail @@ -493,6 +506,7 @@ pl: content_policies: comment: Wewnętrzna notatka description_html: Możesz zdefiniować zasady treści, które zostaną zastosowane do wszystkich kont z tej domeny i jej subdomen. + limited_federation_mode_description_html: Możesz wybrać, czy zezwolić na federację z tą domeną. policies: reject_media: Odrzucaj media reject_reports: Odrzucaj zgłoszenia @@ -593,7 +607,7 @@ pl: many: "%{count} notatek" one: "%{count} notatka" other: "%{count} notatki" - action_log: Dziennik audytu + action_log: Dziennik zdarzeń action_taken_by: Działanie podjęte przez actions: delete_description_html: Zgłoszone posty zostaną usunięte, a zdarzenie zostanie zapisane, aby pomóc w eskalacji przyszłych wykroczeń na tym samym koncie. @@ -604,16 +618,18 @@ pl: suspend_description_html: Konto i cała jego zawartość będą niedostępne i ostatecznie usunięte, a interakcja z nim będzie niemożliwa. Możliwość odwrócenia w ciągu 30 dni. Zamyka wszelkie zgłoszenia dotyczące tego konta. actions_description_html: Zdecyduj, jakie działania należy podjąć, aby rozstrzygnąć niniejsze zgłoszenie. Jeśli podejmiesz działania karne przeciwko zgłoszonemu kontowi, zostanie do nich wysłane powiadomienie e-mail, chyba że wybrano kategorię Spam. actions_description_remote_html: Zdecyduj, jakie działanie należy podjąć, aby rozwiązać to zgłoszenie. Będzie to miało wpływ jedynie na sposób, w jaki Twój serwer komunikuje się z tym kontem zdalnym i obsługuje jego zawartość. - add_to_report: Dodaj więcej do raportu + add_to_report: Dodaj więcej do zgłoszenia are_you_sure: Czy na pewno? assign_to_self: Przypisz do siebie assigned: Przypisany moderator by_target_domain: Domena zgłaszanego konta + cancel: Anuluj category: Kategoria category_description_html: Powód, dla którego to konto i/lub zawartość zostały zgłoszone, będzie cytowany w komunikacji ze zgłoszonym kontem comment: none: Brak comment_description_html: 'Aby dostarczyć więcej informacji, %{name} napisał:' + confirm: Potwierdź confirm_action: Potwierdzenie działań moderacyjnych wobec @%{acct} created_at: Zgłoszono delete_and_resolve: Usuń posty @@ -622,7 +638,7 @@ pl: mark_as_resolved: Oznacz jako rozwiązane mark_as_sensitive: Oznacz jako wrażliwe mark_as_unresolved: Oznacz jako nierozwiązane - no_one_assigned: Nikt nie + no_one_assigned: Nikt notes: create: Utwórz notatkę create_and_resolve: Rozwiąż i pozostaw notatkę @@ -631,7 +647,7 @@ pl: placeholder: Opisz wykonane akcje i inne szczegóły dotyczące tego zgłoszenia… title: Notatki notes_description_html: Przeglądaj i zostaw notatki innym moderatorom i sobie samemu - processed_msg: 'Raport #%{id} został pomyślnie przetworzony' + processed_msg: 'Zgłoszenie #%{id} zostało pomyślnie przetworzone' quick_actions_description_html: 'Wykonaj szybkie działanie lub przewiń w dół, aby zobaczyć zgłoszoną zawartość:' remote_user_placeholder: zdalny użytkownik z %{instance} reopen: Otwórz ponownie @@ -651,11 +667,11 @@ pl: silence_html: 'Zamierzasz ograniczyć konto @%{acct}. To spowoduje:' suspend_html: 'Zamierzasz zawiesić konto @%{acct}. To spowoduje:' actions: - delete_html: Usuń obrażające posty + delete_html: Usuń zgłoszone posty mark_as_sensitive_html: Oznacz obraźliwe media postów jako wrażliwe silence_html: Znacząco ogranicz zasięg @%{acct}, aby ich profil i zawartość były widoczne tylko dla osób, które je już obserwują lub ręcznie wyszukują jego profil suspend_html: Zawieś @%{acct}, co sprawia, że ich profil i zawartość są niedostępne i niemożliwe do interakcji z - close_report: 'Oznacz raport #%{id} jako rozwiązany' + close_report: 'Oznacz zgłoszenie #%{id} jako rozwiązane' close_reports_html: Oznacz wszystkie zgłoszenia dotyczące @%{acct} jako rozwiązane delete_data_html: Usuń profil i zawartość @%{acct} za 30 dni, chyba że w tym czasie zostanie zawieszony preview_preamble_html: "@%{acct} otrzyma ostrzeżenie o następującej treści:" @@ -711,8 +727,8 @@ pl: manage_federation_description: Pozwala użytkownikom na blokowanie lub zezwalanie federacji z innymi domenami i kontrolowanie doręczania manage_invites: Zarządzaj zaproszeniami manage_invites_description: Pozwala użytkownikom przeglądać i dezaktywować linki z zaproszeniami - manage_reports: Zarządzaj raportami - manage_reports_description: Pozwala użytkownikom przeglądać raporty i wykonywać przeciwko nim działania moderacyjne + manage_reports: Zarządzaj zgłoszeniami + manage_reports_description: Pozwala użytkownikom przeglądać zgłoszenia i wykonywać przeciwko nim działania moderacyjne manage_roles: Zarządzaj rolami manage_roles_description: Pozwala użytkownikom zarządzać rolami i przypisywać role poniżej ich własnych manage_rules: Zarządzaj regułami @@ -753,6 +769,9 @@ pl: branding: preamble: Marka Twojego serwera odróżnia go od innych serwerów w sieci. Informacje te mogą być wyświetlane w różnych środowiskach, takich jak interfejs internetowy Mastodon, aplikacje natywne, w podglądzie linków na innych stronach internetowych i w aplikacjach do wysyłania wiadomości itd. Z tego względu najlepiej zachować jasną, krótką i zwięzłą informację. title: Marka + captcha_enabled: + desc_html: Wymaga użycia zewnętrznych skryptów hCaptcha, co może negatywnie wpływać na bezpieczeństwo i prywatność. Może również przyczynić się do znaczącego utrudnienia procesu rejestracji niektórym, np. niepełnosprawnym, osobom. Dlatego sugeruje się używanie zaproszeń bądź ręcznie potwierdzanie kont. + title: W celu potwierdzenia ich kont wymagaj rozwiązania zadania CAPTCHA przez nowych użytkowników content_retention: preamble: Kontroluj, jak treści generowane przez użytkownika są przechowywane w Mastodon. title: Retencja treści @@ -780,10 +799,27 @@ pl: approved: Przyjęcie jest wymagane do rejestracji none: Nikt nie może się zarejestrować open: Każdy może się zarejestrować + security: + authorized_fetch: Wymagaj uwierzytelnienia od sfederowanych serwerów + authorized_fetch_hint: Wymaganie uwierzytelnienia ze sfederowanych serwerów pozwala na ściślejsze wymuszanie bloków z poziomu użytkowników i serwera, ale jest wolniejsze, redukuje zasięg odpowiedzi, i może być niekompatybilne z niektórymi sfederowanymi usługami. Nie chroni również publicznych kont i wpisów przed oddanymi użytkownikami. + authorized_fetch_overridden_hint: Nie możesz zmienić tego ustawienia bo jest nadpisane przez zmienną środowiskową. + federation_authentication: Wymuszanie uwierzytelnienia dla federacji title: Ustawienia serwera site_uploads: delete: Usuń przesłany plik destroyed_msg: Pomyślnie usunięto przesłany plik! + software_updates: + critical_update: Krytyczna — zaktualizuj szybko + description: Zalecamy aktualizować instalacje Mastodona na bieżąco by korzystać z najnowszych poprawek i funkcji. Co więcej, czasami krytycznym jest aktualizować szybko by uniknąć problemów zw. z bezpieczeństwem. Z tego powodu, Mastodon co pół godziny sprawdza czy wydane zostały aktualizacje i powiadomi cię o tym zgodnie z twoimi ustawieniami powiadomień. + documentation_link: Dowiedz się więcej + release_notes: Informacje o wydaniu + title: Dostępne aktualizacje + type: Rodzaj + types: + major: Główne wydanie + minor: Wydanie pomniejsze + patch: Łatka — poprawki błędów i zmiany łatwe do zastosowania + version: Wersja statuses: account: Autor application: Aplikacja @@ -820,9 +856,24 @@ pl: suspend: "%{name} zawiesił(-a) konto %{target}" appeal_approved: Odwołanie appeal_pending: Odwołanie w toku + appeal_rejected: Odwołanie odrzucone system_checks: database_schema_check: message_html: Istnieją oczekujące migracje bazy danych. Uruchom je, aby upewnić się, że aplikacja działa tak, jak powinna + elasticsearch_health_red: + message_html: 'Klaster Elasticseach jest chory (status: czerwony); szukanie jest niedostępne' + elasticsearch_health_yellow: + message_html: 'Klaster Elasticseach jest chory (status: żółty); możliwe, że chcesz zbadać tego powód' + elasticsearch_index_mismatch: + message_html: Mapa indeksu Elasticsearch jest przestarzała. Uruchom tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Dokumentacja + message_html: Twój klaster Elasticsearch ma więcej niż jeden node, ale Mastodon nie jest odpowiednio ustawiony by ich używać. + elasticsearch_preset_single_node: + action: Dokumentacja + message_html: Twój klaster Elasticsearch ma tylko jeden node, więc ES_PRESET powinno mieć wartość single_node_cluster. + elasticsearch_reset_chewy: + message_html: Indeks główny Elasticsearch jest przestarzały przez zmianę ustawień. Uruchom tootctl search deploy --reset-chewy żeby go odświeżyć. elasticsearch_running_check: message_html: Nie można połączyć się z Elasticsearch. Sprawdź czy jest uruchomiony lub wyłącz wyszukiwanie pełnotekstowe elasticsearch_version_check: @@ -833,6 +884,18 @@ pl: message_html: Nie zdefiniowano żadnych reguł serwera. sidekiq_process_check: message_html: Brak uruchomionego procesu Sidekiq dla kolejki(-ek) %{value}. Sprawdź konfigurację Sidekiq + software_version_critical_check: + action: Pokaż dostępne aktualizacje + message_html: Dostępna krytyczna aktualizacja Mastodona, zaktualizuj jak tylko będzie to możliwe. + software_version_patch_check: + action: Pokaż dostępne aktualizacje + message_html: Dostępna aktualizacja poprawkowa Mastodona. + upload_check_privacy_error: + action: Kliknij tutaj, aby dowiedzieć się więcej + message_html: "Twój serwer internetowy jest nieprawidłowo skonfigurowany. Prywatność twoich użytkowników jest zagrożona." + upload_check_privacy_error_object_storage: + action: Kliknij tutaj, aby dowiedzieć się więcej + message_html: "Pamięć obiektu jest nieprawidłowa. Prywatność twoich użytkowników jest zagrożona." tags: review: Stan przeglądu updated_msg: Pomyślnie uaktualniono ustawienia hashtagów @@ -857,6 +920,7 @@ pl: other: Udostępnione przez %{count} osoby w ciągu ostatniego tygodnia title: Popularne linki usage_comparison: Udostępnione %{today} razy dzisiaj, w porównaniu z %{yesterday} wczoraj + not_allowed_to_trend: Wyłączona widoczność w popularnych only_allowed: Tylko dozwolone pending_review: Oczekuje na przegląd preview_card_providers: @@ -947,6 +1011,9 @@ pl: body: "%{target} odwołuje się od decyzji moderatora %{action_taken_by} z %{date}, czyli %{type}. Napisał:" next_steps: Możesz zaakceptować odwołanie o cofnięcie decyzji o moderacji lub je zignorować. subject: "%{username} odwołuje się od decyzji moderacyjnej na %{instance}" + new_critical_software_updates: + body: Zostały wydane nowe krytyczne wersje Mastodona, pewnie chcesz zaktualizować jak najszybciej! + subject: Krytyczne aktualizacje Mastodona dostępne dla %{instance}! new_pending_account: body: Poniżej znajdują się szczegóły dotycząće nowego konta. Możesz przyjąć lub odrzucić to podanie. subject: Nowe konto czeka na przegląd na %{instance} (%{username}) @@ -954,6 +1021,9 @@ pl: body: Użytkownik %{reporter} zgłosił(a) %{target} body_remote: Użytkownik instancji %{domain} zgłosił(a) %{target} subject: Nowe zgłoszenie na %{instance} (#%{id}) + new_software_updates: + body: Zostały wydane nowe wersje Mastodona, pewnie chcesz zaktualizować! + subject: Nowe wersje Mastodona dostępne dla %{instance}! new_trends: body: 'Następujące elementy potrzebują recenzji zanim będą mogły być wyświetlane publicznie:' new_trending_links: @@ -983,24 +1053,28 @@ pl: guide_link: https://pl.crowdin.com/project/mastodon guide_link_text: Każdy może wnieść swój wkład. sensitive_content: Wrażliwa zawartość - toot_layout: Wygląd wpisów application_mailer: notification_preferences: Zmień ustawienia e-maili salutation: "%{name}," settings: 'Zmień ustawienia powiadamiania: %{link}' + unsubscribe: Anuluj subskrypcję view: 'Zobacz:' view_profile: Wyświetl profil view_status: Wyświetl wpis applications: created: Pomyślnie utworzono aplikację destroyed: Pomyślnie usunięto aplikację + logout: Wyloguj się regenerate_token: Wygeneruj nowy token dostępu token_regenerated: Pomyślnie wygenerowano nowy token dostępu warning: Przechowuj te dane ostrożnie. Nie udostępniaj ich nikomu! your_token: Twój token dostępu auth: apply_for_account: Poproś o założenie konta - change_password: Hasło + captcha_confirmation: + help_html: Jeżeli masz problemy z rozwiązywaniem zadań CAPTCHA, możemy pomóc ci po kontakcie z nami pod adresem %{email}. + hint_html: Jeszcze jedno! Potrzebujemy potwierdzić twoje człowieczeństwo, żeby ograniczyć spam. Rozwiąż poniższą CAPTCHA-ę i naciśnij "Kontynuuj". + title: Kontrola bezpieczeństwa confirmations: wrong_email_hint: Jeśli ten adres e-mail nie jest poprawny, możesz go zmienić w ustawieniach konta. delete_account: Usunięcie konta @@ -1009,7 +1083,7 @@ pl: prefix_invited_by_user: "@%{name} zaprasza Cię do dołączenia na ten serwer Mastodona!" prefix_sign_up: Zarejestruj się na Mastodon już dziś! suffix: Mając konto, możesz obserwować ludzi, publikować wpisy i wymieniać się wiadomościami z użytkownikami innych serwerów Mastodona i nie tylko! - didnt_get_confirmation: Nie otrzymałeś(-aś) instrukcji weryfikacji? + didnt_get_confirmation: Nie otrzymano linku potwierdzającego? dont_have_your_security_key: Nie masz klucza bezpieczeństwa? forgot_password: Nie pamiętasz hasła? invalid_reset_password_token: Token do resetowania hasła jest nieprawidłowy lub utracił ważność. Spróbuj uzyskać nowy. @@ -1022,26 +1096,39 @@ pl: migrate_account_html: Jeżeli chcesz skonfigurować przekierowanie z obecnego konta na inne, możesz zrobić to tutaj. or_log_in_with: Lub zaloguj się z użyciem privacy_policy_agreement_html: Przeczytałem/am i akceptuję politykę prywatności + progress: + confirm: Potwierdź e-mail + details: Twoje dane + review: Nasza opinia + rules: Akceptuj zasady providers: cas: CAS saml: SAML register: Rejestracja registration_closed: "%{instance} nie przyjmuje nowych członków" - resend_confirmation: Ponownie prześlij instrukcje weryfikacji + resend_confirmation: Wyślij ponownie link potwierdzający reset_password: Zresetuj hasło rules: + accept: Zaakceptuj + back: Wróć + invited_by: 'Możesz dołączyć do %{domain} dzięki zaproszeniu, które otrzymano od:' preamble: Są one ustawione i wymuszone przez moderatorów %{domain}. + preamble_invited: Zanim przejdziesz dalej, rozważ zasady podstawowe ustalone przez moderatorów %{domain}. title: Kilka podstawowych zasad. + title_invited: Otrzymano zaproszenie. security: Bezpieczeństwo set_new_password: Ustaw nowe hasło setup: - email_below_hint_html: Jeżeli poniższy adres e-mail jest nieprawidłowy, możesz zmienić go tutaj i otrzymać nowy e-mail potwierdzający. - email_settings_hint_html: E-mail potwierdzający został wysłany na %{email}. Jeżeli adres e-mail nie jest prawidłowy, możesz zmienić go w ustawieniach konta. - title: Konfiguracja + email_below_hint_html: Sprawdź folder ze spamem lub poproś o inny link potwierdzający. Możesz poprawić swój adres e-mail, jeśli jest niepoprawny. + email_settings_hint_html: Kliknij link, który wysłaliśmy do Ciebie w celu zweryfikowania %{email}. Poczekamy tutaj. + link_not_received: Nie otrzymano linku? + new_confirmation_instructions_sent: Za kilka minut otrzymasz nowy e-mail z linkiem potwierdzającym! + title: Sprawdź swoją skrzynkę odbiorczą sign_in: preamble_html: Zaloguj się przy użyciu danych logowania %{domain}. Jeśli Twoje konto jest hostowane na innym serwerze, nie będziesz mógł się zalogować tutaj. title: Zaloguj się do %{domain} sign_up: + manual_review: Rejestracja na %{domain} przechodzi przez ręczne sprawdzanie przez naszych moderatorów. Aby pomóc nam usprawnić ten proces, napisz coś o sobie oraz dlaczego chcesz założyć konto na %{domain}. preamble: Z kontem na tym serwerze Mastodon będziesz mógł obserwować każdą inną osobę w sieci, niezależnie od miejsca przechowywania ich konta. title: Skonfigurujmy Twoje konto na %{domain}. status: @@ -1053,18 +1140,6 @@ pl: view_strikes: Zobacz dawne ostrzeżenia nałożone na twoje konto too_fast: Zbyt szybko przesłano formularz, spróbuj ponownie. use_security_key: Użyj klucza bezpieczeństwa - authorize_follow: - already_following: Już obserwujesz to konto - already_requested: Już wysłałeś(-aś) prośbę o możliwość obserwowania tego konta - error: Niestety, podczas sprawdzania zdalnego konta wystąpił błąd - follow: Obsewuj - follow_request: 'Wysłano prośbę o możliwość obserwowania:' - following: 'Pomyślnie! Od teraz obserwujesz:' - post_follow: - close: Ewentualnie, możesz po prostu zamknąć tę stronę. - return: Pokaż stronę użytkownika - web: Przejdź do sieci - title: Obserwuj %{acct} challenge: confirm: Kontynuuj hint_html: "Informacja: Nie będziemy prosić Cię o ponowne podanie hasła przez następną godzinę." @@ -1120,7 +1195,7 @@ pl: appeals: submit: Zgłoś odwołanie approve_appeal: Zatwierdź odwołanie - associated_report: Powiązany raport + associated_report: Powiązane zgłoszenie created_at: Data description_html: Są to działania podjęte przeciwko Twojemu kontu i ostrzeżenia wysłane do ciebie przez administrację %{instance}. recipient: Adresowane do @@ -1141,6 +1216,10 @@ pl: your_appeal_rejected: Twoje odwołanie zostało odrzucone domain_validator: invalid_domain: nie jest prawidłową nazwą domeny + edit_profile: + basic_information: Podstawowe informacje + hint_html: "Dostosuj to, co ludzie widzą na Twoim profilu publicznym i obok Twoich wpisów. Inne osoby są bardziej skłonne obserwować Cię i wchodzić z Tobą w interakcje, gdy masz wypełniony profil i zdjęcie profilowe." + other: Inne errors: '400': Wysłane zgłoszenie jest nieprawidłowe lub uszkodzone. '403': Nie masz uprawnień, aby wyświetlić tę stronę. @@ -1177,7 +1256,7 @@ pl: featured_tags: add_new: Dodaj nowy errors: - limit: Już przekroczyłeś(-aś) maksymalną liczbę wyróżnionych hashtagów + limit: Przekroczono maksymalną liczbę hasztagów hint_html: "Czym są wyróżnione hashtagi? Są one na stałe wyświetlane na Twoim profilu i pozwalają innym na przeglądanie Twoich wpisów używających tych hashtagów. Są doskonałym narzędziem do śledzenia kreatywnej twórczości czy długoterminowych projektów." filters: contexts: @@ -1227,8 +1306,6 @@ pl: index: hint: Ten filtr ma zastosowanie do wybierania poszczególnych wpisów niezależnie od pozostałych kryteriów. Możesz dodać więcej wpisów do tego filtra z interfejsu internetowego. title: Filtrowane posty - footer: - trending_now: Obecnie na czasie generic: all: Wszystkie all_items_on_page_selected_html: @@ -1241,7 +1318,9 @@ pl: many: Wszystkie %{count} elementy pasujące do Twojego wyszukiwania zostały wybrane. one: "%{count} element pasujący do Twojego wyszukiwania został wybrany." other: Wszystkie %{count} elementy pasujące do Twojego wyszukiwania zostały wybrane. + cancel: Anuluj changes_saved_msg: Ustawienia zapisane! + confirm: Zatwierdź copy: Kopiuj delete: Usuń deselect: Odznacz wszystkie @@ -1259,24 +1338,62 @@ pl: many: Coś jest wciąż nie tak! Przejrzyj %{count} poniższych błędów one: Coś jest wciąż nie tak! Przyjrzyj się poniższemu błędowi other: Coś jest wciąż nie tak! Przejrzyj poniższe błędy (%{count}) - html_validator: - invalid_markup: 'zawiera nieprawidłową składnię HTML: %{error}' imports: errors: + empty: Pusty plik CSV + incompatible_type: Niezgodny z wybranym typem importu invalid_csv_file: 'Nieprawidłowy plik CSV. Błąd: %{error}' over_rows_processing_limit: zawiera więcej niż %{count} wierszy + too_large: Plik jest zbyt duży + failures: Błędy + imported: Zaimportowano + mismatched_types_warning: Wygląda na to, że wybrałeś nieprawidłowy typ dla tego importu, sprawdź dwukrotnie. modes: merge: Połącz merge_long: Zachowaj obecne wpisy i dodaj nowe overwrite: Nadpisz overwrite_long: Zastąp obecne wpisy nowymi + overwrite_preambles: + blocking_html: Zamierzasz zastąpić swoją listę bloków maksymalnie %{total_items} kont z %{filename}. + bookmarks_html: Zamierzasz zastąpić swoje zakładki maksymalnie %{total_items} wpisami z %{filename}. + domain_blocking_html: Zamierzasz zastąpić swoją listę bloków domen maksymalnie %{total_items} domenami z %{filename}. + following_html: Zamierzasz zaobserwować maksymalnie %{total_items} kont z %{filename} i przestać obserwować kogokolwiek innego. + lists_html: Zamierzasz zastąpić swoje listy maksymalnie %{total_items} kontami z %{filename}. + muting_html: Zamierzasz zastąpić swoją wyciszonych maksymalnie %{total_items} kontami z %{filename}. + preambles: + blocking_html: Zamierzasz zablokować maksymalnie %{total_items} kont z %{filename}. + bookmarks_html: Zamierzasz dodać maksymalnie %{total_items} wpisów do twoich zakładek z %{filename}. + domain_blocking_html: Zamierzasz zablokować maksymalnie %{total_items} domen z %{filename}. + following_html: Zamierzasz zaobserwować maksymalnie %{total_items} kont z %{filename}. + lists_html: Zamierzasz dodać maksymalnie %{total_items} kont do twoich list z %{filename}. Jeżeli nie ma list, nowe zostaną utworzone. + muting_html: Zamierzasz wyciszyć maksymalnie %{total_items} kont z %{filename}. preface: Możesz zaimportować pewne dane (np. lista kont, które obserwujesz lub blokujesz) do swojego konta na tym serwerze, korzystając z danych wyeksportowanych z innego serwera. + recent_imports: Ostatnie importy + states: + finished: Zakończono + in_progress: W toku + scheduled: Zaplanowane + unconfirmed: Niepotwierdzone + status: Wpisy success: Twoje dane zostały załadowane i zostaną niebawem przetworzone + time_started: Rozpoczęto o + titles: + blocking: Importowanie zablokowanych kont + bookmarks: Importowanie zakładek + domain_blocking: Importowanie zablokowanych domen + following: Importowanie obserwowanych kont + lists: Importowanie list + muting: Importowanie wyciszonych kont + type: Typ importu + type_groups: + constructive: Obserwowani i zakładki + destructive: Zablokowani i wyciszeni użytkownicy types: blocking: Lista blokowanych bookmarks: Zakładki domain_blocking: Lista zablokowanych domen following: Lista obserwowanych + lists: Listy muting: Lista wyciszonych upload: Załaduj invites: @@ -1305,7 +1422,7 @@ pl: title: Zaproś użytkowników lists: errors: - limit: Przekroczyłeś maksymalną liczbę utworzonych list + limit: Przekroczono maksymalną liczbę utworzonych list login_activities: authentication_methods: otp: aplikacja weryfikacji dwuetapowej @@ -1317,6 +1434,21 @@ pl: failed_sign_in_html: Próba logowania zakończona niepowodzeniem przy pomocy %{method} z %{ip} (%{browser}) successful_sign_in_html: Pomyślne logowanie przy pomocy %{method} z %{ip} (%{browser}) title: Historia uwierzytelniania + mail_subscriptions: + unsubscribe: + action: Tak, wypisuję się + complete: Anulowano subskrypcję + confirmation_html: Czy na pewno chcesz wypisać się z otrzymywania %{type} z Mastodona na %{domain} na adres %{email}? Zawsze możesz zapisać się ponownie ze strony ustawień powiadomień mejlowych. + emails: + notification_emails: + favourite: powiadomień mejlowych o polubieniach + follow: powiadomień mejlowych o obserwujących + follow_request: mejli o prośbach o możliwość obserwowania + mention: powiadomień mejlowych o wspomnieniach + reblog: powiadomień mejlowych o podbiciach + resubscribe_html: W przypadku przypadkowego wypisania możesz zapisać się ponownie z ustawień powiadomień mejlowych. + success_html: Już nie będziesz otrzymywać %{type} z Mastodona na %{domain} na adres %{email}. + title: Anuluj subskrypcję media_attachments: validations: images_and_video: Nie możesz załączyć pliku wideo do wpisu, który zawiera już zdjęcia @@ -1364,7 +1496,7 @@ pl: notification_mailer: admin: report: - subject: "%{name} wysłał raport" + subject: "%{name} wysłał zgłoszenie" sign_up: subject: "%{name} zarejestrował(-a) się" favourite: @@ -1396,6 +1528,7 @@ pl: update: subject: "%{name} edytował/a wpis" notifications: + administration_emails: Administracyjne powiadomienia e-mail email_events: 'Powiadamiaj e-mailem o:' email_events_hint: 'Wybierz wydarzenia, o których chcesz otrzymywać powiadomienia:' other_settings: Inne ustawienia powiadomień @@ -1432,12 +1565,22 @@ pl: expired: To głosowanie już zakończyło się invalid_choice: Wybrana opcja głosowania nie istnieje over_character_limit: nie może zawierać więcej niż %{max} znaków + self_vote: Nie możesz głosować we własnych ankietach too_few_options: musi zawierać przynajmniej dwie opcje too_many_options: nie może zawierać więcej niż %{max} opcji preferences: other: Pozostałe posting_defaults: Domyślne ustawienia wpisów public_timelines: Publiczne osie czasu + privacy: + hint_html: "Dostosuj tryb odnajdowania twojego profilu i wpisów. Funkcje Mastodona mogą pomóc ci zwiększać twoją publiczność – przejrzyj te ustawienia i dostosuj je do swojego sposobu użytkowania." + privacy: Prywatność + privacy_hint_html: Ustaw, ile chcesz ujawniać innym. Ciekawe profile i programy często znajduje się przy przeglądaniu cudzych list obserwowanych i tego, z jakich programów zamieszczają, ale może wolisz to ukryć. + reach: Zasięg + reach_hint_html: Ustaw, czy chcesz dać się odkryć i zaobserwować. Chcesz, żeby twoje wpisy pojawiały się w zakładce "Odkrywaj"? Chcesz, żeby sugerowano twoje konto do obserwacji? Chcesz przyjmować nowych obserwujących automatycznie, czy aprobować ich ręcznie? + search: Wyszukiwanie + search_hint_html: Ustaw, w jakim zakresie będziesz znajdowalny(a). Chcesz pojawiać się w wynikach po twoich publicznych wpisach? Chcesz by twój profil dało się znaleźć spoza Mastodona? Pamiętaj, że nie da się zapewnić całkowitego wykluczenia wszystkich informacji publicznie dostępnych z wyszukiwarek. + title: Prywatność i zasięg privacy_policy: title: Polityka prywatności reactions: @@ -1450,6 +1593,7 @@ pl: confirm_remove_selected_followers: Czy na pewno chcesz usunąć wybranych obserwujących? confirm_remove_selected_follows: Czy na pewno chcesz usunąć zaznaczone obserwacje? dormant: Uśpione + follow_failure: Nie można obserwować niektórych wybranych kont. follow_selected_followers: Zacznij obserwować wybranych obserwujących followers: Obserwujący following: Obserwowani @@ -1489,6 +1633,7 @@ pl: electron: Electron firefox: Firefox generic: nieznana przeglądarka + huawei_browser: Przeglądarka Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Przeglądarka Nokia S40 Ovi @@ -1498,6 +1643,7 @@ pl: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Nieznana Przeglądarka weibo: Weibo current_session: Obecna sesja description: "%{browser} na %{platform}" @@ -1510,9 +1656,10 @@ pl: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: nieznana platforma + unknown_platform: Nieznana platforma windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1595,7 +1742,6 @@ pl: show_newer: Pokaż nowsze show_older: Pokaż starsze show_thread: Pokaż wątek - sign_in_to_participate: Zaloguj się, aby udzielić się w tej konwersacji title: '%{name}: "%{quote}"' visibilities: direct: Bezpośredni @@ -1641,8 +1787,6 @@ pl: min_reblogs: Utrzymuj posty wzmocnione więcej niż min_reblogs_hint: Nie usuwa żadnego z Twoich wpisów, które zostały wzmocnione więcej niż tyle razy. Pozostaw puste, aby usunąć posty bez względu na ich liczbę wzmocnień stream_entries: - pinned: Przypięty wpis - reblogged: podbił sensitive_content: Wrażliwa zawartość strikes: errors: @@ -1658,6 +1802,11 @@ pl: default: "%d. %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%-d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Przekroczono limit użycia usługi tłumaczeń dla całego serwera. + too_many_requests: Ostatnio było zbyt wiele zapytań do usługi tłumaczeniowej. two_factor_authentication: add: Dodaj disable: Wyłącz @@ -1737,13 +1886,18 @@ pl: title: Witaj na pokładzie, %{name}! users: follow_limit_reached: Nie możesz obserwować więcej niż %{limit} osób + go_to_sso_account_settings: Przejdź do ustawień konta dostawcy tożsamości invalid_otp_token: Kod uwierzytelniający jest niepoprawny otp_lost_help_html: Jeżeli utracisz dostęp do obu, możesz skontaktować się z %{email} seamless_external_login: Zalogowano z użyciem zewnętrznej usługi, więc ustawienia hasła i adresu e-mail nie są dostępne. signed_in_as: 'Zalogowano jako:' verification: - explanation_html: 'Możesz zweryfikować siebie jako właściciela stron, do których odnośniki znajdują się w metadanych. Aby to zrobić, strona musi zawierać odnośnik do Twojego profilu na Mastodonie. Odnośnik musi zawierać atrybut rel="me". Jego zawartość nie ma znaczenia. Przykład:' + extra_instructions_html: Wskazówka: link na twojej stronie może być niewidoczny. Istotną częścią, zapobiegającą podszywaniu na stronach z treściami dodawanymi przez użytkowników, jest rel="me". Zamiast tagu a możesz w nagłówek osadzić tag link. Oba jednak muszą być dostępne bez JavaScriptu. + here_is_how: Oto jak + hint_html: "Weryfikacja tożsamości na Mastodonie jest dla wszystkich, oparta na otwartych standardach, i darmowa. Potrzebna ci tylko osobista strona WWW po której inni cię rozpoznają – kiedy linkujesz do niej z twojego profilu, sprawdzamy czy ona linkuje doń z powrotem, i wskazujemy to wizualnie." + instructions_html: Skopiuj poniższy kod HTML i wklej go na swoją stronę. Potem dodaj link do twojej strony do jednego z wolnych pól na profilu z zakładki "Edytuj profil". verification: Weryfikacja + verified_links: Twoje zweryfikowane linki webauthn_credentials: add: Dodaj nowy klucz bezpieczeństwa create: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index a34d77f98e..114a486e82 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -91,6 +91,7 @@ pt-BR: moderation: active: Ativo all: Todos + disabled: Desativado pending: Pendente silenced: Limitado suspended: Suspendido @@ -124,8 +125,8 @@ pt-BR: removed_header_msg: A capa de %{username} foi removida resend_confirmation: already_confirmed: Este usuário já está confirmado - send: Reenviar o e-mail de confirmação - success: E-mail de confirmação enviado! + send: Reenviar link de confirmação + success: Link de confirmação enviado com sucesso! reset: Redefinir reset_password: Redefinir senha resubscribe: Reinscrever-se @@ -133,6 +134,7 @@ pt-BR: search: Buscar search_same_email_domain: Outros usuários com o mesmo domínio de e-mail search_same_ip: Outros usuários com o mesmo IP + security: Segurança security_measures: only_password: Apenas senha password_and_2fa: Senha e autenticação de dois fatores @@ -307,6 +309,7 @@ pt-BR: unpublish: Cancelar publicação unpublished_msg: Anúncio desfeito! updated_msg: Anúncio atualizado! + critical_update_pending: Atualização crítica pendente custom_emojis: assign_category: Atribuir categoria by_domain: Domínio @@ -380,6 +383,15 @@ pt-BR: undo: Bloquear federação com domínio domain_blocks: add_new: Adicionar novo bloqueio de domínio + confirm_suspension: + cancel: Cancelar + confirm: Suspender + permanent_action: Desfazer a suspensão não restaurará nenhum dado ou relacionamento. + preamble_html: Você está prestes a suspender %{domain} e seus subdomínios. + remove_all_data: Isto irá remover todo o conteúdo, mídia e dados de perfil para este domínio do seu servidor. + stop_communication: Seu servidor irá parar de se comunicar com esses servidores. + title: Confirmar bloqueio de domínio para %{domain} + undo_relationships: Isso desfará qualquer relação entre as contas desses servidores e as suas. created_msg: Domínio está sendo bloqueado destroyed_msg: Domínio desbloqueado domain: Domínio @@ -392,6 +404,7 @@ pt-BR: create: Criar bloqueio hint: O bloqueio de domínio não vai prevenir a criação de entradas de contas na base de dados, mas vai retroativamente e automaticamente aplicar métodos específicos de moderação nessas contas. severity: + desc_html: "Silenciar vai tornar as publicações da conta invisíveis para qualquer um que não estiver lhe seguindo. Suspender vai remover todo o conteúdo, mídia e dados de perfil da conta. Use Nenhum se você só quer rejeitar arquivos de mídia." noop: Nenhum silence: Limitar suspend: Banir @@ -426,6 +439,7 @@ pt-BR: resolve: Resolver domínio title: Nova entrada de lista negra de e-mail no_email_domain_block_selected: Nenhum bloco de domínio de e-mail foi alterado, pois nenhum foi selecionado + not_permitted: Não permitido resolved_dns_records_hint_html: O nome de domínio resolve os seguintes domínios MX, que são responsáveis finais por aceitar o e-mail. Bloquear um domínio MX bloqueará inscrições de qualquer endereço de e-mail que use o mesmo domínio MX, mesmo que o nome de domínio visível seja diferente. Cuidado para não bloquear os principais provedores de e-mail. resolved_through_html: Resolvido através de %{domain} title: Lista de negra de e-mail @@ -437,8 +451,10 @@ pt-BR: import: description_html: Você está prestes a importar uma lista de boqueio de domínio. Por favor, revise esta lista com muito cuidado, especialmente se você mesmo não criou esta lista. existing_relationships_warning: Existem relações de seguimento + private_comment_description_html: 'Para ajudá-lo a rastrear de onde vêm os blocos importados, serão criados blocos importados com o seguinte comentário privado: %{comment}' private_comment_template: Importado de %{source} em %{date} title: Importar bloqueio de domínios + invalid_domain_block: 'Um ou mais blocos de domínio foram ignorados devido ao(s) seguinte(s) erro(s): %{error}' new: title: Importar bloqueio de domínios no_file: Nenhum arquivo selecionado @@ -470,6 +486,7 @@ pt-BR: content_policies: comment: Nota interna description_html: Você pode definir políticas de conteúdo que serão aplicadas a todas as contas deste domínio e a qualquer um dos seus subdomínios. + limited_federation_mode_description_html: Você pode escolher se deseja permitir a associação com este domínio. policies: reject_media: Rejeitar mídia reject_reports: Rejeitar denúncias @@ -574,17 +591,22 @@ pt-BR: other_description_html: Veja mais opções para controlar o comportamento da conta e personalizar a comunicação com a conta denunciada. resolve_description_html: Nenhuma ação será tomada contra a conta denunciada, nenhuma violação será guardada e a denúncia será encerrada. silence_description_html: A conta ficará visível apenas para aqueles que já a seguem ou que a procuram manualmente, limitando severamente seu alcance. Pode ser revertido a qualquer momento. Fecha todas as denúncias desta conta. + suspend_description_html: A conta e todo o seu conteúdo ficará inacessível e, eventualmente, excluído e interagir com ela será impossível. Reversível dentro de 30 dias. Encerra todas as denúncias contra esta conta. actions_description_html: Decida que medidas tomar para resolver esta denúncia. Se você decidir punir a conta denunciada, ela receberá uma notificação por e-mail, exceto quando for selecionada a categoria spam for selecionada. + actions_description_remote_html: Decida quais medidas tomará para resolver esta denúncia. Isso só afetará como seu servidor se comunica com esta conta remota e manipula seu conteúdo. add_to_report: Adicionar mais à denúncia are_you_sure: Você tem certeza? assign_to_self: Atribuir para si assigned: Moderador responsável by_target_domain: Domínio da conta denunciada + cancel: Cancelar category: Categoria category_description_html: O motivo pelo qual esta conta e/ou conteúdo foi denunciado será citado na comunicação com a conta denunciada comment: none: Nenhum comment_description_html: 'Para fornecer mais informações, %{name} escreveu:' + confirm: Confirmar + confirm_action: Confirmar a moderação de @%{acct} created_at: Denunciado delete_and_resolve: Excluir publicações forwarded: Encaminhados @@ -601,6 +623,7 @@ pt-BR: placeholder: Descreva quais ações foram tomadas ou quaisquer outras atualizações relacionadas... title: Notas notes_description_html: Visualize e deixe anotações para outros moderadores e para você mesmo no futuro + processed_msg: 'Relatório #%{id} processado com sucesso' quick_actions_description_html: 'Tome uma ação rápida ou role para baixo para ver o conteúdo denunciado:' remote_user_placeholder: o usuário remoto de %{instance} reopen: Reabrir denúncia @@ -619,11 +642,18 @@ pt-BR: mark_as_sensitive_html: 'Você está prestes a marcar algumas das publicações de @%{acct} como sensíveis. Isso irá:' silence_html: 'Você está prestes a limitar a conta de @%{acct}. Isso irá:' suspend_html: 'Você está prestes a suspender a conta de @%{acct}. Isso irá:' + actions: + delete_html: Remover as publicações ofensivas + mark_as_sensitive_html: Marcar a mídia de posts ofensivos como sensível + silence_html: Limitar firmemente o alcance de @%{acct}, tornando seus perfis e conteúdos apenas visíveis para pessoas que já os estão seguindo ou olhando manualmente o perfil + suspend_html: Suspender @%{acct}, tornando seu perfil e conteúdo inacessíveis, impossibilitando a interação close_report: 'Marcar denúncia #%{id} como resolvida' close_reports_html: Marcar todas as denúncias contra @%{acct} como resolvidas delete_data_html: Exclua o perfil e o conteúdo de @%{acct} daqui a 30 dias, a menos que a suspensão seja desfeita nesse meio tempo preview_preamble_html: "@%{acct} receberá um aviso com o seguinte conteúdo:" + record_strike_html: Registre uma ação contra @%{acct} para te ajudar em futuras violações desta conta send_email_html: Enviar @%{acct} um e-mail de aviso + warning_placeholder: Argumentos adicionais para a ação de moderação. target_origin: Origem da conta denunciada title: Denúncias unassign: Desatribuir @@ -711,6 +741,9 @@ pt-BR: branding: preamble: A marca do seu servidor o diferencia de outros servidores na rede. Essa informação pode ser exibida em vários ambientes, como a interface web do Mastodon, aplicativos nativos, pré-visualizações de links em outros sites, aplicativos de mensagens, etc. Por isso, é melhor manter essa informação clara, curta e concisa. title: Marca + captcha_enabled: + desc_html: Isso é baseado em scripts externos de hCaptcha, o que pode ser uma preocupação de segurança e privacidade. Além disso, isso pode tornar o processo de registro significativamente menos acessível para algumas pessoas (especialmente deficientes). Por estas razões, favor considerar medidas alternativas como o registro baseado em aprovação ou em convite. + title: Exigir que novos usuários resolvam um CAPTCHA para confirmar sua conta content_retention: preamble: Controlar como o conteúdo gerado pelo usuário é armazenado no Mastodon. title: Retenção de conteúdo @@ -738,10 +771,27 @@ pt-BR: approved: Aprovação necessária para criar conta none: Ninguém pode criar conta open: Qualquer um pode criar conta - title: Configurações do Servidor + security: + authorized_fetch: Exigir autenticação por parte de servidores federados + authorized_fetch_hint: Exigir autenticação de servidores federados permite uma aplicação mais rigorosa de bloqueios tanto de nível de usuário como de servidor. No entanto, isso traz como custo uma penalidade no desempenho, reduz o alcance das suas respostas e pode introduzir problemas de compatibilidade com alguns serviços federados. Além disso, não impedirá atores dedicados de consultar suas publicações e contas públicas. + authorized_fetch_overridden_hint: Você atualmente não pode alterar esta configuração porque ela é sobreposta por uma variável de ambiente. + federation_authentication: Aplicação de autenticação da Federação + title: Configurações do servidor site_uploads: delete: Excluir arquivo enviado destroyed_msg: Upload do site excluído com sucesso! + software_updates: + critical_update: Crítico — por favor, atualize rapidamente + description: Recomenda-se manter a instalação do Mastodon atualizada para se beneficiar das funcionalidades e correções mais recentes. Além disso, por vezes é fundamental atualizar Mastodon em tempo hábil para evitar problemas de segurança. Por estes motivos, o Mastodon verifica atualizações a cada 30 minutos e lhe notificará de acordo com suas preferências de notificação por e-mail. + documentation_link: Saiba mais + release_notes: Notas de lançamento + title: Atualizações disponíveis + type: Tipo + types: + major: Versão maior + minor: Versão menor + patch: Versão de atualização — correções de erros e alterações de fácil aplicação + version: Versão statuses: account: Autor application: Aplicativo @@ -778,9 +828,24 @@ pt-BR: suspend: "%{name} suspendeu a conta de %{target}" appeal_approved: Revisado appeal_pending: Revisão pendente + appeal_rejected: Revisão rejeitada system_checks: database_schema_check: message_html: Existem migrações de banco de dados pendentes. Execute-as para garantir que o aplicativo se comporte como esperado + elasticsearch_health_red: + message_html: O agrupamento de Elasticsearch não é saudável (estado vermelho); os recursos de pesquisa não estão disponíveis + elasticsearch_health_yellow: + message_html: O agrupamento de Elasticsearch não é saudável (estado amarelo); talvez você queira investigar o motivo + elasticsearch_index_mismatch: + message_html: Os mapeamentos de índice do Elasticsearch estão desatualizados. Por favor, execute tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ver documentação + message_html: Seu agrupamento de Elasticsearch tem mais de um nó, mas o Mastodon não está configurado para usá-los. + elasticsearch_preset_single_node: + action: Ver documentação + message_html: Seu agrupamento de Elasticsearch tem apenas um nó, ES_PRESET deve ser definido como single_node_cluster. + elasticsearch_reset_chewy: + message_html: Seu índice do sistema Elasticsearch está desatualizado devido a uma alteração de configuração. Por favor, execute tootctl search deploy --reset-chewy para atualizá-lo. elasticsearch_running_check: message_html: Não foi possível conectar ao Elasticsearch. Verifique se ele está em execução ou desative a pesquisa de texto completo elasticsearch_version_check: @@ -791,6 +856,18 @@ pt-BR: message_html: Você não definiu nenhuma regra de servidor. sidekiq_process_check: message_html: Nenhum processo Sidekiq rodando para a(s) fila(s) %{value}. Por favor, revise a sua configuração para Sidekiq + software_version_critical_check: + action: Ver atualizações disponíveis + message_html: Uma atualização crítica do Mastodon está disponível. Por favor, atualize o mais rápido possível. + software_version_patch_check: + action: Ver atualizações disponíveis + message_html: Uma atualização do Mastodon para correções está disponível. + upload_check_privacy_error: + action: Confira aqui para mais informações + message_html: "Seu servidor está mal configurado. A privacidade de seus usuários está em risco." + upload_check_privacy_error_object_storage: + action: Confira aqui para mais informações + message_html: "Seu armazenamento de objetos está mal configurado. A privacidade de seus usuários está em risco." tags: review: Status da revisão updated_msg: Configurações de hashtag atualizadas @@ -813,6 +890,7 @@ pt-BR: other: Compartilhado por %{count} pessoas na última semana title: Em alta no momento usage_comparison: Compartilhado %{today} vezes hoje, em comparação com %{yesterday} de ontem + not_allowed_to_trend: Não tem permissão para criar tendências only_allowed: Somente permitido pending_review: Revisão pendente preview_card_providers: @@ -897,6 +975,9 @@ pt-BR: body: "%{target} está solicitando uma revisão da decisão da moderação por %{action_taken_by} em %{date}, que era %{type}. Ele escreveu:" next_steps: Você pode aprovar a revisão para desfazer a decisão da moderação ou ignorá-la. subject: "%{username} está solicitando uma revisão da decisão da moderação em %{instance}" + new_critical_software_updates: + body: Novas versões críticas do Mastodon foram lançadas. Talvez queira atualizar o mais breve possível! + subject: Atualizações críticas do Mastodon estão disponíveis para %{instance}! new_pending_account: body: Os detalhes da nova conta estão abaixo. Você pode aprovar ou vetar. subject: Nova conta para revisão em %{instance} (%{username}) @@ -904,6 +985,9 @@ pt-BR: body: "%{reporter} denunciou %{target}" body_remote: Alguém de %{domain} denunciou %{target} subject: Nova denúncia sobre %{instance} (#%{id}) + new_software_updates: + body: Novas versões do Mastodon foram lançadas, talvez você queira atualizar! + subject: Novas versões do Mastodon estão disponíveis para %{instance}! new_trends: body: 'Os seguintes itens precisam de uma análise antes que possam ser exibidos publicamente:' new_trending_links: @@ -933,24 +1017,28 @@ pt-BR: guide_link: https://br.crowdin.com/project/mastodon guide_link_text: Todos podem contribuir. sensitive_content: Conteúdo sensível - toot_layout: Formato da publicação application_mailer: notification_preferences: Alterar preferências de e-mail salutation: "%{name}," settings: 'Alterar e-mail de preferência: %{link}' + unsubscribe: Desinscrever view: 'Ver:' view_profile: Ver perfil view_status: Ver publicação applications: created: Aplicativo criado com sucesso destroyed: Aplicativo excluído com sucesso + logout: Sair regenerate_token: Gerar código de acesso token_regenerated: Código de acesso gerado warning: Tenha cuidado com estes dados. Nunca compartilhe com alguém! your_token: Seu código de acesso auth: apply_for_account: Solicitar uma conta - change_password: Senha + captcha_confirmation: + help_html: Se você tiver problemas para resolver o CAPTCHA, entre em contato conosco através do %{email} e poderemos ajudá-lo. + hint_html: Só mais uma coisa! Precisamos confirmar que você é um humano (isso é para que possamos evitar o spam!). Resolva o CAPTCHA abaixo e clique em "Continuar". + title: Verificação de segurança confirmations: wrong_email_hint: Se esse endereço de e-mail não estiver correto, você pode alterá-lo nas configurações da conta. delete_account: Excluir conta @@ -959,7 +1047,7 @@ pt-BR: prefix_invited_by_user: "@%{name} convidou você para entrar neste servidor Mastodon!" prefix_sign_up: Crie uma conta no Mastodon hoje! suffix: Com uma conta, você poderá seguir pessoas, publicar atualizações, trocar mensagens com usuários de qualquer servidor Mastodon e muito mais! - didnt_get_confirmation: Não recebeu instruções de confirmação? + didnt_get_confirmation: Não recebeu um e-mail de confirmação? dont_have_your_security_key: Não está com a sua chave de segurança? forgot_password: Esqueceu a sua senha? invalid_reset_password_token: Código de alteração de senha é inválido ou expirou. Solicite um novo. @@ -972,26 +1060,39 @@ pt-BR: migrate_account_html: Se você quer redirecionar essa conta para uma outra você pode configurar isso aqui. or_log_in_with: Ou entre com privacy_policy_agreement_html: Eu li e concordo com a política de privacidade + progress: + confirm: Confirmar e-mail + details: Suas informações + review: Nossa avaliação + rules: Aceitar regras providers: cas: CAS saml: SAML register: Criar conta registration_closed: "%{instance} não está aceitando novos membros" - resend_confirmation: Reenviar instruções de confirmação + resend_confirmation: Reenviar link de confirmação reset_password: Redefinir senha rules: + accept: Aceitar + back: Voltar + invited_by: 'Você pode juntar-se a %{domain} graças ao convite que recebeu de:' preamble: Estes são definidos e aplicados pelos moderadores de %{domain}. + preamble_invited: Antes de prosseguir, considere as regras de base definidas pelos moderadores de %{domain}. title: Algumas regras básicas. + title_invited: Você recebeu convite. security: Segurança set_new_password: Definir uma nova senha setup: - email_below_hint_html: Se o endereço de e-mail abaixo não for seu, você pode alterá-lo aqui e receber um novo e-mail de confirmação. - email_settings_hint_html: O e-mail de confirmação foi enviado para %{email}. Se esse endereço de e-mail não estiver correto, você pode alterá-lo nas configurações da conta. - title: Configurações + email_below_hint_html: Verifique a sua pasta de spam, ou solicite outro link de confirmação. Você pode corrigir seu endereço de e-mail se estiver errado. + email_settings_hint_html: Clique no link que te enviamos para verificar %{email}. Esperaremos aqui. + link_not_received: Não recebeu um link? + new_confirmation_instructions_sent: Você receberá um novo e-mail com o link de confirmação em alguns minutos! + title: Verifique sua caixa de entrada sign_in: preamble_html: Entre com suas credenciais de domínios ( %{domain} ) . Se sua conta estiver hospedada em um servidor diferente, você não deve conseguir acessar este conteúdo. title: Entrar em %{domain} sign_up: + manual_review: Inscrições no %{domain} passam pela revisão manual dos nossos moderadores. Para nos ajudar a processar o seu cadastro, escreva um pouco sobre você e por que você quer uma conta no %{domain}. preamble: Com uma conta neste servidor Mastodon, você poderá seguir qualquer outra pessoa na rede, independentemente de onde sua conta esteja hospedada. title: Então vamos lá criar uma conta em %{domain}. status: @@ -1003,18 +1104,6 @@ pt-BR: view_strikes: Veja os avisos anteriores em relação à sua conta too_fast: O formulário foi enviado muito rapidamente, tente novamente. use_security_key: Usar chave de segurança - authorize_follow: - already_following: Você já segue - already_requested: Você já enviou uma solicitação para seguir esta conta - error: Infelizmente, ocorreu um erro ao buscar a conta remota - follow: Seguir - follow_request: 'Você mandou solicitação para seguir para:' - following: 'Sucesso! Agora você está seguindo:' - post_follow: - close: Ou você pode simplesmente fechar esta janela. - return: Mostrar o perfil do usuário - web: Voltar à página inicial - title: Seguir %{acct} challenge: confirm: Continuar hint_html: "Dica: Não pediremos novamente sua senha pela próxima hora." @@ -1091,6 +1180,10 @@ pt-BR: your_appeal_rejected: Sua revisão foi rejeitada domain_validator: invalid_domain: não é um nome de domínio válido + edit_profile: + basic_information: Informações básicas + hint_html: "Personalize o que as pessoas veem no seu perfil público e ao lado de suas publicações. É mais provável que outras pessoas o sigam de volta e interajam com você quando você tiver um perfil preenchido e uma foto de perfil." + other: Outro errors: '400': A solicitação enviada é inválida ou incorreta. '403': Você não tem permissão para ver esta página. @@ -1127,7 +1220,7 @@ pt-BR: featured_tags: add_new: Adicionar hashtag errors: - limit: Você atingiu o limite de hashtags em destaque + limit: Você já destacou o número máximo de hashtags hint_html: "O que são hashtags em destaque? Elas são exibidas no seu perfil público e permitem que as pessoas acessem suas publicações públicos que contenham especificamente essas hashtags. São uma excelente ferramenta para acompanhar os trabalhos criativos ou os projetos de longo prazo." filters: contexts: @@ -1171,8 +1264,6 @@ pt-BR: index: hint: Este filtro se aplica a publicações individuais, independentemente de outros critérios. Você pode adicionar mais postagens a este filtro a partir da interface web. title: Publicações filtradas - footer: - trending_now: Em alta no momento generic: all: Tudo all_items_on_page_selected_html: @@ -1181,7 +1272,9 @@ pt-BR: all_matching_items_selected_html: one: "%{count} item correspondente à sua pesquisa está selecionado." other: Todos os %{count} itens correspondentes à sua pesquisa estão selecionados. + cancel: Cancelar changes_saved_msg: Alterações salvas! + confirm: Confirmar copy: Copiar delete: Excluir deselect: Desmarcar todos @@ -1195,24 +1288,62 @@ pt-BR: validation_errors: one: Algo não está certo! Analise o erro abaixo other: Algo não está certo! Analise os %{count} erros abaixo - html_validator: - invalid_markup: 'contém HTML inválido: %{error}' imports: errors: + empty: Arquivo CSV vazio + incompatible_type: Incompatível com o tipo de importação selecionado invalid_csv_file: 'Arquivo CSV inválido. Erro: %{error}' over_rows_processing_limit: contém mais de %{count} linhas + too_large: O arquivo é muito grande + failures: Falhas + imported: Importado + mismatched_types_warning: Parece que você selecionou o tipo errado para esta importação, por favor verifique novamente. modes: merge: Juntar merge_long: Manter os registros existentes e adicionar novos overwrite: Sobrescrever overwrite_long: Substituir os registros atuais com os novos + overwrite_preambles: + blocking_html: Você está prestes a substituir sua lista de bloqueios com até contas%{total_items} de %{filename}. + bookmarks_html: Você está prestes a substituir seus favoritos por até %{total_items} posts de %{filename}. + domain_blocking_html: Você está prestes a substituir sua lista de bloqueio de domínio com até domínios%{total_items} de %{filename}. + following_html: Você está prestes a seguir até %{total_items} contas de %{filename} e parar de seguir todos os outros. + lists_html: Você está prestes a substituir sua lista pelo conteúdo de %{filename}. Até %{total_items} contas serão adicionadas a novas listas. + muting_html: Você está prestes a substituir sua lista de contas silenciadas com até %{total_items} contas de %{filename}. + preambles: + blocking_html: Você está prestes a bloquear até %{total_items} contas de %{filename}. + bookmarks_html: Você está prestes a adicionar até %{total_items} posts de %{filename} para seus favoritos. + domain_blocking_html: Você está prestes a bloquear até %{total_items} domínios de %{filename}. + following_html: Você está prestes a seguir até %{total_items} contas de %{filename}. + lists_html: Você está prestes a adicionar até %{total_items} contas a partir de %{filename} para suas listas. Novas listas serão criadas se não houver uma para a qual adicionar. + muting_html: Você está prestes a silenciar até contas%{total_items} de %{filename}. preface: Você pode importar dados que você exportou de outro servidor, como a lista de pessoas que você segue ou bloqueou. + recent_imports: Importações recentes + states: + finished: Finalizado + in_progress: Em progresso + scheduled: Agendado + unconfirmed: Não confirmado + status: Estado success: Seus dados foram enviados e serão processados em instantes + time_started: Iniciado em + titles: + blocking: Importando contas bloqueadas + bookmarks: Importando favoritos + domain_blocking: Importando contas bloqueadas + following: Importando contas seguidas + lists: Importando listas + muting: Importando contas silenciadas + type: Tipo de importação + type_groups: + constructive: Seguidores e Favoritos + destructive: Bloqueios e silenciamentos types: blocking: Lista de bloqueio bookmarks: Marcadores domain_blocking: Lista de domínios bloqueados following: Pessoas que você segue + lists: Listas muting: Lista de silenciados upload: Enviar invites: @@ -1239,7 +1370,7 @@ pt-BR: title: Convidar pessoas lists: errors: - limit: Você atingiu o máximo de listas + limit: Você atingiu o número máximo de listas login_activities: authentication_methods: otp: autenticação de dois fatores @@ -1251,6 +1382,21 @@ pt-BR: failed_sign_in_html: Falha na tentativa de login com %{method} de %{ip} (%{browser}) successful_sign_in_html: Login bem-sucedido com %{method} de %{ip} (%{browser}) title: Histórico de autenticação + mail_subscriptions: + unsubscribe: + action: Sim, cancelar subscrição + complete: Desinscrito + confirmation_html: Tem certeza que deseja cancelar a inscrição de receber %{type} para Mastodon em %{domain} para o seu e-mail em %{email}? Você sempre pode se inscrever novamente de suas configurações de notificação de e-mail. + emails: + notification_emails: + favourite: e-mails de notificações de favoritos + follow: e-mails de novos seguidores + follow_request: e-mails de seguidores pendentes + mention: e-mails de notificação de menções + reblog: e-mails de notificação de impulsos + resubscribe_html: Se você cancelou sua inscrição por engano, você pode se inscrever novamente em suas configurações de notificações por e-mail. + success_html: Você não receberá mais %{type} do Mastodon em %{domain} para o seu e-mail %{email}. + title: Cancelar inscrição media_attachments: validations: images_and_video: Não foi possível anexar um vídeo a uma publicação que já contém imagens @@ -1330,6 +1476,7 @@ pt-BR: update: subject: "%{name} editou uma publicação" notifications: + administration_emails: Notificações por e-mail sobre administração email_events: Eventos para notificações por e-mail email_events_hint: 'Selecione os eventos que deseja receber notificações:' other_settings: Outras opções para notificações @@ -1366,12 +1513,22 @@ pt-BR: expired: A enquete já terminou invalid_choice: Opção inválida over_character_limit: não pode ter mais que %{max} caracteres em cada + self_vote: Você não pode votar nas suas próprias enquetes too_few_options: deve ter mais que um item too_many_options: não pode ter mais que %{max} itens preferences: other: Outro posting_defaults: Padrões de publicação public_timelines: Linhas públicas + privacy: + hint_html: "Personalize como você quer que seu perfil e suas publicações sejam encontrados. Uma variedade de funcionalidades no Mastodon pode ajudar a alcançar um público mais amplo quando habilitado. Reserve um momento para revisar estas configurações para garantir que atendem ao seu caso de uso." + privacy: Privacidade + privacy_hint_html: Controle o quanto você deseja revelar para o benefício de outros. As pessoas descobrem perfis interessantes e aplicativos legais navegando pelos seguidores de outras pessoas e vendo de quais aplicativos eles publicam, mas você pode preferir manter isso oculto. + reach: Alcance + reach_hint_html: Controle se você quer ser descoberto e seguido por novas pessoas. Deseja que suas publicações apareçam na tela Explorar? Você quer que outras pessoas lhe vejam nas recomendações sobre quem seguir? Você quer aceitar todos os novos seguidores automaticamente ou ter controle granular sobre cada um? + search: Buscar + search_hint_html: Controle como você deseja que lhe encontrem. Quer que as pessoas lhe encontrem pelo que você publicou abertamente? Quer que pessoas fora do Mastodon encontrem seu perfil quando pesquisarem na web? Por favor, tenha em mente que a exclusão total de todos os motores de busca não pode ser garantida para informações públicas. + title: Privacidade e alcance privacy_policy: title: Política de Privacidade reactions: @@ -1384,6 +1541,7 @@ pt-BR: confirm_remove_selected_followers: Tem certeza que deseja remover os seguidores selecionados? confirm_remove_selected_follows: Tem certeza que deseja remover os grupos seguidos selecionados? dormant: Inativo + follow_failure: Não foi possível seguir algumas das contas selecionadas. follow_selected_followers: Seguir os seguidores selecionados followers: Seguidores following: Seguindo @@ -1423,6 +1581,7 @@ pt-BR: electron: Electron firefox: Firefox generic: Navegador desconhecido + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Navegador Nokia S40 Ovi @@ -1432,6 +1591,7 @@ pt-BR: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Navegador desconhecido weibo: Weibo current_session: Sessão atual description: "%{browser} em %{platform}" @@ -1444,9 +1604,10 @@ pt-BR: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: MacOS - other: Plataforma desconhecida + unknown_platform: Plataforma desconhecida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1517,7 +1678,6 @@ pt-BR: show_newer: Mostrar mais recentes show_older: Mostrar mais antigos show_thread: Mostrar conversa - sign_in_to_participate: Entre para participar dessa conversa title: '%{name}: "%{quote}"' visibilities: direct: Direto @@ -1559,12 +1719,10 @@ pt-BR: '7889238': 3 meses min_age_label: Validade min_favs: Manter publicações favoritadas por ao menos - min_favs_hint: Não exclui publicações que receberam pelo menos esta quantidade de favoritos. Deixe em branco para excluir publicações independentemente da quantidade de favoritos + min_favs_hint: Não exclui suas publicações que receberam pelo menos esta quantidade de favoritos. Deixe em branco para excluir publicações independentemente da quantidade de favoritos min_reblogs: Manter publicações impulsionadas por ao menos min_reblogs_hint: Não exclui publicações que receberam pelo menos esta quantidade de impulsos. Deixe em branco para excluir publicações independentemente da quantidade de impulsos stream_entries: - pinned: Toot fixado - reblogged: deu boost sensitive_content: Conteúdo sensível strikes: errors: @@ -1580,6 +1738,11 @@ pt-BR: default: "%H:%M em %d de %b de %Y" month: "%b de %Y" time: "%H:%M" + with_time_zone: "%d de %b de %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: A cota de uso do servidor para o serviço de tradução foi excedida. + too_many_requests: Recentemente há muitas solicitações para o serviço de tradução. two_factor_authentication: add: Adicionar disable: Desativar autenticação de dois fatores @@ -1659,13 +1822,18 @@ pt-BR: title: Boas vindas, %{name}! users: follow_limit_reached: Você não pode seguir mais de %{limit} pessoas + go_to_sso_account_settings: Vá para as configurações de conta do seu provedor de identidade invalid_otp_token: Código de dois fatores inválido otp_lost_help_html: Se você perder o acesso à ambos, você pode entrar em contato com %{email} seamless_external_login: Você entrou usando um serviço externo, então configurações de e-mail e senha não estão disponíveis. signed_in_as: 'Entrou como:' verification: - explanation_html: 'Você pode verificar os links nos metadados do seu perfil. Para isso, o site citado deve conter um link de volta para o seu perfil do Mastodon. O link de volta deve conter um atributo rel="me". O conteúdo ou texto do link não importa. Aqui está um exemplo:' + extra_instructions_html: Dica: O link do seu site não precisa ser visível. O importante é a parte rel="me", que impede a personificação em sites com conteúdo gerado pelo usuário. Você pode até usar uma tag link no cabeçalho da página ao invés de uma tag a, mas é importante que o HTML esteja acessível sem executar JavaScript. + here_is_how: Veja como + hint_html: "Verificar sua identidade no Mastodon é para todos. Utilizando padrões abertos da web e sem custo, agora e para sempre. Tudo o que você precisa é de um site pessoal pelo qual as pessoas o reconheçam. Você faz um link para este site do seu perfil, e nós verificamos se o site faz links de volta para o seu perfil. Se tudo estiver correto, apresentamos um indicador visual ao lado do link no seu perfil." + instructions_html: Copie o código abaixo e cole no HTML do seu site. Em seguida, adicione o endereço do seu site em um dos campos extras em seu perfil, na aba "Editar perfil", e salve as alterações. verification: Verificação + verified_links: Seus links verificados webauthn_credentials: add: Adicionar nova chave de segurança create: diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index fb296988f6..f4c363324c 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -91,6 +91,7 @@ pt-PT: moderation: active: Activo all: Todos + disabled: Desativado pending: Pendente silenced: Limitadas suspended: Supensos @@ -124,8 +125,8 @@ pt-PT: removed_header_msg: Imagem de cabeçalho de %{username} removida resend_confirmation: already_confirmed: Este utilizador já está confirmado - send: Reenviar um e-mail de confirmação - success: E-mail de confirmação enviado! + send: Reenviar link de confirmação + success: Link de confirmação enviado com sucesso! reset: Reiniciar reset_password: Criar nova palavra-passe resubscribe: Reinscrever @@ -133,6 +134,7 @@ pt-PT: search: Pesquisar search_same_email_domain: Outros utilizadores com o mesmo domínio de correio electrónico search_same_ip: Outros utilizadores com o mesmo IP + security: Segurança security_measures: only_password: Apenas palavra-passe password_and_2fa: Palavra-passe e 2FA @@ -307,6 +309,7 @@ pt-PT: unpublish: Anular publicação unpublished_msg: Comunicado correctamente retirado de publicação! updated_msg: Comunicado correctamente actualizado! + critical_update_pending: Atualização crítica pendente custom_emojis: assign_category: Atribuir categoria by_domain: Domínio @@ -364,7 +367,7 @@ pt-PT: sources: Origem de inscrições space: Utilização do espaço title: Painel de controlo - top_languages: Principais línguas activas + top_languages: Principais idiomas activos top_servers: Servidores mais activos website: Página na teia disputes: @@ -380,6 +383,15 @@ pt-PT: undo: Revogar federação com o domínio domain_blocks: add_new: Adicionar novo bloqueio de domínio + confirm_suspension: + cancel: Cancelar + confirm: Suspender + permanent_action: Desfazer a suspensão não restaurará nenhum dado ou relacionamento. + preamble_html: Está prestes a suspender %{domain} e seus subdomínios. + remove_all_data: Isto irá remover todo o conteúdo, media e dados de perfil para este domínio do seu servidor. + stop_communication: O seu servidor irá parar de comunicar com esses servidores. + title: Confirmar o bloqueio de domínio para %{domain} + undo_relationships: Isto irá desfazer qualquer relação entre as contas desses servidores e as suas. created_msg: Bloqueio do domínio está a ser processado destroyed_msg: Retirado o bloqueio de domínio domain: Domínio @@ -427,6 +439,7 @@ pt-PT: resolve: Domínio de resolução title: Novo bloqueio de domínio de e-mail no_email_domain_block_selected: Nenhum bloqueio de domínio de e-mail foi alterado pois nenhum foi selecionado + not_permitted: Não permitido resolved_dns_records_hint_html: O nome de domínio resolve para os seguintes domínios MX, que são, em última análise, responsáveis por aceitar o e-mail. Bloquear um domínio MX irá bloquear as inscrições de qualquer endereço de e-mail que use o mesmo domínio MX, mesmo quando o nome de domínio visível é diferente. Cuidado para não bloquear os principais provedores de e-mail. resolved_through_html: Resolvido através de %{domain} title: Domínios de e-mail bloqueados @@ -447,7 +460,7 @@ pt-PT: no_file: Nenhum ficheiro selecionado follow_recommendations: description_html: "Recomendações de quem seguir ajudam novos utilizadores a encontrar conteúdo interessante rapidamente.. Quando um utilizador não interage com outros o suficiente para formar recomendações personalizadas, estas contas são recomendadas. Elas são recalculadas diariamente a partir de uma mistura de contas com mais atividade recente e maior número de seguidores locais para um determinado idioma." - language: Para a língua + language: Para o idioma status: Estado suppress: Suprimir recomendação de contas a seguir suppressed: Suprimida @@ -473,6 +486,7 @@ pt-PT: content_policies: comment: Nota interna description_html: Pode definir políticas de conteúdo que serão aplicadas a todas as contas deste domínio e a qualquer um dos seus subdomínios. + limited_federation_mode_description_html: Pode escolher se deseja permitir a federação com este domínio. policies: reject_media: Rejeitar media reject_reports: Rejeitar denúncias @@ -486,7 +500,7 @@ pt-PT: instance_accounts_measure: contas armazenadas instance_followers_measure: nossos seguidores lá instance_follows_measure: os seus seguidores aqui - instance_languages_dimension: Liderança de línguas + instance_languages_dimension: Idiomas mais populares instance_media_attachments_measure: anexos de media armazenados instance_reports_measure: denúncias sobre eles instance_statuses_measure: publicações armazenadas @@ -585,11 +599,13 @@ pt-PT: assign_to_self: Atribuída a mim assigned: Atribuída ao moderador by_target_domain: Domínio da conta denunciada + cancel: Cancelar category: Categorização category_description_html: A razão pela qual esta conta e/ou conteúdo foi denunciado será citada na comunicação com a conta denunciada comment: none: Nenhum comment_description_html: 'Para fornecer mais informações, %{name} escreveu:' + confirm: Confirmar confirm_action: Confirmar a ação de moderação contra @%{acct} created_at: Denunciado delete_and_resolve: Eliminar publicações @@ -725,6 +741,9 @@ pt-PT: branding: preamble: A marca do seu servidor diferencia-a doutros servidores na rede. Essa informação pode ser exibida em vários contexos, como a interface na teia do Mastodon, aplicações nativas, visualizações de hiperligações noutros sites, em aplicações de mensagens, etc. Por esta razão, é melhor manter esta informação clara, curta e concisa. title: Marca + captcha_enabled: + desc_html: Isto depende de scripts externos da hCaptcha, o que pode ser uma preocupação de segurança e privacidade. Além disso, isto pode tornar o processo de registo menos acessível para algumas pessoas (especialmente as com limitações físicas). Por isso, considere medidas alternativas tais como registo mediante aprovação ou sob convite. + title: Requerer que novos utilizadores resolvam um CAPTCHA para confirmar a sua conta content_retention: preamble: Controle como o conteúdo gerado pelos utilizadores é armazenado no Mastodon. title: Retenção de conteúdo @@ -752,10 +771,27 @@ pt-PT: approved: Registo sujeito a aprovação none: Ninguém se pode registar open: Qualquer pessoa se pode registar - title: Definições do Servidor + security: + authorized_fetch: Exigir autenticação de servidores federados + authorized_fetch_hint: Exigir autenticação de servidores federados permite uma aplicação mais rigorosa de bloqueios tanto ao nível do utilizador como do servidor. No entanto, isso é feito à custa de uma diminuição de desempenho, reduz o alcance das suas respostas e pode introduzir problemas de compatibilidade com alguns serviços federados. Além disso, isso não impede os atores mais empenhados de aceder às suas publicações e contas públicas. + authorized_fetch_overridden_hint: Atualmente não pode alterar esta configuração porque ela é substituída por uma variável de ambiente. + federation_authentication: Imposição de autenticação da federação + title: Definições do servidor site_uploads: delete: Eliminar arquivo carregado destroyed_msg: Envio de sítio na teia correctamente eliminado! + software_updates: + critical_update: Crítico — por favor, atualize rapidamente + description: Recomenda-se manter a instalação do Mastodon atualizada para beneficiar das funcionalidades e correções mais recentes. Além disso, por vezes é fundamental actualizar o Mastodon de forma atempada para evitar problemas de segurança. Por estes motivos, o Mastodon procura por atualizações a cada 30 minutos e envia-lhe uma notificação de acordo com suas preferências de notificação por e-mail. + documentation_link: Saber mais + release_notes: Notas de lançamento + title: Atualizações disponíveis + type: Tipo + types: + major: Versão principal + minor: Versão menor + patch: Versão de atualização — correções de problemas e alterações fáceis de aplicar + version: Versão statuses: account: Autor application: Aplicação @@ -768,7 +804,7 @@ pt-PT: favourites: Marcadores history: Histórico de versões in_reply_to: A responder a - language: Língua + language: Idioma media: title: Media metadata: Metadados @@ -792,9 +828,24 @@ pt-PT: suspend: "%{name} suspendeu a conta de %{target}" appeal_approved: Recorrido appeal_pending: Recurso pendente + appeal_rejected: Recurso rejeitado system_checks: database_schema_check: message_html: Há migrações de base de dados pendentes. Queira executá-las, para garantir que a aplicação se comporta como o esperado + elasticsearch_health_red: + message_html: O cluster elasticsearch não está de boa saúde (estado vermelho), as funcionalidades de pesquisa não estão disponíveis + elasticsearch_health_yellow: + message_html: O cluster elasticsearch não está de boa saúde (estado amarelo), pode querer investigar o motivo + elasticsearch_index_mismatch: + message_html: Os mapeamentos elasticsearch estão desatualizados. Por favor, execute tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Ver a documentação + message_html: O seu cluster elasticsearch tem mais de um nó, mas o Mastodon não está configurado para os usar. + elasticsearch_preset_single_node: + action: Ver documentação + message_html: O seu cluster elasticsearch tem apenas um nó, ES_PRESET deve ser configurado para single_node_cluster. + elasticsearch_reset_chewy: + message_html: O seu índice de sistema elasticsearch está desatualizado devido a uma mudança de configuração. Por favor, execute tootctl search deploy --reset-chewy para o atualizar. elasticsearch_running_check: message_html: Não foi possível conectar ao Elasticsearch. Por favor, verifique se está em execução, ou desabilite a pesquisa de texto completo elasticsearch_version_check: @@ -805,6 +856,18 @@ pt-PT: message_html: Não definiu nenhuma regra para a instância. sidekiq_process_check: message_html: Nenhum processo Sidekiq em execução para a(s) fila(s) %{value}. Reveja a configuração do seu Sidekiq + software_version_critical_check: + action: Ver atualizações disponíveis + message_html: Está disponível uma atualização crítica do Mastodon. Por favor, atualize assim que possível. + software_version_patch_check: + action: Ver atualizações disponíveis + message_html: Está disponível uma atualização do Mastodon com correções de problemas. + upload_check_privacy_error: + action: Verifique aqui para mais informações + message_html: "O seu servidor web está mal configurado. A privacidade dos seus utilizadores está em risco." + upload_check_privacy_error_object_storage: + action: Verifique aqui para mais informações + message_html: "O seu armazenamento de objetos está mal configurado. A privacidade dos seus utilizadores está em risco." tags: review: Estado da revisão updated_msg: 'Definições de #etiquetas correctamente actualizadas' @@ -827,6 +890,7 @@ pt-PT: other: Partilhado por %{count} pessoas na última semana title: Ligações em alta usage_comparison: Partilhado %{today} vezes hoje, em comparação com %{yesterday} ontem + not_allowed_to_trend: Não permitido para tendência only_allowed: Apenas permitidos pending_review: Pendente de revisão preview_card_providers: @@ -851,7 +915,7 @@ pt-PT: current_score: Pontuação atual %{score} dashboard: tag_accounts_measure: utilizadores únicos - tag_languages_dimension: Liderança de línguas + tag_languages_dimension: Idiomas mais populares tag_servers_dimension: Topo de servidores tag_servers_measure: servidores diferentes tag_uses_measure: utilizações totais @@ -911,6 +975,9 @@ pt-PT: body: "%{target} está a recorrer de uma decisão de moderação de %{action_taken_by} a %{date}, que consistiu em %{type}. Escreveu:" next_steps: Pode aprovar o recurso para reverter a decisão de moderação, ou ignorá-lo. subject: "%{username} está a recorrer da decisão de moderação em %{instance}" + new_critical_software_updates: + body: Foram lançadas novas versões críticas do Mastodon. Pode querer atualizar assim que possível! + subject: Estão disponíveis atualizações críticas do Mastodon para %{instance}! new_pending_account: body: Abaixo, estão os pormenores da nova conta. Pode aprovar ou rejeitar esta inscrição. subject: Nova conta para revisão em %{instance} (%{username}) @@ -918,6 +985,9 @@ pt-PT: body: "%{reporter} denunciou %{target}" body_remote: Alguém de %{domain} denunciou %{target} subject: Nova denúncia para %{instance} (#%{id}) + new_software_updates: + body: Foram lançadas novas versões do Mastodon, talvez queira atualizar! + subject: Estão disponíveis novas versões do Mastodon para %{instance}! new_trends: body: 'Os seguintes itens precisam ser revistos antes de poderem ser exibidos publicamente:' new_trending_links: @@ -947,24 +1017,28 @@ pt-PT: guide_link: https://pt.crowdin.com/project/mastodon/ guide_link_text: Todos podem contribuir. sensitive_content: Conteúdo problemático - toot_layout: Disposição da publicação application_mailer: notification_preferences: Alterar preferências de e-mail salutation: "%{name}," settings: 'Alterar preferências de e-mail: %{link}' + unsubscribe: Cancelar subscrição view: 'Ver:' view_profile: Ver perfil view_status: Ver publicação applications: created: Aplicação correctamente criada destroyed: Aplicação correctamente eliminada + logout: Sair regenerate_token: Regenerar token de acesso token_regenerated: Token de acesso regenerado com sucesso warning: Cuidado com estes dados. Não partilhar com ninguém! your_token: O teu token de acesso auth: apply_for_account: Solicitar uma conta - change_password: Palavra-passe + captcha_confirmation: + help_html: Se tiver problemas a resolver o CAPTCHA, pode entrar em contacto conosco através de %{email} e poderemos ajudá-lo. + hint_html: Só mais uma coisa! Precisamos confirmar que você é um humano (isto para que possamos evitar spam!). Resolva o CAPTCHA abaixo e clique em "Continuar". + title: Verificação de segurança confirmations: wrong_email_hint: Se esse endereço de e-mail não estiver correto, você pode alterá-lo nas configurações da conta. delete_account: Eliminar conta @@ -973,7 +1047,7 @@ pt-PT: prefix_invited_by_user: "@%{name} convidou-o a juntar-se a esta instância do Mastodon!" prefix_sign_up: Inscreva-se hoje no Mastodon! suffix: Com uma conta, poderá seguir pessoas, publicar atualizações e trocar mensagens com utilizadores de qualquer instância Mastodon e muito mais! - didnt_get_confirmation: Não recebeu o e-mail de confirmação? + didnt_get_confirmation: Não recebeu um link de confirmação? dont_have_your_security_key: Não tem a sua chave de segurança? forgot_password: Esqueceu-se da palavra-passe? invalid_reset_password_token: Token de modificação da palavra-passe é inválido ou expirou. Por favor, solicita um novo. @@ -986,26 +1060,39 @@ pt-PT: migrate_account_html: Se deseja redirecionar esta conta para uma outra pode configurar isso aqui. or_log_in_with: Ou iniciar sessão com privacy_policy_agreement_html: Eu li e concordo com a política de privacidade + progress: + confirm: Confirmar e-mail + details: Os seus dados + review: A nossa avaliação + rules: Aceitar regras providers: cas: CAS saml: SAML register: Registar registration_closed: "%{instance} não está a aceitar novos membros" - resend_confirmation: Reenviar instruções de confirmação + resend_confirmation: Reenviar link de confirmação reset_password: Criar nova palavra-passe rules: + accept: Aceitar + back: Retroceder + invited_by: 'Pode inscrever-se em %{domain} graças ao convite que recebeu de:' preamble: Estas são definidas e aplicadas pelos moderadores de %{domain}. + preamble_invited: Antes de prosseguir, por favor, considere as regras base definidas pelos moderadores de %{domain}. title: Algumas regras básicas. + title_invited: Foi convidado. security: Alterar palavra-passe set_new_password: Editar palavra-passe setup: - email_below_hint_html: Se o endereço de e-mail abaixo estiver incorreto, pode alterá-lo aqui e receber um novo e-mail de confirmação. - email_settings_hint_html: O e-mail de confirmação foi enviado para %{email}. Se esse endereço de e-mail não estiver correto, pode alterá-lo nas definições da conta. - title: Configuração + email_below_hint_html: Verifique a sua pasta de spam, ou solicite outra. Pode corrigir o seu endereço de e-mail se este estiver errado. + email_settings_hint_html: Clique no link que enviamos para verificar %{email}. Esperaremos aqui. + link_not_received: Não recebeu um link? + new_confirmation_instructions_sent: Receberá um novo e-mail com o link de confirmação daqui a poucos minutos! + title: Verifique a caixa de entrada do seu e-mail sign_in: preamble_html: Iniciar sessão com as suas credenciais de %{domain}. Se a sua conta estiver hospedada noutro servidor, não poderá iniciar sessão aqui. title: Iniciar sessão em %{domain} sign_up: + manual_review: Inscrições no %{domain} passam por uma revisão manual pelos nossos moderadores. Para nos ajudar a processar o seu pedido de inscrição, escreva um pouco sobre si e o porquê de quer uma conta no %{domain}. preamble: Com uma conta neste servidor Mastodon, poderá seguir qualquer outra pessoa na rede, independentemente do servidor onde a conta esteja hospedada. title: Vamos lá inscrevê-lo em %{domain}. status: @@ -1017,18 +1104,6 @@ pt-PT: view_strikes: Veja as reprimendas anteriores sobre a sua conta too_fast: Formulário enviado demasiado rapidamente, tente novamente. use_security_key: Usar chave de segurança - authorize_follow: - already_following: Tu já estás a seguir esta conta - already_requested: Já enviou anteriormente um pedido para seguir esta conta - error: Infelizmente, ocorreu um erro ao buscar a conta remota - follow: Seguir - follow_request: 'Enviaste uma solicitação de seguidor para:' - following: 'Sucesso! Agora estás a seguir a:' - post_follow: - close: Ou podes simplesmente fechar esta janela. - return: Mostrar perfil do utilizador - web: Ir para a página na teia - title: Seguir %{acct} challenge: confirm: Continuar hint_html: "Dica: Não vamos pedir novamente a sua palavra-passe durante a próxima hora." @@ -1105,6 +1180,10 @@ pt-PT: your_appeal_rejected: O seu recurso foi indeferido domain_validator: invalid_domain: não é um nome de domínio válido + edit_profile: + basic_information: Informação básica + hint_html: "Personalize o que as pessoas veem no seu perfil público e junto das suas publicações. É mais provável que as outras pessoas o sigam de volta ou interajam consigo se tiver um perfil preenchido e uma imagem de perfil." + other: Outro errors: '400': O pedido que submeteu foi inválido ou mal formulado. '403': Não tens a permissão necessária para ver esta página. @@ -1141,7 +1220,7 @@ pt-PT: featured_tags: add_new: Adicionar nova errors: - limit: Já atingiste o limite máximo de etiquetas + limit: Já destacou o número máximo de hashtags permitido hint_html: "O que são etiquetas em destaque? Exibidas de forma bem visível no seu perfil público, permitem que as pessoas consultem as suas publicações públicas especificamente sob essas etiquetas. São uma óptima ferramenta para dar seguimento a trabalhos criativos ou projectos de longo prazo." filters: contexts: @@ -1185,8 +1264,6 @@ pt-PT: index: hint: Este filtro aplica-se a publicações individuais selecionadas independentemente de outros critérios. Pode adicionar mais publicações a este filtro através da interface web. title: Publicações filtradas - footer: - trending_now: Em alta neste momento generic: all: Tudo all_items_on_page_selected_html: @@ -1195,7 +1272,9 @@ pt-PT: all_matching_items_selected_html: one: "%{count} item que corresponde à sua pesquisa está selecionado." other: Todos os %{count} items que correspondem à sua pesquisa estão selecionados. + cancel: Cancelar changes_saved_msg: Alterações guardadas! + confirm: Confirmar copy: Copiar delete: Eliminar deselect: Desmarcar todos @@ -1209,24 +1288,62 @@ pt-PT: validation_errors: one: Algo não está correcto. Por favor analise o erro abaixo other: Algo não está bem. Queira analisar os %{count} erros abaixo - html_validator: - invalid_markup: 'contém marcação HTML inválida: %{error}' imports: errors: + empty: Ficheiro CSV vazio + incompatible_type: Incompatível com o tipo de importação selecionado invalid_csv_file: 'Arquivo CSV inválido. Erro: %{error}' over_rows_processing_limit: contém mais de %{count} linhas + too_large: O ficheiro é demasiado grande + failures: Falhas + imported: Importado + mismatched_types_warning: Parece que selecionou o tipo errado para esta importação, por favor verifique novamente. modes: merge: Juntar merge_long: Manter os registos existentes e adicionar novos registos overwrite: Escrever por cima overwrite_long: Substituir os registos atuais pelos novos + overwrite_preambles: + blocking_html: Está prestes a substituir a sua lista de bloqueios com até %{total_items} contas de %{filename}. + bookmarks_html: Está prestes a substituir os seus marcadores com até %{total_items} publicações de %{filename}. + domain_blocking_html: Está prestes a substituir a sua lista de bloqueios de domínio com até %{total_items} domínios de %{filename}. + following_html: Está prestes a seguir até %{total_items} contas de %{filename} e parar de seguir quaisquer outras contas. + lists_html: Está prestes a substituir as suas listas pelo conteúdo de %{filename}. Até %{total_items} contas serão adicionadas a novas listas. + muting_html: Está prestes a substituir a sua lista de contas silenciadas com até %{total_items} contas de %{filename}. + preambles: + blocking_html: Está prestes a bloquear até %{total_items} contas de %{filename}. + bookmarks_html: Está prestes a adicionar até %{total_items} publicações de %{filename} aos seus marcadores. + domain_blocking_html: Está prestes a bloquear até %{total_items} domínios de %{filename}. + following_html: Está prestes a seguir até %{total_items} contas de %{filename}. + lists_html: Está prestes a adicionar até %{total_items} contas do ficheiro %{filename} para as suas listas. Novas listas serão criadas se não existir uma lista onde as adicionar. + muting_html: Está prestes a silenciar até %{total_items} contas de %{filename}. preface: Podes importar dados que tenhas exportado de outra instância, como a lista de pessoas que segues ou bloqueadas. + recent_imports: Importações recentes + states: + finished: Concluído + in_progress: Em progresso + scheduled: Agendado + unconfirmed: Não confirmado + status: Estado success: Os teus dados foram enviados correctamente e serão processados em breve + time_started: Iniciado em + titles: + blocking: Importando contas bloqueadas + bookmarks: Importando marcadores + domain_blocking: Importando domínios bloqueados + following: Importando contas seguidas + lists: A importar listas + muting: Importando contas silenciadas + type: Tipo de importação + type_groups: + constructive: Seguidores e Marcadores + destructive: Bloqueios e silenciamentos types: blocking: Lista de bloqueio bookmarks: Itens salvos domain_blocking: Lista de domínios bloqueados following: Lista de pessoas que estás a seguir + lists: Listas muting: Lista de utilizadores silenciados upload: Carregar invites: @@ -1253,7 +1370,7 @@ pt-PT: title: Convidar pessoas lists: errors: - limit: Número máximo de listas alcançado + limit: Atingiu o número máximo de listas permitido login_activities: authentication_methods: otp: aplicação de autenticação em duas etapas @@ -1265,6 +1382,21 @@ pt-PT: failed_sign_in_html: Tentativa falhada de início de sessão com %{method} de %{ip} (%{browser}) successful_sign_in_html: Sessão correctamente iniciada com %{method} de %{ip} (%{browser}) title: Histórico de autenticação + mail_subscriptions: + unsubscribe: + action: Sim, cancelar subscrição + complete: Subscrição Cancelada + confirmation_html: Tem a certeza que deseja cancelar a subscrição para receber %{type} pelo Mastodon em %{domain} no seu e-mail em %{email}? Pode sempre subcrever novamente nas suas configurações de notificação de e-mail. + emails: + notification_emails: + favourite: e-mails de notificação de favorito + follow: e-mails de notificação de seguidor + follow_request: e-mails de notificação de pedido de seguidor + mention: e-mails de notificação de menção + reblog: e-mails de notificação de partilha + resubscribe_html: Se cancelou a subscrição por engano, pode subscrever novamente nas suas configurações de notificação de e-mail. + success_html: Não receberá novamente %{type} pelo Mastodon em %{domain} para o seu e-mail em %{email}. + title: Cancelar subscrição media_attachments: validations: images_and_video: Não é possível anexar um vídeo a uma publicação que já contém imagens @@ -1344,6 +1476,7 @@ pt-PT: update: subject: "%{name} editou uma publicação" notifications: + administration_emails: Notificções administrativas por e-mail email_events: Eventos para notificações por e-mail email_events_hint: 'Selecione os casos para os quais deseja receber notificações:' other_settings: Outras opções de notificações @@ -1380,12 +1513,22 @@ pt-PT: expired: A sondagem já terminou invalid_choice: A opção de voto escolhida não existe over_character_limit: não pode ter mais do que %{max} caracteres cada um + self_vote: Não pode votar numa sondagem criada por si too_few_options: tem de ter mais do que um item too_many_options: não pode conter mais do que %{max} itens preferences: other: Outro posting_defaults: Padrões de publicação public_timelines: Cronologias públicas + privacy: + hint_html: "Defina como quer que o seu perfil e as suas publicações sejam encontrados. Várias funcionalidades no Mastodon podem ajudar a alcançar um público mais amplo quando ativadas. Tire um momento para rever estas definições para garantir que se aplicam ao seu caso de uso." + privacy: Privacidade + privacy_hint_html: Controle quanto pretende partilhar para o benefício de outros. As pessoas descobrem perfis e aplicações interessantes navegando pelos seguidores de outras pessoas e vendo que aplicações eles usam para publicar, mas pode preferir não revelar essa informação. + reach: Alcance + reach_hint_html: Controle se quer ser descoberto e seguido por novas pessoas. Quer que as suas publicações apareçam no ecrã Explorar? Pretende que outras pessoas o vejam nas suas recomendações? Quer aceitar todos os novos seguidores automaticamente, ou ter um controlo individual sobre cada um? + search: Pesquisa + search_hint_html: Controle como deseja ser encontrado. Quer que as pessoas o encontrem com base nas suas publicações? Que pessoas fora do Mastodon encontrem o seu perfil quando pesquisarem na web? Note que a exclusão total de todos os motores de busca não pode ser garantida para informação pública. + title: Privacidade e alcance privacy_policy: title: Política de Privacidade reactions: @@ -1398,6 +1541,7 @@ pt-PT: confirm_remove_selected_followers: Tem a certeza que deseja seguir os seguidores selecionados? confirm_remove_selected_follows: Tem certeza que deseja remover os seguidores selecionados? dormant: Inativo + follow_failure: Não foi possível seguir algumas das contas selecionadas. follow_selected_followers: Seguir seguidores selecionados followers: Seguidores following: A seguir @@ -1437,6 +1581,7 @@ pt-PT: electron: Electron firefox: Firefox generic: Navegador desconhecido + huawei_browser: Navegador Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Navegador Nokia S40 Ovi @@ -1446,6 +1591,7 @@ pt-PT: qq: QQ Browser safari: Safari uc_browser: Navegador UC + unknown_browser: Navegador Desconhecido weibo: Weibo current_session: Sessão atual description: "%{browser} em %{platform}" @@ -1458,9 +1604,10 @@ pt-PT: chrome_os: ChromeOS firefox_os: SO Firefox ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: plataforma desconhecida + unknown_platform: Plataforma Desconhecida windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1505,7 +1652,7 @@ pt-PT: other: "%{count} vídeos" boosted_from_html: Reforçado por %{acct_link} content_warning: 'Aviso de conteúdo: %{warning}' - default_language: A mesma língua que a da interface + default_language: Igual ao idioma da interface disallowed_hashtags: one: 'continha uma #etiqueta proibida: %{tags}' other: 'continha as hashtags proibidas: %{tags}' @@ -1531,7 +1678,6 @@ pt-PT: show_newer: Mostrar mais recentes show_older: Mostrar mais antigos show_thread: Mostrar conversa - sign_in_to_participate: Inicie a sessão para participar na conversa title: '%{name}: "%{quote}"' visibilities: direct: Direto @@ -1573,12 +1719,10 @@ pt-PT: '7889238': 3 meses min_age_label: Limite de idade min_favs: Manter pelo menos as publicações dos marcadores - min_favs_hint: Não apaga nenhuma das suas publicações que tenha recebido mais do que esta quantidade de favoritos. Deixe em branco para apagar as publicações, independentemente do número de favoritos + min_favs_hint: Não elimina nenhuma das suas publicações que tenha recebido pelo menos este número de favoritos. Deixe em branco para eliminar publicações, independentemente do seu número de favoritos min_reblogs: Manter as publicações reforçadas mais de min_reblogs_hint: Não apaga nenhuma das suas publicações que tenha sido partilhada mais do que este número de vezes. Deixe em branco para apagar as publicações, independentemente do número de partilhas stream_entries: - pinned: Publicação afixada - reblogged: reforçada sensitive_content: Conteúdo problemático strikes: errors: @@ -1594,6 +1738,11 @@ pt-PT: default: "%H:%M em %d de %b de %Y" month: "%b de %Y" time: "%H:%M" + with_time_zone: "%d %b de %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: A quota de uso do servidor para o serviço de tradução foi excedida. + too_many_requests: Houve muitos pedidos ao serviço de tradução ultimamente. two_factor_authentication: add: Adicionar disable: Desactivar autenticação por dois factores (2FA) @@ -1673,13 +1822,18 @@ pt-PT: title: Bem-vindo a bordo, %{name}! users: follow_limit_reached: Não pode seguir mais do que %{limit} pessoas + go_to_sso_account_settings: Ir para as definições de conta do seu fornecedor de identidade invalid_otp_token: Código de autenticação inválido otp_lost_help_html: Se perdeu o acesso a ambos, pode entrar em contacto com %{email} seamless_external_login: Tu estás ligado via um serviço externo. Por isso, as configurações da palavra-passe e do e-mail não estão disponíveis. signed_in_as: 'Registado como:' verification: - explanation_html: 'Pode comprovar que é o dono das hiperligações nos metadados do seu perfil. Para isso, a página para a qual a ligação aponta tem de conter uma outra para o seu perfil do Mastodon. Essa ligação tem de ter um atributo rel="me". O conteúdo do texto não é importante. Eis um exemplo:' + extra_instructions_html: Dica: A ligação no seu site pode ser invisível. A parte importante é rel="me" que impede a personificação em sites com conteúdo gerado pelo utilizador. Pode até utilizar uma etiqueta link no cabeçalho da página ao invés de a, mas o HTML deve ser acessível sem executar JavaScript. + here_is_how: Veja como + hint_html: "Verificar a sua identidade no Mastodon é para todos. Baseado em normas públicas da web, agora e para sempre gratuitas. Tudo o que precisa é de um site pessoal pelo qual as pessoas o reconheçam. Quando coloca no seu perfil uma ligação para esse site, vamos verificar que o site tem uma ligação de volta para o seu perfil e mostrar um indicador visual." + instructions_html: Copie e cole o código abaixo no HTML do seu site. Em seguida, adicione o endereço do seu site em um dos campos extras no seu perfil, na aba "Editar perfil" e salve as alterações. verification: Verificação + verified_links: As suas ligações verificadas webauthn_credentials: add: Adicionar nova chave de segurança create: diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 48cf790b77..a0f20d57dc 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -121,8 +121,6 @@ ro: removed_header_msg: S-a îndepărtat cu succes coperta utilizatorului %{username} resend_confirmation: already_confirmed: Acest utilizator este deja confirmat - send: Retrimite e-mail de confirmare - success: E-mail de confirmare trimis cu succes! reset: Resetează reset_password: Resetează parola resubscribe: Resubscrie-te @@ -410,7 +408,6 @@ ro: localization: guide_link_text: Toată lumea poate contribui. sensitive_content: Conținut sensibil - toot_layout: Aspect postare application_mailer: notification_preferences: Modifică preferințe e-mail settings: 'Modifică preferințe e-mail: %{link}' @@ -425,14 +422,12 @@ ro: warning: Fiți foarte atent cu aceste date. Nu le împărtășiți niciodată cu cineva! your_token: Token-ul tău de acces auth: - change_password: Parolă delete_account: Șterge contul delete_account_html: Dacă vrei să ștergi acest cont poți începe aici. Va trebui să confirmi această acțiune. description: prefix_invited_by_user: "@%{name} vă invită să vă alăturați acestui server de Mastodon!" prefix_sign_up: Înscrie-te pe Mastodon astăzi! suffix: Cu un cont, vei putea să urmărești oameni, să postezi actualizări și să schimbi mesaje cu utilizatorii de pe orice server Mastodon și multe altele! - didnt_get_confirmation: Nu ai primit instrucțiunile de confirmare? forgot_password: Ai uitat parola? invalid_reset_password_token: Această cerere este invalidă sau a expirat. Încearcă resetarea parolei din nou. login: Conectare @@ -442,31 +437,14 @@ ro: or_log_in_with: Sau conectează-te cu register: Înregistrare registration_closed: "%{instance} nu acceptă membri noi" - resend_confirmation: Retrimite instrucțiunile de confirmare reset_password: Resetare parolă security: Securitate set_new_password: Setează o nouă parolă - setup: - email_below_hint_html: Dacă adresa de e-mail de mai jos este incorectă, o puteți schimba aici și puteți primi un nou e-mail de confirmare. - email_settings_hint_html: E-mailul de confirmare a fost trimis la %{email}. Dacă această adresă de e-mail nu este corectă, o puteți schimba în setările contului. - title: Configurare status: account_status: Starea contului confirming: Se așteaptă finalizarea confirmării prin e-mail. pending: Cererea dvs. este în curs de revizuire de către personalul nostru. Este posibil să dureze ceva timp. Veți primi un e-mail dacă cererea dvs. este aprobată. redirecting_to: Contul dvs. este inactiv deoarece în prezent se redirecționează către %{acct}. - authorize_follow: - already_following: Urmărești deja acest cont - already_requested: Ați trimis deja o cerere de urmărire către acel cont - error: Din păcate a apărut o eroare - follow: Urmărește - follow_request: 'Ai trimis o cerere de urmărire către:' - following: 'Gata! De acum urmărești:' - post_follow: - close: Sau, poți închide această fereastră. - return: Arată profilul utilizatorului - web: Mergi la web - title: Urmărește %{acct} challenge: confirm: Continuă hint_html: "Sfat: Nu vă vom mai cere parola pentru următoarea oră." @@ -500,10 +478,8 @@ ro: email_change_html: Puteți schimba adresa de e-mail fără a șterge contul dvs email_contact_html: Dacă tot nu ajunge, puteți trimite e-mail la %{email} pentru ajutor errors: - '400': The request you submitted was invalid or malformed. '403': Nu ai permisiunea să vizitezi această pagină. '404': Pagina pe care o cauți nu există. - '406': This page is not available in the requested format. '410': Pagina pe care o cauți nu mai există. '422': content: Verificarea securității a eșuat. Ai blocat cookiurile? @@ -512,7 +488,6 @@ ro: '500': content: Ne pare rău, dar ceva a funcționat greșit. Încercați din nou!? title: Această pagină nu este corectă - '503': The page could not be served due to a temporary server failure. noscript_html: Pentru a utiliza o aplicație web Mastodon, te rog activează JavaScript. Alternativ, încearcă una din aplicațiile native Mastodon pentru platforma ta. exports: archive_takeout: @@ -576,9 +551,6 @@ ro: expires_at: Expiră uses: Utilizări title: Invită persoane - lists: - errors: - limit: Ați atins valoarea maximă a listelor media_attachments: validations: images_and_video: Nu se poate atașa un videoclip la o stare care conține deja imagini @@ -691,7 +663,6 @@ ro: vote: Votează show_more: Arată mai mult show_thread: Arată discuția - sign_in_to_participate: Conectează-te pentru a participa la conversație visibilities: private: Doar urmăritorii private_long: Arată doar urmăritorilor @@ -699,8 +670,6 @@ ro: unlisted: Nelistat unlisted_long: Toată lumea poate vedea, dar nu este listată pe fluxurile publice stream_entries: - pinned: Postare fixată - reblogged: impulsionată sensitive_content: Conținut sensibil tags: does_not_match_previous_name: nu se potrivește cu numele anterior @@ -752,5 +721,4 @@ ro: seamless_external_login: Sunteți autentificat prin intermediul unui serviciu extern, astfel încât parola și setările de e-mail nu sunt disponibile. signed_in_as: 'Conectat ca:' verification: - explanation_html: 'Poți să te verifici ca proprietar al link-urilor din metadatele profilului tău. Pentru aceasta, site-ul web asociat trebuie să conțină un link înapoi la profilul tău. Link-ul înapoi trebuie să aibă un atribut rel="me". Conținut textului link-ului nu contează. Iată un exemplu:' verification: Verificare diff --git a/config/locales/ru.yml b/config/locales/ru.yml index b5fec6cfa7..f9e526c4e8 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -3,7 +3,7 @@ ru: about: about_mastodon_html: 'Социальная сеть будущего: никакой рекламы, слежки корпорациями, этичный дизайн и децентрализация! С Mastodon ваши данные под вашим контролем.' contact_missing: не указан - contact_unavailable: неизв. + contact_unavailable: Н/Д hosted_on: Вы получили это сообщение, так как зарегистрированы на %{domain} title: О проекте accounts: @@ -95,6 +95,7 @@ ru: moderation: active: Действующие all: Все + disabled: Отключено pending: В ожидании silenced: Ограниченные suspended: Заблокированные @@ -130,8 +131,8 @@ ru: removed_header_msg: Успешно удалено изображение заголовка %{username} resend_confirmation: already_confirmed: Этот пользователь уже подтвержден - send: Повторно отправить подтверждение по электронной почте - success: Письмо с подтверждением успешно отправлено! + send: Повторно отправить ссылку подтверждения + success: Ссылка для подтверждения успешно отправлена! reset: Сбросить reset_password: Сбросить пароль resubscribe: Переподписаться @@ -139,6 +140,7 @@ ru: search: Поиск search_same_email_domain: Другие пользователи с тем же доменом электронной почты search_same_ip: Другие пользователи с таким же IP + security: Безопасность security_measures: only_password: Только пароль password_and_2fa: Пароль и 2FA @@ -313,6 +315,7 @@ ru: unpublish: Отменить публикацию unpublished_msg: Объявление скрыто. updated_msg: Объявление обновлено. + critical_update_pending: Ожидается обновление критического уровня custom_emojis: assign_category: Задать категорию by_domain: Домен @@ -354,10 +357,10 @@ ru: new_users: новые пользователи opened_reports: жалоб открыто pending_appeals_html: - few: "%{count} аппеляции в ожидании" - many: "%{count} апелляций в ожидании" + few: "%{count} ожидают аппеляции" + many: "%{count} ожидают апелляции" one: "%{count} ожидает апелляции" - other: "%{count} апелляций в ожидании" + other: 'Ожидают апелляции: %{count}' pending_reports_html: few: "%{count} ожидающих отчета" many: "%{count} ожидающих отчетов" @@ -394,6 +397,15 @@ ru: undo: Убрать из белого списка domain_blocks: add_new: Заблокировать домен + confirm_suspension: + cancel: Отмена + confirm: Приостановить + permanent_action: Отмена приостановки не восстановит никаких данных или отношений. + preamble_html: Вы собираетесь приостановить %{domain} и его субдомены. + remove_all_data: Это удалит весь контент, мультимедиа и данные профиля для учетных записей этого домена с вашего сервера. + stop_communication: Ваш сервер перестанет общаться с этими серверами. + title: Снять блокировку с домена %{domain} + undo_relationships: Это отменит связь между аккаунтами этих серверов и вашими. created_msg: Блокировка домена обрабатывается destroyed_msg: Блокировка домена снята domain: Домен @@ -443,6 +455,7 @@ ru: resolve: Проверить домен title: Новая блокировка по домену no_email_domain_block_selected: Блоки домена электронной почты не были изменены, так как не были выбраны + not_permitted: Не разрешено resolved_dns_records_hint_html: Доменное имя устраняется на следующие MX-домены, которые в конечном итоге отвечают за прием электронной почты. Блокировка MX-домена будет блокировать регистрации с любого адреса электронной почты, который использует тот же MX-домен, даже если видимое доменное имя отличается от него. Будьте осторожны, чтобы не блокировать основных поставщиков электронной почты resolved_through_html: Разрешено через %{domain} title: Блокировка e-mail доменов @@ -457,6 +470,7 @@ ru: private_comment_description_html: 'Чтобы помочь вам отслеживать откуда импортируются блокировка, импортированные блокировки будут созданы со следующим приватным комментарием: %{comment}' private_comment_template: Импортировано из %{source} %{date} title: Импорт доменных блокировок + invalid_domain_block: 'Один или несколько доменных блокировок были пропущены из-за следующих ошибок: %{error}' new: title: Импорт доменных блокировок no_file: Файл не выбран @@ -492,6 +506,7 @@ ru: content_policies: comment: Внутренняя заметка description_html: Вы можете определить политики контента, которые будут применяться ко всем учетным записям этого домена и любого из его субдоменов. + limited_federation_mode_description_html: Вы можете выбрать, разрешать ли объединение с этим доменом. policies: reject_media: Отклонить медиа reject_reports: Отклонять жалобы @@ -599,17 +614,23 @@ ru: mark_as_sensitive_description_html: Весь медиаконтент в обжалованных сообщениях будет отмечен как чувствительный, а претензия - записана, чтобы помочь вам в решении конфликтов при повторных нарушениях со стороны того же аккаунта. other_description_html: Посмотрите больше настроек для контроля поведения учётной записи и наладьте связь с аккаунтом с жалобой. resolve_description_html: Никаких действий не будет выполнено относительно доложенного содержимого. Жалоба будет закрыта. + silence_description_html: Учетная запись будет видна только тем пользователям, которые уже подписаны на неё, либо открыли его вручную. Это действие можно отменить в любой момент, и отменяет все жалобы против аккаунта. + suspend_description_html: Аккаунт и все его содержимое будут недоступны и в конечном итоге удалены, и взаимодействие с ним будет невозможно. Это действие можно отменить в течение 30 дней. Отменяет все жалобы против этого аккаунта. actions_description_html: Выберите действие, чтобы решить данную жалобу. Если вы выберите наказание против аккаунта, вы получите уведомление по E-Mail, проверяйте папку Спам. + actions_description_remote_html: Решите вопрос о том, какие меры необходимо принять для урегулирования этой жалобы. Это повлияет только на то, как ваш сервер взаимодействует с этим удаленным аккаунтом и обрабатывает его содержимое. add_to_report: Прикрепить ещё are_you_sure: Вы уверены? assign_to_self: Назначить себе assigned: Назначенный модератор by_target_domain: Домен объекта жалобы + cancel: Отменить category: Категория category_description_html: Причина, по которой были доложены этот пользователь или содержимое, будет указана при коммуникации с фигурирующим в жалобе пользователем comment: none: Нет comment_description_html: 'В дополнение, %{name} добавил(а) следующий комментарий:' + confirm: Подтвердить + confirm_action: Произвести модерацию учётной записи %{acct} created_at: Создана delete_and_resolve: Удалить посты forwarded: Переслано @@ -626,6 +647,7 @@ ru: placeholder: Опишите, какие действия были приняты, или любые другие подробности… title: Примечания notes_description_html: Просмотрите или оставьте примечания для остальных модераторов и себя в будущем + processed_msg: 'Жалоба #%{id} успешно обработана' quick_actions_description_html: 'Выберите действие или прокрутите вниз, чтобы увидеть контент с жалобой:' remote_user_placeholder: удаленный пользователь из %{instance} reopen: Переоткрыть жалобу @@ -639,13 +661,27 @@ ru: statuses: Содержимое относящееся к жалобе statuses_description_html: Нарушающее правила содержимое будет процитировано при коммуникации с фигурирующим в жалобе аккаунтом summary: + action_preambles: + delete_html: 'Вы собираетесь удалить некоторые посты @%{acct}. В результате этого:' + mark_as_sensitive_html: 'Вы собираетесь удалить некоторые посты @%{acct}. В результате этого:' + silence_html: 'Вы собираетесь заморозить учетную запись @%{acct}. В результате этого:' + suspend_html: 'Вы собираетесь заморозить учетную запись @%{acct}. В результате этого:' + actions: + delete_html: Удалить оскорбительные сообщения + mark_as_sensitive_html: Пометить медиа-оскорбительные сообщения как чувствительные + silence_html: Серьезно ограничить охват @%{acct}, сделав его профиль и содержимое видимым только для тех, кто уже следит за ним или вручную просматривает его профиль + suspend_html: Приостановить @%{acct}, сделав его профиль и содержимое недоступным и невозможным для взаимодействия с ним close_report: 'Отметить жалобу #%{id} как решённую' close_reports_html: Отметить все жалобы на @%{acct} как разрешённые delete_data_html: Удалить профиль и контент @%{acct} через 30 дней, если за это время они не будут разблокированы preview_preamble_html: "@%{acct} получит предупреждение со следующим содержанием:" + record_strike_html: Запишите замечание против @%{acct}, чтобы помочь вам в решении будущих нарушений с этого аккаунта + send_email_html: Отправить @%{acct} предупреждение на почту + warning_placeholder: Необязательное дополнительное обоснование действия модерации. target_origin: Происхождение объекта жалобы title: Жалобы unassign: Снять назначение + unknown_action_msg: 'Неизвестное действие: %{action}' unresolved: Нерешённые updated_at: Обновлена view_profile: Открыть профиль @@ -733,6 +769,9 @@ ru: branding: preamble: Брендинг вашего сервера отличает его от других серверов сети. Эта информация может отображаться в различных средах, таких как веб-интерфейс Mastodon, нативные приложения, в виде предпросмотра ссылок на других веб-сайтах, в почтовых приложениях и так далее. По этой причине лучше держать эту информацию ясной, короткой и краткой. title: Брендинг + captcha_enabled: + desc_html: Это зависит от внешних скриптов из hCaptcha, которые могут представлять интерес для безопасности и конфиденциальности. Кроме того, это может сделать процесс регистрации значительно менее доступным для некоторых (особенно отключенных) людей. По этим причинам просьба рассмотреть альтернативные меры, такие, как регистрация, основанная на официальном утверждении или на приглашении. + title: Запрашивать новых пользователей для решения CAPTCHA для подтверждения учетной записи content_retention: preamble: Управление сохранением пользовательского контента в Mastodon. title: Хранение контента @@ -745,6 +784,7 @@ ru: profile_directory: Каталог профилей public_timelines: Публичные ленты publish_discovered_servers: Публикация списка обнаруженных узлов + publish_statistics: Опубликовать стаитстику title: Обзор trends: Популярное domain_blocks: @@ -759,10 +799,27 @@ ru: approved: Для регистрации требуется подтверждение none: Никто не может регистрироваться open: Все могут регистрироваться - title: Настройки Сервера + security: + authorized_fetch: Требовать аутентификацию от федеративных серверов + authorized_fetch_hint: Требование аутентификации от федеративных серверов позволяет более строго соблюдать блокировки как на уровне пользователя, так и на уровне сервера. Однако при этом снижается производительность, уменьшается охват ваших ответов и могут возникнуть проблемы совместимости с некоторыми федеративными сервисами. Кроме того, это не помешает специальным исполнителям получать ваши публичные сообщения и учётные записи. + authorized_fetch_overridden_hint: В настоящее время вы не можете изменить этот параметр, поскольку он переопределяется переменной среды. + federation_authentication: Принудительная аутентификация федерации + title: Настройки сервера site_uploads: delete: Удалить загруженный файл destroyed_msg: Файл успешно удалён. + software_updates: + critical_update: Критично — пожалуйста, обновите как можно скорее + description: Рекомендуется поддерживать установку Mastodon в актуальном состоянии, чтобы воспользоваться последними исправлениями и возможностями. Кроме того, иногда очень важно своевременно обновлять Mastodon, чтобы избежать проблем с безопасностью. По этим причинам Mastodon проверяет наличие обновлений каждые 30 минут и уведомляет вас об этом в соответствии с вашими предпочтениями в отношении уведомлений по электронной почте. + documentation_link: Узнать больше + release_notes: Примечания к выпуску + title: Доступные обновления + type: Тип + types: + major: Основной выпуск + minor: Незначительный выпуск + patch: Выпуск патчей - исправления ошибок и простые в применении изменения + version: Версия statuses: account: Автор application: Заявка @@ -799,9 +856,24 @@ ru: suspend: "%{name} приостановил аккаунт %{target}" appeal_approved: Обжаловано appeal_pending: Обжалование в обработке + appeal_rejected: Апелляция отклонена system_checks: database_schema_check: message_html: Есть отложенные миграции базы данных. Запустите их, чтобы убедиться, что приложение работает должным образом + elasticsearch_health_red: + message_html: Кластер Elasticsearch неисправен (красный статус), функции поиска недоступны + elasticsearch_health_yellow: + message_html: Кластер Elasticsearch неисправен (желтый статус), возможно, вам потребуется выяснить причину + elasticsearch_index_mismatch: + message_html: Сопоставление индексов Elasticsearch устарело. Пожалуйста, выполните tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Посмотреть документацию + message_html: Ваш кластер Elasticsearch имеет более одного узла, но Mastodon не настроен на их использование. + elasticsearch_preset_single_node: + action: Посмотреть документацию + message_html: Ваш кластер Elasticsearch имеет только один узел, ES_PRESET следует установить значение single_node_cluster. + elasticsearch_reset_chewy: + message_html: Ваш системный индекс Elasticsearch устарел из-за изменения настроек. Пожалуйста, выполните tootctl search deploy --reset-chewy для его обновления. elasticsearch_running_check: message_html: Не удалось подключиться к Elasticsearch. Пожалуйста, проверьте, что он запущен, или отключите полнотекстовый поиск elasticsearch_version_check: @@ -812,6 +884,18 @@ ru: message_html: Вы не определили правила сервера. sidekiq_process_check: message_html: Ни один Sidekiq не запущен для %{value} очереди(-ей). Пожалуйста, просмотрите настройки Sidekiq + software_version_critical_check: + action: Посмотреть доступные обновления + message_html: Доступно критическое обновление Mastodon, пожалуйста, обновитесь как можно скорее. + software_version_patch_check: + action: Посмотреть доступные обновления + message_html: Доступно обновление Mastodon, исправляющее ошибки. + upload_check_privacy_error: + action: Нажмите сюда, чтобы узнать подробности + message_html: "Ваш веб-сервер неправильно настроен. Конфиденциальность ваших пользователей находится под угрозой." + upload_check_privacy_error_object_storage: + action: Нажмите сюда, чтобы узнать подробности + message_html: "Ваше хранилище объектов неправильно настроено. Безопасность ваших пользователей находится под угрозой" tags: review: Состояние проверки updated_msg: Настройки хэштега обновлены @@ -836,6 +920,7 @@ ru: other: Поделился %{count} человек за последнюю неделю title: Актуальные ссылки usage_comparison: Поделились %{today} раз сегодня, по сравнению с %{yesterday} вчера + not_allowed_to_trend: Не допущено в популярное only_allowed: Только разрешенное pending_review: Ожидает рассмотрения preview_card_providers: @@ -926,6 +1011,9 @@ ru: body: "%{target} обжалуют решение модератора %{action_taken_by} от %{date}, которое %{type}. Они написали:" next_steps: Вы можете одобрить апелляцию на отмену решения модерации или проигнорировать её. subject: "%{username} обжалует решение модерации на %{instance}" + new_critical_software_updates: + body: Выпущены новые критические версии Mastodon, которые необходимо обновить как можно скорее! + subject: Критические обновления Mastodon доступны для %{instance}! new_pending_account: body: Ниже указана информация учётной записи. Вы можете одобрить или отклонить заявку. subject: Новая учётная запись для рассмотрения на %{instance} (%{username}) @@ -933,6 +1021,9 @@ ru: body: "%{reporter} подал(а) жалобу на %{target}" body_remote: Кто-то с узла %{domain} пожаловался на %{target} subject: Новая жалоба, узел %{instance} (№%{id}) + new_software_updates: + body: Вышли новые версии Mastodon, возможно, вам стоит обновиться! + subject: Новые версии Mastodon доступны для %{instance}! new_trends: body: 'Прежде чем можно будет опубликовать, проверьте следующие элементы:' new_trending_links: @@ -941,6 +1032,7 @@ ru: title: Популярные посты new_trending_tags: no_approved_tags: На данный момент популярные подтвержденные хэштеги отсутствуют. + requirements: 'Каждый из этих кандидатов может превысить #%{rank} одобренных популярных хештегов. Сейчас это #%{lowest_tag_name} с числом %{lowest_tag_score}.' title: Популярные хэштеги subject: Новые тренды для проверки на %{instance} aliases: @@ -961,31 +1053,37 @@ ru: guide_link: https://ru.crowdin.com/project/mastodon guide_link_text: Каждый может внести свой вклад. sensitive_content: Содержимое деликатного характера - toot_layout: Структура постов application_mailer: notification_preferences: Настроить уведомления можно здесь salutation: "%{name}," settings: 'Настроить уведомления можно здесь: %{link}' + unsubscribe: Отписаться view: 'Просмотр:' view_profile: Просмотреть профиль view_status: Просмотреть пост applications: created: Приложение успешно создано destroyed: Приложение успешно удалено + logout: Выйти regenerate_token: Повторно сгенерировать токен доступа token_regenerated: Токен доступа успешно сгенерирован warning: Будьте очень внимательны с этими данными. Не делитесь ими ни с кем! your_token: Ваш токен доступа auth: apply_for_account: Запросить аккаунт - change_password: Пароль + captcha_confirmation: + help_html: Если у вас есть проблемы с CAPTCHA, вы можете связаться с нами через %{email} и мы вам поможем. + hint_html: Еще одна вещь! Нам нужно подтвердить, что вы человек (так что мы можем держать спам!). Решите капчу ниже и нажмите кнопку «Продолжить». + title: Проверка безопасности + confirmations: + wrong_email_hint: Если этот адрес электронной почты неверен, вы можете изменить его в настройках аккаунта. delete_account: Удалить учётную запись delete_account_html: Удалить свою учётную запись можно в два счёта здесь, но прежде у вас будет спрошено подтверждение. description: prefix_invited_by_user: "@%{name} приглашает вас присоединиться к этому узлу Mastodon." prefix_sign_up: Зарегистрируйтесь в Mastodon уже сегодня! suffix: С учётной записью вы сможете подписываться на людей, публиковать обновления, обмениваться сообщениями с пользователями любых сообществ Mastodon и не только! - didnt_get_confirmation: Не получили инструкцию для подтверждения? + didnt_get_confirmation: Не получили ссылку для подтверждения? dont_have_your_security_key: У вас нет ключа безопасности? forgot_password: Забыли пароль? invalid_reset_password_token: Токен сброса пароля неверен или устарел. Пожалуйста, запросите новый. @@ -998,26 +1096,39 @@ ru: migrate_account_html: Завели новую учётную запись? Перенаправьте подписчиков на неё — настройте перенаправление тут. or_log_in_with: Или войти с помощью privacy_policy_agreement_html: Мной прочитана и принята политика конфиденциальности + progress: + confirm: Подтвердите e-mail + details: Ваши данные + review: Наш обзор + rules: Принять правила providers: cas: CAS saml: SAML register: Зарегистрироваться registration_closed: "%{instance} не принимает новых участников" - resend_confirmation: Повторить отправку инструкции для подтверждения + resend_confirmation: Повторно отправить ссылку подтверждения reset_password: Сбросить пароль rules: + accept: Принять + back: Назад + invited_by: 'Вы можете присоединиться к %{domain} благодаря приглашению полученному от:' preamble: Они устанавливаются и применяются модераторами %{domain}. + preamble_invited: Прежде чем продолжить, ознакомьтесь с основными правилами, установленными модераторами сервера %{domain}. title: Несколько основных правил. + title_invited: Вы были приглашены. security: Безопасность set_new_password: Задать новый пароль setup: - email_below_hint_html: Если ниже указан неправильный адрес, вы можете исправить его здесь и получить новое письмо подтверждения. - email_settings_hint_html: Письмо с подтверждением было отправлено на %{email}. Если адрес указан неправильно, его можно поменять в настройках учётной записи. - title: Установка + email_below_hint_html: Проверьте папку "Спам" или запросите другую. Вы можете исправить свой адрес электронной почты, если он неправильный. + email_settings_hint_html: Нажмите на ссылку, которую мы отправили вам для проверки %{email}. Мы будем ждать прямо здесь. + link_not_received: Не получили ссылку? + new_confirmation_instructions_sent: Через несколько минут вы получите новое письмо со ссылкой для подтверждения! + title: Проверьте свой почтовый ящик sign_in: preamble_html: Войдите, используя ваши учётные данные %{domain}. Если ваша учётная запись размещена на другом сервере, вы не сможете здесь войти. title: Войти в %{domain} sign_up: + manual_review: Регистрация на %{domain} проходит через ручную проверку нашими модераторами. Чтобы помочь нам обработать вашу регистрацию, напишите немного о себе и о том, почему вы хотите получить аккаунт на %{domain}. preamble: С учётной записью на этом сервере Mastodon вы сможете следить за любым другим пользователем в сети, независимо от того, где размещён их аккаунт. title: Зарегистрируйтесь в %{domain}. status: @@ -1029,18 +1140,6 @@ ru: view_strikes: Просмотр предыдущих замечаний в адрес вашей учетной записи too_fast: Форма отправлена слишком быстро, попробуйте еще раз. use_security_key: Использовать ключ безопасности - authorize_follow: - already_following: Вы уже подписаны на эту учётную запись - already_requested: Вы уже отправили запрос на подписку на эту учётную запись - error: К сожалению, при поиске удалённой учётной записи возникла ошибка - follow: Подписаться - follow_request: 'Вы отправили запрос на подписку:' - following: 'Готово! Вы подписались на:' - post_follow: - close: Или просто закройте это окно. - return: Вернуться к профилю пользователя - web: Открыть в веб-версии - title: Подписаться на %{acct} challenge: confirm: Продолжить hint_html: "Подсказка: мы не будем спрашивать пароль повторно в течение часа." @@ -1117,6 +1216,10 @@ ru: your_appeal_rejected: Ваша апелляция отклонена domain_validator: invalid_domain: не является корректным доменным именем + edit_profile: + basic_information: Основная информация + hint_html: "Настройте то, что люди видят в вашем публичном профиле и рядом с вашими сообщениями. Другие люди с большей вероятностью подпишутся на Вас и будут взаимодействовать с вами, если у Вас заполнен профиль и добавлено изображение." + other: Прочее errors: '400': Ваш запрос был недействительным или неправильным. '403': У Вас нет доступа к просмотру этой страницы. @@ -1203,8 +1306,6 @@ ru: index: hint: Этот фильтр применяется для выбора отдельных постов, независимо от других критериев. Вы можете добавить больше записей в этот фильтр из веб-интерфейса. title: Отфильтрованные посты - footer: - trending_now: Актуально сейчас generic: all: Любой all_items_on_page_selected_html: @@ -1217,7 +1318,9 @@ ru: many: Выбрано %{count} элементов, соответствующих вашему запросу. one: Выбран %{count} элемент, соответствующий вашему запросу. other: Выбраны все %{count} элементов, соответствующих вашему запросу. + cancel: Отмена changes_saved_msg: Изменения успешно сохранены! + confirm: Подтвердить copy: Копировать delete: Удалить deselect: Снять выделение @@ -1235,24 +1338,62 @@ ru: many: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже one: Что-то здесь не так! Пожалуйста, прочитайте об ошибке ниже other: Что-то здесь не так! Пожалуйста, прочитайте о %{count} ошибках ниже - html_validator: - invalid_markup: 'невалидная разметка HTML: %{error}' imports: errors: + empty: Пустой CSV-файл + incompatible_type: Несовместимость с выбранным типом импорта invalid_csv_file: 'Неверный файл CSV. Ошибка: %{error}' over_rows_processing_limit: содержит более %{count} строк + too_large: Файл слишком большой + failures: Ошибки + imported: Импортирован + mismatched_types_warning: Возможно, вы выбрали неверный тип для этого импорта, пожалуйста, перепроверьте. modes: merge: Объединить merge_long: Сохранить имеющиеся данные и добавить новые. overwrite: Перезаписать overwrite_long: Перезаписать имеющиеся данные новыми. + overwrite_preambles: + blocking_html: Вы собираетесь заменить свой блок-лист на %{total_items} аккаунтов из %{filename}. + bookmarks_html: Вы собираетесь заменить свои закладки на %{total_items} постов из %{filename}. + domain_blocking_html: Вы собираетесь заменить ваш список блокировки доменов на %{total_items} доменов из %{filename}. + following_html: Вы собираетесь следить за %{total_items} аккаунтами из %{filename} и прекратить следить за всеми остальными. + lists_html: Вы собираетесь заменить ваши списки содержимым %{filename}. До %{total_items} аккаунты будут добавлены в новые списки. + muting_html: Вы собираетесь заменить список отключенных аккаунтов на %{total_items} аккаунтов из %{filename}. + preambles: + blocking_html: Вы собираетесь заблокировать до %{total_items} аккаунтов из %{filename}. + bookmarks_html: Вы собираетесь добавить до %{total_items} постов из %{filename} в свои закладки. + domain_blocking_html: Вы собираетесь блокировать до %{total_items} доменов от %{filename}. + following_html: Вы собираетесь следовать за %{total_items} аккаунтами из %{filename}. + lists_html: Вы собираетесь добавить до %{total_items} аккаунтов от %{filename} к вашим спискам. Новые списки будут созданы, если нет списка для добавления. + muting_html: Вы собираетесь отключить до %{total_items} аккаунтов из %{filename}. preface: Вы можете загрузить некоторые данные, например, списки людей, на которых Вы подписаны или которых блокируете, в Вашу учётную запись на этом узле из файлов, экспортированных с другого узла. + recent_imports: Недавно импортированное + states: + finished: Готово + in_progress: В процессе + scheduled: Запланировано + unconfirmed: Неподтвержденный + status: Статус success: Ваши данные были успешно загружены и будут обработаны с должной скоростью + time_started: Началось в + titles: + blocking: Импорт заблокированных аккаунтов + bookmarks: Импорт закладок + domain_blocking: Импорт заблокированных доменов + following: Импорт последующих аккаунтов + lists: Импортировать список + muting: Импорт отключенных аккаунтов + type: Тип импорта + type_groups: + constructive: Подписки и закладки + destructive: Блокировки и игнорируемые types: blocking: Список блокировки bookmarks: Закладки domain_blocking: Список доменных блокировок following: Подписки + lists: Списки muting: Список глушения upload: Загрузить invites: @@ -1281,7 +1422,7 @@ ru: title: Пригласить людей lists: errors: - limit: Вы достигли максимального числа списков + limit: Вы достигли максимального количества пользователей login_activities: authentication_methods: otp: приложение двухфакторной аутентификации @@ -1293,6 +1434,21 @@ ru: failed_sign_in_html: Неудачная попытка входа используя %{method} через %{browser} (%{ip}) successful_sign_in_html: Успешный вход используя %{method} через %{browser} (%{ip}) title: История входов + mail_subscriptions: + unsubscribe: + action: Да, отписаться + complete: Подписка отменена + confirmation_html: Вы уверены, что хотите отписаться от получения на ваш адрес электронной почты %{email} %{type} от Сообщества Mastodon %{domain}? Вы всегда можете заново подписаться на уведомления по электронной почте в разделе настройки . + emails: + notification_emails: + favourite: Избранные уведомления по электронной почте + follow: подписаться на уведомления по электронной почте + follow_request: Уведомлять по электронной почте о новых запросах + mention: получать уведомления с упоминаниями + reblog: подписаться на уведомления по электронной почте + resubscribe_html: Если вы отказались от подписки по ошибке, вы всегда можете заново подписаться на уведомления по электронной почте по этой ссылке . + success_html: Вы больше не будете получать %{type} для Mastodon на %{domain} к себе на почту %{email}. + title: Отписаться media_attachments: validations: images_and_video: Нельзя добавить видео к посту с изображениями @@ -1372,6 +1528,7 @@ ru: update: subject: "%{name} изменил(а) пост" notifications: + administration_emails: E-mail уведомления администратора email_events: События для e-mail уведомлений email_events_hint: 'Выберите события, для которых вы хотели бы получать уведомления:' other_settings: Остальные настройки уведомлений @@ -1408,12 +1565,22 @@ ru: expired: Опрос уже завершился invalid_choice: Выбранного варианта голосования не существует over_character_limit: каждый не вариант не может быть длиннее %{max} символов + self_vote: Вы не можете голосовать в своих опросах too_few_options: должно быть больше 1 варианта too_many_options: может содержать не больше %{max} вариантов preferences: other: Остальное posting_defaults: Настройки отправки по умолчанию public_timelines: Публичные ленты + privacy: + hint_html: "Настройте, как вы хотите, чтобы ваш профиль и ваши сообщения были найдены. Различные функции в Mastodon могут помочь вам охватить более широкую аудиторию, если они включены. Уделите время изучению этих настроек, чтобы убедиться, что они подходят для вашего случая использования." + privacy: Конфиденциальность + privacy_hint_html: Определите, какую информацию вы хотите раскрыть в интересах других. Люди находят интересные профили и приложения, просматривая список подписчиков других людей и узнавая, из каких приложений они публикуют свои сообщения, но вы можете предпочесть скрыть это. + reach: Охват + reach_hint_html: Укажите, хотите ли вы, чтобы новые люди обнаруживали вас и могли следить за вами. Хотите ли вы, чтобы ваши сообщения появлялись на экране Обзора? Хотите ли вы, чтобы другие люди видели вас в своих рекомендациях? Хотите ли вы автоматически принимать всех новых подписчиков или иметь возможность детально контролировать каждого из них? + search: Поиск + search_hint_html: Определите, как вас могут найти. Хотите ли вы, чтобы люди находили вас по тому, о чём вы публично писали? Хотите ли вы, чтобы люди за пределами Mastodon находили ваш профиль при поиске в Интернете? Следует помнить, что полное исключение из всех поисковых систем не может быть гарантировано для публичной информации. + title: Приватность и доступ privacy_policy: title: Политика конфиденциальности reactions: @@ -1426,6 +1593,7 @@ ru: confirm_remove_selected_followers: Вы уверены, что хотите удалить выбранных подписчиков? confirm_remove_selected_follows: Вы уверены, что хотите удалить выбранные подписки? dormant: Заброшенная + follow_failure: Не удалось подписаться за некоторыми из выбранных аккаунтов. follow_selected_followers: Подписаться на выбранных подписчиков followers: Подписчики following: Подписки @@ -1465,6 +1633,7 @@ ru: electron: Electron firefox: Firefox generic: Неизвестный браузер + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1474,6 +1643,7 @@ ru: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Неизвестный браузер weibo: Weibo current_session: Текущая сессия description: "%{browser} на %{platform}" @@ -1486,9 +1656,10 @@ ru: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: OS Кай linux: Linux mac: Mac - other: неизвестной платформе + unknown_platform: Неизвестная платформа windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1571,7 +1742,6 @@ ru: show_newer: Показать более новое show_older: Показать старые show_thread: Открыть обсуждение - sign_in_to_participate: Войдите, чтобы принять участие в дискуссии title: '%{name}: "%{quote}"' visibilities: direct: Адресованный @@ -1613,12 +1783,10 @@ ru: '7889238': 3 месяца min_age_label: Возрастной порог min_favs: Порог отметок «избранного» - min_favs_hint: Не удаляет ваши посты, у которых количество отметок «избранного» достигло указанного выше значения. Оставьте поле пустым, чтобы удалять посты независимо от количества отметок. + min_favs_hint: Не удалять ваши посты, у которых количество отметок «избранного» достигло указанного выше значения. Оставьте поле пустым, чтобы удалять посты независимо от количества отметок min_reblogs: Порог продвижений min_reblogs_hint: Не удаляет ваши посты, количество продвижений которых достигло указанного выше значения. Оставьте поле пустым, чтобы удалять посты независимо от количества продвижений. stream_entries: - pinned: Закреплённый пост - reblogged: продвинул(а) sensitive_content: Содержимое деликатного характера strikes: errors: @@ -1634,6 +1802,11 @@ ru: default: "%d %b %Y, %H:%M" month: "%m.%Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Превышена квота использования службы перевода в масштабах всего сервера. + too_many_requests: В последнее время в службу переводов поступает слишком много запросов. two_factor_authentication: add: Добавить disable: Отключить @@ -1713,13 +1886,18 @@ ru: title: Добро пожаловать на борт, %{name}! users: follow_limit_reached: Вы не можете подписаться больше, чем на %{limit} человек + go_to_sso_account_settings: Перейти к настройкам сторонних аккаунтов учетной записи invalid_otp_token: Введен неверный код двухфакторной аутентификации otp_lost_help_html: Если Вы потеряли доступ к обоим, свяжитесь с %{email} seamless_external_login: Вы залогинены через сторонний сервис, поэтому настройки e-mail и пароля недоступны. signed_in_as: 'Выполнен вход под именем:' verification: - explanation_html: 'Вы можете подтвердить владение любой из ссылок в таблице. Для этого страница по ссылке должна содержать обратную ссылку на ваш профиль Mastodon, а у самой ссылки должен атрибут rel="me". Текст ссылки значения не имеет. Вот пример:' + extra_instructions_html: Подсказка: Ссылка на вашем сайте может быть невидимой. Важной частью является rel="me", который предотвращает выдачу себя за другое лицо на сайтах с пользовательским контентом. Вы даже можете использовать тег link в заголовке страницы вместо a, но HTML должен быть доступен без выполнения JavaScript. + here_is_how: Вот как + hint_html: "Подтверждение личности на Mastodon доступно каждому. Основано на открытых веб-стандартах, отныне и навсегда бесплатно. Всё, что вам нужно, - это персональный сайт, по которому вас узнают. Когда вы ссылаетесь на этот сайт из своего профиля, мы проверим, что сайт ссылается на ваш профиль, и отобразим на нём визуальный индикатор." + instructions_html: Скопируйте и вставьте код ниже в HTML вашего сайта. Затем, добавьте адрес вашего веб сайта в одно из дополнительных полей на вкладке "Редактировать профиль" и сохраните изменения. verification: Верификация ссылок + verified_links: Ваши ссылки подтверждения webauthn_credentials: add: Добавить новый ключ безопасности create: diff --git a/config/locales/sa.yml b/config/locales/sa.yml index f8c64a7854..07ea4372a3 100644 --- a/config/locales/sa.yml +++ b/config/locales/sa.yml @@ -1,10 +1 @@ ---- sa: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/sc.yml b/config/locales/sc.yml index 3c6149be16..fa7603f2b1 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -106,8 +106,6 @@ sc: removed_header_msg: S'immàgine de intestatzione de %{username} est istada bogada resend_confirmation: already_confirmed: Custa persone est giai cunfirmada - send: Torra a imbiare messàgiu eletrònicu de cunfirmatzione - success: Messàgiu eletrònicu de cunfirmatzione imbiadu. reset: Reseta reset_password: Reseta sa crae resubscribe: Torra a sutascrìere @@ -493,7 +491,6 @@ sc: guide_link: https://crowdin.com/project/mastodon guide_link_text: Chie si siat podet contribuire. sensitive_content: Cuntenutu sensìbile - toot_layout: Dispositzione de is tuts application_mailer: notification_preferences: Muda is preferèntzias de posta salutation: "%{name}," @@ -509,14 +506,12 @@ sc: warning: Dae cara a custos datos. Non ddos cumpartzas mai cun nemos! your_token: S'identificadore tuo de atzessu auth: - change_password: Crae delete_account: Cantzella su contu delete_account_html: Si boles cantzellare su contu, ddu podes fàghere inoghe. T'amus a dimandare una cunfirmatzione. description: prefix_invited_by_user: "@%{name} t'at invitadu a custu serbidore de Mastodon!" prefix_sign_up: Registra·ti oe a Mastodon! suffix: Cun unu contu as a pòdere sighire gente, publicare e cuncambiare messàgios cun persones de cale si siat serbidore de Mastodon e àteru! - didnt_get_confirmation: No as retzidu su messàgiu de cunfirmatzione? dont_have_your_security_key: Non tenes sa crae de seguresa tua? forgot_password: Ti ses iscarèssidu de sa crae? invalid_reset_password_token: Su còdighe de autorizatzione pro resetare sa crae no est vàlidu o est iscadidu. Dimanda·nde un'àteru. @@ -532,14 +527,9 @@ sc: saml: SAML register: Registru registration_closed: "%{instance} no atzetat àteras persones" - resend_confirmation: Torra a imbiare is istrutziones de cunfirmatzione reset_password: Reseta sa crae security: Seguresa set_new_password: Cunfigura una crae noa - setup: - email_below_hint_html: Si s'indiritzu de posta eletrònica imbeniente no est curreta, dda podes mudare inoghe e as a retzire unu messàgiu de cunfirmatzione nou. - email_settings_hint_html: Messàgiu de cunfirmatzione imbiadu a %{email}. Si custu indiritzu de posta eletrònica no est curretu, ddu podes mudare dae is cunfiguratziones de su contu. - title: Cunfiguratzione status: account_status: Istadu de su contu confirming: Isetende chi sa posta eletrònica siat cumpletada. @@ -547,18 +537,6 @@ sc: redirecting_to: Su contu tuo est inativu pro ite in die de oe est torrende a indiritzare a %{acct}. too_fast: Formulàriu imbiadu tropu a lestru, torra a proare. use_security_key: Imprea una crae de seguresa - authorize_follow: - already_following: Ses giai sighende custu contu - already_requested: As giai imbiadu una dimanda de sighidura a custa persone - error: Faddina in sa chirca de su contu remotu - follow: Sighi - follow_request: 'As imbiadu una dimanda de sighidura a:' - following: 'Fatu! Immoe ses sighende a:' - post_follow: - close: O, podes serrare custa ventana. - return: Ammustra su profilu de custa persone - web: Bae a su situ web - title: Sighi a %{acct} challenge: confirm: Sighi hint_html: "Cussìgiu: No t'amus a torrare a dimandare sa crae in s'ora imbeniente." @@ -640,8 +618,6 @@ sc: storage: Immagasinamentu featured_tags: add_new: Agiunghe noa - errors: - limit: As giai evidentziadu sa cantidade màssima de etichetas hint_html: "Ite sunt is etichetas in evidèntzia? Sunt ammustradas in evidèntzia in su profilu pùblicu tuo e permitint a sa gente de navigare is messàgios pùblicos tuos in cussas etichetas ispetzìficas. Sunt unu traste perfetu pro tènnere unu registru de òperas creativas o progetos longos." filters: contexts: @@ -660,8 +636,6 @@ sc: title: Filtros new: title: Agiunghe unu filtru nou - footer: - trending_now: Est tendèntzia immoe generic: all: Totus changes_saved_msg: Modìficas sarvadas. @@ -672,8 +646,6 @@ sc: validation_errors: one: Calicuna cosa ancora no est andende. Bide sa faddina in bàsciu other: Calicuna cosa ancora no est andende. Bide is %{count} faddinas in bàsciu - html_validator: - invalid_markup: 'cuntenet etichetas HTML non vàlidas: %{error}' imports: errors: over_rows_processing_limit: cuntenet prus de %{count} filas @@ -713,9 +685,6 @@ sc: expires_at: Iscadit uses: Impreos title: Invita gente - lists: - errors: - limit: Cantidade màssima de listas cròmpida media_attachments: validations: images_and_video: Non si podet allegare unu vìdeu in una publicatzione chi cuntenet giai immàgines @@ -885,7 +854,6 @@ sc: ios: iOS linux: Linux mac: macOS - other: prataforma disconnota windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -950,7 +918,6 @@ sc: show_newer: Ammustra is prus noos show_older: Ammustra is prus betzos show_thread: Ammustra su tema - sign_in_to_participate: Identìfica·ti pro partetzipare in s'arresonada title: '%{name}: "%{quote}"' visibilities: direct: Deretu @@ -967,12 +934,9 @@ sc: '2629746': 1 mese '31556952': 1 annu '5259492': 2 meses - '604800': 1 week '63113904': 2 annos '7889238': 3 meses stream_entries: - pinned: Tut apicadu - reblogged: cumpartzidu sensitive_content: Cuntenutu sensìbile tags: does_not_match_previous_name: non cointzidet cun su nòmine anteriore @@ -1030,7 +994,6 @@ sc: seamless_external_login: As abertu sa sessione pro mèdiu de unu servìtziu esternu, e pro custa resone is cunfiguratziones de sa crae de intrada e de posta eletrònica non sunt a disponimentu. signed_in_as: 'Sessione aberta comente:' verification: - explanation_html: 'Ti podes verificare a sa sola comente mere de is ligòngios in is metadatos de su profilu tuo. Pro ddu fàghere su situ ligadu depet cuntènnere unu ligòngiu chi torret a su profilu de Mastodon tuo. Su ligòngiu in su situ depet tènnere un''atributu rel="me". Su testu cuntenutu in su ligòngiu no est de importu. Custu est un''esèmpiu:' verification: Verìfica webauthn_credentials: add: Agiunghe una crae de seguresa noa diff --git a/config/locales/sco.yml b/config/locales/sco.yml index accb1c9065..2199c5dbfd 100644 --- a/config/locales/sco.yml +++ b/config/locales/sco.yml @@ -122,8 +122,6 @@ sco: removed_header_msg: Successfully taen aff %{username}'s heider image resend_confirmation: already_confirmed: This uiser is awriddy confirmt - send: Resen confirmation email - success: Confirmation email successfully sent! reset: Reset reset_password: Reset passwird resubscribe: Resubscribe @@ -720,7 +718,6 @@ sco: approved: Approval needit fir sign up none: Naebody kin sign up open: Oniebody kin sign up - title: Server Settins site_uploads: delete: Delete uploadit file destroyed_msg: Site upload successfully deletit! @@ -915,7 +912,6 @@ sco: guide_link: https://crowdin.com/project/mastodon guide_link_text: Awbody kin contribute. sensitive_content: Sensitive content - toot_layout: Post leyoot application_mailer: notification_preferences: Chynge email preferences salutation: "%{name}," @@ -932,14 +928,12 @@ sco: your_token: Yer access token auth: apply_for_account: Request a accoont - change_password: Passwird delete_account: Delete accoont delete_account_html: If ye'r wantin tae delete yer accoont, ye kin dae it here. Ye'll get asked fir confirmation. description: prefix_invited_by_user: "@%{name} invites ye tae jyne this server o Mastodon!" prefix_sign_up: Sign up on Mastodon the day! suffix: Wi a accoont, ye'll be able tae follae fowk, post updates an exchynge messages wi uisers fae onie Mastodon server an mair! - didnt_get_confirmation: Didnae gey yer confirmation instructions? dont_have_your_security_key: Dinnae hae yer security key? forgot_password: Forgot yer passwird? invalid_reset_password_token: Passwird reset token isnae valid or expirit. Please request a new ane. @@ -957,17 +951,12 @@ sco: saml: SAML register: Sign up registration_closed: "%{instance} isnae acceptin onie new memmers" - resend_confirmation: Resen confirmation instructions reset_password: Reset yer passwird rules: preamble: Thir's set an enforced bi the %{domain} moderators. title: Some grun rules. security: Security set_new_password: Set new passwird - setup: - email_below_hint_html: If the email address ablow isnae correct, ye kin chynge it here an get a new confirmation email. - email_settings_hint_html: The confirmation email wis sent tae %{email}. If that email address isnae correct, ye kin chynge it in accoont settins. - title: Setup sign_up: preamble: Wi a accoont on this Mastodon server, ye'll be able tae follae onie ither person on the netwirk, regairdless o whaur their accoont is hostit. title: Let's get ye set up on %{domain}. @@ -980,18 +969,6 @@ sco: view_strikes: Luik at past strikes aginst yer accoont too_fast: Form submittit ower fast, try again. use_security_key: Uise security key - authorize_follow: - already_following: Ye'r awriddy follaein this accoont - already_requested: Ye'v awriddy sent a follae request tae that accoont - error: Unfortunately, there wis a error luikin up the remote accoont - follow: Follae - follow_request: 'Ye hae sent a follae request tae:' - following: 'Success! Ye''r noo follaein:' - post_follow: - close: Or, ye kin juist shut this windae. - return: Shaw the uiser's profile - web: Gang tae the wab - title: Follae %{acct} challenge: confirm: Continue hint_html: "wee tip: We wullnae ask ye fir yer passwird again fir the neist oor." @@ -1103,8 +1080,6 @@ sco: storage: Media storage featured_tags: add_new: Add new - errors: - limit: Ye'v awriddy featurt the maximum amoont o hashtags hint_html: "Whit's featurt hashtags? They get pit prominently on yer public profile an alloo fowk fir tae broose yer public posts specifically unner thae hashtags. They'r a braw tuil fir keepin track o creative warks or lang-term projects." filters: contexts: @@ -1148,8 +1123,6 @@ sco: index: hint: This filter applies tae select individual posts regairdless o ither criteria. Ye kin add mair posts tae this filter fae the wab interface. title: Filtert posts - footer: - trending_now: Trendin the noo generic: all: Aw all_items_on_page_selected_html: @@ -1172,8 +1145,6 @@ sco: validation_errors: one: Somethin isnae quite richt yit! Please luik ower the error ablow other: Somethin isnae quite richt yit! Please review %{count} errors ablow - html_validator: - invalid_markup: 'contains invalid HTML mairkup: %{error}' imports: errors: invalid_csv_file: 'Invalid CSV file. Error: %{error}' @@ -1214,9 +1185,6 @@ sco: expires_at: Expires uses: Uises title: Invite fowk - lists: - errors: - limit: Ye'v hit the maximum amoont o lists login_activities: authentication_methods: otp: twa-factor authentication app @@ -1420,7 +1388,6 @@ sco: ios: iOS linux: Linux mac: macOS - other: unkent platform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1491,7 +1458,6 @@ sco: show_newer: Shaw newer show_older: Shaw aulder show_thread: Shaw threid - sign_in_to_participate: Sign in fir tae tak pairt in the conversation title: '%{name}: "%{quote}"' visibilities: direct: Direck @@ -1533,12 +1499,9 @@ sco: '7889238': 3 month min_age_label: Age threshaud min_favs: Keep posts favouritit at least - min_favs_hint: Disnae delete onie o yer posts thit's got at least this amoont o favourites. Lea blank fir tae delete posts regairdless o their nummer o favourites min_reblogs: Keep posts heezed at least min_reblogs_hint: Disnae delete onie o yer posts thit's been heezed at least this nummer o times. Lea blank fir tae delete posts regairdless o their number o heezes stream_entries: - pinned: Preent post - reblogged: heezed sensitive_content: Sensitive content strikes: errors: @@ -1638,7 +1601,6 @@ sco: seamless_external_login: Ye'r logged in via a external service, sae passwird an email settins urnae available. signed_in_as: 'Signt in as:' verification: - explanation_html: 'Ye kin verify yersel as the ainer o the links in yer profile metadata. Fir that, the linkt wabsteid haes tae contain a link back tae yer Mastodon profile. The link back haes tae hae a rel="me" attribute. The text content o the link disnae maitter. Here a example:' verification: Verification webauthn_credentials: add: Add new security key diff --git a/config/locales/si.yml b/config/locales/si.yml index 18260cba9e..8f04533519 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -1,76 +1,73 @@ --- si: about: - about_mastodon_html: 'අනාගත සමාජ ජාලය: දැන්වීම් නැත, ආයතනික නිරීක්ෂණ නැත, සදාචාරාත්මක සැලසුම් සහ විමධ්‍යගත කිරීම! Mastodon සමඟ ඔබේ දත්ත අයිති කරගන්න!' - contact_missing: සකස් කර නැත + about_mastodon_html: 'අනාගත සමාජ ජාලය: දැන්වීම් නැත, සංස්ථානික අවේක්‍ෂණ නැත, යහපතට නිර්මිතයි සහ විමධ්‍යගතයි! මාස්ටඩන් සමඟ ඔබගේ දත්ත අයිතිව තබාගන්න!' + contact_missing: සකසා නැත contact_unavailable: අ/නොවේ - hosted_on: Mastodon %{domain}හි සත්කාරකත්වය දරයි + hosted_on: "%{domain} හරහා සත්කාරකත්‍වය ලබයි" + title: පිළිබඳව accounts: follow: අනුගමනය followers: one: අනුගාමිකයා other: අනුගාමිකයින් - following: අනුගමනය + following: අනුගමන instance_actor_flash: මෙම ගිණුම සේවාදායකයම නියෝජනය කිරීමට භාවිතා කරන අතථ්‍ය නළුවෙකු වන අතර කිසිදු තනි පරිශීලකයෙකු නොවේ. එය ෆෙඩරේෂන් අරමුණු සඳහා භාවිතා කරන අතර අත්හිටුවිය යුතු නොවේ. last_active: අවසාන ක්රියාකාරී link_verified_on: මෙම සබැඳියේ හිමිකාරිත්වය %{date}හි පරීක්ෂා කරන ලදී - nothing_here: මෙහි කිසිත් නැත! - pin_errors: - following: ඔබට අනුමත කිරීමට අවශ්‍ය පුද්ගලයා ඔබ දැනටමත් අනුගමනය කරමින් සිටිය යුතුය + nothing_here: මෙහි කිසිවක් නැත! posts: one: ලිපිය other: ලිපි posts_tab_heading: ලිපි admin: account_actions: - action: ක්‍රියාව සිදු කරන්න - title: "%{acct}මත මධ්‍යස්ථ ක්‍රියාව සිදු කරන්න" + action: ක්‍රියාමාර්ගයක් ගන්න account_moderation_notes: - create: සටහන හැරයන්න - created_msg: මධ්‍යස්ථ සටහන සාර්ථකව සාදන ලදී! - destroyed_msg: මධ්‍යස්ථ සටහන සාර්ථකව විනාශ විය! + create: සටහනක් තබන්න accounts: add_email_domain_block: වි-තැපැල් වසම අවහිර කරන්න - approve: අනුමත කරන්න + approve: අනුමැතිය approved_msg: "%{username}හි ලියාපදිංචි වීමේ යෙදුම සාර්ථකව අනුමත කරන ලදී" are_you_sure: ඔබට විශ්වාසද? - avatar: අවතාරය + avatar: ප්‍රතිරූපය by_domain: වසම change_email: + changed_msg: වි-තැපෑල සාර්ථකව වෙනස් විය! current_email: වත්මන් වි-තැපෑල label: වි-තැපෑල වෙනස් කරන්න new_email: නව විද්‍යුත් තැපෑල submit: වි-තැපෑල වෙනස් කරන්න title: "%{username} සඳහා වි-තැපෑල වෙනස් කරන්න" + change_role: + changed_msg: භූමිකාව සාර්ථකව වෙනස් විය! + label: භූමිකාව වෙනස් කරන්න + no_role: නව භූමිකාව + title: "%{username} සඳහා භූමිකාව වෙනස් කරන්න" confirm: සනාථ කරන්න - confirmed: තහවුරු කර ඇත + confirmed: සනාථ කර ඇත confirming: සනාථ කරමින් custom: අභිරුචි delete: දත්ත මකන්න - deleted: මකා දමන ලදී - demote: පහත් කරන්න + deleted: මකා ඇත destroyed_msg: "%{username}හි දත්ත ඉක්මනින් මකා දැමීමට පෝලිම් කර ඇත" - disable: කැටි කරන්න disable_sign_in_token_auth: ඊමේල් ටෝකන් සත්‍යාපනය අක්‍රීය කරන්න disable_two_factor_authentication: 2FA අබල කරන්න - disabled: ශීත කළ display_name: ප්රදර්ශන නාමය domain: වසම edit: සංස්කරණය email: විද්‍යුත් තැපෑල email_status: වි-තැපෑලෙහි තත්වය - enable: කැටි කිරීම ඉවත් කරන්න enable_sign_in_token_auth: විද්‍යුත් තැපෑල ටෝකන් සත්‍යාපනය සබල කරන්න enabled: සබල කර ඇත enabled_msg: "%{username}ගේ ගිණුම සාර්ථකව අත්හිටුවා ඇත" followers: අනුගාමිකයින් - follows: පහත සඳහන් header: ශීර්ෂය inbox_url: එන ලිපි URL - invite_request_text: එක්වීම සඳහා + invite_request_text: එක්වීමට හේතුව invited_by: විසින් ආරාධනා කරන ලදී ip: අ.ජා. කෙ. (IP) - joined: එක් වී ඇත + joined: එක් වූ දිනය location: all: සියල්ල local: ස්ථානීය @@ -84,12 +81,13 @@ si: moderation: active: සක්‍රීයයි all: සියල්ල - pending: පොරොත්තුවෙන් + disabled: අබලයි + pending: පොරොත්තු suspended: අත්හිටුවන ලදි - title: මධ්යස්ථභාවය - moderation_notes: මධ්‍යස්ථ සටහන් + title: මැදිහත්කරණය + moderation_notes: මැදිහත්කරණ සටහන් most_recent_activity: වඩාත්ම මෑත ක්රියාකාරිත්වය - most_recent_ip: ඊට වඩා අ.ජා.කේ.(IP) + most_recent_ip: මෑත අ.ජා.කෙ. (IP) no_account_selected: කිසිවක් තෝරා නොගත් බැවින් ගිණුම් කිසිවක් වෙනස් කර නැත no_limits_imposed: සීමාවන් පනවා නැත not_subscribed: දායක වී නැත @@ -99,39 +97,36 @@ si: previous_strikes_description_html: one: මෙම ගිණුමට එක වර්ජනයක් ඇත. other: මෙම ගිණුමේ වර්ජන %{count} ඇත. - promote: ප්රවර්ධනය කරන්න protocol: කෙටුම්පත - public: ප්රසිද්ධ + public: ප්‍රසිද්ධ push_subscription_expires: පුෂ් දායකත්වය කල් ඉකුත් වේ - redownload: පැතිකඩ නැවුම්කරන්න + redownload: පැතිකඩ නැවුම් කරන්න redownloaded_msg: මූලාරම්භයේ සිට %{username}හි පැතිකඩ සාර්ථකව නැවුම් කරන ලදී reject: ප්‍රතික්ෂේප rejected_msg: "%{username}හි ලියාපදිංචි වීමේ අයදුම්පත සාර්ථකව ප්‍රතික්ෂේප විය" - remove_avatar: අවතාරය ඉවත් කරන්න + remove_avatar: ප්‍රතිරූපය ඉවත් කරන්න remove_header: ශීර්ෂය ඉවත්කරන්න removed_avatar_msg: "%{username}ගේ අවතාර රූපය සාර්ථකව ඉවත් කරන ලදී" removed_header_msg: "%{username}හි ශීර්ෂ රූපය සාර්ථකව ඉවත් කරන ලදී" resend_confirmation: already_confirmed: මෙම පරිශීලකයා දැනටමත් තහවුරු කර ඇත - send: තහවුරුකිරීමේ විද්යුත් තැපැල් පණිවිඩය නැවත එවන්න - success: තහවුරු කිරීමේ විද්‍යුත් තැපෑල සාර්ථකව යවා ඇත! reset: නැවත සකසන්න - reset_password: මුරපදය නැවතසකසන්න + reset_password: මුරපදය යළි සකසන්න resubscribe: නැවත දායක වන්න + role: භූමිකාව search: සොයන්න search_same_email_domain: එකම විද්‍යුත් තැපැල් වසම සහිත වෙනත් පරිශීලකයන් search_same_ip: එකම IP සහිත වෙනත් පරිශීලකයන් + security: ආරක්‍ෂාව security_measures: only_password: මුරපදය පමණි password_and_2fa: මුරපදය සහ 2FA - sensitive: සංවේදී - sensitized: සංවේදී ලෙස සලකුණු කර ඇත + sensitized: සංවේදී බව සලකුණු කර ඇත shared_inbox_url: බෙදාගත් එන ලිපි URL show: created_reports: වාර්තා හැදුවා targeted_reports: වෙනත් අය විසින් වාර්තා කරන ලදී - silence: සීමාව - silenced: සීමාසහිත + silenced: සීමා සහිතයි statuses: ලිපි strikes: පෙර වැඩ වර්ජන subscribe: දායක වන්න @@ -149,26 +144,25 @@ si: unsilenced_msg: "%{username}ගිණුමේ සීමාව සාර්ථකව ඉවත් කරන ලදී" unsubscribe: දායක නොවන්න unsuspended_msg: "%{username}ගිණුම සාර්ථකව අත්හිටුවන ලදී" - username: පරිශීලක නාමය + username: පරිශ්‍රීලක නාමය view_domain: වසම සඳහා සාරාංශය බලන්න warn: අවවාද web: වියමන - whitelisted: ෆෙඩරේෂන් සඳහා අවසර ඇත + whitelisted: ඒකාබද්ධයට ඉඩ දී ඇත action_logs: action_types: approve_appeal: අභියාචනය අනුමත කරන්න approve_user: පරිශීලක අනුමත කරන්න assigned_to_self_report: වාර්තාව පැවරීම - change_email_user: පරිශීලකයින්ට වි-තැපෑල වෙනස් කරන්න confirm_user: පරිශීලක තහවුරු කරන්න create_account_warning: අවවාදයක් සාදන්න create_announcement: නිවේදනය සාදන්න create_custom_emoji: අභිරුචි ඉමොජි සාදන්න - create_domain_allow: වසම් ඉඩදීමක් සාදන්න - create_domain_block: වසම් අවහිරයක් සාදන්න + create_domain_allow: වසමකට ඉඩදීම සාදන්න create_email_domain_block: ඊමේල් ඩොමේන් බ්ලොක් එකක් සාදන්න create_ip_block: අ.ජා. කෙ. (IP) නීතියක් සාදන්න create_unavailable_domain: ලබා ගත නොහැකි වසම සාදන්න + create_user_role: භූමිකාව සාදන්න demote_user: පරිශීලකයා පහත් කරන්න destroy_announcement: නිවේදනය මකන්න destroy_custom_emoji: අභිරුචි ඉමොජි මකන්න @@ -177,26 +171,24 @@ si: destroy_email_domain_block: ඊමේල් ඩොමේන් බ්ලොක් එක මකන්න destroy_instance: වසම පිරිසිදු කරන්න destroy_ip_block: IP රීතිය මකන්න - destroy_status: පළ කිරීම මකන්න + destroy_status: ලිපිය මකන්න destroy_unavailable_domain: ලබා ගත නොහැකි වසම මකන්න disable_2fa_user: 2FA අබල කරන්න - disable_custom_emoji: අභිරුචි ඉමොජි අබල කරන්න + disable_custom_emoji: අභිරුචි ඉමෝජි අබල කරන්න disable_sign_in_token_auth_user: පරිශීලකයා සඳහා ඊමේල් ටෝකන් සත්‍යාපනය අක්‍රීය කරන්න - disable_user: පරිශීලනය කරන්න - enable_custom_emoji: අභිරුචි ඉමොජි සබල කරන්න + enable_custom_emoji: අභිරුචි ඉමෝජි සබල කරන්න enable_sign_in_token_auth_user: පරිශීලකයා සඳහා විද්‍යුත් තැපෑල ටෝකන් සත්‍යාපනය සක්‍රීය කරන්න enable_user: පරිශීලක සබල කරන්න memorialize_account: ගිණුම අනුස්මරණ කරන්න - promote_user: පරිශීලක ප්රවර්ධනය කරන්න reject_appeal: අභියාචනය ප්‍රතික්ෂේප කරන්න reject_user: පරිශීලක ප්‍රතික්ෂේප කරන්න - remove_avatar_user: Avatar ඉවත් කරන්න - reopen_report: වාර්තාව නැවත විවෘත කරන්න - reset_password_user: මුරපදය නැවතසකසන්න + remove_avatar_user: ප්‍රතිරූපය ඉවත් කරන්න + reopen_report: වාර්තාව නැවත අරින්න + reset_password_user: මුරපදය යළි සකසන්න resolve_report: වාර්තාව විසඳන්න sensitive_account: බල සංවේදී ගිණුම silence_account: ගිණුම සීමා කරන්න - suspend_account: සැලකිය යුතු + suspend_account: ගිණුම අත්හිටුවන්න unassigned_report: වාර්තාව පැවරීම ඉවත් කරන්න unblock_email_account: ඊමේල් ලිපිනය අවහිර කිරීම ඉවත් කරන්න unsensitive_account: බල සංවේදී ගිණුම අහෝසි කරන්න @@ -205,9 +197,8 @@ si: update_announcement: නිවේදනය යාවත්කාල කරන්න update_custom_emoji: අභිරුචි ඉමොජි යාවත්කාලීන කරන්න update_domain_block: ඩොමේන් බ්ලොක් යාවත්කාලීන කරන්න - update_status: පළ කිරීම යාවත්කාලීන කරන්න + update_status: ලිපිය යාවත්කාල කරන්න actions: - approve_appeal_html: "%{name} අනුමත මධ්‍යස්ථ තීරණ අභියාචනය %{target}සිට" approve_user_html: "%{name} අනුමත ලියාපදිංචිය %{target}සිට" assigned_to_self_report_html: "%{name} වාර්තාව %{target} තමන්ටම පවරා ඇත" change_email_user_html: "%{name} පරිශීලක %{target}ගේ ඊමේල් ලිපිනය වෙනස් කළේය" @@ -227,7 +218,6 @@ si: destroy_email_domain_block_html: "%{name} අවහිර නොකළ විද්‍යුත් තැපැල් වසම %{target}" destroy_instance_html: "%{name} පිරිසිදු කරන ලද වසම %{target}" destroy_ip_block_html: IP %{target}සඳහා %{name} මකා දැමූ රීතිය - destroy_status_html: "%{name} පෝස්ට් %{target}විසින් ඉවත් කරන ලදී" destroy_unavailable_domain_html: "%{name} වසම %{target}වෙත බෙදා හැරීම නැවත ආරම්භ විය" disable_2fa_user_html: "%{name} පරිශීලක %{target}සඳහා සාධක දෙකක අවශ්‍යතාවය අක්‍රීය කර ඇත" disable_custom_emoji_html: "%{name} ආබාධිත ඉමොජි %{target}" @@ -238,27 +228,25 @@ si: enable_user_html: පරිශීලක %{target}සඳහා %{name} සක්‍රීය පුරනය වීම memorialize_account_html: "%{name} %{target}ගේ ගිණුම සිහිවටන පිටුවක් බවට පත් කළේය" promote_user_html: "%{name} උසස් පරිශීලක %{target}" - reject_appeal_html: "%{name} %{target}සිට මධ්‍යස්ථ තීරණ අභියාචනය ප්‍රතික්ෂේප කරන ලදී" reject_user_html: "%{name} %{target}සිට ලියාපදිංචි වීම ප්‍රතික්ෂේප විය" remove_avatar_user_html: "%{name} %{target}ගේ අවතාරය ඉවත් කරන ලදී" reopen_report_html: "%{name} නැවත විවෘත කළ වාර්තාව %{target}" reset_password_user_html: "%{name} පරිශීලක %{target}හි මුරපදය යළි පිහිටුවන්න" resolve_report_html: "%{name} විසඳන ලද වාර්තාව %{target}" - sensitive_account_html: "%{name} %{target}හි මාධ්‍ය සංවේදී ලෙස සලකුණු කර ඇත" + sensitive_account_html: "%{target}ගේ මාධ්‍ය සංවේදී බව %{name} සලකුණු කර ඇත" silence_account_html: "%{name} සීමිත %{target}ගිණුමක්" suspend_account_html: "%{name} %{target}ගේ ගිණුම අත්හිටුවා ඇත" unassigned_report_html: "%{name} පවරා නොදුන් වාර්තාව %{target}" unblock_email_account_html: "%{name} %{target}ගේ ඊමේල් ලිපිනය අවහිර කිරීම ඉවත් කරන ලදී" - unsensitive_account_html: "%{name} සලකුණු නොකළ %{target}ගේ මාධ්‍ය සංවේදී ලෙස" + unsensitive_account_html: "%{target}ගේ මාධ්‍ය සංවේදී බව %{name} ඉවත් කර ඇත" unsilence_account_html: "%{target}ගිණුමේ %{name} undid සීමාව" unsuspend_account_html: "%{name} අත්හිටුවන ලද %{target}ගිණුම" update_announcement_html: "%{name} යාවත්කාලීන නිවේදනය %{target}" update_custom_emoji_html: "%{name} යාවත්කාලීන කළ ඉමොජි %{target}" update_domain_block_html: "%{target}සඳහා %{name} යාවත්කාලීන කරන ලද වසම් වාරණ" - update_status_html: "%{name} %{target}යාවත්කාලීන කරන ලද පළ කිරීම" empty: ලඝු-සටහන් හමු නොවිණි. - filter_by_action: ක්‍රියාව අනුව පෙරන්න - filter_by_user: පරිශීලක අනුව පෙරන්න + filter_by_action: ක්‍රියාමාර්ගය අනුව පෙරන්න + filter_by_user: පරිශ්‍රීලකයා අනුව පෙරන්න title: විගණන සටහන announcements: destroyed_msg: නිවේදනය සාර්ථකව මකා ඇත! @@ -281,22 +269,22 @@ si: assign_category: කාණ්ඩය පැවරීම by_domain: වසම copied_msg: ඉමොජි වල දේශීය පිටපත සාර්ථකව සාදන ලදී - copy: පිටපත් + copy: පිටපතක් copy_failed_msg: එම ඉමොජියේ දේශීය පිටපතක් සෑදීමට නොහැකි විය create_new_category: නව ප්‍රවර්ගයක් සාදන්න created_msg: ඉමොජි සාර්ථකව නිර්මාණය කළා! delete: මකන්න destroyed_msg: Emojo සාර්ථකව විනාශ විය! disable: අබල කරන්න - disabled: අබල කර ඇත + disabled: අබලයි disabled_msg: එම ඉමොජිය සාර්ථකව අබල කරන ලදී - emoji: ඉමොජි + emoji: ඉමෝජි enable: සබල කරන්න - enabled: සබල කර ඇත + enabled: සබලයි enabled_msg: එම ඉමොජි සාර්ථකව සබල කරන ලදී image_hint: PNG හෝ GIF %{size}දක්වා list: ලැයිස්තුව - listed: ලැයිස්තුගත කර ඇත + listed: ලැයිස්තුගත new: title: නව අභිරුචි ඉමොජි එක් කරන්න not_permitted: මෙම ක්‍රියාව සිදු කිරීමට ඔබට අවසර නැත @@ -313,9 +301,9 @@ si: dashboard: active_users: ක්රියාකාරී පරිශීලකයන් interactions: අන්තර්ක්රියා - media_storage: මාධ්ය ගබඩාව - new_users: නව පරිශීලකයන් - opened_reports: වාර්තා විවෘත විය + media_storage: මාධ්‍ය ආචයනය + new_users: නව පරිශ්‍රීලකයින් + opened_reports: විවෘත වාර්තා pending_appeals_html: one: "%{count} අභියාචනයක් බලාපොරොත්තු වේ" other: "%{count} අභියාචනා පොරොත්තු" @@ -331,11 +319,11 @@ si: resolved_reports: වාර්තා විසඳා ඇත software: මෘදුකාංගය sources: ලියාපදිංචි මූලාශ්‍ර - space: අවකාශය භාවිතය + space: ඉඩ භාවිතය title: උපකරණ පුවරුව top_languages: ඉහළම ක්රියාකාරී භාෂා top_servers: ඉහළම ක්රියාකාරී සේවාදායකයන් - website: වෙබ් අඩවිය + website: අඩවිය disputes: appeals: empty: අභියාචනා හමු නොවීය. @@ -355,7 +343,6 @@ si: existing_domain_block_html: ඔබ දැනටමත් %{name}මත දැඩි සීමාවන් පනවා ඇත, ඔබට එය අවහිර කිරීම ඉවත් කිරීමට අවශ්‍යයි. new: create: බ්ලොක් එකක් සාදන්න - hint: ඩොමේන් බ්ලොක් එක දත්ත සමුදාය තුල ගිණුම් ඇතුලත් කිරීම් නිර්මාණය වීම වලක්වන්නේ නැත, නමුත් එම ගිණුම් වලට ප්‍රතික්‍රියාශීලීව සහ ස්වයංක්‍රීයව විශේෂිත මධ්‍යස්ථ ක්‍රම යොදනු ඇත. severity: noop: කිසිවක් නැත suspend: අත්හිටුවන්න @@ -363,7 +350,6 @@ si: obfuscate: අපැහැදිලි වසම් නාමය obfuscate_hint: වසම් සීමාවන් ලැයිස්තුව ප්‍රචාරණය කිරීම සබල කර ඇත්නම් ලැයිස්තුවේ වසම් නාමය අර්ධ වශයෙන් අපැහැදිලි කරන්න private_comment: පුද්ගලික අදහස - private_comment_hint: පරිපාලකයින් විසින් අභ්‍යන්තර භාවිතය සඳහා මෙම වසම් සීමාව ගැන අදහස් දක්වන්න. public_comment: ප්‍රසිද්ධ අදහස public_comment_hint: වසම් සීමාවන් ලැයිස්තුව ප්‍රචාරණය කිරීම සබල කර ඇත්නම්, සාමාන්‍ය ජනතාව සඳහා මෙම වසම් සීමාව ගැන අදහස් දක්වන්න. reject_media: මාධ්‍ය ගොනු ප්‍රතික්ෂේප කරන්න @@ -397,7 +383,7 @@ si: status: තත්‍වය suppress: අනුගමනය නිර්දේශය යටපත් කරන්න suppressed: යටපත් කළා - title: නිර්දේශ අනුගමනය කරන්න + title: අනුගමනයට නිර්දේශ unsuppress: නිර්දේශ පිළිපැදීම ප්‍රතිසාධනය කරන්න instances: availability: @@ -417,16 +403,16 @@ si: by_domain: වසම confirm_purge: ඔබට මෙම වසමෙන් දත්ත ස්ථිරවම මැකීමට අවශ්‍ය බව විශ්වාසද? content_policies: - comment: අභ්යන්තර සටහන + comment: අභ්‍යන්තර සටහන description_html: ඔබට මෙම වසම සහ එහි ඕනෑම උප වසමකින් සියලුම ගිණුම් වලට අදාළ වන අන්තර්ගත ප්‍රතිපත්ති නිර්වචනය කළ හැක. policies: reject_media: මාධ්‍ය ප්‍රතික්ෂේප කරන්න reject_reports: වාර්තා ප්‍රතික්ෂේප කරන්න silence: සීමාව suspend: අත්හිටුවන්න - policy: ප්රතිපත්ති + policy: ප්‍රතිපත්තිය reason: පොදු හේතුව - title: අන්තර්ගත ප්රතිපත්ති + title: අන්තර්ගත ප්‍රතිපත්ති dashboard: instance_accounts_dimension: වැඩිපුරම අනුගමනය කරන ගිණුම් instance_accounts_measure: ගබඩා කර ඇති ගිණුම් @@ -445,7 +431,7 @@ si: unavailable: ලබා ගත නොහැක delivery_available: බෙදා හැරීම ලබා ගත හැකිය delivery_error_days: බෙදා හැරීමේ දෝෂ සහිත දින - delivery_error_hint: දින %{count} ක් සඳහා බෙදා හැරීම කළ නොහැකි නම්, එය ස්වයංක්‍රීයව බෙදා හැරිය නොහැකි ලෙස ලකුණු කරනු ලැබේ. + delivery_error_hint: දවස් %{count} කින් බාරදීමට නොහැකි වුවහොත්, බාරදීමට නොහැකි බව ස්වයංක්‍රීයව සලකුණු වේ. destroyed_msg: "%{domain} සිට දත්ත දැන් ආසන්න මකාදැමීම සඳහා පෝලිම් කර ඇත." empty: වසම් කිසිවක් හමු නොවීය. known_accounts: @@ -454,7 +440,7 @@ si: moderation: all: සියල්ල limited: සීමා සහිතයි - title: මධ්යස්ථභාවය + title: මැදිහත්කරණය private_comment: පුද්ගලික අදහස public_comment: ප්‍රසිද්ධ අදහස purge: පිරිසිදු කරන්න @@ -464,13 +450,12 @@ si: total_followed_by_them: ඔවුන් විසින් අනුගමනය කරන ලදී total_followed_by_us: අප විසින් අනුගමනය කරන ලදී total_reported: ඔවුන් ගැන වාර්තා - total_storage: මාධ්ය ඇමුණුම් + total_storage: මාධ්‍ය ඇමුණුම් totals_time_period_hint_html: පහත දැක්වෙන එකතුවෙහි සියලු කාලය සඳහා දත්ත ඇතුළත් වේ. invites: deactivate_all: සියල්ල අක්‍රිය කරන්න filter: all: සියල්ල - available: පවතින expired: ඉකුත් වී ඇත title: පෙරහන title: ඇරයුම් @@ -494,15 +479,13 @@ si: relays: add_new: නව රිලේ එක් කරන්න delete: මකන්න - description_html: "ෆෙඩරේෂන් රිලේ යනු එයට දායක වී ප්‍රකාශයට පත් කරන සේවාදායකයන් අතර විශාල ප්‍රසිද්ධ පළ කිරීම් හුවමාරු කරන අතරමැදි සේවාදායකයකි. එය කුඩා සහ මධ්‍යම සේවාදායකයන්ට fediverseවෙතින් අන්තර්ගතය සොයා ගැනීමට උදවු කළ හැකි අතර, එසේ නොමැති නම් දේශීය පරිශීලකයින්ට දුරස්ථ සේවාදායකයන් මත වෙනත් පුද්ගලයින් හස්තීයව අනුගමනය කිරීම අවශ්‍ය වේ." disable: අබල කරන්න - disabled: අබල කර ඇත + disabled: අබලයි enable: සබල කරන්න - enable_hint: සක්‍රිය කළ පසු, ඔබේ සේවාදායකය මෙම රිලේ වෙතින් සියලුම පොදු පළ කිරීම් සඳහා දායක වන අතර, මෙම සේවාදායකයේ පොදු පළ කිරීම් එයට යැවීම ආරම්භ කරනු ඇත. enabled: සබල කර ඇත inbox_url: රිලේ URL pending: රිලේ අනුමැතිය සඳහා රැඳී සිටිමින් - save_and_enable: සුරකින්න සහ සක්රිය කරන්න + save_and_enable: සුරකින්න හා සබල කරන්න setup: රිලේ සම්බන්ධතාවයක් සකසන්න signatures_not_enabled: ආරක්ෂිත මාදිලිය හෝ සීමිත ෆෙඩරේෂන් මාදිලිය සබල කර ඇති අතර රිලේ නිවැරදිව ක්‍රියා නොකරනු ඇත status: තත්වය @@ -518,40 +501,37 @@ si: action_log: විගණන සටහන action_taken_by: විසින් ගන්නා ලද පියවර actions: - delete_description_html: වාර්තා කරන ලද පළ කිරීම් මකා දැමෙනු ඇති අතර එම ගිණුමේම අනාගත උල්ලංඝනයන් තීව්‍ර කිරීමට ඔබට උදවු කිරීමට වර්ජනයක් වාර්තා කරනු ඇත. - mark_as_sensitive_description_html: වාර්තා කරන ලද පළ කිරීම් වල මාධ්‍ය සංවේදී ලෙස සලකුණු කරනු ලබන අතර එම ගිණුම මගින් අනාගත උල්ලංඝනයන් උත්සන්න කිරීමට ඔබට උපකාර කිරීමට වර්ජනයක් වාර්තා කරනු ඇත. other_description_html: ගිණුමේ හැසිරීම පාලනය කිරීම සහ වාර්තා කළ ගිණුමට සන්නිවේදනය අභිරුචිකරණය කිරීම සඳහා තවත් විකල්ප බලන්න. resolve_description_html: වාර්තා කරන ලද ගිණුමට එරෙහිව කිසිදු ක්‍රියාමාර්ගයක් නොගනු ඇත, වැඩ වර්ජනයක් වාර්තා නොකෙරේ, වාර්තාව වසා දමනු ඇත. actions_description_html: මෙම වාර්තාව විසඳීමට ගත යුතු ක්‍රියාමාර්ගය තීරණය කරන්න. ඔබ වාර්තා කරන ලද ගිණුමට එරෙහිව දණ්ඩනීය ක්‍රියාමාර්ගයක් ගන්නේ නම්, Spam කාණ්ඩය තෝරාගත් විට හැර, ඔවුන්ට විද්‍යුත් තැපෑලෙන් දැනුම්දීමක් යවනු ලැබේ. add_to_report: වාර්තා කිරීමට තවත් එක් කරන්න are_you_sure: ඔබට විශ්වාසද? assign_to_self: මට පවරන්න - assigned: පවරා ඇති උපපරිපාලක by_target_domain: වාර්තා කළ ගිණුමෙහි වසම - category: වර්ගය + cancel: අවලංගු + category: ප්‍රවර්ගය category_description_html: මෙම ගිණුම සහ/හෝ අන්තර්ගතය වාර්තා කළ හේතුව වාර්තා කළ ගිණුම සමඟ සන්නිවේදනයේ සඳහන් කරනු ඇත comment: none: කිසිවක් නැත comment_description_html: 'වැඩි විස්තර සැපයීම සඳහා, %{name} ලිවීය:' created_at: වාර්තා කර ඇත - delete_and_resolve: පළ කිරීම් මකන්න - forwarded: යොමු කළා - forwarded_to: "%{domain}වෙත යොමු කරන ලදී" - mark_as_resolved: විසඳා ඇති ලෙස ලකුණු කරන්න - mark_as_sensitive: සංවේදී ලෙස ලකුණු කරන්න - mark_as_unresolved: නොවිසඳුනු ලෙස ලකුණු කරන්න - no_one_assigned: කිසි කෙනෙක නැහැ + delete_and_resolve: ලිපි මකන්න + forwarded: හරවා යවා ඇත + forwarded_to: "%{domain} වෙත හරවා යැවිණි" + mark_as_resolved: විසඳූ බව යොදන්න + mark_as_sensitive: සංවේදී බව යොදන්න + mark_as_unresolved: නොවිසඳූ බව යොදන්න + no_one_assigned: කිසිවෙක් නැත notes: create: සටහන එකතු කරන්න - create_and_resolve: සටහන සමඟ විසඳන්න - create_and_unresolve: සටහනක් සමඟ නැවත විවෘත කරන්න + create_and_resolve: සටහනක් සමඟ විසඳන්න + create_and_unresolve: සටහනක් සමඟ නැවත අරින්න delete: මකන්න placeholder: ගෙන ඇති ක්‍රියාමාර්ග, හෝ වෙනත් අදාළ යාවත්කාලීන විස්තර කරන්න... title: සටහන් - notes_description_html: අනෙකුත් උපපරිපාලකයින්ට සහ ඔබේ අනාගතයට සටහන් බලන්න සහ තබන්න quick_actions_description_html: 'වාර්තා කළ අන්තර්ගතය බැලීමට ඉක්මන් ක්‍රියාමාර්ගයක් ගන්න හෝ පහළට අනුචලනය කරන්න:' remote_user_placeholder: "%{instance}සිට දුරස්ථ පරිශීලකයා" - reopen: වාර්තාව නැවත විවෘත කරන්න + reopen: වාර්තාව නැවත අරින්න report: "@%{id} වාර්තා කරන්න" reported_account: වාර්තා කළ ගිණුම reported_by: විසින් වාර්තා @@ -564,17 +544,52 @@ si: target_origin: වාර්තා කළ ගිණුමේ ආරම්භය title: වාර්තා unassign: පැවරීම ඉවත් කරන්න + unknown_action_msg: 'නොදන්නා ක්‍රියාමාර්ගයකි: %{action}' unresolved: නොවිසඳී ඇත updated_at: යාවත්කාලීන කරන ලදී view_profile: පැතිකඩ බලන්න + roles: + categories: + administration: පරිපාලනය + devops: DevOps + invites: ඇරයුම් + moderation: මැදිහත්කරණය + special: විශේෂ + delete: මකන්න + permissions_count: + one: අවසර %{count} + other: අවසර %{count} + privileges: + administrator: පරිපාලක + delete_user_data: පරිශ්‍රීලක දත්ත මකන්න + invite_users: ආරාධනා කරන්න + manage_announcements: නිවේදනය කළමනාකරණය + manage_federation: ඒකාබද්ධ කළමනාකරණය + manage_invites: ආරාධනා කළමනාකරණය + manage_reports: වාර්තා කළමනාකරණය + manage_roles: භූමිකා කළමනාකරණය + manage_rules: නීති කළමනාකරණය + manage_settings: සැකසුම් කළමනාකරණය + manage_user_access: ප්‍රවේශය කළමනාකරණය + manage_users: පරිශ්‍රීලකයින් කළමනාකරණය + view_dashboard: උපකරණ පුවරුව බලන්න + view_devops: DevOps + title: භූමිකා rules: - add_new: නීතිය එකතු කරන්න delete: මකන්න description_html: බොහෝ දෙනා සේවා කොන්දේසි කියවා එකඟ වූ බව ප්‍රකාශ කරන අතර, සාමාන්‍යයෙන් මිනිසුන් ගැටලුවක් පැනනඟින තුරු කියවා නොගනිති. පැතලි බුලට් පොයින්ට් ලිස්ට් එකකින් ඒවා ලබා දීමෙන් බැලූ බැල්මට ඔබේ සේවාදායකයේ නීති බැලීම පහසු කරන්න. තනි නීති කෙටි හා සරලව තබා ගැනීමට උත්සාහ කරන්න, නමුත් ඒවා විවිධ අයිතම වලට බෙදීමට උත්සාහ නොකරන්න. - edit: නීතිය සංස්කරණය කරන්න + edit: නීතිය සංස්කරණය empty: තවමත් සේවාදායක රීති නිර්වචනය කර නොමැත. title: සේවාදායකයේ නීති settings: + about: + manage_rules: සේවාදායකයේ නීති කළමනාකරණය + title: පිළිබඳව + appearance: + title: පෙනුම + discovery: + profile_directory: පැතිකඩ නාමාවලිය + public_timelines: ප්‍රසිද්ධ කාලරේඛා domain_blocks: all: හැමෝටම disabled: කාටවත් නෑ @@ -584,28 +599,45 @@ si: approved: ලියාපදිංචි වීමට අනුමැතිය අවශ්‍යයි none: කිසිවෙකුට ලියාපදිංචි විය නොහැක open: ඕනෑම කෙනෙකුට ලියාපදිංචි විය හැක + title: සේවාදායකයේ සැකසුම් site_uploads: delete: උඩුගත කළ ගොනුව මකන්න destroyed_msg: අඩවිය උඩුගත කිරීම සාර්ථකව මකා ඇත! + software_updates: + documentation_link: තව දැනගන්න + release_notes: නිකුතු සටහන් + title: තිබෙන යාවත්කාල + type: වර්ගය + version: අනුවාදය statuses: - back_to_account: ගිණුම් පිටුවට ආපසු යන්න - back_to_report: වාර්තා පිටුවට ආපසු යන්න + account: කර්තෘ + application: යෙදුම + back_to_account: ගිණුමේ පිටුවට ආපසු + back_to_report: වාර්තා පිටුවට ආපසු batch: remove_from_report: වාර්තාවෙන් ඉවත් කරන්න report: වාර්තාව - deleted: මකා දමන ලදී + deleted: මකා ඇත + favourites: ප්‍රියතමයන් + history: අනුවාද ඉතිහාසය + language: භාෂාව media: - title: මාධ්‍යය - no_status_selected: කිසිවක් තෝරා නොගත් බැවින් තනතුරු කිසිවක් වෙනස් කර නැත - title: ගිණුම් තනතුරු - with_media: මාධ්‍ය දායකත්වය + title: මාධ්‍ය + metadata: පාරදත්ත + no_status_selected: කිසිවක් නොතේරූ බැවින් ලිපි කිසිවක් වෙනස් කර නැත + open: ලිපිය අරින්න + original_status: මුල් ලිපිය + status_changed: ලිපිය සංශෝධිතයි + title: ගිණුමේ ලිපි + trending: නැගී එන + with_media: මාධ්‍ය සමඟ strikes: actions: - delete_statuses: "%{target}ගේ පළ කිරීම් %{name} මකා දමන ලදී" + delete_statuses: "%{target}ගේ ලිපි %{name} මකා ඇත" disable: "%{name} %{target}ගේ ගිණුම නිශ්චල කළේය" - mark_statuses_as_sensitive: "%{name} %{target}ගේ පළ කිරීම් සංවේදී ලෙස ලකුණු කර ඇත" + mark_statuses_as_sensitive: "%{target}ගේ ලිපි සංවේදී බව %{name} සලකුණු කර ඇත" none: "%{name} %{target}අනතුරු ඇඟවීමක් යවා ඇත" - sensitive: "%{name} %{target}ගේ ගිණුම සංවේදී ලෙස ලකුණු කර ඇත" + sensitive: "%{target}ගේ ගිණුම සංවේදී බව %{name} සලකුණු කර ඇත" silence: "%{name} සීමිත %{target}ගිණුමක්" suspend: "%{name} %{target}ගේ ගිණුම අත්හිටුවා ඇත" appeal_approved: අභියාචනා කළා @@ -613,28 +645,35 @@ si: system_checks: database_schema_check: message_html: පොරොත්තු දත්ත සමුදා සංක්‍රමණයන් ඇත. යෙදුම අපේක්ෂිත පරිදි ක්‍රියා කරන බව සහතික කිරීමට කරුණාකර ඒවා ධාවනය කරන්න + elasticsearch_preset: + action: ප්‍රලේඛනය බලන්න + elasticsearch_preset_single_node: + action: ප්‍රලේඛනය බලන්න elasticsearch_running_check: message_html: Elasticsearch වෙත සම්බන්ධ වීමට නොහැකි විය. කරුණාකර එය ක්‍රියාත්මක වන බව පරීක්ෂා කරන්න, නැතහොත් සම්පූර්ණ පෙළ සෙවීම අක්‍රීය කරන්න elasticsearch_version_check: message_html: 'නොගැලපෙන ඉලාස්ටික් සෙවුම් අනුවාදය: %{value}' version_comparison: Elasticsearch %{running_version} ක්‍රියාත්මක වන අතර %{required_version} අවශ්‍ය වේ rules_check: - action: සේවාදායක නීති කළමනාකරණය කරන්න + action: සේවාදායකයේ නීති කළමනාකරණය message_html: ඔබ සේවාදායක රීති කිසිවක් නිර්වචනය කර නැත. sidekiq_process_check: message_html: "%{value} පෝලිම්(ය) සඳහා Sidekiq ක්‍රියාවලියක් ක්‍රියාත්මක නොවේ. කරුණාකර ඔබේ Sidekiq වින්‍යාසය සමාලෝචනය කරන්න" + software_version_critical_check: + action: තිබෙන යාවත්කාල බලන්න + software_version_patch_check: + action: තිබෙන යාවත්කාල බලන්න tags: review: තත්‍වය සමාලෝචනය updated_msg: Hashtag සැකසුම් සාර්ථකව යාවත්කාලීන කරන ලදී title: පරිපාලනය trends: - allow: ඉඩ දෙන්න - approved: අනුමත කළා + allow: ඉඩදෙන්න + approved: අනුමතයි disallow: අවසර නොදෙන්න links: - allow: සබැඳියට ඉඩ දෙන්න + allow: සබැඳියට ඉඩදෙන්න allow_provider: ප්‍රකාශකයාට ඉඩ දෙන්න - description_html: මේවා ඔබගේ සේවාදායකය විසින් පළ කිරීම් දකින ගිණුම් මගින් දැනට බොහෝ සෙයින් බෙදා ගන්නා සබැඳි වේ. එය ඔබගේ පරිශීලකයින්ට ලෝකයේ සිදුවෙමින් පවතින දේ සොයා ගැනීමට උදවු කළ හැක. ඔබ ප්‍රකාශකයා අනුමත කරන තුරු සබැඳි කිසිවක් ප්‍රසිද්ධියේ ප්‍රදර්ශනය නොවේ. ඔබට තනි සබැඳිවලට ඉඩ දීමට හෝ ප්‍රතික්ෂේප කිරීමටද හැකිය. disallow: සබැඳියට ඉඩ නොදෙන්න disallow_provider: ප්‍රකාශකයාට ඉඩ නොදෙන්න shared_by_over_week: @@ -642,7 +681,6 @@ si: other: පසුගිය සතිය පුරා පුද්ගලයින් %{count} දෙනෙකු විසින් බෙදා ගන්නා ලදී title: නැඟී එන සබැඳි usage_comparison: ඊයේ %{yesterday} හා සසඳන විට අද %{today} වරක් බෙදා ගන්නා ලදී - only_allowed: අවසර දී ඇත pending_review: පොරොත්තු සමාලෝචනය preview_card_providers: allowed: මෙම ප්‍රකාශකයාගේ සබැඳි නැඹුරු විය හැක @@ -651,16 +689,15 @@ si: title: ප්‍රකාශකයන් rejected: ප්‍රතික්ෂේප කළා statuses: - allow: පළ කිරීමට ඉඩ දෙන්න + allow: පළ කිරීමට ඉඩදෙන්න allow_account: කතුවරයාට ඉඩ දෙන්න - description_html: මේ වන විට ඔබේ සේවාදායකය දන්නා පෝස්ට් මේ වන විට බොහෝ බෙදාහරින සහ මේ මොහොතේ වැඩි කැමැත්තක් දක්වයි. එය ඔබගේ නව සහ නැවත පැමිණෙන පරිශීලකයින්ට අනුගමනය කිරීමට තවත් පුද්ගලයින් සොයා ගැනීමට උදවු කළ හැක. ඔබ කර්තෘ අනුමත කරන තෙක් පළ කිරීම් කිසිවක් ප්‍රසිද්ධියේ නොපෙන්වන අතර, කර්තෘ තම ගිණුම අන් අයට යෝජනා කිරීමට ඉඩ දෙයි. ඔබට තනි පළ කිරීම්වලට ඉඩ දීමට හෝ ප්‍රතික්ෂේප කිරීමටද හැකිය. - disallow: පළ කිරීමට ඉඩ නොදෙන්න + disallow: ප්‍රකාශනයට ඉඩ නොදෙන්න disallow_account: කතුවරයාට ඉඩ නොදෙන්න not_discoverable: කර්තෘ සොයා ගත හැකි බව තෝරාගෙන නැත shared_by: one: එක් වරක් බෙදාගත් හෝ ප්‍රිය කරන ලදී other: "%{friendly_count} වරක් බෙදාගෙන ප්‍රිය කරන ලදී" - title: ප්‍රවණතා පළ කිරීම් + title: නැගී එන ලිපි tags: current_score: වත්මන් ලකුණු %{score} dashboard: @@ -669,9 +706,8 @@ si: tag_servers_dimension: ඉහළම සේවාදායකයන් tag_servers_measure: විවිධ සේවාදායකයන් tag_uses_measure: සම්පූර්ණ භාවිතය - description_html: මේවා දැනට ඔබගේ සේවාදායකය දකින බොහෝ පළ කිරීම් වල දිස්වන හැෂ් ටැග් වේ. මේ මොහොතේ මිනිසුන් වැඩිපුරම කතා කරන්නේ කුමක් දැයි සොයා ගැනීමට එය ඔබගේ පරිශීලකයින්ට උදවු කළ හැක. ඔබ ඒවා අනුමත කරන තුරු හෑෂ් ටැග් ප්‍රසිද්ධියේ නොපෙන්වයි. - listable: යෝජනා කළ හැක - not_listable: යෝජනා නොකරනු ඇත + listable: යෝජනා කළ හැකිය + not_listable: යෝජනා නොවනු ඇත not_trendable: ප්‍රවණතා යටතේ දිස් නොවනු ඇත not_usable: භාවිතා කළ නොහැක peaked_on_and_decaying: "%{date}හි උච්චතම, දැන් දිරාපත් වෙමින් පවතී" @@ -694,16 +730,15 @@ si: webhooks: add_new: අන්ත ලක්ෂ්‍යය එක් කරන්න delete: මකන්න - description_html: A webhook Mastodon හට තෝරාගත් සිදුවීම් පිළිබඳ තත්‍ය කාලීන දැනුම්දීම් ක් ඔබේම යෙදුමට තල්ලු කිරීමට හැකියාව ලබා දෙයි, එම නිසා ඔබේ යෙදුමට ස්වයංක්‍රීයව ප්‍රතික්‍රියා අවුලුවාලීමට හැකිය. - disable: අක්රිය කරන්න - disabled: ආබාධිතයි + disable: අබල කරන්න + disabled: අබලයි edit: අන්ත ලක්ෂ්‍යය සංස්කරණය කරන්න empty: ඔබට තවම වින්‍යාස කර ඇති කිසිදු webhook අන්ත ලක්ෂ්‍යයක් නොමැත. enable: සබල කරන්න - enabled: ක්රියාකාරී + enabled: ක්‍රියාත්මකයි enabled_events: - one: 1 සබල කළ සිදුවීමක් - other: "%{count} සබල කළ සිදුවීම්" + one: සබල සිදුවීම් 1 + other: සබල සිදුවීම් %{count} events: සිදුවීම් new: නව webhook rotate_secret: රහස කරකවන්න @@ -715,14 +750,10 @@ si: actions: delete_statuses: ඔවුන්ගේ පළ කිරීම් මකා දැමීමට disable: ඔවුන්ගේ ගිණුම කැටි කිරීමට - mark_statuses_as_sensitive: ඔවුන්ගේ තනතුරු සංවේදී ලෙස සලකුණු කිරීමට none: අනතුරු ඇඟවීමක් sensitive: ඔවුන්ගේ ගිණුම සංවේදී ලෙස සලකුණු කිරීමට silence: ඔවුන්ගේ ගිණුම සීමා කිරීමට suspend: ඔවුන්ගේ ගිණුම අත්හිටුවීමට - body: "%{target} යනු %{type}ක් වූ %{date}සිට %{action_taken_by} කින් මධ්‍යස්ථ තීරණයක් අභියාචනා කරයි. ඔවුන් මෙසේ ලිවීය." - next_steps: ඔබට මධ්‍යස්ථ තීරණය අවලංගු කිරීමට අභියාචනය අනුමත කළ හැකිය, නැතහොත් එය නොසලකා හරින්න. - subject: "%{username} යනු %{instance}හි මධ්‍යස්ථ තීරණයකට අභියාචනා කරයි" new_pending_account: body: නව ගිණුමේ විස්තර පහතින්. ඔබට මෙම යෙදුම අනුමත කිරීමට හෝ ප්‍රතික්ෂේප කිරීමට හැකිය. subject: නව ගිණුම සමාලෝචනය සඳහා %{instance} (%{username}) @@ -735,7 +766,7 @@ si: new_trending_links: title: නැඟී එන සබැඳි new_trending_statuses: - title: ප්‍රවණතා පළ කිරීම් + title: නැගී එන ලිපි new_trending_tags: no_approved_tags: දැනට අනුමත ප්‍රවණතා හැෂ් ටැග් නොමැත. requirements: 'මෙම ඕනෑම අපේක්ෂකයෙකුට #%{rank} අනුමත ප්‍රවණතා හැෂ් ටැගය අභිබවා යා හැකිය, එය දැනට ලකුණු %{lowest_tag_score}ක් සමඟ #%{lowest_tag_name} වේ.' @@ -749,40 +780,38 @@ si: hint_html: ඔබට වෙනත් ගිණුමකින් මෙය වෙත මාරු වීමට අවශ්‍ය නම්, මෙහිදී ඔබට අන්වර්ථ නාමයක් සෑදිය හැක, එය පැරණි ගිණුමෙන් අනුගාමිකයින් මෙම ගිණුමට ගෙන යාමට පෙර අවශ්‍ය වේ. මෙම ක්‍රියාවම හානිකර නොවන සහ ආපසු හැරවිය හැකිවේ. ගිණුම් සංක්‍රමණය පැරණි ගිණුමෙන් ආරම්භ වේ. remove: අන්වර්ථය විසන්ධි කරන්න appearance: - advanced_web_interface: උසස් වියමන අතුරුමුහුණත + advanced_web_interface: සංකීර්ණ අතුරු මුහුණත advanced_web_interface_hint: 'ඔබට ඔබේ සම්පූර්ණ තිරයේ පළල භාවිතා කිරීමට අවශ්‍ය නම්, උසස් වෙබ් අතුරු මුහුණත ඔබට අවශ්‍ය පරිදි එකම වේලාවක බොහෝ තොරතුරු බැලීමට විවිධ තීරු වින්‍යාස කිරීමට ඉඩ දෙයි: නිවස, දැනුම්දීම්, ෆෙඩරේටඩ් කාලරාමුව, ඕනෑම ලැයිස්තු සහ හැෂ් ටැග්.' animations_and_accessibility: සජීවිකරණ සහ ප්‍රවේශ්‍යතාව confirmation_dialogs: තහවුරු කිරීමේ සංවාද discovery: සොයාගැනීම localization: - body: Mastodon ස්වේච්ඡා සේවකයන් විසින් පරිවර්තනය කර ඇත. + body: මාස්ටඩන් ස්වේච්ඡාවෙන් පරිවර්තනය කර ඇත. guide_link: https://crowdin.com/project/mastodon - guide_link_text: සෑම කෙනෙකුටම දායක විය හැකිය. - sensitive_content: සංවේදී අන්තර්ගතය - toot_layout: පෝස්ට් පිරිසැලසුම + guide_link_text: පරිවර්තකයින්ට දායක වීමට හැකිය. + sensitive_content: සංවේදී අන්තර්ගත application_mailer: notification_preferences: ඊමේල් මනාප වෙනස් කරන්න salutation: "%{name}," settings: 'ඊමේල් මනාප වෙනස් කරන්න: %{link}' view: 'දැක්ම:' view_profile: පැතිකඩ බලන්න - view_status: පළ කිරීම බලන්න + view_status: ලිපිය බලන්න applications: - created: යෙදුම සාර්ථකව නිර්මාණය කරන ලදී + created: යෙදුම සාර්ථකව සෑදිණි destroyed: යෙදුම සාර්ථකව මකා ඇත + logout: නික්මෙන්න regenerate_token: ප්‍රවේශ ටෝකනය නැවත උත්පාදනය කරන්න token_regenerated: ප්‍රවේශ ටෝකනය සාර්ථකව ප්‍රතිජනනය කරන ලදී warning: මෙම දත්ත සමඟ ඉතා ප්රවේශම් වන්න. එය කිසි විටෙක කිසිවෙකු සමඟ බෙදා නොගන්න! your_token: ඔබේ ප්‍රවේශ ටෝකනය auth: - change_password: මුර පදය + apply_for_account: ගිණුමක් ඉල්ලන්න delete_account: ගිණුම මකන්න delete_account_html: ඔබට ඔබගේ ගිණුම මකා දැමීමට අවශ්‍ය නම්, ඔබට මෙතැනින් ඉදිරියට යා හැක. තහවුරු කිරීම සඳහා ඔබෙන් අසනු ඇත. description: - prefix_invited_by_user: "@%{name} ඔබට Mastodon හි මෙම සේවාදායකයට සම්බන්ධ වීමට ආරාධනා කරයි!" + prefix_invited_by_user: "@%{name} මෙම මාස්ටඩන් සේවාදායකයට ආරාධනා කර ඇත!" prefix_sign_up: අදම මාස්ටඩන් හි ලියාපදිංචි වන්න! - suffix: ගිණුමක් සමඟ, ඔබට ඕනෑම Mastodon සේවාදායකයකින් සහ තවත් බොහෝ දේ භාවිතා කරන්නන් සමඟ පුද්ගලයින් අනුගමනය කිරීමට, යාවත්කාලීන කිරීම් පළ කිරීමට සහ පණිවිඩ හුවමාරු කර ගැනීමට හැකි වනු ඇත! - didnt_get_confirmation: තහවුරු කිරීමේ උපදෙස් ලැබුණේ නැද්ද? dont_have_your_security_key: ඔබගේ ආරක්ෂක යතුර නොමැතිද? forgot_password: මුරපදය අමතක වුනාද? invalid_reset_password_token: මුරපද යළි පිහිටුවීමේ ටෝකනය අවලංගු හෝ කල් ඉකුත් වී ඇත. කරුණාකර අලුත් එකක් ඉල්ලන්න. @@ -793,17 +822,25 @@ si: logout: නික්මෙන්න migrate_account: වෙනත් ගිණුමකට යන්න migrate_account_html: ඔබට මෙම ගිණුම වෙනත් එකකට හරවා යැවීමට අවශ්‍ය නම්, ඔබට එය මෙහි වින්‍යාසගත කළ හැක. - or_log_in_with: හෝ සමඟින් පිවිසෙන්න + progress: + details: ඔබගේ විස්තර + rules: නීති පිළිගන්න + providers: + cas: CAS + saml: SAML register: ලියාපදිංචිය registration_closed: "%{instance} නව සාමාජිකයින් පිළිගන්නේ නැත" - resend_confirmation: තහවුරු කිරීමේ උපදෙස් නැවත යවන්න - reset_password: මුරපදය නැවත සකසන්න - security: ආරක්ෂාව + reset_password: මුරපදය යළි සකසන්න + rules: + accept: පිළිගන්න + back: ආපසු + title_invited: ඔබට ආරාධනා කර ඇත. + security: ආරක්‍ෂාව set_new_password: නව මුරපදය සකසන්න setup: - email_below_hint_html: පහත විද්‍යුත් තැපැල් ලිපිනය වැරදි නම්, ඔබට එය මෙතැනින් වෙනස් කර නව තහවුරු කිරීමේ විද්‍යුත් තැපෑලක් ලබා ගත හැක. - email_settings_hint_html: තහවුරු කිරීමේ විද්‍යුත් තැපෑල %{email}වෙත යවන ලදී. එම විද්‍යුත් තැපැල් ලිපිනය නිවැරදි නොවේ නම්, ඔබට එය ගිණුම් සැකසුම් තුළ වෙනස් කළ හැක. - title: සැලසුම + title: ඔබගේ එනලිපි බලන්න + sign_in: + title: "%{domain} වෙත පිවිසෙන්න" status: account_status: ගිණුමේ තත්වය confirming: විද්‍යුත් තැපෑල තහවුරු කිරීම සම්පූර්ණ කිරීම සඳහා රැඳී සිටිමින්. @@ -812,23 +849,11 @@ si: redirecting_to: එය දැනට %{acct}වෙත හරවා යවන බැවින් ඔබගේ ගිණුම අක්‍රියයි. view_strikes: ඔබගේ ගිණුමට එරෙහිව පසුගිය වර්ජන බලන්න too_fast: පෝරමය ඉතා වේගයෙන් ඉදිරිපත් කර ඇත, නැවත උත්සාහ කරන්න. - use_security_key: ආරක්ෂක යතුර භාවිතා කරන්න - authorize_follow: - already_following: ඔබ දැනටමත් මෙම ගිණුම අනුගමනය කරයි - already_requested: ඔබ දැනටමත් එම ගිණුමට අනුගමනය ඉල්ලීමක් යවා ඇත - error: අවාසනාවකට, දුරස්ථ ගිණුම සෙවීමේදී දෝෂයක් ඇති විය - follow: අනුගමනය - follow_request: 'ඔබ පහත ඉල්ලීමක් යවා ඇත:' - following: 'සාර්ථකත්වය! ඔබ දැන් පහත දැක්වේ:' - post_follow: - close: හෝ ඔබට මෙම කවුළුව වසාදැමිය හැකිය. - return: පරිශීලකගේ පැතිකඩ පෙන්වන්න - web: වියමන ට යන්න - title: "%{acct} අනුගමනය" + use_security_key: ආරක්‍ෂණ යතුර භාවිතා කරන්න challenge: confirm: ඉදිරියට hint_html: "ඉඟිය: අපි ඉදිරි පැය සඳහා නැවත ඔබගේ මුරපදය ඔබෙන් නොඉල්ලමු." - invalid_password: නොවන මුරපදයකි + invalid_password: මුරපදය වැරදිය prompt: ඉදිරියට යාමට මුරපදය තහවුරු කරන්න crypto: errors: @@ -836,20 +861,24 @@ si: invalid_signature: වලංගු Ed25519 අත්සනක් නොවේ date: formats: - default: "%b %d, %Y" - with_month_name: "%B %d, %Y" + default: "%Y %b %d" + with_month_name: "%Y %B %d" datetime: distance_in_words: about_x_hours: පැය %{count} about_x_months: මාස %{count} + about_x_years: ව.%{count} + almost_x_years: ව.%{count} half_a_minute: මේ දැන් - less_than_x_minutes: මීටර් %{count} + less_than_x_minutes: විනාඩි %{count} less_than_x_seconds: මේ දැන් - x_minutes: මීටර් %{count} + over_x_years: ව.%{count} + x_days: ද.%{count} + x_minutes: විනාඩි %{count} x_months: මාස %{count} - x_seconds: "%{count}තත්" + x_seconds: තත්. %{count} deletes: - challenge_not_passed: ඔබ ඇතුළත් කළ තොරතුරු නිවැරදි නැත + challenge_not_passed: ඔබ ඇතුල් කරන ලද තොරතුරු වැරදියි confirm_password: ඔබගේ අනන්‍යතාවය තහවුරු කිරීමට ඔබගේ වත්මන් මුරපදය ඇතුලත් කරන්න confirm_username: ක්රියා පටිපාටිය තහවුරු කිරීමට ඔබගේ පරිශීලක නාමය ඇතුලත් කරන්න proceed: ගිණුම මකන්න @@ -857,7 +886,7 @@ si: warning: before: 'ඉදිරියට යාමට පෙර, කරුණාකර මෙම සටහන් හොඳින් කියවන්න:' caches: වෙනත් සේවාදායකයන් විසින් හැඹිලිගත කර ඇති අන්තර්ගතය දිගටම පැවතිය හැක - data_removal: ඔබගේ පළ කිරීම් සහ අනෙකුත් දත්ත ස්ථිරවම ඉවත් කරනු ලැබේ + data_removal: ඔබගේ ලිපි සහ අනෙකුත් දත්ත සදහටම ඉවත් කෙරෙනු ඇත email_change_html: ඔබට ඔබගේ ගිණුම මකා කළ හැක email_contact_html: එය තවමත් නොපැමිණියේ නම්, ඔබට උදව් සඳහා %{email} විද්‍යුත් තැපෑලෙන් යැවිය හැක email_reconfirmation_html: ඔබට තහවුරු කිරීමේ විද්‍යුත් තැපෑල නොලැබුනේ නම්, ඔබට එය නැවත ඉල්ලා සිටිය හැක @@ -881,13 +910,12 @@ si: description_html: මේවා ඔබගේ ගිණුමට එරෙහිව ගන්නා ලද ක්‍රියා සහ %{instance}හි කාර්ය මණ්ඩලය විසින් ඔබට එවා ඇති අනතුරු ඇඟවීම් වේ. recipient: වෙත යොමු කරන ලදී reject_appeal: අභියාචනය ප්‍රතික්ෂේප කරන්න - status: 'පළ කිරීම #%{id}' - status_removed: පළ කිරීම දැනටමත් පද්ධතියෙන් ඉවත් කර ඇත + status: "#%{id} ලිපිය" + status_removed: ලිපිය දැනටමත් පද්ධතියෙන් ඉවත් කර ඇත title: "%{action} සිට %{date}" title_actions: - delete_statuses: පසු ඉවත් කිරීම + delete_statuses: ලිපි ඉවත් කිරීම disable: ගිණුම කැටි කිරීම - mark_statuses_as_sensitive: තනතුරු සංවේදී ලෙස සලකුණු කිරීම none: අවවාදයයි sensitive: ගිණුම සංවේදී ලෙස සලකුණු කිරීම silence: ගිණුම සීමා කිරීම @@ -897,6 +925,9 @@ si: your_appeal_rejected: ඔබගේ අභියාචනය ප්‍රතික්ෂේප කර ඇත domain_validator: invalid_domain: වලංගු ඩොමේන් නාමයක් නොවේ + edit_profile: + basic_information: මූලික තොරතුරු + other: වෙනත් errors: '400': ඔබ ඉදිරිපත් කළ ඉල්ලීම අවලංගු හෝ විකෘති විය. '403': ඔබට මෙම පිටුව බැලීමට අවසර නැත. @@ -906,44 +937,43 @@ si: '422': content: ආරක්ෂක සත්‍යාපනය අසාර්ථක විය. ඔබ කුකීස් අවහිර කරනවාද? title: ආරක්ෂක සත්‍යාපනය අසාර්ථක විය - '429': ඉල්ලීම් වැඩියි + '429': ඉල්ලීම් බොහෝය '500': content: අපට කණගාටුයි, නමුත් අපගේ පැත්තෙන් යමක් වැරදී ඇත. - title: මෙම පිටුව නිවැරදි නොවේ + title: මෙම පිටුව වැරදියි '503': තාවකාලික සේවාදායකයේ අසාර්ථක වීමක් හේතුවෙන් පිටුව සේවය කිරීමට නොහැකි විය. - noscript_html: Mastodon වෙබ් යෙදුම භාවිතා කිරීමට, කරුණාකර JavaScript සක්‍රීය කරන්න. විකල්පයක් ලෙස, ඔබේ වේදිකාව සඳහා එකක් උත්සාහ කරන්න. + noscript_html: මාස්ටඩන් වියමන යෙදුම භාවිතා කිරීමට ජාවාස්ක්‍රිප්ට් සබල කරන්න. ඊට අමතරව, ඔබගේ වේදිකාව සඳහා වන නිසග යෙදුමක් අත්හදා බලන්න. existing_username_validator: not_found: එම පරිශීලක නාමය සහිත දේශීය පරිශීලකයෙකු සොයා ගැනීමට නොහැකි විය not_found_multiple: "%{usernames}සොයා ගැනීමට නොහැකි විය" exports: archive_takeout: date: දිනය - download: ඔබගේ සුරක්ෂිතභාවය බාගන්න - hint_html: ඔබට ඔබගේ පළ කිරීම් සහ උඩුගත කළ මාධ්‍යහි සංරක්ෂිතයක් ඉල්ලා සිටිය හැක. නිර්යාත කළ දත්ත ActivityPub ආකෘතියෙන්, ඕනෑම අනුකූල මෘදුකාංගයකට කියවිය හැකිය. ඔබට දින 7කට වරක් ලේඛනාගාරයක් ඉල්ලා සිටිය හැක. + download: ඔබගේ සංරක්‍ෂිතය බාගන්න + hint_html: ඔබට ලිපි සහ උඩුගත කළ මාධ්‍යවල සංරක්‍ෂණයක් ඉල්ලීමට හැකිය. නිර්යාත කළ දත්ත ActivityPub ආකෘතියට ගැළපෙන ඕනෑම මෘදුකාංගයකින් කියවීමට හැකිය. ඔබට දවස් 7 කට වරක් සංරක්‍ෂණයක් ඉල්ලීමට හැකිය. in_progress: ඔබගේ සංරක්ෂිතය සම්පාදනය කරමින්... request: ඔබගේ සංරක්ෂිතය ඉල්ලන්න size: ප්‍රමාණය blocks: ඔබ අවහිර කරන්න - bookmarks: පොත් යොමු කරන්න + bookmarks: පොත්යොමු + csv: CSV domain_blocks: වසම් අවහිර කිරීම් - lists: ලැයිස්තුව + lists: ලැයිස්තු mutes: ඔබ නිහඬ කරන්න - storage: මාධ්‍ය ගබඩාව + storage: මාධ්‍ය ආචයනය featured_tags: add_new: අලුතින් එකතු කරන්න - errors: - limit: ඔබ දැනටමත් උපරිම හෑෂ් ටැග් ප්‍රමාණය විශේෂාංග කර ඇත - hint_html: "විශේෂාංගගත හැෂ් ටැග් මොනවාද? ඒවා ඔබේ පොදු පැතිකඩෙහි ප්‍රමුඛව ප්‍රදර්ශනය වන අතර එම හැෂ් ටැග් යටතේ ඔබේ පොදු පළ කිරීම් බ්‍රවුස් කිරීමට මිනිසුන්ට ඉඩ සලසයි. නිර්මාණාත්මක කෘති හෝ දිගු කාලීන ව්යාපෘති පිළිබඳ වාර්තාවක් තබා ගැනීම සඳහා ඔවුන් විශිෂ්ට මෙවලමක් වේ." filters: contexts: account: පැතිකඩයන් - home: නිවස සහ ලැයිස්තු + home: මුල සහ ලැයිස්තු notifications: දැනුම්දීම් - public: පොදු කාලරේඛා + public: ප්‍රසිද්ධ කාලරේඛා thread: සංවාද edit: add_keyword: මූල පදය එක් කරන්න keywords: මූල පද + statuses: තනි ලිපි title: පෙරහන සංස්කරණය errors: deprecated_api_multiple_keywords: මෙම පරාමිති පෙරහන් මූල පද එකකට වඩා අදාළ වන බැවින් මෙම යෙදුමෙන් වෙනස් කළ නොහැක. වඩාත් මෑත යෙදුමක් හෝ වෙබ් අතුරු මුහුණතක් භාවිතා කරන්න. @@ -951,23 +981,32 @@ si: index: contexts: "%{contexts}හි පෙරහන්" delete: මකන්න - empty: ඔබට පෙරහන් නොමැත. - expires_in: "%{distance}කින් කල් ඉකුත් වේ" - expires_on: "%{date}දින කල් ඉකුත් වේ" + empty: ඔබ සතුව පෙරහන් නැත. + expires_in: "%{distance} කින් ඉකුත් වේ" + expires_on: "%{date} දී ඉකුත් වේ" keywords: - one: "%{count} මූල පදය" - other: "%{count} මූල පද" + one: මූල පද %{count} + other: මූල පද %{count} + statuses: + one: ලිපි %{count} + other: ලිපි %{count} title: පෙරහන් new: save: නව පෙරහන සුරකින්න title: නව පෙරහනක් එකතු කරන්න - footer: - trending_now: දැන් ප්‍රවණතාවය + statuses: + back_to_filter: පෙරහනට ආපසු + batch: + remove: පෙරහනෙන් ඉවතලන්න + index: + title: පෙරූ ලිපි generic: all: සියල්ල - changes_saved_msg: වෙනස්කම් සාර්ථකව සුරකින ලදී! + cancel: අවලංගු + changes_saved_msg: වෙනස්කම් සාර්ථකව සුරැකිණි! copy: පිටපතක් delete: මකන්න + deselect: සියල්ල නොතෝරන්න none: කිසිවක් නැත order_by: විසින් ඇණවුම් කරන්න save_changes: වෙනස්කම් සුරකින්න @@ -975,28 +1014,35 @@ si: validation_errors: one: යමක් තවමත් හරි නැත! කරුණාකර පහත දෝෂය සමාලෝචනය කරන්න other: යමක් තවමත් හරි නැත! කරුණාකර පහත දෝෂ %{count} ක් සමාලෝචනය කරන්න - html_validator: - invalid_markup: 'වලංගු නොවන HTML සලකුණු අඩංගු වේ: %{error}' imports: errors: + empty: හිස් CSV ගොනුවකි over_rows_processing_limit: පේළි %{count} කට වඩා අඩංගු වේ + too_large: ගොනුව ඉතා විශාලයි + imported: ආයාත විය modes: - merge: ඒකාබද්ධ කරන්න + merge: ඒකාබද්ධ merge_long: පවතින වාර්තා තබා නව ඒවා එකතු කරන්න overwrite: උඩින් ලියන්න overwrite_long: වත්මන් වාර්තා නව ඒවා සමඟ ප්‍රතිස්ථාපනය කරන්න preface: ඔබ අනුගමන කරන හෝ අවහිර කරන පුද්ගලයින්ගේ ලැයිස්තුවක් වැනි වෙනත් සේවාදායකයකින් ඔබ නිර්යාත කර ඇති දත්ත ඔබට ආයාත කළ හැක. + status: තත්‍වය success: ඔබගේ දත්ත සාර්ථකව උඩුගත කර ඇති අතර නියමිත වේලාවට සැකසෙනු ඇත + titles: + lists: ලැයිස්තු ආයාත වෙමින් + type_groups: + constructive: අනුගමන හා පොත්යොමු types: - blocking: අවහිර කිරීමේ ලැයිස්තුව - bookmarks: පොත් යොමු - domain_blocking: වසම් අවහිර කිරීමේ ලැයිස්තුව - following: පහත ලැයිස්තුව + blocking: අවහිර ලැයිස්තුව + bookmarks: පොත්යොමු + domain_blocking: වසම් අවහිර ලැයිස්තුව + following: අනුගමන ලැයිස්තුව + lists: ලැයිස්තු muting: නිහඬ කිරීමේ ලැයිස්තුව upload: උඩුගත කරන්න invites: - delete: අක්රිය කරන්න - expired: කල් ඉකුත් වී ඇත + delete: අක්‍රිය කරන්න + expired: ඉකුත් වී ඇත expires_in: '1800': විනාඩි 30 '21600': පැය 6 @@ -1015,10 +1061,7 @@ si: table: expires_at: කල් ඉකුත් වේ uses: භාවිතා කරයි - title: මිනිසුන්ට ආරාධනා කරන්න - lists: - errors: - limit: ඔබ උපරිම ලැයිස්තු ප්‍රමාණයට ළඟා වී ඇත + title: ආරාධනා කරන්න login_activities: authentication_methods: otp: ද්වි-සාධක සත්‍යාපන යෙදුම @@ -1032,7 +1075,7 @@ si: title: සත්‍යාපන ඉතිහාසය media_attachments: validations: - images_and_video: දැනටමත් පින්තූර අඩංගු පළ කිරීමකට වීඩියෝවක් ඇමිණිය නොහැක + images_and_video: දැනටමත් රූප අඩංගු ලිපියකට දෘශ්‍යකයක් ඇමිණීමට නොහැකිය not_ready: සැකසීම අවසන් නොකළ ගොනු ඇමිණිය නොහැක. මොහොතකින් නැවත උත්සාහ කරන්න! too_many: ගොනු 4කට වඩා ඇමිණිය නොහැක migrations: @@ -1067,7 +1110,7 @@ si: other_data: වෙනත් දත්ත කිසිවක් ස්වයංක්‍රීයව ගෙන නොයනු ඇත redirect: ඔබගේ ජංගම ගිණුමේ පැතිකඩ යළි-යොමු කිරීමේ දැන්වීමක් සමඟ යාවත්කාලීන කෙරෙන අතර සෙවුම් වලින් බැහැර කරනු ලැබේ moderation: - title: මධ්යස්ථභාවය + title: මැදිහත්කරණය move_handler: carry_blocks_over_text: මෙම පරිශීලකයා ඔබ අවහිර කර තිබූ %{acct}සිට මාරු විය. carry_mutes_over_text: මෙම පරිශීලකයා ඔබ නිශ්ශබ්ද කර තිබූ %{acct}වෙතින් මාරු විය. @@ -1075,37 +1118,31 @@ si: notification_mailer: admin: report: - subject: "%{name} වාර්තාවක් ඉදිරිපත් කළේය" + subject: "%{name} වාර්තාවක් යොමු කර ඇත" sign_up: subject: "%{name} අත්සන් කර ඇත" favourite: - body: 'ඔබේ පළ කිරීම %{name}විසින් ප්‍රිය කරන ලදී:' - subject: "%{name} ඔබගේ පළ කිරීම ප්‍රිය කරන ලදී" - title: නව ප්රියතම + body: "%{name} ඔබගේ ලිපියට ප්‍රිය කළා:" + subject: "%{name} ඔබගේ ලිපියට ප්‍රිය කළා" + title: නව ප්‍රියතමය follow: body: "%{name} දැන් ඔබව අනුගමනය කරයි!" subject: "%{name} දැන් ඔබව අනුගමනය කරයි" title: නව අනුගාමිකයෙක් follow_request: - action: අනුගමනය කරන ඉල්ලීම් කළමනාකරණය කරන්න + action: අනුගමන ඉල්ලීම් කළමනාකරණය body: "%{name} ඔබව අනුගමනය කිරීමට ඉල්ලා ඇත" subject: 'පොරොත්තු අනුගාමිකයා: %{name}' - title: නව අනුගමනය ඉල්ලීම + title: නව අනුගමන ඉල්ලීම mention: action: පිළිතුර - body: 'ඔබව මෙහි %{name} කින් සඳහන් කර ඇත:' - subject: ඔබව %{name}මගින් සඳහන් කර ඇත + body: "%{name} ඔබව මෙහි සඳහන් කර ඇත:" + subject: "%{name} ඔබව සඳහන් කර ඇත" title: නව සඳැහුම - poll: - subject: "%{name} න් මත විමසුමක් අවසන් විය" - reblog: - body: 'ඔබේ පළ කිරීම %{name}කින් වැඩි කරන ලදී:' - subject: "%{name} ඔබේ පළ කිරීම ඉහළ නැංවීය" - title: නව තල්ලුවක් status: subject: "%{name} දැන් පළ කළා" update: - subject: "%{name} පළ කිරීමක් සංස්කරණය කළා" + subject: "%{name} ලිපිය සංශෝධනය කළා" notifications: email_events: ඊමේල් දැනුම්දීම් සඳහා සිදුවීම් email_events_hint: 'ඔබට දැනුම්දීම් ලැබීමට අවශ්‍ය සිදුවීම් තෝරන්න:' @@ -1115,11 +1152,8 @@ si: decimal_units: format: "%n%u" units: - billion: බී million: ද.ල. - quadrillion: ප්‍රශ්නය thousand: ද. - trillion: ටී otp_authentication: code_hint: තහවුරු කිරීමට ඔබගේ සත්‍යාපන යෙදුම මගින් ජනනය කරන ලද කේතය ඇතුළු කරන්න description_html: ඔබ සත්‍යාපන යෙදුමක් භාවිතයෙන් ද්වි-සාධක සත්‍යාපනය සක්‍රීය කරන්නේ නම්, ලොගින් වීමේදී ඔබට ඔබගේ දුරකථනය සන්තකයේ තබා ගැනීමට අවශ්‍ය වනු ඇත, එය ඔබට ඇතුළු වීමට ටෝකන ජනනය කරයි. @@ -1136,19 +1170,21 @@ si: truncate: "…" polls: errors: - already_voted: ඔබ දැනටමත් මෙම මත විමසුමට ඡන්දය දී ඇත - duplicate_options: අනුපිටපත් අයිතම අඩංගු වේ + already_voted: ඔබ මෙම මත විමසුමට ඡන්දය දී ඇත duration_too_long: අනාගතයට බොහෝ දුරයි - duration_too_short: ඉතා ඉක්මනින් වේ - expired: මත විමසුම දැනටමත් අවසන් වී ඇත + expired: මත විමසුම දැනටමත් නිමා වී ඇත invalid_choice: තෝරාගත් ඡන්ද විකල්පය නොපවතී - over_character_limit: එක් එක් අක්ෂර %{max} ට වඩා දිගු විය නොහැක - too_few_options: එක් අයිතමයකට වඩා තිබිය යුතුය - too_many_options: අයිතම %{max} කට වඩා අඩංගු විය නොහැක + self_vote: ඔබගේ මත විමසුමට ජන්දය දීමට නොහැකිය + too_few_options: එක් අථකයකට වඩා තිබිය යුතුය + too_many_options: අථක %{max} කට වඩා අඩංගු නොවිය යුතුය preferences: other: වෙනත් - posting_defaults: පෙරනිමි පළ කිරීම - public_timelines: පොදු කාලරේඛා + posting_defaults: සැමවිට පළ කරන ආකාරය + public_timelines: ප්‍රසිද්ධ කාලරේඛා + privacy: + search: සොයන්න + privacy_policy: + title: රහස්‍යතා ප්‍රතිපත්තිය reactions: errors: limit_reached: විවිධ ප්‍රතික්‍රියා වල සීමාව ළඟා විය @@ -1156,7 +1192,7 @@ si: relationships: activity: ගිණුමේ ක්‍රියාකාරකම් dormant: නිදිමතයි - follow_selected_followers: තෝරාගත් අනුගාමිකයින් අනුගමනය කරන්න + follow_selected_followers: තේරූ අනුගාමිකයින් අනුගමනය කරන්න followers: අනුගාමිකයින් following: අනුගමනය invited: ආරාධනා කළා @@ -1164,11 +1200,11 @@ si: most_recent: මෑතකාලීන moved: මාරු කළා mutual: අන්යෝන්ය - primary: ප්රාථමික + primary: ප්‍රාථමික relationship: සම්බන්ධතාවය - remove_selected_domains: තෝරාගත් වසම් වලින් සියලුම අනුගාමිකයින් ඉවත් කරන්න - remove_selected_followers: තෝරාගත් අනුගාමිකයින් ඉවත් කරන්න - remove_selected_follows: තෝරාගත් පරිශීලකයින් අනුගමනය නොකරන්න + remove_selected_domains: තේරූ වසම් වල සියලුම අනුගාමිකයින් ඉවත් කරන්න + remove_selected_followers: තේරූ අනුගාමිකයින් ඉවත් කරන්න + remove_selected_follows: තේරූ අය අනුගමනය නොකරන්න status: ගිණුමේ තත්‍වය remote_follow: missing_resource: ඔබගේ ගිණුම සඳහා අවශ්‍ය යළි-යොමුවීම් URL එක සොයා ගැනීමට නොහැකි විය @@ -1178,57 +1214,62 @@ si: rss: content_warning: 'අන්තර්ගත අනතුරු ඇඟවීම:' descriptions: - account: "@%{acct}සිට පොදු පළ කිරීම්" - tag: "#%{hashtag}ටැග් කර ඇති පොදු පළ කිරීම්" + account: "@%{acct} වෙතින් ප්‍රසිද්ධ ලිපි" scheduled_statuses: - over_daily_limit: ඔබ අද දිනට නියමිත පළ කිරීම් %{limit} සීමාව ඉක්මවා ඇත - over_total_limit: ඔබ නියමිත පළ කිරීම් %{limit} සීමාව ඉක්මවා ඇත too_soon: නියමිත දිනය අනාගතයේ විය යුතුය sessions: activity: අවසාන ක්‍රියාකාරකම browser: අතිරික්සුව browsers: alipay: අලිපේ + blackberry: බ්ලැක්බෙරි chrome: ක්‍රෝම් edge: මයික්‍රොසොෆ්ට් එඩ්ගේ electron: ඉලෙක්ට්‍රෝන් firefox: ෆයර්ෆොක්ස් generic: නොදන්නා අතිරික්සුවකි + huawei_browser: හුආවේ අතිරික්සුව ie: ඉන්ටර්නෙට් එක්ස්ප්ලෝරර් micro_messenger: මයික්‍රොමැසෙන්ජර් - nokia: Nokia S40 Ovi බ්‍රව්සරය + nokia: නොකියා S40 Ovi අතිරික්සුව opera: ඔපෙරා otter: ඔටර් + phantom_js: PhantomJS qq: කියුකියු අතිරික්සුව safari: සෆාරි + uc_browser: UC අතිරික්සුව + unknown_browser: නොදන්නා අතිරික්සුවකි weibo: වෙයිබො - current_session: වත්මන් සැසිය - description: "%{browser} මත %{platform}" - explanation: මේවා දැනට ඔබගේ Mastodon ගිණුමට ලොග් වී ඇති වෙබ් බ්‍රව්සර් වේ. + current_session: වත්මන් වාරය + description: "%{platform} හි %{browser}" + explanation: ඔබගේ මාස්ටඩන් ගිණුමට පිවිසීම සඳහා භාවිතා කර තිබෙන අතිරික්සු. ip: අ.ජා. කෙ. (IP) platforms: adobe_air: ඇඩෝබි එයාර් android: ඇන්ඩ්‍රොයිඩ් + blackberry: බ්ලැක්බෙරි + chrome_os: ChromeOS firefox_os: ෆයර්ෆොක්ස් ඕඑස් ios: අයිඕඑස් + kai_os: KaiOS linux: ලිනක්ස් mac: මැක්ඕඑස් - other: නොදන්නා වේදිකාව + unknown_platform: නොදන්නා වේදිකාවකි windows: වින්ඩෝස් windows_mobile: වින්ඩෝස් මොබයිල් windows_phone: වින්ඩෝස් පෝන් revoke: අවලංගු කරන්න - revoke_success: සැසිය සාර්ථකව අවලංගු කරන ලදී - title: සැසිවාර + revoke_success: වාරය සාර්ථකව අවලංගු කෙරිණි + title: වාර view_authentication_history: ඔබගේ ගිණුමේ සත්‍යාපන ඉතිහාසය බලන්න settings: account: ගිණුම account_settings: ගිණුමේ සැකසුම් aliases: ගිණුම් අන්වර්ථ නාමයන් appearance: පෙනුම - authorized_apps: අවසර ලත් යෙදුම් - back: Mastodon වෙත නැවත යන්න - delete: ගිණුම මකා දැමීම + authorized_apps: බලයලත් යෙදුම් + back: මාස්ටඩන් වෙත ආපසු + delete: ගිණුම මැකීම development: සංවර්ධනය edit_profile: පැතිකඩ සංස්කරණය export: දත්ත නිර්යාතය @@ -1237,13 +1278,12 @@ si: import_and_export: ආයාත හා නිර්යාත migrate: ගිණුම් සංක්‍රමණය notifications: දැනුම්දීම් - preferences: මනාප - profile: පැතිකඩ - relationships: අනුගාමිකයින් සහ අනුගාමිකයින් - statuses_cleanup: ස්වයංක්‍රීය පළ කිරීම් මකාදැමීම - strikes: මධ්‍යස්ථ වැඩ වර්ජන + preferences: අභිප්‍රේත + profile: ප්‍රසිද්ධ පැතිකඩ + relationships: අනුගමන හා අනුගාමික + statuses_cleanup: ස්වයංක්‍රීය ලිපි මැකීම two_factor_authentication: ද්වි සාධක Aut - webauthn_authentication: ආරක්ෂක යතුරු + webauthn_authentication: ආරක්‍ෂණ යතුරු statuses: attached: audio: @@ -1251,87 +1291,75 @@ si: other: "%{count} ශ්රව්ය" description: 'අමුණා ඇත: %{attached}' image: - one: "%{count} රූපය" - other: පින්තූර %{count} + one: රූප %{count} + other: රූප %{count} video: - one: "%{count} වීඩියෝ" - other: වීඩියෝ %{count} - boosted_from_html: "%{acct_link}සිට වැඩි කරන ලදී" + one: දෘශ්‍යක %{count} + other: දෘශ්‍යක %{count} content_warning: 'අන්තර්ගත අනතුරු ඇඟවීම: %{warning}' - default_language: අතුරු මුහුණත් භාෂාවට සමානයි + default_language: අතුරු මුහුණතේ භාෂාවම disallowed_hashtags: one: 'අනුමත නොකළ හැෂ් ටැගයක් අඩංගු විය: %{tags}' other: 'අනුමත නොකළ හැෂ් ටැග් අඩංගු විය: %{tags}' edited_at_html: සංස්කරණය %{date} errors: - in_reply_not_found: ඔබ පිළිතුරු දීමට උත්සාහ කරන පළ කිරීම පවතින බවක් නොපෙනේ. + in_reply_not_found: ඔබ පිළිතුරු දීමට තැත් කරන ලිපිය නොපවතින බව පෙනෙයි. open_in_web: වෙබයේ විවෘත කරන්න over_character_limit: අක්ෂර සීමාව %{max} ඉක්මවා ඇත pin_errors: - direct: සඳහන් කළ පරිශීලකයින්ට පමණක් පෙනෙන පළ කිරීම් ඇමිණිය නොහැක - limit: ඔබ දැනටමත් උපරිම පළ කිරීම් සංඛ්‍යාව අමුණා ඇත - ownership: වෙනත් කෙනෙකුගේ පළ කිරීමක් ඇමිණිය නොහැක - reblog: බූස්ට් එකක් ඇලවිය නොහැක + direct: සඳහන් කළ අයට පමණක් පෙනෙන ලිපි ඇමිණීමට නොහැකිය + limit: දැනටමත් මුදුනට ඇමිණිමට හැකි ලිපි සීමාවට ළඟා වී ඇත + ownership: වෙනත් අයගේ ලිපි ඇමිණීමට නොහැකිය poll: total_people: - one: "%{count} පුද්ගලයෙක්" - other: පුද්ගලයන් %{count} + one: පුද්ගලයින් %{count} + other: පුද්ගලයින් %{count} total_votes: - one: "%{count} ඡන්ද" + one: ඡන්ද %{count} යි other: ඡන්ද %{count} යි - vote: ඡන්දය දෙන්න + vote: ඡන්දය show_more: තව පෙන්වන්න show_newer: අලුත්ම පෙන්වන්න show_older: පැරණි පෙන්වන්න show_thread: නූල් පෙන්වන්න - sign_in_to_participate: සංවාදයට සහභාගී වීමට පුරන්න title: '%{name}: "%{quote}"' visibilities: direct: සෘජු - private: අනුගාමිකයින්-පමණි + private: අනුගාමිකයින් පමණි private_long: අනුගාමිකයින්ට පමණක් පෙන්වන්න public: ප්‍රසිද්ධ public_long: හැමෝටම පේනවා unlisted: ලැයිස්තුගත නොකළ unlisted_long: සෑම කෙනෙකුටම දැකිය හැක, නමුත් පොදු කාලරාමුවෙහි ලැයිස්තුගත කර නොමැත statuses_cleanup: - enabled: පැරණි පළ කිරීම් ස්වයංක්‍රීයව මකන්න - enabled_hint: ඔබේ පළ කිරීම් පහත ව්‍යතිරේකවලින් එකකට ගැලපෙන්නේ නම් මිස, ඒවා නිශ්චිත වයස් සීමාවකට ළඟා වූ පසු ස්වයංක්‍රීයව මකයි - exceptions: ව්යතිරේක - explanation: පළ කිරීම් මකා දැමීම මිල අධික මෙහෙයුමක් වන බැවින්, සේවාදායකය වෙනත් ආකාරයකින් කාර්යබහුල නොවන විට කාලයත් සමඟ මෙය සෙමින් සිදු කෙරේ. මෙම හේතුව නිසා, ඔබේ පළ කිරීම් වයස් සීමාවට ළඟා වූ පසු ටික වේලාවකට පසුව මකා දැමිය හැක. - ignore_favs: ප්‍රියතමයන් නොසලකා හරින්න - ignore_reblogs: වැඩි කිරීම් නොසලකා හරින්න + enabled: පරණ ලිපි ස්වයංක්‍රීයව මකන්න + exceptions: හැර දැමීම් + ignore_favs: ප්‍රියතමයන් නොසලකන්න interaction_exceptions: අන්තර්ක්‍රියා මත පදනම් වූ ව්‍යතිරේක - interaction_exceptions_explanation: පළ කිරීම් වරක් ඒවා ඉක්මවා ගිය පසු ප්‍රියතම හෝ බූස්ට් සීමාවට පහළින් ගියහොත් ඒවා මැකීමට සහතිකයක් නොමැති බව සලකන්න. - keep_direct: සෘජු පණිවිඩ තබා ගන්න - keep_direct_hint: ඔබගේ සෘජු පණිවිඩ කිසිවක් මකන්නේ නැත - keep_media: මාධ්‍ය ඇමුණුම් සමඟ පළ කිරීම් තබා ගන්න - keep_media_hint: මාධ්‍ය ඇමුණුම් ඇති ඔබේ පළ කිරීම් කිසිවක් මකන්නේ නැත + keep_direct: සෘජු පණිවිඩ තබාගන්න + keep_direct_hint: ඔබගේ සෘජු පණිවිඩ කිසිවක් නොමැකෙයි + keep_media: මාධ්‍ය ඇමුණුම් සහිත ලිපි තබාගන්න + keep_media_hint: මාධ්‍ය ඇමුණුම් සහිත ඔබගේ ලිපි කිසිවක් නොමැකෙයි keep_pinned: ඇමිණූ ලිපි තබාගන්න keep_pinned_hint: ඔබ ඇමිණූ ලිපි කිසිවක් නොමැකෙයි - keep_polls: ඡන්ද තබා ගන්න - keep_polls_hint: ඔබගේ ඡන්ද විමසීම් කිසිවක් මකන්නේ නැත - keep_self_bookmark: ඔබ පිටු සලකුණු කළ පළ කිරීම් තබා ගන්න - keep_self_bookmark_hint: ඔබ ඔබේම පළ කිරීම් පිටු සලකුණු කර ඇත්නම් ඒවා මකා නොදමන්න - keep_self_fav: ඔබ කැමති පළ කිරීම් තබා ගන්න - keep_self_fav_hint: ඔබ ඒවාට කැමති නම් ඔබේම පළ කිරීම් මකා නොදමන්න + keep_polls: මත විමසුම් තබාගන්න + keep_polls_hint: ඔබගේ මත විමසුම් නොමැකෙයි + keep_self_bookmark: ඔබ පොත්යොමු තැබූ ලිපි තබාගන්න + keep_self_bookmark_hint: ඔබගේම ලිපි වලට පොත්යොමු තබා ඇත්නම් ඒවා මකා නොදැමෙයි + keep_self_fav: ඔබ ප්‍රිය කළ ලිපි තබාගන්න + keep_self_fav_hint: ඔබගේම ලිපි වලට ප්‍රිය කර ඇත්නම් ඒවා මකා නොදැමෙයි min_age: - '1209600': සති 2 යි - '15778476': මාස 6 යි - '2629746': මාස 1 යි - '31556952': වසර 1 යි - '5259492': මාස 2 ක් - '604800': 1 සතිය - '63113904': අවුරුදු 2 ක් - '7889238': මාස 3 යි - min_age_label: වයස් සීමාව - min_favs: අඩුම තරමින් පෝස්ට් ප්‍රිය කරන ලෙස තබා ගන්න - min_favs_hint: අවම වශයෙන් මෙම ප්‍රියතම ප්‍රමාණය ලබා ඇති ඔබේ පළ කිරීම් කිසිවක් මකන්නේ නැත. ඔවුන්ගේ ප්‍රියතමයන් ගණන නොතකා පළ කිරීම් මැකීමට හිස්ව තබන්න - min_reblogs: අඩුම තරමේ පෝස්ට් බූස්ට් කරගෙන තියාගන්න - min_reblogs_hint: අඩුම තරමින් මෙම වාර ගණන වැඩි කර ඇති ඔබගේ පළ කිරීම් කිසිවක් මකා නොදමන්න. බූස්ට් ගණන නොතකා පළ කිරීම් මැකීමට හිස්ව තබන්න + '1209600': සති 2 + '15778476': මාස 6 + '2629746': මාස 1 + '31556952': අවුරුදු 1 + '5259492': මාස 2 + '604800': සති 1 + '63113904': අවුරුදු 2 + '7889238': මාස 3 + min_age_label: කාල සීමාව + min_favs: අවම වශයෙන් ප්‍රිය කළ ලිපි තබාගන්න stream_entries: - pinned: ඇමිණූ ලිපිය - reblogged: ඉහල නැංවීය sensitive_content: සංවේදී අන්තර්ගතයකි strikes: errors: @@ -1339,22 +1367,26 @@ si: tags: does_not_match_previous_name: පෙර නමට නොගැලපේ themes: - contrast: Mastodon (ඉහළ වෙනස) - default: මැස්ටෝඩන් (අඳුරු) - mastodon-light: මැස්ටෝඩන් (ආලෝකය) + default: මාස්ටඩන් (අඳුරු) + mastodon-light: මාස්ටඩන් (දීප්ත) + time: + formats: + default: "%Y %b %d, %H:%M" + month: "%Y %b" + with_time_zone: "%Y %b %d, %H:%M %Z" two_factor_authentication: - add: එකතු කරන්න + add: එකතු disable: 2FA අබල කරන්න disabled_success: ද්වි-සාධක සත්‍යාපනය සාර්ථකව අබල කර ඇත edit: සංස්කරණය enabled: ද්වි-සාධක සත්‍යාපනය සක්‍රීය කර ඇත enabled_success: ද්වි-සාධක සත්‍යාපනය සාර්ථකව සබල කර ඇත - generate_recovery_codes: ප්‍රතිසාධන කේත ජනනය කරන්න + generate_recovery_codes: ප්‍රතිසාධන කේත උත්පාදනය කරන්න lost_recovery_codes: ඔබගේ දුරකථනය නැති වුවහොත් ඔබගේ ගිණුමට ප්‍රවේශය නැවත ලබා ගැනීමට ප්‍රතිසාධන කේත ඔබට ඉඩ සලසයි. ඔබට ඔබේ ප්‍රතිසාධන කේත නැති වී ඇත්නම්, ඔබට ඒවා මෙහි නැවත උත්පාදනය කළ හැක. ඔබගේ පැරණි ප්‍රතිසාධන කේත අවලංගු වනු ඇත. - methods: ද්වි සාධක ක්රම + methods: ද්වි සාධක ක්‍රම otp: Authenticator යෙදුම - recovery_codes: උපස්ථ ප්‍රතිසාධන කේත - recovery_codes_regenerated: ප්‍රතිසාධන කේත සාර්ථකව ප්‍රතිජනනය කරන ලදී + recovery_codes: ප්‍රතිසාධන කේත උපස්ථය + recovery_codes_regenerated: ප්‍රතිසාධන කේත නැවත උත්පාදනය කෙරිණි recovery_instructions_html: ඔබට කවදා හෝ ඔබගේ දුරකථනයට ප්‍රවේශය අහිමි වුවහොත්, ඔබගේ ගිණුමට ප්‍රවේශය නැවත ලබා ගැනීමට පහත ප්‍රතිසාධන කේත වලින් එකක් භාවිතා කළ හැක. ප්‍රතිසාධන කේත ආරක්ෂිතව තබා ගන්න. උදාහරණයක් ලෙස, ඔබට ඒවා මුද්‍රණය කර වෙනත් වැදගත් ලේඛන සමඟ ගබඩා කළ හැකිය. webauthn: ආරක්‍ෂණ යතුරු user_mailer: @@ -1368,11 +1400,11 @@ si: subject: "%{date} සිට ඔබගේ අභියාචනය ප්‍රතික්ෂේප කර ඇත" title: අභියාචනය ප්‍රතික්ෂේප විය backup_ready: - explanation: ඔබ ඔබේ Mastodon ගිණුමේ සම්පූර්ණ උපස්ථයක් ඉල්ලා ඇත. එය දැන් බාගත කිරීම සඳහා සූදානම්! + explanation: ඔබගේ මාස්ටඩන් ගිණුමේ පූර්ණ උපස්ථයක් ඉල්ලා ඇත. එය දැන් බාගැනීමට හැකිය! subject: ඔබගේ සංරක්ෂිතය බාගැනීමට සූදානම්ය title: සංරක්ෂිත රැගෙන යාම suspicious_sign_in: - change_password: ඔබගේ මුරපදය වෙනස් කරන්න + change_password: මුරපදය වෙනස් කරන්න details: 'පුරනය වීමේ විස්තර මෙන්න:' explanation: අපි නව IP ලිපිනයකින් ඔබගේ ගිණුමට පුරනය වීමක් අනාවරණය කරගෙන ඇත. further_actions_html: මෙය ඔබ නොවේ නම්, අපි ඔබට වහාම %{action} ලෙස නිර්දේශ කර ඔබගේ ගිණුම සුරක්ෂිතව තබා ගැනීමට සාධක දෙකක සත්‍යාපනය සබල කරන්න. @@ -1382,40 +1414,36 @@ si: appeal: අභියාචනයක් ඉදිරිපත් කරන්න appeal_description: මෙය දෝෂයක් බව ඔබ විශ්වාස කරන්නේ නම්, ඔබට %{instance}හි කාර්ය මණ්ඩලයට අභියාචනයක් ඉදිරිපත් කළ හැක. categories: - spam: ආයාචිත තැපැල් + spam: ආයාචිත violation: අන්තර්ගතය පහත ප්‍රජා මාර්ගෝපදේශ උල්ලංඝනය කරයි explanation: - delete_statuses: ඔබගේ සමහර පළ කිරීම් ප්‍රජා මාර්ගෝපදේශ එකක් හෝ කිහිපයක් උල්ලංඝනය කරන බව සොයා ගෙන ඇති අතර පසුව %{instance}හි උපපරිපාලකයින් විසින් ඉවත් කර ඇත. disable: ඔබට තවදුරටත් ඔබගේ ගිණුම භාවිතා කළ නොහැක, නමුත් ඔබගේ පැතිකඩ සහ අනෙකුත් දත්ත නොවෙනස්ව පවතී. ඔබට ඔබගේ දත්තවල උපස්ථයක් ඉල්ලා සිටීමට, ගිණුම් සැකසීම් වෙනස් කිරීමට හෝ ඔබගේ ගිණුම මකා දැමීමට හැකිය. - mark_statuses_as_sensitive: ඔබගේ සමහර පළ කිරීම් %{instance}හි පරිපාලකයින් විසින් සංවේදී ලෙස සලකුණු කර ඇත. මෙයින් අදහස් කරන්නේ පෙරදසුනක් දර්ශනය වීමට පෙර පුද්ගලයින්ට පළ කිරීම් වල මාධ්‍ය තට්ටු කිරීමට අවශ්‍ය වනු ඇති බවයි. අනාගතයේදී පළ කිරීමේදී ඔබට මාධ්‍ය සංවේදී ලෙස සලකුණු කළ හැක. - sensitive: මෙතැන් සිට, ඔබගේ උඩුගත කරන ලද සියලුම මාධ්‍ය ගොනු සංවේදී ලෙස සලකුණු කර ක්ලික්-හරහා අනතුරු ඇඟවීමක් පිටුපස සඟවනු ඇත. - silence: ඔබට තවමත් ඔබගේ ගිණුම භාවිතා කළ හැකි නමුත් දැනටමත් ඔබව අනුගමනය කරන පුද්ගලයින් පමණක් මෙම සේවාදායකයේ ඔබගේ පළ කිරීම් දකිනු ඇති අතර, විවිධ සොයාගැනීම් විශේෂාංග වලින් ඔබව බැහැර කරනු ලැබිය හැක. කෙසේ වෙතත්, අනෙක් අය තවමත් ඔබව අතින් අනුගමනය කළ හැක. + sensitive: මේ මොහොත් සිට ඔබ උඩුගත කරන සියලුම මාධ්‍ය ගොනු සංවේදී ලෙස සලකා අවවාදයක් පිටුපස සඟවනු ඇත. suspend: ඔබට තවදුරටත් ඔබගේ ගිණුම භාවිතා කළ නොහැකි අතර, ඔබගේ පැතිකඩ සහ අනෙකුත් දත්ත තවදුරටත් ප්‍රවේශ විය නොහැක. දින 30කින් පමණ දත්ත සම්පූර්ණයෙන් ඉවත් කරන තෙක් ඔබට තවමත් ඔබේ දත්තවල උපස්ථයක් ඉල්ලා සිටීමට පුරනය විය හැක, නමුත් ඔබව අත්හිටුවීම මගහැර යාම වැළැක්වීමට අපි මූලික දත්ත කිහිපයක් රඳවා ගන්නෙමු. reason: 'හේතුව:' - statuses: 'උපුටා දක්වන ලද පළ කිරීම්:' subject: - delete_statuses: "%{acct} හි ඔබගේ පළ කිරීම් ඉවත් කර ඇත" + delete_statuses: "%{acct} හි ඔබගේ ලිපිය ඉවත් කර ඇත" disable: ඔබගේ ගිණුම %{acct} කර ඇත - mark_statuses_as_sensitive: "%{acct} හි ඔබගේ පළ කිරීම් සංවේදී ලෙස සලකුණු කර ඇත" - none: "%{acct}සඳහා අනතුරු ඇඟවීම" - sensitive: "%{acct} හි ඔබගේ පළ කිරීම් මෙතැන් සිට සංවේදී ලෙස සලකුණු කෙරේ" + mark_statuses_as_sensitive: ඔබගේ %{acct} ලිපි සංවේදී බව සලකුණු කර ඇත + none: "%{acct} සඳහා අවවාදය" + sensitive: ඔබගේ %{acct} ලිපිය මේ මොහොතේ සිට සංවේදී ලෙස සලකයි silence: ඔබගේ ගිණුම %{acct} සීමා කර ඇත suspend: ඔබගේ ගිණුම %{acct} අත්හිටුවා ඇත title: - delete_statuses: පළ කිරීම් ඉවත් කරන ලදී + delete_statuses: ලිපි ඉවත් කර ඇත disable: ගිණුම නිශ්චල කර ඇත - mark_statuses_as_sensitive: පළ කිරීම් සංවේදී ලෙස ලකුණු කර ඇත + mark_statuses_as_sensitive: ලිපි සංවේදී බව සලකුණු කර ඇත none: අවවාදයයි - sensitive: ගිණුම සංවේදී ලෙස ලකුණු කර ඇත - silence: ගිණුම සීමා සහිතයි + sensitive: ගිණුම සංවේදී බව යොදා ඇත + silence: ගිණුම සීමා කර ඇත suspend: ගිණුම අත්හිටුවා ඇත welcome: - edit_profile_action: සැකසුම් පැතිකඩ + edit_profile_action: පැතිකඩ පිහිටුවන්න explanation: ඔබ ආරම්භ කිරීමට උපදෙස් කිහිපයක් මෙන්න - final_action: පළ කිරීම ආරම්භ කරන්න + final_action: ලිපි පළ කරන්න full_handle: ඔබේ සම්පූර්ණ හසුරුව full_handle_hint: මෙය ඔබ ඔබේ මිතුරන්ට පවසනු ඇත, එවිට ඔවුන්ට වෙනත් සේවාදායකයකින් ඔබට පණිවිඩ යැවීමට හෝ අනුගමනය කිරීමට හැකිය. - subject: Mastodon වෙත සාදරයෙන් පිළිගනිමු + subject: මාස්ටඩන් වෙත පිළිගනිමු title: නැවට සාදරයෙන් පිළිගනිමු, %{name}! users: follow_limit_reached: ඔබට පුද්ගලයින් %{limit} කට වඩා අනුගමනය කළ නොහැක @@ -1424,10 +1452,10 @@ si: seamless_external_login: ඔබ බාහිර සේවාවක් හරහා ලොග් වී ඇත, එබැවින් මුරපදය සහ ඊමේල් සැකසුම් නොමැත. signed_in_as: 'මෙසේ පුරනය වී ඇත:' verification: - explanation_html: 'ඔබගේ පැතිකඩ පාරදත්තහි ඇති සබැඳි වල හිමිකරු ලෙස ඔබට සත්‍යාපනය කළ හැක. ඒ සඳහා, සම්බන්ධිත වෙබ් අඩවියේ ඔබේ Mastodon පැතිකඩ වෙත ආපසු සබැඳියක් තිබිය යුතුය. සබැඳිය ආපසු යුතුය. සබැඳියේ පෙළ අන්තර්ගතය වැදගත් නොවේ. මෙන්න උදාහරණයක්:' - verification: සත්යාපනය + here_is_how: කෙසේදැයි මෙන්න + verification: සත්‍යාපනය webauthn_credentials: - add: නව ආරක්ෂක යතුර එක් කරන්න + add: නව ආරක්‍ෂණ යතුර එක් කරන්න create: error: ඔබගේ ආරක්ෂක යතුර එක් කිරීමේ ගැටලුවක් ඇති විය. කරුණාකර නැවත උත්සාහ කරන්න. success: ඔබගේ ආරක්ෂක යතුර සාර්ථකව එක් කරන ලදී. @@ -1437,9 +1465,9 @@ si: destroy: error: ඔබගේ ආරක්ෂක යතුර මැකීමේ ගැටලුවක් ඇති විය. කරුණාකර නැවත උත්සාහ කරන්න. success: ඔබගේ ආරක්ෂක යතුර සාර්ථකව මකා ඇත. - invalid_credential: වලංගු නොවන ආරක්ෂක යතුර + invalid_credential: ආරක්‍ෂණ යතුර වලංගු නොවේ nickname_hint: ඔබගේ නව ආරක්ෂක යතුරේ අන්වර්ථ නාමය ඇතුළත් කරන්න not_enabled: ඔබ තවමත් WebAuthn සබල කර නැත not_supported: මෙම බ්‍රවුසරය ආරක්ෂක යතුරු සඳහා සහය නොදක්වයි otp_required: ආරක්ෂක යතුරු භාවිතා කිරීමට කරුණාකර පළමුව ද්වි-සාධක සත්‍යාපනය සක්‍රීය කරන්න. - registered_on: "%{date}හි ලියාපදිංචි වී ඇත" + registered_on: "%{date} දී ලියාපදිංචි වී ඇත" diff --git a/config/locales/simple_form.an.yml b/config/locales/simple_form.an.yml index 10671134d4..f354e5ba82 100644 --- a/config/locales/simple_form.an.yml +++ b/config/locales/simple_form.an.yml @@ -37,14 +37,11 @@ an: current_password: Per razons de seguranza per favor ingrese la clau d'a cuenta actual current_username: Pa confirmar, per favor ingrese lo nombre d'usuario d'a cuenta actual digest: Solo ninviau dimpués d'un largo periodo d'inactividat y nomás si has recibiu mensaches personals entre la tuya ausencia - discoverable: Permite que la tuya cuenta sía descubierta per extranyos a traviés de recomendacions, tendencias y atras caracteristicas email: Se le ninviará un correu de confirmación - fields: Puetz tener dica 4 elementos amostrando-se como una tabla en o tuyo perfil header: PNG, GIF u JPG. Maximo %{size}. Será escalau a %{dimensions}px inbox_url: Copia la URL d'a pachina prencipal d'o relés que quiers utilizar irreversible: Las publicacions filtradas desapareixerán irreversiblement, mesmo si este filtro ye eliminau mas abance locale: L'idioma d'a interficie d'usuario, correus y notificacions push - locked: Requiere que manualment aprebes seguidores y las publicacions serán amostradas nomás a las tuyas seguidores password: Utilice a lo menos 8 caracters phrase: S'aplicará sin importar las mayusclas u los avisos de conteniu d'una publicación scopes: Qué APIs de l'aplicación tendrán acceso. Si trías l'aconsiga de libel pero alto, no amenestes triar las individuals. @@ -54,12 +51,8 @@ an: setting_display_media_default: Amagar conteniu multimedia marcau como sensible setting_display_media_hide_all: Siempre amagar tot lo conteniu multimedia setting_display_media_show_all: Amostrar siempre conteniu multimedia marcau como sensible - setting_hide_network: A quí sigues y quí te sigue no será amostrau en o tuyo perfil - setting_noindex: Afecta a lo tuyo perfil publico y pachinas d'estau - setting_show_application: L'aplicación que utiliza vusté pa publicar publicacions s'amostrará en a vista detallada d'as suyas publicacions setting_use_blurhash: Los gradientes se basan en as colors d'as imachens amagadas pero fendo borrosos los detalles setting_use_pending_items: Amagar nuevos estaus dezaga d'un clic en cuenta de desplazar automaticament lo feed - username: Lo tuyo nombre d'usuario será solo en %{domain} whole_word: Quan la parola clau u frase ye nomás alfanumerica, nomás será aplicau si concuerda con tota la parola domain_allow: domain: Este dominio podrá obtener datos d'este servidor y los datos dentrants serán procesaus y archivados @@ -172,7 +165,6 @@ an: context: Filtrar contextos current_password: Clau actual data: Información - discoverable: Sucherir la cuenta a atros display_name: Nombre pa amostrar email: Adreza de correu electronico expires_in: Expirar dimpués de @@ -182,7 +174,6 @@ an: inbox_url: URL d'a dentrada de relés irreversible: Refusar en cuenta d'amagar locale: Idioma - locked: Fer privada esta cuenta max_uses: Máx. numero d'usos new_password: Nueva clau note: Biografía @@ -194,7 +185,6 @@ an: setting_always_send_emails: Ninviar siempre notificacions per correu setting_auto_play_gif: Reproducir automaticament los GIFs animaus setting_boost_modal: Amostrar finestra de confirmación antes de retutar - setting_crop_images: Retallar a 16x9 las imachens d'as publicacions no expandidas setting_default_language: Idioma de publicación setting_default_privacy: Privacidat de publicacions setting_default_sensitive: Marcar siempre imachens como sensibles @@ -206,9 +196,7 @@ an: setting_display_media_show_all: Amostrar tot setting_expand_spoilers: Siempre expandir las publicacions marcadas con alvertencias de conteniu setting_hide_network: Amagar lo tuyo ret - setting_noindex: Excluyir-se d'o indexado de motors de busqueda setting_reduce_motion: Reducir lo movimiento d'as animacions - setting_show_application: Amostrar aplicación usada pa publicar publicacions setting_system_font_ui: Utilizar la tipografía per defecto d'o sistema setting_theme: Tema d'o puesto setting_trends: Amostrar las tendencias de hue diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index 21d9c277f1..92e181a8ed 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -2,12 +2,20 @@ ar: simple_form: hints: + account: + discoverable: يمكن عرض مشاركاتك العامة وملفك الشخصي أو التوصية به في مختلف مناطق ماستدون ويمكن اقتراح ملفك الشخصي على مستخدمين آخرين. + display_name: اسمك الكامل أو اسمك المرح. + fields: صفحتك الرئيسية، ضمائرك، عمرك، أي شيء تريده. + indexable: قد تظهر منشوراتك الموجهة للعامة في نتائج البحث على ماستدون. فالأشخاص الذين تفاعلوا مع منشوراتك قد يكون بمقدورهم البحث عنها بغظ النظر عن ذلك. + note: 'يمكنك @ذكر أشخاص آخرين أو استعمال #الوسوم.' + show_collections: سيستطيع الناس من تصفح متابعيك و متابعاتك. سيرى الأشخاص الذين تتبعهم أنك تتبعهم دون أي شك. + unlocked: سيتمكن الآخرون من متابعتك دون طلب الموافقة. قم بتعطيله إن كنت ترغب في مراجعة تلك الطلبات يدويا باختيار قبول أو رفض المتابعين الجدد. account_alias: acct: ادخِل عنون الحساب username@domain الذي تودّ مغادرته account_migration: acct: ادخِل عنون الحساب username@domain الذي تودّ الإنتقال إليه account_warning_preset: - text: بإمكانك استخدام نفس القواعد التي نجدها في التبويقات كعناوين الروابط والوسوم والإشارات + text: بإمكانك استخدام نفس القواعد التي نجدها في المنشورات كالروابط التشعبية URLs والوسوم والإشارات title: اختياري. غير مرئي للمُستَلِم admin_account_action: include_statuses: سيرى المستخدم أي المنشورات تسببت في إجراء الإشراف أو التحذير @@ -19,6 +27,7 @@ ar: none: استخدم هذه لإرسال تحذير للمستخدم، دون تشغيل أو إثارة أي إجراء آخر. sensitive: إجبار جميع مرفقات الوسائط لهذا المستخدم على أن تكون حساسة. silence: منع المستخدم من القدرة على النشر للعامة، وإخفاء مشاركاته وإشعاراته لمن لا يتبعونه. إغلاق جميع التقارير المقترنة بهذا الحساب. + suspend: منع أي تفاعل من هذا الحساب أو إليه وحذف محتوياته. يمكن التراجع عنه في غضون 30 يوما. إغلاق جميع التقارير المفتوحة ضد هذا الحساب. warning_preset_id: اختياري. يمكنك إضافة نص مخصص إلى نهاية النموذج announcement: all_day: إن أختير، سيتم عرض تواريخ النطاق الزمني فقط @@ -36,29 +45,23 @@ ar: current_password: لأسباب أمنية ، يرجى إدخال الكلمة السرية الخاصة بالحساب الحالي current_username: يرجى إدخال اسم المستخدم الخاص بالحساب الحالي قصد التأكيد digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة - discoverable: السماح للغرباء اكتشاف حسابك من خلال التوصيات والمتداولة وغيرها من الميزات email: سوف تتلقى رسالة إلكترونية للتأكيد - fields: يُمكنك عرض 4 عناصر على شكل جدول في صفحتك التعريفية header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير %{size}. سيتم تصغيره إلى %{dimensions}px inbox_url: نسخ العنوان الذي تريد استخدامه مِن صفحة الاستقبال للمُرحَّل irreversible: المنشورات التي تم تصفيتها ستختفي لا محالة حتى و إن تمت إزالة عامِل التصفية لاحقًا locale: لغة واجهة المستخدم و الرسائل الإلكترونية و الإشعارات - locked: يتطلب منك الموافقة يدويا على طلبات المتابعة password: يُنصح باستخدام 8 أحرف على الأقل phrase: سوف يتم العثور عليه مهما كان نوع النص أو حتى و إن كان داخل الويب فيه تحذير عن المحتوى scopes: ما هي المجالات المسموح بها في التطبيق ؟ إن قمت باختيار أعلى المجالات فيمكنك الاستغناء عن الخَيار اليدوي. setting_aggregate_reblogs: لا تقم بعرض المشارَكات الجديدة لمنشورات قد قُمتَ بمشاركتها سابقا (هذا الإجراء يعني المشاركات الجديدة فقط التي تلقيتَها) - setting_always_send_emails: عادة لن ترسل الإشعارات إلى بريدك الإلكتروني عندما تكون نشط على ماستدون + setting_always_send_emails: عادة لن تُرسَل إليك إشعارات البريد الإلكتروني عندما تكون نشطًا على ماستدون setting_default_sensitive: تُخفى الوسائط الحساسة تلقائيا ويمكن اظهارها عن طريق النقر عليها setting_display_media_default: إخفاء الوسائط المُعيَّنة كحساسة setting_display_media_hide_all: إخفاء كافة الوسائط دائمًا setting_display_media_show_all: دائمًا عرض الوسائط المُعيَّنة كحساسة - setting_hide_network: الحسابات التي تُتابعها و التي تُتابِعك على حد سواء لن تُعرَض على صفحتك التعريفية - setting_noindex: ذلك يؤثر على صفحتك التعريفية وصفحات المنشورات - setting_show_application: سيُعرَض اسم التطبيق الذي تستخدمه عند النشر في العرض المفصّل لمنشوراتك setting_use_blurhash: الألوان التدرّجية مبنية على ألوان المرئيات المخفية ولكنها تحجب كافة التفاصيل - setting_use_pending_items: إخفاء تحديثات الخط وراء نقرة بدلًا مِن التمرير التلقائي للتدفق - username: اسم المستخدم الخاص بك سوف يكون فريدا مِن نوعه على %{domain} + setting_use_pending_items: إخفاء تحديثات الخط وراء نقرة بدلًا مِن التمرير التلقائي للموجزات + username: يمكنك استخدام الأحرف والأرقام والسطور السفلية whole_word: إذا كانت الكلمة أو العبارة مكونة من أرقام وحروف فقط سوف يتم تطبيقها فقط عند مطابقة الكلمة ككل domain_allow: domain: سيكون بإمكان هذا النطاق جلب البيانات من هذا الخادم ومعالجة وتخزين البيانات الواردة منه @@ -73,26 +76,30 @@ ar: hide: إخفاء المحتويات التي تم تصفيتها، والتصرف كما لو أنها غير موجودة warn: إخفاء المحتوى الذي تم تصفيته خلف تحذير يذكر عنوان الفلتر form_admin_settings: + activity_api_enabled: عدد المنشورات المحلية و المستخدمين الناشطين و التسجيلات الأسبوعية الجديدة backups_retention_period: الاحتفاظ بأرشيف المستخدم الذي تم إنشاؤه لعدد محدد من الأيام. bootstrap_timeline_accounts: سيتم تثبيت هذه الحسابات على قمة التوصيات للمستخدمين الجدد. closed_registrations_message: ما سيعرض عند إغلاق التسجيلات - content_cache_retention_period: سيتم حذف المشاركات من الخوادم الأخرى بعد عدد الأيام المحدد عند تعيينها إلى قيمة موجبة. قد يكون هذا لا رجعة فيه. + content_cache_retention_period: سيتم حذف كافة المنشورات والمعاد نشرها من الخوادم الأخرى بعد عدد الأيام المحدد. قد لا تكون بعض المنشورات قابلة للاسترداد. كافة الفواصل المرجعية والمفضلات والمعاد نشرها ذات الصلة سوف تضيع ويستحيل التراجع عن هذا الإجراء. custom_css: يمكنك تطبيق أساليب مخصصة على نسخة الويب من ماستدون. mascot: تجاوز الرسوم التوضيحية في واجهة الويب المتقدمة. media_cache_retention_period: سيتم حذف ملفات الوسائط التي تم تنزيلها بعد عدد الأيام المحدد عند تعيينها إلى قيمة موجبة، وإعادة تنزيلها عند الطلب. + peers_api_enabled: قائمة بأسماء النطاقات التي صادفها هذا الخادم في الفدرالية. لا توجد بيانات هنا حول ما إذا كنت تتحد مع خادم معين، فقط أن خادمك يعرف عنها. ويستخدم هذا الخدمات التي تجمع الإحصاءات المتعلقة بالاتحاد بشكل عام. profile_directory: دليل الملف الشخصي يسرد جميع المستخدمين الذين اختاروا الدخول ليكونوا قابلين للاكتشاف. require_invite_text: عندما تتطلب التسجيلات الموافقة اليدوية، اجعل إدخال النص "لماذا تريد الانضمام ؟" إلزاميا بدلا من اختياري site_contact_email: كيف يمكن للأشخاص أن يصلوا إليك للحصول على استفسارات قانونية أو استفسارات دعم. - site_contact_username: كيف يمكن للناس أن يصلوا إليك في ماستدون. + site_contact_username: كيف يمكن للناس أن يتصلوا بك في ماستدون. site_extended_description: أي معلومات إضافية قد تكون مفيدة للزوار والمستخدمين. يمكن تنظيمها مع بناء بنية Markdown. site_short_description: وصف قصير للمساعدة في التعرف على الخادم الخاص بك. من يقوم بتشغيله، ولمن ؟ site_terms: استخدم سياسة الخصوصية الخاصة بك أو اتركها فارغة لاستخدام الافتراضي. يمكن هيكلتها مع بناء الجملة المصغرة مارك داون. site_title: كيف يمكن للناس الرجوع إلى الخادم الخاص بك إلى جانب اسم النطاق. + status_page_url: العنوان التشعبي حيث يمكن للناس رؤية صفحة حالة هذا الخادم عند حدوث عطب ما theme: الشكل الذي يشاهده الزوار الجدد و الغير مسجلين الدخول. thumbnail: عرض حوالي 2:1 صورة إلى جانب معلومات الخادم الخاص بك. timeline_preview: الزوار الذين سجلوا خروجهم سيكونون قادرين على تصفح أحدث المشاركات العامة المتاحة على الخادم. trendable_by_default: تخطي مراجعة المحتوى التريند اليدوي. لا يزال من الممكن الإزالة اللاحقة للعناصر الفردية من التريندات. - trends: تظهر التريندز أي المشاركات وعلامات وقصص الأخبار التي تجذب الانتباه على الخادم الخاص بك. + trends: تُظهِر المتداولة أي من المنشورات والوسوم وقصص الأخبار التي تجذب الانتباه على خادمك. + trends_as_landing_page: إظهار المحتوى المتداوَل للمستخدمين والزوار غير المسجلين بدلاً من وصف هذا الخادم. يتطلب هذا تفعيل المتداولة. form_challenge: current_password: إنك بصدد الدخول إلى منطقة آمنة imports: @@ -105,7 +112,7 @@ ar: ip: أدخل عنوان IPv4 أو IPv6. يمكنك حظر نطاقات كاملة باستخدام بناء الـCIDR. كن حذراً على أن لا تَحظر نفسك! severities: no_access: حظر الوصول إلى جميع المصادر - sign_up_block: لا يمكن إنشاء حسابات جديدة + sign_up_block: لن يكون بالإمكان إنشاء حسابات جديدة sign_up_requires_approval: التسجيلات الجديدة سوف تتطلب موافقتك severity: اختر ما سيحدث مع الطلبات من هذا الـIP rule: @@ -113,6 +120,9 @@ ar: sessions: otp: 'قم بإدخال رمز المصادقة بخطوتين الذي قام بتوليده تطبيق جهازك أو استخدم أحد رموز النفاذ الاحتياطية:' webauthn: إذا كان مفتاح USB فتأكد من إدخاله، وإذا لزم الأمر، اضعط عليه. + settings: + indexable: قد تظهر صفحة ملفك التعريفي الشخصي في نتائج البحث على محرك البحث غوغل وبينغ وغيرهما. + show_application: سوف تكون دائماً قادراً على رؤية التطبيق الذي نشر مشاركتك بغض النظر عن ذلك. tag: name: يمكنك فقط تغيير غلاف الحروف ، على سبيل المثال ، لجعلها أكثر قابلية للقراءة user: @@ -126,12 +136,17 @@ ar: position: وتقرر الوظيفة الأعلى تسوية النزاعات في حالات معينة، ولا يمكن القيام ببعض الإجراءات إلا على أساس الوظائف ذات الأولوية الأقل webhook: events: حدد الأحداث لإرسالها + template: ألف حمولة JSON الخاصة بك باستخدام استخراج المتغير. اتركه فارغاً لاستخدام JSON الافتراضي. url: إين سترسل الأحداث labels: account: + discoverable: ميزة الملف الشخصي والمنشورات في خوارزميات الاكتشاف fields: name: التسمية value: المحتوى + indexable: فهرسة المنشورات الموجهة للعامة في نتائج البحث + show_collections: إظهار المتابَعين والمتابَعون على الصفحة التعريفية + unlocked: قبول طلبات المتابعة الجدد تلقائياً account_alias: acct: مُعرّف الحساب القديم account_migration: @@ -161,25 +176,23 @@ ar: text: اشرح لماذا يجب إلغاء هذا القرار defaults: autofollow: إرسال دعوة لمتابعة حسابك - avatar: الصورة الرمزية - bot: إنّ هذا الحساب روبوت آلي + avatar: صورة الملف الشخصي + bot: هذا حساب آلي chosen_languages: تصفية اللغات confirm_new_password: تأكيد كلمة السر الجديدة confirm_password: تأكيد كلمة السر context: تصفية السياقات current_password: كلمة السر الحالية data: البيانات - discoverable: القيام بإدراج هذا الحساب في قائمة دليل الحسابات display_name: الاسم المعروض email: عنوان البريد الإلكتروني expires_in: تنتهي مدة صلاحيته بعد - fields: البيانات الوصفية للصفحة التعريفية - header: الرأسية + fields: حقول إضافية + header: صورة الرأسية honeypot: "%{label} (لا تملئ)" inbox_url: عنوان رابط صندوق المُرَحِّل irreversible: إسقاط بدلا من إخفائها locale: لغة الواجهة - locked: تجميد الحساب max_uses: عدد مرات استخدام الرابط new_password: كلمة السر الجديدة note: السيرة الذاتية @@ -187,11 +200,10 @@ ar: password: كلمة السر phrase: كلمة مفتاح أو عبارة setting_advanced_layout: تمكين واجهة الويب المتقدمة - setting_aggregate_reblogs: جمع الترقيات في خيوط زمنية + setting_aggregate_reblogs: جمّع المنشورات المعاد نشرها في الخيوط الزمنية setting_always_send_emails: ارسل إشعارات البريد الإلكتروني دائماً setting_auto_play_gif: تشغيل تلقائي لِوَسائط جيف المتحركة setting_boost_modal: إظهار مربع حوار التأكيد قبل إعادة مشاركة أي منشور - setting_crop_images: قص الصور في المنشورات غير الموسعة إلى 16x9 setting_default_language: لغة النشر setting_default_privacy: خصوصية المنشور setting_default_sensitive: اعتبر الوسائط دائما كمحتوى حساس @@ -203,9 +215,7 @@ ar: setting_display_media_show_all: عرض الكل setting_expand_spoilers: توسيع المنشورات التي تحتوي على تحذيرات عن المحتوى دائما setting_hide_network: إخفِ شبكتك - setting_noindex: الطلب مِن محركات البحث بعدم فهرسة معلوماتك وصفحتك التعريفية الشخصية setting_reduce_motion: تخفيض عدد الصور في الوسائط المتحركة - setting_show_application: اكشف اسم التطبيق المستخدَم لإرسال المنشورات setting_system_font_ui: استخدم الخطوط الافتراضية للنظام setting_theme: سمة الموقع setting_trends: اعرض ما يُتداوَل اليوم @@ -217,7 +227,7 @@ ar: title: العنوان type: صيغة الاستيراد username: اسم المستخدم - username_or_email: اسم المستخدم أو كلمة السر + username_or_email: اسم المستخدم أو عنوان البريد الإلكتروني whole_word: الكلمة كاملة email_domain_block: with_dns_records: تضمين سجلات MX و عناوين IP للنطاق @@ -228,6 +238,7 @@ ar: hide: إخفاء بالكامل warn: إخفاء بتحذير form_admin_settings: + activity_api_enabled: نشر مُجمل الإحصائيات عن نشاط المستخدمين في واجهة برمجة التطبيقات API backups_retention_period: فترة الاحتفاظ بأرشيف المستخدم bootstrap_timeline_accounts: أوصي دائما بهذه الحسابات للمستخدمين الجدد closed_registrations_message: رسالة مخصصة عندما يكون التسجيل غير متاح @@ -247,11 +258,13 @@ ar: site_short_description: وصف الخادم site_terms: سياسة الخصوصية site_title: اسم الخادم + status_page_url: الرابط التشعبي لصفحة حالة الخادم theme: الحُلَّة الإفتراضية thumbnail: الصورة المصغرة للخادم timeline_preview: السماح بالوصول غير الموثق إلى الخيوط الزمنية العامة trendable_by_default: السماح للوسوم بالظهور على المتداوَلة دون مراجعة مسبقة trends: تمكين المتداوَلة + trends_as_landing_page: استخدام المُتداوَلة كصفحة ترحيب interactions: must_be_follower: حظر الإشعارات القادمة من حسابات لا تتبعك must_be_following: حظر الإشعارات القادمة من الحسابات التي لا تتابعها @@ -278,9 +291,18 @@ ar: pending_account: ابعث رسالة إلكترونية إن كان هناك حساب جديد بحاجة إلى مراجعة reblog: ابعث بريداً إلكترونيًا عندما يقوم أحدهم بترقية منشورك report: هناك إبلاغ جديد تم إرساله + software_updates: + all: إشعاري عند توفّر كافة التحديثات + critical: إشعاري عند توفّر التحديثات الحَرِجة فقط + label: هناك إصدار جديد متوفّر لـ Mastodon + none: عدم الإخطار أبداً بالتحديثات (غير مستحسن) + patch: إشعاري عند توفّر تحديثات التصحيح trending_tag: المتداولة الجديدة تتطلّب مراجعة rule: text: قانون + settings: + indexable: السماح لمحركات البحث بفهرسة صفحتك التعريفية + show_application: يعرض اسم التطبيق الذي استخدَمتَه لنشر المنشورات tag: listable: اسمح لهذا الوسم بالظهور في البحث وفي دليل الصفحات التعريفية name: الوسم @@ -288,6 +310,7 @@ ar: usable: اسمح للمنشورات استخدام هذا الوسم user: role: الدور + time_zone: النطاق الزمني user_role: color: لون الشارة highlighted: عرض الدور كشارة على الملفات الشخصية للمستخدمين @@ -296,9 +319,11 @@ ar: position: الأولوية webhook: events: الأحداث المفعلة + template: قالب الحمولة url: الرابط التشعبّي URL لنقطة النهاية 'no': لا not_recommended: غير مستحسن + overridden: مُتجاوَز recommended: موصى بها required: mark: "*" diff --git a/config/locales/simple_form.ast.yml b/config/locales/simple_form.ast.yml index 31501ed860..4ffc4bd166 100644 --- a/config/locales/simple_form.ast.yml +++ b/config/locales/simple_form.ast.yml @@ -3,10 +3,14 @@ ast: simple_form: hints: admin_account_action: - text_html: Opcional. Pues usar la sintaxis de los artículos ya amestar amestar preconfiguraes p'aforrar tiempu + text_html: Opcional. Pues usar la sintaxis de los artículos ya amestar alvertencies preconfiguraes p'aforrar tiempu + type_html: Escueyi qué facer con %{acct} + types: + none: Usa esta opción pa unviar una alvertencia al perfil, ensin aicionar nenguna otra aición. announcement: all_day: Al marcar la opción, namás apaecen les dates del intervalu de tiempu ends_at: Opcional. L'anunciu dexa de tar espublizáu na data qu'indiques + scheduled_at: Dexa esti campu como ta pa espublizar l'anunciu nel intre starts_at: Opcional. En casu de que l'anunciu tea arreyáu a un intervalu de tiempu específicu text: Pues usar la sintaxis de los artículos. Ten en cuenta l'espaciu que l'anunciu va ocupar na pantalla del usuariu/a defaults: @@ -14,25 +18,22 @@ ast: avatar: Ficheros PNG, GIF o JPG de %{size} como muncho. La semeya va redimensionase a %{dimensions} px bot: Avisa a otres persones de qu'esta cuenta fai principalmente aiciones automatizaes ya de que ye posible que nun tean supervisaes digest: Namás s'unvia dempués d'un periodu llongu d'inactividá ya namás si recibiesti dalgún mensaxe personal demientres la to ausencia - discoverable: Permite que persones desconocíes descubran la to cuenta pente recomendaciones, tendencies ya otres funciones - fields: Pues tener hasta 4 elementos qu'apaecen nuna tabla dientro del to perfil header: Ficheros PNG, GIF o JPG de %{size} como muncho. La semeya va redimensionase a %{dimensions} px irreversible: Los artículos peñeraos desapaecen de forma irreversible, magar que la peñera se quite dempués locale: La llingua de la interfaz, los mensaxes per corréu electrónicu ya los avisos push - locked: Controla manualmente quién pue siguite pente l'aprobación de les solicitúes de siguimientu password: Usa polo menos 8 caráuteres + setting_aggregate_reblogs: Nun amuesa los artículos compartíos nuevos que xá se compartieren de recién (namás afeuta a los artículos compartíos d'agora) + setting_always_send_emails: Los avisos nun se suelen unviar per corréu electrónicu si uses activamente Mastodon + setting_default_sensitive: El conteníu multimedia sensible anúbrese por defeutu ya pue amosase al calcar nelli setting_display_media_default: Anubrilu cuando se marque como sensible setting_display_media_hide_all: Anubrilu siempres setting_display_media_show_all: Amosalu siempres - setting_hide_network: Les persones que sigas ya les que te sigan nun van apaecer nel to perfil - setting_show_application: L'aplicación qu'uses pa espublizar apaez na vista detallada de los tos artículos - username: 'El nome d''usuariu va ser únicu en: %{domain}' + setting_use_blurhash: Los dilíos básense nos colores del conteníu multimedia anubríu mas desenfonca los detalles featured_tag: name: 'Equí tán dalgunes de les etiquetes qu''usesti apocayá:' form_admin_settings: backups_retention_period: Caltién los archivos xeneraos polos perfiles demientres el númberu de díes especificáu. closed_registrations_message: Apaez cuando'l rexistru ta desactiváu - content_cache_retention_period: Los artículos d'otros sirvidores desaníciense dempués del numberu de díes especificáu al configurar un valor positivu. Ye posible qu'esta opción seya irreversible. custom_css: Pues aplicar estilos personalizaos a la versión web de Mastodon. mascot: Anula la ilustración na interfaz web avanzada. media_cache_retention_period: Los ficheros multimedia baxaos desaníciense dempués del númberu de díes especificáu al configurar un valor positivu, ya vuelven baxase baxo demanda. @@ -40,6 +41,7 @@ ast: site_extended_description: Cualesquier tipu d'información adicional que pueda ser útil pa visitantes ya pa perfiles rexistraos. El testu pue estructurase cola sintaxis de Mastodon. site_short_description: Un descripción curtia qu'ayuda a identificar de forma única al sirvidor. ¿Quién lu lleva?, ¿pa quién ye? theme: L'estilu que los visitantes ya los perfiles nuevos usen. + trends: Les tendencies amuesen artículos, etiquetes ya noticies que tean ganando popularidá nesti sirvidor. form_challenge: current_password: Tas entrando a una área segura imports: @@ -47,8 +49,14 @@ ast: invite_request: text: Esto va ayudanos a revisar la to solicitú ip_block: - comment: Opcional. Un recordatoriu de por qué amestesti esta regla. + comment: Opcional. Un recordatoriu de por qué amestesti esta norma. expires_in: Les direiciones IP son un recursu finitu, suelen compartise ya cambiar de manes. Por esti motivu, nun s'aconseyen los bloqueos indefiníos de direiciones IP. + severities: + no_access: Bloquia l'accesu a tolos recursos + sign_up_block: Fai que nun se puedan rexistrar cuentes nueves + sign_up_requires_approval: Fai que se tengan de revisar les cuentes rexistraes nueves + user: + chosen_languages: Namás los artículos de les llingües que marques son los que van apaecer nes llinies de tiempu públiques labels: account: fields: @@ -59,8 +67,10 @@ ast: admin_account_action: include_statuses: Incluyir nel mensaxe los artículos de los que s'informó send_email_notification: Avisar al perfil per corréu electrónicu + text: Alvertencia personalizada type: Aición types: + sensitive: Marcar como cuenta sensible suspend: Suspender announcement: all_day: Eventu de tol día @@ -69,22 +79,20 @@ ast: starts_at: Comienzu del eventu text: Anunciu defaults: - avatar: Avatar - bot: Esta cuenta ye d'un robó + avatar: Semeya del perfil + bot: Esta cuenta ta automatizada chosen_languages: Peñera de llingües confirm_new_password: Confirmación de la contraseña nueva confirm_password: Confirmación de la contraseña current_password: Contraseña actual data: Datos - discoverable: Suxerir esta cuenta a otres persones display_name: Nome visible email: Direición de corréu electrónicu expires_in: Caduca dempués de - fields: Metadatos del perfil - header: Testera + fields: Campos adicionales + header: Semeya de la testera irreversible: Escartar en cuentes d'anubrir locale: Llingua de la interfaz - locked: Riquir solicitúes de siguimientu max_uses: Númberu máximu d'usos new_password: Contraseña nueva note: Biografía @@ -93,18 +101,23 @@ ast: phrase: Pallabra clave o fras setting_advanced_layout: Activar la interfaz web avanzada setting_aggregate_reblogs: Agrupar los artículos compartíos nes llinies de tiempu + setting_always_send_emails: Unviar siempres los avisos per corréu electrónicu setting_auto_play_gif: Reproducir automáticamente los GIFs setting_boost_modal: Amosar el diálogu de confirmación enantes de compartir un artículu setting_default_language: Llingua de los artículos setting_default_privacy: Privacidá de los artículos + setting_default_sensitive: Marcar siempres tol conteníu como sensible setting_delete_modal: Amosar el diálogu de confirmación enantes de desaniciar un artículu + setting_disable_swiping: Desactivar el movimientu de desplazamientu setting_display_media: Conteníu multimedia + setting_expand_spoilers: Espander siempres los artículos marcaos con alvertencies de conteníu + setting_hide_network: Anubrir les cuentes que sigas ya te sigan setting_reduce_motion: Amenorgar el movimientu de les animaciones - setting_show_application: Dicir les aplicaciones que s'usen pa unviar artículos setting_system_font_ui: Usar la fonte predeterminada del sistema setting_theme: Estilu del sitiu setting_trends: Amosar les tendencies de güei setting_unfollow_modal: Amosar el diálogu de confirmación enantes de dexar de siguir a daquién + setting_use_blurhash: Facer que'l conteníu multimedia anubríu tenga dilíos coloríos setting_use_pending_items: Mou lentu severity: Gravedá sign_in_token_attempt: Códigu de seguranza @@ -129,6 +142,9 @@ ast: site_title: Nome del sirvidor theme: Estilu predetermináu thumbnail: Miniatura del sirvidor + timeline_preview: Permitir l'accesu ensin autenticar a les llinies de tiempu públiques + trendable_by_default: Permitir tendencies ensin revisión previa + trends: Activar les tendencies interactions: must_be_follower: Bloquiar los avisos de los perfiles que nun te siguen must_be_following: Bloquiar los avisos de los perfiles que nun sigues @@ -136,7 +152,12 @@ ast: invite_request: text: "¿Por qué quies xunite?" ip_block: + comment: Comentariu ip: IP + severities: + no_access: Bloquiar l'accesu + sign_up_block: Bloquiar el rexistru de cuentes nueves + sign_up_requires_approval: Llendar les cuentes rexistraes nueves notification_emails: favourite: Daquién marcó como favoritu'l to artículu follow: Daquién te sigue @@ -146,15 +167,24 @@ ast: reblog: Daquién compartió'l to artículu report: Unvióse un informe nuevu trending_tag: Una tendencia rique una revisión + rule: + text: Norma tag: + listable: Permitir qu'esta etiqueta apaeza nes busques ya nes suxerencies name: Etiqueta + trendable: Permitir qu'esta etiqueta apaeza nes tendencies + usable: Permitir que los artículos usen esta etiqueta user: role: Rol user_role: name: Nome permissions_as_keys: Permisos position: Prioridá + webhook: + events: Eventos activos 'no': Non + not_recommended: Nun s'aconseya + recommended: Aconséyase required: mark: "*" 'yes': Sí diff --git a/config/locales/simple_form.be.yml b/config/locales/simple_form.be.yml index cdd1b34771..1ed6c80848 100644 --- a/config/locales/simple_form.be.yml +++ b/config/locales/simple_form.be.yml @@ -2,12 +2,20 @@ be: simple_form: hints: + account: + discoverable: Вашы публічныя паведамленні і профіль могуць быць паказаны або рэкамендаваны ў розных раздзелах Mastodon, і ваш профіль можа быць прапанаваны іншым карыстальнікам. + display_name: Ваша поўнае імя або ваш псеўданім. + fields: Ваша хатняя старонка, займеннікі, узрост, усё, што заўгодна. + indexable: Вашыя публічныя допісы могуць з'яўляцца ў рэзультатах пошуку Mastodon. Людзі, якія ўзаемадзейнічалі з вашымі допісамі, усё роўна маюць магчымасць іх знаходзіць. + note: 'Вы можаце @згадаць іншых людзей або выкарыстоўваць #хэштэгі.' + show_collections: Людзі змогуць праглядаць спіс вашых падпісак і падпісчыкаў. Людзі, на якіх вы падпісаны ў любым выпадку будуць бачыць, што вы іх чытаеце. + unlocked: Людзі змогуць сачыць за вамі, не запытваючы пацвярджэння. Зніміце сцяжок, калі вы хочаце праглядаць запыты на падпіску і выбіраць, прымаць ці адхіляць новых падпісчыкаў. account_alias: acct: Прызначце карыстальнік@дамен уліковага запісу з якога вы хочаце пераехаць account_migration: acct: Прызначце карыстальнік@дамен уліковага запісу на які вы хочаце пераехаць account_warning_preset: - text: Вы можаце выкарыстоўваць сінтаксіс паведамленняў, такі як URL, хэштэгі ці згадкі + text: Вы можаце выкарыстоўваць сінтаксіс паведамленняў, такі як URL, хэштэгі ці згадванні title: Неабавязкова. Не паказваецца атрымальніку admin_account_action: include_statuses: Карыстальнік пабачыць, якія допісы ёсць прычынай мадэрацыі ці папярэджання @@ -18,6 +26,8 @@ be: disable: Перадухіліць выкарыстанне акаунтаў, але не выдаляць і не хаваць іх змесціва. none: Выкарыстоўвай гэта для папярэджвання карыстальнікаў але без іншых наступстваў. sensitive: Прымусова адмячаць усе медыя карыстальніка як дэлікатныя. + silence: Забараніць карыстальніку пасты з публічнай бачнасцю, схаваць ягоныя допісы і апавяшчэнні ад людзей, якія на яго не падпісаныя. Закрывае ўсе скаргі на гэты ўліковы запіс. + suspend: Забараніць любыя ўзаемадзеянні ад ці з гэтым уліковым запісам і выдаліць ягонае змесціва. Можна адрабіць цягам 30 дзён. Закрывае ўсе скаргі на гэты ўліковы запіс. warning_preset_id: Неабавязкова. Вы можаце дадаць уласны тэкст напрыканцы шаблону announcement: all_day: Калі пазначана, будуць паказаны толькі даты з пазначанага прамежку часу @@ -35,14 +45,11 @@ be: current_password: У мэтах бяспекі, калі ласка, увядзіце пароль бягучага ўліковага запісу current_username: Каб пацвердзіць, увядзіце, калі ласка імя карыстальніка бягучага ўліковага запісу digest: Будзе даслана толькі пасля доўгага перыяду неактыўнасці і толькі калі вы атрымалі асабістыя паведамленні падчас вашай адсутнасці - discoverable: Дазволіць незнаёмым людзям знаходзіць ваш уліковы запіс праз рэкамендацыі, трэнды і іншыя функцыі email: Пацвярджэнне будзе выслана па электроннай пошце - fields: У вашаму профілі можа быць паказана да 4 элементаў у выглядзе табліцы header: PNG, GIF ці JPG. Не больш за %{size}. Будзе сціснуты да памеру %{dimensions}} пікселяў inbox_url: Капіраваць URL са старонкі рэтранслятара, якім вы хочаце карыстацца irreversible: Адфільтраваныя пасты прападуць незваротна, нават калі фільтр потым будзе выдалены locale: Мова карыстальніцкага інтэрфейсу, электронных паведамленняў і апавяшчэнняў - locked: Уручную кантралюйце, хто можа быць вашым падпісантам, ухваляючы запросы на падпіску password: Не менш за 8 сімвалаў phrase: Параўнанне адбудзецца нягледзячы на рэгістр тэксту і папярэджанні аб змесціве допісу scopes: Якімі API праграм будзе дазволена карыстацца. Калі вы абярэце найвышэйшы ўзровень, не трэба абіраць асобныя. @@ -52,12 +59,9 @@ be: setting_display_media_default: Хаваць медыя пазначаныя як далікатныя setting_display_media_hide_all: Заўсёды хаваць медыя setting_display_media_show_all: Заўсёды паказваць медыя - setting_hide_network: Вашы падпіскі і вашы падпісчыкі будуць нябачны ў вашым профілі - setting_noindex: Уплывае на бачнасць старонкі вашага профілю і вашых допісаў - setting_show_application: Праграма, праз якую вы ствараеце допісы, будзе паказвацца ў падрабязнасцях пра допісы setting_use_blurhash: Градыенты заснаваны на колерах схаваных выяў, але размываюць дэталі setting_use_pending_items: Схаваць абнаўленні стужкі за клікам замест аўтаматычнага пракручвання стужкі - username: Ваша імя карыстальніка будзе ўнікальным на %{domain} + username: Вы можаце выкарыстоўваць літары, лічбы і падкрэсліванне whole_word: Калі ключавое слова ці фраза складаецца толькі з літар і лічбаў, яно будзе ўжытае толькі калі супадае з усім словам domain_allow: domain: Гэты дамен зможа атрымліваць даныя з гэтага сервера. Даныя з гэтага дамену будуць апрацаваныя ды захаваныя @@ -72,6 +76,7 @@ be: hide: Поўнасцю схаваць адфільтраванае змесціва, дзейнічаць, нібы яго не існуе warn: Схаваць адфільтраваны кантэнт за папярэджаннем з назвай фільтру form_admin_settings: + activity_api_enabled: Падлік лакальна апублікаваных пастоў, актыўных карыстальнікаў і новых рэгістрацый у тыдзень backups_retention_period: Захоўваць створаныя архівы карыстальніка адзначаную колькасць дзён. bootstrap_timeline_accounts: Гэтыя ўліковыя запісы будуць замацаваны ў топе рэкамендацый для новых карыстальнікаў. closed_registrations_message: Паказваецца, калі рэгістрацыя закрытая @@ -79,6 +84,7 @@ be: custom_css: Вы можаце прымяняць карыстальніцкія стылі ў вэб-версіі Mastodon. mascot: Замяняе ілюстрацыю ў пашыраным вэб-інтэрфейсе. media_cache_retention_period: Спампаваныя медыя будуць выдаляцца пасля выстаўленай колькасці дзён, калі выстаўлены станоўчы лік, і спампоўвацца нанова па запыце. + peers_api_enabled: Спіс даменных імён, з якімі сутыкнуўся гэты сервер у федэсвеце. Дадзеныя аб тым, ці знаходзіцеся вы з пэўным серверам у федэрацыі, не ўключаныя, ёсць толькі тое, што ваш сервер ведае пра гэта. Гэта выкарыстоўваецца сэрвісамі, якія збіраюць статыстыку па федэрацыі ў агульным сэнсе. profile_directory: Дырэкторыя профіляў змяшчае спіс усіх карыстальнікаў, якія вырашылі быць бачнымі. require_invite_text: Калі рэгістрацыя патрабуе ручнога пацвержання, зрабіце поле "Чаму вы хочаце далучыцца?" абавязковым site_contact_email: Як людзі могуць звязацца з вамі па юрыдычных запытах або пытаннях падтрымкі. @@ -87,6 +93,7 @@ be: site_short_description: Кароткае апісанне, каб дапамагчы адназначна ідэнтыфікаваць ваш сервер. Хто яго падтрымлівае, для каго ён? site_terms: Апішыце ўласную палітыку прыватнасці альбо пакіньце поле пустым, калі хочаце скарыстацца прадвызначанай. Можна карыстацца сінтаксісам Markdown каб структураваць тэкст. site_title: Як людзі могуць звяртацца да вашага серверу акрамя яго даменнага імя. + status_page_url: URL старонкі, дзе людзі могуць бачыць стан гэтага сервера падчас збою theme: Тэма, што бачаць новыя карыстальнікі ды наведвальнікі, якія выйшлі. thumbnail: Выява памерамі прыкладна 2:1, якая паказваецца побач з інфармацыяй пра ваш сервер. timeline_preview: Наведвальнікі, якія выйшлі, змогуць праглядаць апошнія публічныя допісы на серверы. @@ -113,6 +120,9 @@ be: sessions: otp: 'Увядзіце код двухфактарнай аўтэнтыфікацыі з вашага тэлефона або адзін з кодаў аднаўлення:' webauthn: Калі гэта USB прылада, устаўце яе і, калі неабходна, націсніце на яе. + settings: + indexable: Старонка вашага профілю можа з'явіцца ў выніках пошуку ў Google, Bing і іншых. + show_application: Вы ў любым выпадку зможаце ўбачыць, якая праграма апублікавала ваш допіс. tag: name: Вы можаце змяняць толькі рэгістр літар, напрыклад для таго, каб падвысіць чытабельнасць user: @@ -126,12 +136,17 @@ be: position: Ролі вышэйшага рангу займаюцца вырашэннем канфліктаў у пэўных сітуацыях. Некаторыя дзеянні можна выкананаць толькі над ролямі з ніжэйшым рангам webhook: events: Выберыце падзеі для адпраўкі + template: Стварыце сваю ўласную карысную нагрузку JSON з дапамогай інтэрпаляцыі зменных. Пакіньце пустым для стандартнага змесціва JSON. url: Куды падзеі будуць адпраўляцца labels: account: + discoverable: Уключыць профіль і допісы ў алгарытмы рэкамендацый fields: name: Пазнака value: Змесціва + indexable: Індэксаваць публічныя допісы ў пошукавых сістэмах + show_collections: Паказаць падпіскі і падпісчыкаў у профілі + unlocked: Аўтаматычна прымаць новых падпісчыкаў account_alias: acct: Маркер старога ўліковага запісу account_migration: @@ -169,7 +184,6 @@ be: context: Фільтр кантэкстаў current_password: Бягучы пароль data: Даныя - discoverable: Рэкамендаваць уліковы запіс іншым карыстальнікам display_name: Адлюстраванае імя email: Адрас электроннай пошты expires_in: Заканчваецца пасля @@ -179,7 +193,6 @@ be: inbox_url: URL паштовай скрыні-рэтранслятара irreversible: Выдаляць, а не хаваць locale: Мова інтэрфейсу - locked: Зрабіць уліковы запіс закрытым max_uses: Максімальная колькасць выкарыстанняў new_password: Новы пароль note: Пра сябе @@ -191,7 +204,6 @@ be: setting_always_send_emails: Заўжды дасылаць для апавяшчэнні эл. пошты setting_auto_play_gif: Аўтапрайграванне анімаваных GIF setting_boost_modal: Паказваць акно пацвярджэння перад пашырэннем - setting_crop_images: У неразгорнутых допісах абразаць відарысы да 16:9 setting_default_language: Мова допісаў setting_default_privacy: Прыватнасць допісаў setting_default_sensitive: Заўсёды пазначаць кантэнт як далікатны @@ -203,9 +215,7 @@ be: setting_display_media_show_all: Паказаць усё setting_expand_spoilers: Заўжды разгортваць допісы з папярэджаннем аб змесціве setting_hide_network: Схаваць вашы сувязі - setting_noindex: Адмовіцца ад індэксавання пашуковымі рухавікамі setting_reduce_motion: Памяншэнне руху ў анімацыях - setting_show_application: Паказваць праграмы, праз якія дасылаюцца допісы setting_system_font_ui: Выкарыстоўваць прадвызначаны сістэмны шрыфт setting_theme: Тэма сайта setting_trends: Паказваць трэнды дня @@ -281,9 +291,18 @@ be: pending_account: Новы акаўнт патрабуе разгляду reblog: Нехта пашырыў ваш допіс report: Новая скарга даслана + software_updates: + all: Апавяшчаць аб усіх абнаўленнях + critical: Апавяшчаць толькі аб крытычных абнаўленнях + label: Даступная новая версія Mastodon + none: Не апавяшчаць аб абнаўленнях (не рэкамендуецца) + patch: Апавяшчаць аб абнаўленнях з выпраўленнем памылак trending_tag: Новы трэнд патрабуе разгляду rule: text: Правіла + settings: + indexable: Індэксаваць профіль у пошукавых сістэмах + show_application: Паказваць з якой праграмы было адпраўлена паведамленне tag: listable: Дазволіць паказ хэштэгу ў пошуку і ў каталозе профіляў name: Хэштэг @@ -291,6 +310,7 @@ be: usable: Дазволіць выкарыстанне хэштэгу ў допісах user: role: Роля + time_zone: Часавы пояс user_role: color: Колер значка highlighted: Паказваць ролю як значок у профілях @@ -299,9 +319,11 @@ be: position: Прыярытэт webhook: events: Актыўныя падзеі + template: Шаблон карыснай нагрузкі url: URL-адрас канцавога пункту 'no': Не not_recommended: Не рэкамендавана + overridden: Перавызначана recommended: Рэкамендуем required: mark: "*" diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml index 94f7f5b3f1..d576da71c6 100644 --- a/config/locales/simple_form.bg.yml +++ b/config/locales/simple_form.bg.yml @@ -2,6 +2,14 @@ bg: simple_form: hints: + account: + discoverable: Вашите публични публикации и профил може да се представят или препоръчват в различни области на Mastodon и вашия профил може да се предлага на други потребители. + display_name: Вашето пълно име или псевдоним. + fields: Вашата начална страница, местоимения, години, всичко що искате. + indexable: Вашите обществени публикации може да се появят в резултатите от търсене в Mastodon. Взаимодействалите с публикациите ви може да ги търсят независимо. + note: 'Може да @споменавате други хора или #хаштагове.' + show_collections: Хората ще може да разглеждат през вашите последвания и последователи. Хората, които сте следвали, ще видят, че ги следвате независимо от това. + unlocked: Хората ще може да ви следват без да се изисква одобрение. Размаркирайте, ако искате да преглеждате заявките за последване и изберете дали да приемете или отхвърлите новите последователи. account_alias: acct: Посочете потребителско_име@домейн на акаунта си, от който искате да се преместите account_migration: @@ -13,56 +21,50 @@ bg: include_statuses: Потребителят ще може да види кои публикации са довели до действието от страна на модератора или до предупреждението send_email_notification: Потребителят ще получи обяснение какво се е случило с неговия акаунт text_html: По избор. Можете да използвате синтаксисът на публикация. Можете да добавите предварително настроени предупреждения, за да спестите време - type_html: Изберете какво да сторите с %{acct} + type_html: Изберете какво ще правите с %{acct} types: - disable: Забранете на потребител да достъпва акаунта си, без да изтривате или скривате съдържанието на този акаунт. - none: Служи за изпращане на предупреждение до потребител, без да се активира друго действие. + disable: Предотвратяване на потребител да употребява акаунта си, но без да се изтрива или скрива съдържанието му. + none: Използвайте това за изпращане на предупреждение до потребител, без задействане на друго действие. sensitive: Принудително отбелязване на прикачената от потребителя мултимедия като чувствителна. - silence: Забраняване на потребителя да публикува публично, скриване на неговите публикации и известия от други потребители, които не го следват. Затваря всички доклади срещу този акаунт. - suspend: Забрана на всякаква интеракция с този акаунт и изтриване на съдържанието му. Обратимо в рамките на 30 дни. Затваря всички доклади срещу този акаунт. + silence: Предотвратяване на потребителя да може да публикува с обществена видимост, скриване на публикациите му и известията от хората, които не го следват. Затваря всички доклади срещу този акаунт. + suspend: Предотвратяване на всякакво взаимодействие от или към този акаунт и изтриване на съдържанието му. Обратимо в рамките на 30 дни. Затваря всички доклади срещу този акаунт. warning_preset_id: По избор. Можете да добавите допълнително текст накрая на предварително настроения текст announcement: all_day: Когато е избрана настройката, само датите от времевия диапазон ще бъдат показани ends_at: По избор. В зададеното време обявлението ще бъде автоматично премахнато - scheduled_at: Ако се остави празно, обявлението ще се публикува незабавно + scheduled_at: Оставете празно, за да публикувате оповестяването веднага starts_at: По избор. В случай, че обявлението е ограничено до определен времеви диапазон - text: Можете да използвате синтаксиса на обикновени публикации. Не забравяйте, че обявлението ще заеме известно място от екрана на потребителя + text: Може да употребявате синтаксиса на публикации. Имайте предвид, че оповестяването ще заема известно място от екрана на потребителя appeal: - text: Можете да възразите срещу провинение само веднъж + text: Може да възразите срещу провинение само веднъж defaults: autofollow: Хората, които се регистрират чрез поканата, автоматично ще ви последват - avatar: PNG, GIF или JPG. До %{size}. Ще бъде смалена до %{dimensions} пиксела - bot: Покажете на останалите потребители, че акаунтът извършва предимно автоматизирани действия, които не се следят + avatar: PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела + bot: Сигнализиране до другите, че акаунтът изпълнява предимно автоматизирани деяния и може да не се наблюдава context: Един или повече контексти, към които да се приложи филтърът current_password: От съображения за сигурност, въведете паролата на текущия акаунт current_username: Въведете потребителското име на текущия профил, за да потвърдите digest: Изпраща се само след дълъг период на бездействие и само ако сте получили лични съобщения във ваше отсъствие - discoverable: Позволяване на странници да откриват вашия акаунт чрез препоръки, нашумели и други неща email: Ще ви се изпрати имейл за потвърждение - fields: Може да добавите до 4 елемента в таблицата към профила си - header: PNG, GIF или JPG. До %{size}. Ще бъде смалена до %{dimensions} пиксела - inbox_url: Копирайте URL адреса на заглавната страница на предаващия сървър, който искат да използвате + header: PNG, GIF или JPG. До най-много %{size}. Ще се смали до %{dimensions} пиксела + inbox_url: Копирайте URL адреса от заглавната страница на предаващия сървър, който искате да използвате irreversible: Филтрираните публикации ще изчезнат безвъзвратно, дори филтърът да бъде премахнат по-късно locale: Езикът на потребителския интерфейс, известиятата по имейл и насочените известия - locked: Изисква ръчно одобрение на последователите. По подразбиране, публикациите са достъпни само до последователи. password: Използвайте поне 8 символа phrase: Ще съвпадне без значение дали са главни или малки букви, или ако е предупреждение към публикация scopes: Указва до кои API има достъп приложението. Ако изберете диапазон от най-високо ниво, няма нужда да избирате индивидуални. setting_aggregate_reblogs: Без показване на нови подсилвания за публикации, които са неотдавна подсилени (засяга само новополучени подсилвания) - setting_always_send_emails: Обикновено известия по имейл няма да бъдат изпратени при активно използване на Mastodon + setting_always_send_emails: Обикновено известията по имейл няма да са изпратени при дейна употреба на Mastodon setting_default_sensitive: Деликатната мултимедия е скрита по подразбиране и може да се разкрие с едно щракване setting_display_media_default: Скриване на мултимедия отбелязана като деликатна - setting_display_media_hide_all: Винаги да се скрива мултимедията - setting_display_media_show_all: Винаги да се показва мултимедията - setting_hide_network: В профила ви ще бъде скрито кой може да последвате и кой може да ви последва - setting_noindex: Засяга вашите публикации и публичен профил - setting_show_application: Приложението, което ползвате за публикуване, ще се показва в подробностите на публикацията ви - setting_use_blurhash: Преливането се определя от цветовете на скритите изображения, но детайлите остават скрити + setting_display_media_hide_all: Винаги скриване на мултимедията + setting_display_media_show_all: Винаги показване на мултимедията + setting_use_blurhash: Преливането е въз основа на цветовете на скритите визуализации, но се замъгляват подробностите setting_use_pending_items: Да се показват обновявания на часовата ос само след щракване вместо автоматично превъртане на инфоканала - username: Вашето потребителско име ще е неповторим в %{domain} - whole_word: Ако ключовата дума/фраза е стриктно буквеноцифрена, ще бъде приложена само, ако съвпадне с цялата дума + username: Може да ползвате букви, цифри и долни черти + whole_word: Ако ключовата дума или фраза е само буквеноцифрена, то ще се приложи само, ако съвпадне с цялата дума domain_allow: - domain: Този домейн ще може да извлече данни от този сървър и входящите данни от него ще бъдат обработени и запазени + domain: Домейнът ще може да извлича данни от този сървър и входящите данни от него ще се обработят и съхранят email_domain_block: domain: Това може да е името на домейна, който се съдържа в имейл адреса или MX записа, който той използва. Ще бъдат проверени при регистрация. with_dns_records: Ще има опит за преобразуване на DNS записите за дадения домейн и резултатите също ще бъдат блокирани @@ -72,39 +74,41 @@ bg: action: Изберете кое действие да се извърши, прецеждайки съвпаденията на публикацията actions: hide: Напълно скриване на филтрираното съдържание, сякаш не съществува - warn: Скриване на филтрираното съдържание зад предупреждение, включващо името на филтъра + warn: Скриване на филтрираното съдържание зад предупреждение, споменавайки заглавието на филтъра form_admin_settings: - activity_api_enabled: Брой публикувани постове, активни потребители и нови регистрации за седмицата - backups_retention_period: Запазване на генерираните потребителски архиви за посочения брой дни. + activity_api_enabled: Броят на местните публикувани публикации, дейни потребители и нови регистрации в седмични кофи + backups_retention_period: Задържане на породените потребителски архиви за определения брой дни. bootstrap_timeline_accounts: Тези акаунти ще се закачат в горния край на препоръките за следване на нови потребители. closed_registrations_message: Показва се, когато е затворено за регистрации - content_cache_retention_period: Публикации от други сървъри ще се изтрият след определен брой дни при положително число. Действието може да е необратимо. - custom_css: Може да прилагате собствени стилове в уеб версията на Mastodon. - mascot: Можете да заместите илюстрацията в разширения уеб интерфейс. - media_cache_retention_period: Свалените мултимедийни файлове ще бъдат изтрити след посочения брой дни, когато броят е положително число, и ще бъдат свалени отново при поискване. - peers_api_enabled: Списък от домейни, с който сървърът се е свързал във fediverse. Тук не се включват данни за това дали федерирате с даден сървър, а само за това дали вашият сървър знае за него. Това се ползва от услуги, които събират статистики за федерацията в общия смисъл. - profile_directory: Указателят на профили съдържа всички потребители, които са се съгласили да бъдат откривани. - require_invite_text: Когато регистрацията изисква ръчно одобрение, текстовото поле за това "Защо желаете да се присъедините?" ще бъде задължително, вместо по желание + content_cache_retention_period: Всички публикации и подсилвания от други сървъри ще се изтрият след определен брой дни. Някои публикации може да не се възстановят. Всички сродни отметки, любими и подсилвания също ще се загубят и невъзможно да се отмени. + custom_css: Може да прилагате собствени стилове в уебверсията на Mastodon. + mascot: Замества илюстрацията в разширения уеб интерфейс. + media_cache_retention_period: Изтеглените мултимедийни файлове ще се изтрият след посочения брой дни, задавайки положително число, и ще се изтеглят пак при поискване. + peers_api_enabled: Списък от имена на домейни, с които сървърът се е свързал във федивселената. Тук не се включват данни за това дали федерирате с даден сървър, а само за това дали сървърът ви знае за него. Това се ползва от услуги, събиращи статистика за федерацията в общия смисъл. + profile_directory: Указателят на профили вписва всички потребители, избрали да бъдат откриваеми. + require_invite_text: Когато регистрацията изисква ръчно одобрение, то направете текстовото поле за това "Защо желаете да се присъедините?" по-скоро задължително, отколкото по желание site_contact_email: Как могат хората да се свържат с вас относно правни запитвания или помощ. site_contact_username: Как хората могат да ви достигнат в Mastodon. site_extended_description: Всяка допълнителна информация, която може да е полезна за посетителите и потребителите ви. Може да се структурира със синтаксиса на Markdown. site_short_description: Кратък опис за помощ на неповторимата самоличност на сървъра ви. Кой го управлява, за кого е? - site_terms: Използвайте собствени правила за поверителност или оставете празно, за да използвате тези по подразбиране. Може да се структурира с Markdown синтаксис. - site_title: Как могат хората да наричат вашия сървър, освен името на домейна. - theme: Темата, която нови и невлезли потребители ще виждат. - thumbnail: Изображение в резолюция около 2:1, показвана до информацията за вашия сървър. - timeline_preview: Невлезлите потребители ще могат да преглеждат най-новите публични публикации, налични на сървъра. - trendable_by_default: Прескачане на ръчния преглед на нашумяло съдържание. Отделни елементи могат да бъдат премахвани от нашумели в последствие. - trends: В секцията Нашумели се показват публикации, хаштагове и новини, набрали популярност на вашия сървър. + site_terms: Употребявайте свои правила за поверителност или оставете празно, за да използвате стандартните правила. Може да се структурира със синтаксиса на Markdown. + site_title: Как могат хората да се обръщат към сървъра ви, освен по името на домейна. + status_page_url: Адресът на страницата, където хората могат да видят състоянието на този сървър по време на прекъсване + theme: Темата, която излизащи от системата посетители и нови потребители виждат. + thumbnail: Образ в съотношение около 2:1, показвано до информацията за сървъра ви. + timeline_preview: Излизащите от системата посетители ще може да разглеждат най-новите публични публикации, налични на сървъра. + trendable_by_default: Прескачане на ръчния преглед на изгряващо съдържание. Отделни елементи още могат да се премахват от изгряващи постфактум. + trends: В раздел „Налагащо се“ се показват публикации, хаштагове и новини, набрали популярност на сървъра ви. + trends_as_landing_page: Показване на налагащото се съдържание за излизащите потребители и посетители вместо на описа на този сървър. Изисква налагащото се да бъде включено. form_challenge: - current_password: Влизате в сигурна зона + current_password: Влизате в зона за сигурност imports: - data: CSV файл, експортиран от друга инстанция на Mastodon + data: Файлът CSV е изнесен от друг сървър на Mastodon invite_request: - text: Това ще ни помогне да разгледаме заявлението ви + text: Това ще ни помага при прегледа на заявлението ви ip_block: - comment: По избор. Помага да се сетите защо сте добавили това правило. - expires_in: IP адресите са краен ресурс. Понякога са споделени и често сменят притежателите си. Поради това, блокиране на IP за неопределен период не се препоръчва. + comment: По избор. Помнете защо сте добавили правилото. + expires_in: IP адресите са ограничен ресурс. Понякога са споделени и често сменят притежателите си. Поради това, блокиране на IP за безсрочен период не се препоръчва. ip: Въведете адреси IPv4 или IPv6. Може да блокирате цели обхвати с помощта на синтаксиса CIDR. Внимавайте да не се самозаключите! severities: no_access: Блокиране на достъп до всички ресурси @@ -116,31 +120,39 @@ bg: sessions: otp: 'Въведете двуфакторния код, породен от приложението на телефона си или използвайте един от кодовете си за възстановяване:' webauthn: Ако е USB ключ, то не забравяйте да го вмъкнете и, ако е необходимо, го натикайте. + settings: + indexable: Вашата страница на профила може да се появи в резултатите от търсене при Google, Bing, и други. + show_application: Винаги ще може да видите кое приложение е публикувало публикацията ви независимо. tag: name: Можете да смените само употребата на големи/малки букви, например, за да е по-четимо user: - chosen_languages: Само публикации на езиците с отметка ще бъдат показвани в публичните инфопотоци + chosen_languages: Само публикации на отметнатите езици ще се показват в публичните часови оси role: Ролите управляват какви права има потребителят user_role: color: Цветът, използван за ролите в потребителския интерфейс, като RGB в шестнадесетичен формат - highlighted: Това прави ролята публично видима - name: Публично име за ролята, ако ролята е настроена да се показва като значка + highlighted: Това прави ролята обществено видима + name: Публично име на ролята, ако ролята е зададена да се показва като значка permissions_as_keys: Потребители с тази роля ще имат достъп до... position: По-висшата роля може да разреши конфликти в някои ситуации. Някои действия могат да бъдат извършени само за роли с по-нисък приоритет webhook: events: Изберете събития за изпращане + template: Съставете свой полезен товар на JSON посредством променлива интерполация. Оставете празно за подразбиращ се JSON. url: До къде ще се изпращат събитията labels: account: + discoverable: Включване на профил и публикации в алгоритмите за откриване fields: name: Етикет value: Съдържание + indexable: Включете обществени публикации в резултатите от търсене + show_collections: Показване на последвания и последователи в профила + unlocked: Автоматично приемане на нови последователи account_alias: acct: Потребителско име на предишния акаунт account_migration: acct: Потребителско име на новия акаунт account_warning_preset: - text: Предварително настроен текст + text: Шаблонен текст title: Заглавие admin_account_action: include_statuses: Включване на докладваните публикации в имейла @@ -153,7 +165,7 @@ bg: sensitive: Деликатно silence: Ограничение suspend: Спиране - warning_preset_id: Употреба на преднастройка за предупреждение + warning_preset_id: Употреба на шаблонно предупреждение announcement: all_day: Целодневно събитие ends_at: Край на събитието @@ -169,10 +181,9 @@ bg: chosen_languages: Филтриране на езиците confirm_new_password: Потвърждаване на новата парола confirm_password: Потвърдете паролата - context: Филтриране на контекста + context: Прецеждане на контекста current_password: Текуща парола data: Данни - discoverable: Предложете акаунта на други display_name: Показвано име email: Адрес на имейла expires_in: Изтича след @@ -182,22 +193,20 @@ bg: inbox_url: URL адрес за входящи съобщения на предаващия сървър irreversible: Премахване, вместо скриване locale: Език на интерфейса - locked: Направи акаунта поверителен - max_uses: Максимален брой използвания + max_uses: Макс брой употреби new_password: Нова парола note: Биогр. otp_attempt: Двуфакторен код password: Парола - phrase: Ключова дума или фраза + phrase: Ключова дума или израз setting_advanced_layout: Включване на разширен уеб интерфейс setting_aggregate_reblogs: Групиране на подсилванията в часовите оси - setting_always_send_emails: Винаги изпращане на известия по имейл + setting_always_send_emails: Все да се пращат известия по имейла setting_auto_play_gif: Самопускащи се анимирани гифчета setting_boost_modal: Показване на прозорец за потвърждение преди подсилване - setting_crop_images: Изрязване на образи в неразгънати публикации до 16x9 setting_default_language: Език на публикуване setting_default_privacy: Поверителност на публикуване - setting_default_sensitive: Винаги да се отбелязва мултимедията като деликатна + setting_default_sensitive: Все да се бележи мултимедията като деликатна setting_delete_modal: Показване на прозорче за потвърждение преди изтриване на публикация setting_disable_swiping: Деактивиране на бързо плъзгащи движения setting_display_media: Показване на мултимедия @@ -205,13 +214,11 @@ bg: setting_display_media_hide_all: Скриване на всичко setting_display_media_show_all: Показване на всичко setting_expand_spoilers: Винаги разширяване на публикации, отбелязани с предупреждения за съдържание - setting_hide_network: Скриване на социалното ви графосвързване - setting_noindex: Отказване от индексирането от търсачки + setting_hide_network: Скриване на социалния ви свързан граф setting_reduce_motion: Обездвижване на анимациите - setting_show_application: Разкриване на приложението, изпращащо публикации setting_system_font_ui: Употреба на стандартния шрифт на системата setting_theme: Тема на сайта - setting_trends: Показване на днешните нашумели + setting_trends: Показване на днешното налагащо се setting_unfollow_modal: Показване на прозорче за потвърждение преди прекратяване следването на някого setting_use_blurhash: Показване на цветни преливки за скрита мултимедия setting_use_pending_items: Бавен режим @@ -231,14 +238,14 @@ bg: hide: Напълно скриване warn: Скриване зад предупреждение form_admin_settings: - activity_api_enabled: Публикуване на агрегирани статиски относно потребителската дейност в API + activity_api_enabled: Публикуване на агрегатна статистика относно потребителската дейност в API backups_retention_period: Период за съхранение на потребителския архив bootstrap_timeline_accounts: Винаги да се препоръчват следните акаунти на нови потребители - closed_registrations_message: Съобщение, показвано, когато записвания не са възможни + closed_registrations_message: Съобщение при неналична регистрация content_cache_retention_period: Период на съхранение на кеша за съдържание custom_css: Персонализиран CSS - mascot: Талисман по избор (остаряла настройка) - media_cache_retention_period: Период на запазване на мултимедията в кеш паметта + mascot: Плашило талисман по избор (остаряло) + media_cache_retention_period: Период на запазване на мултимедийния кеш peers_api_enabled: Публикуване на списъка с открити сървъри в API profile_directory: Показване на директорията от профили registrations_mode: Кой може да се регистрира @@ -251,11 +258,13 @@ bg: site_short_description: Опис на сървъра site_terms: Политика за поверителност site_title: Име на сървъра + status_page_url: URL адрес на страница със състоянието theme: Стандартна тема - thumbnail: Миниобраз на сървъра + thumbnail: Образче на сървъра timeline_preview: Позволяване на неупълномощен достъп до публични часови оси - trendable_by_default: Без преглед на нашумели + trendable_by_default: Без преглед на налагащото се trends: Включване на налагащи се + trends_as_landing_page: Употреба на налагащото се като целева страница interactions: must_be_follower: Блокирай известия от не-последователи must_be_following: Блокиране на известия от неследваните @@ -274,17 +283,26 @@ bg: severity: Правило notification_emails: appeal: Някой възразява срещу решение на модератора - digest: Изпращай извлечения на съобщенията + digest: Изпращане на обобщени е-писма favourite: Някой направи ваша публикация като любима follow: Някой ви последва follow_request: Някой пожела да ви последва mention: Някой ви спомена - pending_account: Новите акаунти трябва да се прегледат + pending_account: Новите акаунти се нуждаят от преглед reblog: Някой подсили ваша публикация report: Новият доклад е подаден + software_updates: + all: Известие за всички обновявания + critical: Известие само за критични обновявания + label: Има нова версия на Mastodon + none: Никога да не се известяват обновявания (не се препоръчва) + patch: Известие за обновявания на оправени грешки trending_tag: Изискване на преглед за новонашумели rule: text: Правило + settings: + indexable: Включване на страницата на профила в търсачките + show_application: Показвате от кое приложение сте изпратили публикация tag: listable: Позволяване на хаштага да се появява при търсене и предложения name: Хаштаг @@ -292,6 +310,7 @@ bg: usable: Позволяване на публикациите да употребяват този хаштаг user: role: Роля + time_zone: Часова зона user_role: color: Цвят на значката highlighted: Показване на ролята като значка на потребителските профили @@ -300,13 +319,15 @@ bg: position: Приоритет webhook: events: Включване на събития + template: Шаблон за полезен товар url: URL адрес на крайната точка 'no': Не - not_recommended: Не се препоръчва - recommended: Препоръчано + not_recommended: Непрепоръчително + overridden: Претоварено + recommended: Препоръчва се required: mark: "*" - text: задължително + text: изисквано title: sessions: webauthn: Употребете един от ключовете си за сигурност, за да влезете diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml index bcabca0344..12a6ac1fe8 100644 --- a/config/locales/simple_form.ca.yml +++ b/config/locales/simple_form.ca.yml @@ -2,12 +2,20 @@ ca: simple_form: hints: + account: + discoverable: El teu perfil i els teus tuts públics poden aparèixer o ser recomanats en diverses àreas de Mastodon i el teu perfil pot ser suggerit a altres usuaris. + display_name: El teu nom complet o el teu nom divertit. + fields: La teva pàgina d'inici, pronoms, edat, el que vulguis. + indexable: Els teus tuts públics poden aparèixer en els resultats de cerca de Mastodon. Les persones que han interaccionat amb el teus tuts seran sempre capaços de cercar-los. + note: 'Pots @mencionar altra gent o #etiquetes.' + show_collections: La gent podrà navegar pels teus seguits i seguidors. Qui segueixis sí que veurà que els segueixes. + unlocked: La gent serà capaç de seguir-te sense sol·licitar-ho. Desmarca si vols revisar les sol·licituds i triar si acceptes o no els nous seguidors. account_alias: acct: Especifica l'usuari@domini del compte des d'on et vols traslladar account_migration: acct: Especifica l'usuari@domini del compte al qual et vols traslladar account_warning_preset: - text: Pots usar totes les sintaxis, com ara URL, etiquetes i mencions + text: Pots usar tota mena de sintaxi, com ara URL, etiquetes i mencions title: Opcional. No és visible per al destinatari admin_account_action: include_statuses: L'usuari veurà quins tuts han causat l'acció de moderació o avís @@ -32,19 +40,16 @@ ca: defaults: autofollow: Qui es registri a través de la invitació et seguirà automàticament avatar: PNG, GIF o JPG de com a màxim %{size}. S'escalarà a %{dimensions}px - bot: Notifica que aquest compte realitza principalment accions automatitzades i que pot no estar controlat per cap persona + bot: Notifica que aquest compte realitza principalment accions automatitzades i que pot estar no monitorat context: Un o diversos contextos en què s'ha d'aplicar el filtre - current_password: Per motius de seguretat, introdueix la contrasenya del compte actual - current_username: Per a confirmar, si us plau entra el nom d'usuari del compte actual + current_password: Per motius de seguretat, introduïu la contrasenya del compte actual + current_username: Per a confirmar, entreu el nom d'usuari del compte actual digest: Només s'envia després d'un llarg període d'inactivitat i només si has rebut algun missatge personal durant la teva absència - discoverable: Permet que el teu compte sigui descobert per desconeguts a través de recomanacions, etiquetes i altres característiques email: Se t'enviarà un correu electrònic de confirmació - fields: Pots tenir fins a 4 elements que es mostren com a taula al teu perfil header: PNG, GIF o JPG de com a màxim %{size}. S'escalarà a %{dimensions}px - inbox_url: Copia l'URL de la pàgina principal del relay que vols usar + inbox_url: Copia l'enllaç de la pàgina principal del relay que vols usar irreversible: Els tuts filtrats desapareixeran de manera irreversible, fins i tot si el filtre es retira més tard locale: L'idioma de la interfície d’usuari, els correus i les notificacions push - locked: Controla manualment qui et pot seguir, aprovant sol·licituds password: Utilitza com a mínim 8 caràcters phrase: Es combinarà independentment del format en el text o l'avís de contingut del tut scopes: API permeses per a accedir a l'aplicació. Si selecciones un àmbit de nivell superior, no cal que en seleccionis un d'individual. @@ -54,17 +59,14 @@ ca: setting_display_media_default: Amaga el contingut gràfic marcat com a sensible setting_display_media_hide_all: Oculta sempre tot el contingut multimèdia setting_display_media_show_all: Mostra sempre el contingut gràfic - setting_hide_network: Qui segueixes i els que et segueixen no es mostraran en el teu perfil - setting_noindex: Afecta el teu perfil públic i les pàgines d'estat - setting_show_application: L'aplicació que fas servir per a publicar es mostrarà a la vista detallada dels teus tuts setting_use_blurhash: Els degradats es basen en els colors de les imatges ocultes, però n'enfosqueixen els detalls setting_use_pending_items: Amaga les actualitzacions de la línia de temps després de fer un clic, en lloc de desplaçar-les automàticament - username: El teu nom d'usuari serà únic a %{domain} + username: Pots emprar lletres, números i subratllats whole_word: Quan la paraula clau o la frase sigui només alfanumèrica, s'aplicarà si coincideix amb la paraula sencera domain_allow: domain: Aquest domini podrà obtenir dades d’aquest servidor i les dades entrants d’aquests seran processades i emmagatzemades email_domain_block: - domain: Aquest pot ser el nom del domini que es mostra en l'adreça de correu o el registre MX que utilitza. Es revisaran ql registrar-se. + domain: Aquest pot ser el nom de domini que es veu a l'adreça de correu o al registre MX que fa servir. Es revisaran en registrar-se. with_dns_records: Es procurarà resoldre els registres DNS del domini determinat i els resultats també es llistaran a la llista negra featured_tag: name: 'Aquí estan algunes de les etiquetes que més has usat recentment:' @@ -77,21 +79,21 @@ ca: activity_api_enabled: Contador de tuts publicats localment, usuaris actius i registres nous en períodes setmanals backups_retention_period: Manté els arxius d'usuari generats durant el nombre de dies especificats. bootstrap_timeline_accounts: Aquests comptes es fixaran en la part superior de les recomanacions de seguiment dels nous usuaris. - closed_registrations_message: Mostrat quan el registres estan tancats + closed_registrations_message: Es mostra quan el registres estan tancats content_cache_retention_period: Els tuts d'altres servidors se suprimiran després del nombre de dies especificat quan s'estableix un valor positiu. Això pot ser irreversible. custom_css: Pots aplicar estils personalitzats en la versió web de Mastodon. mascot: Anul·la la il·lustració en la interfície web avançada. media_cache_retention_period: Els fitxers multimèdia descarregats s'esborraran després del nombre de dies especificat quan el valor configurat és positiu, i tornats a descarregats sota demanda. - peers_api_enabled: Una llista de noms de domini que aquest servidor ha trobat al fedivers. No inclou cap dada sobre si estàs federat amb un servidor determinat, només si el teu en sap res. La fan servir, en un sentit general, serveis que recoŀlecten estadístiques sobre la federació. + peers_api_enabled: Una llista de noms de domini que aquest servidor ha trobat al fedivers. No inclou cap dada sobre si estàs federat amb un servidor determinat, només si el teu en sap res. La fan servir, en un sentit general, serveis que recol·lecten estadístiques sobre la federació. profile_directory: El directori de perfils llista tots els usuaris que tenen activat ser descoberts. - require_invite_text: Quan el registre requereix aprovació manual, fes que sigui obligatori en lloc d'opcional escriure el text de la sol·licitud d'invitació "Per què vols unir-te?" + require_invite_text: Quan el registre requereixi aprovació manual, fes que sigui obligatori en lloc d'opcional d'escriure el text de la sol·licitud d'invitació "Per què vols unir-te?" site_contact_email: Com pot la gent comunicar amb tu per a consultes legals o de recolzament. site_contact_username: Com pot la gent trobar-te a Mastodon. site_extended_description: Qualsevol informació addicional que pot ser útil per als visitants i els teus usuaris. Es pot estructurar amb format Markdown. site_short_description: Una descripció curta per a ajudar a identificar de manera única el teu servidor. Qui el fa anar, per a qui és? site_terms: Fes servir la teva pròpia política de privacitat o deixa-ho en blanc per a la per defecte. Es pot estructurar amb format Markdown. site_title: Com pot la gent referir-se al teu servidor a part del seu nom de domini. - status_page_url: URL de la pàgina on els usuaris poden veure l'estat d'aquest servidor durant una interrupció del servei + status_page_url: Enllaç de la pàgina on els usuaris poden veure l'estat d'aquest servidor durant una interrupció del servei theme: El tema que els visitants i els nous usuaris veuen. thumbnail: Una imatge d'aproximadament 2:1 que es mostra al costat la informació del teu servidor. timeline_preview: Els visitants amb sessió no iniciada seran capaços de navegar per els tuts més recents en el teu servidor. @@ -110,7 +112,7 @@ ca: ip: Introdueix una adreça IPv4 o IPv6. Pots bloquejar rangs complets amb la sintaxi CIDR. Ves a compte no et bloquegis a tu mateix! severities: no_access: Bloqueja l’accés a tots els recursos - sign_up_block: Els nous registres no seran possibles + sign_up_block: No seran possibles nous registres sign_up_requires_approval: Els nous registres requeriran la teva aprovació severity: Tria què passarà amb les sol·licituds des d’aquesta IP rule: @@ -118,6 +120,9 @@ ca: sessions: otp: 'Introdueix el codi de dos factors generat per el teu telèfon o utilitza un dels teus codis de recuperació:' webauthn: Si és una clau USB, assegura't que està inserida i, si cal, toca-la. + settings: + indexable: La pàgina del teu perfil podria aparèixer en els resultats de cerca de Google, Bing i altres. + show_application: Sempre podràs veure quina aplicació ha publicat els teus tuts. tag: name: Només pots canviar la caixa de les lletres, per exemple, per fer-la més llegible user: @@ -131,12 +136,17 @@ ca: position: El rol superior decideix la resolució de conflictes en certes situacions. Certes accions només es poden realitzar amb rols amb menor prioritat webhook: events: Selecciona esdeveniments a enviar + template: Crea el teu propi JSON fent servir interpolació variable. Buit per al JSON per defecte. url: On els esdeveniments seran enviats labels: account: + discoverable: Permet el perfil i el tuts en els algorismes de descobriment fields: name: Etiqueta value: Contingut + indexable: Inclou tuts públics en els resultats de cerca + show_collections: Mostra seguits i seguidors en el perfil + unlocked: Accepta automàticament els nous seguidors account_alias: acct: Nom del compte vell account_migration: @@ -174,17 +184,15 @@ ca: context: Filtre els contextos current_password: Contrasenya actual data: Informació - discoverable: Mostra aquest compte en el directori de perfils display_name: Nom visible email: Adreça de correu electrònic expires_in: Expira després fields: Metadades del perfil header: Capçalera honeypot: "%{label} (no omplir)" - inbox_url: URL de la safata d'entrada del relay + inbox_url: Enllaç de la safata d'entrada del relay irreversible: Cau en lloc d'ocultar locale: Idioma de la interfície - locked: Requereix sol·licituds de seguiment max_uses: Nombre màxim d'usos new_password: Contrasenya nova note: Biografia @@ -196,7 +204,6 @@ ca: setting_always_send_emails: Envia'm sempre notificacions per correu electrònic setting_auto_play_gif: Reprodueix automàticament els GIF animats setting_boost_modal: Mostra la finestra de confirmació abans d'impulsar - setting_crop_images: Retalla les imatges en tuts no ampliats a 16x9 setting_default_language: Llengua dels tuts setting_default_privacy: Privacitat dels tuts setting_default_sensitive: Marcar sempre el contingut gràfic com a sensible @@ -208,9 +215,7 @@ ca: setting_display_media_show_all: Mostra-ho tot setting_expand_spoilers: Desplega sempre els tuts marcats amb advertències de contingut setting_hide_network: Amaga la teva xarxa - setting_noindex: Desactiva la indexació dels motors de cerca setting_reduce_motion: Redueix el moviment de les animacions - setting_show_application: Revela l'aplicació utilitzada per enviar tuts setting_system_font_ui: Usa la lletra predeterminada del sistema setting_theme: Tema del lloc setting_trends: Mostra les tendències d'avui @@ -236,7 +241,7 @@ ca: activity_api_enabled: Publica a l'API estadístiques agregades sobre l'activitat dels usuaris backups_retention_period: Període de retenció del arxiu d'usuari bootstrap_timeline_accounts: Recomana sempre aquests comptes als nous usuaris - closed_registrations_message: Missatge personalitzat quan el registre està tancat + closed_registrations_message: Missatge personalitzat quan el registre no és accessible content_cache_retention_period: Període de retenció de la memòria cau de contingut custom_css: CSS personalitzat mascot: Mascota personalitzada (llegat) @@ -253,7 +258,7 @@ ca: site_short_description: Descripció del servidor site_terms: Política de Privacitat site_title: Nom del servidor - status_page_url: URL de la pàgina de l'estat + status_page_url: Enllaç de la pàgina d'estat theme: Tema per defecte thumbnail: Miniatura del servidor timeline_preview: Permet l'accés no autenticat a les línies de temps públiques @@ -263,7 +268,7 @@ ca: interactions: must_be_follower: Bloqueja les notificacions de persones que no em segueixen must_be_following: Bloqueja les notificacions de persones no seguides - must_be_following_dm: Blocar els missatges directes de persones que no segueixes + must_be_following_dm: Bloqueja les mencions privades de persones que no segueixes invite: comment: Comenta invite_request: @@ -286,9 +291,18 @@ ca: pending_account: Un nou compte necessita revisió reblog: Algú comparteix el teu estat report: S'ha enviat l'informe nou + software_updates: + all: Notificar sobre totes les actualitzacions + critical: Notificar només actualitzacions crítiques + label: Hi ha disponible una nova versió de Mastodon + none: No notifiquis mai les actualitzacions (no és recomanable) + patch: Notificar sobre les actualitzacions de correcció d'errors trending_tag: Nova tendència requereix revisió rule: text: Norma + settings: + indexable: Inclou la pàgina del perfil en els motors de cerca + show_application: Mostra amb quina aplicació has enviat el tut tag: listable: Permet que aquesta etiqueta aparegui en les cerques i en el directori de perfils name: Etiqueta @@ -296,6 +310,7 @@ ca: usable: Permet als tuts emprar aquesta etiqueta user: role: Rol + time_zone: Zona horària user_role: color: Color de la insígnia highlighted: Mostra el rol com a insígnia en el perfil dels usuaris @@ -304,9 +319,11 @@ ca: position: Prioritat webhook: events: Esdeveniments activats - url: URL de l'extrem + template: Plantilla de càrrega + url: Enllaç de l'extrem 'no': 'No' not_recommended: No recomanat + overridden: Anul·lat recommended: Recomanat required: mark: "*" diff --git a/config/locales/simple_form.ckb.yml b/config/locales/simple_form.ckb.yml index 9ce9ac0655..a6110e2034 100644 --- a/config/locales/simple_form.ckb.yml +++ b/config/locales/simple_form.ckb.yml @@ -32,12 +32,10 @@ ckb: current_username: بۆ دڵنیابوون، تکایە ناوی بەکارهێنەری ئەم هەژمارەیە بنووسە digest: تەنیا دوای ماوەیەکی زۆر لە بێ چالاکیدەنێردرێت و تەنیا ئەگەر نامەیەکی کەسیت بۆ نووسرابێت email: ئیمەیڵێکی پشتڕاستکردنەوەت بۆ دەنێردرێت - fields: دەتوانیت تا ٤بڕگەت هەبێت کە وەک خشتەیەک لەسەر پرۆفایلەکەت پیشان بدرێت header: PNG, GIF یان JPG. لە زۆربەی %{size}. دەبێتە ئەندازەیەکی کەمکراوە بۆ %{dimensions}پیکسێڵ inbox_url: نیشانەی پەڕەی سەرەکی ئەو رێڵە کە هەرەکتە بەکاریببەیت ڕوونووس دەکات irreversible: توتە فلتەرکراوەکە بە شێوەیەکی نەگەڕاو فرەدەدرێن، تەنانەت ئەگەر فلتەردواتر لاببرێت locale: زمانی ڕووکاری بەکارهێنەر، ئیمەیلەکان و ئاگانامەکان - locked: خۆت بڕیار بدە کێ دەتوانێت شوێنت بکەوێت بە وەرگتنی داوای شوێنکەوتن password: لایەنی کەم 8 نووسە بەکار بهێنە phrase: سەربەخۆ لە بچکۆلی و گەورەیی پیتەکان، لەگەڵ دەقی ئەسڵی یان ئاگانامەکانی ناوەرۆکی توتەکان هاوئاهەنگ دەکرێت scopes: APIـیەکانی بەرنامەنووسی کە ئەم ماڵپەڕە دەستپێگەیشتنی لەگەڵیان هیە. ئەگەر بەرزترین ئاست هەڵبژێرن ئیتر نیاز بە بژاردەی ئاستی نزم نییە. @@ -46,12 +44,8 @@ ckb: setting_display_media_default: ئەو میدیایانە بشارەوە کە هەستیارن setting_display_media_hide_all: هەمیشە میدیا بشارەوە setting_display_media_show_all: هەمیشە میدیا نیشان بدە - setting_hide_network: شوێنکەوتوو و شوێنکەوتنەکانت لە پرۆفایلەکەت نیشان نادرێن - setting_noindex: کاردەکاتە سەر پرۆفایل و لاپەڕە گشتیەکانت - setting_show_application: بەرنامەیەک کە بە یارمەتیت توت دەکەیت، لە دیمەنی وردی توتەکان پیشان دەدرێت setting_use_blurhash: سێبەرەکان لە سەر بنەمای ڕەنگەکانی بەکارهاتوو لە وێنە داشاراوەکان دروست دەبن بەڵام وردەزانیاری وێنە تێیدا ڕوون نییە setting_use_pending_items: لەجیاتی ئەوەی بە خۆکارانە کێشان هەبێت لە نووسراوەکان بە کرتەیەک بەڕۆژبوونی پێرستی نووسراوەکان بشارەوە - username: ناوی بەکارهێنەری ئێوە لەسەر %{domain} یەکتا دەبێت whole_word: کاتێک کلیل‌وشە بریتییە لە ژمارە و پیت، تنەها کاتێک پەیدا دەبێت کە لەگەڵ گشتی وشە لە نێو دەقەکە هاوئاهەنگ بێت، نە تەنها لەگەڵ بەشێک لە وشە domain_allow: domain: ئەم دۆمەینە دەتوانێت دراوە لە ئەم ڕاژە وەربگرێت و دراوەی ئەم دۆمەینە لێرە ڕێکدەخرین و پاشکەوت دەکرێن @@ -118,7 +112,6 @@ ckb: context: چوارچێوەی پاڵافتن current_password: تێپەروشەی ئێستا data: دراوه - discoverable: ئەم هەژمێرە لە پێرستی بژاردەی بەکارهێنەران نیشان بدە display_name: ناوی پیشاندان email: ناونیشانی ئیمەیڵ expires_in: بەسەردەچێت پاش @@ -127,7 +120,6 @@ ckb: inbox_url: بەستەری سندوقی گواستنەوەی irreversible: فرێدان لەجیاتی شاردنەوە locale: زمانی پەڕەی بەکارهێنەر - locked: داخستنی هەژمارە max_uses: زۆرترین ژمارەی بەکاربەرەکان new_password: تێپەروشەی نوێ note: دەربارەی ئیوە @@ -138,7 +130,6 @@ ckb: setting_aggregate_reblogs: گرووپی توتەکان یەکبخە setting_auto_play_gif: خۆکاربەخشکردنی GIFــەکان setting_boost_modal: پیشاندانی دیالۆگی دووپاتکردنەوە پێش دوبارە توتاندن - setting_crop_images: لە تووتی نەکراوە،وینەکان لە ئەندازی ۱٦×۹ ببڕە setting_default_language: زمانی نووسراوەکانتان setting_default_privacy: چوارچێوەی تایبەتێتی ئێوە setting_default_sensitive: هەمیشە نیشانکردنی میدیا وەک هەستیار @@ -150,9 +141,7 @@ ckb: setting_display_media_show_all: هەموو نیشان بدە setting_expand_spoilers: هەمیشە ئەو توتانەی کە بە ئاگادارکردنەوەکانی ناوەڕۆکەوە نیشانەکراون، پیسان بدە setting_hide_network: شاردنەوەی تۆڕەکەت - setting_noindex: داوا لە مەکینەی گەڕان بۆ پیشاننەدان لە دەئەنجامی گەڕانەکان setting_reduce_motion: کەمکردنەوەی جوڵە لە ئەنیمەکان - setting_show_application: ئاشکراکردنی ئەپەکان بۆ ناردنی توتەکان setting_system_font_ui: فۆنتی بنەڕەتی سیستەم بەکاربهێنە setting_theme: ڕووکاری ماڵپەڕ setting_trends: پیشاندانی نووسراوە بەرچاوکراوەی ئەمڕۆ diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml index 79e5837d4b..fd6f595e91 100644 --- a/config/locales/simple_form.co.yml +++ b/config/locales/simple_form.co.yml @@ -30,12 +30,10 @@ co: current_username: Per cunfirmà, entrate u cugnome di questu contu digest: Solu mandatu dopu à una longa perioda d’inattività, è solu s’elli ci sò novi missaghji diretti email: Avete da riceve un'e-mail di cunfirmazione - fields: Pudete avè fin’à 4 elementi mustrati cum’un tavulone nant’à u vostru prufile header: Furmatu PNG, GIF o JPG. %{size} o menu. Sarà ridottu à %{dimensions}px inbox_url: Cupiate l'URL di a pagina d'accolta di u ripetitore chì vulete utilizà irreversible: I statuti filtrati saranu sguassati di manera irreversibile, ancu s'ellu hè toltu u filtru locale: A lingua di l'interfaccia utilizatore, di l'e-mail è di e nutificazione push - locked: Duvarete appruvà e dumande d’abbunamentu password: Ci volenu almenu 8 caratteri phrase: Sarà trovu senza primura di e maiuscule o di l'avertimenti scopes: L'API à quelle l'applicazione averà accessu. S'è voi selezziunate un parametru d'altu livellu, un c'hè micca bisognu di selezziunà quell'individuali. @@ -44,12 +42,8 @@ co: setting_display_media_default: Piattà i media marcati cum'è sensibili setting_display_media_hide_all: Sempre piattà tutti i media setting_display_media_show_all: Sempre affissà i media marcati cum'è sensibili - setting_hide_network: I vostri abbunati è abbunamenti ùn saranu micca mustrati nant’à u vostru prufile - setting_noindex: Tocca à u vostru prufile pubblicu è i vostri statuti - setting_show_application: L'applicazione chì voi utilizate per mandà statuti sarà affissata indè a vista ditagliata di quelli setting_use_blurhash: I digradati blurhash sò basati nant'à i culori di u ritrattu piattatu ma senza i ditagli setting_use_pending_items: Clicchi per messe à ghjornu i statuti invece di fà sfilà a linea autumaticamente - username: U vostru cugnome sarà unicu nant'à %{domain} whole_word: Quandu a parolla o a frasa sana hè alfanumerica, sarà applicata solu s'ella currisponde à a parolla sana domain_allow: domain: Stu duminiu puderà ricuperà i dati di stu servore è i dati ch'affaccanu da quallà saranu trattati è cunservati @@ -118,7 +112,6 @@ co: context: Cuntesti di u filtru current_password: Chjave d’accessu attuale data: Dati - discoverable: Arregistrà stu contu indè l'annuariu display_name: Nome pubblicu email: Indirizzu e-mail expires_in: Spira dopu à @@ -128,7 +121,6 @@ co: inbox_url: URL di l'inbox di u ripetitore irreversible: Sguassà invece di piattà locale: Lingua di l'interfaccia - locked: Privatizà u contu max_uses: Numeru massimale d’utilizazione new_password: Nova chjave d’accessu note: Descrizzione @@ -139,7 +131,6 @@ co: setting_aggregate_reblogs: Gruppà e spartere indè e linee setting_auto_play_gif: Lettura autumatica di i GIF animati setting_boost_modal: Mustrà una cunfirmazione per sparte un statutu - setting_crop_images: Riquatrà i ritratti in 16x9 indè i statuti micca selezziunati setting_default_language: Lingua di pubblicazione setting_default_privacy: Cunfidenzialità di i statuti setting_default_sensitive: Sempre cunsiderà media cum’è sensibili @@ -151,9 +142,7 @@ co: setting_display_media_show_all: Affissà tuttu setting_expand_spoilers: Sempre slibrà i statutu marcati cù un'avertimentu CW setting_hide_network: Piattà a vostra rete - setting_noindex: Dumandà à i motori di ricerca internet d’un pudè micca esse truvatu·a cusì setting_reduce_motion: Fà chì l’animazione vanu più pianu - setting_show_application: Indicà u nome di l'applicazione utilizata per mandà statuti setting_system_font_ui: Pulizza di caratteri di u sistemu setting_theme: Tema di u situ setting_trends: Vede e tendenze per oghji diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml index 7025c63856..dff9378098 100644 --- a/config/locales/simple_form.cs.yml +++ b/config/locales/simple_form.cs.yml @@ -2,6 +2,10 @@ cs: simple_form: hints: + account: + display_name: Vaše celé jméno nebo přezdívka. + fields: Vaše domovská stránka, zájmena, věk, cokoliv chcete. + note: 'Můžete @zmínit jiné osoby nebo #hashtagy.' account_alias: acct: Zadejte svůj účet, ze kterého se chcete přesunout jinam, ve formátu přezdívka@doména account_migration: @@ -37,14 +41,11 @@ cs: current_password: Z bezpečnostních důvodů prosím zadejte heslo současného účtu current_username: Potvrďte prosím tuto akci zadáním uživatelského jména aktuálního účtu digest: Odesíláno pouze po dlouhé době nečinnosti a pouze, pokud jste během své nepřítomnosti obdrželi osobní zprávy - discoverable: Umožnit, aby mohli váš účet objevit neznámí lidé pomocí doporučení, trendů a dalších funkcí email: Bude vám poslán potvrzovací e-mail - fields: Na svém profilu můžete mít zobrazeny až 4 položky jako tabulku header: PNG, GIF či JPG. Maximálně %{size}. Bude zmenšen na %{dimensions} px inbox_url: Zkopírujte URL z hlavní stránky mostu, který chcete použít irreversible: Filtrované příspěvky nenávratně zmizí, i pokud bude filtr později odstraněn locale: Jazyk uživatelského rozhraní, e-mailů a push notifikací - locked: Kontrolujte, kdo vás může sledovat pomocí schvalování žádostí o sledování password: Použijte alespoň 8 znaků phrase: Shoda bude nalezena bez ohledu na velikost písmen v textu příspěvku či varování o obsahu scopes: Která API bude aplikace moct používat. Pokud vyberete rozsah nejvyššího stupně, nebudete je muset vybírat jednotlivě. @@ -54,12 +55,9 @@ cs: setting_display_media_default: Skrývat média označená jako citlivá setting_display_media_hide_all: Vždy skrývat média setting_display_media_show_all: Vždy zobrazovat média - setting_hide_network: Koho sledujete a kdo sleduje vás bude na vašem profilu skryto - setting_noindex: Ovlivňuje váš veřejný profil a stránky příspěvků - setting_show_application: Aplikace, kterou používáte k odeslání příspěvků, bude zobrazena jejich detailním zobrazení setting_use_blurhash: Gradienty jsou založeny na barvách skryté grafiky, ale zakrývají jakékoliv detaily setting_use_pending_items: Aktualizovat časovou osu až po kliknutí namísto automatického rolování kanálu - username: Vaše uživatelské jméno bude na serveru %{domain} unikátní + username: Pouze písmena, číslice a podtržítka whole_word: Je-li klíčové slovo či fráze pouze alfanumerická, bude aplikován pouze, pokud se shoduje s celým slovem domain_allow: domain: Tato doména bude moci stahovat data z tohoto serveru a příchozí data z ní budou zpracována a uložena @@ -131,6 +129,7 @@ cs: position: Vyšší role rozhoduje o řešení konfliktů v určitých situacích. Některé akce lze provádět pouze na rolích s nižší prioritou webhook: events: Zvolte odesílané události + template: Sestavte si vlastní JSON payload pomocí interpolace proměnných. Pro výchozí JSON ponechte prázdné. url: Kam budou události odesílány labels: account: @@ -174,7 +173,6 @@ cs: context: Kontexty filtrů current_password: Současné heslo data: Data - discoverable: Navrhovat účet ostatním display_name: Zobrazované jméno email: E-mailová adresa expires_in: Vypršet za @@ -184,7 +182,6 @@ cs: inbox_url: URL příchozí schránky mostu irreversible: Zahodit místo skrytí locale: Jazyk rozhraní - locked: Vynutit žádosti o sledování max_uses: Maximální počet použití new_password: Nové heslo note: O vás @@ -196,7 +193,6 @@ cs: setting_always_send_emails: Vždy posílat e-mailová oznámení setting_auto_play_gif: Automaticky přehrávat animace GIF setting_boost_modal: Před boostnutím zobrazovat potvrzovací okno - setting_crop_images: Ořezávat obrázky v nerozbalených příspěvcích na 16x9 setting_default_language: Jazyk příspěvků setting_default_privacy: Soukromí příspěvků setting_default_sensitive: Vždy označovat média jako citlivá @@ -208,9 +204,7 @@ cs: setting_display_media_show_all: Zobrazit vše setting_expand_spoilers: Vždy rozbalit příspěvky označené varováními o obsahu setting_hide_network: Skrýt mou síť - setting_noindex: Neindexovat svůj profil vyhledávači setting_reduce_motion: Omezit pohyb v animacích - setting_show_application: Odhalit aplikaci použitou k odeslání příspěvků setting_system_font_ui: Použít výchozí písmo systému setting_theme: Vzhled stránky setting_trends: Zobrazit dnešní trendy @@ -296,6 +290,7 @@ cs: usable: Povolit používat tento hashtag v příspěvcích user: role: Role + time_zone: Časové pásmo user_role: color: Barva odznaku highlighted: Zobrazit roli jako odznak na profilech uživatelů @@ -304,6 +299,7 @@ cs: position: Priorita webhook: events: Zapnuté události + template: Šablona payloadu url: URL koncového bodu 'no': Ne not_recommended: Nedoporučuje se diff --git a/config/locales/simple_form.csb.yml b/config/locales/simple_form.csb.yml deleted file mode 100644 index 0de706e41f..0000000000 --- a/config/locales/simple_form.csb.yml +++ /dev/null @@ -1 +0,0 @@ -csb: diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml index c51fda6613..ddc1b1b935 100644 --- a/config/locales/simple_form.cy.yml +++ b/config/locales/simple_form.cy.yml @@ -2,6 +2,14 @@ cy: simple_form: hints: + account: + discoverable: Mae'n bosibl y bydd eich postiadau cyhoeddus a'ch proffil yn cael sylw neu'n cael eu hargymell mewn gwahanol feysydd o Mastodon ac efallai y bydd eich proffil yn cael ei awgrymu i ddefnyddwyr eraill. + display_name: Eich enw llawn neu'ch enw hwyl. + fields: Eich tudalen cartref, rhagenwau, oed, neu unrhyw beth. + indexable: Mae'n bosib y bydd eich postiadau cyhoeddus yn ymddangos yng nghanlyniadau chwilio ar Mastodon. Mae'n bosibl y bydd pobl sydd wedi rhyngweithio â'ch postiadau yn dal i allu eu chwilio. + note: 'Gallwch @grybwyll pobl eraill neu #hashnodau.' + show_collections: Bydd pobl yn gallu pori trwy'r rhai rydych yn eu dilyn a'ch dilynwyr. Bydd y bobl rydych chi'n eu dilyn yn gweld eich bod chi'n eu dilyn beth bynnag. + unlocked: Bydd pobl yn gallu eich dilyn heb ofyn am ganiatâd. Dad-diciwch os ydych am adolygu ceisiadau dilyn a dewis a ydych am dderbyn neu wrthod dilynwyr newydd. account_alias: acct: Rhowch enwdefnyddiwr@parth y cyfrif y hoffech chi symud ohono account_migration: @@ -37,14 +45,11 @@ cy: current_password: At ddibenion diogelwch, nodwch gyfrinair y cyfrif cyfredol current_username: I gadarnhau, nodwch enw defnyddiwr y cyfrif cyfredol digest: Ond yn cael eu hanfon ar ôl cyfnod hir o anweithgarwch ac ond os ydych wedi derbyn unrhyw negeseuon personol yn eich absenoldeb - discoverable: Caniatáu i'ch cyfrif gael ei ddarganfod gan ddieithriaid trwy argymhellion, pynciau llosg a nodweddion eraill email: Byddwch yn derbyn e-bost cadarnhau - fields: Mae modd i chi ddangos hyd at 4 eitem fel tabl ar eich proffil header: PNG, GIF neu JPG. %{size} ar y mwyaf. Bydd yn cael ei israddio i %{dimensions}px inbox_url: Copïwch yr URL o dudalen flaen y relái yr ydych am ei ddefnyddio irreversible: Bydd postiadau wedi'u hidlo'n diflannu'n ddiwrthdro, hyd yn oed os caiff yr hidlydd ei dynnu'n ddiweddarach locale: Iaith y rhyngwyneb, e-byst a hysbysiadau gwthiadwy - locked: Mae hyn yn eich galluogi i reoli pwy sy'n gallu eich dilyn drwy gymeradwyo ceisiadau dilyn password: Defnyddiwch o leiaf 8 nod phrase: Caiff ei gyfateb heb ystyriaeth o briflythrennu mewn testun neu rhybudd ynghylch cynnwys postiad scopes: Pa APIs y bydd y rhaglen yn cael mynediad iddynt. Os dewiswch gwmpas lefel uchaf, nid oes angen i chi ddewis rhai unigol. @@ -54,12 +59,9 @@ cy: setting_display_media_default: Cuddio cyfryngau wedi eu marcio'n sensitif setting_display_media_hide_all: Cuddio cyfryngau bob tro setting_display_media_show_all: Dangos cyfryngau bob tro - setting_hide_network: Ni fydd y pobl yr ydych chi'n eu dilyn a'ch dilynwyr yn ymddangos ar eich proffil - setting_noindex: Mae hyn yn effeithio ar eich proffil cyhoeddus a'ch tudalennau statws - setting_show_application: Bydd y cymhwysiad a ddefnyddiwch i bostio yn cael ei arddangos yng ngolwg fanwl eich postiadau setting_use_blurhash: Mae graddiannau wedi'u seilio ar liwiau'r delweddau cudd ond maen nhw'n cuddio unrhyw fanylion setting_use_pending_items: Cuddio diweddariadau llinell amser y tu ôl i glic yn lle sgrolio'n awtomatig - username: Bydd eich enw defnyddiwr yn unigryw ar %{domain} + username: Gallwch ddefnyddio nodau, rhifau a thanlinellau whole_word: Os yw'r allweddair neu'r ymadrodd yn alffaniwmerig yn unig, mi fydd ond yn cael ei osod os yw'n cyfateb a'r gair cyfan domain_allow: domain: Bydd y parth hwn yn gallu nôl data o'r gweinydd hwn a bydd data sy'n dod i mewn ohono yn cael ei brosesu a'i storio @@ -118,6 +120,9 @@ cy: sessions: otp: 'Mewnbynnwch y cod dau gam a gynhyrchwyd gan eich ap ffôn neu defnyddiwch un o''ch codau adfer:' webauthn: Os mai allwedd USB ydyw, gwnewch yn siŵr ei fewnosod ac, os oes angen, tapiwch ef. + settings: + indexable: Mae'n bosib y bydd eich tudalen broffil yn ymddangos mewn canlyniadau chwilio ar Google, Bing ac eraill. + show_application: Byddwch bob amser yn gallu gweld pa ap a gyhoeddodd eich postiad beth bynnag. tag: name: Dim ond er mwyn ei gwneud yn fwy darllenadwy y gallwch chi newid y llythrennau, er enghraifft user: @@ -131,12 +136,17 @@ cy: position: Mae rôl uwch yn penderfynu ar ddatrys gwrthdrawiadau mewn rhai sefyllfaoedd. Dim ond ar rolau â blaenoriaeth is y gellir cyflawni rhai gweithredoedd webhook: events: Dewiswch ddigwyddiadau i'w hanfon + template: Cyfansoddwch eich llwyth tâl JSON eich hun gan ddefnyddio rhyngosod newidiol. Gadewch yn wag ar gyfer JSON rhagosodedig. url: I ble bydd digwyddiadau'n cael eu hanfon labels: account: + discoverable: Proffil nodwedd a phostiadau mewn algorithmau darganfod fields: name: Label value: Cynnwys + indexable: Cynnwys postiadau cyhoeddus mewn canlyniadau chwilio + show_collections: Dangos y rhaid rydych yn eu dilyn a'ch dilynwyr ar eich proffil + unlocked: Derbyn dilynwyr newydd yn awtomatig account_alias: acct: Enw'r hen gyfrif account_migration: @@ -174,7 +184,6 @@ cy: context: Hidlo cyd-destunau current_password: Cyfrinair cyfredol data: Data - discoverable: Awgrymu cyfrif i eraill display_name: Enw dangos email: Cyfeiriad e-bost expires_in: Yn dod i ben ar ôl @@ -184,7 +193,6 @@ cy: inbox_url: URL y mewnflwch relái irreversible: Gollwng yn hytrach na chuddio locale: Iaith y rhyngwyneb - locked: Angen ceisiadau dilyn max_uses: Nifer y ddefnyddiau uchafswm new_password: Cyfrinair newydd note: Bywgraffiad @@ -196,7 +204,6 @@ cy: setting_always_send_emails: Anfonwch hysbysiadau e-bost bob amser setting_auto_play_gif: Chwarae GIFs wedi'u hanimeiddio yn awtomatig setting_boost_modal: Dangos deialog cadarnhau cyn rhoi hwb - setting_crop_images: Tocio delweddau o fewn postiadau nad ydynt wedi'u hehangu i 16x9 setting_default_language: Iaith postio setting_default_privacy: Preifatrwydd cyhoeddi setting_default_sensitive: Marcio cyfryngau fel eu bod yn sensitif bob tro @@ -208,9 +215,7 @@ cy: setting_display_media_show_all: Dangos popeth setting_expand_spoilers: Dangos postiadau wedi'u marcio â rhybudd cynnwys bob tro setting_hide_network: Cuddio eich graff cymdeithasol - setting_noindex: Peidio mynegeio peiriannau chwilio setting_reduce_motion: Lleihau mudiant mewn animeiddiadau - setting_show_application: Datgelu rhaglen a ddefnyddir i anfon postiadau setting_system_font_ui: Defnyddio ffont rhagosodedig y system setting_theme: Thema'r wefan setting_trends: Dangos pynciau llosg heddiw @@ -255,7 +260,7 @@ cy: site_title: Enw'r gweinydd status_page_url: URL tudalen statws theme: Thema ragosodedig - thumbnail: Lluniau bach gweinydd + thumbnail: Bawdlun y gweinydd timeline_preview: Caniatáu mynediad heb ei ddilysu i linellau amser cyhoeddus trendable_by_default: Caniatáu pynciau llosg heb adolygiad trends: Galluogi pynciau llosg @@ -279,16 +284,25 @@ cy: notification_emails: appeal: Mae rhywun yn apelio yn erbyn penderfyniad y cymedrolwr digest: Anfonwch e-byst crynhoi - favourite: Mae rhywun wedi ffafrio eich post + favourite: Mae rhywun wedi ffafrio eich postiad follow: Mae rhywun yn eich dilyn chi follow_request: Mae rhywun yn ceisio eich dilyn chi mention: Mae rhywun yn sôn amdanoch chi pending_account: Mae cyfrif newydd angen adolygiad - reblog: Mae rhywun wedi hybu eich post + reblog: Mae rhywun wedi hybu eich postiad report: Cyflwynwyd adroddiad newydd + software_updates: + all: Rhoi gwybod am bob ddiweddariad + critical: Rhoi gwybod am ddiweddariadau critigol yn unig + label: Mae fersiwn Mastodon newydd ar gael + none: Byth rhoi gwybod am ddiweddariadau (nid argymhellir) + patch: Rhoi gwybod am ddiweddariadau trwsio byg trending_tag: Mae pwnc llosg newydd angen adolygiad rule: text: Rheol + settings: + indexable: Cynnwys tudalen proffil mewn peiriannau chwilio + show_application: Dangoswch o ba ap yr anfonoch chi bostiad tag: listable: Caniatáu i'r hashnod hwn ymddangos mewn chwiliadau ac awgrymiadau name: Hashnod @@ -296,6 +310,7 @@ cy: usable: Caniatáu i bostiadau ddefnyddio'r hashnod hwn user: role: Rôl + time_zone: Cylchfa amser user_role: color: Lliw bathodyn highlighted: Dangos rôl fel bathodyn ar broffiliau defnyddwyr @@ -304,9 +319,11 @@ cy: position: Blaenoriaeth webhook: events: Digwyddiadau wedi'u galluogi + template: Templed prif lwyth url: URL diweddbwynt 'no': Na not_recommended: Heb ei argymell + overridden: Wedi'i gwrth-wneud recommended: Argymhellwyd required: mark: "*" diff --git a/config/locales/simple_form.da.yml b/config/locales/simple_form.da.yml index 3116f02d81..0d86b2bc8d 100644 --- a/config/locales/simple_form.da.yml +++ b/config/locales/simple_form.da.yml @@ -2,6 +2,14 @@ da: simple_form: hints: + account: + discoverable: Dine offentlige indlæg og profil kan blive fremhævet eller anbefalet i forskellige områder af Mastodon, og profilen kan blive foreslået til andre brugere. + display_name: Dit fulde navn eller dit sjove navn. + fields: Din hjemmeside, dine pronominer, din alder, eller hvad du har lyst til. + indexable: Dine offentlige indlæg vil kunne vises i Mastodon-søgeresultater. Folk, som har interageret med dem, vil kunne finde dem uanset. + note: 'Du kan @omtale andre personer eller #hashtags.' + show_collections: Folk vil ikke kunne tjekke dine Følger og Følgere. Folk, du selv følger, vil stadig kunne se dette. + unlocked: Folk vil kunne følge dig uden krav om godkendelse. Fjern markeringen, såfremt du ønsker at tjekke Følg-anmodninger og individuelt acceptere eller afvise nye Følgere. account_alias: acct: Angiv brugernavn@domain for den konto, hvorfra du vil flytte account_migration: @@ -18,6 +26,8 @@ da: disable: Forhindre brugeren i at bruge sin konto, men slet eller skjul ikke vedkommendes indhold. none: Brug dette til at sende en advarsel til brugeren uden at udløse nogen anden handling. sensitive: Gennemtving sensitivmarkering af alle denne brugers medievedhæftninger. + silence: Forhindr brugeren i at udgive offentligt synlige indlæg, skjul vedkommendes indlæg samt notifikationer fra ikke-følgere. Lukker alle indrapporteringer af kontoen. + suspend: Forhindr alle interaktion fra/til kontoen og slet dens indhold. Kan omgøres inden for 30 dage. Lukker alle indrapporteringer af kontoen. warning_preset_id: Valgfri. Du kan stadig tilføje tilpasset tekst til slutningen af forvalgene announcement: all_day: Hvis markeret, vil kun datoerne for tidsintervallet blive vist @@ -35,14 +45,11 @@ da: current_password: Angiv af sikkerhedsårsager adgangskoden til den aktuelle konto current_username: For at bekræfte, angiv brugernavnet for den aktuelle konto digest: Sendes kun efter en lang inaktivitetsperiode, og kun hvis du har modtaget personlige beskeder under fraværet - discoverable: Tillad kontoen at blive fundet af fremmede via anbefalinger og øvrige funktioner email: En bekræftelses-e-mail fremsendes - fields: Profilen kan have op til 4 elementer vist som en tabel header: PNG, GIF eller JPG. Maks. %{size}. Auto-nedskaleres til %{dimensions}px inbox_url: Kopiér URL'en fra forsiden af den videreformidler, der skal anvendes irreversible: Filtrerede indlæg forsvinder permanent, selv hvis filteret senere fjernes locale: Sprog til brug for brugerflade, e-mails og push-notifikationer - locked: Godkend manuelt følgeanmodninger for at styre, hvem der følger dig password: Brug mindst 8 tegn phrase: Matches uanset uanset brug af store/små bogstaver i teksten eller indholdsadvarsel for et indlæg scopes: De API'er, som applikationen vil kunne tilgå. Vælges en topniveaudstrækning, vil detailvalg være unødvendige. @@ -52,12 +59,9 @@ da: setting_display_media_default: Skjul medier med sensitiv-markering setting_display_media_hide_all: Skjul altid medier setting_display_media_show_all: Vis altid medier - setting_hide_network: Hvem du følger, og hvem som følger dig, skjules på din profil - setting_noindex: Påvirker din offentlige profil samt indlægssider - setting_show_application: Applikationen, hvormed der postes, vil fremgå af detailvisningen af dine indlæg setting_use_blurhash: Gradienter er baseret på de skjulte grafikelementers farver, men slører alle detaljer setting_use_pending_items: Skjul tidslinjeopdateringer bag et klik i stedet for brug af auto-feedrulning - username: Dit brugernavn vil være unikt på %{domain} + username: Bogstaver, cifre og understregningstegn kan benyttes whole_word: Ved rent alfanumeriske nøgleord/-sætning, forudsætter brugen matchning af hele ordet domain_allow: domain: Dette domæne vil kunne hente data, som efterfølgende behandles og gemmes, fra denne server @@ -80,6 +84,7 @@ da: custom_css: Man kan anvende tilpassede stilarter på Mastodon-webversionen. mascot: Tilsidesætter illustrationen i den avancerede webgrænseflade. media_cache_retention_period: Downloadede mediefiler slettes efter det angivne antal dage, når sat til en positiv værdi, og gendownloades på forlangende. + peers_api_enabled: En liste med domænenavne, som denne server har stødt på i fediverset. Ingen data inkluderes her om, hvorvidt der fødereres med en given server, blot at din server kender til det. Dette bruges af tjenester, som indsamler generelle føderationsstatistikker. profile_directory: Profilmappen oplister alle brugere, som har valgt at kunne opdages. require_invite_text: Når tilmelding kræver manuel godkendelse, så gør “Hvorfor ønsker du at deltage?” tekstinput obligatorisk i stedet for valgfrit site_contact_email: Hvordan folk kan opnå kontakt ifm. juridiske eller supportforespørgsler. @@ -115,6 +120,9 @@ da: sessions: otp: 'Angiv tofaktorkoden generet af din mobil-app eller brug en af genoprettelseskoderne:' webauthn: Er det en USB-nøgle, så sørg for at isætte den og, om nødvendigt, åbne den manuelt. + settings: + indexable: Din profilside kan fremgå i søgeresultater på Google, Bing mv. + show_application: Du vil dog altid kunne se, hvilken app, der offentliggjorde dit indlæg. tag: name: Kun bogstavtyper (store/små) kan ændres, eksempelvis for at gøre det mere læsbart user: @@ -128,12 +136,17 @@ da: position: Højere rolle bestemmer konfliktløsning i visse situationer. Visse handlinger kan kun udføres på roller med lavere prioritet webhook: events: Vælg begivenheder at sende + template: Skriv din egen JSON nyttelast ved hjælp af variabel interpolation. Lad feltet stå tomt for standard JSON. url: Hvor begivenheder sendes til labels: account: + discoverable: Fremhæv profil og indlæg i opdagelsesalgoritmer fields: name: Etiket value: Indhold + indexable: Medtag offentlige indlæg i søgeresultater + show_collections: Vis Følger og Følgere på profil + unlocked: Acceptér automatisk nye Følgere account_alias: acct: Brugernavn på den gamle konto account_migration: @@ -171,7 +184,6 @@ da: context: Kontekstfiltrering current_password: Aktuel adgangskode data: Data - discoverable: Foreslå konto til andre display_name: Visningsnavn email: E-mailadresse expires_in: Udløb efter @@ -181,7 +193,6 @@ da: inbox_url: URL til videreformidlingsindbakken irreversible: Fjern istedet for skjul locale: Grænsefladesprog - locked: Kræv følgeanmodninger max_uses: Maks. antal afbenyttelser new_password: Ny adgangskode note: Biografi @@ -190,10 +201,9 @@ da: phrase: Nøgleord/-sætning setting_advanced_layout: Aktivér avanceret webgrænseflade setting_aggregate_reblogs: Gruppér boosts på tidslinjer - setting_always_send_emails: Send altid en e-mailnotifikationer + setting_always_send_emails: Send altid e-mailnotifikationer setting_auto_play_gif: Autoafspil animerede GIF'er setting_boost_modal: Vis bekræftelsesdialog inden boosting - setting_crop_images: Beskær billeder i ikke-ekspanderede indlæg til 16x9 setting_default_language: Sprog for indlæg setting_default_privacy: Fortrolighed for indlæg setting_default_sensitive: Markér altid medier som sensitive @@ -205,9 +215,7 @@ da: setting_display_media_show_all: Vis alle setting_expand_spoilers: Ekspandér altid indlæg markeret med indholdsadvarsler setting_hide_network: Skjul din sociale graf - setting_noindex: Fravælg søgemaskineindeksering setting_reduce_motion: Reducér animationsbevægelse - setting_show_application: Vis applikationen brugt til at poste indlæg setting_system_font_ui: Brug systemets standardskrifttype setting_theme: Webstedstema setting_trends: Vis dagens tendenser @@ -238,6 +246,7 @@ da: custom_css: Tilpasset CSS mascot: Tilpasset maskot (ældre funktion) media_cache_retention_period: Media-cache opbevaringsperiode + peers_api_enabled: Udgiv liste over fundne server i API'en profile_directory: Aktivér profiloversigt registrations_mode: Hvem, der kan tilmelde sig require_invite_text: Kræv tilmeldingsbegrundelse @@ -255,10 +264,11 @@ da: timeline_preview: Tillad ikke-godkendt adgang til offentlige tidslinjer trendable_by_default: Tillad ikke-reviderede tendenser trends: Aktivér trends + trends_as_landing_page: Brug tendenser som destinationssiden interactions: - must_be_follower: Blokér notifikationer fra ikke-følgere - must_be_following: Blokér notifikationer fra folk, som ikke følges - must_be_following_dm: Bloker direkte beskeder fra folk, som ikke følges + must_be_follower: Blokér notifikationer fra bruger, der ikke følger dig + must_be_following: Blokér notifikationer fra brugere, du ikke følger + must_be_following_dm: Bloker direkte beskeder fra brugere, du ikke følger invite: comment: Kommentar invite_request: @@ -277,13 +287,22 @@ da: favourite: Nogen favoritmarkerede dit indlæg follow: Nogen begyndte at følge dig follow_request: Nogen anmodede om at følge dig - mention: Nogen nævnte dig + mention: Nogen omtalte dig pending_account: Ny konto kræver gennemgang reblog: Nogen boostede dit indlæg report: Ny anmeldelse indsendt + software_updates: + all: Notificér ved alle opdateringer + critical: Notificér kun ved kritiske opdateringer + label: En ny Mastodon-version er tilgængelig + none: Notificér ikke om opdateringer (anbefales ikke) + patch: Notificér om fejlrettelsesopdateringer trending_tag: Ny tendens kræver revidering rule: text: Regel + settings: + indexable: Inkludér profilside i søgemaskiner + show_application: Vis, fra hvilken app et indlæg er sendt tag: listable: Tillad visning af dette hashtag i søgninger og forslag name: Hashtag @@ -291,6 +310,7 @@ da: usable: Tillad indlæg at benytte dette hashtag user: role: Rolle + time_zone: Tidszone user_role: color: Badge-farve highlighted: Vis rolle som badge på brugerprofiler @@ -299,9 +319,11 @@ da: position: Prioritet webhook: events: Aktive begivenheder + template: Payload skabelon url: Endepunkts-URL 'no': Nej not_recommended: Ikke anbefalet + overridden: Tilsidesat recommended: Anbefalet required: mark: "*" diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index 6829286538..fcf92e29f4 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -2,64 +2,66 @@ de: simple_form: hints: + account: + discoverable: Deine öffentlichen Beiträge und dein Profil können in verschiedenen Bereichen auf Mastodon angezeigt oder empfohlen werden und dein Profil kann anderen vorgeschlagen werden. + display_name: Dein richtiger Name oder dein Fantasiename. + fields: Deine Website, Pronomen, dein Alter – alles, was du möchtest. + indexable: Deine öffentlichen Beiträge können in den Suchergebnissen auf Mastodon erscheinen. Profile, die bereits mit deinen Beiträgen interagiert haben, können deine Beiträge immer auffinden. + note: 'Du kannst andere @Profile erwähnen oder #Hashtags verwenden.' + show_collections: Andere können deine Follower und „Folge ich“ durchstöbern. Profile, denen du folgst, werden immer sehen können, dass du ihnen folgst. + unlocked: Andere können dir folgen, ohne vorher manuell genehmigt werden zu müssen. Wenn du Follower-Anfragen manuell akzeptieren oder ablehnen möchtest, dann lass diese Einstellung deaktiviert. account_alias: acct: Gib profilname@domain des Kontos an, von dem du umziehen möchtest account_migration: acct: Gib profilname@domain des Kontos an, zu dem du umziehen möchtest account_warning_preset: - text: Du kannst Beitragssyntax verwenden, wie z. B. URLs, Hashtags und Erwähnungen - title: Optional. Für den Empfänger nicht sichtbar + text: Du kannst die Syntax wie für Beiträge verwenden – z. B. URLs, Hashtags und Erwähnungen + title: "(Optional) Für Empfänger*in nicht sichtbar" admin_account_action: - include_statuses: Die Person sieht, welche Beiträge die Moderationsmaßnahme oder Warnung verursacht haben + include_statuses: Die Person wird sehen, welche Inhalte dich zu dieser Maßnahme veranlasst haben send_email_notification: Benutzer*in wird eine Erklärung erhalten, was mit dem Konto geschehen ist - text_html: Optional. Du kannst Beitragssyntax verwenden. Du kannst Warnvorlagen hinzufügen, um Zeit zu sparen + text_html: (Optional) Du kannst die Syntax wie für Beiträge verwenden. Du kannst Warnvorlagen hinzufügen, um Zeit zu sparen type_html: Wähle aus, wie mit %{acct} vorgegangen werden soll types: disable: Benutzer*in daran hindern, das Konto verwenden zu können, aber die Inhalte nicht löschen oder ausblenden. - none: Verwende dies, um dem Account eine Warnung zu schicken, ohne dabei eine andere Aktion vorzunehmen. + none: Dem Konto eine Warnung zusenden, ohne dabei eine andere Aktion vorzunehmen. sensitive: Erzwingen, dass alle Medienanhänge dieses Profils mit einer Inhaltswarnung versehen werden. silence: Verhindert, dass dieses Profil öffentlich sichtbare Beiträge verfassen kann, und verbirgt alle Beiträge und Benachrichtigungen vor Personen, die diesem Profil nicht folgen. Alle Meldungen zu diesem Konto werden geschlossen. suspend: Verhindert jegliche Interaktion von oder zu diesem Konto und löscht dessen Inhalt. Dies kann innerhalb von 30 Tagen rückgängig gemacht werden. Alle Meldungen zu diesem Konto werden geschlossen. - warning_preset_id: Optional. Du kannst immer noch eigenen Text an das Ende der Vorlage hinzufügen + warning_preset_id: "(Optional) Du kannst immer noch eigenen Text an das Ende der Vorlage hinzufügen" announcement: all_day: Falls aktiviert, werden nur der Tag bzw. die Tage innerhalb des Zeitraums angezeigt - ends_at: Optional. Die Ankündigung wird zu diesem Zeitpunkt automatisch zurückgezogen + ends_at: "(Optional) Die Ankündigung wird zu diesem Zeitpunkt automatisch zurückgezogen" scheduled_at: Leer lassen, um die Ankündigung sofort zu veröffentlichen - starts_at: Optional. Nur für den Fall, dass deine Ankündigung an einen bestimmten Zeitraum gebunden ist - text: Du kannst die reguläre Syntax wie für Beiträge verwenden, also auch Profile erwähnen und Hashtags nutzen. Bitte beachte den Platz, den die Ankündigung auf dem Bildschirm der Benutzer*innen einnehmen wird + starts_at: "(Optional) Für den Fall, dass deine Ankündigung an einen bestimmten Zeitraum gebunden ist" + text: Du kannst die Syntax wie für Beiträge verwenden. Bitte berücksichtige den Platz, den die Ankündigung auf dem Bildschirm der Benutzer*innen einnehmen wird appeal: - text: Du kannst nur einmal Einspruch gegen einen Verstoß einlegen + text: Du kannst nur einmal Einspruch gegen eine Maßnahme einlegen defaults: autofollow: Personen, die sich über deine Einladung registrieren, folgen automatisch deinem Profil avatar: PNG, GIF oder JPG. Höchstens %{size} groß. Wird auf %{dimensions} px verkleinert - bot: Hinweis an andere Benutzer*innen, dass dieses Konto hauptsächlich automatisierte Aktionen durchführt und möglicherweise nicht persönlich betreut wird - context: In welchem Bereich soll der Filter aktiv sein? - current_password: Aus Sicherheitsgründen gib bitte das Passwort des aktuellen Kontos ein + bot: Signalisiert, dass dieses Konto hauptsächlich automatisierte Aktionen durchführt und möglicherweise nicht persönlich betreut wird + context: Orte, an denen der Filter aktiv sein soll + current_password: Gib aus Sicherheitsgründen bitte das Passwort des aktuellen Kontos ein current_username: Um das zu bestätigen, gib den Profilnamen des aktuellen Kontos ein - digest: Wenn du eine längere Zeit inaktiv bist oder du in deiner Abwesenheit eine Direktnachricht erhalten hast - discoverable: Erlaube deinem Konto, durch Empfehlungen, Trends und andere Funktionen von Fremden entdeckt zu werden + digest: Wenn du eine längere Zeit inaktiv bist oder du während deiner Abwesenheit in einer privaten Nachricht erwähnt worden bist email: Du wirst eine E-Mail zur Verifizierung dieser E-Mail-Adresse erhalten - fields: Du kannst bis zu vier Metadaten auf deinem Profil anzeigen lassen, die als Tabelle dargestellt werden header: PNG, GIF oder JPG. Höchstens %{size} groß. Wird auf %{dimensions} px verkleinert inbox_url: Kopiere die URL von der Startseite des gewünschten Relays irreversible: Bereinigte Beiträge verschwinden unwiderruflich für dich, auch dann, wenn dieser Filter zu einem späteren wieder entfernt wird - locale: Die Sprache der Benutzeroberfläche, E-Mails und Push-Benachrichtigungen - locked: Wer dir folgen und deine Inhalte sehen möchte, muss dein Follower sein und dafür um deine Erlaubnis bitten + locale: Die Sprache der Bedienoberfläche, E-Mails und Push-Benachrichtigungen 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_aggregate_reblogs: Zeige denselben Beitrag nicht nochmal an, wenn er erneut geteilt wurde (dies betrifft nur neulich erhaltene erneut geteilte Beiträge) - setting_always_send_emails: Normalerweise werden Benachrichtigungen nicht per E-Mail verschickt, wenn du gerade auf Mastodon aktiv bist - setting_default_sensitive: Medien, die mit einer Inhaltswarnung versehen worden sind, werden erst nach einem zusätzlichen Klick angezeigt + setting_aggregate_reblogs: Beiträge, die erst kürzlich geteilt wurden, werden nicht noch einmal angezeigt (wirkt sich nur auf zukünftige geteilte Beiträge aus) + setting_always_send_emails: Normalerweise werden Benachrichtigungen nicht per E-Mail versendet, wenn du gerade auf Mastodon aktiv bist + setting_default_sensitive: Medien, die mit einer Inhaltswarnung versehen worden sind, werden – je nach Einstellung – erst nach einem zusätzlichen Klick angezeigt setting_display_media_default: Medien mit Inhaltswarnung ausblenden setting_display_media_hide_all: Medien immer ausblenden setting_display_media_show_all: Medien mit Inhaltswarnung immer anzeigen - setting_hide_network: Wem du folgst und wer dir folgt, wird in deinem Profil nicht angezeigt - setting_noindex: Betrifft alle öffentlichen Daten deines Profils, z. B. deine Beiträge, Account-Empfehlungen und „Über mich“ - setting_show_application: Die Anwendung die du nutzt wird in der detaillierten Ansicht deiner Beiträge angezeigt - setting_use_blurhash: Die Farbverläufe basieren auf den Farben der verborgenen Medien, verschleiern aber jegliche Details - setting_use_pending_items: Neue Beiträge hinter einem Klick verstecken, anstatt des automatischen Bildlaufs - username: Dein Profilname wird auf %{domain} einmalig sein + 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 + username: Du kannst Buchstaben, Zahlen und Unterstriche verwenden whole_word: Wenn das Wort oder die Formulierung nur aus Buchstaben oder Zahlen besteht, tritt der Filter nur dann in Kraft, wenn er exakt dieser Zeichenfolge entspricht domain_allow: domain: Diese Domain kann Daten von diesem Server abrufen, und eingehende Daten werden verarbeitet und gespeichert @@ -67,23 +69,23 @@ de: domain: Das kann die Domain aus einer E-Mail-Adresse oder einem MX-Eintrag sein. Bei der Registrierung eines neuen Profils wird beides überprüft. with_dns_records: Ein Versuch, die DNS-Einträge der Domain aufzulösen, wurde unternommen, und diese Ergebnisse werden unter anderem auch blockiert featured_tag: - name: 'Hier sind ein paar Hashtags, die du in letzter Zeit am häufigsten genutzt hast:' + 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 actions: hide: Den gefilterten Beitrag vollständig ausblenden, als hätte er nie existiert warn: Den gefilterten Beitrag hinter einer Warnung, die den Filtertitel beinhaltet, ausblenden form_admin_settings: - activity_api_enabled: Anzahl der lokal veröffentlichten Beiträge, der aktiven Benutzer*innen und neuen Registrierungen in wöchentlichen Abständen + activity_api_enabled: Anzahl der wöchentlichen Beiträge, aktiven Profile und Registrierungen auf diesem Server backups_retention_period: Behalte die Archive, die von den Benutzer*innen erstellt worden sind, für die angegebene Anzahl an Tagen. - bootstrap_timeline_accounts: Diese Profile werden bei den Follower-Empfehlungen für neu registrierte Nutzer*innen oben angeheftet. + bootstrap_timeline_accounts: Diese Konten werden bei den Follower-Empfehlungen für neu registrierte Nutzer*innen oben angeheftet. closed_registrations_message: Wird angezeigt, wenn Registrierungen deaktiviert sind - content_cache_retention_period: Beiträge von anderen Servern werden nach der angegebenen Anzahl von Tagen, wenn sie auf einen positiven Wert gesetzt werden, gelöscht. Dies kann eventuell nicht rückgängig gemacht werden. + content_cache_retention_period: Sowohl alle Beiträge als auch geteilte Beiträge von anderen Servern werden nach der angegebenen Anzahl von Tagen gelöscht. Alle zugehörigen Lesezeichen, Favoriten und geteilte Beiträge werden ebenfalls verloren gehen. Dies kann nicht mehr rückgängig gemacht werden. custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden. mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche. - media_cache_retention_period: Von anderen Instanzen übertragene Mediendateien werden nach der angegebenen Anzahl an Tagen – sofern das Feld eine positive Zahl enthält – aus dem Cache gelöscht und bei Bedarf erneut heruntergeladen. - peers_api_enabled: Eine Liste von Domainnamen, die diesem Server im Fediverse begegnet sind. Hier werden keine Angaben darüber gemacht, ob du mit einem bestimmten Server föderierst, sondern nur, dass dein Server davon weiß. Dies wird von Diensten verwendet, die Statistiken über Föderation im allgemeinen Sinne sammeln. - profile_directory: Das Profilverzeichnis zeigt alle Benutzer*innen an, die sich dafür entschieden haben, entdeckt zu werden. + media_cache_retention_period: Von anderen Servern übertragene Mediendateien werden nach der angegebenen Anzahl an Tagen – sofern das Feld eine positive Zahl enthält – aus dem Cache gelöscht und bei Bedarf erneut heruntergeladen. + peers_api_enabled: Eine Liste von Domains, die diesem Server im Fediverse begegnet sind. Hierbei werden keine Angaben darüber gemacht, ob du mit einem bestimmten Server föderierst, sondern nur, dass dein Server davon weiß. Dies wird von Diensten verwendet, die allgemein Statistiken übers Ferdiverse sammeln. + profile_directory: Dieses Verzeichnis zeigt alle Profile an, die sich dafür entschieden haben, entdeckt zu werden. require_invite_text: Wenn Registrierungen eine manuelle Genehmigung erfordern, dann werden Nutzer einen Grund für ihre Registrierung angeben müssen site_contact_email: Wie man dich bei rechtlichen oder Support-Anfragen erreichen kann. site_contact_username: Wie man dich auf Mastodon erreichen kann. @@ -91,35 +93,38 @@ de: site_short_description: Eine kurze Beschreibung zur eindeutigen Identifizierung des Servers. Wer betreibt ihn, für wen ist er bestimmt? site_terms: Verwende eine eigene Datenschutzerklärung oder lasse das Feld leer, um die allgemeine Vorlage zu verwenden. Kann mit der Markdown-Syntax formatiert werden. site_title: Wie Personen neben dem Domainnamen auf deinen Server verweisen können. - status_page_url: URL einer Seite, auf der der Status des Servers während eines Ausfalls angezeigt werden kann + status_page_url: Link zu einer Internetseite, auf der der Serverstatus während eines Ausfalls angezeigt wird theme: Das Design, das abgemeldete Besucher und neue Benutzer sehen. thumbnail: Ein Bild ungefähr im 2:1-Format, das neben den Server-Informationen angezeigt wird. - timeline_preview: Besucher*innen und ausgeloggte Benutzer*innen können die neuesten öffentlichen Beiträge dieses Servers aufrufen. + timeline_preview: Nicht angemeldete Personen können die neuesten öffentlichen Beiträge dieses Servers aufrufen. trendable_by_default: Manuelles Überprüfen angesagter Inhalte überspringen. Einzelne Elemente können später noch aus den Trends entfernt werden. trends: Trends zeigen, welche Beiträge, Hashtags und Nachrichten auf deinem Server immer beliebter werden. trends_as_landing_page: Dies zeigt nicht angemeldeten Personen Trendinhalte anstelle einer Beschreibung des Servers an. Erfordert, dass Trends aktiviert sind. form_challenge: - current_password: Du betrittst einen gesicherten Bereich + current_password: Du betrittst einen sicheren Bereich imports: - data: CSV-Datei, exportiert von einem anderen Mastodon-Server + data: CSV-Datei, die von einem Mastodon-Server exportiert worden ist invite_request: text: Dies wird uns bei der Überprüfung deiner Anmeldung behilflich sein ip_block: - comment: Optional. Zur Erinnerung, weshalb du diese Regel eingeführt hast. - expires_in: IP-Adressen sind eine begrenzte Ressource. Sie können außerdem auf viele Computer aufgeteilt sein und auch die Zuordnungen ändern sich. Deshalb werden unbestimmte IP-Blöcke nicht empfohlen. + comment: "(Optional) Zur Erinnerung, weshalb du diese Regel eingeführt hast." + expires_in: IP-Adressen sind eine begrenzte Ressource. Sie können außerdem auf viele Computer aufgeteilt sein und auch die Zuordnungen ändern sich. Deshalb werden unbestimmte IP-Sperren nicht empfohlen. ip: Gib eine IPv4- oder IPv6-Adresse an. Du kannst ganze Bereiche mit der CIDR-Syntax blockieren. Achte darauf, dass du dich nicht selbst aussperrst! severities: - no_access: Blockiere Zugriff auf alle Ressourcen + no_access: Zugriff auf alle Ressourcen blockieren sign_up_block: Neue Registrierungen werden nicht möglich sein sign_up_requires_approval: Neue Registrierungen müssen genehmigt werden severity: Wähle aus, was mit Anfragen von dieser IP-Adresse geschehen soll rule: - text: Führe eine Regel oder Bedingung für Benutzer*innen auf diesem Server ein. Bleib dabei kurz und knapp + text: Führe eine Regel oder Auflage für Profile auf diesem Server ein. Bleib dabei kurz und knapp sessions: - otp: 'Gib den Zwei-Faktor-Code von deinem Telefon ein oder benutze einen deiner Wiederherstellungscodes:' - webauthn: Wenn es sich um einen USB-Schlüssel handelt, vergewissere dich, dass du ihn einsteckst und ihn, wenn notwendig, antippst. + otp: 'Gib den Zwei-Faktor-Code von deinem Smartphone ein oder verwende einen deiner Wiederherstellungscodes:' + webauthn: Wenn es sich um einen USB-Schlüssel handelt, vergewissere dich, dass du ihn einsteckst und – falls erforderlich – antippst. + settings: + indexable: Deine Profilseite kann in Suchergebnissen auf Google, Bing und anderen erscheinen. + show_application: Du wirst immer sehen können, über welche App dein Beitrag veröffentlicht wurde. tag: - name: Du kannst zum Beispiel nur die Groß- und Kleinschreibung der Buchstaben ändern, um es lesbarer zu machen + name: Du kannst nur die Groß- und Kleinschreibung der Buchstaben ändern, um es z. B. lesbarer zu machen user: chosen_languages: Wenn du hier eine oder mehrere Sprachen auswählst, werden ausschließlich Beiträge in diesen Sprachen in deinen öffentlichen Timelines angezeigt role: Die Rolle legt fest, welche Berechtigungen das Konto hat @@ -130,32 +135,37 @@ de: permissions_as_keys: Benutzer*innen mit dieser Rolle haben Zugriff auf... position: Höhere Rollen entscheiden über Konfliktlösungen zu gewissen Situationen. Bestimmte Aktionen können nur mit geringfügigeren Rollen durchgeführt werden webhook: - events: Wähle die zu sendenden Termine - url: Wo Ereignisse hingesendet werden + events: Zu sendende Ereignisse auswählen + template: Erstelle deine eigenen JSON-Nutzdaten mit Hilfe von Variablen-Interpolation. Leer lassen für Standard-JSON. + url: Wohin Ereignisse gesendet werden labels: account: + discoverable: Profil und Beiträge in Suchalgorithmen berücksichtigen fields: - name: Bezeichnung + name: Beschriftung value: Inhalt + indexable: Öffentliche Beiträge in die Suchergebnisse einbeziehen + show_collections: Follower und „Folge ich“ im Profil anzeigen + unlocked: Neue Follower automatisch akzeptieren account_alias: - acct: Betreiber des alten Kontos + acct: Profilname des alten Kontos account_migration: - acct: Betreiber des neuen Kontos + acct: Adresse des neuen Kontos account_warning_preset: text: Vorlagentext title: Titel admin_account_action: - include_statuses: Beitragsmeldungen in die E-Mail mit anfügen - send_email_notification: Nutzer*in per E-Mail benachrichtigen - text: Benutzerdefinierte Warnung + include_statuses: Gemeldete Beiträge der E-Mail beifügen + send_email_notification: Benachrichtigung per E-Mail + text: Individuelle Warnung type: Aktion types: disable: Einfrieren - none: Warnung senden + none: Nur Verwarnung sensitive: Inhaltswarnung - silence: Einschränkung - suspend: Sperren - warning_preset_id: Warnungsvorlage verwenden + silence: Stummschalten + suspend: Sperre + warning_preset_id: Warnvorlage verwenden announcement: all_day: Ganztägiges Ereignis ends_at: Ende der Ankündigung @@ -163,67 +173,62 @@ de: starts_at: Beginn der Ankündigung text: Ankündigung appeal: - text: Teile mit, warum diese Entscheidung zurückgenommen werden soll + text: Begründe, weshalb diese Entscheidung zurückgenommen werden sollte defaults: - autofollow: Lade ein, um deinem Konto zu folgen + autofollow: Meinem Profil automatisch folgen avatar: Profilbild - bot: Dies ist ein Bot-Konto + bot: Dieses Profil ist automatisiert chosen_languages: Sprachen einschränken confirm_new_password: Neues Passwort bestätigen confirm_password: Passwort bestätigen - context: Filter nach Bereichen + context: Nach Bereichen filtern current_password: Derzeitiges Passwort data: Daten - discoverable: Konto für andere empfehlen display_name: Anzeigename email: E-Mail-Adresse expires_in: Läuft ab - fields: Metadaten + fields: Zusatzfelder header: Titelbild honeypot: "%{label} (nicht ausfüllen)" - inbox_url: Inbox-URL des Relais + inbox_url: URL des Relay-Posteingangs irreversible: Endgültig, nicht nur temporär ausblenden locale: Sprache des Webinterface - locked: Geschütztes Profil - max_uses: Maximale Anzahl der Nutzer + max_uses: Maximale Anzahl von Verwendungen new_password: Neues Passwort - note: Über mich + note: Biografie otp_attempt: Zwei-Faktor-Authentisierung password: Passwort phrase: Wort oder Formulierung setting_advanced_layout: Erweitertes Webinterface verwenden - setting_aggregate_reblogs: Boosts in der Timeline gruppieren + 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: Bestätigung vor dem Teilen einholen - setting_crop_images: Bilder in nicht ausgeklappten Beiträgen auf 16:9 zuschneiden + setting_boost_modal: Bestätigungsdialog beim Teilen eines Beitrags anzeigen setting_default_language: Beitragssprache setting_default_privacy: Beitragssichtbarkeit - setting_default_sensitive: Eigene Medien immer mit einer Inhaltswarnung versehen - setting_delete_modal: Bestätigung anzeigen, bevor ein Beitrag gelöscht wird + setting_default_sensitive: Medien immer mit einer Inhaltswarnung versehen + setting_delete_modal: Bestätigungsdialog beim Löschen eines Beitrags anzeigen setting_disable_swiping: Wischgesten deaktivieren - setting_display_media: Medien-Anzeige + setting_display_media: Darstellung von Medien setting_display_media_default: Standard setting_display_media_hide_all: Alle Medien ausblenden setting_display_media_show_all: Alle Medien anzeigen setting_expand_spoilers: Beiträge mit Inhaltswarnung immer ausklappen - setting_hide_network: Deine Follower und „Folge ich“ nicht anzeigen - setting_noindex: Suchmaschinen-Indexierung verhindern + setting_hide_network: Follower und „Folge ich“ nicht anzeigen setting_reduce_motion: Bewegung in Animationen verringern - setting_show_application: Den Namen der App offenlegen, mit der du deine Beiträge veröffentlichst setting_system_font_ui: Standardschriftart des Browsers verwenden setting_theme: Design setting_trends: Heutige Trends anzeigen - setting_unfollow_modal: Bestätigungsdialog anzeigen, bevor jemandem entfolgt wird - setting_use_blurhash: Farbverlauf für verborgene Medien anzeigen + setting_unfollow_modal: Bestätigungsdialog beim Entfolgen eines Profils anzeigen + setting_use_blurhash: Farbverlauf bei ausgeblendeten Medien anzeigen setting_use_pending_items: Langsamer Modus - severity: Schweregrad + severity: Einschränkung sign_in_token_attempt: Sicherheitscode title: Titel - type: Art des Imports + type: Typ username: Profilname username_or_email: Profilname oder E-Mail - whole_word: Phrasensuche mit exakter Zeichenfolge erzwingen + whole_word: Exakte Zeichenfolge email_domain_block: with_dns_records: MX-Einträge und IP-Adressen der Domain einbeziehen featured_tag: @@ -231,43 +236,43 @@ de: filters: actions: hide: Vollständig ausblenden - warn: Mit einer Warnung ausblenden + warn: Mit einer Inhaltswarnung ausblenden form_admin_settings: - activity_api_enabled: Veröffentlichung von Gesamtstatistiken über Nutzeraktivitäten in der API + activity_api_enabled: Aggregierte Nutzungsdaten über die API veröffentlichen backups_retention_period: Aufbewahrungsfrist für Archive bootstrap_timeline_accounts: Neuen Nutzern immer diese Konten empfehlen closed_registrations_message: Nachricht, falls Registrierungen deaktiviert sind content_cache_retention_period: Aufbewahrungsfrist für Inhalte im Cache custom_css: Eigenes CSS mascot: Benutzerdefiniertes Maskottchen (Legacy) - media_cache_retention_period: Aufbewahrungsfrist für den Medien-Cache - peers_api_enabled: Veröffentliche Liste bekannter Server in der API + media_cache_retention_period: Aufbewahrungsfrist für Medien im Cache + peers_api_enabled: Die entdeckten Server im Fediverse über die API veröffentlichen profile_directory: Profilverzeichnis aktivieren registrations_mode: Wer darf ein neues Konto registrieren? - require_invite_text: Grund für den Beitritt verlangen + require_invite_text: Begründung für Beitritt verlangen show_domain_blocks: Anzeigen, welche Domains gesperrt wurden show_domain_blocks_rationale: Anzeigen, weshalb Domains gesperrt wurden site_contact_email: E-Mail-Adresse site_contact_username: Profilname - site_extended_description: Detaillierte Beschreibung + site_extended_description: Erweiterte Beschreibung site_short_description: Serverbeschreibung site_terms: Datenschutzerklärung site_title: Servername - status_page_url: URL der Statusseite + status_page_url: Statusseite (URL) theme: Standard-Design thumbnail: Vorschaubild des Servers - timeline_preview: Nicht-authentifizierten Zugriff auf die öffentliche Timeline gestatten + timeline_preview: Nicht-authentisierten Zugriff auf öffentliche Timelines gestatten trendable_by_default: Trends ohne vorherige Überprüfung erlauben trends: Trends aktivieren trends_as_landing_page: Trends als Landingpage verwenden interactions: - must_be_follower: Benachrichtigungen von Profilen verbergen, die mir nicht folgen - must_be_following: Benachrichtigungen von Profilen verbergen, denen ich nicht folge - must_be_following_dm: Direktnachrichten von Profilen, denen ich nicht folge, ablehnen + must_be_follower: Benachrichtigungen von Profilen, die mir nicht folgen, ausblenden + must_be_following: Benachrichtigungen von Profilen, denen ich nicht folge, ausblenden + must_be_following_dm: Private Nachrichten von Profilen, denen ich nicht folge, ausblenden invite: comment: Kommentar invite_request: - text: Warum möchtest du beitreten? + text: Weshalb möchtest du beitreten? ip_block: comment: Kommentar ip: IP-Adresse @@ -277,25 +282,35 @@ de: sign_up_requires_approval: Registrierungen begrenzen severity: Regel notification_emails: - appeal: wenn jemand einer Moderationsentscheidung widerspricht + appeal: Jemand hat Einspruch gegen eine Moderationsentscheidung erhoben digest: Zusammenfassung senden - favourite: wenn jemand meinen Beitrag favorisiert - follow: wenn mir jemand folgt - follow_request: wenn mir jemand folgen möchte - mention: wenn mich jemand erwähnt - pending_account: wenn ein neues Konto überprüft werden muss - reblog: wenn jemand meinen Beitrag teilt - report: wenn eine neue Meldung vorliegt - trending_tag: wenn ein neuer Trend überprüft werden soll + favourite: Mein Beitrag wurde favorisiert + follow: Jemand Neues folgt mir + follow_request: Jemand möchte mir folgen + mention: Ich wurde erwähnt + pending_account: Ein neues Konto muss überprüft werden + reblog: Mein Beitrag wurde geteilt + report: Eine neue Meldung wurde eingereicht + software_updates: + all: Über alle Updates informieren + critical: Nur über kritische Updates informieren + label: Eine neue Mastodon-Version ist verfügbar + none: Nie über Updates informieren (nicht empfohlen) + patch: Über Fehlerbehebungen informieren + trending_tag: Neuer Trend erfordert eine Überprüfung rule: text: Regel + settings: + indexable: Profilseite in Suchmaschinen einbeziehen + show_application: App anzeigen, über die ich einen Beitrag veröffentlicht habe tag: - listable: Erlaube diesem Hashtag, im Profilverzeichnis zu erscheinen + listable: Erlaube, dass dieser Hashtag in Suchen und Empfehlungen erscheint name: Hashtag - trendable: Erlaube es, diesen Hashtag in den Trends erscheinen zu lassen - usable: Beiträgen erlauben, diesen Hashtag zu verwenden + trendable: Erlaube, dass dieser Hashtag in den Trends erscheint + usable: Erlaube, dass dieser Hashtag in Beiträgen erscheint user: role: Rolle + time_zone: Zeitzone user_role: color: Badge-Farbe highlighted: Rolle als Badge im Profil anzeigen @@ -304,9 +319,11 @@ de: position: Priorität webhook: events: Aktivierte Ereignisse + template: Nutzdaten-Vorlage url: Endpunkt-URL 'no': Nein not_recommended: Nicht empfohlen + overridden: Überschrieben recommended: Empfohlen required: mark: "*" diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml index d28435c7df..dc140a199f 100644 --- a/config/locales/simple_form.el.yml +++ b/config/locales/simple_form.el.yml @@ -7,24 +7,28 @@ el: account_migration: acct: Όρισε το username@domain του λογαριασμού στον οποίο θέλεις να μετακινηθείς account_warning_preset: - text: Μπορείς να χρησιμοποιήσεις το ίδιο συντακτικό των τουτ όπως URL, ετικέτες και αναφορές + text: Μπορείς να χρησιμοποιήσεις το ίδιο συντακτικό των αναρτήσεων όπως URL, ετικέτες και αναφορές title: Προαιρετικό. Δεν εμφανίζεται στον παραλήπτη admin_account_action: - include_statuses: Ο χρήστης θα δει ποια τουτ προκάλεσαν την προειδοποίηση ή την ενέργεια των διαχειριστών - send_email_notification: Ο χρήστης θα λάβει μια εξήγηση του τι συνέβη με τον λογαριασμό του - text_html: Προαιρετικό. Μπορείς να χρησιμοποιήσεις συντακτικό ενός τουτ. Μπορείς να ορίσεις προκαθορισμένες προειδοποιήσεις για να γλυτώσεις χρόνο - type_html: Διάλεξε τι θα κανείς με τον %{acct} + include_statuses: Ο χρήστης θα δει ποιες αναρτήσεις προκάλεσαν την προειδοποίηση ή την ενέργεια των συντονιστών + send_email_notification: Ο χρήστης θα λάβει μια εξήγηση του τί συνέβη με τον λογαριασμό του + text_html: Προαιρετικό. Μπορείς να χρησιμοποιήσεις συντακτικό ανάρτησης. Μπορείς να ορίσεις προκαθορισμένες προειδοποιήσεις για να γλιτώσεις χρόνο + type_html: Διάλεξε τί θα κάνεις με τον %{acct} types: - disable: Αποτρέψτε το χρήστη από τη χρήση του λογαριασμού του, αλλά όχι διαγραφή ή απόκρυψη των περιεχομένων του. - none: Χρησιμοποιήστε αυτό για να στείλετε μια προειδοποίηση στον χρήστη, χωρίς να ενεργοποιήσετε οποιαδήποτε άλλη ενέργεια. - sensitive: Εξαναγκάστε όλα τα συνημμένα πολυμέσα αυτού του χρήστη να επισημαίνονται ως ευαίσθητα. + disable: Απέτρεψε το χρήστη από τη χρήση του λογαριασμού του, αλλά μη διαγράψεις ή αποκρύψεις το περιεχόμενό του. + none: Χρησιμοποίησε αυτό για να στείλεις μια προειδοποίηση στον χρήστη, χωρίς να ενεργοποιήσεις οποιαδήποτε άλλη ενέργεια. + sensitive: Ανάκασε όλα τα συνημμένα πολυμέσα αυτού του χρήστη να επισημαίνονται ως ευαίσθητα. + silence: Απέτρεψετον χρήστη από το να μπορεί να δημοσιεύει με δημόσια ορατότητα, να αποκρύπτει τις αναρτήσεις του και τις ειδοποιήσεις του από άτομα που δεν τον ακολουθούν. Κλείνει όλες τις αναφορές εναντίον αυτού του λογαριασμού. + suspend: Αποτροπή οποιασδήποτε αλληλεπίδρασης από ή προς αυτόν τον λογαριασμό και διαγραφή των περιεχομένων του. Αναστρέψιμο εντός 30 ημερών. Κλείνει όλες τις αναφορές εναντίον αυτού του λογαριασμού. warning_preset_id: Προαιρετικό. Μπορείς να προσθέσεις επιπλέον κείμενο μετά το προκαθορισμένο κείμενο announcement: all_day: Όταν είναι επιλεγμένο, θα εμφανίζονται μόνο οι ημερομηνίες εντός της χρονικής διάρκειας ends_at: Προαιρετικό. Η ανακοίνωση θα αποσυρθεί αυτόματα τη δηλωμένη ώρα scheduled_at: Αν μείνει κενό, η ενημέρωση θα δημοσιευτεί αμέσως starts_at: Προαιρετικό, για την περίπτωση που η ανακοίνωση αφορά συγκεκριμένη χρονική διάρκεια - text: Δεκτό το συντακτικό των τουτ. Παρακαλούμε έχε υπόψιν σου το χώρο που θα καταλάβει η ανακοίνωση στην οθόνη του χρήστη + text: Μπορείς να χρησιμοποιήσεις το συντακτικό των αναρτήσεων. Παρακαλώ να έχεις κατά νου το χώρο που θα καταλάβει η ανακοίνωση στην οθόνη του χρήστη + appeal: + text: Μπορείς να κάνετε έφεση σε ένα παράπτωμα μόνο μία φορά defaults: autofollow: Όσοι εγγραφούν μέσω της πρόσκλησης θα σε ακολουθούν αυτόματα avatar: PNG, GIF ή JPG. Έως %{size}. Θα περιοριστεί σε διάσταση %{dimensions}px @@ -34,34 +38,60 @@ el: current_username: Για επιβεβαίωση, παρακαλώ γράψε το όνομα χρήστη του τρέχοντος λογαριασμού digest: Αποστέλλεται μόνο μετά από μακρά περίοδο αδράνειας και μόνο αν έχεις λάβει προσωπικά μηνύματα κατά την απουσία σου email: Θα σου σταλεί email επιβεβαίωσης - fields: Μπορείς να έχεις έως 4 σημειώσεις σε μορφή πίνακα στο προφίλ σου header: PNG, GIF ή JPG. Έως %{size}. Θα περιοριστεί σε διάσταση %{dimensions}px - inbox_url: Αντέγραψε το URL της αρχικής σελίδας του ανταποκριτή (relay) που θέλεις να χρησιμοποιήσεις - irreversible: Τα φιλτραρισμένα τουτ θα εξαφανιστούν αμετάκλητα, ακόμα και αν το φίλτρο αργότερα αφαιρεθεί - locale: Η γλώσσα χρήσης, των email και των ειδοποιήσεων ώθησης - locked: Απαιτεί να εγκρίνεις χειροκίνητα τους ακόλουθούς σου + inbox_url: Αντέγραψε το URL της αρχικής σελίδας του ανταποκριτή που θέλεις να χρησιμοποιήσεις + irreversible: Οι φιλτραρισμένες αναρτήσεις θα εξαφανιστούν αμετάκλητα, ακόμα και αν το φίλτρο αργότερα αφαιρεθεί + locale: Η γλώσσα χρήσης, των email και των ειδοποιήσεων push password: Χρησιμοποίησε τουλάχιστον 8 χαρακτήρες - phrase: Θα ταιριάζει ανεξαρτήτως πεζών/κεφαλαίων ή προειδοποίησης περιεχομένου του τουτ - scopes: Ποια API θα επιτρέπεται στην εφαρμογή να χρησιμοποιήσεις. Αν επιλέξεις κάποιο υψηλό εύρος εφαρμογής, δε χρειάζεται να επιλέξεις και εξειδικευμένα. - setting_aggregate_reblogs: Απόκρυψη των νέων προωθήσεωνγια τα τουτ που έχουν προωθηθεί πρόσφατα (επηρεάζει μόνο τις νέες προωθήσεις) + phrase: Θα ταιριάζει ανεξαρτήτως πεζών/κεφαλαίων ή προειδοποίησης περιεχομένου μιας ανάρτησης + scopes: Ποια API θα επιτρέπεται στην εφαρμογή να χρησιμοποιήσεις. Αν επιλέξεις κάποιο υψηλό εύρος εφαρμογής, δε χρειάζεται να επιλέξεις και το καθένα ξεχωριστά. + setting_aggregate_reblogs: Απόκρυψη των νέων αναρτήσεων για τις αναρτήσεις που έχουν ενισχυθεί πρόσφατα (επηρεάζει μόνο τις νέες ενισχύσεις) setting_always_send_emails: Κανονικά οι ειδοποιήσεις μέσω ηλεκτρονικού ταχυδρομείου δεν θα αποστέλλονται όταν χρησιμοποιείτε ενεργά το Mastodon setting_default_sensitive: Τα ευαίσθητα πολυμέσα είναι κρυμμένα και εμφανίζονται με ένα κλικ setting_display_media_default: Απόκρυψη ευαίσθητων πολυμέσων setting_display_media_hide_all: Μόνιμη απόκρυψη όλων των πολυμέσων - setting_display_media_show_all: Μόνιμη εμφάνιση ευαίσθητων πολυμέσων - setting_hide_network: Δε θα εμφανίζεται στο προφίλ σου ποιους ακολουθείς και ποιοι σε ακολουθούν - setting_noindex: Επηρεάζει το δημόσιο προφίλ και τις δημοσιεύσεις σου - setting_show_application: Η εφαρμογή που χρησιμοποιείς για να στέλνεις τα τουτ σου θα εμφανίζεται στις αναλυτικές λεπτομέρειες τους + setting_display_media_show_all: Πάντα εμφάνιση πολυμέσων setting_use_blurhash: Οι χρωματισμοί βασίζονται στα χρώματα του κρυμμένου πολυμέσου αλλά θολώνουν τις λεπτομέρειες setting_use_pending_items: Εμφάνιση ενημερώσεων ροής μετά από κλικ αντί για αυτόματη κύλισή τους - username: Το όνομα χρήστη σου θα είναι μοναδικό στο %{domain} + username: Μπορείς να χρησιμοποιήσεις γράμματα, αριθμούς και κάτω παύλες whole_word: Όταν η λέξη ή η φράση κλειδί είναι μόνο αλφαριθμητική, θα εφαρμοστεί μόνο αν ταιριάζει με ολόκληρη τη λέξη domain_allow: domain: Ο τομέας αυτός θα επιτρέπεται να ανακτά δεδομένα από αυτό τον διακομιστή και τα εισερχόμενα δεδομένα θα επεξεργάζονται και θα αποθηκεύονται email_domain_block: + domain: Αυτό μπορεί να είναι το όνομα τομέα που εμφανίζεται στη διεύθυνση email ή η εγγραφή MX που χρησιμοποιεί. Θα ελέγχονται κατά την εγγραφή. with_dns_records: Θα γίνει απόπειρα ανάλυσης των εγγραφών DNS του τομέα και τα αποτελέσματα θα μπουν και αυτά σε μαύρη λίστα featured_tag: name: 'Εδώ είναι μερικά από τα hashtags που χρησιμοποιήσατε περισσότερο πρόσφατα:' + 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. + mascot: Παρακάμπτει την εικονογραφία στην προηγμένη διεπαφή ιστού. + media_cache_retention_period: Τα ληφθέντα αρχεία πολυμέσων θα διαγραφούν μετά τον καθορισμένο αριθμό ημερών, όταν οριστεί σε θετική τιμή, και να γίνει εκ νέου λήψη κατά απαίτηση. + peers_api_enabled: Μια λίστα με ονόματα τομέα που συνάντησε αυτός ο διακομιστής στο fediverse. Δεν περιλαμβάνονται δεδομένα εδώ για το αν συναλλάσσετε με ένα συγκεκριμένο διακομιστή, μόνο ότι ο διακομιστής σας το ξέρει. Χρησιμοποιείται από υπηρεσίες που συλλέγουν στατιστικά στοιχεία για την συναλλαγή με γενική έννοια. + profile_directory: Ο κατάλογος προφίλ παραθέτει όλους τους χρήστες που έχουν επιλέξει να είναι ανακαλύψιμοι. + require_invite_text: 'Όταν η εγγραφή απαιτεί χειροκίνητη έγκριση, κάνε το πεδίο κειμένου: «Γιατί θέλετε να συμμετάσχετε;» υποχρεωτικό αντί για προαιρετικό' + site_contact_email: Πώς μπορούν να σε προσεγγίσουν για νομικές ή υποστηρικτικές έρευνες. + site_contact_username: Πώς μπορούν να σε προσεγγίσουν στο Mastodon. + site_extended_description: Οποιεσδήποτε πρόσθετες πληροφορίες μπορεί να είναι χρήσιμες για τους επισκέπτες και τους χρήστες σας. Μπορεί να δομηθεί με σύνταξη Markdown. + site_short_description: Μια σύντομη περιγραφή για να ξεχωρίζει ο διακομιστής σου. Ποιος τον έχει, για ποιον είναι; + site_terms: Χρησιμοποίησε τη δική σου πολιτική απορρήτου ή άσε το κενό για να χρησιμοποιήσεις την προεπιλεγμένη. Μπορεί να δομηθεί με σύνταξη Markdown. + site_title: Πώς μπορεί κάποιος να αναφέρεται στο διακομιστή σου εκτός από το όνομα τομέα του. + status_page_url: Το URL μιας σελίδας όπου κάποιος μπορεί να δει την κατάσταση αυτού του διακομιστή κατά τη διάρκεια μιας διακοπής λειτουργίας + theme: Θέμα που βλέπουν αποσυνδεδεμένοι επισκέπτες ή νέοι χρήστες. + thumbnail: Μια εικόνα περίπου 2:1 που εμφανίζεται παράλληλα με τις πληροφορίες του διακομιστή σου. + timeline_preview: Αποσυνδεδεμένοι επισκέπτες θα μπορούν να περιηγηθούν στις πιο πρόσφατες δημόσιες δημοσιεύσεις που είναι διαθέσιμες στο διακομιστή. + trendable_by_default: Παράλειψη χειροκίνητης αξιολόγησης του περιεχομένου σε τάση. Μεμονωμένα στοιχεία μπορούν ακόμα να αφαιρεθούν από τις τάσεις μετέπειτα. + trends: Τάσεις δείχνουν ποιες δημοσιεύσεις, ετικέτες και ειδήσεις προκαλούν έλξη στο διακομιστή σας. + trends_as_landing_page: Εμφάνιση περιεχομένου σε τάση σε αποσυνδεδεμένους χρήστες και επισκέπτες αντί για μια περιγραφή αυτού του διακομιστή. Απαιτεί οι τάσεις να έχουν ενεργοποιηθεί. form_challenge: current_password: Μπαίνεις σε ασφαλή περιοχή imports: @@ -86,6 +116,16 @@ el: name: Μπορείς να αλλάξεις μόνο το πλαίσιο των χαρακτήρων, για παράδειγμα για να γίνει περισσότερο ευανάγνωστο user: chosen_languages: Όταν ενεργοποιηθεί, στη δημόσια ροή θα εμφανίζονται τουτ μόνο από τις επιλεγμένες γλώσσες + role: Ο ρόλος ελέγχει ποια δικαιώματα έχει ο χρήστης + user_role: + color: Το χρώμα που θα χρησιμοποιηθεί για το ρόλο σε ολόκληρη τη διεπαφή, ως RGB σε δεκαεξαδική μορφή + highlighted: Αυτό καθιστά το ρόλο δημόσια ορατό + name: Δημόσιο όνομα του ρόλου, εάν ο ρόλος έχει οριστεί να εμφανίζεται ως σήμα + permissions_as_keys: Οι χρήστες με αυτόν τον ρόλο θα έχουν πρόσβαση σε... + position: Ανώτεροι ρόλοι αποφασίζει την επίλυση συγκρούσεων σε ορισμένες περιπτώσεις. Ορισμένες ενέργειες μπορούν να εκτελεστούν μόνο σε ρόλους με χαμηλότερη προτεραιότητα + webhook: + events: Επιλέξτε συμβάντα για αποστολή + url: Πού θα σταλούν τα γεγονότα labels: account: fields: @@ -116,6 +156,8 @@ el: scheduled_at: Προγραμματισμένη δημοσίευση starts_at: Έναρξη γεγονότος text: Ανακοίνωση + appeal: + text: Εξηγήστε γιατί αυτή η απόφαση πρέπει να αντιστραφεί defaults: autofollow: Προσκάλεσε για να ακολουθήσουν το λογαριασμό σου avatar: Αβατάρ @@ -126,7 +168,6 @@ el: context: Πλαίσια φιλτραρίσματος current_password: Τρέχον συνθηματικό data: Δεδομένα - discoverable: Εμφάνιση αυτού του λογαριασμού στον κατάλογο display_name: Όνομα εμφάνισης email: Διεύθυνση email expires_in: Λήξη μετά από @@ -136,7 +177,6 @@ el: inbox_url: Το URL του inbox του ανταποκριτή (relay) irreversible: Απόρριψη αντί για κρύψιμο locale: Γλώσσα χρήσης - locked: Κλείδωμα λογαριασμού max_uses: Μέγιστος αριθμός χρήσεων new_password: Νέο συνθηματικό note: Βιογραφικό @@ -148,7 +188,6 @@ el: setting_always_send_emails: Πάντα να αποστέλλονται ειδοποίησεις μέσω email setting_auto_play_gif: Αυτόματη αναπαραγωγή των GIF setting_boost_modal: Επιβεβαίωση πριν την προώθηση - setting_crop_images: Περιορισμός των εικόνων σε μη-ανεπτυγμένα τουτ σε αναλογία 16x9 setting_default_language: Γλώσσα δημοσιεύσεων setting_default_privacy: Ιδιωτικότητα δημοσιεύσεων setting_default_sensitive: Σημείωση όλων των πολυμέσων ως ευαίσθητου περιεχομένου @@ -160,9 +199,7 @@ el: setting_display_media_show_all: Εμφάνιση όλων setting_expand_spoilers: Μόνιμη ανάπτυξη των τουτ με προειδοποίηση περιεχομένου setting_hide_network: Κρύψε τις διασυνδέσεις σου - setting_noindex: Επέλεξε να μην συμμετέχεις στα αποτελέσματα μηχανών αναζήτησης setting_reduce_motion: Μείωση κίνησης κινουμένων στοιχείων - setting_show_application: Αποκάλυψη εφαρμογής που χρησιμοποιήθηκε για την αποστολή των τουτ setting_system_font_ui: Χρήση της προεπιλεγμένης γραμματοσειράς του συστήματος setting_theme: Θέμα ιστότοπου setting_trends: Εμφάνιση σημερινών τάσεων @@ -185,11 +222,32 @@ el: hide: Πλήρης απόκρυψη warn: Απόκρυψη με προειδοποίηση form_admin_settings: + activity_api_enabled: Δημοσίευση συγκεντρωτικών στατιστικών σχετικά με τη δραστηριότητα του χρήστη στο API + backups_retention_period: Περίοδος αρχειοθέτησης του χρήστη + bootstrap_timeline_accounts: Πρότεινε πάντα αυτούς τους λογαριασμούς σε νέους χρήστες + closed_registrations_message: Προσαρμοσμένο μήνυμα όταν οι εγγραφές δεν είναι διαθέσιμες + content_cache_retention_period: Περίοδος διατήρησης προσωρινής μνήμης περιεχομένου custom_css: Προσαρμοσμένο CSS + mascot: Προσαρμοσμένη μασκότ (απαρχαιωμένο) + media_cache_retention_period: Περίοδος διατήρησης προσωρινής μνήμης πολυμέσων + peers_api_enabled: Δημοσίευση λίστας των εντοπισμένων διακομιστών στο API + profile_directory: Ενεργοποίηση καταλόγου προφίλ registrations_mode: Ποιος μπορεί να εγγραφεί + require_invite_text: Απαίτησε έναν λόγο για να γίνει κάποιος μέλος + show_domain_blocks: Εμφάνιση αποκλεισμένων τομέων + show_domain_blocks_rationale: Εμφάνιση γιατί αποκλείστηκαν οι τομείς site_contact_email: E-mail επικοινωνίας site_contact_username: Όνομα χρήστη επικοινωνίας + site_extended_description: Εκτεταμένη περιγραφή + site_short_description: Περιγραφή διακομιστή + site_terms: Πολιτική Απορρήτου + site_title: Όνομα διακομιστή status_page_url: URL σελίδας κατάστασης + theme: Προεπιλεγμένο θέμα + thumbnail: Μικρογραφία διακομιστή + timeline_preview: Να επιτρέπεται μη πιστοποιημένη πρόσβαση σε δημόσια χρονολόγια + trendable_by_default: Επίτρεψε τις τάσεις χωρίς προηγούμενη αξιολόγηση + trends: Ενεργοποίηση τάσεων trends_as_landing_page: Χρήση των τάσεων ως σελίδα προορισμού interactions: must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν σε ακολουθούν @@ -208,6 +266,7 @@ el: sign_up_requires_approval: Περιορισμός εγγραφών severity: Κανόνας notification_emails: + appeal: Κάποιος κάνει έφεση σε απόφαση συντονιστή digest: Αποστολή συνοπτικών email favourite: Αποστολή email όταν κάποιος σημειώνει ως αγαπημένη τη δημοσίευσή σου follow: Αποστολή email όταν κάποιος σε ακολουθεί @@ -215,6 +274,8 @@ el: mention: Αποστολή email όταν κάποιος σε αναφέρει pending_account: Αποστολή email όταν υπάρχει νέος λογαριασμός για επιθεώρηση reblog: Αποστολή email όταν κάποιος προωθεί τη δημοσίευση σου + report: Υποβλήθηκε νέα αναφορά + trending_tag: Νέο περιεχόμενο προς τάση απαιτεί αξιολόγηση rule: text: Κανόνας tag: @@ -224,7 +285,17 @@ el: usable: Χρήση της ετικέτας σε τουτ user: role: Ρόλος + user_role: + color: Χρώμα εμβλήματος + highlighted: Εμφάνιση ρόλου ως σήμα στα προφίλ χρηστών + name: Όνομα + permissions_as_keys: Δικαιώματα + position: Προτεραιότητα + webhook: + events: Ενεργοποιημένα συμβάντα + url: Endpoint URL 'no': Όχι + not_recommended: Δεν προτείνεται recommended: Προτείνεται required: mark: "*" diff --git a/config/locales/simple_form.en-GB.yml b/config/locales/simple_form.en-GB.yml index 27aa80c426..f0c18d1128 100644 --- a/config/locales/simple_form.en-GB.yml +++ b/config/locales/simple_form.en-GB.yml @@ -2,6 +2,14 @@ en-GB: simple_form: hints: + account: + discoverable: Your public posts and profile may be featured or recommended in various areas of Mastodon and your profile may be suggested to other users. + display_name: Your full name or your fun name. + fields: Your homepage, pronouns, age, anything you want. + indexable: Your public posts may appear in search results on Mastodon. People who have interacted with your posts may be able to search them regardless. + note: 'You can @mention other people or #hashtags.' + show_collections: People will be able to browse through your follows and followers. People that you follow will see that you follow them regardless. + unlocked: People will be able to follow you without requesting approval. Uncheck if you want to review follow requests and chose whether to accept or reject new followers. account_alias: acct: Specify the username@domain of the account you want to move from account_migration: @@ -37,14 +45,11 @@ en-GB: current_password: For security purposes please enter the password of the current account current_username: To confirm, please enter the username of the current account digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence - discoverable: Allow your account to be discovered by strangers through recommendations, trends and other features email: You will be sent a confirmation e-mail - fields: You can have up to 4 items displayed as a table on your profile header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px inbox_url: Copy the URL from the frontpage of the relay you want to use irreversible: Filtered posts will disappear irreversibly, even if filter is later removed locale: The language of the user interface, e-mails and push notifications - locked: Manually control who can follow you by approving follow requests password: Use at least 8 characters phrase: Will be matched regardless of casing in text or content warning of a post scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones. @@ -54,12 +59,9 @@ en-GB: setting_display_media_default: Hide media marked as sensitive setting_display_media_hide_all: Always hide media setting_display_media_show_all: Always show media - setting_hide_network: Who you follow and who follows you will be hidden on your profile - setting_noindex: Affects your public profile and post pages - setting_show_application: The application you use to post will be displayed in the detailed view of your posts setting_use_blurhash: Gradients are based on the colors of the hidden visuals but obfuscate any details setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed - username: Your username will be unique on %{domain} + username: You can use letters, numbers, and underscores whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word domain_allow: domain: This domain will be able to fetch data from this server and incoming data from it will be processed and stored @@ -118,6 +120,9 @@ en-GB: sessions: otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:' webauthn: If it's an USB key be sure to insert it and, if necessary, tap it. + settings: + indexable: Your profile page may appear in search results on Google, Bing, and others. + show_application: You will always be able to see which app published your post regardless. tag: name: You can only change the casing of the letters, for example, to make it more readable user: @@ -131,12 +136,17 @@ en-GB: position: Higher role decides conflict resolution in certain situations. Certain actions can only be performed on roles with a lower priority webhook: events: Select events to send + template: Compose your own JSON payload using variable interpolation. Leave blank for default JSON. url: Where events will be sent to labels: account: + discoverable: Feature profile and posts in discovery algorithms fields: name: Label value: Content + indexable: Include public posts in search results + show_collections: Show follows and followers on profile + unlocked: Automatically accept new followers account_alias: acct: Handle of the old account account_migration: @@ -174,7 +184,6 @@ en-GB: context: Filter contexts current_password: Current password data: Data - discoverable: Suggest account to others display_name: Display name email: E-mail address expires_in: Expire after @@ -184,7 +193,6 @@ en-GB: inbox_url: URL of the relay inbox irreversible: Drop instead of hide locale: Interface language - locked: Require follow requests max_uses: Max number of uses new_password: New password note: Bio @@ -196,7 +204,6 @@ en-GB: setting_always_send_emails: Always send e-mail notifications setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialogue before boosting - setting_crop_images: Crop images in non-expanded posts to 16x9 setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_sensitive: Always mark media as sensitive @@ -208,9 +215,7 @@ en-GB: setting_display_media_show_all: Show all setting_expand_spoilers: Always expand posts marked with content warnings setting_hide_network: Hide your social graph - setting_noindex: Opt-out of search engine indexing setting_reduce_motion: Reduce motion in animations - setting_show_application: Disclose application used to send posts setting_system_font_ui: Use system's default font setting_theme: Site theme setting_trends: Show today's trends @@ -286,9 +291,18 @@ en-GB: pending_account: New account needs review reblog: Someone boosted your post report: New report is submitted + software_updates: + all: Notify on all updates + critical: Notify on critical updates only + label: A new Mastodon version is available + none: Never notify of updates (not recommended) + patch: Notify on bugfix updates trending_tag: New trend requires review rule: text: Rule + settings: + indexable: Include profile page in search engines + show_application: Display from which app you sent a post tag: listable: Allow this hashtag to appear in searches and suggestions name: Hashtag @@ -296,6 +310,7 @@ en-GB: usable: Allow posts to use this hashtag user: role: Role + time_zone: Time Zone user_role: color: Badge colour highlighted: Display role as badge on user profiles @@ -304,14 +319,16 @@ en-GB: position: Priority webhook: events: Enabled events + template: Payload template url: Endpoint URL 'no': 'No' not_recommended: Not recommended + overridden: Overridden recommended: Recommended required: mark: "*" text: required title: sessions: - webauthn: Use one of your security keys to sign in + webauthn: Use one of your security keys to log in 'yes': 'Yes' diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 96b0131efe..0b718c5b65 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -2,6 +2,14 @@ en: simple_form: hints: + account: + discoverable: Your public posts and profile may be featured or recommended in various areas of Mastodon and your profile may be suggested to other users. + display_name: Your full name or your fun name. + fields: Your homepage, pronouns, age, anything you want. + indexable: Your public posts may appear in search results on Mastodon. People who have interacted with your posts may be able to search them regardless. + note: 'You can @mention other people or #hashtags.' + show_collections: People will be able to browse through your follows and followers. People that you follow will see that you follow them regardless. + unlocked: People will be able to follow you without requesting approval. Uncheck if you want to review follow requests and chose whether to accept or reject new followers. account_alias: acct: Specify the username@domain of the account you want to move from account_migration: @@ -37,14 +45,11 @@ en: current_password: For security purposes please enter the password of the current account current_username: To confirm, please enter the username of the current account digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence - discoverable: Allow your account to be discovered by strangers through recommendations, trends and other features email: You will be sent a confirmation e-mail - fields: You can have up to 4 items displayed as a table on your profile header: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px inbox_url: Copy the URL from the frontpage of the relay you want to use irreversible: Filtered posts will disappear irreversibly, even if filter is later removed locale: The language of the user interface, e-mails and push notifications - locked: Manually control who can follow you by approving follow requests password: Use at least 8 characters phrase: Will be matched regardless of casing in text or content warning of a post scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones. @@ -54,12 +59,9 @@ en: setting_display_media_default: Hide media marked as sensitive setting_display_media_hide_all: Always hide media setting_display_media_show_all: Always show media - setting_hide_network: Who you follow and who follows you will be hidden on your profile - setting_noindex: Affects your public profile and post pages - setting_show_application: The application you use to post will be displayed in the detailed view of your posts setting_use_blurhash: Gradients are based on the colors of the hidden visuals but obfuscate any details setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed - username: Your username will be unique on %{domain} + username: You can use letters, numbers, and underscores whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word domain_allow: domain: This domain will be able to fetch data from this server and incoming data from it will be processed and stored @@ -78,7 +80,7 @@ en: backups_retention_period: Keep generated user archives for 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: Posts from other servers will be deleted after the specified number of days when set to a positive value. This may be irreversible. + content_cache_retention_period: All posts and boosts from other servers will be deleted after the specified number of days. Some posts may not be recoverable. All related bookmarks, favourites and boosts will also be lost and impossible to undo. custom_css: You can apply custom styles on the web version of Mastodon. mascot: Overrides the illustration in the advanced web interface. media_cache_retention_period: Downloaded media files will be deleted after the specified number of days when set to a positive value, and re-downloaded on demand. @@ -118,6 +120,9 @@ en: sessions: otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:' webauthn: If it's an USB key be sure to insert it and, if necessary, tap it. + settings: + indexable: Your profile page may appear in search results on Google, Bing, and others. + show_application: You will always be able to see which app published your post regardless. tag: name: You can only change the casing of the letters, for example, to make it more readable user: @@ -131,12 +136,17 @@ en: position: Higher role decides conflict resolution in certain situations. Certain actions can only be performed on roles with a lower priority webhook: events: Select events to send + template: Compose your own JSON payload using variable interpolation. Leave blank for default JSON. url: Where events will be sent to labels: account: + discoverable: Feature profile and posts in discovery algorithms fields: name: Label value: Content + indexable: Include public posts in search results + show_collections: Show follows and followers on profile + unlocked: Automatically accept new followers account_alias: acct: Handle of the old account account_migration: @@ -166,25 +176,23 @@ en: text: Explain why this decision should be reversed defaults: autofollow: Invite to follow your account - avatar: Avatar - bot: This is a bot account + avatar: Profile picture + bot: This is an automated account chosen_languages: Filter languages confirm_new_password: Confirm new password confirm_password: Confirm password context: Filter contexts current_password: Current password data: Data - discoverable: Suggest account to others display_name: Display name email: E-mail address expires_in: Expire after - fields: Profile metadata - header: Header + fields: Extra fields + header: Header picture honeypot: "%{label} (do not fill in)" inbox_url: URL of the relay inbox irreversible: Drop instead of hide locale: Interface language - locked: Require follow requests max_uses: Max number of uses new_password: New password note: Bio @@ -196,7 +204,6 @@ en: setting_always_send_emails: Always send e-mail notifications setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before boosting - setting_crop_images: Crop images in non-expanded posts to 16x9 setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_sensitive: Always mark media as sensitive @@ -208,9 +215,7 @@ en: setting_display_media_show_all: Show all setting_expand_spoilers: Always expand posts marked with content warnings setting_hide_network: Hide your social graph - setting_noindex: Opt-out of search engine indexing setting_reduce_motion: Reduce motion in animations - setting_show_application: Disclose application used to send posts setting_system_font_ui: Use system's default font setting_theme: Site theme setting_trends: Show today's trends @@ -286,9 +291,18 @@ en: pending_account: New account needs review reblog: Someone boosted your post report: New report is submitted + software_updates: + all: Notify on all updates + critical: Notify on critical updates only + label: A new Mastodon version is available + none: Never notify of updates (not recommended) + patch: Notify on bugfix updates trending_tag: New trend requires review rule: text: Rule + settings: + indexable: Include profile page in search engines + show_application: Display from which app you sent a post tag: listable: Allow this hashtag to appear in searches and suggestions name: Hashtag @@ -296,6 +310,7 @@ en: usable: Allow posts to use this hashtag user: role: Role + time_zone: Time zone user_role: color: Badge color highlighted: Display role as badge on user profiles @@ -304,9 +319,11 @@ en: position: Priority webhook: events: Enabled events + template: Payload template url: Endpoint URL 'no': 'No' not_recommended: Not recommended + overridden: Overridden recommended: Recommended required: mark: "*" diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml index d54248de08..3504b39537 100644 --- a/config/locales/simple_form.eo.yml +++ b/config/locales/simple_form.eo.yml @@ -2,6 +2,12 @@ eo: simple_form: hints: + account: + discoverable: Viaj publikaj afiŝoj kaj profilo povas esti prezentitaj aŭ rekomenditaj en diversaj lokoj de Mastodon kaj via profilo povas esti proponita al aliaj uzantoj. + display_name: Via plena nomo aŭ via kromnomo. + fields: Via retpaĝo, pronomoj, aĝo, ĉio, kion vi volas. + indexable: Viaj publikaj afiŝoj povas aperi en serĉrezultoj ĉe Mastodon. Homoj, kiuj interagis kun viaj afiŝoj, eble povos serĉi ilin sendepende. + note: 'Vi povas @mencii aliajn homojn aŭ #haŝetikedoj.' account_alias: acct: Specifu la uzantnomon@domajnon de la konto el kiu vi volas translokiĝi account_migration: @@ -37,14 +43,11 @@ eo: current_password: Pro sekuraj kialoj, bonvolu enigi la pasvorton de la nuna konto current_username: Por konfirmi, bonvolu enigi la uzantnomon de la nuna konto digest: Sendita nur post longa tempo de neaktiveco, kaj nur se vi ricevis personan mesaĝon en via foresto - discoverable: Permesi vian konton esti malkovrita de fremduloj per rekomendoj, tendencoj kaj aliaj funkcioj email: Vi ricevos konfirman retpoŝton - fields: Vi povas havi ĝis 4 tabelajn elementojn en via profilo header: Formato PNG, GIF aŭ JPG. Ĝis %{size}. Estos malgrandigita al %{dimensions}px inbox_url: Kopiu la URL de la ĉefpaĝo de la ripetilo, kiun vi volas uzi irreversible: La filtritaj mesaĝoj malaperos por eterne, eĉ se la filtrilo poste estas forigita locale: La lingvo de la fasado, retpoŝtaĵoj, kaj sciigoj - locked: Vi devos aprobi ĉiun peton de sekvado mane password: Uzu almenaŭ 8 signojn phrase: Estos provita senzorge pri la uskleco de teksto aŭ averto pri enhavo de mesaĝo scopes: Kiujn API-ojn la aplikaĵo permesiĝos atingi. Se vi elektas supran amplekson, vi ne bezonas elekti la individuajn. @@ -54,12 +57,9 @@ eo: setting_display_media_default: Kaŝi plurmediojn markitajn kiel tiklaj setting_display_media_hide_all: Ĉiam kaŝi la plurmediojn setting_display_media_show_all: Ĉiam montri la plurmediojn - setting_hide_network: Tiuj kiujn vi sekvas, kaj tiuj kiuj sekvas vin estos kaŝitaj en via profilo - setting_noindex: Influas vian publikan profilon kaj afiŝajn paĝojn - setting_show_application: La aplikaĵo, kiun vi uzas por afiŝi, estos montrita en la detala vido de viaj afiŝoj setting_use_blurhash: Transirojn estas bazita sur la koloroj de la kaŝitaj aŭdovidaĵoj sed ne montri iun ajn detalon setting_use_pending_items: Kaŝi tempoliniajn ĝisdatigojn malantaŭ klako anstataŭ aŭtomate rulumi la fluon - username: Via uzantnomo estos unika en %{domain} + username: Vi povas uzi literojn, ciferojn kaj substrekojn whole_word: Kiam la vorto aŭ frazo estas nur litera aŭ cifera, ĝi estos uzata nur se ĝi kongruas kun la tuta vorto domain_allow: domain: Ĉi tiu domajno povos akiri datumon de ĉi tiu servilo kaj envenanta datumo estos prilaborita kaj konservita @@ -131,6 +131,7 @@ eo: position: Pli altaj rolo decidas konfliktosolvo en kelkaj situacioj webhook: events: Elektu eventojn por sendi + template: Skribu vian propran JSON-ŝarĝon per varia interpolado. Lasu malplenan por defaŭlta JSON. url: Kien eventoj sendotas labels: account: @@ -174,7 +175,6 @@ eo: context: Filtri kuntekstojn current_password: Nuna pasvorto data: Datumoj - discoverable: Montri ĉi tiun konton en la profilujo display_name: Publika nomo email: Retadreso expires_in: Eksvalidiĝas post @@ -184,7 +184,6 @@ eo: inbox_url: URL de la ripetila enirkesto irreversible: Forĵeti anstataŭ kaŝi locale: Lingvo de la fasado - locked: Ŝlosi konton max_uses: Maksimuma nombro de uzoj new_password: Nova pasvorto note: Sinprezento @@ -196,7 +195,6 @@ eo: setting_always_send_emails: Ĉiam sendi la sciigojn per retpoŝto setting_auto_play_gif: Aŭtomate ekigi GIF-ojn setting_boost_modal: Montri konfirman fenestron antaŭ ol diskonigi mesaĝon - setting_crop_images: Stuci bildojn en negrandigitaj mesaĝoj al 16x9 setting_default_language: Publikada lingvo setting_default_privacy: Privateco de afiŝado setting_default_sensitive: Ĉiam marki plurmediojn kiel tiklaj @@ -208,9 +206,7 @@ eo: setting_display_media_show_all: Montri ĉiujn setting_expand_spoilers: Ĉiam malfoldas mesaĝojn markitajn per averto pri enhavo setting_hide_network: Kaŝi viajn sekvantojn kaj sekvatojn - setting_noindex: Ellistiĝi de retserĉila indeksado setting_reduce_motion: Redukti la movecojn de la animacioj - setting_show_application: Publikigi la aplikaĵon uzatan por sendi mesaĝojn setting_system_font_ui: Uzi la dekomencan tiparon de la sistemo setting_theme: Etoso de la retejo setting_trends: Montri hodiaŭajn furoraĵojn @@ -296,6 +292,7 @@ eo: usable: Permesi mesaĝojn uzi ĉi tiun kradvorton user: role: Rolo + time_zone: Horzono user_role: color: Koloro de ŝildo highlighted: Montri rolon kiel insignon sur uzantoprofiloj @@ -304,6 +301,7 @@ eo: position: Prioritato webhook: events: Ŝaltitaj eventoj + template: Utilŝarĝa ŝablono url: Finpunkto-URL 'no': Ne not_recommended: Nerekomendita diff --git a/config/locales/simple_form.es-AR.yml b/config/locales/simple_form.es-AR.yml index bcceccfb18..9b52ece34e 100644 --- a/config/locales/simple_form.es-AR.yml +++ b/config/locales/simple_form.es-AR.yml @@ -2,6 +2,14 @@ es-AR: simple_form: hints: + account: + discoverable: Tu perfil y publicaciones pueden ser destacadas o recomendadas en varias áreas de Mastodon, y tu perfil puede ser sugerido a otros usuarios. + display_name: Tu nombre completo o tu pseudónimo. + fields: Tu sitio web, pronombres, edad, o lo que quieras. + indexable: Tus mensajes públicos pueden aparecer en los resultados de la búsqueda en Mastodon. La gente que interactuó con tus mensajes puede ser capaz de buscarlos sin importar el momento. + note: 'Podés @mencionar otras cuentas o usar #etiquetas.' + show_collections: La gente podrá navegar a través de tus seguidos y seguidores. Sin embargo, la gente que sigás, sabrá que lo estás haciendo. + unlocked: La gente podrá seguirte sin solicitar aprobación. Desmarcá si querés revisar las solicitudes de seguimiento y elegir si aceptar o rechazar nuevos seguidores. account_alias: acct: Especificá el nombredeusuario@dominio de la cuenta desde la que querés mudarte account_migration: @@ -37,14 +45,11 @@ es-AR: current_password: Por razones de seguridad, por favor, ingresá la contraseña de la cuenta actual current_username: Para confirmar, por favor, ingresá el nombre de usuario de la cuenta actual digest: Sólo enviado tras un largo periodo de inactividad, y sólo si recibiste mensajes personales en tu ausencia - discoverable: Permití que tu cuenta sea descubierta por extraños a través de recomendaciones, tendencias y otras funciones email: Se te enviará un correo electrónico de confirmación - fields: Podés tener hasta 4 elementos mostrados en una tabla en tu perfil header: 'PNG, GIF o JPG. Máximo: %{size}. Será subescalado a %{dimensions} píxeles.' inbox_url: Copiá la dirección web desde la página principal del relé que querés usar irreversible: Los mensajes filtrados desaparecerán irreversiblemente, incluso si este filtro es eliminado después locale: El idioma de la interface de usuario, correos electrónicos y notificaciones push - locked: Controlá manualmente quién puede seguirte al aprobar solicitudes de seguimiento password: Usá al menos 8 caracteres phrase: Se aplicará sin importar las mayúsculas o las advertencias de contenido de un mensaje scopes: Qué APIs de la aplicación tendrán acceso. Si seleccionás el alcance de nivel más alto, no necesitás seleccionar las individuales. @@ -54,12 +59,9 @@ es-AR: setting_display_media_default: Ocultar medios marcados como sensibles setting_display_media_hide_all: Siempre ocultar todos los medios setting_display_media_show_all: Siempre mostrar todos los medios - setting_hide_network: Las cuentas que seguís y tus seguidores serán ocultados en tu perfil - setting_noindex: Afecta a tu perfil público y páginas de mensajes - setting_show_application: La aplicación que usás para enviar mensajes se mostrará en la vista detallada de tus mensajes setting_use_blurhash: Los gradientes se basan en los colores de las imágenes ocultas pero haciendo borrosos los detalles setting_use_pending_items: Ocultar actualizaciones de la línea temporal detrás de un clic en lugar de desplazar automáticamente el flujo - username: Tu nombre de usuario será único en %{domain} + username: Podés usar letras, números y subguiones ("_") whole_word: Cuando la palabra clave o frase es sólo alfanumérica, sólo será aplicado si coincide con toda la palabra domain_allow: domain: Este dominio podrá recolectar datos de este servidor, y los datos entrantes serán procesados y archivados @@ -78,7 +80,7 @@ es-AR: backups_retention_period: Conservar los archivos historiales generados por el usuario durante el número de días especificado. bootstrap_timeline_accounts: Estas cuentas serán fijadas a la parte superior de las recomendaciones de cuentas a seguir para nuevos usuarios. closed_registrations_message: Mostrado cuando los registros están cerrados - content_cache_retention_period: Los mensajes de otros servidores se eliminarán después del número especificado de días cuando se establezca un valor positivo. Esto puede ser irreversible. + content_cache_retention_period: Todos los mensajes y adhesiones de otros servidores se eliminarán después del número especificado de días. Es posible que algunos mensajes no sean recuperables. Todos los marcadores relacionados, mensajes marcados como favoritos y adhesiones también se perderán y será imposible de deshacer. custom_css: Podés aplicar estilos personalizados a la versión web de Mastodon. mascot: Reemplaza la ilustración en la interface web avanzada. media_cache_retention_period: Los archivos de medios descargados se eliminarán después del número especificado de días cuando se establezca un valor positivo, y se volverán a descargar a pedido. @@ -118,6 +120,9 @@ es-AR: sessions: otp: 'Ingresá el código de autenticación de dos factores generado por la aplicación en tu dispositivo, o usá uno de tus códigos de recuperación:' webauthn: Si es una llave USB, asegurate de insertarla y, de ser necesario, tocarla. + settings: + indexable: Tu página de perfil podría aparecer en los resultados de búsqueda en Google, Bing y otros motores de búsqueda. + show_application: Sin embargo, siempre podrás ver desde qué aplicación se envió tu mensaje. tag: name: Sólo podés cambiar la capitalización de las letras, por ejemplo, para que sea más legible user: @@ -131,12 +136,17 @@ es-AR: position: Un rol más alto decide la resolución de conflictos en ciertas situaciones. Ciertas acciones sólo pueden llevarse a cabo en roles con prioridad inferior webhook: events: Seleccionar eventos para enviar + template: Creá tu propio archivo JSON usando interpolación variable. Dejalo en blanco para usar el archivo JSON predeterminado. url: Adónde serán enviados los eventos labels: account: + discoverable: Destacar perfil y mensajes en algoritmos de descubrimiento fields: name: Nombre de campo value: Valor de campo + indexable: Incluir mensajes públicos en los resultados de la búsqueda + show_collections: Mostrar seguidos y seguidores en el perfil + unlocked: Automáticamente aceptar nuevos seguidores account_alias: acct: Alias de la cuenta antigua account_migration: @@ -152,7 +162,7 @@ es-AR: types: disable: Congelar none: Enviar una advertencia - sensitive: Sensible + sensitive: Marcar como sensible silence: Limitar suspend: Suspender warning_preset_id: Usar una advertencia preestablecida @@ -167,24 +177,22 @@ es-AR: defaults: autofollow: Invitar para seguir tu cuenta avatar: Avatar - bot: Esta es una cuenta bot + bot: Esta es una cuenta automatizada chosen_languages: Filtrar idiomas confirm_new_password: Confirmar nueva contraseña confirm_password: Confirmar contraseña context: Filtrar contextos current_password: Contraseña actual data: Datos - discoverable: Sugerir cuenta a otros display_name: Nombre para mostrar email: Dirección de correo electrónico expires_in: Vence después de - fields: Metadatos de perfil + fields: Campos extras header: Cabecera honeypot: "%{label} (no rellenar)" inbox_url: Dirección web de la bandeja de entrada del relé irreversible: Dejar en lugar de ocultar locale: Idioma de la interface - locked: Requerir solicitudes de seguimiento max_uses: Número máximo de usos new_password: Nueva contraseña note: Biografía @@ -196,7 +204,6 @@ es-AR: setting_always_send_emails: Siempre enviar notificaciones por correo electrónico setting_auto_play_gif: Reproducir automáticamente los GIFs animados setting_boost_modal: Mostrar diálogo de confirmación antes de adherir - setting_crop_images: Recortar imágenes en mensajes no expandidos a 16x9 setting_default_language: Idioma de tus mensajes setting_default_privacy: Privacidad de mensajes setting_default_sensitive: Siempre marcar medios como sensibles @@ -208,9 +215,7 @@ es-AR: setting_display_media_show_all: Mostrar todo setting_expand_spoilers: Siempre expandir los mensajes marcados con advertencias de contenido setting_hide_network: Ocultá tu gráfica social - setting_noindex: Excluirse del indexado de motores de búsqueda setting_reduce_motion: Reducir el movimiento de las animaciones - setting_show_application: Mostrar aplicación usada para enviar mensajes setting_system_font_ui: Utilizar la tipografía predeterminada del sistema setting_theme: Tema del sitio setting_trends: Mostrar las tendencias de hoy @@ -286,9 +291,18 @@ es-AR: pending_account: Una nueva cuenta necesita revisión reblog: Una cuenta adhiere a tu mensaje report: Se envió una nueva denuncia + software_updates: + all: Notificar en todas las actualizaciones + critical: Notificar solamente sobre actualizaciones críticas + label: Una nueva versión de Mastodon está disponible + none: Nunca notificar sobre actualizaciones (no recomendado) + patch: Notificar sobre actualizaciones de corrección de errores trending_tag: Una nueva tendencia requiere revisión rule: text: Regla + settings: + indexable: Incluir la página de perfil en los motores de búsqueda + show_application: Mostrar desde qué aplicación enviaste un mensaje tag: listable: Permitir que esta etiqueta aparezca en las búsquedas y en las sugerencias name: Etiqueta @@ -296,6 +310,7 @@ es-AR: usable: Permitir a los mensajes usar esta etiqueta user: role: Rol + time_zone: Zona horaria user_role: color: Color de Insignia highlighted: Mostrar rol como insignia en perfiles de usuario @@ -304,9 +319,11 @@ es-AR: position: Prioridad webhook: events: Eventos habilitados + template: Plantilla de carga url: Dirección web del punto final 'no': 'No' not_recommended: No recomendado + overridden: Sobrescrito recommended: Opción recomendada required: mark: "*" diff --git a/config/locales/simple_form.es-MX.yml b/config/locales/simple_form.es-MX.yml index 52d8974f2e..932ed6c59a 100644 --- a/config/locales/simple_form.es-MX.yml +++ b/config/locales/simple_form.es-MX.yml @@ -2,6 +2,14 @@ es-MX: simple_form: hints: + account: + discoverable: Tu perfil y las publicaciones públicas pueden ser destacadas o recomendadas en varias áreas de Mastodon y tu perfil puede ser sugerido a otros usuarios. + display_name: Tu nombre completo o tu nick. + fields: Tu página de inicio, pronombres, edad, todo lo que quieras. + indexable: Tus publicaciones públicas pueden aparecer en los resultados de búsqueda en Mastodon. Las personas que han interactuado con tus publicaciones pueden buscarlas en cualquier momento. + note: 'Puedes @mencionar a otra gente o #hashtags.' + show_collections: Las personas pueden navegar a través de tus seguidos y seguidores. Las personas que te siguen pueden ver que las sigues. + unlocked: Las personas pueden seguirte sin solicitar la aprobación. No lo selecciones si quieres revisar las solicitudes de seguimiento y elegir si aceptas o rechazas a nuevos seguidores. account_alias: acct: Especifique el nombre de usuario@dominio de la cuenta desde la cual se desea migrar account_migration: @@ -37,14 +45,11 @@ es-MX: current_password: Por razones de seguridad por favor ingrese la contraseña de la cuenta actual current_username: Para confirmar, por favor ingrese el nombre de usuario de la cuenta actual digest: Solo enviado tras un largo periodo de inactividad y solo si has recibido mensajes personales durante tu ausencia - discoverable: Permite que tu cuenta sea descubierta por extraños a través de recomendaciones, tendencias y otras características email: Se le enviará un correo de confirmación - fields: Puedes tener hasta 4 elementos mostrándose como una tabla en tu perfil header: PNG, GIF o JPG. Máximo %{size}. Será escalado a %{dimensions}px inbox_url: Copia la URL de la página principal del relés que quieres utilizar irreversible: Los toots filtrados desaparecerán irreversiblemente, incluso si este filtro es eliminado más adelante locale: El idioma de la interfaz de usuario, correos y notificaciones push - locked: Requiere que manualmente apruebes seguidores y las publicaciones serán mostradas solamente a tus seguidores password: Utilice al menos 8 caracteres phrase: Se aplicará sin importar las mayúsculas o los avisos de contenido de un toot scopes: Qué APIs de la aplicación tendrán acceso. Si seleccionas el alcance de nivel mas alto, no necesitas seleccionar las individuales. @@ -54,12 +59,9 @@ es-MX: setting_display_media_default: Ocultar contenido multimedia marcado como sensible setting_display_media_hide_all: Siempre ocultar todo el contenido multimedia setting_display_media_show_all: Mostrar siempre contenido multimedia marcado como sensible - setting_hide_network: A quién sigues y quién te sigue no será mostrado en tu perfil - setting_noindex: Afecta a tu perfil público y páginas de estado - setting_show_application: La aplicación que utiliza usted para publicar toots se mostrará en la vista detallada de sus toots setting_use_blurhash: Los gradientes se basan en los colores de las imágenes ocultas pero haciendo borrosos los detalles setting_use_pending_items: Ocultar nuevos estados detrás de un clic en lugar de desplazar automáticamente el feed - username: Tu nombre de usuario será único en %{domain} + username: Puedes usar letras, números y guiones bajos whole_word: Cuando la palabra clave o frase es solo alfanumérica, solo será aplicado si concuerda con toda la palabra domain_allow: domain: Este dominio podrá obtener datos de este servidor y los datos entrantes serán procesados y archivados @@ -118,6 +120,9 @@ es-MX: sessions: otp: 'Introduce el código de autenticación de dos factores generado por tu aplicación de teléfono o usa uno de tus códigos de recuperación:' webauthn: Si es una tecla USB, asegúrese de insertarla y, si es necesario, púlsela. + settings: + indexable: Tu página de perfil puede aparecer en los resultados de búsqueda en Google, Bing, entre otros. + show_application: Siempre podrás ver desde cuál aplicación realizaste una publicación. tag: name: Sólo se puede cambiar el cajón de las letras, por ejemplo, para que sea más legible user: @@ -131,12 +136,17 @@ es-MX: position: Un rol superior decide la resolución de conflictos en ciertas situaciones. Ciertas acciones sólo pueden llevarse a cabo en roles con menor prioridad webhook: events: Seleccionar eventos para enviar + template: Crea tu propio JSON usando interpolación variable. Déjalo en blanco para el JSON predeterminado. url: Donde los eventos serán enviados labels: account: + discoverable: Destacar el perfil y las publicaciones en el algoritmo de descubrimiento fields: name: Etiqueta value: Contenido + indexable: Incluir publicaciones públicas en los resultados de búsqueda + show_collections: Mostrar los seguidos y seguidores en el perfil + unlocked: Aceptar automáticamente a nuevos seguidores account_alias: acct: Maneja la cuenta antigua account_migration: @@ -174,7 +184,6 @@ es-MX: context: Filtrar contextos current_password: Contraseña actual data: Información - discoverable: Listar esta cuenta en el directorio display_name: Nombre para mostrar email: Dirección de correo electrónico expires_in: Expirar tras @@ -184,7 +193,6 @@ es-MX: inbox_url: URL de la entrada de relés irreversible: Dejar en lugar de ocultar locale: Idioma - locked: Hacer privada esta cuenta max_uses: Máx. número de usos new_password: Nueva contraseña note: Biografía @@ -196,7 +204,6 @@ es-MX: setting_always_send_emails: Enviar siempre notificaciones por correo setting_auto_play_gif: Reproducir automáticamente los GIFs animados setting_boost_modal: Mostrar ventana de confirmación antes de un Retoot - setting_crop_images: Recortar a 16x9 las imágenes de los toots no expandidos setting_default_language: Idioma de publicación setting_default_privacy: Privacidad de publicaciones setting_default_sensitive: Marcar siempre imágenes como sensibles @@ -208,9 +215,7 @@ es-MX: setting_display_media_show_all: Mostrar todo setting_expand_spoilers: Siempre expandir los toots marcados con advertencias de contenido setting_hide_network: Ocultar tu red - setting_noindex: Excluirse del indexado de motores de búsqueda setting_reduce_motion: Reducir el movimiento de las animaciones - setting_show_application: Mostrar aplicación usada para publicar toots setting_system_font_ui: Utilizar la tipografía por defecto del sistema setting_theme: Tema del sitio setting_trends: Mostrar las tendencias de hoy @@ -286,9 +291,18 @@ es-MX: pending_account: Enviar correo electrónico cuando una nueva cuenta necesita revisión reblog: Enviar correo electrónico cuando alguien comparta su publicación report: Nuevo reporte enviado + software_updates: + all: Notificar en todas las actualizaciones + critical: Notificar solo en actualizaciones críticas + label: Una nueva versión de Mastodon está disponible + none: Nunca notificar actualizaciones (no recomendado) + patch: Notificar en actualizaciones de errores trending_tag: La nueva tendencia requiere de revisión rule: text: Norma + settings: + indexable: Incluir la página de perfil en los motores de búsqueda + show_application: Mostrar desde cuál aplicación enviaste una publicación tag: listable: Permitir que esta etiqueta aparezca en las búsquedas y en el directorio del perfil name: Etiqueta @@ -296,6 +310,7 @@ es-MX: usable: Permitir a los toots usar esta etiqueta user: role: Rol + time_zone: Zona horaria user_role: color: Color de insignia highlighted: Mostrar rol como insignia en perfiles de usuario @@ -304,9 +319,11 @@ es-MX: position: Prioridad webhook: events: Eventos habilitados + template: Plantilla de carga url: URL de Endpoint 'no': 'No' not_recommended: No recomendado + overridden: Reemplazado recommended: Recomendado required: mark: "*" diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml index fc8c332e08..997f09bf08 100644 --- a/config/locales/simple_form.es.yml +++ b/config/locales/simple_form.es.yml @@ -2,6 +2,14 @@ es: simple_form: hints: + account: + discoverable: Tu perfil y publicaciones públicas pueden ser destacadas o recomendadas en varias áreas de Mastodon y tu perfil puede ser sugerido a otros usuarios. + display_name: Tu nombre completo o tu apodo. + fields: Tu carta de presentación, pronombres, edad, lo que quieras. + indexable: Tus publicaciones públicas pueden aparecer en los resultados de búsqueda en Mastodon. Las personas que han interactuado con tus publicaciones pueden ser capaces de buscarlas sin importar su visibilidad. + note: Puedes mencionar a otras personas o etiquetas. + show_collections: Las personas podrán navegar a través de tus seguidos y seguidores. Esto no impide que las personas que sigues sepan que las estás siguiendo. + unlocked: Las personas podrán seguirte sin pedir aprobación. Desmarca si deseas revisar las solicitudes de seguimiento y aceptar o rechazar nuevos seguidores. account_alias: acct: Especifique su nombre de usuario@dominio de la cuenta de donde se desea migrar account_migration: @@ -37,29 +45,23 @@ es: current_password: Por razones de seguridad por favor ingrese la contraseña de la cuenta actual current_username: Para confirmar, por favor ingrese el nombre de usuario de la cuenta actual digest: Solo enviado tras un largo periodo de inactividad y solo si has recibido mensajes personales durante tu ausencia - discoverable: Permite que tu cuenta sea descubierta por extraños a través de recomendaciones, tendencias y otras características email: Se le enviará un correo de confirmación - fields: Puedes tener hasta 4 elementos mostrándose como una tabla en tu perfil header: PNG, GIF o JPG. Máximo %{size}. Será escalado a %{dimensions}px inbox_url: Copia la URL de la página principal del relés que quieres utilizar irreversible: Las publicaciones filtradas desaparecerán irreversiblemente, incluso si este filtro es eliminado más adelante locale: El idioma de la interfaz de usuario, correos y notificaciones push - locked: Requiere que manualmente apruebes seguidores y las publicaciones serán mostradas solamente a tus seguidores password: Utilice al menos 8 caracteres phrase: Se aplicará sin importar las mayúsculas o los avisos de contenido de una publicación scopes: Qué APIs de la aplicación tendrán acceso. Si seleccionas el alcance de nivel mas alto, no necesitas seleccionar las individuales. - setting_aggregate_reblogs: No mostrar nuevos retoots para las publicaciones que han sido recientemente retooteadas (sólo afecta a los retoots recibidos recientemente) + setting_aggregate_reblogs: No mostrar nuevos impulsos para las publicaciones que han sido recientemente impulsadas (sólo afecta a los impulsos recibidos recientemente) setting_always_send_emails: Normalmente las notificaciones por correo electrónico no se enviarán cuando estés usando Mastodon activamente setting_default_sensitive: El contenido multimedia sensible está oculto por defecto y puede ser mostrado con un click setting_display_media_default: Ocultar contenido multimedia marcado como sensible setting_display_media_hide_all: Siempre ocultar todo el contenido multimedia setting_display_media_show_all: Mostrar siempre contenido multimedia marcado como sensible - setting_hide_network: A quién sigues y quién te sigue no será mostrado en tu perfil - setting_noindex: Afecta a tu perfil público y páginas de estado - setting_show_application: La aplicación que utiliza usted para publicar publicaciones se mostrará en la vista detallada de sus publicaciones setting_use_blurhash: Los gradientes se basan en los colores de las imágenes ocultas pero haciendo borrosos los detalles - setting_use_pending_items: Ocultar nuevos estados detrás de un clic en lugar de desplazar automáticamente el feed - username: Tu nombre de usuario será único en %{domain} + setting_use_pending_items: Ocultar nuevas publicaciones detrás de un clic en lugar de desplazar automáticamente el feed + username: Puedes usar letras, números y guiones bajos whole_word: Cuando la palabra clave o frase es solo alfanumérica, solo será aplicado si concuerda con toda la palabra domain_allow: domain: Este dominio podrá obtener datos de este servidor y los datos entrantes serán procesados y archivados @@ -85,18 +87,19 @@ es: peers_api_enabled: Una lista de nombres de dominio que este servidor ha encontrado en el Fediverso. Aquí no se incluye ningún dato sobre si federas con un servidor determinado, solo que tu servidor lo conoce. Esto es utilizado por los servicios que recopilan estadísticas sobre la federación en un sentido general. profile_directory: El directorio de perfiles lista a todos los usuarios que han optado por que su cuenta pueda ser descubierta. require_invite_text: Cuando los registros requieren aprobación manual, hace obligatoria la entrada de texto "¿Por qué quieres unirte?" en lugar de opcional - site_contact_email: Cómo la gente puede ponerse en contacto contigo para consultas legales o de ayuda. - site_contact_username: Cómo puede contactarte la gente en Mastodon. + site_contact_email: Cómo pueden ponerse en contacto contigo para consultas legales o de ayuda. + site_contact_username: Cómo pueden contactarte en Mastodon. site_extended_description: Cualquier información adicional que pueda ser útil para los visitantes y sus usuarios. Se puede estructurar con formato Markdown. site_short_description: Una breve descripción para ayudar a identificar su servidor de forma única. ¿Quién lo administra, a quién va dirigido? site_terms: Utiliza tu propia política de privacidad o déjala en blanco para usar la predeterminada Puede estructurarse con formato Markdown. - site_title: Cómo puede referirse la gente a tu servidor además de por el nombre de dominio. - status_page_url: URL de la página donde la gente pueda ver el estado de este servidor durante la exclusión + site_title: Cómo pueden referirse a tu servidor además de por el nombre de dominio. + status_page_url: URL de una página donde se pueda ver el estado de este servidor durante una incidencia theme: El tema que los visitantes no registrados y los nuevos usuarios ven. thumbnail: Una imagen de aproximadamente 2:1 se muestra junto a la información de tu servidor. timeline_preview: Los visitantes no registrados podrán navegar por los mensajes públicos más recientes disponibles en el servidor. trendable_by_default: Omitir la revisión manual del contenido en tendencia. Los elementos individuales aún podrán eliminarse de las tendencias. trends: Las tendencias muestran qué mensajes, etiquetas y noticias están ganando tracción en tu servidor. + trends_as_landing_page: Mostrar contenido en tendencia para usuarios y visitantes en lugar de una descripción de este servidor. Requiere que las tendencias estén habilitadas. form_challenge: current_password: Estás entrando en un área segura imports: @@ -117,6 +120,9 @@ es: sessions: otp: 'Introduce el código de autenticación de dos factores generado por tu aplicación de teléfono o usa uno de tus códigos de recuperación:' webauthn: Si es una tecla USB, asegúrese de insertarla y, si es necesario, púlsela. + settings: + indexable: Puede que tu página de perfil aparezca en los resultados de búsqueda en Google, Bing y otros. + show_application: Tú siempre podrás ver desde qué aplicación se ha publicado tu publicación. tag: name: Sólo se puede cambiar el cajón de las letras, por ejemplo, para que sea más legible user: @@ -130,12 +136,17 @@ es: position: Un rol superior decide la resolución de conflictos en ciertas situaciones. Ciertas acciones sólo pueden llevarse a cabo en roles con menor prioridad webhook: events: Seleccionar eventos para enviar + template: Crea tu propio JSON usando interpolación variable. Déjalo en blanco para el JSON predeterminado. url: Donde los eventos serán enviados labels: account: + discoverable: Destacar perfil y publicaciones en algoritmos de descubrimiento fields: name: Etiqueta value: Contenido + indexable: Incluir publicaciones públicas en los resultados de búsqueda + show_collections: Mostrar seguidos y seguidores en el perfil + unlocked: Aceptar automáticamente nuevos seguidores account_alias: acct: Maneja la cuenta antigua account_migration: @@ -173,7 +184,6 @@ es: context: Filtrar contextos current_password: Contraseña actual data: Información - discoverable: Sugerir la cuenta a otros display_name: Nombre para mostrar email: Dirección de correo electrónico expires_in: Expirar tras @@ -183,7 +193,6 @@ es: inbox_url: URL de la entrada de relés irreversible: Rechazar en lugar de ocultar locale: Idioma - locked: Hacer privada esta cuenta max_uses: Máx. número de usos new_password: Nueva contraseña note: Biografía @@ -191,11 +200,10 @@ es: password: Contraseña phrase: Palabra clave o frase setting_advanced_layout: Habilitar interfaz web avanzada - setting_aggregate_reblogs: Agrupar retoots en las líneas de tiempo + setting_aggregate_reblogs: Agrupar impulsos en las líneas de tiempo setting_always_send_emails: Enviar siempre notificaciones por correo setting_auto_play_gif: Reproducir automáticamente los GIFs animados - setting_boost_modal: Mostrar ventana de confirmación antes de retootear - setting_crop_images: Recortar a 16x9 las imágenes de las publicaciones no expandidas + setting_boost_modal: Mostrar ventana de confirmación antes de impulsar setting_default_language: Idioma de publicación setting_default_privacy: Privacidad de publicaciones setting_default_sensitive: Marcar siempre imágenes como sensibles @@ -207,9 +215,7 @@ es: setting_display_media_show_all: Mostrar todo setting_expand_spoilers: Siempre expandir las publicaciones marcadas con advertencias de contenido setting_hide_network: Ocultar tu red - setting_noindex: Excluirse del indexado de motores de búsqueda setting_reduce_motion: Reducir el movimiento de las animaciones - setting_show_application: Mostrar aplicación usada para publicar publicaciones setting_system_font_ui: Utilizar la tipografía por defecto del sistema setting_theme: Tema del sitio setting_trends: Mostrar las tendencias de hoy @@ -252,15 +258,17 @@ es: site_short_description: Descripción del servidor site_terms: Política de Privacidad site_title: Nombre del servidor + status_page_url: URL de página de estado theme: Tema por defecto thumbnail: Miniatura del servidor timeline_preview: Permitir el acceso no autenticado a las líneas de tiempo públicas trendable_by_default: Permitir tendencias sin revisión previa trends: Habilitar tendencias + trends_as_landing_page: Usar tendencias como la página de inicio interactions: must_be_follower: Bloquear notificaciones de personas que no te siguen must_be_following: Bloquear notificaciones de personas que no sigues - must_be_following_dm: Bloquear mensajes directos de la gente que no sigues + must_be_following_dm: Bloquear mensajes directos de personas que no sigues invite: comment: Comentar invite_request: @@ -283,9 +291,18 @@ es: pending_account: Enviar correo electrónico cuando una nueva cuenta necesita revisión reblog: Enviar correo electrónico cuando alguien comparta su publicación report: Nuevo informe enviado + software_updates: + all: Notificar de cualquier actualización + critical: Notificar solo de actualizaciones críticas + label: Hay disponible una nueva versión de Mastodon + none: No notificar nunca de actualizaciones (no recomendado) + patch: Notificar de actualizaciones de errores trending_tag: Una nueva tendencia requiere revisión rule: text: Norma + settings: + indexable: Incluye la página de perfil en los buscadores + show_application: Mostrar desde qué aplicación enviaste una publicación tag: listable: Permitir que esta etiqueta aparezca en las búsquedas y en el directorio del perfil name: Etiqueta @@ -293,6 +310,7 @@ es: usable: Permitir a las publicaciones usar esta etiqueta user: role: Rol + time_zone: Zona horaria user_role: color: Color de insignia highlighted: Mostrar rol como insignia en perfiles de usuario @@ -301,9 +319,11 @@ es: position: Prioridad webhook: events: Eventos habilitados + template: Plantilla de carga url: URL de Endpoint 'no': 'No' not_recommended: No recomendado + overridden: Sobrescrito recommended: Recomendado required: mark: "*" diff --git a/config/locales/simple_form.et.yml b/config/locales/simple_form.et.yml index 8b7dace23c..b5a80da981 100644 --- a/config/locales/simple_form.et.yml +++ b/config/locales/simple_form.et.yml @@ -2,6 +2,14 @@ et: simple_form: hints: + account: + discoverable: Su profiili ja avalikke postitusi võidakse Mastodoni erinevates piirkondades esile tõsta või soovitada ning su profiili soovitada teistele kasutajatele. + display_name: Su täisnimi või naljanimi. + fields: Su koduleht, sugu, vanus. Mistahes, mida soovid. + indexable: Sinu avalikud postitused võivad ilmuda Mastodoni otsingutulemustes. Inimesed, kes on sinu postitustele reageerinud, saavad neid otsida nii või naa. + note: 'Saad @mainida teisi inimesi või #silte.' + show_collections: Inimesed saavad sirvida su jälgijaid ja jälgitavaid. Inimesed, keda sa jälgid, näevad seda sõltumata häälestuse valikust. + unlocked: Inimesed saavad sind jälgima hakata kinnitamist taotlemata. Eemalda märge, kui soovid jälgimistaotlusi üle vaadata ja valida, kas nõustuda või keelduda uute jälgijatega. account_alias: acct: Sisesta konto kasutajanimi@domeen, mille soovid siia ümber kolida account_migration: @@ -30,21 +38,18 @@ et: appeal: text: Otsust on võimalik vaidlustada vaid 1 kord defaults: - autofollow: Inimesed, kes loovad konto selle kutse läbi, automaatselt jälgivad Teid + autofollow: Inimesed, kes loovad konto selle kutse läbi, automaatselt jälgivad sind avatar: PNG, GIF või JPG. Kõige rohkem %{size}. Vähendatakse %{dimensions} pikslini bot: Teavita teisi, et see konto teeb enamjaolt automatiseeritud tegevusi ja ei pruugi olla järelvalve all context: Üks või mitu konteksti, mille vastu see filter peaks rakenduma current_password: Sisesta turvalisuse huvides oma siinse konto salasõna current_username: Kinnitamiseks palun sisesta oma konto kasutajanimi digest: Saadetakse ainult pärast pikka tegevusetuse perioodi ja ainult siis, kui on saadetud otsesõnumeid - discoverable: Konto on leitav võhivõõraste jaoks soovituste ja trendide sirvimise teel vm sarnaste vahenditega email: Sulle saadetakse e-posti teel kinnituskiri - fields: Saad oma profiilil tabelina kuvada kuni 4 asja header: PNG, GIF või JPG. Kõige rohkem %{size}. Vähendatakse %{dimensions} pikslini inbox_url: Kopeeri soovitud vahendaja avalehe URL irreversible: Filtreeritud postitused kaovad taastamatult, isegi kui filter on hiljem eemaldatud locale: Kasutajaliidese, e-kirjade ja tõuketeadete keel - locked: Nõuab käsitsi jälgijate kinnitamist 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. @@ -54,12 +59,9 @@ et: setting_display_media_default: Peida tundlikuks märgitud meedia setting_display_media_hide_all: Alati peida kõik meedia setting_display_media_show_all: Alati näita tundlikuks märgistatud meedia - setting_hide_network: Profiilil ei kuvata Keda sa jälgid ja kes jälgib sind - setting_noindex: Mõjutab avalikku profiili ja postituste lehekülgi - setting_show_application: Postitamiseks kasutatud rakenduse infot kuvatakse postituse üksikasjavaates 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 - username: Sinu kasutajanimi on %{domain}-il unikaalne + username: Võid kasutada ladina tähti, numbreid ja allkriipsu whole_word: Kui võtmesõna või fraas on ainult tähtnumbriline, rakendub see ainult siis, kui see kattub terve sõnaga domain_allow: domain: See domeen saab tõmmata andmeid sellelt serverilt ning sissetulevad andmed sellelt domeenilt töödeldakse ning salvestatakse @@ -118,6 +120,9 @@ et: sessions: otp: 'Kaheastmelise autentimise kood telefonirakendusest või mõni taastekood:' webauthn: Kui see on USB-võti, sisesta see ning vajadusel aktiveeri. + settings: + indexable: Su profiilileht võib ilmuda Google, Bingi ja teiste otsimootorite tulemustes. + show_application: Sa saad sõltumata sellest vaadata, milline äpp su postituse postitas. tag: name: Saad muuta ainult tähtede suurtähelisust, näiteks selleks, et muuta seda loetavamaks user: @@ -131,12 +136,17 @@ et: position: Kõrgem roll otsustab teatud olukordades konfliktide lahendamise. Teatud toiminguid saab teha ainult madalama prioriteediga rollidega webhook: events: Saadetavate sündmuste valik + template: Koosta oma JSON manus kasutades muutujateasendust. Jäta tühaks tavalise JSONi jaoks. url: Kuhu sündmused saadetakse labels: account: + discoverable: Tõsta postitused ja profiil avastamise algoritmides esile fields: name: Nimetus value: Sisu + indexable: Kaasa avalikud postitused otsingutulemustesse + show_collections: Näita profiilil jälgitavaid ja jälgijaid + unlocked: Nõustu automaatselt uute jälgijatega account_alias: acct: Vana konto aadress account_migration: @@ -174,7 +184,6 @@ et: context: Filtreeri kontekste current_password: Kehtiv salasõna data: Andmed - discoverable: Lisa see konto kataloogi display_name: Kuvanimi email: E-posti aadress expires_in: Aegu pärast @@ -184,7 +193,6 @@ et: inbox_url: Vahendaja sisendkausta URL irreversible: Kustuta selle asemel, et peita locale: Kasutajaliidese keel - locked: Lukusta konto max_uses: Maksimum kasutajate arv new_password: Uus salasõna note: Elulugu @@ -196,7 +204,6 @@ et: setting_always_send_emails: Edasta kõik teavitused meilile setting_auto_play_gif: Esita GIF-e automaatselt setting_boost_modal: Näita enne jagamist kinnitusdialoogi - setting_crop_images: Laiendamata postitustes kärbi pildid 16:9 küljesuhtesse setting_default_language: Postituse keel setting_default_privacy: Postituse nähtavus setting_default_sensitive: Alati märgista meedia tundlikuks @@ -208,9 +215,7 @@ et: setting_display_media_show_all: Kuva kõik setting_expand_spoilers: Alati näita tundlikuks märgitud postituste sisu setting_hide_network: Peida oma võrk - setting_noindex: Keeldu otsingumootorite indekseerimistest setting_reduce_motion: Vähenda animatsioonides liikumist - setting_show_application: Avalikusta postituste tegemisel kasutatud rakendus setting_system_font_ui: Kasuta süsteemi vaikefonti setting_theme: Saidi teema setting_trends: Näita tänaseid trende @@ -281,14 +286,23 @@ et: digest: Saada ülevaatlike e-kirju favourite: Saada e-kiri, kui keegi lisab su postituse lemmikuks follow: Saada e-kiri, kui keegi alustab jälgimist - follow_request: Saada e-kiri, kui keegi soovib Teid jälgida - mention: Saada e-kiri, kui keegi mainib Teid + follow_request: Saada e-kiri, kui keegi soovib sind jälgida + mention: Saada e-kiri, kui keegi mainib sind pending_account: Saada e-kiri, kui uus konto vajab ülevaatlust reblog: Keegi jagas postitust report: Esitatud on uus raport + software_updates: + all: Teata kõikidest uuendustest + critical: Teata vaid kriitilistest uuendustest + label: Saadaval on Mastodoni uus versioon + none: Ära teata ühestki uuendusest (pole soovitatav) + patch: Teata veaparandusuuendustest trending_tag: Uus trend vajab ülevaatust rule: text: Reegel + settings: + indexable: Kaasa profiilileht otsimootoritesse + show_application: Näita, millisest äpist postituse saatsid tag: listable: Luba sellel sildil ilmuda profiilide kataloogis name: Silt @@ -296,6 +310,7 @@ et: usable: Luba postitustel seda silti kasutada user: role: Roll + time_zone: Ajavöönd user_role: color: Märgi värv highlighted: Kuva roll kasutajaprofiilidel märgina @@ -304,9 +319,11 @@ et: position: Positsioon webhook: events: Lubatud sündmused + template: Manuse mall url: Lõpp-punkti URL 'no': Ei not_recommended: Pole soovitatav + overridden: Ülekirjutatud recommended: Soovituslik required: mark: "*" diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml index 175e0c96d7..6f2bbfd969 100644 --- a/config/locales/simple_form.eu.yml +++ b/config/locales/simple_form.eu.yml @@ -2,6 +2,14 @@ eu: simple_form: hints: + account: + discoverable: Zure bidalketa publikoak eta profila nabarmendu edo gomendatu egin daitezke Mastodoneko hainbat eremutan eta zure profila beste erabiltzaile batzuei iradoki dakieke. + display_name: Zure izena edo ezizena. + fields: Zure webgunea, izenordainak, adina, nahi duzun guztia. + indexable: Zure argitalpen publikoak bilaketa-emaitzetan ager daitezke Mastodonen. Zure argitalpenekin elkarregin duten jendeak ikusi ahal izango dituzte, hala ere. + note: 'Beste pertsona edo #traola batzuk @aipatu ditzakezu.' + show_collections: Pertsonek zuk jarraitzen dituzunak eta zure jarraitzaileak arakatu ahal izango dute. Jarraitzen dituzun pertsonak jarraitzen dituzula ikusi ahal izando dute, hala ere. + unlocked: Pertsonek zuri jarraitu ahal izango dizute onarpen-eskaerarik gabe. Desgaitu jarraipen-eskaerak berrikusi nahi badituzu eta hauek onartu edo ez erabaki nahi baduzu. account_alias: acct: Zehaztu migrazioaren jatorri den kontuaren erabiltzailea@domeinua account_migration: @@ -37,14 +45,11 @@ eu: current_password: Segurtasunagatik sartu uneko kontuaren pasahitza current_username: Berresteko sartu uneko kontuaren erabiltzaile-izena digest: Jarduerarik gabeko epe luze bat eta gero mezu pertsonalen bat jaso baduzu, besterik ez - discoverable: Baimendu zure kontua ezezagunek aurkitu ahal izatea gomendio, joera eta beste ezaugarrien bidez email: Baieztapen e-mail bat bidaliko zaizu - fields: 4 elementu bistaratu ditzakezu taula batean zure profilean header: PNG, GIF edo JPG. Gehienez %{size}. %{dimensions}px eskalara txikituko da inbox_url: Kopiatu erabili nahi duzun errelearen hasiera orriaren URLa irreversible: Iragazitako tootak betirako galduko dira, geroago iragazkia kentzen baduzu ere locale: Erabiltzaile-interfazea, e-mail mezuen eta jakinarazpenen hizkuntza - locked: Jarraitzaileak eskuz onartu behar dituzu password: Erabili 8 karaktere gutxienez phrase: Bat egingo du Maiuskula/minuskula kontuan hartu gabe eta edukiaren abisua kontuan hartu gabe scopes: Zeintzuk API atzitu ditzakeen aplikazioak. Goi mailako arloa aukeratzen baduzu, ez dituzu azpikoak aukeratu behar. @@ -54,12 +59,9 @@ eu: setting_display_media_default: Ezkutatu hunkigarri gisa markatutako multimedia setting_display_media_hide_all: Ezkutatu multimedia guztia beti setting_display_media_show_all: Erakutsi beti hunkigarri gisa markatutako multimedia - setting_hide_network: Nor jarraitzen duzun eta nork jarraitzen zaituen ez da bistaratuko zure profilean - setting_noindex: Zure profil publiko eta tooten orrietan eragina du - setting_show_application: Tootak bidaltzeko erabiltzen duzun aplikazioa zure tooten ikuspegi xehetsuan bistaratuko da setting_use_blurhash: Gradienteak ezkutatutakoaren koloreetan oinarritzen dira, baina xehetasunak ezkutatzen dituzte setting_use_pending_items: Ezkutatu denbora-lerroko eguneraketak klik baten atzean jarioa automatikoki korritu ordez - username: Zure erabiltzaile-izena bakana izango da %{domain} domeinuan + username: Hizkiak, zenbakiak eta azpimarrak erabil ditzakezu whole_word: Hitz eta esaldi gakoa alfanumerikoa denean, hitz osoarekin bat datorrenean besterik ez da aplikatuko domain_allow: domain: Domeinu honek zerbitzari honetatik datuak hartu ahal izango ditu eta bertatik jasotako informazioa prozesatu eta gordeko da @@ -97,7 +99,7 @@ eu: timeline_preview: Saioa hasi gabeko erabiltzaileek ezingo dituzte arakatu zerbitzariko bidalketa publiko berrienak. trendable_by_default: Saltatu joeretako edukiaren eskuzko berrikuspena. Ondoren elementuak banan-bana kendu daitezke joeretatik. trends: Joeretan zure zerbitzarian bogan dauden bidalketa, traola eta albisteak erakusten dira. - trends_as_landing_page: Saioa hasita ez duten erabiltzaileei eta bisitariei pil-pilean dagoen edukia erakutsi zerbitzari honen deskribapena erakutsi ordez. Joerak aktibatuak edukitzea beharrezkoa da. + trends_as_landing_page: Erakutsi pil-pilean dagoen edukia saioa hasita ez duten erabiltzaileei eta bisitariei, zerbitzari honen deskribapena erakutsi ordez. Joerak aktibatuak edukitzea beharrezkoa da. form_challenge: current_password: Zonalde seguruan sartzen ari zara imports: @@ -118,6 +120,9 @@ eu: sessions: otp: 'Sartu zure telefonoko aplikazioak sortutako bi faktoreetako kodea, edo erabili zure berreskuratze kodeetako bat:' webauthn: USB gako bat bada, ziurtatu sartu duzula, eta behar izanez gero ukitu ezazu. + settings: + indexable: Zure profila bilaketa-emaitzetan ager daiteke Google, Bing eta beste batzuetan. + show_application: Dena dela, beti ikusi ahal izango duzu zein aplikaziok argitaratu zuen zure bidalketa. tag: name: Letrak maiuskula/minuskulara aldatu ditzakezu besterik ez, adibidez irakurterrazago egiteko user: @@ -131,12 +136,17 @@ eu: position: Maila goreneko rolak erabakitzen du gatazkaren konponbidea kasu batzuetan. Ekintza batzuk maila baxuagoko rolen gain bakarrik gauzatu daitezke webhook: events: Hautatu gertaerak bidaltzeko + template: Osatu zure JSON karga interpolazio aldakorra erabiliz. Utzi hutsik JSON lehenetsiarentzat. url: Nora bidaliko diren gertaerak labels: account: + discoverable: Ezagutarazi profila eta bidalketak bilaketa algoritmoetan fields: name: Etiketa value: Edukia + indexable: Gehitu argitalpen publikoak bilaketa-emaitzetan + show_collections: Erakutsi nor jarraitzen duzun eta nork jarraitzen zaituen profilean + unlocked: Onartu automatikoki jarraitzake berriak account_alias: acct: Kontu zaharraren helbidea account_migration: @@ -174,7 +184,6 @@ eu: context: Iragazkiaren testuinguruak current_password: Oraingo pasahitza data: Datuak - discoverable: Zerrendatu kontu hau direktorioan display_name: Pantaila-izena email: E-mail helbidea expires_in: Iraungitzea @@ -184,7 +193,6 @@ eu: inbox_url: Errelearen sarrera ontziaren URLa irreversible: Baztertu ezkutatu ordez locale: Interfazearen hizkuntza - locked: Giltzapetu kontua max_uses: Gehieneko erabiltzaile kopurua new_password: Pasahitz berria note: Biografia @@ -196,7 +204,6 @@ eu: setting_always_send_emails: Bidali beti eposta jakinarazpenak setting_auto_play_gif: Erreproduzitu GIF animatuak automatikoki setting_boost_modal: Erakutsi baieztapen elkarrizketa-koadroa bultzada eman aurretik - setting_crop_images: Moztu irudiak hedatu gabeko tootetan 16x9 proportzioan setting_default_language: Argitalpenen hizkuntza setting_default_privacy: Mezuen pribatutasuna setting_default_sensitive: Beti markatu edukiak hunkigarri gisa @@ -208,9 +215,7 @@ eu: setting_display_media_show_all: Erakutsi guztia setting_expand_spoilers: Hedatu beti edukia abisua (CW) duten tootak setting_hide_network: Ezkutatu zure sarea - setting_noindex: Atera bilaketa motorraren indexaziotik setting_reduce_motion: Murriztu animazioen mugimenduak - setting_show_application: Utzi agerian tootak bidaltzeko erabilitako aplikazioa setting_system_font_ui: Erabili sistemako tipografia lehenetsia setting_theme: Gunearen azala setting_trends: Erakutsi gaurko joerak @@ -222,7 +227,7 @@ eu: title: Izenburua type: Inportazio mota username: Erabiltzaile-izena - username_or_email: Erabiltzaile-izena edo e-mail helbidea + username_or_email: Erabiltzaile-izena edo eposta helbidea whole_word: Hitz osoa email_domain_block: with_dns_records: Sartu ere domeinuaren MX erregistroak eta IPak @@ -253,13 +258,13 @@ eu: site_short_description: Zerbitzariaren deskribapena site_terms: Pribatutasun politika site_title: Zerbitzariaren izena - status_page_url: Egoera-orriaren URL + status_page_url: Egoera-orriaren URLa theme: Lehenetsitako gaia thumbnail: Zerbitzariaren koadro txikia timeline_preview: Onartu autentifikatu gabeko sarbidea denbora lerro publikoetara trendable_by_default: Onartu joerak aurrez berrikusi gabe trends: Gaitu joerak - trends_as_landing_page: Joerak erabili helburuko orri gisa + trends_as_landing_page: Erabili joerak hasierako orri gisa interactions: must_be_follower: Blokeatu jarraitzaile ez direnen jakinarazpenak must_be_following: Blokeatu zuk jarraitzen ez dituzu horien jakinarazpenak @@ -286,9 +291,18 @@ eu: pending_account: Bidali e-mail bat kontu bat berrikusi behar denean reblog: Bidali e-mail bat norbaitek zure mezuari bultzada ematen badio report: Salaketa berria bidali da + software_updates: + all: Jakinarazi eguneraketa guztiak + critical: Jakinarazi eguneraketa kritikoak soilik + label: Mastodon bertsio berria eskuragarri + none: Inoiz ez jakinarazi egunerakerak (ez da gomendagarria) + patch: Jakinarazi akats zuzenketa eguneraketa guztiak trending_tag: Joera berriak berrikuspena behar du rule: text: Araua + settings: + indexable: Gehitu profila bilaketa-motorretan + show_application: Utzi agerian tootak bidaltzeko erabilitako aplikazioa tag: listable: Baimendu traola hau bilaketetan agertzea eta profilen direktorioan name: Traola @@ -296,6 +310,7 @@ eu: usable: Baimendu tootek traola hau erabiltzea user: role: Rola + time_zone: Ordu zona user_role: color: Bereizgarriaren kolorea highlighted: Bistaratu rola bereizgarri bezala erabiltzaileen profiletan @@ -304,9 +319,11 @@ eu: position: Lehentasuna webhook: events: Gertaerak gaituta + template: Karga txantiloia url: Amaiera-puntuaren URLa 'no': Ez not_recommended: Ez gomendatua + overridden: Gainidatzita recommended: Aholkatua required: mark: "*" diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index 18dd827906..676eb192ee 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -2,6 +2,14 @@ fa: simple_form: hints: + account: + discoverable: ممکن است نمایه و فرسته‌های عمومیتان در جاهای مختلف ماستودون نمایانده و توصیه شود و نمایه‌تان به دیگر کاربران پیشنهاد شود. + display_name: نام کامل یا باحالتان. + fields: صفحهٔ خانگی، تلفّظ، سن و هرچیزی که دوست دارید. + indexable: ممکن است فرسته‌های عمومیتان در نتیجه‌های جست‌وجوی ماستودون ظاهر شود. افرادی که با فرسته‌هایتان تعامل داشتند در هر صورت می‌توانند جست‌وجویشان کنند. + note: 'می‌توانید افراد دیگر را @نام برده یا #برچسب بزنید.' + show_collections: افراد خواهند توانست پی‌گیران و پی‌گرفته شده‌هایتان را مرور کنند. افرادی که پی‌می‌گیریدشان در هر صورت خواهند دید که پی‌می‌گیریدشان. + unlocked: افراد خواهند توانست بدون درخواست تأیید پی‌بگیرندتان. اگر می‌خواهید درخواست‌های پی‌گیری را بازبینی کرده و بگزینید که پی‌گیران جدید را بپذیرید یا رد کنید، علامت را بردارید. account_alias: acct: مشخّص کردن username@domain حسابی که می‌خواهید از آن منتقل شوید account_migration: @@ -34,17 +42,14 @@ fa: avatar: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد bot: این حساب بیشتر به طور خودکار فعالیت می‌کند و نظارت پیوسته‌ای روی آن وجود ندارد context: یک یا چند زمینه که پالایه باید در آن‌ها اعمال شود - current_password: به دلایل امنیتی لطفاً رمز این حساب را وارد کنید + current_password: به دلایل امنیتی لطفاً گذرواژه این حساب را وارد کنید current_username: برای تأیید، لطفاً نام کاربری حساب فعلی را وارد کنید digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد - discoverable: اجازه دهید حساب‌تان از طریق پیشنهادها، پرطرفدارها و سایر قابلیت‌ها، توسط افراد غریبه قابل کشف باشد email: به شما ایمیل تأییدی فرستاده خواهد شد - fields: شما می‌توانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید header: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد inbox_url: نشانی صفحهٔ اصلی رله‌ای را که می‌خواهید به کار ببرید کپی کنید irreversible: فرسته‌های پالوده به طور برگشت‌ناپذیری ناپدید می‌شوند، حتا اگر بعدها پالایه برداشته شود locale: زبان واسط کاربری، رایانامه‌ها و آگاهی‌های ارسالی - locked: باید پیگیران تازه را خودتان تأیید کنید password: دست‌کم باید ۸ نویسه داشته باشد phrase: مستقل از کوچکی و بزرگی حروف، با متن اصلی یا هشدار محتوای فرسته‌ها مقایسه می‌شود scopes: واسط‌های برنامه‌نویسی که این برنامه به آن دسترسی دارد. اگر بالاترین سطح دسترسی را انتخاب کنید، دیگر نیازی به انتخاب سطح‌های پایینی ندارید. @@ -54,12 +59,9 @@ fa: setting_display_media_default: تصویرهایی را که به عنوان حساس علامت زده شده‌اند پنهان کن setting_display_media_hide_all: همیشه همهٔ عکس‌ها و ویدیوها را پنهان کن setting_display_media_show_all: همیشه تصویرهایی را که به عنوان حساس علامت زده شده‌اند را نشان بده - setting_hide_network: فهرست پیگیران شما و فهرست کسانی که شما پی می‌گیرید روی نمایهٔ شما دیده نخواهد شد - setting_noindex: روی نمایهٔ عمومی و صفحهٔ نوشته‌های شما تأثیر می‌گذارد - setting_show_application: برنامه‌ای که به کمک آن فرسته می‌زنید، در جزئیات فرسته شما نمایش خواهد یافت setting_use_blurhash: سایه‌ها بر اساس رنگ‌های به‌کاررفته در تصویر پنهان‌شده ساخته می‌شوند ولی جزئیات تصویر در آن‌ها آشکار نیست setting_use_pending_items: به جای پیش‌رفتن خودکار در فهرست، به‌روزرسانی فهرست نوشته‌ها را پشت یک کلیک پنهان کن - username: نام کاربری شما روی %{domain} یکتا خواهد بود + username: تنها می‌توانید از حروف، اعداد، و زیرخط استفاده کنید whole_word: اگر کلیدواژه فقط دارای حروف و اعداد باشد، تنها وقتی پیدا می‌شود که با کل یک واژه در متن منطبق باشد، نه با بخشی از یک واژه domain_allow: domain: این دامین خواهد توانست داده‌ها از این سرور را دریافت کند و داده‌های از این دامین در این‌جا پردازش و ذخیره خواهند شد @@ -74,7 +76,21 @@ fa: hide: نهفتن کامل محتوای پالوده، گویی وجود ندارد warn: نهفتن محتوای پالوده پشت هشداری که به عنوان پالایه اشاره می‌کند form_admin_settings: + activity_api_enabled: تعداد بوق‌های منتشرهٔ محلی، کاربران فعال، و کاربران تازه در هر هفته 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: می‌توانیدروی نگارش وب ماستودون سبک‌های سفارشی اعمال کنید. + mascot: نقش میانای وب پیش‌رفته را پایمال می‌کند. + media_cache_retention_period: اگر به مقدار مثبتی تنظیم شود، پرونده‌های رسانهٔ بارگرفته پس از روزهای مشخّص شده حذف خواهند شد و هنگام درخواست دوباره بارگرفته می‌شوند. + profile_directory: شاخهٔ نمایه، همهٔ کاربرانی که کشف‌پذیری را برگزیده‌اند سیاهه می‌کند. + require_invite_text: زمانی که نام‌نویسی ها نیازمند تایید دستی است، متن «چرا می‌خواهید بپیوندید؟» بخش درخواست دعوت را به جای اختیاری، اجباری کنید + site_contact_email: چگونگی دسترسی افراد به شما برای مقاصد قانونی یا پشتیبانی. + site_contact_username: چکونگی رسیدن افراد به شما روی ماستودون. + site_extended_description: هر اطّلاعات بیش‌تری که ممکن است برای بازدیدکنندگان و کاربرانتان مفید باشد. می‌تواند به شکل مارک‌دون باشد. + site_short_description: شرحی کوتاه برای کمک به شناسایی یکتای کارسازتان. چه‌کسی می‌گرداندش و برای چه کسیست؟ + site_terms: از سیاست محرمانگی خوتان استفاده کرده یا برای استفاده از سیاست پیش‌گزیده خالی بگذارید. می‌تواند در قالب مارک‌دون باشد. form_challenge: current_password: شما در حال ورود به یک منطقهٔ‌ حفاظت‌شده هستید imports: @@ -87,22 +103,33 @@ fa: ip: یک آی‌پی نکارش ۴ یا ۶ وارد کنید. می‌توانید تمامی دامنه‌ای را با استفاده از ساختار CIDR مسدود کنید. مراقب باشید خودتان را بیرون نیندازید! severities: no_access: انسداد دسترسی به تمامی منابع + sign_up_block: ثبت‌نام جدید ممکن نخواهد بود sign_up_requires_approval: ثبت‌نام‌های جدید، نیازمند تأییدتان خواهند بود severity: بگزنید با درخواست‌ها از این آی‌پی چه شود rule: text: قائده یا نیازمندی‌هایی را برای کاربران این کارساز تشریح کنید. سعی کنید آن را ساده و کوتاه نگاه دارید sessions: - otp: 'کد تأیید دومرحله‌ای که اپ روی تلفن شما ساخته را وارد کنید یا یکی از کدهای بازیابی را به کار ببرید:' + otp: 'کد تأیید دومرحله‌ای که کاره روی تلفن شما ساخته را وارد کنید یا یکی از کدهای بازیابی را به کار ببرید:' webauthn: اگر کلید USB باشد ، از اتصاڵ آن مطمئن شوید و، اگر لازم باشد، به آن ضربه‌ایی بزنید. + settings: + indexable: صفحهٔ نمایه‌تان ممکن است در نتیجه‌های جست‌وجو روی گوگل، بینگ و جاهای دیگر ظاهر شود. + show_application: خودتان همواره خواهید توانست ببینید که کدام کاره فرسته‌تان را منتشر کرده. tag: name: شما تنها می‌توانید بزرگی و کوچکی حروف را تغییر دهید تا مثلاً آن را خواناتر کنید user: chosen_languages: اگر انتخاب کنید، تنها نوشته‌هایی که به زبان‌های برگزیدهٔ شما نوشته شده‌اند در فهرست نوشته‌های عمومی نشان داده می‌شوند + webhook: + events: گزینش رویدادها برای فرستادن + url: جایی که رویدادها فرستاده می‌شوند labels: account: + discoverable: معرّفی نمایه و فرسته‌ها در الگوریتم‌های کشف fields: name: برچسب value: محتوا + indexable: بودن فرسته‌های عمومی در نتیجه‌های جست‌وجو + show_collections: نمایش پی‌گیران و پی‌گرفته شده‌ها روی نمایه + unlocked: پذیرش خودکار پی‌گیران جدید account_alias: acct: نشانی حساب قدیمی account_migration: @@ -135,12 +162,11 @@ fa: avatar: تصویر نمایه bot: این حساب یک ربات است chosen_languages: جدا کردن زبان‌ها - confirm_new_password: تأیید رمز تازه - confirm_password: تأیید رمز + confirm_new_password: تأیید گذرواژه تازه + confirm_password: تأیید گذرواژه context: زمینه‌های پالایش - current_password: رمز فعلی + current_password: گذرواژه کنونی data: داده‌ها - discoverable: پیشنهاد حساب به دیگران display_name: نمایش به نام email: نشانی ایمیل expires_in: تاریخ انقضا @@ -150,18 +176,17 @@ fa: inbox_url: نشانی صندوق ورودی رله irreversible: به جای پنهان‌سازی، حذف کن locale: زبان محیط کاربری - locked: خصوصی‌کردن حساب max_uses: بیشترین شمار استفاده - new_password: رمز تازه + new_password: گذرواژه تازه note: دربارهٔ شما otp_attempt: کد ورود دومرحله‌ای - password: رمز + password: گذرواژه phrase: کلیدواژه یا عبارت setting_advanced_layout: فعال‌سازی رابط کاربری پیشرفته setting_aggregate_reblogs: تقویت‌ها را در خط‌زمانی گروه‌بندی کن + setting_always_send_emails: فرستادن همیشگی آگاهی‌های رایانامه‌ای setting_auto_play_gif: پخش خودکار تصویرهای متحرک setting_boost_modal: نمایش پیغام تأیید پیش از تقویت کردن - setting_crop_images: در فرسته‌های ناگسترده، تصویرها را به ابعاد ‎۱۶×۹ کوچک کن setting_default_language: زبان نوشته‌های شما setting_default_privacy: حریم خصوصی نوشته‌ها setting_default_sensitive: همیشه تصاویر را به عنوان حساس علامت بزن @@ -173,9 +198,7 @@ fa: setting_display_media_show_all: نمایش همه setting_expand_spoilers: همیشه فرسته‌هایی را که هشدار محتوا دارند کامل نشان بده setting_hide_network: نهفتن شبکهٔ ارتباطی - setting_noindex: درخواست از موتورهای جستجوگر برای ظاهر نشدن در نتایج جستجو setting_reduce_motion: کاستن از حرکت در پویانمایی‌ها - setting_show_application: برنامه‌ای که به کار می‌برید آشکار شود setting_system_font_ui: به‌کاربردن قلم پیش‌فرض سیستم setting_theme: تم سایت setting_trends: نشان‌دادن موضوعات پرطرفدار روز @@ -198,12 +221,33 @@ fa: hide: نهفتن کامل warn: نهفتن با هشدار form_admin_settings: + activity_api_enabled: انتشار آمار تجمیعی دربارهٔ فعالیت کاربران در API backups_retention_period: دورهٔ نگه‌داری بایگانی کاربری + bootstrap_timeline_accounts: پیشنهاد همیشگی این حساب‌ها به کاربران جدید + closed_registrations_message: پیام سفارشی هنگام در دسترس نبودن ثبت‌نام‌ها + content_cache_retention_period: دورهٔ نگه‌داری انبارهٔ محتوا + custom_css: سبک CSS سفارشی + mascot: نشان سفارشی (قدیمی) + media_cache_retention_period: دورهٔ نگه‌داری انبارهٔ رسانه + peers_api_enabled: انتشار سیاههٔ کارسازهای کشف شده در API + profile_directory: به کار انداختن شاخهٔ نمایه + registrations_mode: چه کسانی می‌توانند ثبت‌نام کنند + require_invite_text: نیازمند دلیلی برای پیوستن + show_domain_blocks: نمایش مسدودیت‌های دامنه + show_domain_blocks_rationale: نمایش چرایی مسدودیت دامنه‌ها + site_contact_email: رایانامهٔ ارتباطی + site_contact_username: نام کاربری ارتباطی + site_extended_description: شرح گسترده + site_short_description: شرح کارساز + site_terms: سیاست محرمانگی + site_title: نام کارساز + status_page_url: نشانی صفحهٔ وضعیت theme: زمینهٔ پیش‌گزیده thumbnail: بندانگشتی کارساز timeline_preview: اجازهٔ دسترسی بدون تأیید هویت به خط‌زمانی‌های عمومی trendable_by_default: اجازهٔ پرطرفدار شدن بدون بازبینی پیشین trends: به کار انداختن پرطرفدارها + trends_as_landing_page: استفاده از داغ‌ها به عنوان صفحهٔ فرود interactions: must_be_follower: انسداد آگاهی‌ها از ناپی‌گیران must_be_following: انسداد آگاهی‌ها از افرادی که پی نمی‌گیرید @@ -230,9 +274,18 @@ fa: pending_account: وقتی حساب تازه‌ای نیاز به بازبینی داشت ایمیل بفرست reblog: وقتی کسی فرستهٔ شما را تقویت کرد ایمیل بفرست report: گزارش جدیدی فرستاده شد + software_updates: + all: آگاهی برای همهٔ به‌روز رسانی‌ها + critical: آگاهی فقط برای به‌روز رسانی‌های بحرانی + label: نگارشی جدید از ماستادون موجود است + none: هرگز برای به‌روز رسانی‌ها آگاهی داده نشود (توصیه نمی‌شود) + patch: آگاهی برای به‌روز رسانی‌های رفع اشکال trending_tag: روند جدیدی نیازمند بازبینی است rule: text: قانون + settings: + indexable: بودن صفحهٔ نمایه در نتیجه‌های جست‌وجو + show_application: نمایش این که فرسته را از کدام کاره فرستاده‌اید tag: listable: اجازه به این برچسب برای ظاهر شدن در جست‌وجوها و پیشنهادها name: برچسب @@ -240,6 +293,7 @@ fa: usable: بگذارید که این برچسب در فرسته‌ها به کار بروند user: role: نقش + time_zone: منطقهٔ زمانی user_role: color: رنگ نشان highlighted: نمایش نقش به شکل نشان روی نمایهً کاربری @@ -251,6 +305,7 @@ fa: url: نشانی نقطهٔ پایانی 'no': خیر not_recommended: پیشنهاد نشده + overridden: پایمال recommended: توصیه می‌شود required: mark: "*" diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index f22ba7a981..1925ba77f3 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -2,16 +2,24 @@ fi: simple_form: hints: + account: + discoverable: Julkisia julkaisujasi ja profiiliasi voidaan pitää esillä tai suositella Mastodonin eri alueilla ja profiiliasi voidaan ehdottaa toisille käyttäjille. + display_name: Koko nimesi tai lempinimesi. + fields: Kotisivusi, pronominit, ikä, mitä ikinä haluat. + indexable: Julkiset julkaisusi voivat näkyä hakutuloksissa Mastodonissa. Ihmiset, jotka ovat olleet vuorovaikutuksessa julkaisujesi kanssa, voivat etsiä niitä asetuksesta riippumatta. + note: 'Voit @mainita muita käyttäjiä tai #aihetunnisteita.' + show_collections: Käyttäjät voivat selata seurattujasi ja seuraajiasi. Käyttäjät, joita seuraat, näkevät joka tapauksessa, että seuraat heitä. + unlocked: Käyttäjät voivat seurata sinua pyytämättä hyväksyntää. Poista valinta, jos haluat tarkistaa ja hyväksyä tai hylätä vastaanottamasi seuraamispyynnöt. account_alias: - acct: Määrittele käyttäjän käyttäjänimi@verkkotunnus, josta haluat siirtyä + acct: Määrittele sen tilin käyttäjänimi@verkkotunnus, josta haluat siirtyä account_migration: - acct: Määrittele käyttäjän käyttäjänimi@verkkotunnus, johon haluat siirtyä + acct: Määrittele sen tilin käyttäjänimi@verkkotunnus, johon haluat siirtyä account_warning_preset: text: Voit käyttää julkaisun syntaksia, kuten URL-osoitteita, aihetunnisteita ja mainintoja - title: Vapaaehtoinen. Ei näytetä vastaanottajalle + title: Valinnainen. Ei näy vastaanottajalle admin_account_action: - include_statuses: Käyttäjä näkee mitkä viestit johtivat toimenpiteeseen tai varoitukseen - send_email_notification: Käyttäjä saa selityksen mitä tapahtui hänen tililleen + include_statuses: Käyttäjä näkee, mitkä julkaisut johtivat valvontatoimeen tai varoitukseen + send_email_notification: Käyttäjä saa selvityksen siitä, mitä hänen tililleen tapahtui text_html: Valinnainen. Voit käyttää julkaisun syntaksia. Voit lisätä varoitusasetuksia säästääksesi aikaa type_html: Valitse mitä teet käyttäjälle %{acct} types: @@ -23,56 +31,50 @@ fi: warning_preset_id: Valinnainen. Voit silti lisätä mukautetun tekstin esiasetuksen loppuun announcement: all_day: Kun valittu, vain valittu aikaväli näytetään - ends_at: Valinnainen. Ilmoitus tullaan poistamaan automaattisesti tällä hetkellä - scheduled_at: Jätä tyhjäksi julkaistaksesi ilmoituksen välittömästi - starts_at: Valinnainen. Jos ilmoituksesi on sidottu tiettyyn aikaväliin - text: Voit käyttää julkaisun syntaksia. Muista, kuinka paljon tilaa ilmoitus vie käyttäjän näytöltä + ends_at: Valinnainen. Tiedote poistetaan automaattisesti tällä hetkellä + scheduled_at: Jätä tyhjäksi julkaistaksesi tiedotteen heti + starts_at: Valinnainen. Jos tiedotteesi on sidottu tiettyyn aikaväliin + text: Voit käyttää julkaisun syntaksia. Ota huomioon, kuinka paljon tilaa tiedote vie käyttäjän näytöltä appeal: text: Voit valittaa varoituksesta vain kerran defaults: autofollow: Henkilöt, jotka rekisteröityvät kutsun kautta, seuraavat sinua automaattisesti avatar: PNG, GIF tai JPG. Enintään %{size}. Skaalataan kokoon %{dimensions} px bot: Tämä tili suorittaa enimmäkseen automaattisia toimintoja eikä sitä ehkä valvota - context: Yksi tai useampi asiayhteys, jossa suodattimen pitäisi olla käytössä + context: Ainakin yksi konteksti, jossa suodattimen pitäisi olla voimassa current_password: Turvallisuussyistä kirjoita nykyisen tilin salasana current_username: Vahvista kirjoittamalla nykyisen tilin käyttäjätunnus digest: Lähetetään vain pitkän poissaolon jälkeen ja vain, jos olet saanut suoria viestejä poissaolosi aikana - discoverable: Salli tuntemattomien löytää tilisi suositusten, trendien ja muiden ominaisuuksien kautta email: Sinulle lähetetään vahvistussähköposti - fields: Sinulla voi olla korkeintaan 4 asiaa profiilissasi taulukossa header: PNG, GIF tai JPG. Enintään %{size}. Skaalataan kokoon %{dimensions} px inbox_url: Kopioi URL-osoite haluamasi välittäjän etusivulta irreversible: Suodatetut julkaisut katoavat lopullisesti, vaikka suodatin poistettaisiin myöhemmin - locale: Käyttöliittymän, sähköpostien ja ilmoitusten kieli - locked: Sinun täytyy hyväksyä seuraajat manuaalisesti + locale: Käyttöliittymän, sähköpostien ja puskuilmoitusten kieli password: Käytä vähintään 8 merkkiä - phrase: Täytetään riippumatta julkaisun kirjainkoon tai sisällön varoituksesta + phrase: Täsmää riippumatta tekstin aakkoslajista tai julkaisun sisältövaroituksesta scopes: Mihin sovellusliittymiin sovellus pääsee käsiksi. Jos valitset ylätason laajuuden, sinun ei tarvitse valita yksittäisiä. - setting_aggregate_reblogs: Älä näytä uusia tehosteita viesteille, joita on äskettäin tehostettu (koskee vain äskettäin saatuja tehosteita) - setting_always_send_emails: Yleensä sähköposti-ilmoituksia ei lähetetä, kun käytät aktiivisesti Mastodonia - setting_default_sensitive: Arkaluontoinen media on oletuksena piilotettu ja se voidaan näyttää yhdellä napsautuksella + setting_aggregate_reblogs: Älä näytä uusia tehostuksia julkaisuille, joita on äskettäin tehostettu (koskee vain juuri vastaanotettuja tehostuksia) + setting_always_send_emails: Yleensä sähköposti-ilmoituksia ei lähetetä, kun käytät Mastodonia aktiivisesti + setting_default_sensitive: Arkaluonteinen media on oletuksena piilotettu, ja se voidaan näyttää yhdellä napsautuksella setting_display_media_default: Piilota arkaluonteiseksi merkitty media - setting_display_media_hide_all: Piilota aina kaikki media - setting_display_media_show_all: Näytä aina arkaluonteiseksi merkitty media - setting_hide_network: Ketä seuraat ja kuka seuraa sinua, piilotetaan profiiliisi - setting_noindex: Vaikuttaa julkiseen profiiliisi ja tilasivuihisi - setting_show_application: Viestittelyyn käyttämäsi sovellus näkyy viestiesi yksityiskohtaisessa näkymässä + setting_display_media_hide_all: Piilota media aina + setting_display_media_show_all: Näytä media aina setting_use_blurhash: Liukuvärit perustuvat piilotettujen kuvien väreihin, mutta sumentavat yksityiskohdat - setting_use_pending_items: Piilota aikajanan päivitykset napsautuksen taakse sen sijaan, että vierittäisi syötettä automaattisesti - username: Käyttäjänimesi tulee olemaan yksilöllinen %{domain} - whole_word: Kun avainsana tai lause on vain aakkosnumeerinen, se otetaan käyttöön, jos se vastaa koko sanaa + setting_use_pending_items: Piilota aikajanan päivitykset napsautuksen taakse syötteen automaattisen vierityksen sijaan + username: Voit käyttää kirjaimia, numeroita ja alaviivoja + whole_word: Kun avainsana tai -fraasi on kokonaan aakkosnumeerinen, se on voimassa vain, jos se vastaa koko sanaa domain_allow: domain: Tämä verkkotunnus voi noutaa tietoja tältä palvelimelta ja sieltä saapuvat tiedot käsitellään ja tallennetaan email_domain_block: domain: Tämä voi olla se verkkotunnus, joka näkyy sähköpostiosoitteessa tai MX tietueessa jota se käyttää. Ne tarkistetaan rekisteröitymisen yhteydessä. with_dns_records: Annetun verkkotunnuksen DNS-tietueet yritetään ratkaista ja tulokset myös estetään featured_tag: - name: 'Tässä muutamia aihetunnisteita, joita käytit viime aikoina:' + name: 'Tässä muutamia hiljattain käyttämiäsi aihetunnisteita:' filters: - action: Valitse, mikä toiminto suoritetaan, kun viesti vastaa suodatinta + action: Valitse, mikä toiminto suoritetaan, kun julkaisu vastaa suodatinta actions: hide: Piilota suodatettu sisältö kokonaan ja käyttäydy ikään kuin sitä ei olisi olemassa - warn: Piilota suodatettu sisältö varoituksen taakse, jossa mainitaan suodattimen otsikko + warn: Piilota suodatettu sisältö varoituksen taakse, jossa mainitaan suodattimen nimi form_admin_settings: activity_api_enabled: Paikallisesti julkaistujen julkaisujen, aktiivisten käyttäjien ja rekisteröitymisten viikoittainen määrä backups_retention_period: Säilytä luodut arkistot määritetyn määrän päiviä. @@ -82,7 +84,7 @@ fi: custom_css: Voit käyttää mukautettuja tyylejä Mastodonin verkkoversiossa. mascot: Ohittaa kuvituksen edistyneessä käyttöliittymässä. media_cache_retention_period: Ladatut mediatiedostot poistetaan määritetyn määrän päiviä jälkeen, kun arvo on positiivinen ja ladataan uudelleen pyynnöstä. - peers_api_enabled: Lista verkkotunnuksista, joita tämä palvelin on kohdannut fediversessä. Täällä ei ole tietoja siitä, oletko liitossa tiettyjen palvelinten kanssa, vaan ainoastaan luettelo niistä verkkotunnuksista, joista palvelimesi on ylipäätään tietoinen. Tätä tietoa käytetään palveluissa, jotka keräävät liittotilastoja laajassa merkityksessä. + peers_api_enabled: Luettelo verkkotunnuksista, jotka tämä palvelin on kohdannut fediversumissa. Se ei kerro, oletko liitossa tietyn palvelimen kanssa, vaan että palvelimesi on ylipäätään tietoinen siitä. Tätä tietoa käytetään palveluissa, jotka keräävät tilastoja liittoutumisesta yleisellä tasolla. profile_directory: Profiilihakemisto lueteloi kaikki käyttäjät, jotka ovat ilmoittaneet olevansa löydettävissä. require_invite_text: Kun kirjautuminen vaatii manuaalisen hyväksynnän, tee ”Miksi haluat liittyä?” teksti syötetään pakolliseksi eikä vapaaehtoiseksi site_contact_email: Kuinka ihmiset voivat tavoittaa sinut oikeudellisissa tai tukikysymyksissä. @@ -91,17 +93,17 @@ fi: site_short_description: Lyhyt kuvaus auttaa yksilöimään palvelimesi. Kuka sitä johtaa, kenelle se on tarkoitettu? site_terms: Käytä omaa tietosuojakäytäntöä tai jätä tyhjäksi, jos haluat käyttää oletusta. Voidaan jäsentää Markdown-syntaksilla. site_title: Kuinka ihmiset voivat viitata palvelimeen sen verkkotunnuksen lisäksi. - status_page_url: URL-osoite, jonka kautta palvelimen tila voidaan tarkastaa sen ollessa tavoittamattomissa + status_page_url: URL-osoite sivulle, jonka kautta tämän palvelimen tila voidaan ongelmatilanteissa tarkastaa theme: Teema, jonka uloskirjautuneet vierailijat ja uudet käyttäjät näkevät. thumbnail: Noin 2:1 kuva näytetään palvelimen tietojen rinnalla. timeline_preview: Uloskirjautuneet vierailijat voivat selata uusimpia julkisia viestejä, jotka ovat saatavilla palvelimella. trendable_by_default: Ohita suositun sisällön manuaalinen tarkistus. Yksittäisiä kohteita voidaan edelleen poistaa jälkikäteen. trends: Trendit osoittavat, mitkä julkaisut, aihetunnisteet ja uutiset ovat saamassa vetoa palvelimellasi. - trends_as_landing_page: Näytä suosittu sisältö uloskirjautuneille käyttäjille ja kävijöille palvelimen kuvauksen sijaan. Edellyttää suositun sisällön käyttöönottoa. + trends_as_landing_page: Näytä vierailijoille ja uloskirjautuneille käyttäjille suosittu sisältö palvelininstanssin kuvaustekstin sijaan. Edellytyksenä on, että suosittu sisältö -ominaisuus on käytössä. form_challenge: current_password: Olet menossa suojatulle alueelle imports: - data: Toisesta Mastodon-instanssista tuotu CSV-tiedosto + data: Toiselta Mastodon-palvelimelta tuotu CSV-tiedosto invite_request: text: Tämä auttaa meitä arvioimaan hakemustasi ip_block: @@ -118,10 +120,13 @@ fi: sessions: otp: Syötä puhelimeen saamasi kaksivaiheisen tunnistautumisen koodi tai käytä palautuskoodia. webauthn: Jos kyseessä on USB-avain, muista laittaa se paikalleen ja tarvittaessa napauttaa sitä. + settings: + indexable: Profiilisi voi näkyä Googlen, Bingin ja muiden hakukoneiden hakutuloksissa. + show_application: Voit silti aina nähdä, mistä sovelluksesta julkaisusi lähetettiin. tag: name: Voit muuttaa esimerkiksi kirjaimia paremmin luettavaksi user: - chosen_languages: Kun valittu, vain valituilla kielillä julkaistut viestit näkyvät julkisilla aikajanoilla + chosen_languages: Kun valittu, vain valituilla kielillä kirjoitetut julkaisut näkyvät julkisilla aikajanoilla role: Rooli määrää, mitkä käyttöoikeudet käyttäjällä on user_role: color: Väri, jota käytetään roolin koko käyttöliittymässä, RGB heksamuodossa @@ -131,37 +136,42 @@ fi: position: Korkeampi rooli ratkaisee konfliktit tietyissä tilanteissa. Tiettyjä toimintoja voidaan suorittaa vain rooleille, joiden prioriteetti on pienempi webhook: events: Valitse lähetettävät tapahtumat + template: Luo oma JSON-hyötykuorma käyttäen muuttujien interpolointia. Jätä kenttä tyhjäksi käyttääksesi vakio-JSON-kuormaa. url: Mihin tapahtumat lähetetään labels: account: + discoverable: Nosta profiili ja julkaisut esille löytämisalgoritmeissa fields: name: Nimike value: Sisältö + indexable: Sisällytä julkiset julkaisut hakutuloksiin + show_collections: Näytä seuratut ja seuraajat profiilissa + unlocked: Hyväksy uudet seuraajat automaattisesti account_alias: - acct: Vanhan tilin käsittely + acct: Vanhan tilin käyttäjätunnus account_migration: - acct: Uuden tilin käsittely + acct: Uuden tilin käyttäjätunnus account_warning_preset: text: Esiasetettu teksti - title: Otsikko + title: Nimi admin_account_action: include_statuses: Sisällytä raportoidut viestit sähköpostiin send_email_notification: Ilmoita käyttäjälle sähköpostitse text: Mukautettu varoitus - type: Toimenpide + type: Toimi types: disable: Poista kirjautuminen käytöstä none: Älä tee mitään - sensitive: Arkaluontoinen + sensitive: Arkaluonteinen silence: Hiljennä suspend: Poista käytöstä ja tuhoa käyttäjätunnuksen tiedot peruuttamattomasti warning_preset_id: Käytä varoitusmallia announcement: all_day: Koko päivän kestävä tapahtuma ends_at: Tapahtuman loppu - scheduled_at: Ajasta julkaisu + scheduled_at: Ajoita julkaisu starts_at: Tapahtuman alku - text: Ilmoitus + text: Tiedote appeal: text: Perustele, miksi tämä päätös olisi kumottava defaults: @@ -171,56 +181,51 @@ fi: chosen_languages: Suodata kieliä confirm_new_password: Vahvista uusi salasana confirm_password: Vahvista salasana - context: Suodata konteksteista + context: Suodattimen kontekstit current_password: Nykyinen salasana data: Tiedot - discoverable: Listaa tämä tili hakemistoon - display_name: Nimimerkki + display_name: Näyttönimi email: Sähköpostiosoite expires_in: Vanhenee - fields: Profiilin metadata - header: Otsakekuva + fields: Lisäkentät + header: Otsikkokuva honeypot: "%{label} (älä täytä)" inbox_url: Välittäjän postilaatikon URL-osoite irreversible: Pudota piilottamisen sijaan locale: Kieli - locked: Lukitse tili max_uses: Käyttökertoja enintään new_password: Uusi salasana - note: Kuvaus + note: Elämäkerta otp_attempt: Kaksivaiheisen tunnistuksen koodi password: Salasana - phrase: Avainsana tai lause - setting_advanced_layout: Ota käyttöön edistynyt selainkäyttöliittymä - setting_aggregate_reblogs: Ryhmitä tehostukset aikajanalla - setting_always_send_emails: Lähetä aina sähköposti-ilmoituksia + phrase: Avainsana tai -fraasi + setting_advanced_layout: Ota edistynyt selainkäyttöliittymä käyttöön + setting_aggregate_reblogs: Ryhmitä tehostukset aikajanoilla + setting_always_send_emails: Lähetä sähköposti-ilmoitukset aina setting_auto_play_gif: Toista GIF-animaatiot automaattisesti - setting_boost_modal: Kysy vahvistus ennen tehostusta - setting_crop_images: Rajaa kuvat avaamattomissa tuuttauksissa 16:9 kuvasuhteeseen - setting_default_language: Julkaisujen kieli - setting_default_privacy: Viestin näkyvyys - setting_default_sensitive: Merkitse media aina arkaluontoiseksi - setting_delete_modal: Kysy vahvistusta ennen viestin poistamista + setting_boost_modal: Kysy vahvistusta ennen tehostusta + setting_default_language: Julkaisun kieli + setting_default_privacy: Julkaisun näkyvyys + setting_default_sensitive: Merkitse media aina arkaluonteiseksi + setting_delete_modal: Kysy vahvistusta ennen julkaisun poistamista setting_disable_swiping: Poista pyyhkäisyt käytöstä setting_display_media: Median näyttäminen setting_display_media_default: Oletus setting_display_media_hide_all: Piilota kaikki setting_display_media_show_all: Näytä kaikki - setting_expand_spoilers: Laajenna aina sisältövaroituksilla merkityt viestit + setting_expand_spoilers: Laajenna aina sisältövaroituksilla merkityt julkaisut setting_hide_network: Piilota verkkosi - setting_noindex: Jättäydy hakukoneindeksoinnin ulkopuolelle setting_reduce_motion: Vähennä animaatioiden liikettä - setting_show_application: Näytä sovellus mistä lähetät viestejä setting_system_font_ui: Käytä järjestelmän oletusfonttia setting_theme: Sivuston teema setting_trends: Näytä päivän trendit - setting_unfollow_modal: Kysy vahvistusta, ennen kuin lopetat seuraamisen + setting_unfollow_modal: Kysy vahvistusta ennen seuraamisen lopettamista setting_use_blurhash: Näytä värikkäät liukuvärit piilotetulle medialle - setting_use_pending_items: Hidastila + setting_use_pending_items: Hidas tila severity: Vakavuus sign_in_token_attempt: Turvakoodi - title: Otsikko - type: Tietojen laji + title: Nimi + type: Tuontilaji username: Käyttäjänimi username_or_email: Käyttäjänimi tai sähköposti whole_word: Koko sana @@ -231,7 +236,7 @@ fi: filters: actions: hide: Piilota kokonaan - warn: Piilota varoituksella + warn: Piilota ja näytä varoitus form_admin_settings: activity_api_enabled: Julkaise yhteenlasketut tilastot käyttäjätoiminnasta rajapinnassa backups_retention_period: Käyttäjän arkiston säilytysaika @@ -263,14 +268,14 @@ fi: interactions: must_be_follower: Estä ilmoitukset käyttäjiltä, jotka eivät seuraa sinua must_be_following: Estä ilmoitukset käyttäjiltä, joita et seuraa - must_be_following_dm: Estä suorat viestit käyttäjiltä, joita et seuraa + must_be_following_dm: Estä yksityisviestit käyttäjiltä, joita et seuraa invite: comment: Kommentoi invite_request: text: Miksi haluat liittyä? ip_block: comment: Kommentti - ip: IP + ip: IP-osoite severities: no_access: Estä pääsy sign_up_block: Estä kirjautumiset @@ -279,16 +284,25 @@ fi: notification_emails: appeal: Joku valittaa valvojan päätöksestä digest: Lähetä koosteviestejä sähköpostitse - favourite: Lähetä sähköposti, kun joku tykkää tilastasi - follow: Lähetä sähköposti, kun joku seuraa sinua - follow_request: Lähetä sähköposti, kun joku pyytää seurata sinua - mention: Lähetä sähköposti, kun sinut mainitaan - pending_account: Uusi tili tarvitsee tarkastusta - reblog: Lähetä sähköposti, kun joku tehosti viestiäsi + favourite: Joku lisäsi julkaisusi suosikkeihinsa + follow: Joku seurasi sinua + follow_request: Joku pyysi saada seurata sinua + mention: Joku mainitsi sinut + pending_account: Uusi tili tarvitsee tarkistusta + reblog: Joku tehosti julkaisuasi report: Uusi raportti on lähetetty - trending_tag: Uusi trendi vaatii tarkastelua + software_updates: + all: Ilmoita kaikista päivityksistä + critical: Ilmoita vain kriittisistä päivityksistä + label: Uusi Mastodon-versio on saatavilla + none: Älä koskaan ilmoita päivityksistä (ei suositeltu) + patch: Ilmoita virhekorjauspäivityksistä + trending_tag: Uusi trendi vaatii tarkistusta rule: text: Sääntö + settings: + indexable: Sisällytä profiilisivu hakukoneisiin + show_application: Näytä, mistä sovelluksesta lähetit julkaisun tag: listable: Salli tämän aihetunnisteen näkyä hauissa ja ehdotuksissa name: Aihetunniste @@ -296,6 +310,7 @@ fi: usable: Salli julkaisujen käyttää tätä aihetunnistetta user: role: Rooli + time_zone: Aikavyöhyke user_role: color: Merkin väri highlighted: Näyttä rooli merkkinä käyttäjäprofiileissa @@ -304,9 +319,11 @@ fi: position: Prioriteetti webhook: events: Tapahtumat käytössä + template: Hyötykuormapohja url: Päätepisteen URL 'no': Ei not_recommended: Ei suositella + overridden: Ohitettu recommended: Suositeltu required: mark: "*" diff --git a/config/locales/simple_form.fo.yml b/config/locales/simple_form.fo.yml index 2713d1f89a..e4d87e1786 100644 --- a/config/locales/simple_form.fo.yml +++ b/config/locales/simple_form.fo.yml @@ -2,6 +2,14 @@ fo: simple_form: hints: + account: + discoverable: Tínir almennu postar og tín vangi kunnu vera drigin fram og viðmæld ymsa staðni í Mastodon og vangin hjá tær kann vera viðmæltur øðrum brúkarum. + display_name: Títt fulla navn og títt stuttliga navn. + fields: Heimasíðan hjá tær, fornøvn, aldur ella hvat tú vil. + indexable: Almennu postar tínir kunnu vera sjónligir í leitiúrslitum á Mastodon. Óansæð, so kunnu fólk, sum hava samvirkað við tínar postar, finna teir. + note: 'Tú kanst @umrøða onnur fólk ella #frámerki.' + show_collections: Tað verður gjørligt hjá fólki at kaga í listan yvir tey, sum fylgja tær, og tey, sum tú fylgir. Tó so, fólk, sum tú fylgir, síggja at tú fylgir teimum. + unlocked: Fólk kunnu fylgja tær uttan at biðja um loyvi. Frável hetta, um tú vilt eftirkanna umbønir og góðkenna ella avvísa nýggjar fylgjarar. account_alias: acct: Upplýs brúkaranavn@navnaøki á kontuni, sum tú vilt flyta frá account_migration: @@ -37,14 +45,11 @@ fo: current_password: Av trygdarávum vinarliga les inn loyniorðið hjá verandi kontu current_username: Fyri at vátta, vinarliga les inn brúkaranavnið á verandi kontu digest: Einans sent eftir eitt langt tíðarskeið við óvirkni og einans um tú hevur móttikið persónlig boð meðan tú var burtur - discoverable: Loyv kontu tíni at verða funnin av fremmandum gjøgnum viðmæli, rák og aðrar hentleikar email: Tú fær sendandi ein váttanarteldupost - fields: Tú kanst hava upp til 4 lutir vístar sum eina talvu á vanga tínum header: PNG, GIF ella JPG. Ikki størri enn %{size}. Verður minkað til %{dimensions}px inbox_url: Avrita URL'in frá forsíðuni hjá reiðlagnum, sum tú vilt brúka irreversible: Filtreraðir postar blíva burtur med alla, eisini sjálvt um filtrið seinni verður strikað locale: Málið, sum verður brúkt í brúkaramarkamótinum, teldupostum og skumpiboðum - locked: Stýr hvør kann fylgja tær við at góðtaka ella vraka umbønir um at fylgja password: Skriva minst 8 tekin phrase: Fer at samsvara óanæsð um tað er skrivað við lítlum ella stórum ella um postar hava innihaldsávaringar scopes: Hvørji API nýtsluskipanin fær atgongd til. Velur tú eitt vav á hægsta stigi, so er ikki neyðugt at velja tey einstøku. @@ -54,12 +59,9 @@ fo: setting_display_media_default: Fjal miðlafílur, sum eru merktar sum viðkvæmar setting_display_media_hide_all: Fjal altíð miðlafílur setting_display_media_show_all: Vís altíð miðlafílur - setting_hide_network: Tey, ið tú fylgir og tey, ið fylgja tær, verða ikki víst á tínum vanga - setting_noindex: Ávirkar almenna vangan og síður við postum hjá tær - setting_show_application: Nýtsluskipanin, sum tú brúkar at posta við, verður víst í nágreinligu vísingini av postum tínum setting_use_blurhash: Gradientar eru grundaðir á litirnar av fjaldu myndunum, men grugga allar smálutir setting_use_pending_items: Fjal tíðarlinjudagføringar aftan fyri eitt klikk heldur enn at skrulla tilføringina sjálvvirkandi - username: Brúkaranavnið hjá tær verður eindømi á %{domain} + username: Tú kanst brúka bókstavir, tøl og botnstrikur whole_word: Tá lyklaorðið ella frasan einans hevur bókstavir og tøl, so verður hon einans nýtt, um tú samsvarar við alt orðið domain_allow: domain: Økisnavnið kann heinta dátur frá hesum ambætaranum og inngangandi dátur frá honum verða viðgjørdar og goymdar @@ -118,6 +120,9 @@ fo: sessions: otp: 'Skriva tvey-faktor koduna frá telefon-appini ella brúka eina av tínum endurgerðskodum:' webauthn: Er tað ein geymi, minst so til at seta hann í og, um neyðugt, pikka hann. + settings: + indexable: Vangasíðan hjá tær kann síggjast í leitiúrslitum á Google, Bing og aðrastaðni. + show_application: Óansæð, so er altíð møguligt hjá tær at síggja, hvør app postaði tín post. tag: name: Tú kanst einans broyta millum stórar og smáar stavir, til dømis fyri at gera tað meira lesiligt user: @@ -131,12 +136,17 @@ fo: position: Hægri leiklutur er avgerandi fyri loysn av ósemjum í ávísum støðum. Ávísar atgerðir kunnu einans verða gjørdar móti leiklutum, sum hava eina lægri raðfesting webhook: events: Vel hendingar at senda + template: Samanset títt egna JSON farm við at brúka variabul-interpolasjón. Lat vera blankt fyri sjálvgaldandi JSON. url: Hvar hendingar verða sendar til labels: account: + discoverable: Framheva vanga og postar í uppdagingar-algoritmum fields: name: Spjaldur value: Innihald + indexable: Tak almennar postar við í leitiúrslit + show_collections: Vís fylgjarar og tey, tú fylgir, á vanganum + unlocked: Góðtak nýggjar fylgjarar sjálvvirkandi account_alias: acct: Brúkaranavn á gomlu kontuni account_migration: @@ -174,7 +184,6 @@ fo: context: Filtrera kontekstir current_password: Núverandi loyniorð data: Dáta - discoverable: Skjót kontuna upp fyri øðrum display_name: Navn, sum skal vísast email: Teldubrævabústaður expires_in: Endar aftan á @@ -184,7 +193,6 @@ fo: inbox_url: URL'ur hjá innbakkanum hjá reiðlagnum irreversible: Strika heldur enn at fjala locale: Markamótsmál - locked: Krev umbønir um at fylgja max_uses: Ikki brúka oftari enn new_password: Nýtt loyniorð note: Ævilýsing @@ -196,7 +204,6 @@ fo: setting_always_send_emails: Send altíð fráboðanir við telduposti setting_auto_play_gif: Spæl teknimyndagjørdar GIFar sjálvvirkandi setting_boost_modal: Vís váttanarmynd, áðrenn tú stimbrar postar - setting_crop_images: Sker myndir til lutfallið 16x9 í postum, sum ikki eru víðkaðir setting_default_language: Mál, sum verður brúkt til postar setting_default_privacy: Hvussu privatir eru postar? setting_default_sensitive: Merk altíð miðlafílur sum viðkvæmar @@ -208,9 +215,7 @@ fo: setting_display_media_show_all: Vís alt setting_expand_spoilers: Víðka altíð postar, sum eru merktir við innihaldsávaringum setting_hide_network: Fjal sosiala grafin hjá tær - setting_noindex: Frábið tær indeksering á leitimaskinum setting_reduce_motion: Minka um rørslu í teknimyndum - setting_show_application: Avdúka serskipan, sum verður brúkt til at senda postar setting_system_font_ui: Brúka vanliga skriftaslagið hjá skipanini setting_theme: Uppsetingareyðkenni setting_trends: Vís dagsins rák @@ -286,9 +291,18 @@ fo: pending_account: Nýggj konta krevur viðgerð reblog: Onkur stimbraði postin hjá tær report: Nýggj melding er send inn + software_updates: + all: Gev fráboðan um allar dagføringar + critical: Gev einans fráboðan um kritiskar dagføringar + label: Ein nýggj Mastodon-útgáva er tøk + none: Gev aldrin fráboðan um dagføringar (ikki viðmælt) + patch: Gev fráboðan um feilrættingardagføringar trending_tag: Broytt rák skal kannast rule: text: Regla + settings: + indexable: Lat vangasíðu vera tøka í leitimaskinum + show_application: Vís frá hvørjari app tú sendi ein post tag: listable: Loyva hesum tvíkrossið, at verða vístur í leitingum og uppskotum name: Tvíkrossur @@ -296,6 +310,7 @@ fo: usable: Loyva uppsløgum at brúka hendan tvíkross user: role: Leiklutur + time_zone: Tíðarsona user_role: color: Litur á tignarmerki highlighted: Vís leiklut sum tignarmerki á brúkaravangum @@ -304,9 +319,11 @@ fo: position: Raðfesting webhook: events: Virknar hendingar + template: Farmaformur url: Endapunkts-URLur 'no': Nei not_recommended: Ikki viðmælt + overridden: Ógildað recommended: Viðmælt required: mark: "*" diff --git a/config/locales/simple_form.fr-QC.yml b/config/locales/simple_form.fr-QC.yml index bc78f0ae65..7a95a1c882 100644 --- a/config/locales/simple_form.fr-QC.yml +++ b/config/locales/simple_form.fr-QC.yml @@ -2,6 +2,14 @@ fr-QC: simple_form: hints: + account: + discoverable: Vos messages publics et votre profil peuvent être mis en avant ou recommandés dans diverses parties de Mastodon et votre profil peut être suggéré à d’autres utilisateurs. + display_name: Votre nom complet ou votre nom cool. + fields: Votre page d'accueil, pronoms, âge, tout ce que vous voulez. + indexable: Vos messages publics peuvent apparaître dans les résultats de recherche sur Mastodon. Les personnes qui ont interagi avec vos messages peuvent les trouver dans une recherche quoi qu’il arrive. + note: 'Vous pouvez @mentionner d’autres personnes ou des #hashtags.' + show_collections: Les gens pourront voir les personnes que vous suivez ou qui vous suivent. Ceux que vous suivez verront que vous les suivez dans tous les cas. + unlocked: Les gens pourront vous suivre sans demander d'approbation. Décochez cette option si vous voulez valider les demandes d'abonnement et choisir d'accepter ou de rejeter les nouveaux abonnés. account_alias: acct: Spécifiez l’identifiant@domaine du compte que vous souhaitez faire migrer account_migration: @@ -37,14 +45,11 @@ fr-QC: current_password: Par mesure de sécurité, veuillez saisir le mot de passe de ce compte current_username: Pour confirmer, veuillez saisir le nom d'utilisateur de ce compte digest: Uniquement envoyé après une longue période d’inactivité en cas de messages personnels reçus pendant votre absence - discoverable: Permet à votre compte d’être découvert par des inconnus par le biais de recommandations, de tendances et autres fonctionnalités email: Vous recevrez un courriel de confirmation - fields: Vous pouvez avoir jusqu’à 4 éléments affichés en tant que tableau sur votre profil header: Au format PNG, GIF ou JPG. %{size} maximum. Sera réduit à %{dimensions}px inbox_url: Copiez l’URL depuis la page d’accueil du relai que vous souhaitez utiliser irreversible: Les messages filtrés disparaîtront irrévocablement, même si le filtre est supprimé plus tard locale: La langue de l’interface, des courriels et des notifications - locked: Nécessite que vous approuviez manuellement chaque abonné·e password: Utilisez au moins 8 caractères phrase: Sera filtré peu importe la casse ou l’avertissement de contenu du message 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. @@ -54,12 +59,9 @@ fr-QC: setting_display_media_default: Masquer les médias marqués comme sensibles setting_display_media_hide_all: Toujours masquer les médias setting_display_media_show_all: Toujours afficher les médias - setting_hide_network: Ceux que vous suivez et ceux qui vous suivent ne seront pas affichés sur votre profil - setting_noindex: Affecte votre profil public ainsi que vos messages - setting_show_application: Le nom de l’application que vous utilisez pour publier sera affichée dans la vue détaillée de vos messages setting_use_blurhash: Les dégradés sont basés sur les couleurs des images cachées mais n’en montrent pas les détails setting_use_pending_items: Cacher les mises à jour des fils d’actualités derrière un clic, au lieu de les afficher automatiquement - username: Votre nom d’utilisateur sera unique sur %{domain} + username: Vous pouvez utiliser des lettres, des chiffres, et des tirets bas whole_word: Si le mot-clé ou la phrase est alphanumérique, alors le filtre ne sera appliqué que s’il correspond au mot entier domain_allow: domain: Ce domaine pourra récupérer des données de ce serveur et les données entrantes seront traitées et stockées @@ -82,7 +84,7 @@ fr-QC: custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon. mascot: Remplace l'illustration dans l'interface Web avancée. media_cache_retention_period: Les fichiers multimédias téléchargés seront supprimés après le nombre de jours spécifiés lorsque la valeur est positive, et seront téléchargés à nouveau sur demande. - peers_api_enabled: Une liste de noms de domaine que ce serveur a rencontrés dans le fediverse. Aucune donnée indiquant si vous vous fédérez ou non avec un serveur particulier n'est incluse ici, seulement l'information que votre serveur connaît un autre serveur. Cette option est utilisée par les services qui collectent des statistiques sur la fédération en général. + peers_api_enabled: Une liste de noms de domaine que ce serveur a rencontrés dans le fédiverse. Aucune donnée indiquant si vous vous fédérez ou non avec un serveur particulier n'est incluse ici, seulement l'information que votre serveur connaît un autre serveur. Cette option est utilisée par les services qui collectent des statistiques sur la fédération en général. profile_directory: L'annuaire des profils répertorie tous les utilisateurs qui ont opté pour être découverts. require_invite_text: Lorsque les inscriptions nécessitent une approbation manuelle, rendre le texte de l’invitation "Pourquoi voulez-vous vous inscrire ?" obligatoire plutôt que facultatif site_contact_email: Comment les personnes peuvent vous joindre pour des demandes de renseignements juridiques ou d'assistance. @@ -91,11 +93,13 @@ fr-QC: site_short_description: Une courte description pour aider à identifier de manière unique votre serveur. Qui l'exécute, à qui il est destiné ? site_terms: Utilisez votre propre politique de confidentialité ou laissez vide pour utiliser la syntaxe par défaut. Peut être structurée avec la syntaxe Markdown. site_title: Comment les personnes peuvent se référer à votre serveur en plus de son nom de domaine. + status_page_url: URL d'une page où les gens peuvent voir l'état de ce serveur en cas de panne theme: Thème que verront les utilisateur·rice·s déconnecté·e·s ainsi que les nouveaux·elles utilisateur·rice·s. thumbnail: Une image d'environ 2:1 affichée à côté des informations de votre serveur. timeline_preview: Les visiteurs déconnectés pourront parcourir les derniers messages publics disponibles sur le serveur. trendable_by_default: Ignorer l'examen manuel du contenu tendance. Des éléments individuels peuvent toujours être supprimés des tendances après coup. trends: Les tendances montrent quelles publications, hashtags et actualités sont en train de gagner en traction sur votre serveur. + trends_as_landing_page: Afficher le contenu tendance au lieu d'une description de ce serveur pour les comptes déconnectés et les non-inscrit⋅e⋅s. Nécessite que les tendances soient activées. form_challenge: current_password: Vous entrez une zone sécurisée imports: @@ -116,6 +120,9 @@ fr-QC: sessions: otp: 'Entrez le code d’authentification à deux facteurs généré par l’application de votre téléphone ou utilisez un de vos codes de récupération :' webauthn: Si c'est une clé USB, assurez-vous de l'insérer et, si nécessaire, de la tapoter. + settings: + indexable: Votre page de profil peut apparaître dans les résultats de recherche sur Google, Bing et autres. + show_application: Vous pourrez toujours voir quelle application vous avez utilisé pour publier un message dans tous les cas. tag: name: Vous ne pouvez modifier que la casse des lettres, par exemple, pour le rendre plus lisible user: @@ -129,12 +136,17 @@ fr-QC: position: Dans certaines situations, un rôle supérieur peut trancher la résolution d'un conflit. Mais certaines opérations ne peuvent être effectuées que sur des rôles ayant une priorité inférieure webhook: events: Sélectionnez les événements à envoyer + template: Écrivez votre propre bloc JSON avec la possibilité d’utiliser de l’interpolation de variables. Laissez vide pour le bloc JSON par défaut. url: Là où les événements seront envoyés labels: account: + discoverable: Autoriser des algorithmes de découverte à mettre en avant votre profil et vos messages fields: name: Étiquette value: Contenu + indexable: Inclure mes messages publics dans les résultats de recherche + show_collections: Afficher les profils abonnés et suivis sur le profil + unlocked: Accepter automatiquement les nouveaux abonnés account_alias: acct: Identifiant de l’ancien compte account_migration: @@ -172,7 +184,6 @@ fr-QC: context: Contextes du filtre current_password: Mot de passe actuel data: Données - discoverable: Suggérer ce compte aux autres display_name: Nom public email: Adresse courriel expires_in: Expire après @@ -182,7 +193,6 @@ fr-QC: inbox_url: URL de la boîte de relais irreversible: Supprimer plutôt que masquer locale: Langue de l’interface - locked: Verrouiller le compte max_uses: Nombre maximum d’utilisations new_password: Nouveau mot de passe note: Présentation @@ -194,7 +204,6 @@ fr-QC: setting_always_send_emails: Toujours envoyer les notifications par courriel setting_auto_play_gif: Lire automatiquement les GIFs animés setting_boost_modal: Demander confirmation avant de partager un message - setting_crop_images: Recadrer en 16x9 les images des messages qui ne sont pas ouverts en vue détaillée setting_default_language: Langue de publication setting_default_privacy: Confidentialité des messages setting_default_sensitive: Toujours marquer les médias comme sensibles @@ -206,9 +215,7 @@ fr-QC: setting_display_media_show_all: Montrer tout setting_expand_spoilers: Toujours déplier les messages marqués d’un avertissement de contenu setting_hide_network: Cacher votre réseau - setting_noindex: Demander aux moteurs de recherche de ne pas indexer vos informations personnelles setting_reduce_motion: Réduire la vitesse des animations - setting_show_application: Dévoiler l’application utilisée pour envoyer les messages setting_system_font_ui: Utiliser la police par défaut du système setting_theme: Thème du site setting_trends: Afficher les tendances du jour @@ -225,7 +232,7 @@ fr-QC: email_domain_block: with_dns_records: Inclure les enregistrements MX et IP du domaine featured_tag: - name: Hashtag + name: Mot-clic filters: actions: hide: Cacher complètement @@ -251,11 +258,13 @@ fr-QC: site_short_description: Description du serveur site_terms: Politique de confidentialité site_title: Nom du serveur + status_page_url: URL de la page de l'état du serveur theme: Thème par défaut thumbnail: Miniature du serveur timeline_preview: Autoriser l’accès non authentifié aux fils publics trendable_by_default: Autoriser les tendances sans révision préalable trends: Activer les tendances + trends_as_landing_page: Utiliser les tendances comme page d'accueil interactions: must_be_follower: Bloquer les notifications des personnes qui ne vous suivent pas must_be_following: Bloquer les notifications des personnes que vous ne suivez pas @@ -282,16 +291,26 @@ fr-QC: pending_account: Nouveau compte en attente d’approbation reblog: Quelqu’un a partagé mon message report: Nouveau signalement soumis + software_updates: + all: Notifier toutes les mises à jour + critical: Notifier pour les mises à jour critiques uniquement + label: Une nouvelle mise à jour de Mastodon est disponible + none: Ne jamais notifier des mises à jour (déconseillé) + patch: Notifier pour des mises à jour de corrections de bug trending_tag: Nouvelle tendance nécessitant supervision rule: text: Règle + settings: + indexable: Inclure la page de profil dans les moteurs de recherches + show_application: Afficher quelle application a été utilisée pour envoyer un message tag: listable: Autoriser ce hashtag à apparaître dans les recherches et dans l’annuaire des profils - name: Hashtag + name: Mot-clic trendable: Autoriser ce hashtag à apparaitre dans les tendances usable: Autoriser les messages à utiliser ce hashtag user: role: Rôle + time_zone: Fuseau horaire user_role: color: Couleur du badge highlighted: Afficher le rôle avec un badge sur les profils des utilisateur·rice·s @@ -300,9 +319,11 @@ fr-QC: position: Priorité webhook: events: Événements activés + template: Modèle de charge utile url: URL du point de terminaison 'no': Non not_recommended: Non recommandé + overridden: Surchargé recommended: Recommandé required: mark: "*" diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index d395b8517e..5a74facb7a 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -2,6 +2,14 @@ fr: simple_form: hints: + account: + discoverable: Vos messages publics et votre profil peuvent être mis en avant ou recommandés dans diverses parties de Mastodon et votre profil peut être suggéré à d’autres utilisateurs. + display_name: Votre nom complet ou votre nom rigolo. + fields: Votre page personnelle, vos pronoms, votre âge, ce que vous voulez. + indexable: Vos messages publics peuvent apparaître dans les résultats de recherche sur Mastodon. Les personnes qui ont interagi avec vos messages peuvent les trouver dans une recherche quoi qu’il arrive. + note: 'Vous pouvez @mentionner d’autres personnes ou des #hashtags.' + show_collections: Les gens pourront voir les personnes que vous suivez ou qui vous suivent. Ceux que vous suivez verront que vous les suivez dans tous les cas. + unlocked: Les gens pourront vous suivre sans demander d'approbation. Décochez cette option si vous voulez valider les demandes d'abonnement et choisir d'accepter ou de rejeter les nouveaux abonnés. account_alias: acct: Spécifiez l’identifiant@domaine du compte à partir duquel vous souhaitez migrer account_migration: @@ -37,14 +45,11 @@ fr: current_password: Par mesure de sécurité, veuillez saisir le mot de passe de ce compte current_username: Pour confirmer, veuillez saisir l’identifiant de ce compte digest: Uniquement envoyé après une longue période d’inactivité en cas de messages personnels reçus pendant votre absence - discoverable: Permet à votre compte d’être découvert par des inconnus par le biais de recommandations, de tendances et autres fonctionnalités email: Vous recevrez un courriel de confirmation - fields: Vous pouvez avoir jusqu’à 4 éléments affichés en tant que tableau sur votre profil header: Au format PNG, GIF ou JPG. %{size} maximum. Sera réduit à %{dimensions}px inbox_url: Copiez l’URL depuis la page d’accueil du relais que vous souhaitez utiliser irreversible: Les messages filtrés disparaîtront irrévocablement, même si le filtre est supprimé plus tard locale: La langue de l’interface, des courriels et des notifications - locked: Nécessite que vous approuviez manuellement chaque abonné·e password: Utilisez au moins 8 caractères phrase: Sera filtré peu importe la casse ou l’avertissement de contenu du message 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. @@ -54,12 +59,9 @@ fr: setting_display_media_default: Masquer les médias marqués comme sensibles setting_display_media_hide_all: Toujours masquer les médias setting_display_media_show_all: Toujours afficher les médias - setting_hide_network: Ceux que vous suivez et ceux qui vous suivent ne seront pas affichés sur votre profil - setting_noindex: Affecte votre profil public ainsi que vos messages - setting_show_application: Le nom de l’application que vous utilisez pour publier sera affichée dans la vue détaillée de vos messages setting_use_blurhash: Les dégradés sont basés sur les couleurs des images cachées mais n’en montrent pas les détails setting_use_pending_items: Cacher les mises à jour des fils d’actualités derrière un clic, au lieu de les afficher automatiquement - username: Votre identifiant sera unique sur %{domain} + username: Vous pouvez utiliser des lettres, des chiffres, et des tirets bas whole_word: Si le mot-clé ou la phrase est alphanumérique, alors le filtre ne sera appliqué que s’il correspond au mot entier domain_allow: domain: Ce domaine pourra récupérer des données de ce serveur et les données entrantes seront traitées et stockées @@ -118,6 +120,9 @@ fr: sessions: otp: 'Entrez le code d’authentification à deux facteurs généré par l’application de votre téléphone ou utilisez un de vos codes de récupération :' webauthn: Si c'est une clé USB, assurez-vous de l'insérer et, si nécessaire, de la tapoter. + settings: + indexable: Votre page de profil peut apparaître dans les résultats de recherche sur Google, Bing et autres. + show_application: Vous pourrez toujours voir quelle application vous avez utilisé pour publier un message dans tous les cas. tag: name: Vous ne pouvez modifier que la casse des lettres, par exemple, pour le rendre plus lisible user: @@ -131,12 +136,17 @@ fr: position: Dans certaines situations, un rôle supérieur peut trancher la résolution d'un conflit. Mais certaines opérations ne peuvent être effectuées que sur des rôles ayant une priorité inférieure webhook: events: Sélectionnez les événements à envoyer + template: Écrivez votre propre bloc JSON avec la possibilité d’utiliser de l’interpolation de variables. Laissez vider pour utiliser le bloc JSON par défaut. url: Là où les événements seront envoyés labels: account: + discoverable: Autoriser des algorithmes de découverte à mettre en avant votre profil et vos messages fields: name: Étiquette value: Contenu + indexable: Inclure mes messages publics dans les résultats de recherche + show_collections: Afficher les profils abonnés et suivis sur le profil + unlocked: Accepter automatiquement les nouveaux abonnés account_alias: acct: Identifiant de l’ancien compte account_migration: @@ -174,7 +184,6 @@ fr: context: Contextes du filtre current_password: Mot de passe actuel data: Données - discoverable: Suggérer ce compte aux autres display_name: Nom public email: Adresse de courriel expires_in: Expire après @@ -184,7 +193,6 @@ fr: inbox_url: URL de la boîte de relais irreversible: Supprimer plutôt que masquer locale: Langue de l’interface - locked: Verrouiller le compte max_uses: Nombre maximum d’utilisations new_password: Nouveau mot de passe note: Présentation @@ -196,7 +204,6 @@ fr: setting_always_send_emails: Toujours envoyer les notifications par courriel setting_auto_play_gif: Lire automatiquement les GIFs animés setting_boost_modal: Demander confirmation avant de partager un message - setting_crop_images: Recadrer en 16x9 les images des messages qui ne sont pas ouverts en vue détaillée setting_default_language: Langue de publication setting_default_privacy: Confidentialité des messages setting_default_sensitive: Toujours marquer les médias comme sensibles @@ -208,9 +215,7 @@ fr: setting_display_media_show_all: Montrer tout setting_expand_spoilers: Toujours déplier les messages marqués d’un avertissement de contenu setting_hide_network: Cacher votre réseau - setting_noindex: Demander aux moteurs de recherche de ne pas indexer vos informations personnelles setting_reduce_motion: Réduire la vitesse des animations - setting_show_application: Dévoiler l’application utilisée pour envoyer les messages setting_system_font_ui: Utiliser la police par défaut du système setting_theme: Thème du site setting_trends: Afficher les tendances du jour @@ -286,9 +291,18 @@ fr: pending_account: Nouveau compte en attente d’approbation reblog: Quelqu’un a partagé votre message report: Nouveau signalement soumis + software_updates: + all: Notifier toutes les mises à jour + critical: Notifier pour les mises à jour critiques uniquement + label: Une nouvelle mise à jour de Mastodon est disponible + none: Ne jamais notifier des mises à jour (déconseillé) + patch: Notifier pour des mises à jour de corrections de bug trending_tag: Nouvelle tendance nécessitant supervision rule: text: Règle + settings: + indexable: Inclure la page de profil dans les moteurs de recherches + show_application: Afficher quelle application a été utilisée pour envoyer un message tag: listable: Autoriser ce hashtag à apparaître dans les recherches et dans l’annuaire des profils name: Hashtag @@ -296,6 +310,7 @@ fr: usable: Autoriser les messages à utiliser ce hashtag user: role: Rôle + time_zone: Fuseau horaire user_role: color: Couleur du badge highlighted: Afficher le rôle avec un badge sur les profils des utilisateur·rice·s @@ -304,9 +319,11 @@ fr: position: Priorité webhook: events: Événements activés + template: Modèle de payload url: URL du point de terminaison 'no': Non not_recommended: Non recommandé + overridden: Surchargé recommended: Recommandé required: mark: "*" diff --git a/config/locales/simple_form.fy.yml b/config/locales/simple_form.fy.yml index be950189b2..474d858382 100644 --- a/config/locales/simple_form.fy.yml +++ b/config/locales/simple_form.fy.yml @@ -2,6 +2,14 @@ fy: simple_form: hints: + account: + discoverable: Jo iepenbiere berjochten kinne útljochte wurde op ferskate plakken binnen Mastodon en jo account kin oanrekommandearre wurde oan oare brûkers. + display_name: Jo folsleine namme of in aardige bynamme. + fields: Jo website, persoanlike foarnammewurden, leeftiid, alles wat jo mar kwyt wolle. + indexable: Jo iepenbiere berjochten kinne ferskine yn de sykresultaten op Mastodon. Minsken dy’t reagearre hawwe op jo berjochten kinne se hoe dan ek trochsykje. + note: 'Jo kinne oare minsken @fermelde of #hashtags brûke.' + show_collections: Minsken kinne sjen wa’t jo folgje en wa’t jo folget. + unlocked: Minsken kinne jo folgje sûnder dêrfoar tastimming freegje te hoegen. Wannear’t jo nije folgers hânmjittich goedkarre wolle, moatte jo dizze opsje deselektearje. account_alias: acct: Fermeld de brûkersnamme@domein fan de account fan wêr’t jo ferhúzje wolle account_migration: @@ -37,14 +45,11 @@ fy: current_password: Fier foar feilichheidsredenen it wachtwurd fan jo aktuele account yn current_username: Fier ta befêstiging de brûkersnamme fan jo aktuele account yn digest: Wurdt allinnich nei in lange perioade fan ynaktiviteit ferstjoerd en allinnich wannear’t jo wylst jo ôfwêzigens persoanlike berjochten ûntfongen hawwe - discoverable: Tastean dat jo account te finen is foar ûnbekenden, fia oanrekommandaasjes, trends en op oare manieren email: Jo krije in befêstigings-e-mailberjocht - fields: Jo kinne maksimaal 4 items as in tabel op jo profyl werjaan header: PNG, GIF of JPG. Maksimaal %{size}. Wurdt weromskeald nei %{dimensions}px inbox_url: Kopiearje de URL fan de foarside fan de relayserver dy’t jo brûke wolle irreversible: Filtere berjochten ferdwine definityf, sels as it filter letter fuortsmiten wurdt locale: De taal fan de brûkersomjouwing, e-mailberjochten en pushmeldingen - locked: Troch it goedkarren fan folgers hânmjittich bepale wa’t jo folgje mei password: Brûk op syn minst 8 tekens phrase: Komt oerien nettsjinsteande haad-/lytse letters of in ynhâldswarskôging scopes: Ta hokker API’s hat de tapassing tagong. Wannear’t jo in tastimming fan it boppeste nivo kieze, hoege jo gjin yndividuele tastimmingen mear te kiezen. @@ -54,12 +59,9 @@ fy: setting_display_media_default: As gefoelich markearre media ferstopje setting_display_media_hide_all: Media altyd ferstopje setting_display_media_show_all: Media altyd toane - setting_hide_network: Wa’t jo folgje en wa’t jo folget wurdt net op jo profyl toand - setting_noindex: Hat ynfloed op jo iepenbiere profyl en siden mei berjochten - setting_show_application: De tapassing dy’t jo brûke om berjochten te pleatsen, wurdt yn de detaillearre werjefte fan it berjocht toand setting_use_blurhash: Dizige kleuroergongen binne basearre op de kleuren fan de ferstoppe media, wêrmei elk detail ferdwynt setting_use_pending_items: De tiidline wurdt bywurke troch op it oantal nije items te klikken, yn stee fan dat dizze automatysk bywurke wurdt - username: Jo brûkersnamme is unyk op %{domain} + username: Jo kinne letters, sifers en ûnderstreekjes brûke whole_word: Wannear it trefwurd of part fan de sin alfanumeryk is, wurdt it allinnich filtere wannear’t it hiele wurd oerienkomt domain_allow: domain: Dit domein is yn steat om gegevens fan dizze server op te heljen, en ynkommende gegevens wurde ferwurke en bewarre @@ -118,6 +120,9 @@ fy: sessions: otp: 'Fier de twa-stapstagongskoade fan jo mobile telefoan ôf yn of brûk ien fan jo werstelkoaden:' webauthn: Wannear’t it in USB-kaai is, soargje der dan foar dat jo dizze yn de kompjûter stekke en, wannear nedich, aktivearje. + settings: + indexable: Jo profylside kin yn de sykresultaten fan Google, Bing, DuckDuckGo en oare sykmasinen ferskine. + show_application: Jo kinne sels altyd sjen mei hokker app jo in berjocht pleatst hawwe. tag: name: Jo kinne elk wurd mei in haadletter begjinne, om sa bygelyks de tekst mear lêsber te meitsjen user: @@ -131,12 +136,17 @@ fy: position: In hegere rol beslist yn bepaalde situaasjes oer it oplossen fan konflikten. Bepaalde aksjes kinne allinnich útfierd wurde op rollen mei in legere prioriteit webhook: events: Selektearje de te ferstjoeren eveneminten + template: Meitsje eigen JSON-payload oan mei fariabele ynterpolaasje. Lit leech foar standert JSON. url: Wêr’t eveneminten nei ta stjoerd wurde labels: account: + discoverable: Profyl en bydragen yn sykalgoritmen opnimme litte fields: name: Label value: Ynhâld + indexable: Iepenbiere berjochten opnimme yn sykresultaten + show_collections: Accounts dy’t jó folgje en dy’t jo fólgje op jo profyl toane + unlocked: Automatysk nije folgers akseptearje account_alias: acct: Mastodonadres fan it âlde account account_migration: @@ -174,7 +184,6 @@ fy: context: Filterlokaasjes current_password: Aktueel wachtwurd data: Gegevens - discoverable: Dizze account oanrekommandearje litte en yn de brûkersgids toane display_name: Werjeftenamme email: E-mailadres expires_in: Ferrint nei @@ -184,7 +193,6 @@ fy: inbox_url: Relais-ynboks-URL irreversible: Fuortsmite yn stee fan ferstopje locale: Taal fan de brûkersomjouwing - locked: Folchfersyk fereaskje max_uses: Maksimaal tal kear te brûken new_password: Nije wachtwurd note: Bio @@ -196,7 +204,6 @@ fy: setting_always_send_emails: Altyd e-mailmeldingen ferstjoere setting_auto_play_gif: Spylje animearre GIF’s automatysk ôf setting_boost_modal: Freegje foar it boosten fan in berjocht in befêstiging - setting_crop_images: Ofbyldingen bysnije oant 16x9 yn berjochten op tiidlinen setting_default_language: Taal fan jo berjochten setting_default_privacy: Sichtberheid fan nije berjochten setting_default_sensitive: Media altyd as gefoelich markearje @@ -208,9 +215,7 @@ fy: setting_display_media_show_all: Alles toane setting_expand_spoilers: Berjochten mei ynhâldswarskôgingen altyd útklappe setting_hide_network: Jo folgers en wa’t jo folget ferstopje - setting_noindex: Jo berjochten net troch sykmasinen yndeksearje litte setting_reduce_motion: Stadigere animaasjes - setting_show_application: Tapassing dy’t jo foar it ferstjoeren fan berjochten brûke toane setting_system_font_ui: Standertlettertype fan jo systeem brûke setting_theme: Websitetema setting_trends: Trends fan hjoed toane @@ -286,9 +291,18 @@ fy: pending_account: Wannear in nij account beoardiele wurde moat reblog: Wannear ien jo berjocht boost hat report: Nije rapportaazje yntsjinne is + software_updates: + all: Meldingen jaan foar alle fernijingen + critical: Allinnich meldingen foar kritike fernijingen jaan + label: Der is in nije ferzje fan Mastodon beskikber + none: Nea meldingen fan fernijingen jaan (net oanrekommandearre) + patch: Meldingen by bugfix-fernijingen trending_tag: Nije trend beoardieling fereasket rule: text: Regel + settings: + indexable: Sykmasinen jo profylside fine litte + show_application: App dy’t jo foar it pleatsen fan berjochten brûke toane tag: listable: Tastean dat dizze hashtag yn sykopdrachten en oanrekommandaasjes te sjen is name: Hashtag @@ -296,6 +310,7 @@ fy: usable: Tastean dat dizze hashtag yn berjochten brûkt wurde mei user: role: Rol + time_zone: Tiidsône user_role: color: Badgekleur highlighted: Rol as badge op profylsiden toane @@ -304,9 +319,11 @@ fy: position: Prioriteit webhook: events: Ynskeakele eveneminten + template: Payload-sjabloan url: Einpunt-URL 'no': Nee not_recommended: Net oanrekommandearre + overridden: Oerskreaun recommended: Oanrekommandearre required: mark: "*" diff --git a/config/locales/simple_form.ga.yml b/config/locales/simple_form.ga.yml index 39190ad9b4..3597544ce3 100644 --- a/config/locales/simple_form.ga.yml +++ b/config/locales/simple_form.ga.yml @@ -3,15 +3,15 @@ ga: simple_form: hints: account_alias: - acct: Sonraigh ainm@fearann an chuntais ar mhaith leat aistriú uaidh + acct: Sonraigh ainm@fearann don chuntas ar mhaith leat aistriú uaidh account_migration: - acct: Sonraigh ainm@fearann an chuntais ar mhaith leat aistriú chuige + acct: Sonraigh ainm@fearann don chuntas ar mhaith leat aistriú chuige admin_account_action: types: - disable: Cuir cosc ar an úsáideoir a chuntas a úsáid, ach ná scrios nó folaigh a bhfuil ann. + disable: Cuir cosc ar an úsáideoir a chuntas a úsáid, ach ná scrios ná folaigh a bhfuil ann. defaults: - setting_display_media_hide_all: Folaítear meáin i gcónaí - setting_display_media_show_all: Go dtaispeántar meáin i gcónaí + setting_display_media_hide_all: Folaigh meáin i gcónaí + setting_display_media_show_all: Taispeáin meáin i gcónaí labels: account: fields: @@ -40,7 +40,7 @@ ga: setting_display_media_hide_all: Cuir uile i bhfolach setting_display_media_show_all: Taispeáin uile setting_theme: Téama suímh - setting_trends: Taispeáin treochta an lae + setting_trends: Taispeáin treochtaí an lae inniu title: Teideal username: Ainm úsáideora featured_tag: diff --git a/config/locales/simple_form.gd.yml b/config/locales/simple_form.gd.yml index 55df2370da..f567866c3e 100644 --- a/config/locales/simple_form.gd.yml +++ b/config/locales/simple_form.gd.yml @@ -2,6 +2,14 @@ gd: simple_form: hints: + account: + discoverable: Dh’fhaoidte gun dèid na postaichean poblach ’s a’ phròifil agad a bhrosnachadh no a mholadh ann an caochladh roinnean de Mhastodon agus gun dèid a’ phròifil agad a mholadh do chàch. + display_name: D’ ainm slàn no spòrsail. + fields: An duilleag-dhachaigh agad, roimhearan, aois, rud sam bith a thogras tu. + indexable: Faodaidh na postaichean poblach agad a nochdadh am measg toraidhean luirg air Mastodon. ’S urrainn dhan fheadhainn a rinn eadar-ghabhail leis na postaichean agad lorg annta air a h-uile dòigh. + note: "’S urrainn dhut @iomradh a thoirt air càch no air #tagaicheanHais." + show_collections: "’S urrainn do chàch na dàimhean leantainn agad a rùrachadh. Chì daoine a leanas tu gu bheil thu ’gan leantainn air a h-uile dòigh." + unlocked: "’S urrainnear do leantainn gun aontachadh iarraidh. Thoir a’ chromag far a’ bhogsa nam bu mhiann leat lèirmheas a dhèanamh air na h-iarrtasan leantainn agus taghadh an aontaich thu ri neach-leantainn ùr no an dhiùlt thu iad." account_alias: acct: Sònraich ainm-cleachdaiche@àrainn dhen chunntas a tha thu airson imrich uaithe account_migration: @@ -18,6 +26,8 @@ gd: disable: Bac an cleachdaiche o chleachdadh a’ chunntais aca ach na sguab às no falaich an t-susbaint aca. none: Cleachd seo airson rabhadh a chur dhan chleachdaiche gun ghnìomh eile a ghabhail. sensitive: Èignich comharra gu bheil e frionasach air a h-uile ceanglachan meadhain a’ chleachdaiche seo. + silence: Bac an cleachdaiche o bhith a’ postadh le faicsinneachd poblach, falaich na postaichean aca agus brathan o na daoine nach eil ’ga leantainn. Dùinidh seo gach gearan mun chunntas seo. + suspend: Bac eadar-ghnìomh sam bith leis a’ chunntas seo agus sguab às an t-susbaint aige. Gabhaidh seo a neo-dhèanamh am broinn 30 latha. Dùinidh seo gach gearan mun chunntas seo. warning_preset_id: Roghainneil. ’S urrainn dhut teacsa gnàthaichte a chur ri deireadh an ro-sheata fhathast announcement: all_day: Nuair a bhios cromag ris, cha nochd ach cinn-latha na rainse-ama @@ -35,14 +45,11 @@ gd: current_password: A chùm tèarainteachd, cuir a-steach facal-faire a’ chunntais làithrich current_username: Airson seo a dhearbhadh, cuir a-steach ainm-cleachdaiche a’ chunntais làithrich digest: Cha dèid seo a chur ach nuair a bhios tu air ùine mhòr gun ghnìomh a ghabhail agus ma fhuair thu teachdaireachd phearsanta fhad ’s a bha thu air falbh - discoverable: Ceadaich gun rùraich coigrich an cunntas agad le taic o mholaidhean, treandaichean is gleusan eile email: Thèid post-d dearbhaidh a chur thugad - fields: Faodaidh tu suas ri 4 nithean a shealltainn mar chlàr air a’ phròifil agad header: PNG, GIF or JPG. %{size} air a char as motha. Thèid a sgèileadh sìos gu %{dimensions}px inbox_url: Dèan lethbhreac dhen URL o phrìomh-dhuilleag an ath-sheachadain a bu mhiann leat cleachdadh irreversible: Thèid postaichean criathraichte à sealladh gu buan fiù ’s ma bheir thu a’ chriathrag air falbh às dèidh làimhe locale: Cànan eadar-aghaidh a’ chleachdaiche, nam post-d ’s nam brathan putaidh - locked: Stiùirich cò dh’fhaodas ’gad leantainn le gabhail ri iarrtasan leantainn a làimh password: Cleachd co-dhiù 8 caractaran phrase: Thèid a mhaidseadh gun aire air litrichean mòra ’s beaga no air rabhadh susbainte puist scopes: Na APIan a dh’fhaodas an aplacaid inntrigeadh. Ma thaghas tu sgòp air ìre as àirde, cha leig thu leas sgòpaichean fa leth a thaghadh. @@ -52,12 +59,9 @@ gd: setting_display_media_default: Falaich meadhanan ris a bheil comharra gu bheil iad frionasach setting_display_media_hide_all: Falaich na meadhanan an-còmhnaidh setting_display_media_show_all: Seall na meadhanan an-còmhnaidh - setting_hide_network: Thèid cò a tha thu a’ leantainn ’s an luchd-leantainn agad fhèin a chur am falach air a’ phròifil agad - setting_noindex: Bheir seo buaidh air a’ phròifil phoblach ’s air duilleagan nam postaichean agad - setting_show_application: Chithear cò an aplacaid a chleachd thu airson post a sgrìobhadh ann an seallaidhean mionaideach nam postaichean agad 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 - username: Bidh ainm-cleachdaiche àraidh agad air %{domain} + username: Faodaidh tu litrichean, àireamhan is fo-loidhnichean a chleachdadh whole_word: Mur eil ach litrichean is àireamhan san fhacal-luirg, cha dèid a chur an sàs ach ma bhios e a’ maidseadh an fhacail shlàin domain_allow: domain: "’S urrainn dhan àrainn seo dàta fhaighinn on fhrithealaiche seo agus thèid an dàta a thig a-steach uaithe a phròiseasadh ’s a stòradh" @@ -72,13 +76,15 @@ gd: hide: Falaich an t-susbaint chriathraichte uile gu lèir mar nach robh i ann idir warn: Falaich an t-susbaint chriathraichte air cùlaibh rabhaidh a dh’innseas tiotal na criathraige form_admin_settings: + 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 backups_retention_period: Cùm na tasg-lannan a chaidh a ghintinn dhan luchd-cleachdaidh rè 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 na postaichean o fhrithealaichean eile a sguabadh às às dèidh an àireamh de làithean a shònraich thu nuair a bhios luach dearbh air. Dh’fhaoidte nach gabh seo a neo-dhèanamh. + content_cache_retention_period: Thèid gach post is brosnachadh o fhrithealaichean eile a sguabadh às às dèidh an àireamh de làithean a shònraicheas tu. Dh’fhaoidte nach gabh a h-uile post aiseag. Thèid gach comharran-lìn, annsachd is brosnachadh co-cheangailte riutha air chall cuideachd agus cha ghabh sin a neo-dhèanamh. custom_css: "’S urrainn dhut stoidhlean gnàthaichte a chur an sàs air an tionndadh-lìn de Mhastodon." mascot: Tar-àithnidh seo an sgead-dhealbh san eadar-aghaidh-lìn adhartach. media_cache_retention_period: Thèid na faidhlichean meadhain air an luchdadh a-nuas a sguabadh às às dèidh an àireamh de làithean a shònraich thu nuair a bhios luach dearbh air agus an ath-luachdadh nuair a thèid an iarraidh an uairsin. + peers_api_enabled: Seo liosta de dh’ainmean àrainne ris an do thachair am frithealaiche seo sa cho-shaoghal. Chan eil dàta sam bith ’ga ghabhail a-staigh an-seo mu a bheil thu co-naisgte ri frithealaiche sònraichte gus nach eil ach dìreach gu bheil am frithealaiche agad eòlach air. Thèid seo a chleachdadh le seirbheisean a chruinnicheas stadastaireachd air a’ cho-nasgadh san fharsaingeachd. profile_directory: Seallaidh eòlaire nam pròifil liosta dhen luchd-cleachdaidh a dh’aontaich gun gabh an rùrachadh. require_invite_text: Nuair a bhios aontachadh a làimh riatanach dhan chlàradh, dèan an raon teacsa “Carson a bu mhiann leat ballrachd fhaighinn?” riatanach seach roghainneil site_contact_email: Mar a ruigear thu le ceistean laghail no taice. @@ -87,11 +93,13 @@ gd: site_short_description: Tuairisgeul goirid a chuidicheas le aithneachadh sònraichte an fhrithealaiche agad. Cò leis is cò dha a tha e? site_terms: Cleachd am poileasaidh prìobhaideachd agad fhèin no fàg bàn e gus am fear bunaiteach a chleachdadh. ’S urrainn dhut structar a chur air le co-chàradh Markdown. site_title: An t-ainm a tha air an fhrithealaiche agad seach ainm àrainne. + status_page_url: URL duilleige far am faicear staid an fhrithealaiche seo nuair a bhios e sìos theme: An t-ùrlar a chì na h-aoighean gun chlàradh a-staigh agus an luchd-cleachdaidh ùr. thumbnail: Dealbh mu 2:1 a thèid a shealltainn ri taobh fiosrachadh an fhrithealaiche agad. timeline_preview: "’S urrainn dha na h-aoighean gun chlàradh a-staigh na postaichean poblach as ùire a tha ri fhaighinn air an fhrithealaiche a bhrabhsadh." trendable_by_default: Geàrr leum thar lèirmheas a làimh na susbainte a’ treandadh. Gabhaidh nithean fa leth a thoirt far nan treandaichean fhathast an uairsin. trends: Seallaidh na treandaichean na postaichean, tagaichean hais is naidheachdan a tha fèill mhòr orra air an fhrithealaiche agad. + trends_as_landing_page: Seall susbaint a’ treandadh dhan fheadhainn nach do chlàraich a-steach is do dh’aoighean seach tuairisgeul an fhrithealaiche seo. Feumaidh treandaichean a bhith an comas airson sin. form_challenge: current_password: Tha thu a’ tighinn a-steach gu raon tèarainte imports: @@ -101,7 +109,7 @@ gd: ip_block: comment: Roghainneil. Cùm an cuimhne carson an do chuir thu an riaghailt seo ris. expires_in: Tha an uiread de sheòlaidhean IP cuingichte is thèid an co-roinneadh aig amannan agus an gluasad do chuideigin eile gu tric. Air an adhbhar seo, cha mholamaid bacadh IP gun chrìoch. - ip: Cuir a-steach seòladh IPv4 no IPv6. ’S urrainn dhut rainsean gu lèir a bhacadh le co-chàradh CIDR. Thoir an aire nach gluais thu thu fhèin a-mach! + ip: Cuir a-steach seòladh IPv4 no IPv6. ’S urrainn dhut rainsean gu lèir a bhacadh le co-chàradh CIDR. Thoir an aire nach glais thu thu fhèin a-mach! severities: no_access: Bac inntrigeadh dha na goireasan uile sign_up_block: Cha bhi ùr-chlàradh ceadaichte @@ -112,6 +120,9 @@ gd: sessions: otp: 'Cuir a-steach an còd dà-cheumnach a ghin aplacaid an fhòn agad no cleachd fear dhe na còdan aisig agad:' webauthn: Mas e iuchair USB a th’ ann, dèan cinnteach gun cuir thu a-steach e is gun doir thu gnogag air ma bhios feum air sin. + settings: + indexable: Dh’fhaoidte gun nochd duilleag na pròifil agad am measg nan toraidhean luirg air Google, Bing is eile. + show_application: Gidheadh, chì thu dè an aplacaid a dh’fhoillsich am post agad an-còmhnaidh. tag: name: Mar eisimpleir, ’s urrainn dhut measgachadh de litrichean mòra ’s beaga a chleachdadh ach an gabh a leughadh nas fhasa user: @@ -125,12 +136,17 @@ gd: position: Ma tha còmhstri ann, buannaichidh an dreuchd as àirde ann an cuid a shuidheachaidhean. Tha gnìomhan sònraichte ann nach urrainn ach dreuchdan le prìomhachas ìosail a ghabhail webhook: events: Tagh na tachartasan a thèid a chur + template: Cruthaich an JSON payload agad fhèin le eadar-phòlachadh chaochladairean. Fàg seo bàn airson JSON bunaiteach fhaighinn. url: Far an dèid na tachartasan a chur labels: account: + discoverable: Brosnaich a’ phròifil is postaichean agad sna h-algairimean luirg fields: name: Leubail value: Susbaint + indexable: Gabh na postaichean poblach a-staigh ann an toraidhean luirg + show_collections: Seall na dàimhean leantainn air a’ phròifil + unlocked: Aontaich ri luchd-leantainn ùr gu fèin-obrachail account_alias: acct: Ainm-cleachdaiche an t-seann-chunntais account_migration: @@ -160,25 +176,23 @@ gd: text: Mìnich carson a bu chòir an caochladh a chur orra defaults: autofollow: Thoir cuireadh dhaibh airson an cunntas agad a leantainn - avatar: Avatar - bot: Seo cunntas bot + avatar: Dealbh na pròifil + bot: Seo cunntas fèin-obrachail chosen_languages: Criathraich na cànain confirm_new_password: Dearbh am facal-faire ùr confirm_password: Dearbh am facal-faire context: Co-theacsaichean na criathraige current_password: Am facal-faire làithreach data: Dàta - discoverable: Mol an cunntas do chàch display_name: Ainm-taisbeanaidh email: Seòladh puist-d expires_in: Falbhaidh an ùine air às dèidh - fields: Meata-dàta na pròifile - header: Bann-cinn + fields: Raointean a bharrachd + header: Dealbh a’ bhanna-chinn honeypot: "%{label} (na lìon seo)" inbox_url: URL bogsa a-steach an ath-sheachadain irreversible: Leig seachad seach falach locale: Cànan na h-eadar-aghaidh - locked: Iarr iarrtasan leantainn max_uses: An àireamh as motha de chleachdaidhean new_password: Facal-faire ùr note: Mu mo dhèidhinn @@ -190,7 +204,6 @@ gd: setting_always_send_emails: Cuir brathan puist-d an-còmhnaidh setting_auto_play_gif: Cluich GIFs beòthaichte gu fèin-obrachail setting_boost_modal: Seall còmhradh dearbhaidh mus dèan thu brosnachadh - setting_crop_images: Beàrr na dealbhan sna postaichean gun leudachadh air 16x9 setting_default_language: Cànan postaidh setting_default_privacy: Prìobhaideachd postaidh setting_default_sensitive: Cuir comharra ri meadhanan an-còmhnaidh gu bheil iad frionasach @@ -202,9 +215,7 @@ gd: setting_display_media_show_all: Seall na h-uile setting_expand_spoilers: Leudaich postaichean ris a bheil rabhadh susbainte an-còmhnaidh setting_hide_network: Falaich an graf sòisealta agad - setting_noindex: Thoir air falbh an ro-aonta air inneacsadh le einnseanan-luirg setting_reduce_motion: Ìslich an gluasad sna beòthachaidhean - setting_show_application: Foillsich dè an aplacaid a chleachdas tu airson postaichean a chur setting_system_font_ui: Cleachd cruth-clò bunaiteach an t-siostaim setting_theme: Ùrlar na làraich setting_trends: Seall na treandaichean an-diugh @@ -227,6 +238,7 @@ gd: hide: Falaich uile gu lèir warn: Falaich le rabhadh form_admin_settings: + activity_api_enabled: Foillsich agragaid dhen stadastaireachd mu ghnìomhachd nan cleachdaichean san API backups_retention_period: Ùine glèidhidh aig tasg-lannan an luchd-cleachdaidh bootstrap_timeline_accounts: Mol na cunntasan seo do chleachdaichean ùra an-còmhnaidh closed_registrations_message: Teachdaireachd ghnàthaichte nuair nach eil clàradh ri fhaighinn @@ -234,6 +246,7 @@ gd: custom_css: CSS gnàthaichte mascot: Suaichnean gnàthaichte (dìleabach) media_cache_retention_period: Ùine glèidhidh aig tasgadan nam meadhanan + peers_api_enabled: Foillsich liosta nam frithealaichean a chaidh a rùrachadh san API profile_directory: Cuir eòlaire nam pròifil an comas registrations_mode: Cò dh’fhaodas clàradh require_invite_text: Iarr adhbhar clàraidh @@ -245,11 +258,13 @@ gd: site_short_description: Tuairisgeul an fhrithealaiche site_terms: Poileasaidh prìobhaideachd site_title: Ainm an fhrithealaiche + status_page_url: URL duilleag na staide theme: An t-ùrlar bunaiteach thumbnail: Dealbhag an fhrithealaiche timeline_preview: Ceadaich inntrigeadh gun ùghdarrachadh air na loidhnichean-ama phoblach trendable_by_default: Ceadaich treandaichean gun lèirmheas ro làimh trends: Cuir na treandaichean an comas + trends_as_landing_page: Cleachd na treandaichean ’nan duilleag-laighe interactions: must_be_follower: Bac na brathan nach eil o luchd-leantainn must_be_following: Bac na brathan o dhaoine nach lean thu @@ -276,9 +291,18 @@ gd: pending_account: Tha cunntas ùr feumach air lèirmheas reblog: Bhrosnaich cuideigin am post agad report: Chaidh gearan ùr a chur a-null + software_updates: + all: Thoir brath dhomh do gach ùrachadh + critical: Thoir brathan dhomh do dh’ùrachaidhean èiginneach a-mhàin + label: Tha tionndadh ùr de Mhastodon ri fhaighinn + none: Na doir brathan thugam mu ùrachaidhean idir (cha mholamaid seo) + patch: Thoir brathan dhomh do dh’ùrachaidhean càraidh trending_tag: Tha treand ùr ri lèirmheasadh rule: text: Riaghailt + settings: + indexable: Gabh a-staigh duilleag na pròifil sna h-einnseanan-luirg + show_application: Seall dè an aplacaid a chuir thu post leatha tag: listable: Leig leis an taga hais seo gun nochd e ann an toraidhean luirg ’s am measg nam molaidhean name: Taga hais @@ -286,6 +310,7 @@ gd: usable: Leig le postaichean an taga hais seo a chleachdadh user: role: Dreuchd + time_zone: Roinn-tìde user_role: color: Dathan na baidse highlighted: Seall an dreuchd ’na baidse air pròifilean nan cleachdaichean @@ -294,9 +319,11 @@ gd: position: Prìomhachas webhook: events: Na tachartas an comas + template: Teamplaid payload url: URL na puinge-deiridh 'no': Chan eil not_recommended: Cha mholamaid seo + overridden: "’Ga thar-àithneadh" recommended: Molta required: mark: "*" diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index c4a6da5669..4eb4ae4f24 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -2,6 +2,14 @@ gl: simple_form: hints: + account: + discoverable: As túas publicacións públicas e perfil poden mostrarse ou recomendarse en varias zonas de Mastodon e o teu perfil ser suxerido a outras usuarias. + display_name: O teu nome completo ou un nome divertido. + fields: Páxina web, pronome, idade, o que ti queiras. + indexable: As túas publicacións públicas poderían aparecer nos resultados das buscas en Mastodon. En calquera caso, as persoas que interactúen coas túas publicacións poderán buscalas igualmente. + note: 'Podes @mencionar a outras persoas ou #cancelos.' + show_collections: Calquera poderá ver os teus seguimentos e seguidoras, e as persoas ás que segues tamén poden ver que as segues. + unlocked: Poderán seguirte directamente sen solicitar o seguimento. Desmarca isto se queres revisar manualmente cada solicitude e decidir se aceptas ou rexeitas novos seguimentos. account_alias: acct: Indica o usuaria@servidor da conta desde a cal queres migrar account_migration: @@ -37,14 +45,11 @@ gl: current_password: Por razóns de seguridade, introduce o contrasinal da conta actual current_username: Para confirmar, introduce o nome de usuaria da conta actual digest: Enviar só tras un longo período de inactividade e só se recibiches algunha mensaxe directa na tua ausencia - discoverable: Permite que a túa conta poida ser descuberta por persoas descoñecidas a través de recomendacións, tendencias e outras ferramentas email: Ímosche enviar un correo de confirmación - fields: Podes ter ate 4 elementos no teu perfil mostrados como unha táboa header: PNG, GIF ou JPG. Máximo %{size}. Será reducida a %{dimensions}px inbox_url: Copiar o URL desde a páxina de inicio do repetidor que queres utilizar irreversible: As publicacións filtradas desaparecerán de xeito irreversible, incluso se despois se elimina o filtro locale: O idioma da interface de usuaria, correos e notificacións - locked: Xestionar manualmente quen pode seguirte aprobando as solicitudes de seguimento password: Utiliza 8 caracteres ao menos phrase: Concordará independentemente das maiúsculas ou avisos de contido na publicación scopes: A que APIs terá acceso a aplicación. Se escolles un ámbito de alto nivel, non precisas seleccionar elementos individuais. @@ -54,12 +59,9 @@ gl: setting_display_media_default: Ocultar medios marcados como sensibles setting_display_media_hide_all: Ocultar sempre os medios setting_display_media_show_all: Mostrar sempre os medios marcados como sensibles - setting_hide_network: Non se mostrará no teu perfil quen te segue e a quen estás a seguir - setting_noindex: Afecta ao teu perfil público e páxinas de publicación - setting_show_application: A aplicación que estás a utilizar para enviar publicacións mostrarase na vista detallada da publicación setting_use_blurhash: Os gradientes toman as cores da imaxe oculta pero esvaecendo tódolos detalles setting_use_pending_items: Agochar actualizacións da cronoloxía tras un click no lugar de desprazar automáticamente os comentarios - username: O teu nome de usuaria será único en %{domain} + username: Podes usar letras, números e trazos baixos whole_word: Se a chave ou frase de paso é só alfanumérica, só se aplicará se concorda a palabra completa domain_allow: domain: Este dominio estará en disposición de obter datos desde este servidor e datos de entrada a el poderán ser procesados e gardados @@ -118,6 +120,9 @@ gl: sessions: otp: 'Escribe o código do segundo factor creado pola aplicación do teu móbil ou usa un dos códigos de recuperación:' webauthn: Se é unha chave USB asegúrate de que está conectada e preme o botón. + settings: + indexable: A túa páxina de perfil podería aparecer nos resultados de busca de Google, Bing e outros. + show_application: Independentemente, ti sempre poderás ver a app coa que publicaches a túa publicación. tag: name: Só podes cambiar maiús/minúsculas, por exemplo, mellorar a lexibilidade user: @@ -131,12 +136,17 @@ gl: position: O rol superior decide nos conflitos en certas situacións. Algunhas accións só poden aplicarse sobre roles cunha prioridade menor webhook: events: Elixir eventos a enviar + template: Crea o teu propio JSON interpolando variables. Déixao en branco para usar o JSON predeterminado. url: A onde se enviarán os eventos labels: account: + discoverable: Perfil destacado e publicacións nos algoritmos de descubrimento fields: name: Etiqueta value: Contido + indexable: Incluír publicacións públicas nos resultados das buscas + show_collections: Mostrar os seguimentos e seguidoras no perfil + unlocked: Aceptar automáticamente os novos seguimentos account_alias: acct: Xestiona a conta antiga account_migration: @@ -174,7 +184,6 @@ gl: context: Contextos do filtro current_password: Contrasinal actual data: Datos - discoverable: Suxerir esta conta a outras persoas display_name: Nome mostrado email: Enderezo de email expires_in: Caduca tras @@ -184,7 +193,6 @@ gl: inbox_url: URL da caixa de entrada do repetidor irreversible: Desbotar en lugar de agochar locale: Idioma da interface - locked: Requerir aprobar seguimento max_uses: Número máximo de usos new_password: Novo contrasinal note: Acerca de ti @@ -196,7 +204,6 @@ gl: setting_always_send_emails: Enviar sempre notificacións por correo electrónico setting_auto_play_gif: Reprodución automática de GIFs animados setting_boost_modal: Solicitar confirmación antes de promover - setting_crop_images: Recortar imaxes a 16x9 en publicacións non despregadas setting_default_language: Idioma de publicación setting_default_privacy: Privacidade da publicación setting_default_sensitive: Marcar sempre multimedia como sensible @@ -208,9 +215,7 @@ gl: setting_display_media_show_all: Mostrar todo setting_expand_spoilers: Despregar sempre as publicacións marcadas con avisos de contido setting_hide_network: Non mostrar contactos - setting_noindex: Pedir non aparecer nas buscas dos motores de busca setting_reduce_motion: Reducir o movemento nas animacións - setting_show_application: Mostrar a aplicación utilizada para publicar setting_system_font_ui: Utilizar a tipografía por defecto do sistema setting_theme: Decorado da instancia setting_trends: Mostrar as tendencias de hoxe @@ -261,7 +266,7 @@ gl: trends: Activar tendencias trends_as_landing_page: Usar as tendencias como páxina de benvida interactions: - must_be_follower: Bloquear as notificacións de non-seguidoras + must_be_follower: Bloquea as notificacións de persoas que non te seguen must_be_following: Bloquea as notificacións de persoas que non segues must_be_following_dm: Bloquea as mensaxes directas de persoas que non segues invite: @@ -286,9 +291,18 @@ gl: pending_account: Enviar un correo cando unha nova conta precisa revisión reblog: Enviar un correo cando alguén promociona a tua mensaxe report: Enviouse unha nova denuncia + software_updates: + all: Notificar todas as actualizacións + critical: Notificar só as actualizacións críticas + label: Hai unha nova versión de Mastodon dispoñible + none: Non notificar nunca as actualizacións (non se recomenda) + patch: Notificar as actualizacións de arranxos trending_tag: Hai que revisar unha nova tendencia rule: text: Regra + settings: + indexable: Incluír páxina de perfil nos motores de busca + show_application: Mostrar a app coa que enviaches unha publicación tag: listable: Permitir que este cancelo apareza en buscas e no directorio de perfil name: Cancelo @@ -296,6 +310,7 @@ gl: usable: Permitir que as publicacións utilicen este cancelo user: role: Rol + time_zone: Fuso horario user_role: color: Cor da insignia highlighted: Mostrar rol como insignia en perfís de usuarias @@ -304,9 +319,11 @@ gl: position: Prioridade webhook: events: Eventos activados + template: Modelo de carga url: URL do extremo 'no': Non not_recommended: Non é recomendable + overridden: Sobreescrita recommended: Recomendado required: mark: "*" diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index 8e6631e36a..d8d47fee61 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -2,6 +2,14 @@ he: simple_form: hints: + account: + discoverable: הפוסטים והפרופיל שלך עשויים להיות מוצגים או מומלצים באזורים שונים באתר וייתכן שהפרופיל שלך יוצע למשתמשים אחרים. + display_name: שמך המלא או שם הכיף שלך. + fields: עמוד הבית שלך, כינויי גוף, גיל, וכל מידע אחר לפי העדפתך האישית. + indexable: ההודעות הפומביות שלך עשויות להופיע בתוצאות חיפוש במסטודון. אחרים שהדהדו, חיבבו או ענו להודעות האלו יוכלו למצוא אותן בחיפוש בכל מקרה. + note: 'ניתן לאזכר @אחרים או #תגיות.' + show_collections: אנשים יוכלו לדפדף בין העוקבים והנעקבים שלך. אנשים שאת.ה עוקב.ת אחריהם יראו את המעקב אחריהם כרגיל. + unlocked: אנשים יוכלו לעקוב אחריך ללא בקשת אישור. יש להסיר סימון אם ברצונך לאשר או לסרב לבקשות עקיבה מכל משתמש.ת לחוד. account_alias: acct: נא לציין משתמש@דומיין של החשבון ממנו תרצה/י לעבור account_migration: @@ -37,14 +45,11 @@ he: current_password: מסיבות אבטחה נא להזין את הסיסמא של החשבון הנוכחי current_username: על מנת לאשר, נא להכניס את שם המשתמש של החשבון הנוכחי digest: נשלח לאחר תקופה ארוכה של אי-פעילות עם סיכום איזכורים שקיבלת בהעדרך - discoverable: אשר/י לחשבונך להתגלות לזרים על ידי המלצות, נושאים חמים ושאר דרכים email: דוא"ל אישור יישלח אליך - fields: ניתן להציג עד ארבעה פריטים כטבלה בפרופילך header: PNG, GIF או JPG. מקסימום %{size}. גודל התמונה יוקטן %{dimensions}px inbox_url: נא להעתיק את הקישורית מדף הבית של הממסר בו תרצה/י להשתמש irreversible: הודעות מסוננות יעלמו באופן בלתי הפיך, אפילו אם מאוחר יותר יוסר המסנן locale: שפת ממשק המשתמש, הדוא"ל וההתראות בדחיפה - locked: מחייב אישור עוקבים באופן ידני. פרטיות ההודעות תהיה עוקבים-בלבד אלא אם יצוין אחרת password: נא להשתמש בלפחות 8 תוים phrase: התאמה תמצא ללא תלות באזהרת תוכן בהודעה scopes: לאיזה ממשק יורשה היישום לגשת. בבחירת תחום כללי, אין צורך לבחור ממשקים ספציפיים. @@ -54,12 +59,9 @@ he: setting_display_media_default: הסתרת מדיה המסומנת כרגישה setting_display_media_hide_all: הסתר מדיה תמיד setting_display_media_show_all: גלה מדיה תמיד - setting_hide_network: עוקבייך ונעקבייך יוסתרו בפרופילך - setting_noindex: משפיע על הפרופיל הציבורי שלך ועמודי ההודעות - setting_show_application: היישום בו נעשה שימוש כדי לחצרץ יופיע בתצוגה המפורטת של החצרוץ setting_use_blurhash: הגראדיינטים מבוססים על תוכן התמונה המוסתרת, אבל מסתירים את כל הפרטים setting_use_pending_items: הסתר עדכוני פיד מאחורי קליק במקום לגלול את הפיד אוטומטית - username: שם המשתמש שלך יהיה ייחודי ב- %{domain} + username: ניתן להשתמש בספרות, אותיות לטיניות ומקף תחתון whole_word: אם מילת מפתח או ביטוי הם אלפאנומריים בלבד, הם יופעלו רק אם נמצאה התאמה למילה שלמה domain_allow: domain: דומיין זה יוכל לייבא מידע משרת זה והמידע המגיע ממנו יעובד ויאופסן @@ -118,6 +120,9 @@ he: sessions: otp: 'נא להקליד קוד אימות דו-שלבי ממכשירך או להשתמש באחד מקודי אחזור הגישה שלך:' webauthn: אם זהו מכשיר USB יש לוודא שהוא מוכנס, ואם יש צורך, להקיש עליו. + settings: + indexable: המשתמש שלך עלול להופיע בתוצאות החיפוש של גוגל, בינג או מנועי חיפוש אחרים. + show_application: תמיד ניתן לראות איזו אפליקציה פרסמה את הפוסט שלך בכל מקרה. tag: name: ניתן רק להחליף בין אותיות קטנות וגדולות, למשל כדי לשפר את הקריאות user: @@ -131,12 +136,17 @@ he: position: תפקיד גבוה יותר מכריע בחילוקי דעות במצבים מסוימים. פעולות מסוימות יכולות להתבצע רק על תפקידים בדרגה נמוכה יותר webhook: events: בחר אירועים לשליחה + template: ניתן להרכיב מטען JSON משלך בשימוש בשילוב משתנים. יש להשאיר ריק בשביל JSON ברירת המחדל. url: היעד שאליו יישלחו אירועים labels: account: + discoverable: חשיפת פרופיל משתמש והודעות לאלגוריתם של האתר fields: name: תווית value: תוכן + indexable: הכללת הודעות ציבוריות בתוצאות חיפוש + show_collections: הצגת נעקבים ועוקבים בפרופיל + unlocked: אישור אוטומטי של עוקבים/ות חדשים/ות account_alias: acct: שם משתמש של החשבון הישן account_migration: @@ -174,7 +184,6 @@ he: context: סינון לפי הקשר current_password: סיסמא נוכחית data: מידע - discoverable: הצע חשבון לאחרים display_name: שם להצגה email: כתובת דוא"ל expires_in: תפוגה לאחר @@ -184,7 +193,6 @@ he: inbox_url: קישורית לתיבת ממסר irreversible: הסרה במקום הסתרה locale: שפה - locked: הפוך חשבון לפרטי max_uses: מספר מרבי של שימושים new_password: סיסמא חדשה note: אודות @@ -196,7 +204,6 @@ he: setting_always_send_emails: תמיד שלח התראות לדוא"ל setting_auto_play_gif: ניגון אוטומטי של גיפים setting_boost_modal: הצגת דיאלוג אישור לפני הדהוד - setting_crop_images: קטום תמונות בהודעות לא מורחבות ל 16 על 9 setting_default_language: שפת ברירת מחדל להודעה setting_default_privacy: פרטיות ההודעות setting_default_sensitive: תמיד לתת סימון "רגיש" למדיה @@ -208,9 +215,7 @@ he: setting_display_media_show_all: להציג הכול setting_expand_spoilers: להרחיב תמיד הודעות מסומנות באזהרת תוכן setting_hide_network: להחביא את הגרף החברתי שלך - setting_noindex: לבקש הסתרה ממנועי חיפוש setting_reduce_motion: הפחתת תנועה בהנפשות - setting_show_application: הצגת הישום ששימש לפרסום ההודעה setting_system_font_ui: להשתמש בגופן ברירת המחדל של המערכת setting_theme: ערכת העיצוב של האתר setting_trends: הצגת הנושאים החמים @@ -286,9 +291,18 @@ he: pending_account: נדרשת סקירה של חשבון חדש reblog: שליחת דוא"ל כשמהדהדים הודעה שלך report: דו"ח חדש הוגש + software_updates: + all: קבלת הודעה על כל העדכונים + critical: קבלת הודעה על עדכונים קריטיים בלבד + label: יצאה גרסת מסטודון חדשה + none: לא לשלוח הודעות על עדכונים (לא מומלץ) + patch: קבלת הודעה על עדכוני תיקון שקצים trending_tag: נושאים חמים חדשים דורשים סקירה rule: text: כלל + settings: + indexable: חשיפת דף המשתמש במנועי החיפוש + show_application: חשיפת שם היישומון שהעלה את ההודעה tag: listable: הרשה/י לתגית זו להופיע בחיפושים והצעות name: תגית @@ -296,6 +310,7 @@ he: usable: הרשה/י להודעות להכיל תגית זו user: role: תפקיד + time_zone: אזור זמן user_role: color: צבע תג highlighted: הצג תפקיד כתג בפרופיל משתמש @@ -304,9 +319,11 @@ he: position: עדיפות webhook: events: אירועים מאופשרים + template: תבנית מטען url: כתובת URL של נקודת הקצה 'no': לא not_recommended: לא מומלצים + overridden: נאכף recommended: מומלץ required: mark: "*" diff --git a/config/locales/simple_form.hr.yml b/config/locales/simple_form.hr.yml index b45c2f3574..0f2896fe05 100644 --- a/config/locales/simple_form.hr.yml +++ b/config/locales/simple_form.hr.yml @@ -5,7 +5,6 @@ hr: defaults: avatar: PNG, GIF ili JPG. Najviše %{size}. Bit će smanjeno na %{dimensions}px header: PNG, GIF ili JPG. Najviše %{size}. Bit će smanjeno na %{dimensions}px - locked: Zahtijeva ručno odobravanje pratitelja setting_display_media_default: Sakrij medijski sadržaj označen kao osjetljiv setting_display_media_hide_all: Uvijek sakrij medijski sadržaj setting_display_media_show_all: Uvijek prikaži medijski sadržaj @@ -24,7 +23,6 @@ hr: display_name: Prikazano ime email: Adresa e-pošte locale: Jezik sučelja - locked: Zaključaj račun new_password: Nova lozinka note: Biografija otp_attempt: Dvofaktorski kôd diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml index 81d74cebee..70c225e8ff 100644 --- a/config/locales/simple_form.hu.yml +++ b/config/locales/simple_form.hu.yml @@ -2,6 +2,14 @@ hu: simple_form: hints: + account: + discoverable: A nyilvános bejegyzéseid és a profilod kiemelhető vagy ajánlható a Mastodon különböző területein, a profilod más felhasználóknak is javasolható. + display_name: Teljes neved vagy vicces neved. + fields: Weboldalad, megszólításaid, korod, bármi, amit szeretnél. + indexable: A nyilvános bejegyzéseid megjelenhetnek a Mastodon keresési eredményei között. Azok, akik kapcsolatba léptek a bejegyzéseiddel, ettől függetlenül kereshetik azokat. + note: 'Megemlíthetsz @másokat vagy #hashtag-eket.' + show_collections: Mások böngészhetnek a követőid és követetteid között. Ettől függetlenül a követetteid látják majd, hogy követed őket. + unlocked: Mások jóváhagyás kérése nélkül követhetnek téged. Töröld a jelölést, ha szeretnéd áttekinteni a követési kéréseket és választani az új követők elfogadása vagy elutasítása közül. account_alias: acct: Add meg annak a fióknak a felhasználónév@domain párosát, ahonnan át szeretnéd mozgatni account_migration: @@ -37,14 +45,11 @@ hu: current_password: Biztonsági okok miatt kérlek, írd be a jelenlegi fiók jelszavát current_username: A jóváhagyáshoz írd be a jelenlegi fiók felhasználói nevét digest: Csak hosszú távollét esetén küldődik és csak ha személyes üzenetet kaptál távollétedben - discoverable: Engedélyezés, hogy a fiókod idegenek által megtalálható legyen javaslatokon, trendeken és más funkciókon keresztül email: Kapsz egy megerősítő e-mailt - fields: A profilodon legfeljebb 4 bejegyzés szerepelhet táblázatos formában header: PNG, GIF vagy JPG. Maximum %{size}. Átméretezzük %{dimensions} pixelre inbox_url: Másold ki a használandó relé szerver kezdőoldalának URL-jét irreversible: A kiszűrt bejegyzések visszafordíthatatlanul eltűnnek, a szűrő későbbi törlése esetén is locale: A felhasználói felület, e-mailek, push üzenetek nyelve - locked: Egyenként engedélyezned kell a követőidet password: Legalább 8 karakter phrase: Illeszkedni fog kis/nagybetű függetlenül, és tartalmi figyelmeztetések mögött is scopes: Mely API-kat érheti el az alkalmazás. Ha felső szintű hatáskört választasz, nem kell egyesével kiválasztanod az alatta lévőeket. @@ -54,12 +59,9 @@ hu: setting_display_media_default: Kényes tartalomnak jelölt média elrejtése setting_display_media_hide_all: Mindig minden média elrejtése setting_display_media_show_all: Mindig mutasd a szenzitív tartalomként jelölt médiát - setting_hide_network: Nem látszik majd a profilodon, kik követnek és te kiket követsz - setting_noindex: A nyilvános profilodra és a bejegyzéseidre vonatkozik - setting_show_application: A bejegyzések részletes nézetében látszani fog, milyen alkalmazást használtál a bejegyzés közzétételéhez setting_use_blurhash: A kihomályosítás az eredeti képből történik, de minden részletet elrejt setting_use_pending_items: Idővonal frissítése csak kattintásra automatikus görgetés helyett - username: A felhasználói neved egyedi lesz a %{domain} domainen + username: Betűk, számok és alávonások használhatók whole_word: Ha a kulcsszó alfanumerikus, csak akkor minősül majd találatnak, ha teljes szóra illeszkedik domain_allow: domain: Ez a domain adatokat kérhet le erről a kiszolgálóról, és a bejövő adatok fel lesznek dolgozva és tárolva lesznek @@ -118,6 +120,9 @@ hu: sessions: otp: 'Add meg a telefonodon generált kétlépcsős azonosító kódodat vagy használd az egyik tartalék bejelentkező kódot:' webauthn: Ha ez egy USB kulcs, ellenőrizd, hogy csatlakoztattad és ha szükséges, aktiváltad is. + settings: + indexable: A profiloldalad megjelenhet a Google, a Bing és más keresőmotorok keresési eredményei között. + show_application: Ettől függetlenül mindig láthatod, melyik alkalmazás tette közzé a bejegyzésedet. tag: name: Csak a kis/nagybetűséget változtathatod meg, pl. hogy olvashatóbb legyen user: @@ -131,12 +136,17 @@ hu: position: A magasabb szerepkör oldja fel az ütközéseket bizonyos helyzetekben. Bizonyos műveleteket csak alacsonyabb prioritású szerepkörrel lehet elvégezni. webhook: events: Válaszd ki a küldendő eseményeket + template: Saját JSON adatcsomagot állíthatsz össze változó-behelyettesítés használatával. Hagyd üresen az alapértelmezett JSON adatcsomaghoz. url: Ahová az eseményket küldjük labels: account: + discoverable: Profil és bejegyzések szerepeltetése a felfedezési algoritmusokban fields: name: Címke value: Tartalom + indexable: Nyilvános bejegyzések szerepeltetése a keresési eredményekben + show_collections: Követők és követettek megjelnítése a profilban + unlocked: Új követők automatikus elfogadása account_alias: acct: Régi fiók kezelése account_migration: @@ -174,7 +184,6 @@ hu: context: Szűrés kontextusai current_password: Jelenlegi jelszó data: Adatok - discoverable: Fiók listázása a profilok adatbázisában display_name: Megjelenített név email: E-mail cím expires_in: Elévül @@ -184,7 +193,6 @@ hu: inbox_url: Relé inbox-hoz tartozó URL irreversible: Eldobás elrejtés helyett locale: Felhasználói felület nyelve - locked: Felhasználói fiók lezárása max_uses: Hányszor használható new_password: Új jelszó note: Bemutatkozás @@ -196,7 +204,6 @@ hu: setting_always_send_emails: E-mail értesítések küldése mindig setting_auto_play_gif: GIF-ek automatikus lejátszása setting_boost_modal: Megerősítés kérése megtolás előtt - setting_crop_images: Képek 16x9-re vágása nem kinyitott bejegyzéseknél setting_default_language: Bejegyzések nyelve setting_default_privacy: Bejegyzések láthatósága setting_default_sensitive: Minden médiafájl megjelölése kényesként @@ -208,9 +215,7 @@ hu: setting_display_media_show_all: Mindent mutat setting_expand_spoilers: Tartalmi figyelmeztetéssel ellátott bejegyzések automatikus kinyitása setting_hide_network: Hálózatod elrejtése - setting_noindex: Megtiltom a keresőmotoroknak, hogy indexeljék a tartalmaimat setting_reduce_motion: Animációk mozgásának csökkentése - setting_show_application: Bejegyzések küldésére használt alkalmazás feltüntetése setting_system_font_ui: Rendszer betűtípusának használata setting_theme: Megjelenítési sablon setting_trends: Mai trend mutatása @@ -286,9 +291,18 @@ hu: pending_account: E-mail küldése, ha új fiókot kell engedélyezni reblog: Valaki megtolta a bejegyzésedet report: Új bejelentést küldtek be + software_updates: + all: Értesítés az összes frissítésről + critical: Értesítés csak a kritikus frissítésekről + label: Új Mastodon verzió érhető el + none: Nincs értesítés a frissítésekről (nem ajánlott) + patch: Értesítés hibajavítási frissítésekről trending_tag: Új trend felülvizsgálatra vár rule: text: Szabály + settings: + indexable: A profiloldal szerepeltetése a keresőmotorokban + show_application: A bejegyzést küldő alkalmazás megjelenítése tag: listable: A hashtag megjelenhet a profiladatbázisban name: Hashtag @@ -296,6 +310,7 @@ hu: usable: Bejegyzések használhatják ezt a hashtaget user: role: Szerep + time_zone: Időzóna user_role: color: Jelvény színe highlighted: Szerep megjelenítése jelvényként a felhasználói profilokon @@ -304,9 +319,11 @@ hu: position: Prioritás webhook: events: Engedélyezett események + template: Adatcsomag sablon url: Végponti URL 'no': Nem not_recommended: Nem ajánlott + overridden: Felülbírálva recommended: Ajánlott required: mark: "*" diff --git a/config/locales/simple_form.hy.yml b/config/locales/simple_form.hy.yml index b955021550..56aa1d66b1 100644 --- a/config/locales/simple_form.hy.yml +++ b/config/locales/simple_form.hy.yml @@ -30,12 +30,10 @@ hy: current_username: Հաստատելու համար խնդրում ենք մուտքագրել տուել հաշուի օգտանունը digest: Ուղարկուում է պասիւութեան երկար շրջանից յետոյ եւ միայն այն դէպքում, երբ բացակայութեանդ ժամանակ որեւէ անձնական հաղորդագրութիւն ես ստացել email: Քեզ ուղարկուել է հաստատման իմակ - fields: Կարող ես ունենալ մինչեւ 4 կէտ հաշուիդ աղիւսակում ցուցադրելու header: PNG, GIF կամ JPG։ Առաւելագոյնը՝ %{size}։ Կը փոքրացուի մինչեւ %{dimensions} inbox_url: Պատճէնիր URL այն շերտի դիմերեսից, որը ցանկանում ես օգտագործել irreversible: Զտուած գրառումները կորչելու են անդառնալիօրէն, նոյնիսկ եթէ զտիչը յետոյ հեռացնես locale: Ինտերֆեյսի լեզուն, էլ. նամակները եւ push ծանուցումները - locked: Անհրաժեշտ կը լինի ձեռքով հաստատել հետեւորդներին password: Օգտագործիր առնուազն 8 նիշ phrase: Կը համընկնի անկախ տեքստի ձեւից կամ զգուշացնող բովանդակութիւնից scopes: Որ API֊ին յաւելուածն ունի հասանելիութիւն։ Եթէ ընտրել ես բարձր մակարդակի դաշտ, ապա անհատական ընտրելու կարիք չկայ։ @@ -44,12 +42,9 @@ hy: setting_display_media_default: Թաքցնել կասկածելի բովանդակութիւնը setting_display_media_hide_all: Երբեք մեդիա ցոյց չտալ setting_display_media_show_all: Մեդիա միշտ ցոյց տալ - setting_hide_network: Ուրիշները չեն կարողանայ տեսնել ձեզ հետեւողներին եւ թե ում էք հետեւում դուք - setting_noindex: Ազդում է քո հրապարակային հաշուի եւ գրառումների էջի վրայ - setting_show_application: Գրառման մանրամասներում կերեւայ թէ որ ծրագրով ես հրապարակել այն setting_use_blurhash: Կտորները հիմնուում են թաքցուած վիզուալի վրայ՝ խամրեցնելով դետալները setting_use_pending_items: Թաքցնել հոսքի թարմացումները կտտոի ետեւում՝ աւտօմատ թարմացուող հոսքի փոխարէն - username: Քո օգտանունը պէտք է եզակի լինի %{domain}-ում։ + username: Միայն լատինատառեր, թուեր եւ տակի գծիկ whole_word: Եթէ բանալի բառը կամ արտայայտութիւնը պարունակում է միայն այբբենական նիշեր եւ թուեր, ապա այն կիրառուելու է ամբողջ բառի հետ համընկնելու դէպքում միայն domain_allow: domain: Այս տիրոյթը կարող է ստանալ տուեալներ այս սպասարկչից եւ ստացուող տուեալները կարող են օգտագործուել եւ պահուել @@ -116,7 +111,6 @@ hy: context: Զտել կոնտեքստները current_password: Ներկայիս գաղտնաբառը data: Տուեալներ - discoverable: Աւելացնել հաշիւը հասցէագրքում display_name: Ցուցադրուող անուն email: Էլ․ հասցէ expires_in: Սպառուում է @@ -126,7 +120,6 @@ hy: inbox_url: Ներմուծման շերտի URL irreversible: Թաքցնելու փոխարէն ջնջել locale: Ինտերֆեյսի լեզու - locked: Փակել հաշիւը max_uses: Օգտագործման առաւելագոյն քանակ new_password: Նոր գաղտնաբառ note: Բիո @@ -137,7 +130,6 @@ hy: setting_aggregate_reblogs: Տարծածները խմբաւորել հոսքում setting_auto_play_gif: Աւտոմատ մեկնարկել GIFs անիմացիաները setting_boost_modal: Ցուցադրել հաստատման պատուհանը տարածելուց առաջ - setting_crop_images: Ցոյց տալ գրառման նկարը 16x9 համամասնութեամբ setting_default_language: Հրապարակման լեզու setting_default_privacy: Հրապարակման գաղտնիութիւն setting_default_sensitive: Միշտ նշել մեդիան որպէս դիւրազգաց @@ -149,9 +141,7 @@ hy: setting_display_media_show_all: Ցուցադրել բոլորը setting_expand_spoilers: Միշտ բացել բովանդակութեան զգուշացմամբ գրառումները setting_hide_network: Թաքցնել ցանցդ - setting_noindex: Խուսափել որոնողական համակարգերի ինդէքսաւորումից setting_reduce_motion: Կրճատել անիմացիաների շարժումը - setting_show_application: Բացայայտել գրառման համար օգտագործուած յաւելուածը setting_system_font_ui: Օգտագործել համակարգի լռելեայն տառատեսակը setting_theme: Կայքի թեման setting_trends: Ցուցադրել օրուայ թրենդները @@ -168,6 +158,8 @@ hy: with_dns_records: Ներառել MX գրառում կամ դոմէյնի IP featured_tag: name: Պիտակ + form_admin_settings: + site_terms: Գաղտնիութեան քաղաքականութիւն interactions: must_be_follower: Արգելափակել ծանուցումները ոչ հետեւորդներից must_be_following: Արգելափակել ծանուցումները մարդկանցից, որոնց չես հետեւում diff --git a/config/locales/simple_form.id.yml b/config/locales/simple_form.id.yml index 43f2782642..51046ce9d4 100644 --- a/config/locales/simple_form.id.yml +++ b/config/locales/simple_form.id.yml @@ -35,14 +35,11 @@ id: current_password: Untuk tujuan keamanan mohon masukkan kata sandi akun ini current_username: Untuk konfirmasi, mohon masukkan nama pengguna akun ini digest: Hanya kirim setelah lama tidak aktif dan hanya jika Anda menerima pesan personal atas absensi Anda - discoverable: Izinkan akun Anda ditemukan orang lain lewat rekomendasi, tren, dan fitur lain email: Anda akan dikirimi email konfirmasi - fields: Anda bisa memiliki hingga 4 item utk ditampilkan sebagai tabel di profil Anda header: PNG, GIF atau JPG. Maksimal %{size}. Ukuran dikecilkan menjadi %{dimensions}px inbox_url: Salin URL dari halaman depan relai yang ingin Anda pakai irreversible: Toot tersaring akan hilang permanen bahkan jika saringan dihapus kemudian locale: Bahasa antar muka pengguna, email, dan notifikasi dorong - locked: Anda harus menerima permintaan pengikut secara manual dan setting privasi postingan akan diubah khusus untuk pengikut password: Gunakan minimal 8 karakter phrase: Akan dicocokkan terlepas dari luaran dalam teks atau peringatan konten dari toot scopes: API mana yang diizinkan untuk diakses aplikasi. Jika Anda memilih cakupan level-atas, Anda tidak perlu memilih yang individu. @@ -52,12 +49,8 @@ id: setting_display_media_default: Sembunyikan media yang ditandai sebagai sensitif setting_display_media_hide_all: Selalu sembunyikan semua media setting_display_media_show_all: Selalu tampilkan media sensitif - setting_hide_network: Siapa yang Anda ikuti dan yang mengikuti Anda tak akan ditampilkan dalam profil - setting_noindex: Pengaruhi profil publik dan halaman status Anda - setting_show_application: Aplikasi yang Anda pakai untuk men-toot akan ditampilkan di tampilan detail toot setting_use_blurhash: Gradien didasarkan pada warna visual yang tersembunyi tetapi mengaburkan setiap detail setting_use_pending_items: Sembunyikan pembaruan linimasa di balik klik alih-alih bergulir secara otomatis - username: Nama pengguna Anda unik di %{domain} whole_word: Ketika kata kunci/frasa hanya alfanumerik, maka itu hanya akan diterapkan jika cocok dengan semua kata domain_allow: domain: Domain ini dapat mengambil data dari server ini dan data yang diterima akan diproses dan disimpan @@ -168,7 +161,6 @@ id: context: Saring konteks current_password: Kata sandi sekarang data: Data - discoverable: Daftarkan akun ini di direktori display_name: Nama yang ditampilkan email: Alamat e-mail expires_in: Kedaluwarsa setelah @@ -178,7 +170,6 @@ id: inbox_url: URL kotak relai irreversible: Hapus alih-alih sembunyikan locale: Bahasa - locked: Buat akun menjadi pribadi max_uses: Jumlah maksimal penggunaan new_password: Password baru note: Bio @@ -190,7 +181,6 @@ id: setting_always_send_emails: Selalu kirim notifikasi email setting_auto_play_gif: Mainkan otomatis animasi GIF setting_boost_modal: Tampilkan dialog konfirmasi dialog sebelum boost - setting_crop_images: Potong gambar ke 16x9 pada toot yang tidak dibentangkan setting_default_language: Bahasa posting setting_default_privacy: Privasi postingan setting_default_sensitive: Selalu tandai media sebagai sensitif @@ -202,9 +192,7 @@ id: setting_display_media_show_all: Tunjukkan semua setting_expand_spoilers: Selalu bentangkan kiriman yang bertanda peringatan konten setting_hide_network: Sembunyikan jaringan Anda - setting_noindex: Opt-out dari pengindeksan mesin pencari setting_reduce_motion: Kurangi gerakan animasi - setting_show_application: Singkap aplikasi yang dipakai utk kirim toot setting_system_font_ui: Gunakan fon bawaan sistem setting_theme: Tema situs setting_trends: Tampilkan tren hari ini diff --git a/config/locales/simple_form.io.yml b/config/locales/simple_form.io.yml index d6aff6afd7..b21b86723c 100644 --- a/config/locales/simple_form.io.yml +++ b/config/locales/simple_form.io.yml @@ -35,14 +35,11 @@ io: current_password: Por sekuresorezoni, pozez pasvorto di ca konto current_username: Por konfirmar, pozez uzantonomo di ca konto digest: Nur sendesas pos longa neaktiveso e nur se vu ganis irga mesaji dum ke vu esas neprezenta - discoverable: Permisez vua konto deskovresar da nekonociti tra rekomendi, tendenci e altra traiti email: Vu sendesos konfirmretposto - fields: On povas havar maxime 4 kozi quo montresas quale tabelo che ona profilo header: En la formato PNG, GIF o JPG. Til %{size}. Esos mikrigita a %{dimensions}px inbox_url: Kopiez URL de frontpagino de relayo quon vu volas uzar irreversible: Filtrita posti neinversigeble desaparos, mem se filtro efacesas pose locale: Linguo di uzantointervizajo, retposti e pulsavizi - locked: Tu devos aprobar omna demandi di sequado, e tua mesaji esos senchanje nur por tua sequanti. password: Uzes minime 8 litri phrase: Parigesos ne ye textosituaciono o konteneyoaverto di posto scopes: Quala API quon softwaro permisesas acesar. Se vu selektas alta skopo, vu ne mustas selektar individui. @@ -52,12 +49,8 @@ io: setting_display_media_default: Celez medii quo markizesis quale sentoza setting_display_media_hide_all: Sempre celez medii setting_display_media_show_all: Sempre montrez medii - setting_hide_network: Vua sequato e sequanto celesos che vua profilo - setting_noindex: Efektigar vua publika profilo e postopagini - setting_show_application: Softwaro quon vu uzar por postigar montresos che detala vidajo di vua posti setting_use_blurhash: Inklini esas segun kolori di celesis vidaji ma kovras irga detali setting_use_pending_items: Celez tempolineonovi dop kliktar e ne automatike movigar niuzeto - username: Vua uzantonomo esos nura che %{domain} whole_word: Kande klefvorto o fraz esas nur litera e nombra, ol nur aplikesos se ol parigesas la tota vorto domain_allow: domain: Ca domeno povas ganar informi de ca servilo e venanta informo de ol procedagesos e sparesos @@ -166,7 +159,6 @@ io: context: Filtrez kuntexti current_password: Nuna pasvorto data: Datumi - discoverable: Sugestez konto a altra personi display_name: Publika nomo email: Retpost-adreso expires_in: Expiras pos @@ -176,7 +168,6 @@ io: inbox_url: URL di relayomesajbuxo irreversible: Deslevez e ne celez locale: Linguo - locked: Privatigar la konto max_uses: Maxima uzi new_password: Nova pasvorto note: Suprizento @@ -188,7 +179,6 @@ io: setting_always_send_emails: Sempre sendez retpostoavizi setting_auto_play_gif: Automate pleez animigita GIFi setting_boost_modal: Montrez konfirmdialogo ante bustar - setting_crop_images: Ektranchez imaji en neexpansigita posti a 16x9 setting_default_language: Postolinguo setting_default_privacy: Videbleso di la mesaji setting_default_sensitive: Sempre markizez medii quale sentoza @@ -200,9 +190,7 @@ io: setting_display_media_show_all: Montrez omno setting_expand_spoilers: Sempre expansigez posti quo markizesis kun kontenajaverti setting_hide_network: Celez vua sociala grafiko - setting_noindex: Desjuntez trovmotorindexigo setting_reduce_motion: Diminutez moveso di animacii - setting_show_application: Montrez softwaro quo uzesis por sendar posti setting_system_font_ui: Uzez originala literfonto di sistemo setting_theme: Sittemo setting_trends: Montrez tendenco di hodie diff --git a/config/locales/simple_form.is.yml b/config/locales/simple_form.is.yml index ed17c97536..87190693f6 100644 --- a/config/locales/simple_form.is.yml +++ b/config/locales/simple_form.is.yml @@ -2,6 +2,14 @@ is: simple_form: hints: + account: + discoverable: Opinberar færslur og notandasnið þitt geta birst eða verið mælt með á hinum ýmsu svæðum í Mastodon auk þess sem hægt er að mæla með þér við aðra notendur. + display_name: Fullt nafn þitt eða eitthvað til gamans. + fields: Heimasíðan þín, fornöfn, aldur eða eitthvað sem þú vilt koma á framfæri. + indexable: Opinberar færslur þínar gætu birst í leitarniðurstöðum á Mastodon. Fólk sem hefur haft afskipti af færslunum mun eftir sem áður geta leitað í þeim. + note: 'Þú getur @minnst á annað fólk eða #myllumerki.' + show_collections: Fólk mun geta skoðað þá sem fylgjast með þér og með hverjum þú fylgist. Fólk sem þú fylgist með mun alltaf sjá að þú sért að gera það. + unlocked: Fólk mun geta fylgst með þér án þess að bíða eftir samykki. Taktu merkið úr þessu ef þú vilt yfirfara fylgjendabeiðnir og velja hvort þú samþykkir eða hafnar nýjum fylgjendum. account_alias: acct: Tilgreindu notandanafn@lén á notandaaðgangnum sem þú vilt flytjast frá account_migration: @@ -37,14 +45,11 @@ is: current_password: Í öryggisskyni skaltu setja inn lykilorðið fyrir þennan notandaaðgang current_username: Til að staðfesta skaltu setja inn notandanafnið fyrir þennan notandaaðgang digest: Er aðeins sent eftir lengri tímabil án virkni og þá aðeins ef þú hefur fengið persónuleg skilaboð á meðan þú hefur ekki verið á línunni - discoverable: Gerðu öðrum kleift að finna aðganginn þinn í gegnum meðmæli, vinsældir og annað slíkt email: Þú munt fá sendan staðfestingarpóst - fields: Þú getur birt allt að 4 atriði sem töflu á notandasniðinu þínu header: PNG, GIF eða JPG. Mest %{size}. Verður smækkað í %{dimensions}px inbox_url: Afritaðu slóðina af forsíðu endurvarpans sem þú vilt nota irreversible: Síaðar færslur munu hverfa óendurkræft, jafnvel þó sían sé seinna fjarlægð locale: Tungumál notandaviðmótsins, tölvupósts og ýti-tilkynninga - locked: Krefst þess að þú samþykkir fylgjendur handvirkt password: Notaðu minnst 8 stafi phrase: Verður notað til samsvörunar burtséð frá stafstöðu texta eða viðvörunar vegna efnis í færslu scopes: Að hvaða API-kerfisviðmótum forritið fær aðgang. Ef þú velur efsta-stigs svið, þarftu ekki að gefa einstakar heimildir. @@ -54,12 +59,9 @@ is: setting_display_media_default: Fela myndefni sem merkt er viðkvæmt setting_display_media_hide_all: Alltaf fela allt myndefni setting_display_media_show_all: Alltaf birta myndefni sem merkt er viðkvæmt - setting_hide_network: Hverjum þú fylgist með og hverjir fylgjast með þér verður ekki birt á notandasniðinu þínu - setting_noindex: Hefur áhrif á opinbera notandasniðið þitt og færslusíður - setting_show_application: Nafnið á forritinu sem þú notar til að senda færslur mun birtast í ítarlegri sýn á færslunum þínum setting_use_blurhash: Litstiglarnir byggja á litunum í földu myndunum, en gera öll smáatriði óskýr setting_use_pending_items: Fela uppfærslur tímalínu þar til smellt er, í stað þess að hún skruni streyminu sjálfvirkt - username: Notandanafnið þitt verður einstakt á %{domain} + username: Þú mátt nota bókstafi, tölur og undirstrik whole_word: Þegar stikkorð eða setning er einungis tölur og bókstafir, verður það aðeins notað ef það samsvarar heilu orði domain_allow: domain: Þetta lén mun geta sótt gögn af þessum vefþjóni og tekið verður á móti innsendum gögnum frá léninu til vinnslu og geymslu @@ -118,6 +120,9 @@ is: sessions: otp: 'Settu inn tveggja-þátta kóðann sem farsímaforritið útbjó eða notaðu einn af endurheimtukóðunum þínum:' webauthn: Ef þetta er USB-lykill, gakktu úr skugga um að honum sé stungið í samband og ef þörf þykir að ýta á hann. + settings: + indexable: Síðan með notandasniðinu þínu gæti birst í leitarniðurstöðum Google, Bing og fleiri. + show_application: Þú munt alltaf geta séð hvaða forrit birti færsluna þína. tag: name: Þú getur aðeins breytt stafstöði mill há-/lágstafa, til gæmis til að gera þetta læsilegra user: @@ -131,12 +136,17 @@ is: position: Rétthærra hlutverk ákvarðar lausn árekstra í ákveðnum tilfellum. Sumar aðgerðir er aðeins hægt að framkvæma á hlutverk með lægri forgangi webhook: events: Veldu atburði sem á að senda + template: Sníddu eigin JSON með breytilegri brúun. Skiljið eftir autt fyrir sjálfgefið JSON. url: Hvert atburðir verða sendir labels: account: + discoverable: Hafa notandasnið og færslur með í reikniritum leitar fields: name: Skýring value: Efni + indexable: Hafa opinberar færslur með í leitarniðurstöðum + show_collections: Birta fylgjendur og þá sem fylgst er með í notandasniði + unlocked: Samþykkja nýja fylgjendur sjálfkrafa account_alias: acct: Auðkenni gamla aðgangsins account_migration: @@ -174,7 +184,6 @@ is: context: Samhengi síu current_password: Núverandi lykilorð data: Gögn - discoverable: Hafa þennan aðgang með í notendaskránni display_name: Birtingarnafn email: Tölvupóstfang expires_in: Rennur út eftir @@ -184,7 +193,6 @@ is: inbox_url: URL-slóð á innhólf endurvarpa irreversible: Fella niður í staðinn fyrir að fela locale: Tungumál viðmóts - locked: Krefjast fylgjendabeiðna max_uses: Hámarksfjöldi afnota new_password: Nýtt lykilorð note: Æviágrip @@ -196,7 +204,6 @@ is: setting_always_send_emails: Alltaf senda tilkynningar í tölvupósti setting_auto_play_gif: Spila sjálfkrafa GIF-hreyfimyndir setting_boost_modal: Sýna staðfestingarglugga fyrir endurbirtingu - setting_crop_images: Utansníða myndir í ekki-útfelldum færslum í 16x9 setting_default_language: Tungumál sem skrifað er á setting_default_privacy: Gagnaleynd færslna setting_default_sensitive: Alltaf merkja myndefni sem viðkvæmt @@ -208,9 +215,7 @@ is: setting_display_media_show_all: Birta allt setting_expand_spoilers: Alltaf útfella færslur sem eru með aðvörun vegna efnisins setting_hide_network: Fela félagsnetið þitt - setting_noindex: Afþakka atriðaskráningu í leitarvélum setting_reduce_motion: Minnka hreyfingu í hreyfimyndum - setting_show_application: Upplýsa um forrit sem er til að senda færslur setting_system_font_ui: Nota sjálfgefið letur kerfisins setting_theme: Þema vefsvæðis setting_trends: Birta það sem er efst á baugi í dag @@ -286,9 +291,18 @@ is: pending_account: Nýr notandaaðgangur þarfnast yfirferðar reblog: Einhver endurbirti færsluna þína report: Ný kæra hefur verið send inn + software_updates: + all: Láta vita við allar uppfærslur + critical: Láta einungis vita við áríðandi uppfærslur + label: Ný útgáfa á Mastodon er tiltæk + none: Aldrei láta vita um uppfærslur (ekki mælt með því) + patch: Láta vita við uppfærslur með lagfæringum trending_tag: Nýtt vinsælt efni krefst yfirferðar rule: text: Regla + settings: + indexable: Hafa notandasnið með í leitarvélum + show_application: Birta úr hvaða forriti þú sendir færslu tag: listable: Leyfa þessu myllumerki að birtast í leitum og í persónusniðamöppunni name: Myllumerki @@ -296,6 +310,7 @@ is: usable: Leyfa færslum að nota þetta myllumerki user: role: Hlutverk + time_zone: Tímabelti user_role: color: Litur merkis highlighted: Birta hlutverk sem merki á notandaauðkenni @@ -304,9 +319,11 @@ is: position: Forgangur webhook: events: Virkjaðir atburðir + template: Sniðmát gagna url: Slóð á endapunkt 'no': Nei not_recommended: Ekki mælt með þessu + overridden: Yfirtekið recommended: Mælt með required: mark: "*" diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml index 3af09275fb..9ad4323504 100644 --- a/config/locales/simple_form.it.yml +++ b/config/locales/simple_form.it.yml @@ -2,6 +2,14 @@ it: simple_form: hints: + account: + discoverable: I tuoi post pubblici e il tuo profilo potrebbero essere presenti o consigliati in varie aree di Mastodon e il tuo profilo potrebbe essere suggerito ad altri utenti. + display_name: Il tuo nome completo o il tuo soprannome. + fields: La tua homepage, i pronomi, l'età, tutto quello che vuoi. + indexable: I tuoi post pubblici potrebbero apparire nei risultati di ricerca su Mastodon. Le persone che hanno interagito con i tuoi post potrebbero essere in grado di cercarli indipendentemente. + note: 'Puoi @menzionare altre persone o usare gli #hashtags.' + show_collections: Le persone saranno in grado di navigare attraverso i tuoi seguaci e seguaci. Le persone che segui vedranno che li seguirai indipendentemente dalle tue impostazioni. + unlocked: Le persone saranno in grado di seguirti senza richiedere l'approvazione. Deseleziona se vuoi controllare le richieste di seguirti e scegli se accettare o rifiutare nuovi follower. account_alias: acct: Indica il nomeutente@dominio dell'account dal quale vuoi trasferirti account_migration: @@ -37,14 +45,11 @@ it: current_password: Per motivi di sicurezza inserisci la password dell'account attuale current_username: Per confermare, inserisci il nome utente dell'account attuale digest: Inviata solo dopo un lungo periodo di inattività e solo se hai ricevuto qualche messaggio personale in tua assenza - discoverable: Consenti al tuo account di essere scoperto da sconosciuti tramite consigli, tendenze e altre funzionalità email: Ti manderemo una email di conferma - fields: Puoi avere fino a 4 voci visualizzate come una tabella sul tuo profilo header: PNG, GIF o JPG. Al massimo %{size}. Verranno scalate a %{dimensions}px inbox_url: Copia la URL dalla pagina iniziale del ripetitore che vuoi usare irreversible: I post filtrati scompariranno in modo irreversibile, anche se il filtro viene eliminato locale: La lingua dell'interfaccia utente, di email e notifiche push - locked: Richiede che approvi i follower manualmente password: Usa almeno 8 caratteri phrase: Il confronto sarà eseguito ignorando minuscole/maiuscole e i content warning scopes: A quali API l'applicazione potrà avere accesso. Se selezionate un ambito di alto livello, non c'è bisogno di selezionare quelle singole. @@ -54,12 +59,9 @@ it: setting_display_media_default: Nascondi media segnati come sensibili setting_display_media_hide_all: Nascondi sempre tutti i media setting_display_media_show_all: Mostra sempre i media segnati come sensibili - setting_hide_network: Chi segui e chi segue te non saranno mostrati sul tuo profilo - setting_noindex: Ha effetto sul tuo profilo pubblico e sulle pagine degli status - setting_show_application: L'applicazione che usi per pubblicare i toot sarà mostrata nella vista di dettaglio dei tuoi toot setting_use_blurhash: I gradienti sono basati sui colori delle immagini nascoste ma offuscano tutti i dettagli setting_use_pending_items: Fare clic per mostrare i nuovi messaggi invece di aggiornare la timeline automaticamente - username: Il tuo nome utente sarà unico su %{domain} + username: Puoi usare lettere, numeri e caratteri di sottolineatura whole_word: Quando la parola chiave o la frase è solo alfanumerica, si applica solo se corrisponde alla parola intera domain_allow: domain: Questo dominio potrà recuperare i dati da questo server e i dati in arrivo da esso verranno elaborati e memorizzati @@ -118,6 +120,9 @@ it: sessions: otp: 'Inserisci il codice a due fattori generato dall''app del tuo telefono o usa uno dei codici di recupero:' webauthn: Se si tratta di una chiavetta USB assicurati di inserirla e, se necessario, toccarla. + settings: + indexable: La pagina del tuo profilo potrebbe apparire nei risultati di ricerca su Google, Bing e altri. + show_application: Sarai sempre in grado di vedere quale app ha pubblicato il tuo post indipendentemente. tag: name: Puoi cambiare solo il minuscolo/maiuscolo delle lettere, ad esempio, per renderlo più leggibile user: @@ -131,12 +136,17 @@ it: position: Un ruolo più alto decide la risoluzione dei conflitti in determinate situazioni. Alcune azioni possono essere eseguite solo su ruoli con priorità più bassa webhook: events: Seleziona eventi da inviare + template: Componi il tuo carico utile JSON utilizzando l'interpolazione variabile. Lascia vuoto per il JSON predefinito. url: Dove gli eventi saranno inviati labels: account: + discoverable: Include il profilo e i post negli algoritmi di scoperta fields: name: Etichetta value: Contenuto + indexable: Includi i post pubblici nei risultati di ricerca + show_collections: Mostra chi segui e chi ti segue sul profilo + unlocked: Accetta automaticamente nuovi follower account_alias: acct: Handle del vecchio account account_migration: @@ -174,7 +184,6 @@ it: context: Contesti del filtro current_password: Password corrente data: Dati - discoverable: Inserisci questo account nella directory display_name: Nome visualizzato email: Indirizzo email expires_in: Scade dopo @@ -184,7 +193,6 @@ it: inbox_url: URL della inbox del ripetitore irreversible: Elimina invece di nascondere locale: Lingua dell'interfaccia - locked: Blocca account max_uses: Numero massimo di utilizzi new_password: Nuova password note: Biografia @@ -196,7 +204,6 @@ it: setting_always_send_emails: Manda sempre notifiche via email setting_auto_play_gif: Riproduci automaticamente le GIF animate setting_boost_modal: Mostra dialogo di conferma prima del boost - setting_crop_images: Ritaglia immagini in post non espansi a 16x9 setting_default_language: Lingua dei post setting_default_privacy: Privacy dei post setting_default_sensitive: Segna sempre i media come sensibili @@ -208,9 +215,7 @@ it: setting_display_media_show_all: Mostra tutti setting_expand_spoilers: Espandi sempre post con content warning setting_hide_network: Nascondi la tua rete - setting_noindex: Non farti indicizzare dai motori di ricerca setting_reduce_motion: Riduci movimento nelle animazioni - setting_show_application: Rendi pubblica l'applicazione usata per inviare i post setting_system_font_ui: Usa il carattere predefinito del sistema setting_theme: Tema del sito setting_trends: Mostra tendenze di oggi @@ -259,7 +264,7 @@ it: timeline_preview: Consenti l'accesso non autenticato alle timeline pubbliche trendable_by_default: Consenti le tendenze senza revisione preventiva trends: Abilita le tendenze - trends_as_landing_page: Utilizza le tendenze come pagina di destinazione + trends_as_landing_page: Usa le tendenze come pagina di destinazione interactions: must_be_follower: Blocca notifiche da chi non ti segue must_be_following: Blocca notifiche dalle persone che non segui @@ -286,9 +291,18 @@ it: pending_account: Invia e-mail quando un nuovo account richiede l'approvazione reblog: Qualcuno ha condiviso il tuo post report: Una nuova segnalazione è stata inviata + software_updates: + all: Notifica su tutti gli aggiornamenti + critical: Notifica soltanto sugli aggiornamenti critici + label: Una nuova versione di Mastodon è disponibile + none: Non notificare mai sugli aggiornamenti (sconsigliato) + patch: Notifica sulle correzioni di bug trending_tag: La nuova tendenza richiede un controllo rule: text: Regola + settings: + indexable: Includi la pagina del profilo nei motori di ricerca + show_application: Mostra da quale app hai inviato un post tag: listable: Permetti a questo hashtag di apparire nella directory dei profili name: Hashtag @@ -296,6 +310,7 @@ it: usable: Permetti ai post di usare questo hashtag user: role: Ruolo + time_zone: Fuso orario user_role: color: Colore distintivo highlighted: Mostra il ruolo come distintivo sui profili utente @@ -304,9 +319,11 @@ it: position: Priorità webhook: events: Eventi abilitati + template: Modello di carico utile url: URL endpoint 'no': 'No' not_recommended: Non consigliato + overridden: Sostituito recommended: Consigliato required: mark: "*" diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index f7e2cb9545..41ae838b2e 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -2,6 +2,14 @@ ja: simple_form: hints: + account: + discoverable: プロフィールと公開投稿をMastodonのおすすめやハイライトとしてほかのユーザーに表示することを許可します。 + display_name: フルネーム、ハンドルネームなど + fields: ホームページ、代名詞、年齢など何でも構いません。 + indexable: "「公開」で送信された投稿がMastodonの検索結果にヒットするようになります。ここのチェック状態にかかわらず、ほかのユーザーにブーストやお気に入り登録された投稿はそのユーザーから検索されることがあります。" + note: '自己紹介には #ハッシュタグ や、ほかのアカウントのユーザー名 (@user) を使用できます' + show_collections: チェックを入れるとフォローとフォロワーの一覧を誰でも見られるようにします。チェックをはずすとこれらの情報を非公開にできますが、あなたがフォローしているユーザーからは、あなたがフォロワーになっていることがわかります。 + unlocked: 新しいフォロワーを自動的に承認します。チェックをはずすとフォローリクエストとその承認が必要になり、新しいフォロワーを受け入れるか拒否するかを自分で選べるようになります。 account_alias: acct: 引っ越し元のユーザー名@ドメインを指定してください account_migration: @@ -37,14 +45,11 @@ ja: current_password: 現在のアカウントのパスワードを入力してください current_username: 確認のため、現在のアカウントのユーザー名を入力してください digest: 長期間使用していない場合と不在時に返信を受けた場合のみ送信されます - discoverable: レコメンド、トレンド、その他の機能により、あなたのアカウントを他の人から見つけられるようにします email: 確認のメールが送信されます - fields: プロフィールに表として4つまでの項目を表示することができます header: "%{size}までのPNG、GIF、JPGが利用可能です。 %{dimensions}pxまで縮小されます" inbox_url: 使用したいリレーサーバーのトップページからURLをコピーします irreversible: フィルターが後で削除されても、除外された投稿は元に戻せなくなります locale: ユーザーインターフェース、メールやプッシュ通知の言語 - locked: フォロワーを手動で承認する必要があります password: 少なくとも8文字は入力してください phrase: 投稿内容の大文字小文字や閲覧注意に関係なく一致 scopes: アプリの API に許可するアクセス権を選択してください。最上位のスコープを選択する場合、個々のスコープを選択する必要はありません。 @@ -54,12 +59,9 @@ ja: setting_display_media_default: 閲覧注意としてマークされたメディアは隠す setting_display_media_hide_all: メディアを常に隠す setting_display_media_show_all: メディアを常に表示する - setting_hide_network: フォローとフォロワーの情報がプロフィールページで見られないようにします - setting_noindex: 公開プロフィールおよび各投稿ページに影響します - setting_show_application: 投稿するのに使用したアプリが投稿の詳細ビューに表示されるようになります setting_use_blurhash: ぼかしはメディアの色を元に生成されますが、細部は見えにくくなっています setting_use_pending_items: 新着があってもタイムラインを自動的にスクロールしないようにします - username: あなたのユーザー名は%{domain}の中で重複していない必要があります + username: アルファベット大文字と小文字、数字、アンダーバー「_」が使えます whole_word: キーワードまたはフレーズが英数字のみの場合、単語全体と一致する場合のみ適用されるようになります domain_allow: domain: 登録するとこのサーバーからデータを受信したり、このドメインから受信するデータを処理して保存できるようになります @@ -78,7 +80,7 @@ ja: backups_retention_period: 生成されたユーザーのアーカイブを指定した日数の間保持します。 bootstrap_timeline_accounts: これらのアカウントは、新しいユーザー向けのおすすめユーザーの一番上にピン留めされます。 closed_registrations_message: アカウント作成を停止している時に表示されます - content_cache_retention_period: 正の値に設定されている場合、他のサーバーの投稿は指定された日数の後に削除されます。元に戻せません。 + content_cache_retention_period: 指定した日数が経過した他のサーバーの投稿とブーストを削除します。削除された投稿は再取得できない場合があります。削除された投稿についたブックマークやお気に入り、ブーストも失われ、元に戻せません。 custom_css: ウェブ版のMastodonでカスタムスタイルを適用できます。 mascot: 上級者向けWebインターフェースのイラストを上書きします。 media_cache_retention_period: 正の値に設定されている場合、ダウンロードされたメディアファイルは指定された日数の後に削除され、リクエストに応じて再ダウンロードされます。 @@ -118,6 +120,9 @@ ja: sessions: otp: '携帯電話のアプリで生成された二要素認証コードを入力するか、リカバリーコードを使用してください:' webauthn: USBキーの場合は、必ず挿入し、必要に応じてタップしてください。 + settings: + indexable: プロフィールがGoogleやBingなどの検索結果にヒットするようになります。 + show_application: 自分で自分の投稿の送信元アプリを確認することは、ここのチェック状態にかかわらず可能です。 tag: name: 視認性向上などのためにアルファベット大文字小文字の変更のみ行うことができます user: @@ -131,12 +136,17 @@ ja: position: 場合により、より高いロールのユーザーが紛争の解決を決定します。特定のアクションは優先度が低いロールでのみ実行できます。 webhook: events: 送信するイベントを選択 + template: 変数補完を使用して、独自のJSONペイロードを構成できます。デフォルトのJSONを使用する場合は空白のままにします。 url: イベントの送信先 labels: account: + discoverable: アカウントを見つけやすくする fields: name: ラベル value: 内容 + indexable: 公開投稿を検索できるようにする + show_collections: フォローとフォロワーの一覧を開示する + unlocked: フォローリクエストを不要にする account_alias: acct: 引っ越し元のユーザー ID account_migration: @@ -174,7 +184,6 @@ ja: context: 除外対象 current_password: 現在のパスワード data: データ - discoverable: ディレクトリに掲載する display_name: 表示名 email: メールアドレス expires_in: 有効期限 @@ -184,7 +193,6 @@ ja: inbox_url: リレーサーバーの inbox URL irreversible: 隠すのではなく除外する locale: 言語 - locked: 承認制アカウントにする max_uses: 使用できる回数 new_password: 新しいパスワード note: プロフィール @@ -196,7 +204,6 @@ ja: setting_always_send_emails: 常にメール通知を送信する setting_auto_play_gif: アニメーションGIFを自動再生する setting_boost_modal: ブーストする前に確認ダイアログを表示する - setting_crop_images: 投稿の詳細以外では画像を16:9に切り抜く setting_default_language: 投稿する言語 setting_default_privacy: 投稿の公開範囲 setting_default_sensitive: メディアを常に閲覧注意としてマークする @@ -208,9 +215,7 @@ ja: setting_display_media_show_all: 表示 setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する setting_hide_network: 繋がりを隠す - setting_noindex: 検索エンジンによるインデックスを拒否する setting_reduce_motion: アニメーションの動きを減らす - setting_show_application: 送信したアプリを開示する setting_system_font_ui: システムのデフォルトフォントを使う setting_theme: サイトテーマ setting_trends: 本日のトレンドタグを表示する @@ -286,9 +291,18 @@ ja: pending_account: 新しいアカウントの承認が必要な時 reblog: 投稿がブーストされた時 report: 新しい通報が送信された時 + software_updates: + all: すべてのアップデートを通知する + critical: 緊急のアップデートのみ通知する + label: 新しいMastodonバージョンが利用可能です + none: 通知しない (非推奨) + patch: 緊急のアップデートとバグ修正アップデートを通知する trending_tag: 新しいトレンドのレビューをする必要がある時 rule: text: ルール + settings: + indexable: 検索エンジンからアクセスできるようにする + show_application: 投稿に使ったアプリを開示する tag: listable: 検索とディレクトリへの使用を許可する name: ハッシュタグ @@ -296,6 +310,7 @@ ja: usable: 投稿への使用を許可する user: role: ロール + time_zone: タイムゾーン user_role: color: バッジの色 highlighted: プロフィールにロールのバッジを表示する @@ -304,9 +319,11 @@ ja: position: 優先度 webhook: events: 有効なイベント + template: ペイロードテンプレート url: エンドポイントURL 'no': いいえ not_recommended: 非推奨 + overridden: 上書き済み recommended: おすすめ required: mark: "*" diff --git a/config/locales/simple_form.ka.yml b/config/locales/simple_form.ka.yml index 2df3db45bf..e5d874c5a5 100644 --- a/config/locales/simple_form.ka.yml +++ b/config/locales/simple_form.ka.yml @@ -8,16 +8,12 @@ ka: bot: ეს ანგარიში უმთავრესად ასრულებს ავტომატურ მოქმედებებს და შესაძლოა არ იყოს მონიტორინგის ქვეშ context: ერთ ან მრავალი კონტექსტი სადაც ფილტრი უნდა შესრულდეს digest: იგზავნება მხოლოდ ხანგრძლივი უაქტივობის პერიოდის შემდეგ და არყოფნისას თუ მიიღეთ ერთი წერილი მაინც - fields: პროფილზე ტაბულის სახით შესაძლოა საჩვენებლად გაგაჩნდეთ მაქს. 4 პუნქტი header: პნგ, გიფ ან ჯპგ. მაქს. %{size}. ზომა დაპატარავდება %{dimensions}პიქს.-ზე inbox_url: ურლ დააკოირეთ გამოყენებისთვის სასურველი რილეის წინა გვერდიდან irreversible: გაფილტრული ტუტები გაუქმდება აღუდგენლად, იმ შემთხვევაშიც კი თუ ფილტრი სამომავლოდ გაუქმდება locale: მომხმარებლის ინტერფეისის, ელ-ფოსტის წერილების და ფუშ შეტყობინებების ენა - locked: საჭიროებს თქვენ მიერ მიმდევრების ხელით დადასტურებას phrase: დამთხვევა მოხდება დიდი და პატარა ასოების ან კონტენტის გაფრთხილების გათვალისწინების გარეშე scopes: რომელი აპიებისადმი ექნება აპლიკაციას ცვდომა. თუ არიჩევთ უმთავრეს ფარგლებს, არ დაგჭირდებათ ინდივიდუალურების ამორჩევა. - setting_hide_network: ვის მიყვებით და ვინ მოგყვებათ არ გამოჩნდება აქ - setting_noindex: გავლენას ახდენს თქვენს ღია პროფილისა და სტატუსის გვერდებზე whole_word: როდესაც სიტყვა ან ფრაზა მხოლოდ ალფა-ნუმერიკულია, ის დაფიქსირდება თუ ემთხვევა სრულ სიტყვას imports: data: ცსვ ფაილის ექსპორტი მოხდა მასტოდონის სხვა ინსტანციიდან @@ -48,7 +44,6 @@ ka: inbox_url: რილეი ინბოქსის ურლ irreversible: გაუქმდეს დამალვის მაგივრად locale: ინტერფეისის ენა - locked: ანგარიშის ჩაკეტვა max_uses: მოხმარების მაქს. ოდენობა new_password: ახალი პაროლი note: ბიო. @@ -62,7 +57,6 @@ ka: setting_default_sensitive: ყოველთვის მოინიშნოს მედია მგრძნობიარედ setting_delete_modal: ტუტის გაუქმებამდე გამოჩნდეს დადასტურების ფანჯარა setting_hide_network: თქვენი ქსელის დამალვა - setting_noindex: საძოები სისტემების ინდექსაციის შეჩერება setting_reduce_motion: მოძრაობის შემცირება ანიმაციებში setting_system_font_ui: მოხდეს სისტემის საწყისი ფონტის მოხმარება setting_theme: საიტის თემა diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml index 2f8a9261e3..1e1c52da24 100644 --- a/config/locales/simple_form.kab.yml +++ b/config/locales/simple_form.kab.yml @@ -14,13 +14,10 @@ kab: email: Ad n-teṭṭfeḍ imayl i usentem irreversible: Tijewwaqin i tessazedgeḍ ad ttwakksent i lebda, ula ma tekkseḍ imsizdeg-nni ar zdat locale: Tutlayt n ugrudem, imaylen d tilγa - locked: Isra asentem s wufus n ineḍfaren password: Seqdec ma drus 8 n yisekkilen setting_display_media_default: Ffer teywalt yettwacreḍ d tanafrit setting_display_media_hide_all: Ffer yal tikkelt akk taywalt setting_display_media_show_all: Ffer yal tikkelt teywalt yettwacreḍ d tanafrit - setting_hide_network: Wid i teṭṭafaṛeḍ d wid i k-yeṭṭafaṛen ur d-ttwaseknen ara deg umaγnu-inek - username: Isem-ik n umseqdac ad yili d ayiwen, ulac am netta deg %{domain} imports: data: Afaylu CSV id yusan seg uqeddac-nniḍen n Maṣṭudun ip_block: @@ -56,12 +53,10 @@ kab: confirm_password: Sentem awal uffir current_password: Awal uffir n tura data: Isefka - discoverable: Rnu amiḍan-a γer ukaram display_name: Isem ara d-yettwaskanen email: Tansa imayl header: Ixef locale: Tutlayt n wegrudem - locked: Rgel amiḍan max_uses: Amḍan afellay n iseqdacen new_password: Awal uffir amaynut note: Tameddurt diff --git a/config/locales/simple_form.kk.yml b/config/locales/simple_form.kk.yml index 7932e54beb..5c1854d188 100644 --- a/config/locales/simple_form.kk.yml +++ b/config/locales/simple_form.kk.yml @@ -29,14 +29,12 @@ kk: context: Фильтр контекстері current_password: Ағымдағы кілтсөз data: Дата - discoverable: Бұл аккаунтты каталогта көрсету display_name: Атын көрсет email: Эл. пошта мекен жайы expires_in: Аяқталу мерзімі fields: Профиль метадатасы header: Басы locale: Интерфейс тілі - locked: Аккаунтты құлыптау max_uses: Максимум қолданушы саны new_password: Жаңа құпиясөз note: Био @@ -46,7 +44,6 @@ kk: setting_advanced_layout: Кеңейтілген веб-интерфейс қосу setting_auto_play_gif: GIF анимацияларды бірден қосу setting_boost_modal: Бөлісу алдында растау диалогын көрсету - setting_crop_images: Кеңейтілмеген жазбаларда суреттерді 16х9 көлеміне кес setting_default_language: Жазба тілі setting_default_privacy: Жазба құпиялылығы setting_default_sensitive: Медиаларды әрдайым нәзік ретінде белгілеу diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index 9cb8dae478..7b26561553 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -2,6 +2,14 @@ ko: simple_form: hints: + account: + discoverable: 내 공개 게시물과 프로필이 마스토돈의 다양한 추천 기능에 나타날 수 있고 프로필이 다른 사용자에게 제안될 수 있습니다 + display_name: 실명 혹은 별명. + fields: 홈페이지, 호칭, 나이, 뭐든지 적고 싶은 것들. + indexable: 내 공개 게시물이 마스토돈의 검색 결과에 나타날 수 있습니다. 내 게시물과 상호작용했던 사람들은 이 설정과 관계 없이 그 게시물을 검색할 수 있습니다. + note: '남을 @mention 하거나 #hashtag 태그를 달 수 있습니다.' + show_collections: 사람들이 내 계정의 팔로우와 팔로워를 볼 수 있습니다. 내가 팔로우 하는 사람은 이 설정에 관계 없이 내가 팔로우 했다는 사실을 알 수 있습니다. + unlocked: 사람들이 승인 요청 없이 나를 팔로우 할 수 있습니다. 팔로우 요청을 심사하고 새 팔로워를 승인할지 거부할지 선택하고 싶다면 해제하세요. account_alias: acct: 이동하고자 하는 계정의 사용자이름@도메인을 설정하세요 account_migration: @@ -37,29 +45,23 @@ ko: current_password: 보안을 위해 현재 계정의 암호를 입력해주세요 current_username: 확인을 위해, 현재 계정의 사용자명을 입력해주세요 digest: 오랫동안 활동하지 않았을 때 받은 멘션들에 대한 요약 받기 - discoverable: 추천, 트렌드 및 기타 기능을 통해 낯선 사람이 내 계정을 발견할 수 있도록 허용합니다 - email: 당신은 확인 메일을 받게 됩니다 - fields: 당신의 프로파일에 최대 4개까지 표 형식으로 나타낼 수 있습니다 + email: 확인용 이메일을 보냈습니다. header: PNG, GIF 혹은 JPG. 최대 %{size}. %{dimensions}px로 축소 됨 inbox_url: 사용 할 릴레이 서버의 프론트페이지에서 URL을 복사합니다 irreversible: 필터링 된 게시물은 나중에 필터가 사라지더라도 돌아오지 않게 됩니다 locale: 사용자 인터페이스, 이메일, 푸시 알림 언어 - locked: 팔로우 요청을 승인제로 두어 누가 당신을 팔로우 할 수 있는지를 수동으로 제어합니다. password: 최소 8글자 phrase: 게시물 내용이나 열람주의 내용 안에서 대소문자 구분 없이 매칭 됩니다 scopes: 애플리케이션에 허용할 API들입니다. 최상위 스코프를 선택하면 개별적인 것은 선택하지 않아도 됩니다. setting_aggregate_reblogs: 최근에 부스트 됐던 게시물은 새로 부스트 되어도 보여주지 않기 (새로 받은 부스트에만 적용됩니다) setting_always_send_emails: 기본적으로 마스토돈을 활동적으로 사용하고 있을 때에는 이메일 알림이 보내지지 않습니다 setting_default_sensitive: 민감한 미디어는 기본적으로 가려져 있으며 클릭해서 볼 수 있습니다 - setting_display_media_default: 민감함으로 설정 된 미디어 가리기 - setting_display_media_hide_all: 항상 모든 미디어를 가리기 - setting_display_media_show_all: 민감함으로 설정 된 미디어를 항상 보이기 - setting_hide_network: 나를 팔로우 하는 사람들과 내가 팔로우 하는 사람들을 내 프로필에서 숨깁니다 - setting_noindex: 공개 프로필 및 각 게시물 페이지에 영향을 미칩니다 - setting_show_application: 당신이 게시물을 작성하는데에 사용한 앱이 게시물의 상세정보에 표시 됩니다 + setting_display_media_default: 민감함으로 표시된 미디어 가리기 + setting_display_media_hide_all: 모든 미디어를 가리기 + setting_display_media_show_all: 모든 미디어를 보이기 setting_use_blurhash: 그라디언트는 숨겨진 내용의 색상을 기반으로 하지만 상세 내용은 보이지 않게 합니다 setting_use_pending_items: 타임라인의 새 게시물을 자동으로 보여 주는 대신, 클릭해서 나타내도록 합니다 - username: 당신의 사용자명은 %{domain} 안에서 유일해야 합니다 + username: 문자, 숫자, 밑줄을 사용할 수 있습니다 whole_word: 키워드가 영문과 숫자로만 이루어 진 경우, 단어 전체에 매칭 되었을 때에만 작동하게 합니다 domain_allow: domain: 이 도메인은 이 서버에서 데이터를 가져갈 수 있고 이 도메인에서 보내진 데이터는 처리되고 저장 됩니다 @@ -72,15 +74,15 @@ ko: action: 게시물이 필터에 걸러질 때 어떤 동작을 수행할 지 고르세요 actions: hide: 필터에 걸러진 글을 처음부터 없었던 것처럼 완전히 가리기 - warn: 필터에 걸러진 글을 필터 제목과 함께 경고 뒤에 가리기 + warn: 필터 제목을 언급하는 경고 뒤에 걸러진 내용을 숨기기 form_admin_settings: activity_api_enabled: 주별 로컬에 게시된 글, 활성 사용자 및 새로운 가입자 수 backups_retention_period: 생성된 사용자 아카이브를 며칠동안 저장할 지. bootstrap_timeline_accounts: 이 계정들은 팔로우 추천 목록 상단에 고정됩니다. closed_registrations_message: 새 가입을 차단했을 때 표시됩니다 - content_cache_retention_period: 양수로 설정되었다면 다른 서버의 게시물은 여기서 설정된 일수가 지나면 삭제될 것입니다. 되돌릴 수 없는 작업일 수 있습니다. + content_cache_retention_period: 다른 서버의 게시물과 부스트들은 지정한 일수가 지나면 삭제될 것입니다. 몇몇 게시물들은 복구가 불가능할 것입니다. 관련된 북마크, 좋아요, 부스트 또한 잃어버릴 것이며 취소도 할 수 없습니다. custom_css: 사용자 지정 스타일을 웹 버전의 마스토돈에 지정할 수 있습니다. - mascot: 고급 사용자 인터페이스에 있는 일러스트를 교체합니다. + mascot: 고급 웹 인터페이스의 그림을 대체합니다. media_cache_retention_period: 양수로 설정된 경우 다운로드된 미디어 파일들은 지정된 일수가 지나면 삭제될 것이고 필요할 때 다시 다운로드 될 것입니다. peers_api_enabled: 이 서버가 연합우주에서 만났던 서버들에 대한 도메인 네임의 목록입니다. 해당 서버와 어떤 연합을 했는지에 대한 정보는 전혀 포함되지 않고, 단순히 그 서버를 알고 있는지에 대한 것입니다. 이것은 일반적으로 연합에 대한 통계를 수집할 때 사용됩니다. profile_directory: 프로필 책자는 발견되기를 희망하는 모든 사람들의 목록을 나열합니다. @@ -89,7 +91,7 @@ ko: site_contact_username: 사람들이 마스토돈에서 당신에게 연락할 방법. site_extended_description: 방문자와 사용자에게 유용할 수 있는 추가정보들. 마크다운 문법을 사용할 수 있습니다. site_short_description: 이 서버를 특별하게 구분할 수 있는 짧은 설명. 누가 운영하고, 누구를 위한 것인가요? - site_terms: 자신만의 개인정보 정책을 사용하거나 비워두는 것으로 기본값을 사용할 수 있습니다. 마크다운 문법을 사용할 수 있습니다. + site_terms: 자신만의 개인정보처리방침을 사용하거나 비워두는 것으로 기본값을 사용할 수 있습니다. 마크다운 문법을 사용할 수 있습니다. site_title: 사람들이 이 서버를 도메인 네임 대신에 부를 이름. status_page_url: 이 서버가 중단된 동안 사람들이 서버의 상태를 볼 수 있는 페이지 URL theme: 로그인 하지 않은 사용자나 새로운 사용자가 보게 될 테마. @@ -101,7 +103,7 @@ ko: form_challenge: current_password: 당신은 보안 구역에 진입하고 있습니다 imports: - data: 다른 마스토돈 서버에서 추출된 CSV 파일 + data: 다른 마스토돈 서버에서 내보낸 CSV 파일 invite_request: text: 이 정보는 신청을 검토하는데 도움을 줄 수 있습니다. ip_block: @@ -116,8 +118,11 @@ ko: rule: text: 이 서버 사용자들이 지켜야 할 규칙과 요구사항을 설명해주세요. 짧고 간단하게 작성해주세요 sessions: - otp: '휴대전화에서 생성 된 2단계 인증 코드를 입력하거나, 복구 코드 중 하나를 사용하세요:' + otp: '휴대전화에서 생성된 이중 인증 코드를 입력하거나, 복구 코드 중 하나를 사용하세요:' webauthn: USB 키라면 삽입했는지 확인하고, 필요하다면 누르세요. + settings: + indexable: 내 프로필 페이지가 구글, 빙 등의 검색엔진에 표시될 수 있습니다. + show_application: 나 자신은 이 설정과 관계 없이 어떤 앱으로 게시물을 작성했는지 볼 수 있습니다. tag: name: 읽기 쉽게하기 위한 글자의 대소문자만 변경할 수 있습니다. user: @@ -131,12 +136,17 @@ ko: position: 특정 상황에서 충돌이 발생할 경우 더 높은 역할이 충돌을 해결합니다. 특정 작업은 우선순위가 낮은 역할에 대해서만 수행될 수 있습니다 webhook: events: 전송할 이벤트를 선택하세요 + template: 원하는 JSON 페이로드를 변수와 함께 작성하거나, 그냥 냅둬서 기본 JSON을 사용할 수 있습니다. url: 이벤트가 어디로 전송될 지 labels: account: + discoverable: 발견하기 알고리즘에 프로필과 게시물을 추천하기 fields: name: 라벨 value: 내용 + indexable: 공개 게시물을 검색 결과에 포함시키기 + show_collections: 프로필에 팔로우와 팔로워 보이기 + unlocked: 새 팔로워를 자동으로 수락하기 account_alias: acct: 기존 계정의 핸들 account_migration: @@ -150,11 +160,11 @@ ko: text: 커스텀 경고 type: 조치 types: - disable: 비활성화 - none: 아무 것도 하지 않기 + disable: 동결 + none: 경고 보내기 sensitive: 민감함 silence: 제한 - suspend: 정지하고 되돌릴 수 없는 데이터 삭제 + suspend: 정지 warning_preset_id: 경고 틀 사용하기 announcement: all_day: 종일 일정 @@ -163,40 +173,37 @@ ko: starts_at: 이벤트 시작 text: 공지사항 appeal: - text: 이 결정이 왜 번복되어야 하는지에 대해 설명해주세요 + text: 이 결정을 번복해야만 하는 이유가 무엇입니까 defaults: autofollow: 초대를 통한 팔로우 - avatar: 아바타 - bot: 이것은 봇 계정입니다 + avatar: 프로필 사진 + bot: 이것은 자동화된 계정입니다 chosen_languages: 언어 필터링 confirm_new_password: 암호 다시 입력 confirm_password: 암호 다시 입력 context: 필터 컨텍스트 current_password: 현재 암호 입력 data: 데이터 - discoverable: 계정을 다른 사람들에게 추천하기 - display_name: 표시되는 이름 + display_name: 표시 이름 email: 이메일 주소 - expires_in: 만료시각 - fields: 프로필 메타데이터 + expires_in: 만기 + fields: 부가 필드 header: 헤더 honeypot: "%{label} (채우지 마시오)" inbox_url: 릴레이 서버의 inbox URL irreversible: 숨기는 대신 삭제 locale: 인터페이스 언어 - locked: 팔로우 요청 필요 max_uses: 사용 횟수 제한 new_password: 새로운 암호 입력 - note: 자기소개 - otp_attempt: 2단계 인증 코드 + note: 소개 + otp_attempt: 이중 인증 코드 password: 암호 phrase: 키워드 또는 문장 - setting_advanced_layout: 고급 웹 UI 활성화 + setting_advanced_layout: 고급 웹 인터페이스 활성화 setting_aggregate_reblogs: 타임라인의 부스트를 그룹화 setting_always_send_emails: 항상 이메일 알림 보내기 setting_auto_play_gif: 애니메이션 GIF를 자동 재생 setting_boost_modal: 부스트 전 확인 창을 표시 - setting_crop_images: 확장되지 않은 게시물의 이미지를 16x9로 자르기 setting_default_language: 게시물 언어 setting_default_privacy: 게시물 프라이버시 setting_default_sensitive: 미디어를 언제나 민감한 콘텐츠로 설정 @@ -206,15 +213,13 @@ ko: setting_display_media_default: 기본 setting_display_media_hide_all: 모두 가리기 setting_display_media_show_all: 모두 보이기 - setting_expand_spoilers: 열람주의 툿을 항상 펼치기 + setting_expand_spoilers: 내용 경고로 표시된 게시물을 항상 펼치기 setting_hide_network: 내 인맥 숨기기 - setting_noindex: 검색엔진의 인덱싱을 거절 setting_reduce_motion: 애니메이션 줄이기 - setting_show_application: 툿 작성에 사용한 앱을 공개 setting_system_font_ui: 시스템의 기본 글꼴을 사용 setting_theme: 사이트 테마 setting_trends: 오늘의 유행 보이기 - setting_unfollow_modal: 언팔로우 전 언팔로우 확인 표시 + setting_unfollow_modal: 누군가를 언팔로우 할 때 확인란 표시하기 setting_use_blurhash: 숨겨진 미디어에 대해 그라디언트 표시 setting_use_pending_items: 느린 모드 severity: 심각도 @@ -251,7 +256,7 @@ ko: site_contact_username: 연락 받을 관리자 사용자명 site_extended_description: 확장된 설명 site_short_description: 서버 설명 - site_terms: 개인정보 정책 + site_terms: 개인정보처리방침 site_title: 서버 이름 status_page_url: 상태 페이지 URL theme: 기본 테마 @@ -286,9 +291,18 @@ ko: pending_account: 새 계정이 심사가 필요할 때 reblog: 누군가 내 게시물을 부스트 했을 때 report: 새 신고가 접수되었을 때 + software_updates: + all: 모든 업데이트에 대해 알림 + critical: 긴급 업데이트에 대해서만 알림 + label: 새 마스토돈 버전이 사용 가능합니다 + none: 업데이트에 대해 알리지 않기 (비추천) + patch: 버그픽스 업데이트에 대해 알림 trending_tag: 검토해야 할 새 유행 rule: text: 규칙 + settings: + indexable: 검색 엔진에 프로필 페이지 기재하기 + show_application: 어떤 앱으로 게시물을 보냈는지 표시 tag: listable: 이 해시태그가 검색과 추천에 보여지도록 허용 name: 해시태그 @@ -296,6 +310,7 @@ ko: usable: 이 해시태그를 게시물에 사용 가능하도록 허용 user: role: 역할 + time_zone: 시간대 user_role: color: 배지 색상 highlighted: 역할 배지를 사용자 프로필에 표시 @@ -304,9 +319,11 @@ ko: position: 우선순위 webhook: events: 활성화된 이벤트 + template: 페이로드 템플릿 url: 엔드포인트 URL - 'no': 아니오 + 'no': 아니요 not_recommended: 추천하지 않음 + overridden: 덮어씌워짐 recommended: 추천함 required: mark: "*" diff --git a/config/locales/simple_form.ku.yml b/config/locales/simple_form.ku.yml index f7188152d6..fb7a45c34b 100644 --- a/config/locales/simple_form.ku.yml +++ b/config/locales/simple_form.ku.yml @@ -35,14 +35,11 @@ ku: current_password: Ji bo ewlehiyê ji kerema xwe borînpeyva ajimêrê xwe têxe current_username: Ji bo piştrastkirinê, ji kerema xwe navê bikarhêner ya ajimêrê niha binvîse digest: Tenê piştî demek dirêj neçalakiyê de û tenê di nebûna te da peyamên teybetî standî be tê şandin - discoverable: Mafê biden ku ajimêra te bi pêşniyar û taybetmendiyên din ji aliyê biyaniyan ve bê vedîtin email: Ji te re e-name ya pejirandinê were - fields: Tu dikarî heya 4 hêmanan wekî tabloyek li ser profîla xwe nîşan bidî header: PNG, GIF an jî JPG. Herî zêde %{size} ber bi %{dimensions}px ve were kêmkirin inbox_url: Girêdanê ji rûpela pêşîn a guhêrkera ku tu dixwazî bi kar bînî jê bigire irreversible: Şandiyên parzûnkirî êdî bê veger wenda bibe, heger parzûn paşê were rakirin jî nabe locale: Zimanê navrûyê bikarhêner, agahdarîyên e-name û pêl kirin - locked: Bi pejirandina daxwazên şopandinê, kî dikare te bişopîne bi destan kontrol bike password: Herî kêm 8 tîpan bi kar bîne phrase: Ji rewşa nivîsê tîpên girdek/hûrdek an jî ji hişyariya naveroka ya şandiyê wek serbixwe wê were hevbeş kirin scopes: |- @@ -54,12 +51,8 @@ ku: setting_display_media_default: Medyaya wekî hestyarî hatiye nîşankirî ye veşêre setting_display_media_hide_all: Medyayê tim veşêre setting_display_media_show_all: Medyayê tim nîşan bike - setting_hide_network: Kesên ku te dişopîne û kesên tu dişopînî ev ên profîla te de were veşartin - setting_noindex: Bandor li hemî profîla te û şandiyên rûpela te dike - setting_show_application: Navê sepana ku tu ji bo şandinê wê bi kar tîne dê di dîtinê berferh ên di şandiyên te de were xuyakirin setting_use_blurhash: Gradyen xwe bi rengên dîtbarîyên veşartî ve radigire, lê belê hûrgilîyan diveşêre setting_use_pending_items: Li şûna ku herkê wek bixweber bizivirînî nûvekirina demnameyê li paş tikandinekî veşêre - username: Navê te yê bikarhênerî li ser %{domain} de bêhempa be whole_word: Dema peyvkilîd an jî hevok bi tenê alfahejmarî çêbe, bi tenê hemû bêjeyê re li hev bike wê pêk bê domain_allow: domain: Ev navê navperê, ji vê rajekarê wê daneyan bistîne û daneyên ku jê bê wê were sazkirin û veşartin @@ -170,7 +163,6 @@ ku: context: Parzûnê naverokan current_password: Borînpeyva heyî data: Dane - discoverable: Ji yên din re ajimêrê pêşniyar bike display_name: Navê nîşandanê email: Navnîşana E-nameyê expires_in: Dîroka xilasbûyînê @@ -180,7 +172,6 @@ ku: inbox_url: Girêdana guhêrkera peymanên hatî irreversible: Li şûna veşartinê jê bibe locale: Zimanê navrûyê - locked: Ajimêr kilît bike max_uses: Hejmara bikaranîna herî zêde new_password: Borînpeyva nû note: Jiyanname @@ -192,7 +183,6 @@ ku: setting_always_send_emails: Her dem agahdariya e-nameyê bişîne setting_auto_play_gif: GIF ên livok bi xweber bilîzine setting_boost_modal: Gotûbêja pejirandinê nîşan bide berî ku şandî werê bilindkirin - setting_crop_images: Wêneyên di nav şandiyên ku nehatine berfireh kirin wek 16×9 jê bike setting_default_language: Zimanê weşanê setting_default_privacy: Ewlehiya weşanê setting_default_sensitive: Her dem medya wek hestyar bide nîşan @@ -204,9 +194,7 @@ ku: setting_display_media_show_all: Hemûyan nîşan bide setting_expand_spoilers: Şandîyên ku bi agahdarîyên naverokê va hatine nîşankirin her dem berfireh bike setting_hide_network: Grafîka xwe ya civakî veşêre - setting_noindex: Bes e nexe di nav rêzên lêgerîna gerokan setting_reduce_motion: Lîstikên livoka kêm bike - setting_show_application: Sepana ku ji bo şandina şandiyan tê bikaranîn diyar bike setting_system_font_ui: Curenivîsa berdest a pergalê bi kar bîne setting_theme: Rûkarê malperê setting_trends: Rojeva îro nîşan bide diff --git a/config/locales/simple_form.lv.yml b/config/locales/simple_form.lv.yml index ff727235ed..bf831c946f 100644 --- a/config/locales/simple_form.lv.yml +++ b/config/locales/simple_form.lv.yml @@ -2,6 +2,14 @@ lv: simple_form: hints: + account: + discoverable: Tavas publiskās ziņas un profils var tikt piedāvāti vai ieteikti dažādās Mastodon vietās, un tavs profils var tikt ieteikts citiem lietotājiem. + display_name: Tavs pilnais vārds vai tavs joku vārds. + fields: Tava mājas lapa, vietniekvārdi, vecums, viss, ko vēlies. + indexable: Tavas publiskās ziņas var tikt parādītas Mastodon meklēšanas rezultātos. Personas, kuras ir mijiedarbojušās ar tavām ziņām, var tās meklēt neatkarīgi no tā. + note: 'Tu vari @minēt citus cilvēkus vai #mirkļbirkas.' + show_collections: Cilvēki varēs pārlūkot tavus sekotājus un kam tu seko. Cilvēki, kuriem seko, redzēs, ka tu seko viņiem neatkarīgi no tā. + unlocked: Cilvēki varēs tev sekot, neprasot apstiprinājumu. Noņem atzīmi, ja vēlies pārskatīt sekošanas pieprasījumus un izvēlēties, pieņemt vai noraidīt jaunus sekotājus. account_alias: acct: Norādi konta lietotājvārdu@domēnu, no kura vēlies pārvākties account_migration: @@ -37,14 +45,11 @@ lv: current_password: Drošības nolūkos, lūdzu, ievadi pašreizējā konta paroli current_username: Lai apstiprinātu, lūdzu, ievadi pašreizējā konta paroli digest: Sūta tikai pēc ilgstošas neaktivitātes un tikai tad, ja savas prombūtnes laikā neesi saņēmis personiskas ziņas - discoverable: Ļauj svešiniekiem atklāt savu kontu caur ieteikumiem, tendencēm un citām iespējām email: Tev tiks nosūtīts apstiprinājuma e-pasts - fields: Savā profilā kā tabulu vari parādīt līdz 4 vienumiem header: PNG, GIF vai JPG. Ne vairāk kā %{size}. Tiks samazināts līdz %{dimensions}px inbox_url: Nokopē URL no tā releja sākumlapas, kuru vēlies izmantot irreversible: Filtrētās ziņas neatgriezeniski pazudīs, pat ja filtrs vēlāk tiks noņemts locale: Lietotāja saskarnes, e-pasta ziņojumu un push paziņojumu valoda - locked: Manuāli kontrolē, kas var tev sekot, apstiprinot sekošanas pieprasījumus password: Izmanto vismaz 8 rakstzīmes phrase: Tiks saskaņots neatkarīgi no ziņas teksta reģistra vai satura brīdinājuma scopes: Kuriem API lietojumprogrammai būs atļauta piekļuve. Ja izvēlies augstākā līmeņa tvērumu, tev nav jāatlasa atsevišķi vienumi. @@ -54,12 +59,9 @@ lv: setting_display_media_default: Paslēpt multividi, kas atzīmēta kā sensitīva setting_display_media_hide_all: Vienmēr slēpt multividi setting_display_media_show_all: Vienmēr rādīt multividi - setting_hide_network: Tavā profilā netiks rādīts, kam tu seko un kurš seko tev - setting_noindex: Ietekmē tavu publisko profilu un ziņu lapas - setting_show_application: Lietojumprogramma, ko tu izmanto publicēšanai, tiks parādīta tavu ziņu detalizētajā skatā setting_use_blurhash: Gradientu pamatā ir paslēpto vizuālo attēlu krāsas, bet neskaidras visas detaļas setting_use_pending_items: Paslēpt laika skalas atjauninājumus aiz klikšķa, nevis automātiski ritini plūsmu - username: Tavs lietotājvārds %{domain} būs unikāls + username: Tu vari lietot burtus, ciparus un zemsvītras whole_word: Ja atslēgvārds vai frāze ir tikai burtciparu, tas tiks lietots tikai tad, ja tas atbilst visam vārdam domain_allow: domain: Šis domēns varēs izgūt datus no šī servera, un no tā ienākošie dati tiks apstrādāti un saglabāti @@ -118,6 +120,9 @@ lv: sessions: otp: 'Ievadi divfaktoru kodu, ko ģenerējusi tava tālruņa lietotne, vai izmanto kādu no atkopšanas kodiem:' webauthn: Ja tā ir USB atslēga, noteikti ievieto to un, ja nepieciešams, pieskaries tai. + settings: + indexable: Tava profila lapa var tikt parādīta Google, Bing un citu meklēšanas dzinēju rezultātos. + show_application: Tu vienmēr varēsi redzēt, kura lietotne publicēja tavu ziņu. tag: name: Tu vari mainīt tikai burtu lielumu, piemēram, lai tie būtu vieglāk lasāmi user: @@ -131,12 +136,17 @@ lv: position: What is "alower"? webhook: events: Atlasi nosūtāmos notikums + template: Izveido savu JSON lietderīgo slodzi, izmantojot mainīgo interpolāciju. Atstāj tukšu noklusējuma JSON. url: Kur notikumi tiks nosūtīti labels: account: + discoverable: Funkcijas profils un ziņas atklāšanas algoritmos fields: name: Marķējums value: Saturs + indexable: Iekļaut meklēšanas rezultātos publiskas ziņas + show_collections: Rādīt profilā sekotājus un sekojamos + unlocked: Automātiski akceptēt jaunus sekotājus account_alias: acct: Vecā konta rokturis account_migration: @@ -174,7 +184,6 @@ lv: context: Filtrēt kontekstus current_password: Pašreizējā parole data: Dati - discoverable: Ieteikt kontu citiem display_name: Parādāmais vārds email: E-pasta adrese expires_in: Beidzas pēc @@ -184,7 +193,6 @@ lv: inbox_url: URL vai releja pastkaste irreversible: Nomest, nevis paslēpt locale: Saskarnes valoda - locked: Pieprasīt sekotāju pieprasījumus max_uses: Maksimālais lietojumu skaits new_password: Jauna parole note: Par sevi @@ -196,7 +204,6 @@ lv: setting_always_send_emails: Vienmēr sūtīt e-pasta paziņojumus setting_auto_play_gif: Automātiski atskaņot animētos GIF setting_boost_modal: Rādīt apstiprinājuma dialogu pirms izcelšanas - setting_crop_images: Apgrieziet attēlus neizvērstajās ziņās līdz 16x9 setting_default_language: Publicēšanas valoda setting_default_privacy: Publicēšanas privātums setting_default_sensitive: Atļaut atzīmēt multividi kā sensitīvu @@ -208,9 +215,7 @@ lv: setting_display_media_show_all: Parādīt visu setting_expand_spoilers: Vienmēr izvērst ziņas, kas apzīmētas ar brīdinājumiem par saturu setting_hide_network: Slēpt savu sociālo grafu - setting_noindex: Atteikties no meklētājprogrammu indeksēšanas setting_reduce_motion: Ierobežot kustību animācijās - setting_show_application: Atklāt lietojumprogrammu, ko izmanto ziņu nosūtīšanai setting_system_font_ui: Lietot sistēmas noklusējuma fontu setting_theme: Vietnes motīvs setting_trends: Parādīt šodienas tendences @@ -286,9 +291,18 @@ lv: pending_account: Jāpārskata jaunu kontu reblog: Kāds izcēla tavu ierakstu report: Tika iesniegts jauns ziņojums + software_updates: + all: Paziņot par visiem atjauninājumiem + critical: Paziņot tikai par kritiskajiem atjauninājumiem + label: Ir pieejama jauna Mastodon versija + none: Nekad neziņot par atjauninājumiem (nerekomendēts) + patch: Paziņot par novērsto kļūdu atjauninājumiem trending_tag: Jaunā tendence ir jāpārskata rule: text: Noteikumi + settings: + indexable: Ietvert profila lapu meklēšanas dzinējos + show_application: Parādi, no kuras lietotnes nosūtīji ziņu tag: listable: Atļaut šim tēmturim parādīties meklējumos un ieteikumos name: Tēmturis @@ -296,6 +310,7 @@ lv: usable: Atļaut lietot ziņās šo tēmturi user: role: Loma + time_zone: Laika josla user_role: color: Emblēmas krāsa highlighted: Atainot lomu kā emblēmu lietotāju profilos @@ -304,9 +319,11 @@ lv: position: Prioritāte webhook: events: Iespējotie notikumi + template: Noslodzes veidne url: Galapunkta URL 'no': Nē not_recommended: Nav ieteicams + overridden: Ignorēts recommended: Ieteicams required: mark: "*" diff --git a/config/locales/simple_form.ms.yml b/config/locales/simple_form.ms.yml index 57aff248b6..c0d47ace0a 100644 --- a/config/locales/simple_form.ms.yml +++ b/config/locales/simple_form.ms.yml @@ -2,6 +2,14 @@ ms: simple_form: hints: + account: + discoverable: Siaran awam dan profil anda mungkin dipaparkan atau disyorkan dalam pelbagai kawasan Mastodon dan profil anda mungkin dicadangkan kepada pengguna lain. + display_name: Nama penuh anda atau nama anda yang menyeronokkan. + fields: Halaman utama anda, kata ganti nama, umur, apa sahaja yang anda mahukan. + indexable: Pos awam anda mungkin muncul dalam hasil carian di Mastodon. Orang yang telah berinteraksi dengan pos anda mungkin boleh mencarinya tanpa mengira. + note: 'Anda boleh @menyebut orang lain atau #hashtags.' + show_collections: Orang akan dapat menyemak imbas mengikut dan pengikut anda. Orang yang anda ikuti akan melihat bahawa anda mengikuti mereka tanpa mengira. + unlocked: Orang akan dapat mengikuti anda tanpa meminta kelulusan. Nyahtanda jika anda ingin menyemak permintaan ikuti dan pilih sama ada untuk menerima atau menolak pengikut baharu. account_alias: acct: Tentukan namapengguna@domain akaun yang ingin anda alihkan daripada account_migration: @@ -18,6 +26,8 @@ ms: disable: Halang pengguna daripada menggunakan akaun mereka, tetapi jangan hapus atau sorokkan kandungan mereka. none: Gunakan ini untuk menghantar amaran kepada pengguna, tanpa mencetuskan sebarang tindakan lain. sensitive: Memaksa semua lampiran media pengguna ini ditandakan sebagai sensitif. + silence: Halang pengguna daripada dapat membuat siaran dengan keterlihatan awam, menyembunyikan siaran dan pemberitahuan mereka daripada orang yang tidak mengikutinya. Menutup semua laporan terhadap akaun ini. + suspend: Halang sebarang interaksi daripada atau ke akaun ini dan padamkan kandungannya. Boleh diterbalikkan dalam masa 30 hari. Menutup semua laporan terhadap akaun ini. warning_preset_id: Pilihan. Anda masih boleh menambah teks tersuai pada akhir praset announcement: all_day: Apabila diperiksa, hanya tarikh dalam julat masa yang akan dipaparkan @@ -30,20 +40,66 @@ ms: defaults: autofollow: Orang yang mendaftar melalui undangan akan mengikuti anda secara automatik avatar: PNG, GIF atau JPG. Kebanyakannya %{size}. Saiz akan dikecilkan kepada %{dimensions}px + bot: Memberi isyarat kepada orang lain bahawa akaun itu kebanyakannya melakukan tindakan automatik dan mungkin tidak dipantau + context: Satu atau berbilang konteks di mana penapis harus digunakan + current_password: Untuk tujuan keselamatan sila masukkan kata laluan akaun semasa + current_username: Untuk mengesahkan, sila masukkan nama pengguna akaun semasa + digest: Hanya dihantar selepas tempoh yang lama tidak aktif dan hanya jika anda telah menerima sebarang mesej peribadi semasa ketiadaan anda email: Anda akan dihantar e-mel pengesahan + header: PNG, GIF atau JPG. Paling banyak %{size}. Akan diturunkan skala kepada %{dimensions}px + inbox_url: Salin URL dari muka depan geganti yang anda mahu gunakan + irreversible: Siaran yang ditapis akan hilang secara tidak dapat dipulihkan, walaupun penapis dialih keluar kemudian locale: Bahasa untuk antara muka pengguna, e-mel dan pemberitahuan segera password: Gunakan sekurang-kurangnya 8 aksara + phrase: Akan dipadankan tanpa mengira sarung dalam teks atau amaran kandungan siaran + scopes: API mana yang akan dibenarkan untuk diakses oleh aplikasi. Jika anda memilih skop peringkat atasan, anda tidak perlu memilih skop individu. + setting_aggregate_reblogs: Jangan tunjukkan rangsangan baharu untuk siaran yang telah dirangsang baru-baru ini (hanya menjejaskan rangsangan yang baru diterima) setting_always_send_emails: Biasanya pemberitahuan e-mel tidak akan dihantar apabila anda selalu menggunakan Mastodon + setting_default_sensitive: Media sensitif disembunyikan secara lalai dan boleh didedahkan dengan satu klik setting_display_media_default: Sembunyikan media yang ditanda sebagai sensitif setting_display_media_hide_all: Sentiasa sembunyikan media setting_display_media_show_all: Sentiasa paparkan media - setting_hide_network: Sesiapa yang anda ikuti dan sesiapa yang mengikuti anda akan disembunyi daripada profil anda - setting_noindex: Menjejaskan profil awam dan laman hantaran anda + setting_use_blurhash: Kecerunan adalah berdasarkan warna visual tersembunyi tetapi mengelirukan sebarang butiran + setting_use_pending_items: Sembunyikan kemas kini garis masa di belakang satu klik dan bukannya menatal suapan secara automatik + username: Anda boleh menggunakan huruf, nombor dan garis bawah + whole_word: Apabila kata kunci atau frasa adalah alfanumerik sahaja, ia hanya akan digunakan jika ia sepadan dengan keseluruhan perkataan + domain_allow: + domain: Domain ini akan dapat mengambil data daripada server ini dan data masuk daripadanya akan diproses dan disimpan + email_domain_block: + domain: Ini boleh menjadi nama domain yang dipaparkan dalam alamat e-mel atau rekod MX yang digunakannya. Mereka akan diperiksa semasa mendaftar. + with_dns_records: Percubaan untuk menyelesaikan rekod DNS domain yang diberikan akan dibuat dan hasilnya juga akan disekat + 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 + backups_retention_period: Simpan arkib pengguna yang dijana untuk bilangan hari yang ditentukan. + bootstrap_timeline_accounts: Akaun ini akan disematkan pada bahagian atas cadangan ikutan pengguna baharu. closed_registrations_message: Dipaparkan semasa pendaftaran ditutup + content_cache_retention_period: Semua pos dan rangsangan daripada server lain akan dipadamkan selepas bilangan hari yang ditentukan. Sesetengah siaran mungkin tidak boleh dipulihkan. Semua penanda halaman, kegemaran dan rangsangan yang berkaitan juga akan hilang dan mustahil untuk dibuat asal. + custom_css: Anda boleh menggunakan gaya tersuai pada versi web Mastodon. + mascot: Mengatasi ilustrasi dalam antara muka web lanjutan. + media_cache_retention_period: Fail media yang dimuat turun akan dipadamkan selepas bilangan hari yang ditetapkan apabila ditetapkan kepada nilai positif dan dimuat turun semula atas permintaan. + peers_api_enabled: Senarai nama domain yang pernah ditemui oleh server ini dalam fediverse. Tiada data disertakan di sini tentang sama ada anda bersekutu dengan server tertentu, cuma server anda mengetahuinya. Ini digunakan oleh perkhidmatan yang mengumpul statistik mengenai persekutuan dalam pengertian umum. + profile_directory: Direktori profil menyenaraikan semua pengguna yang telah mengikut serta untuk ditemui. + require_invite_text: Apabila pendaftaran memerlukan kelulusan manual, buat "Mengapa anda mahu menyertai?" input teks wajib dan bukannya pilihan + site_contact_email: Cara orang boleh menghubungi anda untuk pertanyaan undang-undang atau sokongan. site_contact_username: Bagaimana orang boleh menghubungi anda pada Mastodon. site_extended_description: Apa-apa maklumat tambahan yang mungkin berguna untuk pelawat dan pengguna anda. Boleh distruktur dengan sintaks Markdown. + site_short_description: Penerangan ringkas untuk membantu mengenal pasti server anda. Siapa yang menjalankannya, untuk siapa? site_terms: Gunakan dasar polisi anda atau biarkan kosong untuk menggunakan lalai. Boleh distruktur dengan sintaks Markdown. + site_title: Bagaimana orang boleh merujuk kepada server anda selain nama domainnya. + status_page_url: URL halaman yang membolehkan orang ramai melihat status server ini semasa gangguan + theme: Tema yang pelawat log keluar dan pengguna baharu lihat. + thumbnail: Imej kira-kira 2:1 dipaparkan bersama maklumat server anda. + timeline_preview: Pelawat yang log keluar akan dapat menyemak imbas siaran awam terkini yang tersedia pada server. + trendable_by_default: Langkau semakan manual kandungan sohor kini. Item individu masih boleh dialih keluar daripada trend selepas fakta itu. + trends: Aliran menunjukkan pos, hashtag dan cerita berita yang mendapat tarikan pada server anda. + trends_as_landing_page: Tunjukkan kandungan trend kepada pengguna dan pelawat yang log keluar dan bukannya penerangan tentang server ini. Memerlukan trend untuk didayakan. form_challenge: current_password: Anda sedang memasuki kawasan selamat imports: @@ -51,34 +107,76 @@ ms: invite_request: text: Ini akan membantu kami menyemak permohonan anda ip_block: + comment: Pilihan. Ingat sebab anda menambahkan peraturan ini. + expires_in: Alamat IP adalah sumber terhingga, kadangkala dikongsi dan sering bertukar tangan. Atas sebab ini, blok IP tidak ditentukan tidak disyorkan. + ip: Masukkan alamat IPv4 atau IPv6. Anda boleh menyekat keseluruhan julat menggunakan sintaks CIDR. Berhati-hati untuk tidak mengunci diri anda! severities: no_access: Menyekat akses kepada semua sumber sign_up_block: Pendaftaran baru tidak akan dibenarkan sign_up_requires_approval: Pendaftaran baru akan memerlukan kelulusan anda + severity: Pilih perkara yang akan berlaku dengan permintaan daripada IP ini + rule: + text: Terangkan peraturan atau keperluan untuk pengguna pada server ini. Cuba pastikan ia pendek dan ringkas + sessions: + otp: 'Masukkan kod dua faktor yang dijana oleh apl telefon anda atau gunakan salah satu kod pemulihan anda:' + webauthn: Jika ia adalah kunci USB, pastikan anda memasukkannya dan, jika perlu, ketiknya. + settings: + indexable: Halaman profil anda mungkin muncul dalam hasil carian di Google, Bing dan lain-lain. + show_application: Anda akan sentiasa dapat melihat apl yang menerbitkan siaran anda tanpa mengira. + tag: + name: Anda hanya boleh menukar selongsong huruf, sebagai contoh, untuk menjadikannya lebih mudah dibaca + user: + chosen_languages: Apabila disemak, hanya siaran dalam bahasa terpilih akan dipaparkan dalam garis masa awam + role: Peranan mengawal kebenaran yang dimiliki oleh pengguna user_role: color: Warna yang akan digunakan untuk peranan ini dalam seluruh UI, sebagai RGB dalam format hex highlighted: Ini menjadikan peranan ini dipaparkan secara umum + name: Nama awam peranan, jika peranan ditetapkan untuk dipaparkan sebagai lencana permissions_as_keys: Pengguna dengan peranan ini akan mempunyai akses kepada... + position: Peranan yang lebih tinggi menentukan penyelesaian konflik dalam situasi tertentu. Tindakan tertentu hanya boleh dilakukan pada peranan dengan keutamaan yang lebih rendah + webhook: + events: Pilih acara untuk dihantar + template: Karang muatan JSON anda sendiri menggunakan interpolasi berubah-ubah. Biarkan kosong untuk JSON lalai. + url: Di mana acara akan dihantar labels: account: + discoverable: Ciri profil dan siaran dalam algoritma penemuan fields: + name: Label value: Kandungan + indexable: Sertakan pos awam dalam hasil carian + show_collections: Tunjukkan ikutan dan pengikut pada profil + unlocked: Terima pengikut baharu secara automatik + account_alias: + acct: Pemegang akaun lama + account_migration: + acct: Pengendali akaun baharu account_warning_preset: + text: Teks pratetap title: Tajuk admin_account_action: + include_statuses: Sertakan siaran yang dilaporkan dalam e-mel + send_email_notification: Beritahu pengguna setiap e-mel text: Amaran tersuai type: Tindakan types: + disable: Bekukan none: Hantar amaran sensitive: Sensitif silence: Hadkan suspend: Gantung warning_preset_id: Gunakan amaran yang ditetapkan announcement: + all_day: Acara sepanjang hari + ends_at: Tamat acara + scheduled_at: Jadual penerbitan + starts_at: Permulaan acara text: Pengumuman appeal: text: Jelaskan mengapa keputusan ini patut diterbalikkan defaults: + autofollow: Jemput mengikuti akaun anda + avatar: Gambar profil bot: Ini ialah akaun bot chosen_languages: Tapis bahasa confirm_new_password: Sahkan kata laluan baru @@ -86,33 +184,53 @@ ms: context: Konteks penapis current_password: Kata laluan semasa data: Data - discoverable: Mencadangkan akaun kepada pengguna lain display_name: Nama paparan email: Alamat e-mel expires_in: Tamat tempoh selepas fields: Metadata profil + header: Gambar Tajuk + honeypot: "%{label} (jangan isi)" + inbox_url: URL peti masuk geganti + irreversible: Sebaliknya sembunyikan, jatuhkan locale: Bahasa antara muka + max_uses: Bilangan maksimum penggunaan new_password: Kata laluan baru + note: Bio otp_attempt: Kod dua faktor password: Kata laluan phrase: Kata kunci atau frasa setting_advanced_layout: Dayakan antara muka web lanjutan + setting_aggregate_reblogs: Rangsangan kumpulan dalam garis masa + setting_always_send_emails: Sentiasa hantar pemberitahuan e-mel + setting_auto_play_gif: Automain GIF animasi + setting_boost_modal: Tunjukkan dialog pengesahan sebelum meningkatkan setting_default_language: Bahasa hantaran setting_default_privacy: Privasi hantaran setting_default_sensitive: Selalu tandakan media sebagai sensitif + setting_delete_modal: Tunjukkan dialog pengesahan sebelum memadamkan pos + setting_disable_swiping: Lumpuhkan gerakan meleret setting_display_media: Paparan media setting_display_media_default: Lalai setting_display_media_hide_all: Sembunyikan semua setting_display_media_show_all: Paparkan semua + setting_expand_spoilers: Sentiasa kembangkan pos yang ditandakan dengan amaran kandungan + setting_hide_network: Sembunyikan graf sosial anda + setting_reduce_motion: Kurangkan gerakan dalam animasi setting_system_font_ui: Gunakan fon lalai sistem setting_theme: Tema halaman setting_trends: Paparkan trend hari ini + setting_unfollow_modal: Tunjukkan dialog pengesahan sebelum berhenti mengikuti seseorang + setting_use_blurhash: Tunjukkan kecerunan berwarna-warni untuk media tersembunyi + setting_use_pending_items: Mod perlahan + severity: Keterukan sign_in_token_attempt: Kod keselamatan title: Tajuk type: Jenis import username: Nama pengguna username_or_email: Nama Pengguna atau E-mel whole_word: Seluruh perkataan + email_domain_block: + with_dns_records: Sertakan rekod MX dan IP domain featured_tag: name: Tanda pagar filters: @@ -120,7 +238,15 @@ ms: hide: Sembunyikan sepenuhnya warn: Sembunyikan dengan amaran form_admin_settings: + activity_api_enabled: Terbitkan statistik agregat tentang aktiviti pengguna dalam API + backups_retention_period: Tempoh pengekalan arkib pengguna + bootstrap_timeline_accounts: Sentiasa mengesyorkan akaun ini kepada pengguna baharu + closed_registrations_message: Mesej tersuai apabila pendaftaran tidak tersedia + content_cache_retention_period: Tempoh pengekalan cache kandungan custom_css: CSS tersuai + mascot: Maskot tersuai (warisan) + media_cache_retention_period: Tempoh pengekalan cache media + peers_api_enabled: Terbitkan senarai pelayan yang ditemui dalam API profile_directory: Dayakan direktori profil registrations_mode: Siapa boleh mendaftar require_invite_text: Memerlukan sebab penyertaan @@ -132,8 +258,17 @@ ms: site_short_description: Penerangan pelayan site_terms: Dasar Privasi site_title: Nama pelayan + status_page_url: URL halaman status theme: Tema asal + thumbnail: Server thumbnail + timeline_preview: Benarkan akses tidak disahkan kepada garis masa awam + trendable_by_default: Benarkan aliran tanpa semakan terlebih dahulu trends: Dayakan trend + trends_as_landing_page: Gunakan trend sebagai halaman pendaratan + interactions: + must_be_follower: Sekat pemberitahuan daripada bukan pengikut + must_be_following: Sekat pemberitahuan daripada orang yang anda tidak ikuti + must_be_following_dm: Sekat mesej langsung daripada orang yang anda tidak ikuti invite: comment: Komen invite_request: @@ -147,6 +282,8 @@ ms: sign_up_requires_approval: Hadkan pendaftaran severity: Peraturan notification_emails: + appeal: Seseorang merayu keputusan moderator + digest: Hantar e-mel ringkasan favourite: Seorang menggemarkan hantaran anda follow: Seorang mengikuti anda follow_request: Seorang meminta untuk mengikuti anda @@ -157,19 +294,34 @@ ms: trending_tag: Trend baru memerlukan semakan rule: text: Peraturan + settings: + indexable: Sertakan halaman profil dalam enjin carian + show_application: Paparkan daripada apl yang anda hantar siaran tag: + listable: Benarkan hashtag ini muncul dalam carian dan cadangan name: Tanda pagar + trendable: Benarkan hashtag ini muncul di bawah aliran usable: Benarkan siaran untuk menggunakan tanda pagar ini user: role: Peranan + time_zone: Zon masa user_role: color: Warna lencana + highlighted: Paparkan peranan sebagai lencana pada profil pengguna name: Nama permissions_as_keys: Kebenaran position: Keutamaan + webhook: + events: Acara yang didayakan + template: Templat muatan + url: URL titik akhir 'no': Tidak not_recommended: Tidak disyorkan recommended: Disyorkan required: + mark: "*" text: diperlukan + title: + sessions: + webauthn: Gunakan salah satu kunci keselamatan anda untuk log masuk 'yes': Ya diff --git a/config/locales/simple_form.my.yml b/config/locales/simple_form.my.yml index 5e1fc6bee9..80b234c17c 100644 --- a/config/locales/simple_form.my.yml +++ b/config/locales/simple_form.my.yml @@ -1 +1,334 @@ +--- my: + simple_form: + hints: + account: + discoverable: သင်၏ အများမြင် ပို့စ်များနှင့် ပရိုဖိုင်များကို Mastodon ၏ နယ်ပယ်အသီးသီးတွင် ဖော်ပြခြင်း သို့မဟုတ် အကြံပြုနိုင်ပြီး သင့်ပရိုဖိုင်ကို အခြားအသုံးပြုသူများအား အကြံပြုနိုင်ပါသည်။ + display_name: သင့်အမည်အပြည့်အစုံ သို့မဟုတ် သင့်အမည်ပြောင်။ + fields: သင့် ပင်မစာမျက်နှာ၊ နာမ်စား၊ အသက်၊ သင်လိုချင်သည့်အရာ။ + indexable: သင်၏ အများမြင်ပို့စ်များသည် Mastodon ရှိ ရှာဖွေမှုရလဒ်များတွင် ပေါ်လာနိုင်သည်။ သင့်ပို့စ်များမှတစ်ဆင့် အပြန်အလှန်တုံ့ပြန်ပြီး ရှာဖွေနိုင်ပါမည်။ + note: 'သင်သည် အခြားသူများ သို့မဟုတ် #hashtag များကို @mention ဖြင့် ဖော်ပြနိုင်သည်။' + show_collections: သင်စောင့်ကြည့်သူများနှင့် သင့်ကိုစောင့်ကြည့်သူများမှတစ်ဆင့် ရှာဖွေနိုင်မည်ဖြစ်သည်။ သင်စောင့်ကြည့်သူများသည် သင်သူတို့ကို မည်သို့စောင့်ကြည့်သည်ကို တွေ့ရလိမ့်မည်။ + unlocked: ခွင့်ပြုချက်မတောင်းဘဲ လူများက သင့်ကိုစောင့်ကြည့်နိုင်ပါမည်။ စောင့်ကြည့်ရန်အတွက် တောင်းဆိုချက်များထားရှိလိုပါက အမှန်ခြစ်ဖြုတ်ပြီး စောင့်ကြည့်သူသစ်များကို လက်ခံခြင်း သို့မဟုတ် ငြင်းပယ်ခြင်းလည်း အမှန်ခြစ်ဖြုတ်နိုင်ပါသည်။ + account_alias: + acct: ပြောင်းရွှေ့မည့်အကောင့်မှ username@domain ကို သတ်မှတ်ပါ + account_migration: + acct: ပြောင်းရွှေ့လိုသောအကောင့်၏ username@domain ကို သတ်မှတ်ပါ + account_warning_preset: + text: URLs၊ hashtags နှင့် mentions များကဲ့သို့ ပို့စ်ကို သုံးနိုင်သည် + title: လက်ခံသူမှ မြင်နိုင်၊ မမြင်နိုင် ရွေးချယ်ခွင့် + admin_account_action: + include_statuses: အသုံးပြုသူသည် မည်သည့်ပို့စ်များမှာ စိစစ်ထားခြင်း သို့မဟုတ် သတိပေးထားခြင်းဖြစ်စေသည်ကို တွေ့မြင်နိုင်ပါသည် + send_email_notification: အသုံးပြုသူသည် ၎င်းတို့၏အကောင့်နှင့် ဖြစ်ပျက်ခဲ့သော ရှင်းလင်းချက်ကို လက်ခံရရှိမည်ဖြစ်သည် + text_html: Post Syntax ကို သုံးနိုင်သည်။ အချိန်ကုန်သက်သာစေရန်အတွက် ကြိုတင်သတိပေးချက်များ ထည့်နိုင်သည် + type_html: "%{acct} နှင့် ဘာလုပ်ရမည်ကို ရွေးပါ။" + types: + disable: အသုံးပြုသူကို ၄င်း၏အကောင့်အား သုံးစွဲခြင်းမှ ဟန့်တားပါ။ သို့သော် ၄င်းဖန်တီးထားသည့် အချက်အလက်များကို မဖျက်ပါ။ မဖျောက်ပါ။ + none: အခြားလုပ်ဆောင်ချက်တစ်ခုမှ မလုပ်ဘဲ အသုံးပြုသူထံ သတိပေးချက်ပေးပို့ရန် ၎င်းကို အသုံးပြုပါ။ + sensitive: ဤအသုံးပြုသူ၏ မီဒီယာပူးတွဲပါဖိုင်များအားလုံးကို သတိထားရသောမီဒီယာအဖြစ် သတ်မှတ်ရန် တိုက်တွန်းပါ။ + silence: စောင့်ကြည့်မထားသူများ၏ ပို့စ်များနှင့် အသိပေးချက်များကို ဖျောက်ထားနိုင်ပြီး အသုံးပြုသူအား အများမြင်မည့်ပို့စ် တင်ခြင်းကို တားမြစ်နိုင်သည်။ ဤအကောင့်နှင့်ပတ်သက်သည့် အစီရင်ခံစာအားလုံးကို ပိတ်ထားနိုင်သည်။ + suspend: ဤအကောင့်မှ သို့မဟုတ် ဤအကောင့်နှင့် အပြန်အလှန်တုံ့ပြန်မှုကို တားဆီးပြီး အကြောင်းအရာများကို ဖျက်ပါ။ ရက်ပေါင်း ၃၀ အတွင်း ပြန်ပြောင်းနိုင်သည်။ ဤအကောင့်နှင့်ပတ်သက်သည့် အစီရင်ခံစာအားလုံးကို ပိတ်ရန်။ + warning_preset_id: ကြိုတင်သတ်မှတ်မှုအဆုံးတွင် စိတ်ကြိုက်စာသားကို ထည့်နိုင်သည် + announcement: + all_day: အချိန်အပိုင်းအခြား ရက်စွဲများကိုသာ ပြသပါမည် + ends_at: ကြေညာချက်ထုတ်ပြန်ခြင်းကို ဤအချိန်တွင် အလိုအလျောက် ရပ်တန့်လိုက်ပါမည် + scheduled_at: ကြေညာချက်ချက်ချင်းထုတ်ပြန်ရန်အတွက် နေရာလွတ်ချန်ထားပါ + starts_at: သင့်ကြေညာချက်သည် အချိန်အပိုင်းအခြားတစ်ခုနှင့် ဆက်စပ်နိုင်ပါသည် + text: Post Syntax ကို သုံးနိုင်သည်။ အသုံးပြုသူ၏ဖန်သားပြင်တွင် ပေါ်လာမည့် ကြေညာချက်နေရာကို သတိထားပါ + appeal: + text: လုပ်ဆောင်ချက်တစ်ကြိမ်သာ အသုံးပြုနိုင်သည် + defaults: + autofollow: ဖိတ်ကြားချက်မှတစ်ဆင့် အကောင့်ဖွင့်သူများမှာ သင့်ကို အလိုအလျောက်စောင့်ကြည့်မည်ဖြစ်ပါသည် + avatar: PNG၊ GIF သို့မဟုတ် JPG။ အများဆုံး %{size}။ %{dimensions}px သို့ လျှော့ချပါမည်။ + bot: အကောင့်သည် အဓိကအားဖြင့် အလိုအလျောက် လုပ်ဆောင်ချက်များ ဆောင်ရွက်နိုင်ပြီး စောင့်ကြည့်ခြင်းမပြုနိုင်ကြောင်း အခြားသူများအား အသိပေးပါ + context: စစ်ထုတ်သင့်သည့် အကြောင်းအရာ တစ်ခု သို့မဟုတ် များစွာ + current_password: လုံခြုံရေးအတွက် ကျေးဇူးပြုပြီး လက်ရှိအကောင့်၏ စကားဝှက်ကို ထည့်ပါ + current_username: အတည်ပြုရန်အတွက် လက်ရှိအကောင့်၏ အသုံးပြုသူအမည်ကို ရိုက်ထည့်ပါ + digest: အချိန်အတော်ကြာ အသုံးမပြုသည့်သည့်နောက်တွင်သာ ပေးပို့ပြီး အသုံးမပြုသည့်ကာလအတွင်း ကိုယ်ရေးကိုယ်တာစာများသာ လက်ခံရန် + email: သင့်ထံ အတည်ပြုချက်အီးမေးလ်တစ်စောင် ပေးပို့ပါမည် + header: PNG၊ GIF သို့မဟုတ် JPG။ အများဆုံး %{size}။ %{dimensions}px သို့ လျှော့ချပါမည် + inbox_url: သင်အသုံးပြုလိုသော relay ၏ ရှေ့စာမျက်နှာမှ URL ကို ကူးယူပါ + irreversible: စစ်ထုတ်ခြင်းကိုဖယ်ရှားလိုက်ပါက စစ်ထုတ်ထားသော ပို့စ်များမှာ ပျောက်ကွယ်သွားပါမည် + locale: အသုံးပြုသူမှ လက်ရှိသုံးနေသည့်ဘာသာစကား၊ အီးမေးလ်များနှင့် ရရှိစေရန်ပေးပို့သည့် အသိပေးချက်များ + password: အနည်းဆုံး စာလုံး ၈ လုံး အသုံးပြုပါ။ + phrase: ပို့စ်တစ်ခု၏ စာသား သို့မဟုတ် အကြောင်းအရာသတိပေးချက်တွင် စာသားသတ်မှတ်ထားမှုမရှိဘဲ ကိုက်ညီရပါမည် + scopes: API အက်ပလီကေးရှင်းများကို ဝင်ရောက်ကြည့်ရှုခွင့်ပြုပါမည်။ ထိပ်တန်းအဆင့်နယ်ပယ်ကို ရွေးချယ်ထားပါက တစ်ခုချင်းစီရွေးချယ်ရန် မလိုအပ်တော့ပါ။ + setting_aggregate_reblogs: မကြာသေးခင်က Boost လုပ်ထားသောပို့စ်များအတွက် Boost အသစ်များကို မပြပါနှင့် (အသစ်ရရှိထားသော Boost များကိုသာ ပြသပါရန်) + setting_always_send_emails: Mastodon ကို လက်ရှိအသုံးပြုနေချိန်တွင် ပုံမှန်အားဖြင့် အီးမေးလ်အသိပေးချက်များကို ပေးပို့မည်မဟုတ်ပါ + setting_default_sensitive: သတိထားရသောမီဒီယာကို မူလအားဖြင့် ဖျောက်ထားနိုင်ပြီး ကလစ်တစ်ချက်နှိပ်ရုံဖြင့် ပြန်လည်ဖော်ပြနိုင်သည် + setting_display_media_default: သတိထားရသောမီဒီယာအဖြစ် သတ်မှတ်ထားမှုအား ဖျောက်ပါ + setting_display_media_hide_all: မီဒီယာကို အမြဲတမ်းဖျောက်ထားပါ + setting_display_media_show_all: မီဒီယာကို အမြဲတမ်းပြပါ + setting_use_blurhash: Gradients မှာ ဖျောက်ထားသောရုပ်ပုံများ၏ အရောင်များကိုအခြေခံသော်လည်း မည်သည့်အသေးစိတ်အချက်အလက်ကိုမဆို ရှုပ်ထွေးစေနိုင်ပါသည်။ + setting_use_pending_items: အပေါ်အောက်လှိမ့်မည့်အစား ကလစ်တစ်ခုနောက်တွင် စာမျက်နှာအပ်ဒိတ်များကို ဖျောက်ထားပါ။ + username: အက္ခရာများ၊ နံပါတ်များနှင့် underscore များကို အသုံးပြုနိုင်သည် + whole_word: အဓိကစကားလုံး သို့မဟုတ် စကားစုသည် အက္ခရာဂဏန်းများသာဖြစ်ပါကစကားလုံးတစ်ခုလုံးနှင့် ကိုက်ညီမှသာ အသုံးပြုနိုင်မည်ဖြစ်သည် + domain_allow: + domain: ဤဒိုမိန်းသည် ဤဆာဗာမှ အချက်အလက်များကို ရယူနိုင်မည်ဖြစ်ပြီး ဝင်လာသောအချက်အလက်များကို စီမံဆောင်ရွက်ပေးပြီး သိမ်းဆည်းသွားမည်ဖြစ်သည် + email_domain_block: + domain: "၎င်းမှာ အီးမေးလ်လိပ်စာ သို့မဟုတ် အသုံးပြုသည့် MX မှတ်တမ်းတွင် ပေါ်လာသည့် ဒိုမိန်းအမည် ဖြစ်နိုင်သည်။ အကောင့်ဖွင့်ပြီးပါက စစ်ဆေးနိုင်မည်ဖြစ်သည်။" + with_dns_records: ပေးထားသော ဒိုမိန်း၏ DNS မှတ်တမ်းများကို ဖြေရှင်းရန် ကြိုးပမ်းမှု ပြုလုပ်မည်ဖြစ်ပြီး ရလဒ်များကိုလည်း ပိတ်ဆို့သွားမည်ဖြစ်သည်။ + featured_tag: + name: ဤသည်မှာ သင်မကြာသေးမီက အသုံးပြုခဲ့သော hashtag အချို့ဖြစ်သည် - + 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 ဝဘ်ဗားရှင်းတွင် စိတ်ကြိုက်စတိုင်များကို အသုံးပြုနိုင်ပါသည်။ + mascot: အဆင့်မြင့် ဝဘ်ပုံစံတွင်တွင် ရုပ်ပုံဖြင့်ဖော်ပြထားသည်။ + media_cache_retention_period: သတ်မှတ်ထားသောရက်များပြီးနောက် ဒေါင်းလုဒ်လုပ်ထားသော မီဒီယာဖိုင်များကို ဖျက်လိုက်ပါမည်။ တောင်းဆိုပါက ပြန်လည်ဒေါင်းလုဒ် လုပ်ခွင့်ရှိသည်။ + peers_api_enabled: ဤဆာဗာမှတွေ့ရသော ဖက်ဒီနယ်ပယ်ပေါင်းစုံရှိ ဒိုမိန်းအမည်များစာရင်း။ ဖက်ဒီနယ်ပယ်များမှာ သင်အသုံးပြုနေသည့်ဆာဗာနှင့် ပေါင်းစပ်ခြင်းရှိသည်ဖြစ်စေ၊ မရှိသည်ဖြစ်စေ ဤနေရာတွင် အချက်အလက်များကို မပြသထားပါ။ ယေဘုယျအားဖြင့် ဖက်ဒရယ်ဆိုင်ရာ စာရင်းအင်းများစုဆောင်းသည့် ဝန်ဆောင်မှုကိုသာ အသုံးပြုထားသည်။ + profile_directory: ပရိုဖိုင်လမ်းညွှန်တွင် ရှာဖွေ‌နိုင်သည့်အသုံးပြုသူအားလုံးကို စာရင်းပြုစုထားသည်။ + require_invite_text: အကောင့်ဖွင့်ရာတွင် လူကိုယ်တိုင်ခွင့်ပြုချက်လိုအပ်သောအခါ “ဘာကြောင့်ပါဝင်ချင်သလဲ” ဟုလုပ်ပါ။ စိတ်ကြိုက်ရွေးချယ်မည့်အစား စာသားထည့်သွင်းရန်မဖြစ်မနေထည့်သွင်းပါ။ + site_contact_email: ဥပဒေရေးရာ သို့မဟုတ် အကူအညီ စုံစမ်းမေးမြန်းရန် လူများက သင့်ထံ မည်သို့ဆက်သွယ်နိုင်မည်နည်း။ + site_contact_username: Mastodon တွင် အခြားသူများက သင့်ကို မည်သို့သိရှိနိုင်မည်နည်း။ + site_extended_description: ဝင်ရောက်ကြည့်ရှုသူများနှင့် အသုံးပြုသူများအတွက် အသုံးဝင်မည့် နောက်ထပ်အချက်အလက်များကို Markdown စာကြောင်းများဖြင့် ရေးသားနိုင်သည်။ + site_short_description: သင်၏ဆာဗာအား သိသားထင်ရှားစွာ အမှတ်အသားပြုနိုင်မည့် အကျဉ်းရုံးဖော်ပြချက်။ မည်သူမှ ဆာဗာအား ထိန်းကြောင်းလည်ပတ်နေသည်၊ မည်သူ့အတွက် ဖြစ်သည်? + site_terms: သင့်ကိုယ်ပိုင် ကိုယ်ရေးအချက်အလက်မူဝါဒကို အသုံးပြုပါ သို့မဟုတ် မူလသတ်မှတ်ချက်ကို အသုံးပြုရန်အတွက် ကွက်လပ်ထားပါ။ Markdown စာများဖြင့် ရေးသားနိုင်သည်။ + site_title: ဒိုမိန်းအမည်မှတပါး သင့်ဆာဗာကို လူများက မည်သို့သိရှိနိုင်မည်နည်း။ + status_page_url: ပြတ်တောက်နေစဉ်အတွင်း လူများက ဤဆာဗာအခြေအနေကို မြင်နိုင်မည့် စာမျက်နှာ URL + theme: အကောင့်မှထွက်ပြီး အသုံးပြုသူအသစ်များနှင့် ဝင်ကြည့်မည့်သူများအတွက် မြင်ရမည့်ပုံစံ။ + thumbnail: သင့်ဆာဗာအချက်အလက်နှင့်အတူ အကြမ်းဖျင်းအားဖြင့် ၂:၁ ဖြင့် ပြသထားသောပုံတစ်ပုံ။ + timeline_preview: အကောင့်မှထွက်ထားသူများသည် ဆာဗာပေါ်ရှိ လတ်တလော အများမြင်ပို့စ်များကို ရှာဖွေကြည့်ရှုနိုင်မည်ဖြစ်သည်။ + trendable_by_default: ခေတ်စားနေသော အကြောင်းအရာများ၏ ကိုယ်တိုင်သုံးသပ်ချက်ကို ကျော်ပါ။ နောက်ပိုင်းတွင် အချက်အလက်တစ်ခုချင်းစီကို ခေတ်စားနေသောအကြောင်းအရာများကဏ္ဍမှ ဖယ်ရှားနိုင်ပါသေးသည်။ + trends: လက်ရှိခေတ်စားနေသာပို့စ်များ၊ hashtag များနှင့် သတင်းဇာတ်လမ်းများကို သင့်ဆာဗာပေါ်တွင် တွေ့မြင်နိုင်ပါမည်။ + trends_as_landing_page: ဤဆာဗာဖော်ပြချက်အစား အကောင့်မှ ထွက်ထားသူများနှင့် ဝင်ရောက်ကြည့်ရှုသူများအတွက် ခေတ်စားနေသော အကြောင်းအရာများကို ပြသပါ။ ခေတ်စားနေသောပို့စ်များကို ဖွင့်ထားရန် လိုအပ်သည်။ + form_challenge: + current_password: သင်သည် လုံခြုံသောနေရာသို့ ဝင်ရောက်နေပါသည် + imports: + data: အခြား Mastodon ဆာဗာမှ CSV ဖိုင်ကို ပို့ထားသည် + invite_request: + text: "၎င်းသည် သင့်အက်ပလီကေးရှင်းကို ပြန်လည်သုံးသပ်ရန်အတွက် ကူညီပေးနိုင်ပါသည်" + ip_block: + comment: ဤစည်းမျဉ်း ဘာကြောင့်ထည့်ခဲ့သည်အား သတိရရန်။ + expires_in: အိုင်ပီလိပ်စာများမှာ အကန့်အသတ်ရှိသည့် အရင်းအမြစ်ဖြစ်သည်။ တခါတရံ လိပ်စာများအား မျှဝေသုံးစွဲကြသည်။ အခါအားလျှော်စွာ လက်လွှဲသုံးစွဲမှုများလည်း ရှီတတ်သည်။ ထို့အတွက်ကြောင့် အကန့်အသတ်မဲ့ အိုင်ပီကန့်သတ်ထိန်းချုပ်မှု လုပ်ဆောင်ခြင်းကို အားမပေးပါ။ + ip: IPv4 သို့မဟုတ် IPv6 လိပ်စာကို ထည့်ပါ။ CIDR syntax ကို အသုံးပြု၍ အတိုင်းအတာတစ်ခုလုံးကို ပိတ်ဆို့နိုင်သည်။ ကိုယ်တိုင် လော့ခ်မချမိစေရန် သတိထားပါ။ + severities: + no_access: အရင်းအမြစ်များအားလုံးသို့ ဝင်ရောက်ခွင့်ကို ပိတ်ပါ + sign_up_block: အကောင့်အသစ်များ မဖွင့်နိုင်တော့ပါ + sign_up_requires_approval: အကောင့်အသစ်များသည် သင့်ခွင့်ပြုချက်လိုအပ်ပါသည် + severity: ဤ IP မှ တောင်းဆိုမှုများဖြင့် ဖြစ်ပေါ်လာမည့်အရာ ရွေးချယ်ပါ + rule: + text: ဤဆာဗာအသုံးပြုသူများအတွက် စည်းမျဉ်း သို့မဟုတ် လိုအပ်ချက် ဖော်ပြပါ။ လိုရင်းတိုရှင်းဖြစ်ပါစေ။ + sessions: + otp: သင့်ဖုန်းအက်ပ်မှထုတ်ပေးသောနှစ်ဆင့်ခံလုံခြုံရေးကုဒ်ကို ထည့်ပါ သို့မဟုတ် ပြန်လည်ရယူရေးကုဒ်များထဲမှ တစ်ခုကို အသုံးပြုပါ - + webauthn: USB ကီးဖြစ်ပါက ထည့်သွင်းပါ။ လိုအပ်ပါက နှိပ်ပါ။ + settings: + indexable: သင့်ပရိုဖိုင်စာမျက်နှာသည် Google၊ Bing နှင့် အခြားရှိ ရှာဖွေမှုရလဒ်များတွင် ပေါ်လာနိုင်သည်။ + show_application: မည်သည့်အက်ပ်က သင့်ပို့စ်ကို တင်ထားကြောင်း သင်အမြဲမြင်နိုင်မည်ဖြစ်သည်။ + tag: + name: ဥပမာအားဖြင့် စာလုံးများကို ပိုမိုဖတ်ရှုနိုင်စေရန်မှာ သင်သာ ပြောင်းလဲနိုင်သည်။ + user: + chosen_languages: အမှန်ခြစ် ရွေးချယ်ထားသော ဘာသာစကားများဖြင့်သာ ပို့စ်များကို အများမြင်စာမျက်နှာတွင် ပြသပါမည် + role: အသုံးပြုသူ၏ ခွင့်ပြုချက်ကဏ္ဍကို ထိန်းချုပ်ထားသည် + user_role: + color: hex ပုံစံ RGB အဖြစ် UI တစ်လျှောက်လုံး အခန်းကဏ္ဍအတွက် အသုံးပြုရမည့်အရောင် + highlighted: ယင်းက အခန်းကဏ္ဍကို အများမြင်အောင် ဖွင့်ပေးထားသည်။ + name: အကယ်၍ အခန်းကဏ္ဍကို သင်္ကေတတစ်ခုအဖြစ်ပြသရန် သတ်မှတ်ထားပါက အခန်းကဏ္ဍကို အများမြင်မည့်အမည် + permissions_as_keys: ဤအခန်းကဏ္ဍဖြင့် အသုံးပြုသူများသာ အသုံးပြုခွင့်ရှိပါမည်... + position: အခန်းကဏ္ဍအဆင့်မြင့်သူအနေဖြင့် အချို့သောအခြေအနေများတွင် ပဋိပက္ခများကို ဖြေရှင်းနိုင်သည်။ အချို့လုပ်ဆောင်ချက်များမှာ အဆင့်နိမ့်အခန်းကဏ္ဍများတွင်သာ လုပ်ဆောင်နိုင်သည်။ + webhook: + events: ပို့မည့်အကြောင်းအရာများကို ရွေးချယ်ပါ + template: variable interpolation ကိုအသုံးပြု၍ ကိုယ်ပိုင် JSON payload ရေးပါ။ မူရင်း JSON အတွက် နေရာလွတ်ချန်ထားပါ။ + url: အကြောင်းအရာများကို ဘယ်ကို ပို့မလဲ။ + labels: + account: + discoverable: ရှာဖွေမှု အယ်လ်ဂိုရီသမ်များတွင် ဖော်ပြပါ ပရိုဖိုင်နှင့် ပို့စ်များ + fields: + name: အညွှန်း + value: အကြောင်းအရာ + indexable: ရှာဖွေမှုရလဒ်များတွင် အများမြင်ပို့စ်များ ထည့်သွင်းပါ + show_collections: ပရိုဖိုင်တွင် စောင့်ကြည့်မှုများနှင့် စောင့်ကြည့်သူများကို ပြပါ + unlocked: စောင့်ကြည့်သူအသစ်များကို အလိုအလျောက် လက်ခံပါ + account_alias: + acct: အကောင့်ဟောင်းကို ကိုင်တွယ်ပါ။ + account_migration: + acct: အကောင့်သစ်ကို ကိုင်တွယ်ပါ။ + account_warning_preset: + text: ကြိုရေးထားသောစာ + title: ခေါင်းစဥ် + admin_account_action: + include_statuses: အီးမေးလ်တွင် တိုင်ကြားထားသောပို့စ်များကို ထည့်သွင်းပါ + send_email_notification: အသုံးပြုသူတစ်ယောက်တွင် အီးမေးလ်တစ်ခုသာ အသုံးပြုရပါမည် + text: စိတ်ကြိုက်သတိပေးချက် + type: လုပ်ဆောင်ချက် + types: + disable: ရပ်တန့် + none: သတိပေးချက်ပေးပို့ပါ + sensitive: သတိထားရသော + silence: ကန့်သတ် + suspend: ရပ်ဆိုင်းရန် + warning_preset_id: ကြိုတင်သတိပေးချက်ကို အသုံးပြုပါ + announcement: + all_day: တစ်နေ့တာလုပ်ငန်းစဉ် + ends_at: အကြောင်းအရာ၏အဆုံး + scheduled_at: ထုတ်ပြန်မည့်အချိန် + starts_at: အကြောင်းအရာ၏အစ + text: ကြေညာချက် + appeal: + text: ဆုံးဖြတ်ချက် ပြောင်းပြန်ချသင့်သောအကြောင်းရင်းအား ရှင်းပြပါ။ + defaults: + autofollow: သင့်အကောင့်စောင့်ကြည့်ရန် ဖိတ်ခေါ်ပါ + avatar: ကိုယ်စားပြုရုပ်ပုံ + bot: ဤသည်မှာ ဘော့တ်အကောင့်တစ်ခုဖြစ်သည်။ + chosen_languages: ဘာသာစကားများကို စစ်ထုတ်ထားခြင်း + confirm_new_password: စကားဝှက်အသစ်ကို အတည်ပြုပါ + confirm_password: စကားဝှက်ကို အတည်ပြုပါ။ + context: အကြောင်းအရာများကို စစ်ထုတ်ပါ။ + current_password: လက်ရှိစကားဝှက် + data: အချက်အလက် + display_name: ဖော်ပြမည့်အမည် + email: အီးမေးလ်လိပ်စာ + expires_in: သက်တမ်းကုန်ဆုံးမည့်ရက် + fields: ပရိုဖိုင်မီတာဒေတာ + header: မျက်နှာဖုံးပုံ + honeypot: "%{label} (မဖြည့်ပါနှင့်)" + inbox_url: ထပ်ဆင့်ဝင်စာ၏ URL + irreversible: ဖျောက်မယ့်အစား လွှတ်လိုက်ပါ။ + locale: ဘာသာစကား + max_uses: အများဆုံးအသုံးပြုမှုအရေအတွက် + new_password: စကားဝှက်အသစ် + note: ကိုယ်ရေးအကျဉ်း + otp_attempt: နှစ်ဆင့်ခံလုံခြုံရေးကုဒ် + password: စကားဝှက် + phrase: အဓိကစကားလုံး သို့မဟုတ် စကားစု + setting_advanced_layout: အဆင့်မြှင့်ထားသည့်ဝဘ်ကို ဖွင့်ပါ + setting_aggregate_reblogs: စာမျက်နှာများရှိ အဖွဲ့လိုက် Boost များ + setting_always_send_emails: အီးမေးလ်သတိပေးချက်များကို အမြဲပို့ပါ + setting_auto_play_gif: ကာတွန်း GIF များကို အလိုအလျောက်ဖွင့်ပါ + setting_boost_modal: Boost မလုပ်မီ အတည်ပြုချက်ပြပါ + setting_default_language: ပို့စ်တင်မည့်ဘာသာစကား + setting_default_privacy: ပို့စ်ကို ဘယ်သူမြင်နိုင်မလဲ + setting_default_sensitive: သတိထားရသောမီဒီယာအဖြစ် အမြဲအမှတ်အသားပြုပါ + setting_delete_modal: ပို့စ်တစ်ခုမဖျက်မီ အတည်ပြုချက်ပြပါ။ + setting_disable_swiping: ပွတ်ဆွဲခြင်းများကို ပိတ်ပါ + setting_display_media: မီဒီယာဖော်ပြမှု + setting_display_media_default: မူလသတ်မှတ်ချက် + setting_display_media_hide_all: အားလုံးကို ဖျောက်ပါ + setting_display_media_show_all: အားလုံးပြရန် + setting_expand_spoilers: အကြောင်းအရာသတိပေးချက်များဖြင့် အမှတ်အသားပြုထားသော ပို့စ်များကို အမြဲချဲ့ပါ + setting_hide_network: သင့် Social Graph ကို ဖျောက်ထားပါ + setting_reduce_motion: ကာတွန်းများတွင် လှုပ်ရှားမှုကို လျှော့ချပါ + setting_system_font_ui: စနစ်ရှိ နဂိုမူလ စာလုံးပုံစံကို အသုံးပြုပါ + setting_theme: ဆိုက်အပြင်အဆင် + setting_trends: ယနေ့ ရေပန်းစားသည်များကို ပြပါ + setting_unfollow_modal: တစ်စုံတစ်ဦးကို မစောင့်ကြည့်မီ အတည်ပြုချက် ဒိုင်ယာလော့ခ်ကို ပြပါ + setting_use_blurhash: ဖုံးကွယ်ထားသော ရုပ်ပုံ၊ဗီဒီယိုများအား အရောင်စုံ ရောင်ပြေးအနေနှင့် ပြသပါ။ + setting_use_pending_items: အနှေးပြကွက် + severity: ပြင်းထန်မှု + sign_in_token_attempt: လုံခြုံရေးကုဒ် + title: ခေါင်းစဥ် + type: ထည့်သွင်းမှုအမျိုးအစား + username: အသုံးပြုသူအမည် + username_or_email: အသုံးပြုသူအမည် သို့မဟုတ် အီးမေးလ် + whole_word: စကားလုံးဖြင့်သာ + email_domain_block: + with_dns_records: ဒိုမိန်း၏ MX မှတ်တမ်းများနှင့် IP များ ထည့်သွင်းပါ + featured_tag: + name: Hashtag + filters: + actions: + hide: လုံးဝဖျောက်ထားပါ + warn: သတိပေးချက်ဖြင့် ဖျောက်ပါ + form_admin_settings: + activity_api_enabled: API ရှိ အသုံးပြုသူလုပ်ဆောင်ချက်စာရင်းများကို ထုတ်ပြန်ပါ + backups_retention_period: အသုံးပြုသူ၏ မှတ်တမ်းကာလ + bootstrap_timeline_accounts: ဤအကောင့်များကို အသုံးပြုသူအသစ်များအတွက် အကြံပြုပေးပါ + closed_registrations_message: အကောင့်ဖွင့်ခြင်းများ မရတော့သောအခါ စိတ်ကြိုက်မက်ဆေ့ချ်ပို့ခြင်း + content_cache_retention_period: အကြောင်းအရာ ကက်ရှ်ထိန်းသိမ်းသည့်ကာလ + custom_css: စိတ်ကြိုက်ပြုလုပ်ထားသော CSS + mascot: စိတ်ကြိုက်ပြုလုပ်ထားသော mascot (legacy) + media_cache_retention_period: မီဒီယာကက်ရှ် ထိန်းသိမ်းသည့်ကာလ + peers_api_enabled: API တွင် ရှာဖွေတွေ့ရှိထားသော ဆာဗာများစာရင်းကို ထုတ်ပြန်ပါ + profile_directory: ပရိုဖိုင်လမ်းညွှန်ကို ဖွင့်ပါ + registrations_mode: ဘယ်သူတွေ အကောင့်ဖွင့်နိုင်မလဲ + require_invite_text: ပါဝင်ရန် အကြောင်းပြချက်တစ်ခု လိုအပ်ပါသည် + show_domain_blocks: ဒိုမိန်းပိတ်ပင်ထားမှုများကိုပြရန် + show_domain_blocks_rationale: ဒိုမိန်းများကို ဘာကြောင့် ပိတ်ဆို့ထားရကြောင်း ပြရန် + site_contact_email: ဆက်သွယ်ရမည့် အီးမေးလ် + site_contact_username: ဆက်သွယ်ရမည့် အသုံးပြုသူအမည် + site_extended_description: တိုးချဲ့ဖော်ပြချက် + site_short_description: ဆာဗာဖော်ပြချက် + site_terms: ကိုယ်ရေးအချက်အလက်မူဝါဒ + site_title: ဆာဗာအမည် + status_page_url: အခြေအနေပြစာမျက်နှာ URL + theme: မူလသတ်မှတ်ထားသည့် အပြင်အဆင် + thumbnail: ဆာဗာ ပုံသေး + timeline_preview: အများမြင်စာမျက်နှာများသို့ အထောက်အထားမရှိဘဲ ဝင်ရောက်ခွင့်ပြုပါ + trendable_by_default: ကြိုမသုံးသပ်ဘဲ ခေတ်စားနေသောအကြောင်းအရာများကို ခွင့်ပြုပါ + trends: လက်ရှိခေတ်စားနေမှုများကိုပြပါ + trends_as_landing_page: ခေတ်စားနေသောပို့စ်များကို landing စာမျက်နှာအဖြစ် အသုံးပြုပါ + interactions: + must_be_follower: စောင့်ကြည့်မနေသူများထံမှ အသိပေးချက်များကို ပိတ်ပါ + must_be_following: သင် စောင့်ကြည့်မထားသူများထံမှ အသိပေးချက်များကို ပိတ်ပါ + must_be_following_dm: သင် စောင့်ကြည့်မထားသူများထံမှ တိုက်ရိုက်မက်ဆေ့ချ်များကို ပိတ်ပါ + invite: + comment: မှတ်ချက် + invite_request: + text: သင် ဘာကြောင့် ပါဝင်ချင်တာလဲ။ + ip_block: + comment: မှတ်ချက် + ip: IP + severities: + no_access: ဝင်ရောက်ခွင့်ကို ပိတ်ပါ + sign_up_block: အကောင့်ဖွင့်ခြင်းများကို ပိတ်ပါ + sign_up_requires_approval: အကောင့်ဖွင့်ခြင်းများကို ကန့်သတ်ပါ + severity: စည်းမျဉ်း + notification_emails: + appeal: တစ်စုံတစ်ယောက်က စိစစ်ဆုံးဖြတ်ခြင်းကို တောင်းခံနေသည် + digest: အီးမေးလ်အကျဉ်းချုပ်များပို့ရန် + favourite: တစ်စုံတစ်ဦးက သင့်ပို့စ်ကို နှစ်သက်ခဲ့သည်။ + follow: တစ်စုံတစ်ဦးက သင့်ကို စောင့်ကြည့်ခဲ့သည် + follow_request: တစ်စုံတစ်ဦးက သင့်ကို စောင့်ကြည့်ရန် တောင်းဆိုခဲ့သည် + mention: တစ်စုံတစ်ဦးက သင့်ကို ဖော်ပြခဲ့သည် + pending_account: အကောင့်အသစ်ကို ပြန်လည်သုံးသပ်ရန် လိုအပ်သည် + reblog: တစ်ယောက်က သင့်ပို့စ်ကို Boost လုပ်ခဲ့သည် + report: အစီရင်ခံစာအသစ် တင်သွင်းထားသည် + software_updates: + all: အပ်ဒိတ်အားလုံးအတွက် အသိပေးရန် + critical: အရေးကြီးသော အပ်ဒိတ်များအတွက်သာ အသိပေးပါ + label: Mastodon ဗားရှင်းအသစ်ကို ရပါပြီ + none: "(မထောက်ခံထားသည့်) အပ်ဒိတ်များကို မည်သည့်အခါမျှ အသိပေးမည်မဟုတ်ပါ" + patch: ပြင်ဆင်ပြီးသောအပ်ဒိတ်များကို အသိပေးရန် + trending_tag: လက်ရှိခေတ်စားနေသောပို့စ်များကို ပြန်လည်သုံးသပ်ရန် လိုသည် + rule: + text: စည်းမျဉ်း + settings: + indexable: ရှာဖွေရေးအင်ဂျင်များတွင် ပရိုဖိုင်စာမျက်နှာကို ထည့်သွင်းပါ + show_application: သင် ပို့စ်တစ်ခုပေးပို့သည့် အက်ပ်မှ ပြသပါ။ + tag: + listable: ရှာဖွေမှုများနှင့် အကြံပြုချက်များတွင် ဤ hashtag ပေါ်လာစေရန် ခွင့်ပြုပါ + name: Hashtag + trendable: ခေတ်စားနေသောအကြောင်းအရာများအောက်တွင် ဤ hashtag ပေါ်လာစေရန် ခွင့်ပြုပါ + usable: ပို့စ်များကို ဤ hashtag သုံးခွင့်ပြုပါ + user: + role: အခန်းကဏ္ဍ + time_zone: အချိန်ဇုန် + user_role: + color: သင်္ကေတအရောင် + highlighted: အသုံးပြုသူပရိုဖိုင်များတွင် သင်္ကေတအဖြစ် အခန်းကဏ္ဍကို ပြသပါ + name: အမည် + permissions_as_keys: ခွင့်ပြုချက်များ + position: ဦးစားပေး + webhook: + events: အကြောင်းအရာများကဏ္ဍကို ဖွင့်ထားသည် + template: Payload ပုံစံ + url: URL ဆုံးမှတ် + 'no': မလုပ်ပါ + not_recommended: ထောက်ခံထားမှုမရှိ + overridden: ပယ်ဖျက် + recommended: ထောက်ခံထားပြီး + required: + mark: "*" + text: လိုအပ်သော + title: + sessions: + webauthn: အကောင့်ဝင်ရန်အတွက် သင့်လုံခြုံရေးကီးများထဲမှ တစ်ခုကို အသုံးပြုပါ + 'yes': ဟုတ်ကဲ့ diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index 44e9e78197..b0b695745b 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -2,6 +2,14 @@ nl: simple_form: hints: + account: + discoverable: Jouw openbare berichten kunnen worden uitgelicht op verschillende plekken binnen Mastodon en jouw account kan worden aanbevolen aan andere gebruikers. + display_name: Jouw volledige naam of een leuke bijnaam. + fields: Jouw website, persoonlijke voornaamwoorden, leeftijd, alles wat je maar kwijt wilt. + indexable: Jouw openbare berichten kunnen in de zoekresultaten op Mastodon verschijnen. Mensen die op jouw berichten hebben gereageerd kunnen ze sowieso doorzoeken. + note: 'Je kunt andere mensen @vermelden of #hashtags gebruiken.' + show_collections: Mensen kunnen zien wie jij volgt en wie jou volgen. + unlocked: Mensen kunnen jou volgen zonder daarvoor toestemming te hoeven vragen. Wanneer je nieuwe volgers handmatig wil goedkeuren moet je deze optie deselecteren. account_alias: acct: Vermeld de gebruikersnaam@domein van het account vanwaar je wilt verhuizen account_migration: @@ -32,19 +40,16 @@ nl: defaults: autofollow: Mensen die zich via de uitnodiging hebben geregistreerd, volgen jou automatisch avatar: PNG, GIF of JPG. Maximaal %{size}. Wordt teruggeschaald naar %{dimensions}px - bot: Signaal naar andere gebruikers toe dat dit account hoofdzakelijk geautomatiseerde berichten stuurt en mogelijk niet wordt gemonitord + bot: Signaal aan anderen dat het account voornamelijk geautomatiseerde acties uitvoert en mogelijk niet wordt gecontroleerd context: Een of meerdere locaties waar de filter actief moet zijn current_password: Voer voor veiligheidsredenen het wachtwoord van je huidige account in current_username: Voer ter bevestiging de gebruikersnaam van je huidige account in digest: Wordt alleen na een lange periode van inactiviteit verzonden en alleen wanneer je tijdens jouw afwezigheid persoonlijke berichten hebt ontvangen - discoverable: Toestaan dat jouw account vindbaar is voor onbekenden, via aanbevelingen, trends en op andere manieren email: Je krijgt een bevestigingsmail - fields: Je kunt maximaal 4 items als een tabel op je profiel weergeven header: PNG, GIF of JPG. Maximaal %{size}. Wordt teruggeschaald naar %{dimensions}px inbox_url: Kopieer de URL van de voorpagina van de relayserver die je wil gebruiken irreversible: Gefilterde berichten verdwijnen onomkeerbaar, zelfs als de filter later wordt verwijderd locale: De taal van de gebruikersomgeving, e-mails en pushmeldingen - locked: Door het goedkeuren van volgers handmatig bepalen wie jou mag volgen password: Gebruik tenminste 8 tekens phrase: Komt overeen ongeacht hoofd-/kleine letters of een inhoudswaarschuwing scopes: Tot welke API's heeft de toepassing toegang. Wanneer je een toestemming van het bovenste niveau kiest, hoef je geen individuele toestemmingen meer te kiezen. @@ -54,12 +59,9 @@ nl: setting_display_media_default: Als gevoelig gemarkeerde media verbergen setting_display_media_hide_all: Media altijd verbergen setting_display_media_show_all: Media altijd tonen - setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond - setting_noindex: Heeft invloed op jouw openbare profiel en pagina's met berichten - setting_show_application: De toepassing de je gebruikt om berichten te plaatsen wordt in de gedetailleerde weergave van het bericht getoond setting_use_blurhash: Wazige kleurovergangen zijn gebaseerd op de kleuren van de verborgen media, waarmee elk detail verdwijnt setting_use_pending_items: De tijdlijn wordt bijgewerkt door op het aantal nieuwe items te klikken, in plaats van dat deze automatisch wordt bijgewerkt - username: Jouw gebruikersnaam is uniek op %{domain} + username: Je kunt letters, cijfers en underscores gebruiken whole_word: Wanneer het trefwoord of zinsdeel alfanumeriek is, wordt het alleen gefilterd wanneer het hele woord overeenkomt domain_allow: domain: Dit domein is in staat om gegevens van deze server op te halen, en binnenkomende gegevens worden verwerkt en opgeslagen @@ -78,7 +80,7 @@ nl: backups_retention_period: De aangemaakte gebruikersarchieven voor het opgegeven aantal dagen behouden. bootstrap_timeline_accounts: Deze accounts worden bovenaan de aanbevelingen aan nieuwe gebruikers getoond. Meerdere gebruikersnamen met komma's scheiden. closed_registrations_message: Weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld - content_cache_retention_period: 'Berichten van andere servers worden na het opgegeven aantal dagen verwijderd. Let op: Dit is onomkeerbaar.' + content_cache_retention_period: Alle berichten van andere servers worden na het opgegeven aantal dagen verwijderd. Deze berichten kunnen daarna hoogstwaarschijnlijk niet meer worden hersteld. Alle gerelateerde bladwijzers, favorieten en boosts worden eveneens onomkeerbaar verwijderd. custom_css: Je kunt aangepaste CSS toepassen op de webversie van deze Mastodon-server. mascot: Overschrijft de illustratie in de geavanceerde webomgeving. media_cache_retention_period: Mediabestanden die van andere servers zijn gedownload worden na het opgegeven aantal dagen verwijderd en worden op verzoek opnieuw gedownload. @@ -118,6 +120,9 @@ nl: sessions: otp: 'Voer de tweestaps-toegangscode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcodes:' webauthn: Wanneer het een USB-sleutel is, zorg er dan voor dat je deze in de computer steekt en, wanneer nodig, activeert. + settings: + indexable: Jouw profielpagina kan in de zoekresultaten van Google, Bing, DuckDuckGo en andere zoekmachines verschijnen. + show_application: Je kunt zelf altijd zien met welke app je een bericht hebt geplaatst. tag: name: Je kunt elk woord met een hoofdletter beginnen, om zo bijvoorbeeld de tekst leesbaarder te maken user: @@ -131,12 +136,17 @@ nl: position: Een hogere rol beslist in bepaalde situaties over het oplossen van conflicten. Bepaalde acties kunnen alleen worden uitgevoerd op rollen met een lagere prioriteit webhook: events: Selecteer de te verzenden gebeurtenissen + template: Maak een eigen JSON payload aan met variabele interpolatie. Laat leeg voor standaard JSON. url: Waar gebeurtenissen naartoe worden verzonden labels: account: + discoverable: Jouw account en berichten laten uitlichten door Mastodon fields: name: Label value: Inhoud + indexable: Openbare berichten in zoekresultaten opnemen + show_collections: Accounts die jij volgt en die jou volgen op je profiel tonen + unlocked: Automatisch nieuwe volgers accepteren account_alias: acct: Mastodonadres van het oude account account_migration: @@ -167,24 +177,22 @@ nl: defaults: autofollow: Uitnodigen om jouw account te volgen avatar: Profielfoto - bot: Dit is een bot-account + bot: Dit is een geautomatiseerd account chosen_languages: Talen filteren confirm_new_password: Nieuw wachtwoord bevestigen confirm_password: Wachtwoord bevestigen context: Filterlocaties current_password: Huidig wachtwoord data: Gegevens - discoverable: Dit account laten aanbevelen en in de gebruikersgids tonen display_name: Weergavenaam email: E-mailadres expires_in: Vervalt na - fields: Metadata profiel + fields: Extra velden header: Omslagfoto honeypot: "%{label} (niet invullen)" inbox_url: Inbox-URL van de relayserver irreversible: Verwijderen in plaats van verbergen locale: Taal van de gebruikersomgeving - locked: Volgverzoek vereisen max_uses: Max. aantal keer te gebruiken new_password: Nieuwe wachtwoord note: Bio @@ -194,9 +202,8 @@ nl: setting_advanced_layout: Geavanceerde webomgeving inschakelen setting_aggregate_reblogs: Boosts in tijdlijnen groeperen setting_always_send_emails: Altijd e-mailmeldingen verzenden - setting_auto_play_gif: Speel geanimeerde GIF's automatisch af + setting_auto_play_gif: Geanimeerde GIF's automatisch afspelen setting_boost_modal: Vraag voor het boosten van een bericht een bevestiging - setting_crop_images: Afbeeldingen bijsnijden tot 16x9 in berichten op tijdlijnen setting_default_language: Taal van jouw berichten setting_default_privacy: Zichtbaarheid van nieuwe berichten setting_default_sensitive: Media altijd als gevoelig markeren @@ -206,12 +213,10 @@ nl: setting_display_media_default: Standaard setting_display_media_hide_all: Alles verbergen setting_display_media_show_all: Alles tonen - setting_expand_spoilers: Altijd berichten met inhoudswaarschuwingen uitklappen + setting_expand_spoilers: Berichten met inhoudswaarschuwingen altijd uitklappen setting_hide_network: Jouw volgers en wie je volgt verbergen - setting_noindex: Jouw berichten niet door zoekmachines laten indexeren - setting_reduce_motion: Langzamere animaties - setting_show_application: Toepassing onthullen die je voor het verzenden van berichten gebruikt - setting_system_font_ui: Standaardlettertype van jouw systeem gebruiken + setting_reduce_motion: Beweging in animaties verminderen + setting_system_font_ui: Standaardlettertype van het systeem gebruiken setting_theme: Thema website setting_trends: Trends van vandaag tonen setting_unfollow_modal: Vraag voor het ontvolgen van iemand een bevestiging @@ -263,7 +268,7 @@ nl: interactions: must_be_follower: Meldingen van mensen die jou niet volgen blokkeren must_be_following: Meldingen van mensen die jij niet volgt blokkeren - must_be_following_dm: Directe berichten van mensen die jij niet volgt blokkeren + must_be_following_dm: Privéberichten van mensen die jij niet volgt blokkeren invite: comment: Opmerking invite_request: @@ -286,9 +291,18 @@ nl: pending_account: Wanneer een nieuw account moet worden beoordeeld reblog: Wanneer iemand jouw bericht heeft geboost report: Nieuwe rapportage is ingediend + software_updates: + all: Meldingen geven voor alle updates + critical: Alleen meldingen voor kritieke updates geven + label: Er is een nieuwe versie van Mastodon beschikbaar + none: Nooit meldingen van updates geven (niet aanbevolen) + patch: Meldingen bij bugfix-updates trending_tag: Nieuwe trend vereist beoordeling rule: text: Regel + settings: + indexable: Zoekmachines jouw profielpagina laten vinden + show_application: App tonen die je voor het plaatsen van berichten gebruikt tag: listable: Toestaan dat deze hashtag in zoekopdrachten en aanbevelingen te zien valt name: Hashtag @@ -296,6 +310,7 @@ nl: usable: Toestaan dat deze hashtag in berichten gebruikt mag worden user: role: Rol + time_zone: Tijdzone user_role: color: Kleur van badge highlighted: Rol als badge op profielpagina's tonen @@ -304,9 +319,11 @@ nl: position: Prioriteit webhook: events: Ingeschakelde gebeurtenissen + template: Sjabloon Payload url: Eindpunt URL 'no': Nee not_recommended: Niet aanbevolen + overridden: Overschreven recommended: Aanbevolen required: mark: "*" diff --git a/config/locales/simple_form.nn.yml b/config/locales/simple_form.nn.yml index db4007c4f7..266ef1fcce 100644 --- a/config/locales/simple_form.nn.yml +++ b/config/locales/simple_form.nn.yml @@ -2,6 +2,14 @@ nn: simple_form: hints: + account: + discoverable: Dei offentlege innlegga dine og profilen din kan dukka opp i tilrådingar på ulike stader på Mastodon, og profilen din kan bli føreslegen for andre folk. + display_name: Ditt fulle namn eller ditt tøysenamn. + fields: Heimesida di, pronomen, alder, eller kva du måtte ynskje. + indexable: Dei offentlege innlegga dine kan dukka opp i søkjeresultat på Mastodon. Folk som har reagert på oinnlegga dine kan uansett søkja gjennom dei. + note: 'Du kan @nemne folk eller #emneknaggar.' + show_collections: Andre kan sjå kven du følgjer og kven som følgjer deg. Dei du følgjer kan alltid sjå at du følgjer dei. + unlocked: Alle kan følgje deg utan å måtte spørje om det. Vel bort om du vil gå gjennom førespurnadar om å følgje deg og seie ja eller nei. account_alias: acct: Angi brukarnamn@domene til brukaren du ynskjer å flytta frå account_migration: @@ -18,6 +26,8 @@ nn: disable: Hindre eigaren frå å bruke kontoen, men fjern eller skjul ikkje innhaldet deira. none: Bruk dette for å senda ei åtvaring til brukaren utan å utløyse andre handlingar. sensitive: Tving markering for sensitivt innhald på alle mediavedlegga til denne brukaren. + silence: Hindre brukaren frå å leggja ut offentlege innlegg, gøym innlegga deira og varslingar frå folk som ikkje fylgjer dei. Lukkar alle rapportar om denne kontoen. + suspend: Hindre samhandling med– og slett innhaldet til denne kontoen. Kan omgjerast innan 30 dagar. Lukkar alle rapportar om denne kontoen. warning_preset_id: Valfritt. Du kan leggja inn eigen tekst på enden av føreoppsettet announcement: all_day: Når merka, vil berre datoane til tidsramma synast @@ -35,14 +45,11 @@ nn: current_password: For sikkerhetsgrunner, vennligst oppgi passordet til den nåværende bruker current_username: Skriv inn brukarnamnet til den noverande kontoen for å stadfesta digest: Kun sendt etter en lang periode med inaktivitet og bare dersom du har mottatt noen personlige meldinger mens du var borte - discoverable: La kontoen din bli oppdaga av ukjende gjennom anbefalingar, trendar og andre funksjonar email: Du får snart ein stadfestings-e-post - fields: Du kan ha opptil 4 gjenstander vist som en tabell på profilsiden din header: PNG, GIF eller JPG. Maksimalt %{size}. Minkast til %{dimensions}px inbox_url: Kopier URLen fra forsiden til overgangen du vil bruke irreversible: Filtrerte tut vil verta borte for evig, sjølv om filteret vert fjerna seinare locale: Språket til brukargrensesnittet, e-postar og push-varsel - locked: Krev at du manuelt godkjenner fylgjarar password: Nytt minst 8 teikn phrase: Vil bli samsvart med, uansett bruk av store/små bokstaver eller innholdsadvarselen til en tut scopes: API-ane som programmet vil få tilgjenge til. Ettersom du vel eit toppnivåomfang tarv du ikkje velja einskilde API-ar. @@ -52,12 +59,9 @@ nn: setting_display_media_default: Gøym media som er merka som nærtakande setting_display_media_hide_all: Alltid skjul alt media setting_display_media_show_all: Vis alltid media - setting_hide_network: Kven du fylgjer og kven som fylgjer deg vert ikkje vist på profilen din - setting_noindex: Påverkar den offentlege profilen og statussidene dine - setting_show_application: Programmet du brukar for å tuta blir vist i den detaljerte visninga av tuta dine setting_use_blurhash: Overgangar er basert på fargane til skjulte grafikkelement, men gjer detaljar utydelege setting_use_pending_items: Gøym tidslineoppdateringar bak eit klikk, i staden for å rulla ned automatisk - username: Brukarnamnet ditt vert unikt på %{domain} + username: Du kan bruka bokstavar, tal og understrekar whole_word: Når søkjeordet eller setninga berre er alfanumerisk, nyttast det berre om det samsvarar med heile ordet domain_allow: domain: Dette domenet er i stand til å henta data frå denne tenaren og innkomande data vert handsama og lagra @@ -72,6 +76,7 @@ nn: hide: Skjul filtrert innhald fullstendig og lat som om det ikkje finst warn: Skjul det filtrerte innhaldet bak ei åtvaring som nemner tittelen på filteret form_admin_settings: + activity_api_enabled: Tal på lokale innlegg, aktive brukarar og nyregistreringar kvar veke backups_retention_period: Ta vare på genererte brukararkiv i angitt 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 @@ -79,6 +84,7 @@ nn: custom_css: Du kan bruka eigendefinerte stilar på nettversjonen av Mastodon. mascot: Overstyrer illustrasjonen i det avanserte webgrensesnittet. media_cache_retention_period: Mediafiler som har blitt lasta ned vil bli sletta etter det angitte talet på dagar når det er sett til ein positiv verdi, og lasta ned på nytt ved etterspørsel. + peers_api_enabled: Ei liste over domenenamn denne tenaren har møtt på i allheimen. Det står ingenting om tenaren din samhandlar med ein annan tenar, berre om tenaren din veit om den andre. Dette blir brukt av tenester som samlar statistikk om føderering i det heile. profile_directory: Profilkatalogen viser alle brukarar som har valt å kunne bli oppdaga. require_invite_text: Når registrering krev manuell godkjenning, lyt du gjera tekstfeltet "Kvifor vil du bli med?" obligatorisk i staden for valfritt site_contact_email: Korleis kan ein få tak i deg når det gjeld juridiske spørsmål eller spørsmål om støtte. @@ -87,11 +93,13 @@ nn: site_short_description: Ein kort omtale for lettare å finne tenaren blant alle andre. Kven driftar han, kven er i målgruppa? site_terms: Bruk eigen personvernpolicy eller la stå tom for å bruka standard. Kan strukturerast med Markdown-syntaks. site_title: Kva ein kan kalla tenaren, utanom domenenamnet. + status_page_url: Adressa til ei side der folk kan sjå statusen til denne tenaren ved feil og utkoplingar theme: Tema som er synleg for nye brukarar og besøkjande som ikkje er logga inn. thumbnail: Eit omlag 2:1 bilete vist saman med informasjon om tenaren. timeline_preview: Besøkjande som ikkje er logga inn vil kunne bla gjennom dei siste offentlege innlegga på tenaren. trendable_by_default: Hopp over manuell gjennomgang av populært innhald. Enkeltståande innlegg kan fjernast frå trendar i etterkant. trends: Trendar viser kva for nokre innlegg, emneknaggar og nyheiter som er i støytet på tenaren. + trends_as_landing_page: Vis populært innhald til utlogga brukarar og folk som kjem innom sida i staden for ei skildring av tenaren. Du må ha skrudd på trendar for å kunna bruka dette. form_challenge: current_password: Du går inn i eit trygt område imports: @@ -112,6 +120,9 @@ nn: sessions: otp: Angi tofaktorkoden fra din telefon eller bruk en av dine gjenopprettingskoder. webauthn: Om det er ein USB-nøkkel må du setja han inn og om nødvendig trykkja på han. + settings: + indexable: Profilsida di kan dukka opp søkjeresultat frå Google, Bing, Duckduckgo og andre. + show_application: Du vil uansett alltid kunna sjå kva app som la ut innlegga dine. tag: name: Du kan berre endra bruken av store/små bokstavar, t. d. for å gjera det meir leseleg user: @@ -125,12 +136,17 @@ nn: position: Høgare rolle avgjer konfliktløysing i visse situasjonar. Visse handlingar kan kun utførast på rollar med lågare prioritet webhook: events: Vel hendingar å senda + template: Skriv di eiga JSON nyttelast ved å bruka variabel interpolering. La stå tom for standard JSON. url: Kvar hendingar skal sendast labels: account: + discoverable: Ta med profilen og innlegga i oppdagingsalgoritmar fields: name: Merkelapp value: Innhald + indexable: Ta med offentlege innlegg i søkjeresultat + show_collections: Vis følgjer og følgjare på profilen + unlocked: Godta nye følgjare automatisk account_alias: acct: Brukarnamnet på den gamle kontoen account_migration: @@ -168,7 +184,6 @@ nn: context: Filtrer kontekstar current_password: Noverande passord data: Data - discoverable: Før denne kontoen opp i mappa display_name: Synleg namn email: E-post-adresse expires_in: Vert ugyldig etter @@ -178,7 +193,6 @@ nn: inbox_url: URL-addressen til overgangsinnboksen irreversible: Forkast i staden for å gøyma locale: Språk - locked: Lås konto max_uses: Grense på brukartal new_password: Nytt passord note: Om meg @@ -190,7 +204,6 @@ nn: setting_always_send_emails: Alltid send epostvarsel setting_auto_play_gif: Spel av animerte GIF-ar automatisk setting_boost_modal: Vis stadfesting før framheving - setting_crop_images: Skjer bilete i ikkje-utvida tut til 16x9 setting_default_language: Språk på innlegg setting_default_privacy: Privatliv setting_default_sensitive: Merk alltid media som nærtakande @@ -202,9 +215,7 @@ nn: setting_display_media_show_all: Vis alle setting_expand_spoilers: Vid alltid ut tut som er merka med innhaldsåtvaringar setting_hide_network: Gøym nettverket ditt - setting_noindex: Vel bort søkjemotorregistrering setting_reduce_motion: Minsk rørsle i animasjonar - setting_show_application: Avdekk programmet bruka for å senda tut setting_system_font_ui: Bruk standardskrifttypen på systemet setting_theme: Sidetema setting_trends: Vis kva som er populært i dag @@ -227,6 +238,7 @@ nn: hide: Gøym totalt warn: Gøym med ei advarsel form_admin_settings: + activity_api_enabled: Legg ut samla statistikk om brukaraktiviteten i APIet backups_retention_period: Arkiveringsperiode for brukararkiv bootstrap_timeline_accounts: Tilrå alltid desse kontoane for nye brukarar closed_registrations_message: Eigendefinert melding når registrering ikkje er mogleg @@ -234,6 +246,7 @@ nn: custom_css: Egendefinert CSS mascot: Eigendefinert maskot (eldre funksjon) media_cache_retention_period: Oppbevaringsperiode for mediebuffer + peers_api_enabled: Legg ut ei liste over oppdaga tenarar i APIet profile_directory: Aktiver profilkatalog registrations_mode: Kven kan registrera seg require_invite_text: Krev ei grunngjeving for å få bli med @@ -245,11 +258,13 @@ nn: site_short_description: Stutt om tenaren site_terms: Personvernsreglar site_title: Tenarnamn + status_page_url: Adresse til statussida theme: Standardtema thumbnail: Miniatyrbilete for tenaren timeline_preview: Tillat uautentisert tilgang til offentleg tidsline trendable_by_default: Tillat trendar utan gjennomgang på førehand trends: Aktiver trendar + trends_as_landing_page: Bruk trendar som startside interactions: must_be_follower: Gøym varslingar frå folk som ikkje fylgjer deg must_be_following: Gøym varslingar frå folk du ikkje fylgjer @@ -276,9 +291,18 @@ nn: pending_account: Send e-post når ein ny konto treng gjennomgang reblog: Send e-post når nokon framhevar statusen din report: Ny rapport er sendt + software_updates: + all: Varsle om alle oppdateringar + critical: Varsle kun om kristiske oppdateringar + label: Ein ny versjon av Mastodon er tilgjengeleg + none: Aldri varsle om oppdateringar (ikkje anbefalt) + patch: Varsle om feilrettingsoppdateringar trending_tag: Ny trend krev gjennomgang rule: text: Regler + settings: + indexable: Ta med profilsida i søkjemotorar + show_application: Vis kva app du brukte når du skreiv innlegg tag: listable: Tillat denne emneknaggen å synast i søk og i profilmappa name: Emneknagg @@ -286,6 +310,7 @@ nn: usable: Gje tut lov til å nytta denne emneknaggen user: role: Rolle + time_zone: Tidssone user_role: color: Emblemfarge highlighted: Vis rolle som emblem på brukarprofil @@ -294,9 +319,11 @@ nn: position: Prioritet webhook: events: Aktiverte hendingar + template: Nyttelastmal url: Endepunkts-URL 'no': Nei not_recommended: Ikkje anbefalt + overridden: Overstyrt recommended: Tilrådt required: mark: "*" diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index 4cf678b83e..a9d5465f36 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -2,8 +2,16 @@ 'no': simple_form: hints: + account: + discoverable: Dine offentlige innlegg og profil kan bli omtalt eller anbefalt i ulike deler av Mastodon, og profilen din kan foreslås til andre brukere. + display_name: Ditt fulle navn eller ditt morsomme navn. + fields: Din hjemmeside, uttalelse, alder, eller alt annet du vil. + indexable: Dine offentlige innlegg kan vises i søkeresultat på Mastodon. Personer som har samhandlet med innleggene dine kan finne de uansett. + note: 'Du kan @nevne andre eller #emneknagger.' + show_collections: Folk vil kunne bla gjennom de du følger og dine følgere. Folk du følger vil uansett se at du følger dem. + unlocked: Folk vil kunne følge deg uten å be om godkjenning. Fjern markeringen om du vil gjennomgå følge-forespørsler og velge om du vil akseptere eller avvise nye følgere. account_alias: - acct: Spesifiser brukernavn@domene til brukeren du vil flytte fra + acct: Spesifiser brukernavn@domene til kontoen du vil flytte fra account_migration: acct: Spesifiser brukernavn@domene til brukeren du vil flytte til account_warning_preset: @@ -18,6 +26,8 @@ disable: Forhindre brukeren fra å bruke kontoen sin, men ikke slett eller skjul innholdet deres. none: Bruk dette for å sende en advarsel til brukeren uten å utløse noen andre handlinger. sensitive: Tving alle denne brukerens medievedlegg til å bli merket som følsomme. + silence: Forhindre at brukeren kan legge ut innlegg med offentlig synlighet, skjul innleggene deres og varslene fra folk som ikke følger dem. Lukker alle rapporter mot denne kontoen. + suspend: Forhindre interaksjon fra eller til denne kontoen og slett innholdet. Tilbakestiller innholdet innen 30 dager. Lukk alle rapporter mot denne kontoen. warning_preset_id: Valgfritt. Du kan fortsatt legge til tilpasset tekst til slutten av forhåndsinnstillingen announcement: all_day: Hvis noen av dem er valgt, vil kun datoene av tidsrammen bli vist @@ -35,14 +45,11 @@ current_password: For sikkerhetsgrunner, vennligst oppgi passordet til den nåværende bruker current_username: For å bekrefte, vennligst skriv inn brukernavnet til den nåværende kontoen digest: Kun sendt etter en lang periode med inaktivitet og bare dersom du har mottatt noen personlige meldinger mens du var borte - discoverable: La kontoen din bli oppdaget av ukjente gjennom anbefalinger, trender og andre funksjoner email: Du vil bli tilsendt en bekreftelses-E-post - fields: Du kan ha opptil 4 gjenstander vist som en tabell på profilsiden din header: PNG, GIF eller JPG. Maksimalt %{size}. Vil bli nedskalert til %{dimensions}px inbox_url: Kopier URLen fra forsiden til overgangen du vil bruke irreversible: Filtrerte innlegg vil ugjenkallelig forsvinne, selv om filteret senere blir fjernet locale: Språket til brukergrensesnittet, e-mailer og push-varsler - locked: Krever at du manuelt godkjenner følgere password: Bruk minst 8 tegn phrase: Vil bli samsvart med, uansett bruk av store/små bokstaver eller innholdsvarselet til et innlegg scopes: Hvilke API-er programmet vil bli gitt tilgang til. Dersom du velger et toppnivåomfang, trenger du ikke å velge individuelle API-er. @@ -52,12 +59,9 @@ setting_display_media_default: Skjul media som er merket som følsomt setting_display_media_hide_all: Skjul alltid all media setting_display_media_show_all: Alltid vis media som er merket som sensitivt - setting_hide_network: De som du følger, og de som følger deg, vil ikke bli vist på profilen din - setting_noindex: Påvirker din offentlige profil og statussider - setting_show_application: Appen du bruker til å publisere innlegg vil bli vist i den detaljerte visningen til innleggene dine setting_use_blurhash: Gradientene er basert på fargene til de skjulte visualitetene, men gjør alle detaljer uklare setting_use_pending_items: Skjul tidslinjeoppdateringer bak et klikk, i stedet for å automatisk la strømmen skrolle - username: Brukernavnet ditt vil være unikt på %{domain} + username: Du kan bruke bokstaver, tall og understrekingstegn whole_word: Når søkeordet eller setningen bare er alfanumerisk, aktiveres det bare hvis det samsvarer med hele ordet domain_allow: domain: Dette domenet vil være i stand til å hente data fra denne serveren og dets innkommende data vil bli prosessert og lagret @@ -72,6 +76,7 @@ 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 backups_retention_period: Behold genererte brukerarkiv i det angitte antall dager. 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 @@ -79,6 +84,7 @@ custom_css: Du kan bruke egendefinerte stiler på nettversjonen av Mastodon. mascot: Overstyrer illustrasjonen i det avanserte webgrensesnittet. media_cache_retention_period: Mediafiler som lastes ned vil bli slettet etter det angitte antall dager når det settes til en positiv verdi, og blir lastet ned på nytt ved behov. + peers_api_enabled: En liste over domenenavn denne serveren har oppstått i fødiverset. Det finnes ikke data om du føderer med en gitt server, for akkurat det serveren din vet om. Dette brukes av tjenester som i all hovedsak innhenter føderasjonsstatistikk. profile_directory: Profilkatalogen viser alle brukere som har valgt å kunne bli oppdaget. require_invite_text: Når registreringer krever manuell godkjenning, må du gjøre «Hvorfor vil du bli med?»-tekstinput obligatorisk i stedet for valgfritt site_contact_email: Hvordan mennesker får tak i deg for rettslige spørsmål eller brukerstøtte. @@ -87,7 +93,13 @@ site_short_description: En kort beskrivelse for å bidra til å definere din tjeners identitet. Hvem kjører den, hvem er det for? site_terms: Bruk dine egne personvernregler eller la stå tom for å bruke standarden. Kan struktureres med Markdown-syntaks. site_title: Hva man kan kalle tjeneren din utover domenenavnet. + status_page_url: URL-adressen til en side hvor folk kan se tilstanden til denne tjeneren under et avbrudd theme: Tema som vises for nye brukere og besøkende som ikke er logget inn. + thumbnail: Et omtrent 2:1 bilde vist sammen med serverinformasjonen din. + timeline_preview: Logget ut besøkende vil kunne bla gjennom de siste offentlige innlegg tilgjengelig på serveren. + trendable_by_default: Hopp over manuell gjennomgang av populære innhold. Individuelle elementer kan fjernes fra populært etter faktaen. + trends: Trender viser hvilke innlegg, emneknagger og nyheter som får trekkraft på serveren din. + trends_as_landing_page: Vis populære innhold til innloggede brukere og besøkende i stedet for en beskrivelse av tjeneren. Krever populært for å bli aktivert. form_challenge: current_password: Du går inn i et sikkert område imports: @@ -107,10 +119,15 @@ text: Beskriv en regel eller krav til brukere på denne serveren. Prøv å holde den kort og enkelt sessions: otp: Angi tofaktorkoden fra din telefon eller bruk en av dine gjenopprettingskoder. + webauthn: Hvis det er en USB-nøkkel må du sette den inn og om nødvendig trykke på den. + settings: + indexable: Profilsiden din kan vises i søkeresultater på Google, Bing og så videre. + show_application: Du vil uansett kunne se hvilken app publiserte ditt innlegg. tag: name: Du kan bare forandre bruken av store/små bokstaver, f.eks. for å gjøre det mer lesbart user: chosen_languages: Hvis noen av dem er valgt, vil kun innlegg i de valgte språkene bli vist i de offentlige tidslinjene + role: Rollekontroller som bestemmer rettigheter brukeren har user_role: color: Farge som skal brukes for rollen gjennom hele UI, som RGB i hex-format highlighted: Dette gjør rollen offentlig synlig @@ -119,12 +136,17 @@ position: Høyere rolle bestemmer konfliktløsning i visse situasjoner. Enkelte tiltak kan bare utføres på roller med lavere prioritet webhook: events: Velg hendelser som skal sendes + template: Skriv din egen JSON nyttelast ved å bruke variabel interpolering. La stå tom for standard JSON. url: Hvor hendelser vil bli sendt til labels: account: + discoverable: Anbefal profil og innlegg i Mastodons algoritmer fields: name: Etikett value: Innhold + indexable: Inkluder offentlige innlegg i søkeresultater + show_collections: Vis de du følger og dine følgere på profilen + unlocked: Godta nye følgere automatisk account_alias: acct: Brukernavnet til den gamle brukeren account_migration: @@ -155,24 +177,22 @@ defaults: autofollow: Inviter til å følge kontoen din avatar: Profilbilde - bot: Dette er en botkonto + bot: Dette er en automatisert konto chosen_languages: Filtrer språk confirm_new_password: Bekreft nytt passord confirm_password: Bekreft passord context: Filtersammenhenger current_password: Nåværende passord data: Data - discoverable: Før opp denne kontoen i mappen display_name: Visningsnavn email: E-postadresse expires_in: Utløper etter - fields: Profilmetadata - header: Overskrift + fields: Ekstrafelt + header: Bakgrunnsbilde på profilen honeypot: "%{label} (ikke fyll ut)" inbox_url: URL til overgangsinnboksen irreversible: Forkast i stedet for å skjule locale: Språk - locked: Lås konto max_uses: Maksimalt antall bruk new_password: Nytt passord note: Om meg @@ -180,11 +200,10 @@ password: Passord phrase: Nøkkelord eller frase setting_advanced_layout: Skru på det avanserte nettgrensesnittet - setting_aggregate_reblogs: Gruppefremhevinger i tidslinjer + setting_aggregate_reblogs: Samle fremhevinger i tidslinjer setting_always_send_emails: Alltid send e-postvarslinger setting_auto_play_gif: Autoavspill animert GIF-filer setting_boost_modal: Vis bekreftelse før fremheving - setting_crop_images: Klipp bilder i ikke-utvidede innlegg til 16:9 setting_default_language: Innleggsspråk setting_default_privacy: Postintegritet setting_default_sensitive: Merk alltid media som følsomt @@ -196,9 +215,7 @@ setting_display_media_show_all: Vis alle setting_expand_spoilers: Utvid alltid innlegg som er merket med innholdsvarsler setting_hide_network: Skjul nettverket ditt - setting_noindex: Avmeld fra søkemotorindeksering setting_reduce_motion: Reduser bevegelser i animasjoner - setting_show_application: Vis hvilken app som ble brukt til å sende innlegg setting_system_font_ui: Bruk systemets standardfont setting_theme: Sidens tema setting_trends: Vis dagens trender @@ -221,12 +238,15 @@ hide: Skjul fullstendig warn: Skjul med en advarsel form_admin_settings: + activity_api_enabled: Publiser samlet statistikk om brukeraktivitet i API backups_retention_period: Brukers oppbevaringsperiode for arkiv bootstrap_timeline_accounts: Anbefaler alltid disse kontoene til nye brukere closed_registrations_message: Egendefinert melding når registrering ikke er tilgjengelig content_cache_retention_period: Oppbevaringsperiode for innholdsbuffer custom_css: Egendefinert CSS + mascot: Egendefinert maskot (legacy) media_cache_retention_period: Oppbevaringsperiode for mediebuffer + peers_api_enabled: Publiser liste over oppdagede instanser i API profile_directory: Aktiver profilkatalog registrations_mode: Hvem kan opprette konto require_invite_text: Krev en grunn for å bli med @@ -238,10 +258,13 @@ site_short_description: Beskrivelse av server site_terms: Retningslinjer for personvern site_title: Servernavn + status_page_url: Status side lenke theme: Standard tema thumbnail: Miniatyrbilde til server + timeline_preview: Tillat uautentisert tilgang til offentlige tidslinjer trendable_by_default: Tillat trender uten foregående vurdering trends: Aktiver trender + trends_as_landing_page: Bruk trender som landingsside interactions: must_be_follower: Blokker varslinger fra ikke-følgere must_be_following: Blokker varslinger fra personer du ikke følger @@ -268,9 +291,18 @@ pending_account: Ny bruker avventer gjennomgang reblog: Send e-post når noen fremhever din status report: Ny rapport er sendt + software_updates: + all: Varsle om alle oppdateringer + critical: Varsle kun om kritiske oppdateringer + label: En ny versjon av Mastodon er tilgjengelig + none: Aldri varsle om oppdateringer (anbefales ikke) + patch: Varsle om oppdateringer med feilrettinger trending_tag: Ny trend krever gjennomgang rule: text: Regler + settings: + indexable: Inkluder profilside i søkemotorer + show_application: Vis hvilket program du brukte når du sendte et innlegg tag: listable: Tillat denne emneknaggen å vises i søk og på profilmappen name: Emneknagg @@ -278,6 +310,7 @@ usable: Tillat innlegg å bruke denne emneknaggen user: role: Rolle + time_zone: Tidssone user_role: color: Merkefarge highlighted: Vis rolle som merke på brukerprofiler @@ -286,6 +319,8 @@ position: Prioritet webhook: events: Aktiverte hendelser + template: Nyttelast mal + url: Endepunkt lenke 'no': Nei not_recommended: Ikke anbefalt recommended: Anbefalt diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml index 566f4f100b..7159eed322 100644 --- a/config/locales/simple_form.oc.yml +++ b/config/locales/simple_form.oc.yml @@ -32,12 +32,10 @@ oc: current_username: Per confirmar, volgatz picar lo nom d’utilizaire del compte actual digest: Solament enviat aprèp un long moment d’inactivitat e solament s’avètz recebut de messatges personals pendent vòstra abséncia email: Vos mandarem un corrièl de confirmacion - fields: Podètz far veire cap a 4 elements sus vòstre perfil header: PNG, GIF o JPG. Maximum %{size}. Serà retalhada en %{dimensions}px inbox_url: Copiatz l’URL de la pagina màger del relai que volètz utilizar irreversible: Los tuts filtrats desapareisseràn irreversiblament, encara que lo filtre siá suprimit mai tard locale: La lenga de l’interfàcia d’utilizacion, los messatges e las notificacions - locked: Demanda qu’acceptetz manualament lo mond que vos sègon e botarà la visibilitat de vòstras publicacions coma accessiblas a vòstres seguidors solament password: Utilizatz almens 8 caractèrs phrase: Serà pres en compte que siá en majuscula o minuscula o dins un avertiment de contengut sensible scopes: A quinas APIs poiràn accedir las aplicacions. Se seleccionatz un encastre de naut nivèl, fa pas mestièr de seleccionar los nivèls mai basses. @@ -47,12 +45,8 @@ oc: setting_display_media_default: Rescondre los mèdias marcats coma sensibles setting_display_media_hide_all: Totjorn rescondre los mèdias setting_display_media_show_all: Totjorn mostrar los mèdias marcats coma sensibles - setting_hide_network: Vòstre perfil mostrarà pas los que vos sègon e lo mond que seguètz - setting_noindex: Aquò es destinat a vòstre perfil public e vòstra pagina d’estatuts - setting_show_application: Lo nom de l’aplicacion qu’utilizatz per publicar serà mostrat dins la vista detalhada de vòstres tuts setting_use_blurhash: Los degradats venon de las colors de l’imatge rescondut en enfoscar los detalhs setting_use_pending_items: Rescondre las actualizacions del flux d’actualitat aprèp un clic allòc de desfilar lo flux automaticament - username: Vòstre nom d’utilizaire serà unic sus %{domain} whole_word: Quand lo mot-clau o frasa es solament alfranumeric, serà pas qu’aplicat se correspond al mot complèt domain_allow: domain: Aqueste domeni poirà recuperar las donadas d’aqueste servidor estant e las donadas venent d’aqueste domeni seràn tractadas e gardadas @@ -119,7 +113,6 @@ oc: context: Contèxte del filtre current_password: Senhal actual data: Donadas - discoverable: Far aparéisser aqueste compte a l’annuari display_name: Escais email: Corrièl expires_in: Expira aprèp @@ -129,7 +122,6 @@ oc: inbox_url: URL de la bóstia de recepcion del relai irreversible: Suprimir allòc de rescondre locale: Lenga de l’interfàcia - locked: Far venir lo compte privat max_uses: Limit d’utilizacions new_password: Nòu senhal note: Biografia @@ -141,7 +133,6 @@ oc: setting_always_send_emails: Totjorn enviar los corrièls de notificacion setting_auto_play_gif: Lectura automatica dels GIFS animats setting_boost_modal: Mostrar una fenèstra de confirmacion abans de partejar un estatut - setting_crop_images: Retalhar los imatges dins los tuts pas desplegats a 16x9 setting_default_language: Lenga de publicacion setting_default_privacy: Confidencialitat dels tuts setting_default_sensitive: Totjorn marcar los mèdias coma sensibles @@ -153,9 +144,7 @@ oc: setting_display_media_show_all: O mostrar tot setting_expand_spoilers: Totjorn desplegar los tuts marcats amb un avertiment de contengut setting_hide_network: Amagar vòstre malhum - setting_noindex: Èsser pas indexat pels motors de recèrca setting_reduce_motion: Reduire la velocitat de las animacions - setting_show_application: Revelar lo nom de l’aplicacion utilizada per enviar de tuts setting_system_font_ui: Utilizar la polissa del sistèma setting_theme: Tèma del site setting_trends: Veire las tendéncias d’uèi diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml index b6d351cb22..a55a93556f 100644 --- a/config/locales/simple_form.pl.yml +++ b/config/locales/simple_form.pl.yml @@ -2,6 +2,14 @@ pl: simple_form: hints: + account: + discoverable: Twój profil i publiczne wpisy mogą być promowane lub polecane na Mastodonie i twój profil może być sugerowany innym użytkownikom. + display_name: Twoje imię lub pseudonim. + fields: Co ci się tylko podoba – twoja strona domowa, zaimki, wiek… + indexable: Twoje publiczne wpisy mogą pojawiać się w wynikach wyszukiwania w Mastodonie. Użytkownicy, którzy wchodzili w interakcje z twoimi wpisami będą mogli je znaleźć niezależnie od tego ustawienia. + note: 'Możesz @wspomnieć użytkowników albo #hasztagi.' + show_collections: Twoja lista obserwowanych i obserwujących będzie widoczna dla wszystkich. Użytkownicy których obserwujesz będą jednak o tym wiedzieli. + unlocked: Inni użytkownicy będą mogli cię obserwować bez proszenia o zgodę. Odznacz, jeżeli chcesz aprobować obserwujących ręcznie po przejrzeniu próśb o obserwowanie. account_alias: acct: Określ nazwę@domenę konta z którego chcesz się przenieść account_migration: @@ -37,14 +45,11 @@ pl: current_password: Ze względów bezpieczeństwa wprowadź hasło obecnego konta current_username: Aby potwierdzić, wprowadź nazwę użytkownika obecnego konta digest: Wysyłane tylko po długiej nieaktywności, jeżeli w tym czasie otrzymaleś jakąś wiadomość bezpośrednią - discoverable: Pozwala na odkrywanie twojego konta przez nieznajomych poprzez rekomendacje, popularne wpisy i inne funkcje email: Otrzymasz e-mail potwierdzający - fields: Możesz ustawić maksymalnie 4 niestandardowe pola wyświetlane jako tabela na Twoim profilu header: PNG, GIF lub JPG. Maksymalnie %{size}. Zostanie zmniejszony do %{dimensions}px inbox_url: Skopiuj adres ze strony głównej przekaźnika, którego chcesz użyć irreversible: Filtrowane wpisy znikną bezpowrotnie, nawet gdy filtr zostanie usunięty locale: Język interfejsu, wiadomości e-mail i powiadomieniach push - locked: Musisz akceptować prośby o możliwość obserwacji password: Użyj co najmniej 8 znaków phrase: Zostanie wykryte nawet, gdy znajduje się za ostrzeżeniem o zawartości scopes: Wybór API, do których aplikacja będzie miała dostęp. Jeżeli wybierzesz nadrzędny zakres, nie musisz wybierać jego elementów. @@ -54,12 +59,9 @@ pl: setting_display_media_default: Ukrywaj zawartość multimedialną oznaczoną jako wrażliwa setting_display_media_hide_all: Zawsze ukrywaj zawartość multimedialną setting_display_media_show_all: Zawsze pokazuj zawartość multimedialną - setting_hide_network: Informacje o tym, kto Cię obserwuje i kogo obserwujesz nie będą widoczne - setting_noindex: Wpływa na widoczność strony profilu i Twoich wpisów - setting_show_application: W informacjach o wpisie będzie widoczna informacja o aplikacji, z której został wysłany setting_use_blurhash: Gradienty są oparte na kolorach ukrywanej zawartości, ale uniewidaczniają wszystkie szczegóły setting_use_pending_items: Ukryj aktualizacje osi czasu za kliknięciem, zamiast automatycznego przewijania strumienia - username: Twoja nazwa użytkownika będzie niepowtarzalna na %{domain} + username: Możesz używać liter, cyfr i podkreślników whole_word: Jeśli słowo lub fraza składa się jedynie z liter lub cyfr, filtr będzie zastosowany tylko do pełnych wystąpień domain_allow: domain: Ta domena będzie mogła pobierać dane z serwera, a dane przychodzące z niej będą przetwarzane i przechowywane @@ -118,6 +120,9 @@ pl: sessions: otp: 'Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych:' webauthn: Jeżeli jest to klucz USB, upewnij się, że go włożyłeś i, jeśli to konieczne, naciśnij go. + settings: + indexable: Twój profil pojawi się w wynikach wyszukiwarek internetowych. + show_application: Ty zawsze widzisz program użyty do zamieszczenia. tag: name: Możesz zmieniać tylko wielkość liter, np. aby były bardziej widoczne user: @@ -131,12 +136,17 @@ pl: position: Wyższa rola decyduje o rozwiązywaniu konfliktów w pewnych sytuacjach. Niektóre działania mogą być wykonywane tylko na rolach z niższym priorytetem webhook: events: Wybierz zdarzenia do wysłania + template: Poskładaj zawartość JSON, podstawiając zmienne. Użyjemy domyślnej wartości, jeżeli pole zostawisz pustym. url: Dokąd będą wysłane zdarzenia labels: account: + discoverable: Udostępniaj profil i wpisy funkcjom odkrywania fields: name: Nazwa value: Zawartość + indexable: Pokaż publiczne wpisy w wynikach wyszukiwania + show_collections: Pokazuj na profilu listę obserwowanych i obserwujących + unlocked: Automatycznie przyjmuj nowych obserwujących account_alias: acct: Nazwa starego konta account_migration: @@ -174,7 +184,6 @@ pl: context: Filtruj zawartość current_password: Obecne hasło data: Dane - discoverable: Wyświetlaj ten profil w katalogu display_name: Widoczna nazwa email: Adres e-mail expires_in: Wygaśnie po @@ -184,7 +193,6 @@ pl: inbox_url: Adres skrzynki przekaźnika irreversible: Usuwaj zamiast ukrywać locale: Język interfejsu - locked: Ustaw konto jako prywatne max_uses: Maksymalna liczba użyć new_password: Nowe hasło note: Biogram @@ -196,7 +204,6 @@ pl: setting_always_send_emails: Zawsze wysyłaj powiadomienia e-mail setting_auto_play_gif: Automatycznie odtwarzaj animowane GIFy setting_boost_modal: Pytaj o potwierdzenie przed podbiciem - setting_crop_images: Przycinaj obrazki w nierozwiniętych wpisach do 16x9 setting_default_language: Język wpisów setting_default_privacy: Widoczność wpisów setting_default_sensitive: Zawsze oznaczaj zawartość multimedialną jako wrażliwą @@ -208,9 +215,7 @@ pl: setting_display_media_show_all: Pokaż wszystko setting_expand_spoilers: Zawsze rozwijaj wpisy oznaczone ostrzeżeniem o zawartości setting_hide_network: Ukryj swoją sieć - setting_noindex: Nie indeksuj mojego profilu w wyszukiwarkach internetowych setting_reduce_motion: Ogranicz ruch w animacjach - setting_show_application: Informuj o aplikacji z której wysłano wpisy setting_system_font_ui: Używaj domyślnej czcionki systemu setting_theme: Motyw strony setting_trends: Pokazuj dzisiejsze „Na czasie” @@ -285,17 +290,27 @@ pl: mention: Powiadamiaj mnie e-mailem, gdy ktoś o mnie wspomni pending_account: Wyślij e-mail kiedy nowe konto potrzebuje recenzji reblog: Powiadamiaj mnie e-mailem, gdy ktoś podbije mój wpis - report: Nowy raport został wysłany + report: Nowe zgłoszenie zostało wysłane + software_updates: + all: Powiadamiaj o wszystkich aktualizacjach + critical: Powiadamiaj tylko o aktualizacjach krytycznych + label: Dostępna nowa wersja Mastodona + none: Nigdy nie powiadamiaj o aktualizacjach (niezalecane) + patch: Powiadamiaj o aktualizacjach naprawiających błędy trending_tag: Nowe popularne wymagają przeglądu rule: text: Zasada + settings: + indexable: Udostępniaj profil wyszukiwarkom + show_application: Pokazuj program z którego zamieszczasz wpisy tag: listable: Pozwól, aby ten hashtag pojawiał się w wynikach wyszukiwania i katalogu profilów - name: Hashtag + name: Hasztag trendable: Pozwól na wyświetlanie tego hashtagu w „Na czasie” usable: Pozwól na umieszczanie tego hashtagu we wpisach user: role: Rola + time_zone: Strefa czasowa user_role: color: Kolor odznaki highlighted: Wyświetl rolę jako odznakę na profilach użytkowników @@ -304,9 +319,11 @@ pl: position: Priorytet webhook: events: Włączone zdarzenia + template: Szablon zawartości url: Endpoint URL 'no': Nie not_recommended: Niezalecane + overridden: Nadpisane recommended: Polecane required: mark: "*" diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index 02e317ab6e..1c303c0dae 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -2,6 +2,14 @@ pt-BR: simple_form: hints: + account: + discoverable: Suas publicações e perfil públicos podem ser destaques ou recomendados em várias áreas de Mastodon, e seu perfil pode ser sugerido a outros usuários. + display_name: Seu nome completo ou apelido. + fields: Sua página inicial, pronomes, idade ou qualquer coisa que quiser. + indexable: Suas publicações públicas podem aparecer nos resultados da pesquisa em Mastodon. As pessoas que interagiram com suas publicações podem conseguir pesquisá-las independentemente disso. + note: 'Você pode @mencionar outras pessoas ou #hashtags.' + show_collections: As pessoas poderão navegar entre os seus seguidores e seguidores. As pessoas que você segue verão que você as segue independentemente disso. + unlocked: As pessoas poderão te seguir sem pedir aprovação. Desmarque se você deseja revisar pedidos e escolher se aceita ou rejeita novos seguidores. account_alias: acct: Especifique o usuário@domínio de onde veio account_migration: @@ -37,14 +45,11 @@ pt-BR: current_password: Para fins de segurança, digite a senha da conta atual current_username: Para confirmar, digite o nome de usuário da conta atual digest: Enviado apenas após um longo período de inatividade com um resumo das menções recebidas durante ausência - discoverable: Permita que a sua conta seja descoberta por estranhos através de recomendações, tendências e outros recursos email: Você receberá um e-mail de confirmação - fields: Você pode ter até 4 itens mostrados em forma de tabela no seu perfil header: PNG, GIF ou JPG de até %{size}. Serão redimensionados para %{dimensions}px inbox_url: Copie o link da página inicial do repetidor que você deseja usar irreversible: As publicações filtradas desaparecerão irreversivelmente, mesmo se o filtro for removido depois locale: O idioma da interface do usuário, e-mails e notificações - locked: Requer aprovação manual de seguidores 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. @@ -54,12 +59,9 @@ pt-BR: setting_display_media_default: Sempre ocultar mídia sensível setting_display_media_hide_all: Sempre ocultar todas as mídias setting_display_media_show_all: Sempre mostrar mídia sensível - setting_hide_network: Quem você segue e seus seguidores não serão mostrados no seu perfil - setting_noindex: Afeta seu perfil público e as páginas das suas publicações - setting_show_application: O aplicativo que você usar para publicar será exibido na visão detalhada das suas publicações 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 - username: Seu nome de usuário será único em %{domain} + username: Você pode usar letras, números e underlines whole_word: Quando a palavra-chave ou frase é inteiramente alfanumérica, ela será aplicada somente se corresponder a palavra inteira domain_allow: domain: Este domínio poderá obter dados deste servidor e os dados recebidos dele serão processados e armazenados @@ -91,11 +93,13 @@ pt-BR: site_short_description: Uma curta descrição para ajudar unicamente a identificar a sua instância. Quem está o administrando, e para quem é direcionado? site_terms: Use a sua própria política de privacidade ou deixe em branco para usar o padrão. Pode ser estruturado com o formato Markdown. site_title: Como as pessoas podem se referir ao seu servidor além do nome do domínio. + status_page_url: URL de uma página onde as pessoas podem ver o status deste servidor durante uma interrupção theme: Tema que visitantes e novos usuários veem. thumbnail: Uma imagem de aproximadamente 2:1 exibida ao lado da informação de sua instância. timeline_preview: Visitantes conseguirão navegar pelas postagens públicas mais recentes disponíveis na instância. trendable_by_default: Pular a revisão manual do conteúdo em tendência. Itens individuais ainda poderão ser removidos das tendências após a sua exibição. trends: Tendências mostram quais publicações, hashtags e notícias estão ganhando destaque na sua instância. + trends_as_landing_page: Mostrar conteúdo de tendências para usuários deslogados e visitantes em vez de uma descrição deste servidor. Requer que as tendências sejam ativadas. form_challenge: current_password: Você está entrando em uma área segura imports: @@ -116,6 +120,9 @@ pt-BR: sessions: otp: 'Digite o código de dois fatores gerado pelo aplicativo no seu celular ou use um dos códigos de recuperação:' webauthn: Se for uma chave USB tenha certeza de inseri-la e, se necessário, tocar nela. + settings: + indexable: Sua página de perfil pode aparecer nos resultados de pesquisa no Google, Bing e outros. + show_application: Você sempre conseguirá ver qual aplicativo realizou sua publicação independentemente disso. tag: name: Você pode mudar a capitalização das letras, por exemplo, para torná-la mais legível user: @@ -129,12 +136,17 @@ pt-BR: position: Um cargo superior decide a resolução de conflitos em certas situações. Certas ações só podem ser executadas com cargos de menor prioridade webhook: events: Selecione eventos para enviar + template: Elabore seu próprio conteúdo JSON usando interpolação de variáveis. Deixe em branco para utilizar o JSON padrão. url: Aonde os eventos serão enviados labels: account: + discoverable: Destacar perfil e publicações nos algoritmos de descoberta fields: name: Rótulo value: Conteúdo + indexable: Incluir publicações abertas nos resultados da pesquisa + show_collections: Mostrar quem segue e seguidores no perfil + unlocked: Aceitar automaticamente novos seguidores account_alias: acct: Nome de usuário da conta antiga account_migration: @@ -172,7 +184,6 @@ pt-BR: context: Contextos do filtro current_password: Senha atual data: Dados - discoverable: Mostrar conta no diretório de perfis display_name: Nome de exibição email: E-mail expires_in: Expira em @@ -182,7 +193,6 @@ pt-BR: inbox_url: Link da caixa de entrada do repetidor irreversible: Ignorar ao invés de ocultar locale: Idioma da interface - locked: Trancar perfil max_uses: Limite de uso new_password: Nova senha note: Biografia @@ -194,7 +204,6 @@ pt-BR: setting_always_send_emails: Sempre enviar notificações por e-mail setting_auto_play_gif: Reproduzir GIFs automaticamente setting_boost_modal: Solicitar confirmação antes de dar boost - setting_crop_images: Cortar imagens no formato 16x9 em publicações não expandidas setting_default_language: Idioma dos toots setting_default_privacy: Privacidade dos toots setting_default_sensitive: Sempre marcar mídia como sensível @@ -206,9 +215,7 @@ pt-BR: setting_display_media_show_all: Mostrar tudo setting_expand_spoilers: Sempre expandir toots com Aviso de Conteúdo setting_hide_network: Ocultar suas relações - setting_noindex: Não quero ser indexado por mecanismos de pesquisa setting_reduce_motion: Reduzir animações - setting_show_application: Mostrar o aplicativo usado para enviar as publicações setting_system_font_ui: Usar fonte padrão do sistema setting_theme: Tema do site setting_trends: Mostrar em alta hoje @@ -251,11 +258,13 @@ pt-BR: site_short_description: Descrição do servidor site_terms: Política de privacidade site_title: Nome do servidor + status_page_url: Endereço da página de status theme: Tema padrão thumbnail: Miniatura do servidor timeline_preview: Permitir acesso não autenticado às linhas do tempo públicas trendable_by_default: Permitir tendências sem revisão prévia trends: Habilitar tendências + trends_as_landing_page: Usar tendências como página inicial interactions: must_be_follower: Bloquear notificações de não-seguidores must_be_following: Bloquear notificações de não-seguidos @@ -282,9 +291,18 @@ pt-BR: pending_account: Enviar e-mail quando uma nova conta precisa ser revisada reblog: Enviar e-mail quando alguém der boost nos teus toots report: Nova denúncia foi enviada + software_updates: + all: Notificar sobre todas as atualizações + critical: Notificar apenas sobre atualizações críticas + label: Uma nova versão do Mastodon está disponível + none: Nunca notificar sobre atualizações (não recomendado) + patch: Notificar sobre atualizações de correções trending_tag: Uma nova tendência requer revisão rule: text: Regra + settings: + indexable: Incluir página de perfil nos motores de busca + show_application: Exibir a partir de qual aplicativo você publicou tag: listable: Permitir que esta hashtag apareça em pesquisas e sugestões name: Hashtag @@ -292,6 +310,7 @@ pt-BR: usable: Permitir que toots usem esta hashtag user: role: Cargo + time_zone: Fuso horário user_role: color: Cor do emblema highlighted: Exibir cargo como distintivo nos perfis de usuários @@ -300,9 +319,11 @@ pt-BR: position: Prioridade webhook: events: Eventos habilitados + template: Conteúdo JSON url: URL do Endpoint 'no': Não not_recommended: Não recomendado + overridden: Sobreposto recommended: Recomendado required: mark: "*" diff --git a/config/locales/simple_form.pt-PT.yml b/config/locales/simple_form.pt-PT.yml index 4e34c5897b..691ecec3a0 100644 --- a/config/locales/simple_form.pt-PT.yml +++ b/config/locales/simple_form.pt-PT.yml @@ -2,6 +2,14 @@ pt-PT: simple_form: hints: + account: + discoverable: As suas publicações e perfil públicos podem ser destacados ou recomendados em várias áreas do Mastodon e o seu perfil pode ser sugerido a outros utilizadores. + display_name: O seu nome completo ou o seu nome divertido. + fields: A sua página inicial, os seus pronomes, idade e tudo o que quiser. + indexable: As suas mensagens públicas podem aparecer nos resultados da pesquisa no Mastodon. Independentemente disso, as pessoas que interagiram com as suas publicações podem ser capazes de as pesquisar. + note: 'Pode @mencionar outras pessoas ou #hashtags.' + show_collections: As pessoas podem navegar pelas listas das pessoas que segue e dos seus seguidores. Independentemente disso, as pessoas que segue verão que você as segue. + unlocked: As pessoas podem segui-lo/a sem pedir a sua aprovação. Desmarque se quiser rever os pedidos para seguir e escolher se aceita ou rejeita os novos seguidores. account_alias: acct: Especifique o utilizador@domínio da conta de onde você deseja migrar account_migration: @@ -37,14 +45,11 @@ pt-PT: current_password: Para fins de segurança, queira inserir a palavra-passe da conta atual current_username: Para confirmar, queira inserir o nome de utilizador da conta atual digest: Enviado após um longo período de inatividade e apenas se foste mencionado na tua ausência - discoverable: Permitir que a sua conta seja descoberta por outros através de recomendações, destaques e outras funções email: Será enviado um e-mail de confirmação - fields: Pode ter até 4 elementos expostos, em forma de tabela, no seu perfil header: PNG, GIF ou JPG. Ficheiros no máximo de %{size}. Serão reduzidos para %{dimensions}px inbox_url: Copie o URL da página inicial do repetidor que quer usar irreversible: Publicações filtradas irão desaparecer irremediavelmente, mesmo que o filtro seja removido posteriormente - locale: A língua da interface de utilizador, e-mails e notificações push - locked: Requer aprovação manual de seguidores + locale: O idioma da interface de utilizador, e-mails e notificações push password: Use pelo menos 8 caracteres phrase: Será correspondido independentemente da capitalização ou do aviso de conteúdo duma publicação scopes: Quais as API a que será concedido acesso. Se escolher uma abrangência de nível superior, não precisará de as seleccionar individualmente. @@ -54,12 +59,9 @@ pt-PT: setting_display_media_default: Esconder media marcada como problemática setting_display_media_hide_all: Esconder sempre toda a media setting_display_media_show_all: Mostrar sempre a media - setting_hide_network: Quem tu segues e quem te segue não será mostrado no teu perfil - setting_noindex: Afecta o teu perfil público e as páginas das tuas publicações - setting_show_application: A aplicação que usa para publicar será mostrada na vista pormenorizada das suas publicações setting_use_blurhash: Os gradientes são baseados nas cores das imagens escondidas, mas ofuscam quaisquer pormenores setting_use_pending_items: Ocultar atualizações da cronologia por detrás dum clique, em vez de rolar automaticamente o fluxo - username: O teu nome de utilizador será único em %{domain} + username: Pode utilizar letras, números e sublinhados whole_word: Quando a palavra-chave ou expressão-chave é somente alfanumérica, ela só será aplicada se corresponder à palavra completa domain_allow: domain: Este domínio será capaz de obter dados desta instância e os dados dele recebidos serão processados e armazenados @@ -118,10 +120,13 @@ pt-PT: sessions: otp: 'Insira o código de autenticação em duas etapas gerado pelo seu telemóvel ou use um dos seus códigos de recuperação:' webauthn: Se for uma chave USB tenha certeza de inseri-la e, se necessário, toque nela. + settings: + indexable: A sua página de perfil pode aparecer nos resultados de pesquisa no Google, Bing e outros. + show_application: Independentemente disso será sempre capaz de ver em que aplicação publicou a sua mensagem. tag: name: Só pode alterar a capitalização das letras, por exemplo, para torná-las mais legíveis user: - chosen_languages: Quando seleccionado, só publicações nas línguas escolhidas serão mostradas nas cronologias públicas + chosen_languages: Quando seleccionado, só serão mostradas nas cronologias públicas as publicações nos idiomas escolhidos role: A função controla que permissões o utilizador tem user_role: color: Cor a ser utilizada para a função em toda a interface de utilizador, como RGB no formato hexadecimal @@ -131,12 +136,17 @@ pt-PT: position: Cargos mais altos decidem a resolução de conflitos em certas situações. Certas ações só podem ser executadas em cargos com uma menor prioridade webhook: events: Selecione os eventos a enviar + template: Componha o seu próprio conteúdo JSON utilizando a interpolação de variáveis. Deixar em branco para o JSON predefinido. url: Para onde os eventos serão enviados labels: account: + discoverable: Destacar perfil e publicações nos algoritmos de descoberta fields: name: Rótulo value: Conteúdo + indexable: Incluir mensagens públicas nos resultados da pesquisa + show_collections: Mostrar quem sigo e os meus seguidores no perfil + unlocked: Aceitar automaticamente novos seguidores account_alias: acct: Nome de utilizador da conta antiga account_migration: @@ -168,13 +178,12 @@ pt-PT: autofollow: Convidar para seguir a tua conta avatar: Imagem de perfil bot: Esta é uma conta robô - chosen_languages: Filtrar línguas + chosen_languages: Filtrar idiomas confirm_new_password: Confirmar nova palavra-passe confirm_password: Confirmar palavra-passe context: Filtrar contextos current_password: Palavra-passe actual data: Dados - discoverable: Sugerir esta conta a outros display_name: Nome a apresentar email: Endereço de correio electrónico expires_in: Expira em @@ -183,8 +192,7 @@ pt-PT: honeypot: "%{label} (não preencher)" inbox_url: URL da caixa de entrada do repetidor irreversible: Expandir em vez de esconder - locale: Língua da interface - locked: Exigir pedidos de seguimento + locale: Idioma da interface max_uses: Número máximo de utilizações new_password: Nova palavra-passe note: Biografia @@ -196,8 +204,7 @@ pt-PT: setting_always_send_emails: Enviar sempre notificações de email setting_auto_play_gif: Reproduzir GIF automaticamente setting_boost_modal: Solicitar confirmação antes de partilhar uma publicação - setting_crop_images: Recortar imagens para o formato 16x9 nas publicações não expandidas - setting_default_language: Língua de publicação + setting_default_language: Idioma de publicação setting_default_privacy: Privacidade da publicação setting_default_sensitive: Marcar sempre os media como problemáticos setting_delete_modal: Solicitar confirmação antes de eliminar uma publicação @@ -208,9 +215,7 @@ pt-PT: setting_display_media_show_all: Mostrar todos setting_expand_spoilers: Expandir sempre as publicações marcadas com avisos de conteúdo setting_hide_network: Esconder a tua rede - setting_noindex: Não quero ser indexado por motores de pesquisa setting_reduce_motion: Reduz movimento em animações - setting_show_application: Revelar sempre qual a aplicação usada para enviar as publicações setting_system_font_ui: Usar o tipo de letra padrão do sistema setting_theme: Tema do sítio setting_trends: Mostrar o que está hoje em alta @@ -286,9 +291,18 @@ pt-PT: pending_account: Uma nova conta aguarda aprovação reblog: Alguém reforçou uma publicação sua report: Uma nova denúncia foi submetida + software_updates: + all: Notificar todas as atualizações + critical: Notificar apenas atualizações críticas + label: Está disponível uma nova versão do Mastodon + none: Nunca notificar atualizações (não recomendado) + patch: Notificar sobre atualizações de correções de problemas trending_tag: Uma nova publicação em alta requer avaliação rule: text: Regra + settings: + indexable: Incluir página de perfil nos motores de busca + show_application: Mostrar de que aplicação criou uma publicação tag: listable: Permitir que esta etiqueta apareça em pesquisas e no diretório de perfis name: Etiqueta @@ -296,6 +310,7 @@ pt-PT: usable: Permitir que as publicações usem esta etiqueta user: role: Cargo + time_zone: Fuso horário user_role: color: Cor do emblema highlighted: Apresentar o cargo como emblema nos perfis de utilizador @@ -304,9 +319,11 @@ pt-PT: position: Prioridade webhook: events: Eventos ativados + template: Modelo de conteúdo url: URL do Endpoint 'no': Não not_recommended: Não recomendado + overridden: Substituído recommended: Recomendado required: mark: "*" diff --git a/config/locales/simple_form.ro.yml b/config/locales/simple_form.ro.yml index 6ed4905db9..cade572f38 100644 --- a/config/locales/simple_form.ro.yml +++ b/config/locales/simple_form.ro.yml @@ -30,12 +30,10 @@ ro: current_username: Pentru a confirma, vă rugăm să introduceţi numele de utilizator al contului curent digest: Este trimis doar după o lungă perioadă de inactivitate și numai dacă primești mesaje personale în perioada de absență email: Vei primi un e-mail de confirmare - fields: Poti afișa pană la maxim 4 adrese sub formă de tabel pe pofilul tău header: PNG, GIF sau JPG. Cel mult %{size}. Vor fi redimensionate la %{dimensions}px inbox_url: Copiază adresa URL de pe prima pagină a reului pe care vrei să îl utilizezi irreversible: Postările sortate vor dispărea ireversibil, chiar dacă filtrul este ulterior șters locale: Limba interfaței de utilizator, e-mailurile si notificările push - locked: Necesită aprobare manuală a urmăritorilor password: Utilizează cel puțin 8 caractere phrase: Vor fi potrivite indiferent de textul din casetă sau advertismentul unei postări scopes: La care API-uri aplicația are nevoie de acces. Dacă selectezi un scop principal nu mai e nevoie să selectezi fiecare sub-scop al acestuia. @@ -44,12 +42,8 @@ ro: setting_display_media_default: Ascunde conținutul media marcat ca sensibil (NSFW) setting_display_media_hide_all: Întotdeauna ascunde tot conținutul media setting_display_media_show_all: Întotdeauna afișează conținutul media marcat ca sensibil - setting_hide_network: Pe cine urmărești și cine te urmărește nu vor fi afișați pe profilul tău - setting_noindex: Afecteazâ profilul tău public și statusurile tale - setting_show_application: Aplicația pe care o utilizați pentru a posta va fi afișată în vizualizarea detaliată a postărilor setting_use_blurhash: Gradienții sunt bazați pe culorile vizualelor ascunse, dar ofuscă orice detalii setting_use_pending_items: Ascunde actualizările cronologice din spatele unui click în loc de a derula automat fluxul - username: Numele tău de utilizator va fi unic pe %{domain} whole_word: Când fraza sau cuvântul este doar alfanumeric, acesta se aplică doar dacă există o potrivire completă domain_allow: domain: Acest domeniu va putea prelua date de pe acest server și datele primite de la el vor fi procesate și stocate @@ -106,7 +100,6 @@ ro: context: Contextele filtrului current_password: Parola actuală data: Date - discoverable: Listează acest cont in director display_name: Numele afișat email: Adresa de e-mail expires_in: Expiră după @@ -115,7 +108,6 @@ ro: inbox_url: Adresa URL a inbox-ului irreversible: Lasă înloc să ascunzi locale: Limbă - locked: Cont Privat max_uses: Numărul maxim de utilizatori new_password: Parola nouă note: Descriere @@ -126,7 +118,6 @@ ro: setting_aggregate_reblogs: Grupează impulsurile în fluxuri setting_auto_play_gif: Redă automat animațiile GIF setting_boost_modal: Arată dialogul de confirmare înainte de a impulsiona - setting_crop_images: Decupează imaginile în postările non-extinse la 16x9 setting_default_language: În ce limbă postezi setting_default_privacy: Cine vede postările tale setting_default_sensitive: Întotdeauna marchează conținutul media ca fiind sensibil @@ -137,9 +128,7 @@ ro: setting_display_media_show_all: Arată toate setting_expand_spoilers: Întotdeauna extinde postările marcate cu avertismente referitoare la conținut setting_hide_network: Ascunde rețeaua - setting_noindex: Nu permite motoarelor de căutare să indexeze rețeaua ta setting_reduce_motion: Redu mișcarea în animații - setting_show_application: Dezvăluie aplicația folosită pentru a trimite postări setting_system_font_ui: Utilizează fontul standard as sistemului setting_theme: Tema siteului setting_trends: Arată tendințele de astăzi diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml index 7e23edf7dd..2d82a66358 100644 --- a/config/locales/simple_form.ru.yml +++ b/config/locales/simple_form.ru.yml @@ -2,12 +2,20 @@ ru: simple_form: hints: + account: + discoverable: Ваши публичные сообщения и профиль могут быть показаны или рекомендованы в различных разделах Mastodon, и ваш профиль может быть предложен другим пользователям. + display_name: Ваше полное имя или псевдоним. + fields: Ваша домашняя страница, местоимения, возраст - все, что угодно. + indexable: Ваши публичные сообщения могут появляться в результатах поиска на Mastodon. Люди, которые взаимодействовали с вашими сообщениями, могут искать их независимо от этого. + note: 'Вы можете @упоминать других людей или #хэштеги.' + show_collections: Люди смогут просматривать список ваших подписок и подписчиков. Люди, за которыми вы следуете, будут видеть, что вы подписаны на них, несмотря ни на что. + unlocked: Люди смогут подписываться на вас, не запрашивая подтверждения. Снимите флажок, если вы хотите просматривать запросы на подписку и выбирать, принимать или отклонять новых подписчиков. account_alias: - acct: Укажите ник@домен учётной записи, с которой вы собираетесь мигрировать + acct: Укажите имя_пользователя@домен учётной записи, с которой вы собираетесь мигрировать account_migration: acct: Укажите имя_пользователя@домен учётной записи, на которую вы собираетесь мигрировать account_warning_preset: - text: Вы можете использовать всё, что в обычных постах — ссылки, хэштеги, упоминания и т.д. + text: Можно использовать синтаксис сообщений, например URL, хэштеги и упоминания title: Необязательно. Не видно получателю admin_account_action: include_statuses: Пользователь будет видеть к каким постами применялись модераторские действия и выносились предупреждения @@ -37,14 +45,11 @@ ru: current_password: В целях безопасности введите пароль текущей учётной записи current_username: Для подтверждения, пожалуйста, введите имя пользователя текущей учётной записи digest: Если вы долго не заглядывали, отправим вам дайджест событий, которые происходили в период вашего отсутствия. - discoverable: Разрешить другим людям находить ваш профиль через рекомендации, тренды и другие функции. email: Вам будет отправлено электронное письмо с подтверждением. - fields: В профиле можно отобразить до 4 пунктов в виде таблицы. Например, ваши местоимения, часовой пояс или ссылку на свой сайт. header: Поддерживается PNG, GIF и JPG. Максимальный размер — %{size}. Будет уменьшена до %{dimensions}px. inbox_url: Копировать URL с главной страницы ретранслятора, который вы хотите использовать irreversible: Отфильтрованные посты будут утеряны навсегда, даже если в будущем фильтр будет убран locale: Язык интерфейса, e-mail писем и push-уведомлений - locked: Вручную контролируйте, кто может подписываться на вас, утверждая запросы на подписку password: Укажите не менее 8 символов. phrase: Будет сопоставлено независимо от присутствия в тексте или предупреждения о содержании поста scopes: Какие API приложению будет позволено использовать. Если вы выберете самый верхний, нижестоящие будут выбраны автоматически. @@ -54,12 +59,9 @@ ru: setting_display_media_default: Скрывать файлы «деликатного характера» setting_display_media_hide_all: Всегда скрывать любые медиафайлы setting_display_media_show_all: Всегда показывать любые медиафайлы - setting_hide_network: Другие не смогут видеть ни ваши подписки, ни ваших подписчиков. - setting_noindex: Ваш публичный профиль и публикации будут скрыты от поисковых систем. - setting_show_application: При просмотре поста будет видно из какого приложения он отправлен. setting_use_blurhash: Градиенты основаны на цветах скрытых медиа, но скрывают любые детали. setting_use_pending_items: Показывать обновления в ленте только после клика вместо автоматической прокрутки. - username: Ваше имя пользователя будет уникальным на %{domain} + username: Вы можете использовать буквы, цифры и знаки подчеркивания whole_word: Если слово или фраза состоит только из букв и цифр, сопоставление произойдёт только по полному совпадению domain_allow: domain: Этот домен сможет получать данные с этого сервера и его входящие данные будут обрабатываться и сохранены @@ -118,6 +120,9 @@ ru: sessions: otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из ваших кодов восстановления:' webauthn: Если это ключ USB, не забудьте его вставить и, при необходимости, нажмите на него. + settings: + indexable: Страница вашего профиля может отображаться в результатах поиска Google, Bing и других поисковых системах. + show_application: Вы всегда сможете увидеть, какое приложение опубликовало ваше сообщение. tag: name: Вы можете изменить только регистр букв чтобы, например, сделать тег более читаемым user: @@ -131,12 +136,17 @@ ru: position: Повышение роли разрешают конфликты интересов в некоторых ситуациях. Некоторые действия могут выполняться только на ролях с более низким приоритетом webhook: events: Выберите события для отправки + template: Составьте собственную полезную нагрузку JSON с использованием интерполяции переменных. Оставьте поле пустым для стандартного JSON. url: Куда события будут отправляться labels: account: + discoverable: Профиль и сообщения в алгоритмах обнаружения fields: name: Пункт value: Значение + indexable: Включить публичные сообщения в результаты поиска + show_collections: Показать подписки и подписчиков в профиле + unlocked: Автоматически принимать новых подписчиков account_alias: acct: Имя старой учётной записи account_migration: @@ -174,7 +184,6 @@ ru: context: Контекст фильтра current_password: Текущий пароль data: Данные - discoverable: Рекомендовать учётную запись другим пользователям display_name: Отображаемое имя email: Адрес e-mail expires_in: Истекает через @@ -184,7 +193,6 @@ ru: inbox_url: URL для входящих от ретрансляторов irreversible: Удалять, а не скрывать locale: Язык интерфейса - locked: Сделать учётную запись закрытой max_uses: Максимальное кол-во использований new_password: Новый пароль note: О себе @@ -196,7 +204,6 @@ ru: setting_always_send_emails: Всегда отправлять уведомления по электронной почте setting_auto_play_gif: Автоматически проигрывать GIF анимации setting_boost_modal: Всегда спрашивать перед продвижением - setting_crop_images: Кадрировать изображения в нераскрытых постах до 16:9 setting_default_language: Язык публикуемых постов setting_default_privacy: Видимость постов setting_default_sensitive: Всегда отмечать медиафайлы как «деликатного характера» @@ -208,9 +215,7 @@ ru: setting_display_media_show_all: Показывать все setting_expand_spoilers: Всегда раскрывать посты, имеющие предупреждение о содержании setting_hide_network: Скрыть свои связи - setting_noindex: Отказаться от индексации в поисковых машинах setting_reduce_motion: Уменьшить движение в анимации - setting_show_application: Указывать приложение, с которого отправлен пост setting_system_font_ui: Использовать шрифт системы по умолчанию setting_theme: Тема сайта setting_trends: Показывать сегодняшние тренды @@ -286,9 +291,18 @@ ru: pending_account: Новая заявка на создание аккаунта reblog: Ваш пост продвинули report: Новое обращение отправлено + software_updates: + all: Уведомлять о всех обновлениях + critical: Уведомлять только о критических обновлениях + label: Доступна новая версия Mastodon + none: Никогда не уведомлять об обновлениях (не рекомендуется) + patch: Уведомлять об обновлении исправлений trending_tag: Новый тренд требует рассмотрения rule: text: Правило + settings: + indexable: Включить страницу профиля в поисковые системы + show_application: Отображать, из какого приложения вы отправили сообщение tag: listable: Разрешить показ хэштега в поиске или в каталоге профилей name: Хэштег @@ -296,6 +310,7 @@ ru: usable: Разрешить использовать этот хэштег в постах user: role: Роль + time_zone: Часовой пояс user_role: color: Цвет значка highlighted: Отображать роль в качестве значка в профилях пользователей @@ -304,10 +319,12 @@ ru: position: Приоритет webhook: events: Включенные события + template: Шаблон полезной нагрузки url: Endpoint URL 'no': Нет not_recommended: Не рекомендуется - recommended: Рекомендуем + overridden: Переопределено + recommended: Рекомендуется required: mark: "*" text: обязательно diff --git a/config/locales/simple_form.sc.yml b/config/locales/simple_form.sc.yml index 56638352a8..2c47259961 100644 --- a/config/locales/simple_form.sc.yml +++ b/config/locales/simple_form.sc.yml @@ -34,12 +34,10 @@ sc: current_username: Pro cunfirmare inserta su nòmine utente de su contu atuale digest: Imbiadu isceti a pustis de unu perìodu longu de inatividade, e isceti si as retzidu calicunu messàgiu personale cando non bi fias email: As a retzire unu messàgiu eletrònicu de cunfirma - fields: Podes tènnere finas a 4 elementos ammustrados in una tabella in su profilu tuo header: PNG, GIF o JPG. Màssimu %{size}. Ant a èssere iscaladas a %{dimensions}px inbox_url: Còpia s'URL dae sa pàgina printzipale de su ripetidore chi boles impreare irreversible: Is tuts filtrados ant a isparèssere in manera irreversìbile, fintzas si prus a tardu s'at a bogare su filtru locale: S'idioma de s'interfache de s'utente, de is messàgios de posta eletrònica e de is notìficas push - locked: Gesti a manu chie ti podet sighire aprovende a manu is sighiduras password: Imprea a su mancu 8 caràteres phrase: At a cuncordare sena cunsiderare is minùsculas e is majùsculas o is avisos de cuntenutu scopes: A ite API s'aplicatzione at a pòdere atzèdere. Si seletzionas un'àmbitu de su livellu prus artu, non serbit a nde seletzionare de sìngulos. @@ -48,12 +46,8 @@ sc: setting_display_media_default: Cua elementos multimediales marcados comente sensìbiles setting_display_media_hide_all: Cua semper is elementos multimediales setting_display_media_show_all: Ammustra semper is elementos multimediales - setting_hide_network: Sa gente chi sighis o chi ti sighit no at a èssere ammustrada in su profilu tuo - setting_noindex: Tenet efetu in su profilu pùblicu tuo e in is pàginas de is istados - setting_show_application: S'aplicatzione chi impreas pro publicare tuts at a èssere ammustrada in sa visualizatzione de detàlliu de is tuts setting_use_blurhash: Is gradientes sunt basados in subra de is colores de is immàgines cuadas ma imbelant totu is detàllios setting_use_pending_items: Cua is atualizatziones in segus de un'incarcu imbetzes de iscùrrere in automàticu su flussu de publicatziones - username: Su nòmine de utente tuo at a èssere ùnicu in %{domain} whole_word: Cando sa crae (faeddu o fràsia) siat isceti alfanumèrica, s'at a aplicare isceti si currispondet a su faeddu intreu domain_allow: domain: Custu domìniu at a pòdere recuperare datos dae custu serbidore e is datos in intrada dae cue ant a èssere protzessados e archiviados @@ -122,7 +116,6 @@ sc: context: Filtra cuntestos current_password: Crae atuale data: Data - discoverable: Cussìgia custu contu a àtere display_name: Nòmine visìbile email: Indiritzu de posta eletrònica expires_in: Iscadit a pustis de @@ -132,7 +125,6 @@ sc: inbox_url: URL de sa cartella de intrada de su ripetidore irreversible: Cantzella imbetzes de cuare locale: Idioma de s'interfache - locked: Rechede rechestas de sighidura max_uses: Nùmeru màssimu de impreos new_password: Crae noa note: Biografia @@ -143,7 +135,6 @@ sc: setting_aggregate_reblogs: Agrupa is cumpartziduras in is lìnias de tempus setting_auto_play_gif: Riprodui is GIF animadas in automàticu setting_boost_modal: Ammustra unu diàlogu de cunfirma in antis de cumpartzire - setting_crop_images: Retàllia a 16x9 is immàgines de is tuts no ismanniados setting_default_language: Idioma de publicatzione setting_default_privacy: Riservadesa de is publicatziones setting_default_sensitive: Marca semper is elementos multimediales comente sensìbiles @@ -155,9 +146,7 @@ sc: setting_display_media_show_all: Ammustra totu setting_expand_spoilers: Ismànnia semper is tuts marcados cun avisos de cuntenutu setting_hide_network: Cua sa retza tua - setting_noindex: Pedi de non ti fàghere inditzizare dae is motores de chirca setting_reduce_motion: Mìnima su movimentu in is animatziones - setting_show_application: Rivela s'aplicatzione impreada pro imbiare tuts setting_system_font_ui: Imprea sa tipografia predefinida de su sistema setting_theme: Tema de su situ setting_trends: Ammustra is tendèntzias de oe diff --git a/config/locales/simple_form.sco.yml b/config/locales/simple_form.sco.yml index 0dc4fdd797..85fa66ddc9 100644 --- a/config/locales/simple_form.sco.yml +++ b/config/locales/simple_form.sco.yml @@ -35,14 +35,11 @@ sco: current_password: Fir security purposes please pit in the passwird o the current accoont current_username: Fir tae confirm, please pit in the uisernemm o the current accoont digest: Ainly sent efter a lang whilie o inactivity an ainly if ye'v gotten onie personal messages whilst ye wis awa - discoverable: Alloo yer accoont fir tae get discovert bi strangers throu recommendations, trends an ither features email: Ye'll be sent a confirmation email - fields: Ye kin hae up tae 4 items displayed as a table on yer profile header: PNG, GIF or JPG. At maist %{size}. Wull get doonscaled tae %{dimensions}px inbox_url: Copy the URL fae the frontpage o the relay thit ye'r wantin tae uise irreversible: Filtert posts wull dizappear irreversibly, even if filter is taen aff efter locale: The leid o the uiser interface, emails an push notes - locked: Control bi haun wha kin follae ye bi approvin follae requests password: Uise at least 8 chairecters phrase: Wull get matched regairdless o case in text or content warnin o a post scopes: Whit APIs the application wull be allooed tae access. Gin ye dinnae pick a tap-level scope, ye dinnae need tae pick anes ane at a time. @@ -52,12 +49,8 @@ sco: setting_display_media_default: Hide media mairked sensitive setting_display_media_hide_all: Aye hide media setting_display_media_show_all: Aye shaw media - setting_hide_network: Wha ye follae an thaim thit follaes ye wull get hid on yer profile - setting_noindex: Affects yer public profile an post pages - setting_show_application: The application thit ye uise fir tae post wull be displayed in the detailt view o yer posts setting_use_blurhash: Gradients is based aff o the colors o the image thit's hid, but ye cannae see onie details setting_use_pending_items: Plank timeline updates ahin a chap insteid o automatic scrowin o the feed - username: Yer uisernemm wull be a ane aff on %{domain} whole_word: Whan the keywird or phrase is alphanumeric ainly, it wull ainly get applied if it matches the haill wird domain_allow: domain: This domain wull be able tae get data fae this server an data comin in fae it wull get processed an stowed @@ -168,7 +161,6 @@ sco: context: Filter contexts current_password: Current passwird data: Data - discoverable: Suggest accoont tae ithers display_name: Display nemm email: Email address expires_in: Rin oot efter @@ -178,7 +170,6 @@ sco: inbox_url: URL o the relay inbox irreversible: Drap insteid o plank locale: Interface leid - locked: Require follae requests max_uses: Maist nummer o uises new_password: New passwird note: Bio @@ -190,7 +181,6 @@ sco: setting_always_send_emails: Aye sen email notifications setting_auto_play_gif: Auto-pley animatit GIFs setting_boost_modal: Shaw confirmation dialog afore heezin - setting_crop_images: Crap images in non-expandit posts tae 16x9 setting_default_language: Postin leid setting_default_privacy: Postin privacy setting_default_sensitive: Aye mairk media as sensitive @@ -202,9 +192,7 @@ sco: setting_display_media_show_all: Shaw aw setting_expand_spoilers: Aye expand posts mairked wi content warnins setting_hide_network: Plank yer social graph - setting_noindex: Opt-oot o seirch engine indexin setting_reduce_motion: Reduce motion in animations - setting_show_application: Disclose application uised fir tae sen posts setting_system_font_ui: Uise system's defaut font setting_theme: Steid theme setting_trends: Shaw the day's trends diff --git a/config/locales/simple_form.si.yml b/config/locales/simple_form.si.yml index e107d82ace..ededa85bcc 100644 --- a/config/locales/simple_form.si.yml +++ b/config/locales/simple_form.si.yml @@ -7,12 +7,10 @@ si: account_migration: acct: ඔබට යාමට අවශ්‍ය ගිණුමේ username@domain සඳහන් කරන්න account_warning_preset: - text: ඔබට URL, හෑෂ් ටැග් සහ සඳහන් කිරීම් වැනි පෝස්ට් සින්ටැක්ස් භාවිතා කළ හැක + text: ඔබට ඒ.ස.නි., පූරක අනන්‍යන සහ සැඳහුම් වැනි ලිපි පද ගැළපුම් භාවිතා කිරීමට හැකිය title: විකල්ප. ලබන්නාට නොපෙනේ admin_account_action: - include_statuses: මධ්‍යස්ථ ක්‍රියාව හෝ අනතුරු ඇඟවීමට හේතු වී ඇත්තේ කුමන පළ කිරීම්දැයි පරිශීලකයා දකිනු ඇත send_email_notification: පරිශීලකයාට ඔවුන්ගේ ගිණුම සමඟ සිදු වූ දේ පිළිබඳ පැහැදිලි කිරීමක් ලැබෙනු ඇත - text_html: විකල්ප. ඔබට post syntax භාවිතා කළ හැක. කාලය ඉතිරි කර ගැනීම සඳහා ඔබට අනතුරු ඇඟවීමේ කළ හැක type_html: "%{acct}සමඟ කළ යුතු දේ තෝරන්න" types: disable: පරිශීලකයාගේ ගිණුම භාවිතා කිරීමෙන් වළක්වන්න, නමුත් ඔවුන්ගේ අන්තර්ගතය මකා දැමීම හෝ සඟවන්න එපා. @@ -24,7 +22,7 @@ si: ends_at: විකල්ප. මෙම අවස්ථාවේදී නිවේදනය ස්වයංක්‍රීයව ප්‍රකාශනය කිරීමෙන් ඉවත් වනු ඇත scheduled_at: නිවේදනය වහාම ප්‍රකාශයට පත් කිරීමට හිස්ව තබන්න starts_at: විකල්ප. ඔබගේ නිවේදනය නිශ්චිත කාල පරාසයකට බැඳී ඇත්නම් - text: ඔබට post syntax භාවිතා කළ හැක. කරුණාකර පරිශීලකයාගේ තිරය මත නිවේදනය ලබා ගන්නා ඉඩ ගැන සැලකිලිමත් වන්න + text: ඔබට ලිපි පද ගැළපුම් භාවිතා කිරීමට හැකිය. කරුණාකර නිවේදනයෙන් පරිශ්‍රීලකයින්ගේ තිරයේ ඉඩ කෙතරම් ඇහිරෙනවා ද පිළිබඳව සැලකිලිමත් වන්න appeal: text: ඔබට වර්ජනයකට අභියාචනා කළ හැක්කේ එක් වරක් පමණි defaults: @@ -35,29 +33,21 @@ si: current_password: ආරක්ෂක අරමුණු සඳහා කරුණාකර ජංගම ගිණුමේ මුරපදය ඇතුළත් කරන්න current_username: තහවුරු කිරීමට, කරුණාකර වත්මන් ගිණුමේ පරිශීලක නාමය ඇතුළත් කරන්න digest: දිගු කාලයක් අක්‍රියව සිටීමෙන් පසුව පමණක් යවන ලද අතර ඔබ නොමැති විට ඔබට කිසියම් පුද්ගලික පණිවිඩයක් ලැබී ඇත්නම් පමණි - discoverable: නිර්දේශ, ප්‍රවණතා සහ වෙනත් විශේෂාංග හරහා ඔබේ ගිණුම ආගන්තුකයන්ට සොයා ගැනීමට ඉඩ දෙන්න email: ඔබට තහවුරු කිරීමේ විද්‍යුත් තැපෑලක් එවනු ලැබේ - fields: ඔබට ඔබගේ පැතිකඩෙහි වගුවක් ලෙස අයිතම 4ක් දක්වා පෙන්විය හැක header: PNG, GIF හෝ JPG. වැඩිම %{size}. %{dimensions}px දක්වා අඩු කරනු ඇත inbox_url: ඔබට භාවිතා කිරීමට අවශ්‍ය රිලේ හි මුල් පිටුවෙන් URL එක පිටපත් කරන්න - irreversible: පෙරහන පසුව ඉවත් කළද, පෙරූ පළ කිරීම් ආපසු හැරවිය නොහැකි ලෙස අතුරුදහන් වනු ඇත - locale: පරිශීලක අතුරුමුහුණතේ භාෂාව, ඊමේල් සහ තල්ලු දැනුම්දීම් - locked: අනුගමන ඉල්ලීම් අනුමත කිරීමෙන් ඔබව අනුගමනය කළ හැක්කේ කාටදැයි හස්තීයව පාලනය කරන්න + irreversible: පෙරහන පසුව ඉවත් කළ ද, පෙරූ ලිපි අප්‍රතිවර්ත්‍යව අතුරුදහන් වනු ඇත + locale: වි-තැපැල්, තල්ලු දැනුම්දීම් සහ පරිශ්‍රීලක අතුරුමුහුණතේ භාෂාව password: අවම වශයෙන් අක්ෂර 8 ක් භාවිතා කරන්න - phrase: පළ කිරීමක පෙළ හෝ අන්තර්ගත අනතුරු ඇඟවීම නොසලකා ගැලපේ + phrase: ලිපිවල පෙළ හෝ අන්තර්ගත අවවාද නොසලකා ගැළපෙනු ඇත scopes: යෙදුමට ප්‍රවේශ වීමට ඉඩ දෙන්නේ කුමන API වලටද. ඔබ ඉහළ මට්ටමේ විෂය පථයක් තෝරා ගන්නේ නම්, ඔබට තනි ඒවා තෝරා ගැනීමට අවශ්‍ය නොවේ. - setting_aggregate_reblogs: මෑතකදී බූස්ට් කරන ලද පළ කිරීම් සඳහා නව බූස්ට් පෙන්වන්න එපා (අලුතින් ලැබුණු බූස්ට් වලට පමණක් බලපායි) - setting_always_send_emails: සාමාන්‍යයෙන් ඔබ Mastodon සක්‍රියව භාවිතා කරන විට විද්‍යුත් තැපැල් දැනුම්දීම් නොයවනු ඇත + setting_always_send_emails: ඔබ නිතර මාස්ටඩන් භාවිතා කරන විට වි-තැපැල් දැනුම්දීම් නොලැබෙයි setting_default_sensitive: සංවේදී මාධ්‍ය පෙරනිමියෙන් සඟවා ඇති අතර ක්ලික් කිරීමකින් හෙළිදරව් කළ හැක - setting_display_media_default: සංවේදී ලෙස සලකුණු කළ මාධ්‍ය සඟවන්න - setting_display_media_hide_all: සෑම විටම මාධ්‍ය සඟවන්න - setting_display_media_show_all: සෑම විටම මාධ්‍ය පෙන්වන්න - setting_hide_network: ඔබ අනුගමනය කරන්නේ කවුරුන්ද සහ ඔබව අනුගමනය කරන්නේ කවුරුන්ද යන්න ඔබගේ පැතිකඩෙහි සඟවනු ඇත - setting_noindex: ඔබගේ පොදු පැතිකඩ සහ පළ කිරීම් පිටු වලට බලපායි - setting_show_application: ඔබ පළ කිරීමට භාවිතා කරන යෙදුම ඔබගේ පළ කිරීම් වල සවිස්තරාත්මක දර්ශනයේ පෙන්වනු ඇත + setting_display_media_default: සංවේදී බව සලකුණු කළ මාධ්‍ය සඟවන්න + setting_display_media_hide_all: සැමවිට මාධ්‍ය සඟවන්න + setting_display_media_show_all: සැමවිට මාධ්‍ය පෙන්වන්න setting_use_blurhash: අනුක්‍රමණ සැඟවුණු දෘශ්‍යවල වර්ණ මත පදනම් වන නමුත් ඕනෑම විස්තරයක් අපැහැදිලි කරයි setting_use_pending_items: සංග්‍රහය ස්වයංක්‍රීයව අනුචලනය කරනවා වෙනුවට ක්ලික් කිරීමක් පිටුපස කාලරේඛා යාවත්කාලීන සඟවන්න - username: ඔබගේ පරිශීලක නාමය %{domain}හි අද්විතීය වනු ඇත whole_word: මූල පදය හෝ වාක්‍ය ඛණ්ඩය අක්ෂරාංක පමණක් වන විට, එය යෙදෙන්නේ එය සම්පූර්ණ වචනයට ගැලපේ නම් පමණි domain_allow: domain: මෙම වසමට මෙම සේවාදායකයෙන් දත්ත ලබා ගැනීමට හැකි වන අතර එයින් ලැබෙන දත්ත සකස් කර ගබඩා කරනු ලැබේ @@ -65,14 +55,14 @@ si: domain: මෙය විද්‍යුත් තැපැල් ලිපිනයේ හෝ එය භාවිතා කරන MX වාර්තාවේ පෙන්වන ඩොමේන් නාමය විය හැක. ලියාපදිංචි වූ පසු ඒවා පරීක්ෂා කරනු ලැබේ. with_dns_records: ලබා දී ඇති වසමේ DNS වාර්තා විසඳීමට උත්සාහ කරන අතර ප්‍රතිඵල ද අවහිර කරනු ලැබේ filters: - action: පළ කිරීමක් පෙරහනට ගැළපෙන විට සිදු කළ යුතු ක්‍රියාව තෝරන්න + action: ලිපියක් පෙරහනට ගැළපෙන විට ඉටු විය යුතු ක්‍රියාමාර්ගය තෝරන්න actions: hide: පෙරහන් කළ අන්තර්ගතය සම්පූර්ණයෙන්ම සඟවන්න, එය නොපවතින ලෙස හැසිරෙන්න warn: පෙරහන මාතෘකාව සඳහන් කරන අනතුරු ඇඟවීමක් පිටුපස පෙරූ අන්තර්ගතය සඟවන්න form_challenge: current_password: ඔබ ආරක්ෂිත ප්‍රදේශයකට ඇතුල් වේ imports: - data: CSV ගොනුව වෙනත් Mastodon සේවාදායකයකින් අපනයනය කරන ලදී + data: CSV ගොනුව වෙනත් මාස්ටඩන් සේවාදායකයකින් නිර්යාත කර ඇත invite_request: text: මෙය ඔබගේ අයදුම්පත සමාලෝචනය කිරීමට අපට උපකාරී වනු ඇත ip_block: @@ -91,7 +81,7 @@ si: tag: name: ඔබට අකුරු වල ආවරණය පමණක් වෙනස් කළ හැකිය, උදාහරණයක් ලෙස, එය වඩාත් කියවිය හැකි කිරීමට user: - chosen_languages: පරීක්ෂා කළ විට, තෝරාගත් භාෂාවලින් පළ කිරීම් පමණක් පොදු කාලරේඛා තුළ සංදර්ශන කෙරේ + chosen_languages: සබල නම්, තෝරාගත් භාෂාවල ලිපි පමණක් ප්‍රසිද්ධ කාල රේඛාවේ දිස්වේ webhook: events: යැවීමට සිදුවීම් තෝරන්න url: සිදුවීම් යවනු ලබන ස්ථානය @@ -100,22 +90,24 @@ si: fields: name: නම්පත value: අන්තර්ගතය + show_collections: අනුගමන හා අනුගාමිකයින් පැතිකඩෙහි පෙන්වන්න + unlocked: නව අනුගාමිකයින් ස්වයංක්‍රීයව පිළිගන්න account_alias: acct: පැරණි ගිණුමේ හැසිරවීම account_migration: acct: නව ගිණුමේ හැසිරවීම account_warning_preset: text: පෙර සැකසූ පෙළ - title: ශීර්ෂය + title: සිරැසිය admin_account_action: - include_statuses: විද්‍යුත් තැපෑලෙහි වාර්තා කරන ලද පළ කිරීම් ඇතුළත් කරන්න + include_statuses: වි-තැපෑලට වාර්තා කරන ලද ලිපි ද ඇතුළත් කරන්න send_email_notification: විද්‍යුත් තැපෑලෙන් පරිශීලකයාට දැනුම් දෙන්න text: අභිරුචි අනතුරු ඇඟවීම type: ක්‍රියාමාර්ගය types: disable: කැටි කරන්න none: අනතුරු ඇඟවීමක් යවන්න - sensitive: පවතී + sensitive: සංවේදීතාව silence: සීමාව suspend: අත්හිටුවන්න warning_preset_id: අනතුරු ඇඟවීමේ පෙරසිටුවක් භාවිතා කරන්න @@ -128,16 +120,15 @@ si: appeal: text: මෙම තීරණය ආපසු හැරවිය යුත්තේ මන්දැයි පැහැදිලි කරන්න defaults: - autofollow: ඔබගේ ගිණුම අනුගමනය කිරීමට ආරාධනා කරන්න - avatar: අවතාරය - bot: මෙය ස්වයං ක්‍රමලේඛගත ගිණුමකි - chosen_languages: භාෂා පෙරහන් කරන්න - confirm_new_password: නව මුර පදය තහවුරු කරන්න - confirm_password: මුරපදය තහවුරු කර ඇත - context: සන්දර්භ පෙරහන් කරන්න - current_password: වත්මන් මුර පදය + autofollow: ඔබගේ ගිණුම අනුගමනයයට ආරාධනා කරන්න + avatar: පැතිකඩ ඡායාරූපය + bot: මෙම ගිණුම ස්වයංක්‍රියයි + chosen_languages: භාෂා පෙරන්න + confirm_new_password: නව මුරපදය තහවුරු කරන්න + confirm_password: මුරපදය තහවුරු කරන්න + context: සන්දර්භ පෙරන්න + current_password: වත්මන් මුරපදය data: දත්ත - discoverable: අන් අයට ගිණුමක් යෝජනා කරන්න display_name: ප්රදර්ශන නාමය email: වි-තැපැල් ලිපිනය expires_in: පසු කල් ඉකුත් වේ @@ -146,43 +137,35 @@ si: honeypot: "%{label} (පුරවන්න එපා)" inbox_url: රිලේ එන ලිපි URL irreversible: සැඟවීම වෙනුවට අතහරින්න - locale: අතුරු මුහුණත භාෂාව - locked: ඉල්ලීම් අනුගමනය කිරීම අවශ්‍ය වේ + locale: අතුරු මුහුණතේ භාෂාව max_uses: උපරිම භාවිත ගණන new_password: නව මුරපදය - note: ජෛව otp_attempt: ද්වි සාධක කේතය password: මුරපදය phrase: මූල පදය හෝ වාක්‍ය ඛණ්ඩය - setting_advanced_layout: උසස් වෙබ් අතුරු මුහුණත සබල කරන්න - setting_aggregate_reblogs: කණ්ඩායම් කාලරේඛාව වැඩි කරයි + setting_advanced_layout: සංකීර්ණ අතුරු මුහුණත සබල කරන්න setting_always_send_emails: සෑම විටම විද්‍යුත් තැපැල් දැනුම්දීම් යවන්න setting_auto_play_gif: සජීවිකරණ GIF ස්වයංක්‍රීයව ධාවනය කරන්න - setting_boost_modal: වැඩි කිරීමට පෙර තහවුරු කිරීමේ සංවාදය පෙන්වන්න - setting_crop_images: ප්‍රසාරණය නොකළ පළ කිරීම් වල පින්තූර 16x9 දක්වා කප්පාදු කරන්න - setting_default_language: පළ කිරීමේ භාෂාව - setting_default_privacy: පුද්ගලිකත්වය පළ කිරීම - setting_default_sensitive: සෑම විටම මාධ්‍ය සංවේදී ලෙස සලකුණු කරන්න - setting_delete_modal: පළ කිරීමක් මැකීමට පෙර තහවුරු කිරීමේ සංවාදය පෙන්වන්න - setting_disable_swiping: ස්වයිප් චලන අක්‍රීය කරන්න + setting_default_language: ලිපිවල භාෂාව + setting_default_privacy: ලිපියේ රහස්‍යතාව + setting_default_sensitive: සෑමවිට මාධ්‍ය සංවේදී බව සලකුණු කරන්න + setting_delete_modal: ලිපියක් මැකීමට පෙර ඒ ගැන විමසන්න setting_display_media: මාධ්ය සංදර්ශකය - setting_display_media_default: පෙරනිමිය + setting_display_media_default: පෙරනිමි setting_display_media_hide_all: සියල්ල සඟවන්න setting_display_media_show_all: සියල්ල පෙන්වන්න - setting_expand_spoilers: අන්තර්ගත අනතුරු ඇඟවීම් සමඟ සලකුණු කර ඇති පළ කිරීම් සැමවිටම පුළුල් කරන්න + setting_expand_spoilers: අන්තර්ගත අවවාද සහිත ලිපි සැමවිට දිගහරින්න setting_hide_network: ඔබගේ ජාලය සඟවන්න - setting_noindex: සෙවුම් යන්ත්‍ර සුචිගත කිරීමෙන් ඉවත් වීම setting_reduce_motion: සජීවිකරණවල චලනය අඩු කරන්න - setting_show_application: පළ කිරීම් යැවීමට භාවිතා කරන යෙදුම හෙළි කරන්න - setting_system_font_ui: පද්ධතියේ පෙරනිමි අකුරු භාවිතා කරන්න + setting_system_font_ui: පද්ධතියේ පෙරනිමි රුවකුරු භාවිතා කරන්න setting_theme: අඩවියේ තේමාව setting_trends: අද ප්‍රවණතා පෙන්වන්න setting_unfollow_modal: යමෙකු අනුගමනය නොකිරීමට පෙර තහවුරු කිරීමේ සංවාදය පෙන්වන්න setting_use_blurhash: සැඟවුණු මාධ්‍ය සඳහා වර්ණවත් අනුක්‍රමික පෙන්වන්න - setting_use_pending_items: මන්දගාමී මාදිලිය + setting_use_pending_items: මන්දගාමී ප්‍රකාරය severity: බරපතලකම sign_in_token_attempt: ආරක්‍ෂණ කේතය - title: ශීර්ෂය + title: සිරැසිය type: ආයාත වර්ගය username: පරිශීලක නාමය username_or_email: පරි. නාමය හෝ වි-තැපෑල @@ -193,12 +176,16 @@ si: name: හෑෂ් ටැගය filters: actions: - hide: සම්පූර්ණයෙන්ම සඟවන්න - warn: අනතුරු ඇඟවීමක් සමඟ සඟවන්න + hide: මුළුමනින්ම සඟවන්න + warn: අවවාදයක් සහිතව සඟවන්න + form_admin_settings: + custom_css: අභිරුචි CSS + profile_directory: පැතිකඩ නාමාවලිය සබල කරන්න + site_terms: රහස්‍යතා ප්‍රතිපත්තිය + site_title: සේවාදායකයේ නම + theme: පෙරනිමි තේමාව interactions: - must_be_follower: අනුගාමිකයින් නොවන අයගේ දැනුම්දීම් අවහිර කරන්න - must_be_following: ඔබ අනුගමනය නොකරන පුද්ගලයින්ගේ දැනුම්දීම් අවහිර කරන්න - must_be_following_dm: ඔබ අනුගමනය නොකරන පුද්ගලයින්ගෙන් සෘජු පණිවිඩ අවහිර කරන්න + must_be_following_dm: ඔබ නොදන්නා අයගෙන් සෘජු පණිවිඩ ලැබීම අවහිර කරන්න invite: comment: අදහස invite_request: @@ -207,31 +194,34 @@ si: comment: අදහස ip: අ.ජා. කෙ. (IP) severities: - no_access: ප්රවේශය අවහිර කරන්න + no_access: ප්‍රවේශය අවහිර කරන්න sign_up_requires_approval: ලියාපදිංචි වීම සීමා කරන්න severity: නීතිය notification_emails: - appeal: යමෙක් උපපරිපාලක තීරණයකට අභියාචනා කරයි digest: digest ඊමේල් යවන්න - favourite: කවුරුහරි ඔබේ පළ කිරීම ප්‍රිය කළා - follow: කවුරුහරි ඔබව අනුගමනය කළා - follow_request: කවුරුහරි ඔබව අනුගමනය කරන ලෙස ඉල්ලා සිටියේය - mention: කවුරුහරි ඔබව සඳහන් කළා - pending_account: නව ගිණුම සමාලෝචනය අවශ්‍යයි - reblog: කවුරුහරි ඔබේ පළ කිරීම වැඩි කළා - report: නව වාර්තාවක් ඉදිරිපත් කෙරේ - trending_tag: නව ප්‍රවණතාවයට සමාලෝචනයක් අවශ්‍ය වේ + favourite: යමෙක් ඔබගේ ලිපියට ප්‍රිය කළා + follow: යමෙක් ඔබව අනුගමනය කළා + mention: යමෙක් ඔබව සඳහන් කළා + report: නව වාර්තාවක් යොමු කර ඇත rule: text: නීතිය tag: listable: මෙම හැෂ් ටැගය සෙවීම් සහ යෝජනා වල දිස් වීමට ඉඩ දෙන්න name: හෑෂ් ටැගය trendable: මෙම හැෂ් ටැගය ප්‍රවණතා යටතේ දිස් වීමට ඉඩ දෙන්න - usable: මෙම හැෂ් ටැගය භාවිතා කිරීමට පළ කිරීම් වලට ඉඩ දෙන්න + usable: ලිපි සඳහා මෙම පූරක අනන්‍යනය භාවිතයට ඉඩදෙන්න + user: + role: භූමිකාව + time_zone: වේලා කලාපය + user_role: + color: චිහ්නයේ පාට + name: නම + permissions_as_keys: අවසර + position: ප්‍රමුඛත්‍වය webhook: events: සබල කළ සිදුවීම් url: අන්ත ලක්ෂ්‍ය URL - 'no': නැත + 'no': නැහැ recommended: නිර්දේශිත required: mark: "*" diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index e8fb86f29b..a89e1a4290 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -23,12 +23,10 @@ sk: current_username: Pre potvrdenie prosím zadaj prezývku súčasného účtu digest: Odoslané iba v prípade dlhodobej neprítomnosti, a len ak si obdržal/a nejaké osobné správy kým si bol/a preč email: Bude ti odoslaný potvrdzujúci email - fields: Až štyri položky môžeš mať na svojom profile zobrazené vo forme tabuľky header: PNG, GIF, alebo JPG. Maximálne %{size}. Bude zmenšený na %{dimensions}px inbox_url: Skopíruj adresu z hlavnej stránky mostíka, ktorý chceš používať irreversible: Vytriedené príspevky zmiznú nenávratne, aj keď triedenie neskôr zrušíš locale: Jazyk užívateľského rozhrania, emailových, a nástenkových oboznámení - locked: Vyžaduje sa manuálne schvaľovanie sledujúcich password: Zadaj aspoň osem znakov phrase: Zhoda sa nájde nezávisle od toho, či je text napísaný, veľkými, alebo malými písmenami, či už v tele, alebo v hlavičke scopes: Ktoré API budú povolené aplikácii pre prístup. Ak vyberieš vrcholný stupeň, nemusíš už potom vyberať po jednom. @@ -37,12 +35,8 @@ sk: setting_display_media_default: Ukry médiá označené ako chúlostivé setting_display_media_hide_all: Vždy ukry všetky médiá setting_display_media_show_all: Vždy zobrazuj médiá - setting_hide_network: Koho následuješ, a kto následuje teba, nebude zobrazené na tvojom profile - setting_noindex: Ovplyvňuje verejný profil a stránky s príspevkami - setting_show_application: Aplikácia, ktorú používaš na písanie príspevkov, bude zobrazená v podrobnom náhľade jednotlivých tvojích príspevkov setting_use_blurhash: Prechody sú založené na farbách skrytých vizuálov, ale zahaľujú akékoľvek podrobnosti setting_use_pending_items: Skry aktualizovanie časovej osi tak, aby bola načitávaná iba po kliknutí, namiesto samostatného posúvania - username: Tvoja prezývka bude unikátna pre server %{domain} whole_word: Ak je kľúčové slovo, alebo fráza poskladaná iba s písmen a čísel, bude použité iba ak sa zhoduje s celým výrazom domain_allow: domain: Táto doména bude schopná získavať dáta z tohto servera, a prichádzajúce dáta ním budú spracovávané a uložené @@ -99,7 +93,6 @@ sk: context: Triedenie kontextov current_password: Súčasné heslo data: Dáta - discoverable: Zaraď tento účet do databázy profilov display_name: Zobrazované meno email: Emailová adresa expires_in: Expiruj po @@ -108,7 +101,6 @@ sk: inbox_url: URL adresa prechodnej schránky irreversible: Zahoď, namiesto ukrytia locale: Jazyk rozhrania - locked: Zamknúť účet max_uses: Najviac možno použiť new_password: Nové heslo note: O tebe @@ -119,7 +111,6 @@ sk: setting_aggregate_reblogs: Zoskupuj vyzdvihnutia v časovej osi setting_auto_play_gif: Automaticky prehrávaj animované GIFy setting_boost_modal: Zobrazuj potvrdzovacie okno pred povýšením - setting_crop_images: Orež obrázky v nerozbalených príspevkoch na 16x9 setting_default_language: Píšeš v jazyku setting_default_privacy: Súkromie príspevkov setting_default_sensitive: Označ všetky mediálne súbory ako chúlostivé @@ -130,9 +121,7 @@ sk: setting_display_media_show_all: Ukáž všetky setting_expand_spoilers: Stále rozbaľ príspevky označené varovaním o chúlostivom obsahu setting_hide_network: Ukry svoju sieť kontaktov - setting_noindex: Nezaraďuj príspevky do indexu pre vyhľadávče setting_reduce_motion: Mierni pohyb pri animáciách - setting_show_application: Zverejni akú aplikáciu používaš na posielanie príspevkov setting_system_font_ui: Použi základné systémové písmo setting_theme: Vzhľad webu setting_trends: Ukáž dnešné trendy diff --git a/config/locales/simple_form.sl.yml b/config/locales/simple_form.sl.yml index ac14735a91..ef345f78c3 100644 --- a/config/locales/simple_form.sl.yml +++ b/config/locales/simple_form.sl.yml @@ -2,6 +2,14 @@ sl: simple_form: hints: + account: + discoverable: Vaše javne objave in profil so lahko predstavljeni ali priporočeni v različnih delih Mastodona, vaš profil pa je lahko predlagan drugim uporabnikom. + display_name: Vaše polno ime ali lažno ime. + fields: Vaša domača stran, starost, kar koli. + indexable: Vaše javne objave se lahko pojavijo v rezultatih iskanja na Mastodonu. Ljudje, ki so bili v interakciji z vašimi objavami, jih bodo lahko iskali ne glede na to. + note: 'Druge osebe lahko @omenite ali #ključnite.' + show_collections: Ljudje bodo lahko brskali po vaših sledilcih in sledenih. Ljudje, ki jim sledite, bodo videli, da jim sledite ne glede na to. + unlocked: Ljudje vam bodo lahko sledili, ne da bi zahtevali odobritev. Ne potrdite, če želite pregledati prošnje za sledenje, in izbirajte, ali želite nove sledilce sprejeti ali zavrniti. account_alias: acct: Določite uporabniškoime@domena računa, od katerega se želite preseliti account_migration: @@ -37,14 +45,11 @@ sl: current_password: Iz varnostnih razlogov vnesite geslo trenutnega računa current_username: Za potrditev vnesite uporabniško ime trenutnega računa digest: Pošlje se le po dolgem obdobju nedejavnosti in samo, če ste prejeli osebna sporočila v vaši odsotnosti - discoverable: Dovolite, da vaš račun odkrijejo neznanci prek priporočil, trendov in drugih funkcij email: Poslali vam bomo potrditveno e-pošto - fields: Na svojem profilu lahko imate do 4 predmete prikazane kot tabelo. header: PNG, GIF ali JPG. Največ %{size}. Zmanjšana bo na %{dimensions}px inbox_url: Kopirajte URL naslov s prve strani releja, ki ga želite uporabiti irreversible: Filtrirane objave bodo nepovratno izginile, tudi če je filter kasneje odstranjen locale: Jezik uporabniškega vmesnika, e-poštnih sporočil in potisnih obvestil - locked: Zahteva, da ročno odobrite sledilce password: Uporabite najmanj 8 znakov phrase: Se bo ujemal, ne glede na začetnice v besedilu ali opozorilo o vsebini objave scopes: Do katerih API-jev bo imel program dostop. Če izberete obseg najvišje ravni, vam ni treba izbrati posameznih. @@ -54,12 +59,9 @@ sl: setting_display_media_default: Skrij medij, ki je označen kot občutljiv setting_display_media_hide_all: Vedno skrij vse medije setting_display_media_show_all: Vedno pokaži medij, ki je označen kot občutljiv - setting_hide_network: Kogar spremljate in kdo vas spremlja ne bo prikazano na vašem profilu - setting_noindex: Vpliva na vaš javni profil in na strani z objavami - setting_show_application: Aplikacija, ki jo uporabljate za objavljanje, bo prikazana v podrobnem pogledu vaših objav setting_use_blurhash: Prelivi temeljijo na barvah skrite vizualne slike, vendar zakrivajo vse podrobnosti setting_use_pending_items: Skrij posodobitev časovnice za klikom namesto samodejnega posodabljanja - username: Vaše uporabniško ime bo edinstveno na %{domain} + username: Uporabite lahko črke, števke in podčrtaje. whole_word: Ko je ključna beseda ali fraza samo alfanumerična, se bo uporabljala le, če se bo ujemala s celotno besedo domain_allow: domain: Ta domena bo lahko prejela podatke s tega strežnika, dohodni podatki z nje pa bodo obdelani in shranjeni @@ -118,6 +120,9 @@ sl: sessions: otp: 'Vnesite dvomestno kodo, ki je ustvarjena z aplikacijo na telefonu, ali uporabite eno od vaših obnovitvenih kod:' webauthn: Če gre za ključek USB, ga ne pozabite vstaviti in, če je potrebno, tapniti. + settings: + indexable: Stran vašega profila se lahko pojavi med zadetki iskanja iskalnikov Google, Bing idr. + show_application: Ne glede na to boste vedno lahko pogledali, katera aplikacija je objavila vašo objavo. tag: name: Spremenite lahko le npr. velikost črk (velike/male), da je bolj berljivo user: @@ -131,12 +136,17 @@ sl: position: Višja vloga se odloča o razrešitvi sporov v določenih situacijah. Določena dejanja lahko izvede le na vlogah z nižjo prioriteto webhook: events: Izberite dogodke za pošiljanje + template: Sestavite svojo obremenitev JSON z uporabo interpolacije spremenljivk. Za privzeti JSON pustite prazno. url: Kam bodo poslani dogodki labels: account: + discoverable: Izpostavljaj profile in objave v algoritmih odkrivanja fields: name: Oznaka value: Vsebina + indexable: Med zadetke iskanja vključi javne objave + show_collections: Pokaži sledene in sledilce v profilu + unlocked: Samodejno sprejmi nove sledilce account_alias: acct: Ročica starega računa account_migration: @@ -174,7 +184,6 @@ sl: context: Filtriraj vsebino current_password: Trenutno geslo data: Podatki - discoverable: Dodaj ta račun v imenik display_name: Prikazno ime email: E-poštni naslov expires_in: Preteče po @@ -184,7 +193,6 @@ sl: inbox_url: URL mape "Prejeto" irreversible: Opusti namesto skrij locale: Jezik vmesnika - locked: Zaklenjen račun max_uses: Največje število uporabnikov new_password: Novo geslo note: Biografija @@ -196,7 +204,6 @@ sl: setting_always_send_emails: Vedno pošlji e-obvestila setting_auto_play_gif: Samodejno predvajanje animiranih GIF-ov setting_boost_modal: Pred izpostavljanjem pokaži potrditveno okno - setting_crop_images: Obreži slike v nerazširjenih objavah v razmerju 16:9 setting_default_language: Jezik objavljanja setting_default_privacy: Zasebnost objave setting_default_sensitive: Vedno označi medije kot občutljive @@ -208,9 +215,7 @@ sl: setting_display_media_show_all: Prikaži vse setting_expand_spoilers: Vedno razširi objave, označene z opozorili o vsebini setting_hide_network: Skrij svoje omrežje - setting_noindex: Odsotnost indeksiranja iskalnikov setting_reduce_motion: Zmanjšanje premikanja v animacijah - setting_show_application: Razkrij aplikacijo za pošiljanje objav setting_system_font_ui: Uporabi privzeto pisavo sistema setting_theme: Tema strani setting_trends: Pokaži današnje trende @@ -286,9 +291,18 @@ sl: pending_account: Pošlji e-pošto, ko je potreben pregled novega računa reblog: Pošlji e-sporočilo, ko nekdo izpostavi vašo objavo report: Novo poročilo je oddano + software_updates: + all: Obveščaj o vseh posodobitvah + critical: Obveščaj le o kritičnih posodobitvah + label: Na voljo je nova različica Mastodona + none: Nikoli ne obveščaj o posodobitvah (ni priporočeno) + patch: Obveščaj o posodobitvah z odpravljenimi hrošči trending_tag: Nov trend zahteva pregled rule: text: Pravilo + settings: + indexable: V iskalnike vključi stran profila + show_application: Pokaži, iz katerega programa je poslana objava tag: listable: Dovoli, da se ta ključnik pojavi v iskanjih in predlogih name: Ključnik @@ -296,6 +310,7 @@ sl: usable: Dovoli, da objave uporabljajo ta ključnik user: role: Vloga + time_zone: Časovni pas user_role: color: Barva značke highlighted: Prikaži vlogo kot značko na uporabniškem profilu @@ -304,9 +319,11 @@ sl: position: Prioriteta webhook: events: Omogočeni dogodki + template: Predloga obremenitev url: URL končne točke 'no': Ne not_recommended: Ni priporočeno + overridden: Preglašeno recommended: Priporočeno required: mark: "*" diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index a11037fa92..3256e7378d 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -2,6 +2,14 @@ sq: simple_form: hints: + account: + discoverable: Postimet dhe profili juaj publik mund të shfaqen, ose rekomandohen në zona të ndryshme të Mastodon-it dhe profili juaj mund të sugjerohet përdoruesve të tjerë. + display_name: Emri juaj i plotë, ose emri juaj lojcak. + fields: Faqja juaj hyrëse, përemra, moshë, ç’të keni qejf. + indexable: Postimet tuaja publike mund të shfaqen në përfundime kërkimesh në Mastodon. Pavarësisht nga kjo, personat që kanë ndërvepruar me postimet tuaja, mund të jenë në gjendje të kërkojnë për to. + note: 'Mundeni të @përmendni persona apo #hashtagë të tjerë.' + show_collections: Njerëzit do të jenë në gjendje të shfletojnë ndjekjet dhe ndjekësit tuaj. Njerëzit që ndiqni, do ta shohin që i ndiqni. + unlocked: Njerëzit do të jenë në gjendje t’ju ndjekin pa u dashur miratim. Hiqjani shenjën, nëse doni të shqyrtoni kërkesa ndjekjeje dhe të zgjidhni pranimin apo hedhjen poshtë e ndjekësve të rinj. account_alias: acct: Specifikoni emrinepërdoruesit@përkatësi të llogarisë prej nga doni të lëvizet account_migration: @@ -37,14 +45,11 @@ sq: current_password: Për qëllime sigurie, ju lutemi, jepni fjalëkalimin e llogarisë së tanishme current_username: Që ta ripohoni, ju lutemi, jepni emrin e përdoruesit të llogarisë së tanishme digest: I dërguar vetëm pas një periudhe të gjatë pasiviteti dhe vetëm nëse keni marrë ndonjë mesazh personal gjatë mungesës tuaj - discoverable: Lejoni që llogaria juaj të zbulohet nga të huaj përmes rekomandimesh, gjërash në modë dhe veçorish të tjera email: Do t’ju dërgohet një email ripohimi - fields: Te profili juaj mund të keni deri në 4 objekte të shfaqur si tabelë header: PNG, GIF ose JPG. E shumta %{size}. Do të ripërmasohet në %{dimensions}px inbox_url: Kopjoni URL-në prej faqes ballore të relesë që doni të përdorni irreversible: Mesazhet e filtruar do të zhduken në mënyrë të pakthyeshme, edhe nëse filtri hiqet më vonë locale: Gjuha e ndërfaqes së përdoruesit, email-eve dhe njoftimeve push - locked: Lyp që ju të miratoni dorazi ndjekësit password: Përdorni të paktën 8 shenja phrase: Do të kërkohet përputhje pavarësish se teksti ose sinjalizimi mbi lëndën e një mesazhi është shkruar me të mëdha apo me të vogla scopes: Cilat API do të lejohen të përdorin aplikacioni. Nëse përzgjidhni një shkallë të epërme, nuk ju duhet të përzgjidhni individualet një nga një. @@ -54,12 +59,9 @@ sq: setting_display_media_default: Fshih media me shenjën rezervat setting_display_media_hide_all: Fshih përherë mediat setting_display_media_show_all: Mediat shfaqi përherë - setting_hide_network: Cilët ndiqni dhe cilët ju ndjekin nuk do të shfaqen në profilin tuaj - setting_noindex: Prek faqet e profilit tuaj publik dhe gjendjeve - setting_show_application: Aplikacioni që përdorni për mesazhe do të shfaqet te pamja e hollësishme për mesazhet tuaj setting_use_blurhash: Gradientët bazohen në ngjyrat e elementëve pamorë të fshehur, por errësojnë çfarëdo hollësie setting_use_pending_items: Fshihi përditësimet e rrjedhës kohore pas një klikimi, në vend të rrëshqitjes automatike nëpër prurje - username: Emri juaj i përdoruesit do të jetë unik në %{domain} + username: Mund të përdorni shkronja, numra dhe nënvija whole_word: Kur fjalëkyçi ose fraza është vetëm numerike, do të aplikohet vetëm nëse përputhet me krejt fjalën domain_allow: domain: Kjo përkatësi do të jetë në gjendje të sjellë të dhëna prej këtij shërbyesi dhe të dhënat ardhëse prej tij do të përpunohen dhe depozitohen @@ -118,6 +120,9 @@ sq: sessions: otp: 'Jepni kodin dyfaktorësh të prodhuar nga aplikacioni i telefonit tuaj ose përdorni një nga kodet tuaj të rikthimeve:' webauthn: Nëse është një diskth USB, sigurohuni se e keni futur dhe, në qoftë e nevojshme, prekeni. + settings: + indexable: Faqja e profilit tuaj mund të shfaqet në përfundime kërkimi në Google, Bing dhe të tjerë. + show_application: Pavarësisht nga kjo, do të jeni përherë në gjendje të shihni cili aplikacion botoi postimin tuaj. tag: name: Mund të ndryshoni shkronjat vetëm nga të mëdha në të vogla ose anasjelltas, për shembull, për t’i bërë më të lexueshme user: @@ -131,12 +136,17 @@ sq: position: Role më të lartë vendosin zgjidhje përplasje në disa raste. Disa veprime mund të kryhen vetëm mbi role të një shkalle më të ulët webhook: events: Përzgjidhni akte për dërgim + template: Hartoni ngarkesë tuajën JSON, duke përdorur ndërkëmbim ndryshoresh. Lëreni të zbrazët, për JSON-in parazgjedhje. url: Ku do të dërgohen aktet labels: account: + discoverable: Profilin dhe postimet bëji objekt të algoritmeve të zbulimit fields: name: Etiketë value: Lëndë + indexable: Përfshi postime publike në përfundime kërkimi + show_collections: Shfaq te profili ndjekje dhe ndjekës + unlocked: Prano automatikisht ndjekës të rinj account_alias: acct: Trajtim i llogarisë së vjetër account_migration: @@ -174,7 +184,6 @@ sq: context: Filtroni kontekste current_password: Fjalëkalimi i tanishëm data: Të dhëna - discoverable: Sugjerojuni llogari të tjerëve display_name: Emër në ekran email: Adresë email expires_in: Skadon pas @@ -184,7 +193,6 @@ sq: inbox_url: URL e Të marrëve të relesë irreversible: Heqje, në vend se fshehje locale: Gjuhë ndërfaqeje - locked: Kyçe llogarinë max_uses: Numër maksimum përdorimesh new_password: Fjalëkalim i ri note: Jetëshkrim @@ -196,7 +204,6 @@ sq: setting_always_send_emails: Dërgo përherë njoftime me email setting_auto_play_gif: Vetëluaji GIF-et e animuar setting_boost_modal: Shfaq dialog ripohimi përpara përforcimi - setting_crop_images: Në mesazhe jo të zgjerueshëm, qethi figurat në 16x9 setting_default_language: Gjuhë postimi setting_default_privacy: Privatësi postimi setting_default_sensitive: Mediave vëru përherë shenjë si rezervat @@ -208,9 +215,7 @@ sq: setting_display_media_show_all: Shfaqi krejt setting_expand_spoilers: Mesazhet me sinjalizime mbi lëndën, zgjeroji përherë setting_hide_network: Fshiheni rrjetin tuaj - setting_noindex: Zgjidhni lënien jashtë nga indeksim prej motorësh kërkimi setting_reduce_motion: Zvogëlo lëvizjen në animacione - setting_show_application: Tregoje aplikacionin e përdorur për të dërguar mesazhe setting_system_font_ui: Përdor shkronja parazgjedhje të sistemit setting_theme: Temë sajti setting_trends: Shfaq prirjet sot @@ -286,9 +291,18 @@ sq: pending_account: Llogaria e re lyp shqyrtim reblog: Dikush përforcoi gjendjen tuaj report: Parashtrohet raportim i ri + software_updates: + all: Njofto për krejt përditësimet + critical: Njofto vetëm për përditësime kritike + label: Ka gati një version të ri Mastodon-i + none: Mos njofto apo përditëso kurrë (nuk rekomandohet) + patch: Njofto për ndreqje të metash trending_tag: Për gjëra të reja në modë lypset shqyrtim rule: text: Rregull + settings: + indexable: Përfshi faqe profili në motorë kërkimesh + show_application: Shfaq prej cilit aplikacion dërguat një postim tag: listable: Lejoje këtë hashtag të shfaqet në kërkime dhe në drejtori profilesh name: Hashtag @@ -296,6 +310,7 @@ sq: usable: Lejoji mesazhet të përdorin këtë hashtag user: role: Rol + time_zone: Zonë kohore user_role: color: Ngjyrë steme highlighted: Shfaqe rolin si një stemë në profile përdoruesish @@ -304,9 +319,11 @@ sq: position: Përparësi webhook: events: Akte të aktivizuar + template: Gjedhe ngarkese url: URL pikëmbarimi 'no': Jo not_recommended: Jo e këshilluar + overridden: I anashkaluar recommended: E rekomanduar required: mark: "*" diff --git a/config/locales/simple_form.sr-Latn.yml b/config/locales/simple_form.sr-Latn.yml index 2f45b63576..6405ee338a 100644 --- a/config/locales/simple_form.sr-Latn.yml +++ b/config/locales/simple_form.sr-Latn.yml @@ -2,135 +2,151 @@ sr-Latn: simple_form: hints: + account: + discoverable: Vaše javne objave i profil mogu biti istaknuti ili preporučeni u različitim oblastima Mastodon-a i vaš profil može biti predložen drugim korisnicima. + display_name: Vaše puno ime ili nadimak. + fields: Vaša matična stranica, zamenice, godine, sve što želite. + indexable: Vaše javne objave se mogu pojaviti u rezultatima pretrage na Mastodon-u. Ljudi koji su stupili u interakciju sa vašim objavama će možda moći da ih pretražuju. + note: 'Možete da @pomenete druge ljude ili #heš oznake.' + show_collections: Ljudi će moći da pregledaju vaše pratioce i pratioce. Ljudi koje pratite videće da ih pratite. + unlocked: Ljudi će moći da vas prate bez zahtevanja odobrenja. Opozovite izbor ako želite da pregledate zahteve za praćenje i izaberite da li da prihvatite ili odbijete nove pratioce. account_alias: - acct: Navedi korisničko_ime@domen naloga sa kojeg želiš da pređeš + acct: Navedite korisničko_ime@domen naloga sa kojeg želite da se preselite account_migration: - acct: Navedi korisničko_ime@domen naloga na koji želiš da pređeš + acct: Navedite korisničko_ime@domen naloga na koji želite da se preselite account_warning_preset: - text: Možete koristiti sintaksu truba, kao što su npr. URL-ova, tarabe i pominjanja + text: Možete koristiti sintaksu objava, kao što su URL adrese, heš oznake i pominjanja title: Opciono. Nije vidljivo primaocu admin_account_action: - include_statuses: Korisnik će videti koje su objave prouzrokovale moderiranje ili upozorenje - send_email_notification: Korisnik će dobiti objašnjenje toga šta mu se desilo sa naloga - text_html: Opcionalno. Možete koristiti sintaksu truba. Možete dodati upozoravajuća prepodešavanje da sačuvate vreme + include_statuses: Korisnik će videti koje su objave prouzrokovale moderacijsku radnju ili upozorenje + send_email_notification: Korisnik će dobiti objašnjenje toga šta mu se desilo sa nalogom + text_html: Opcionalno. Možete koristiti sintaksu objava. Možete dodati unapred određene postavke upozorenja za uštedu vremena type_html: Izaberite šta da radite sa %{acct} types: - disable: Spreči korisnika da koristi svoj nalog, ali nemoj brisati ili sakrivati njegov sadržaj. - none: Koristi ovo da pošalješ upozorenje korisniku, bez pokretanja bilo koje druge akcije. + disable: Sprečava korisnika da koristi svoj nalog, ali ne briše niti sakriva njegove sadržaje. + none: Koristite ovo da pošaljete upozorenje korisniku bez pokretanja bilo koje druge radnje. sensitive: Učini da svi medijski prilozi ovog korisnika prisilno budu označeni kao osetljivi. + silence: Sprečava korisnika da pravi javne objave, sakriva njegove objave i obaveštenja od ljudi koji ga ne prate. Zatvara sve prijave podnete protiv ovog naloga. + suspend: Sprečava svu interakciju od ovog naloga i ka ovom nalogu i briše njegov sadržaj. Opozivo u roku od 30 dana. Zatvara sve prijave podnete protiv ovog naloga. warning_preset_id: Opcionalno. Možete i dalje dodati prilagođeni tekst na kraj preseta announcement: - all_day: Biće prikazani samo datumi vremenskog opsega koji su označeni + all_day: Kada je ova opcija označena, samo datumi iz vremenskog opsega će biti prikazani ends_at: Opciono. Objava će biti automatski opozvana u ovom trenutku - scheduled_at: Ostavi prazno da bi najava bila odmah objavljena + scheduled_at: Ostavite prazno da biste odmah objavili obaveštenje starts_at: Opciono. U slučaju da je najava vezana za određeni vremenski raspon - text: Možeš koristiti post sintaksu. Vodi računa o prostoru koji će objava zauzimati na ekranu korisnika + text: Možete koristiti sintaksu objava. Molimo vas vodite računa o prostoru koji će objava zauzimati na ekranu korisnika appeal: - text: Na brisanje se možeš žaliti samo jednom + text: Možete podneti samo jednu žalbu na upisan prestup defaults: autofollow: Osobe koje se prijave kroz pozivnice će vas automatski zapratiti - avatar: PNG, GIF ili JPG. Najviše %{size}. Biće smanjena na %{dimensions}px - bot: Ovaj nalog uglavnom vrši automatizovane radnje i možda se ne nadgleda + avatar: PNG, GIF ili JPG. Najviše %{size}. Biće smanjeno na %{dimensions}px + bot: Daje drugima do znanja da ovaj nalog uglavnom vrši automatizovane radnje i možda se ne nadgleda context: Jedan ili više konteksta u kojima treba da se primeni filter - current_password: Unesi lozinku tekućeg naloga iz bezbednosnih razloga - current_username: Unesi korisničko ime tekućeg naloga za potvrdu - digest: Poslato posle dužeg perioda neaktivnosti sa pregledom svih bitnih stvari koje ste dobili dok ste bili odsutni - discoverable: Dozvoli nepoznatim korisnicima da otkriju tvoj nalog putem preporuka, trendova i drugih funkcija - email: Biće vam poslata e-pošta sa potvrdom - fields: Možete imati do 4 stavke prikazane kao tabela na vašem nalogu - header: PNG, GIF ili JPG. Najviše %{size}. Biće smanjena na %{dimensions}px + current_password: Iz bezbednosnih razloga molimo Vas unesite lozinku trenutnog naloga + current_username: Da biste potvrdili, Molimo Vas unesite korisničko ime trenutno aktivnog naloga + digest: Šalje se samo posle dužeg perioda neaktivnosti i samo u slučaju da ste primili jednu ili više ličnih poruka tokom Vašeg odsustva + email: Biće Vam poslat mejl sa potvrdom + header: PNG, GIF ili JPG. Najviše %{size}. Biće smanjeno na %{dimensions}px inbox_url: Kopirajte URL sa naslovne strane releja koji želite koristiti - irreversible: Filtrirane trube će nestati nepovratno, čak i ako je filter kasnije uklonjen - locale: Jezik korisničkog interfejsa, e-pošte i mobilnih obaveštenja - locked: Zahteva da pojedinačno odobrite pratioce + irreversible: Filtrirane obajve će nestati nepovratno, čak i ako je filter kasnije uklonjen + locale: Jezik korisničkog okruženja, e-pošte i mobilnih obaveštenja password: Koristite najmanje 8 znakova - phrase: Biće uparena bez obzira na veliko ili malo slovo u tekstu ili upozorenja o sadržaju trube - scopes: Kojim API-jima će aplikacija dozvoliti pristup. Ako izaberete opseg najvišeg nivoa, ne morate odabrati pojedinačne. - setting_aggregate_reblogs: Ne pokazuj nova deljenja za trube koje su nedavno podeljene (utiče samo na nedavno primljena deljenja) - setting_always_send_emails: Obaveštenja e-poštom se po pravilu neće slati kada aktivno koristiš Mastodon + phrase: Biće uparena bez obzira na veliko ili malo slovo u tekstu ili upozorenja o sadržaju objave + scopes: Kojim API-jima će aplikacija imati pristup. Ako izaberete opseg najvišeg nivoa, ne morate odabrati pojedinačne. + setting_aggregate_reblogs: Ne prikazuj nova podržavanja za objave koje su nedavno podržane (utiče samo na nedavno primljena podržavanja) + setting_always_send_emails: Obaveštenja e-poštom se po pravilu neće slati kada aktivno koristite Mastodon setting_default_sensitive: Osetljivi mediji su podrazumevano skriveni i mogu se otkriti klikom setting_display_media_default: Sakrij medije označene kao osetljive setting_display_media_hide_all: Uvek sakrij sve medije setting_display_media_show_all: Uvek prikaži medije označene kao osetljive - setting_hide_network: Koga pratite i ko vas prati neće biti prikazano na vašem nalogu - setting_noindex: Utiče na Vaš javni nalog i statusne strane - setting_show_application: Aplikacija koju koristiš za objavljivanje biće prikazana u detaljnom prikazu tvojih objava - setting_use_blurhash: Gradijent se zasniva na bojama skrivenih vizuelnih prikaza, ali prikriva sve detalje - setting_use_pending_items: Sakrij ažuriranja vremenske ose iza klika umesto automatskog pomeranja izvora objava - username: Vaš nadimak će biti jedinstven na %{domain} - whole_word: Kada je ključna reč ili fraza isključivo alfanumerička, biće primenjena samo ako se podudara sa celom reči + setting_use_blurhash: Gradijenti se formiraju na osnovu bojâ skrivenih slika i zamućuju prikaz, prikrivajući detalje + setting_use_pending_items: Sakriva ažuriranja vremenske linije iza klika umesto automatskog ažuriranja i pomeranja vremenske linije + username: Možete koristiti slova, brojeve i donje crte + whole_word: Kada je ključna reč ili fraza isključivo alfanumerička, biće primenjena samo ako se podudara sa celom rečju domain_allow: domain: Ovaj domen će moći da preuzima podatke sa ovog servera i dolazni podaci sa njega će se obrađivati i čuvati email_domain_block: domain: Ovo može biti ime domena koje se pojavljuje u adresi e-pošte ili MX zapisa koji koristi. Oni će biti provereni prilikom registracije. with_dns_records: Biće učinjen pokušaj da se razreše DNS zapisi datog domena i rezultati će takođe biti blokirani featured_tag: - name: 'Evo nekih od heš oznaka koje ste nedavno koristili:' + name: 'Evo nekih od heš oznaka koje ste u prethodnom periodu često koristili:' filters: - action: Izaberi koju radnju treba izvršiti kada objava odgovara filteru + 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 form_admin_settings: + activity_api_enabled: Brojevi lokalno postavljenih objava, aktivnih korisnika i novih registracija na nedeljnoj bazi backups_retention_period: Čuvaj generisane korisničke arhive navedeni broj 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 prijave zatvorene - content_cache_retention_period: Kada se postavi na pozitivnu vrednost, objave sa drugih servera će biti izbrisane nakon navedenog broja dana. Ovo može biti nepovratno. - custom_css: Možeš da primeniš prilagođene stilove na veb verziji Mastodona. - mascot: Zamenjuje ilustraciju u naprednom veb interfejsu. + closed_registrations_message: Prikazuje se kada su registracije zatvorene + content_cache_retention_period: Sve objave i podržavanja sa drugih servera će biti izbrisani nakon navedenog broja dana. Neke objave se možda neće moći oporaviti. Svi povezani obeleživači, omiljeni i podržavanja će takođe biti izgubljeni i nemoguće je opozvati radnju. + custom_css: Možete da primenite prilagođene stilove na veb verziji Mastodon-a. + mascot: Zamenjuje ilustraciju u naprednom veb okruženju. media_cache_retention_period: Kada se postavi na pozitivnu vrednost, preuzete medijske datoteke će biti izbrisane nakon navedenog broja dana, i ponovo preuzete na zahtev. + peers_api_enabled: Lista domena sa kojima se ovaj server susreo u fediverzumu. Ovde nisu sadržani podaci o tome da li se Vaš server federiše sa drugim serverima, već samo da Vaš server zna za njih. Ove informacije koriste servisi koji prikupljaju podatke i vode statistiku o federaciji u širem smislu. profile_directory: Direktorijum profila navodi sve korisnike koji su se opredelili da budu vidljivi. - require_invite_text: Kada registracije zahtevaju ručno odobrenje, postavi da unos teksta „Zašto želiš da se pridružiš?“ bude obavezan, a ne opcioni - site_contact_email: Kako korisnici mogu da te kontaktiraju za pravna pitanja ili pitanja u vezi podrške. - site_contact_username: Kako korisnici mogu da te kontaktiraju na Mastodonu. - site_extended_description: Bilo koja dodatna informacija koja može biti korisne posetiocima i tvojim korisnicima. Može se strukturirati pomoću Markdown sintakse. - site_short_description: Kratak opis pomoću koga se na jedinstven način identifikuje tvoj server. Ko ga održava, kome je namenjen? - site_terms: Koristi sopstvenu politiku privatnosti ili ostavi prazno da bi se koristila podrazumevana. Može se strukturirati pomoću Markdown sintakse. - site_title: Način na moji može da se pozove na tvoj server osim naziva njegovog domena. + require_invite_text: Kada registracije zahtevaju ručno odobrenje, postavite da odgovor na „Zašto želite da se pridružite?“ bude obavezan, a ne opcionalan + site_contact_email: Kako korisnici mogu da kontaktiraju sa Vama za pravna pitanja ili pitanja u vezi podrške. + site_contact_username: Kako korisnici mogu da kontaktiraju sa vama na Mastodon-u. + site_extended_description: Bilo kakve dodatne informacije koje mogu biti korisne posetiocima i Vašim korisnicima. Mogu se strukturirati pomoću Markdown sintakse. + site_short_description: Kratak opis pomoću koga se na jedinstven način identifikuje Vaš server. Ko ga održava, kome je namenjen? + site_terms: Koristite sopstvenu politiku privatnosti ili ostavite prazno da bi se koristila podrazumevana. Može se strukturirati pomoću Markdown sintakse. + site_title: Način na koji ljudi mogu da referišu na Vaš server osim naziva njegovog domena. + status_page_url: URL stranice gde ljudi mogu da vide status servera dok je server oboren theme: Tema koju vide posetioci koji nisu prijavljeni i novi korisnici. - thumbnail: Slika koja se približno 2:1 prikazuje pored informacija o tvom serveru. + thumbnail: Slika u razmeri od približno 2:1 koja se prikazuje pored informacija o Vašem serveru. timeline_preview: Posetioci koji nisu prijavljeni će moći da pregledaju najnovije javne objave dostupne na serveru. trendable_by_default: Preskoči ručni pregled sadržaja koji je u trendu. Pojedinačne stavke se nakon toga i dalje mogu ukloniti iz trendova. - trends: Trendovi pokazuju koje objave, heš oznake i vesti postaju sve popularniji na tvom serveru. + trends: Trendovi pokazuju koje objave, heš oznake i vesti postaju sve popularnije na Vašem serveru. + trends_as_landing_page: Prikaži sadržaj u trendu odjavljenim korisnicima i posetiocima umesto opisa ovog servera. Zahteva da trendovi budu omogućeni. form_challenge: - current_password: Ulaziš u bezbedno područje + current_password: Ulazite u bezbedno područje imports: - data: CSV fajl izvezen sa druge Mastodont instance + data: CSV fajl izvezen sa druge Mastodon instance invite_request: - text: Ovo će nam pomoći da pregledamo tvoju prijavu + text: Ovo će nam pomoći da pregledamo Vašu prijavu ip_block: - comment: Opciono. Zapamti zašto si dodao ovo pravilo. + comment: Opciono. Zapamtite zašto ste dodali ovo pravilo. expires_in: IP adrese su ograničeni resurs, ponekad se dele i često menjaju korisnika. Zbog toga se IP blokovi na neograničeno vreme ne preporučuju. - ip: Unesi IPv4 ili IPv6 adresu. Možeš blokirati čitave opsege koristeći CIDR sintaksu. Vodi računa da sebe ne zaključaš! + ip: Unesite IPv4 ili IPv6 adresu. Možete blokirati čitave opsege koristeći CIDR sintaksu. Vodite računa da se ne zaključate! severities: no_access: Blokiraj pristup svim resursima - sign_up_block: Nove prijave neće biti moguće - sign_up_requires_approval: Nove prijave će zahtevati tvoje odobrenje - severity: Izaberi šta će se desiti sa zahtevima sa ove IP adrese + sign_up_block: Nove registracije neće biti moguće + sign_up_requires_approval: Nove registracije će zahtevati Vaše odobrenje + severity: Izaberite šta će se desiti sa zahtevima sa ove IP adrese rule: - text: Opiši pravilo ili zahtev za korisnike na ovom serveru. Potrudi se da opis bude kratak i jednostavan + text: Opišite pravilo ili uslov za korisnike na ovom serveru. Potrudite se da opis bude kratak i jednostavan sessions: otp: 'Unesite dvofaktorski kod sa Vašeg telefona ili koristite jedan od kodova za oporavak:' - webauthn: Ako je to USB ključ, obavezno ga ubaci i, ako je potrebno, pritisni ga. + webauthn: Ako je u pitanju USB ključ, obavezno ga ubacite i, ako je potrebno, pritisnite ga. + settings: + indexable: Stranica vašeg profila se može pojaviti u rezultatima pretrage na Google-u, Bing-u i ostalima. + show_application: Uvek ćete moći da vidite koja je aplikacija objavila vašu objavu. tag: - name: Mogu se samo promeniti mala slova u velika, na primer, da bi bilo čitljivije + name: Mogu se samo promeniti mala slova u velika ili obrnuto, na primer, da bi bilo čitljivije user: - chosen_languages: Kada označite, trube u izabranim jezicima će se prikazati na javnoj vremenskoj liniji + chosen_languages: Kada je označeno, objave u izabranim jezicima će biti prikazane na javnoj vremenskoj liniji role: Uloga kontroliše koje dozvole korisnik ima user_role: - color: Boja koja će se koristiti za ulogu u celom korisničkom interfejsu, kao RGB, u heksadecimalnom formatu + color: Boja koja će se koristiti za ulogu u celom korisničkom okruženju, kao RGB u heksadecimalnom formatu highlighted: Ovo čini ulogu javno vidljivom name: Javni naziv uloge, ako je uloga podešena da se prikazuje kao značka permissions_as_keys: Korisnici sa ovom ulogom će imati pristup... position: Viša uloga odlučuje o rešavanju sukoba u određenim situacijama. Određene radnje se mogu izvršiti samo na ulogama sa nižim prioritetom webhook: events: Izaberite događaje za slanje + template: Sastavite sopstveni JSON korisnih podataka koristeći promenljivu interpolaciju. Ostavite prazno za podrazumevani JSON. url: Gde će se događaji slati labels: account: + discoverable: Istakni funkcije i objave u algoritmima otkrivanja fields: name: Etiketa value: Sadržaj + indexable: Uključi javne objave u rezultatima pretrage + show_collections: Prikaži praćenja i pratioce na profilu + unlocked: Automatski prihvati nove pratioce account_alias: acct: Ručica (@) starog naloga account_migration: @@ -160,51 +176,46 @@ sr-Latn: text: Objasni zašto ovu odluku treba poništiti defaults: autofollow: Pozovite da prati vaš nalog - avatar: Avatar - bot: Ovo je nalog bota + avatar: Profilna slika + bot: Ovo je automatizovani nalog chosen_languages: Filtriraj jezike confirm_new_password: Potvrdite novu lozinku confirm_password: Potvrdite lozinku context: Filtriraj kontekste current_password: Trenutna lozinka data: Podaci - discoverable: Navedite ovaj nalog u fascikli display_name: Ime za prikaz email: Adresa e-pošte expires_in: Ističe nakon - fields: Metapodaci naloga - header: Zaglavlje + fields: Dodatna polja + header: Slika u zaglavlju honeypot: "%{label} (ne popunjavaj)" inbox_url: URL od relejnog prijemnog sandučeta irreversible: Ispustiti umesto sakriti locale: Jezik - locked: Zahtevaj zahteve za praćenje max_uses: Maksimalni broj korišćenja new_password: Nova lozinka note: Biografija otp_attempt: Dvofaktorski kod password: Lozinka phrase: Ključna reč ili fraza - setting_advanced_layout: Omogući napredni veb interfejs + setting_advanced_layout: Omogući napredno veb okruženje setting_aggregate_reblogs: Grupiši deljenja u vremenskim linijama setting_always_send_emails: Uvek šalji obaveštenja e-poštom - setting_auto_play_gif: Automatski puštaj animirane GIF-ove + setting_auto_play_gif: Automatski reprodukuj animirane GIF-ove setting_boost_modal: Prikaži dijalog za potvrdu pre davanja podrške - setting_crop_images: Izreži slike u neproširenim objavama na 16x9 setting_default_language: Jezik objavljivanja setting_default_privacy: Privatnost objava setting_default_sensitive: Uvek označi multimediju kao osetljivu - setting_delete_modal: Prikaži dijalog za potvrdu pre brisanja tuta + setting_delete_modal: Prikaži dijalog za potvrdu pre brisanja objave setting_disable_swiping: Onemogući pokrete prevlačenja setting_display_media: Prikaz medija setting_display_media_default: Podrazumevano setting_display_media_hide_all: Sakrij sve setting_display_media_show_all: Prikaži sve - setting_expand_spoilers: Uvek prošiti trube koje su označene upozorenjem sadržaja + setting_expand_spoilers: Uvek proširi objave koje su označene upozorenjem sadržaja setting_hide_network: Sakrij svoju mrežu - setting_noindex: Odjavi se od indeksiranja search engine-a setting_reduce_motion: Smanji pokrete u animacijama - setting_show_application: Otkrij aplikaciju koja se koristi za slanje postova setting_system_font_ui: Koristi sistemski font setting_theme: Tema sajta setting_trends: Prikaži današnje trendove @@ -227,6 +238,7 @@ sr-Latn: hide: Sakrij u potpunosti warn: Sakrij uz upozorenje form_admin_settings: + activity_api_enabled: Objavi prikupljenu statistiku o korisničkoj aktivnosti u API backups_retention_period: Period čuvanja korisničke arhive bootstrap_timeline_accounts: Uvek preporuči ove naloge novim korisnicima closed_registrations_message: Prilagođena poruka kada prijave nisu moguće @@ -234,6 +246,7 @@ sr-Latn: custom_css: Prilagođeni CSS mascot: Prilagođena maskota (nasleđe) media_cache_retention_period: Period čuvanja keša medija + peers_api_enabled: Objavite listu otkrivenih servera u API profile_directory: Omogući direktorijum profila registrations_mode: Ko može da se prijavi require_invite_text: Zatraži razlog za pristupanje @@ -245,11 +258,13 @@ sr-Latn: site_short_description: Opis servera site_terms: Politika privatnosti site_title: Ime servera + status_page_url: URL statusne stranice theme: Podrazumevana tema thumbnail: Sličica servera timeline_preview: Dozvoli neautorizovan pristup javnim vremenskim osama trendable_by_default: Dozvoli trendove bez prethodnog pregleda trends: Omogući trendove + trends_as_landing_page: Koristite trendove kao stranicu dočeka interactions: must_be_follower: Blokiraj obaveštenja od korisnika koji me ne prate must_be_following: Blokiraj obaveštenja od ljudi koje ne pratim @@ -260,7 +275,7 @@ sr-Latn: text: Zašto želiš da se pridružiš? ip_block: comment: Komentar - ip: Avatar + ip: IP severities: no_access: Blokiraj pristup sign_up_block: Blokiraj prijave @@ -276,9 +291,18 @@ sr-Latn: pending_account: Novi nalog treba pregledati reblog: Šalji e-poštu kada neko podrži Vaš status report: Podneta je nova prijava + software_updates: + all: Obavesti o svim ažuriranjima + critical: Obavesti samo o kritičnim ažuriranjima + label: Dostupna je nova verzija Mastodon-a + none: Nikada ne obaveštavaj o ažuriranjima (ne preporučuje se) + patch: Obavesti o ispravkama grešaka trending_tag: Novi trend treba pregledati rule: text: Pravilo + settings: + indexable: Uključi stranicu profila u pretraživače + show_application: Prikaži iz koje aplikacije ste poslali objavu tag: listable: Dozvoli da se ova heš oznaka pojavljuje u pretragama i predlozima name: Heš oznaka @@ -286,6 +310,7 @@ sr-Latn: usable: Dozvoli objavama da koriste ovu heš oznaku user: role: Uloga + time_zone: Vremenska zona user_role: color: Boja bedža highlighted: Prikaži ulogu i bedž na profilima korisnika @@ -294,9 +319,11 @@ sr-Latn: position: Prioritet webhook: events: Omogućeni događaji + template: Šablon korisnih podataka url: URL krajnje tačke 'no': Ne not_recommended: Nije preporučeno + overridden: Zamenjeno recommended: Preporučeno required: mark: "*" diff --git a/config/locales/simple_form.sr.yml b/config/locales/simple_form.sr.yml index 67c6daf4b3..da1ac81233 100644 --- a/config/locales/simple_form.sr.yml +++ b/config/locales/simple_form.sr.yml @@ -2,135 +2,151 @@ sr: simple_form: hints: + account: + discoverable: Ваше јавне објаве и профил могу бити истакнути или препоручени у различитим областима Mastodon-а и ваш профил може бити предложен другим корисницима. + display_name: Ваше пуно име или надимак. + fields: Ваша матична страница, заменице, године, све што желите. + indexable: Ваше јавне објаве се могу појавити у резултатима претраге на Mastodon-у. Људи који су ступили у интеракцију са вашим објавама ће можда моћи да их претражују. + note: 'Можете да @поменете друге људе или #хеш ознаке.' + show_collections: Људи ће моћи да прегледају ваше пратиоце и пратиоце. Људи које пратите видеће да их пратите. + unlocked: Људи ће моћи да вас прате без захтевања одобрења. Опозовите избор ако желите да прегледате захтеве за праћење и изаберите да ли да прихватите или одбијете нове пратиоце. account_alias: - acct: Наведи корисничко_име@домен налога са којег желиш да пређеш + acct: Наведите корисничко_име@домен налога са којег желите да се преселите account_migration: - acct: Наведи корисничко_име@домен налога на који желиш да пређеш + acct: Наведите корисничко_име@домен налога на који желите да се преселите account_warning_preset: - text: Можете користити синтаксу труба, као што су нпр. УРЛ-ова, тарабе и помињања + text: Можете користити синтаксу објава, као што су URL адресе, хеш ознаке и помињања title: Опционо. Није видљиво примаоцу admin_account_action: - include_statuses: Корисник ће видети које су објаве проузроковале модерирање или упозорење - send_email_notification: Корисник ће добити објашњење тога шта му се десило са налога - text_html: Опционално. Можете користити синтаксу труба. Можете додати упозоравајућа преподешавање да сачувате време + include_statuses: Корисник ће видети које су објаве проузроковале модерацијску радњу или упозорење + send_email_notification: Корисник ће добити објашњење тога шта му се десило са налогом + text_html: Опционално. Можете користити синтаксу објава. Можете додати унапред одређене поставке упозорења за уштеду времена type_html: Изаберите шта да радите са %{acct} types: - disable: Спречи корисника да користи свој налог, али немој брисати или сакривати његов садржај. - none: Користи ово да пошаљеш упозорење кориснику, без покретања било које друге акције. + disable: Спречава корисника да користи свој налог, али не брише нити сакрива његове садржаје. + none: Користите ово да пошаљете упозорење кориснику без покретања било које друге радње. sensitive: Учини да сви медијски прилози овог корисника присилно буду означени као осетљиви. + silence: Спречава корисника да прави јавне објаве, сакрива његове објаве и обавештења од људи који га не прате. Затвара све пријаве поднете против овог налога. + suspend: Спречава сву интеракцију од овог налога и ка овом налогу и брише његов садржај. Опозиво у року од 30 дана. Затвара све пријаве поднете против овог налога. warning_preset_id: Опционално. Можете и даље додати прилагођени текст на крај пресета announcement: - all_day: Биће приказани само датуми временског опсега који су означени + all_day: Када је ова опција означена, само датуми из временског опсега ће бити приказани ends_at: Опционо. Објава ће бити аутоматски опозвана у овом тренутку - scheduled_at: Остави празно да би најава била одмах објављена + scheduled_at: Оставите празно да бисте одмах објавили обавештење starts_at: Опционо. У случају да је најава везана за одређени временски распон - text: Можеш користити пост синтаксу. Води рачуна о простору који ће објава заузимати на екрану корисника + text: Можете користити синтаксу објава. Молимо вас водите рачуна о простору који ће објава заузимати на екрану корисника appeal: - text: На брисање се можеш жалити само једном + text: Можете поднети само једну жалбу на уписан преступ defaults: autofollow: Особе које се пријаве кроз позивнице ће вас аутоматски запратити - avatar: PNG, GIF или JPG. Највише %{size}. Биће смањена на %{dimensions}px - bot: Овај налог углавном врши аутоматизоване радње и можда се не надгледа + avatar: PNG, GIF или JPG. Највише %{size}. Биће смањено на %{dimensions}px + bot: Даје другима до знања да овај налог углавном врши аутоматизоване радње и можда се не надгледа context: Један или више контекста у којима треба да се примени филтер - current_password: Унеси лозинку текућег налога из безбедносних разлога - current_username: Унеси корисничко име текућег налога за потврду - digest: Послато после дужег периода неактивности са прегледом свих битних ствари које сте добили док сте били одсутни - discoverable: Дозволи непознатим корисницима да открију твој налог путем препорука, трендова и других функција - email: Биће вам послата е-пошта са потврдом - fields: Можете имати до 4 ставке приказане као табела на вашем налогу - header: PNG, GIF или JPG. Највише %{size}. Биће смањена на %{dimensions}px + current_password: Из безбедносних разлога молимо Вас унесите лозинку тренутног налога + current_username: Да бисте потврдили, Молимо Вас унесите корисничко име тренутно активног налога + digest: Шаље се само после дужег периода неактивности и само у случају да сте примили једну или више личних порука током Вашег одсуства + email: Биће Вам послат мејл са потврдом + header: PNG, GIF или JPG. Највише %{size}. Биће смањено на %{dimensions}px inbox_url: Копирајте URL са насловне стране релеја који желите користити - irreversible: Филтриранe трубе ће нестати неповратно, чак и ако је филтер касније уклоњен - locale: Језик корисничког интерфејса, е-поште и мобилних обавештења - locked: Захтева да појединачно одобрите пратиоце + irreversible: Филтриранe обајве ће нестати неповратно, чак и ако је филтер касније уклоњен + locale: Језик корисничког окружења, е-поште и мобилних обавештења password: Користите најмање 8 знакова - phrase: Биће упарена без обзира на велико или мало слово у тексту или упозорења о садржају трубе - scopes: Којим API-јима ће апликација дозволити приступ. Ако изаберете опсег највишег нивоа, не морате одабрати појединачне. - setting_aggregate_reblogs: Не показуј нова дељења за трубе које су недавно подељене (утиче само на недавно примљена дељења) - setting_always_send_emails: Обавештења е-поштом се по правилу неће слати када активно користиш Мастодон + phrase: Биће упарена без обзира на велико или мало слово у тексту или упозорења о садржају објаве + scopes: Којим API-јима ће апликација имати приступ. Ако изаберете опсег највишег нивоа, не морате одабрати појединачне. + setting_aggregate_reblogs: Не приказуј нова подржавања за објаве које су недавно подржане (утиче само на недавно примљена подржавања) + setting_always_send_emails: Обавештења е-поштом се по правилу неће слати када активно користите Mastodon setting_default_sensitive: Осетљиви медији су подразумевано скривени и могу се открити кликом setting_display_media_default: Сакриј медије означене као осетљиве setting_display_media_hide_all: Увек сакриј све медије setting_display_media_show_all: Увек прикажи медије означене као осетљиве - setting_hide_network: Кога пратите и ко вас прати неће бити приказано на вашем налогу - setting_noindex: Утиче на Ваш јавни налог и статусне стране - setting_show_application: Апликација коју користиш за објављивање биће приказана у детаљном приказу твојих објава - setting_use_blurhash: Градијент се заснива на бојама скривених визуелних приказа, али прикрива све детаље - setting_use_pending_items: Сакриј ажурирања временске осе иза клика уместо аутоматског померања извора објава - username: Ваш надимак ће бити јединствен на %{domain} - whole_word: Када је кључна реч или фраза искључиво алфанумеричка, биће примењена само ако се подудара са целом речи + setting_use_blurhash: Градијенти се формирају на основу бојâ скривених слика и замућују приказ, прикривајући детаље + setting_use_pending_items: Сакрива ажурирања временске линије иза клика уместо аутоматског ажурирања и померања временске линије + username: Можете користити слова, бројеве и доње црте + whole_word: Када је кључна реч или фраза искључиво алфанумеричка, биће примењена само ако се подудара са целом речjу domain_allow: domain: Овај домен ће моћи да преузима податке са овог сервера и долазни подаци са њега ће се обрађивати и чувати email_domain_block: domain: Ово може бити име домена које се појављује у адреси е-поште или MX записа који користи. Они ће бити проверени приликом регистрације. with_dns_records: Биће учињен покушај да се разреше DNS записи датог домена и резултати ће такође бити блокирани featured_tag: - name: 'Ево неких од хеш ознака које сте недавно користили:' + name: 'Ево неких од хеш ознака које сте у претходном периоду често користили:' filters: - action: Изабери коју радњу треба извршити када објава одговара филтеру + 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: Можеш да примениш прилагођене стилове на веб верзији Мастодона. - mascot: Замењује илустрацију у напредном веб интерфејсу. + closed_registrations_message: Приказује се када су регистрације затворене + content_cache_retention_period: Све објаве и подржавања са других сервера ће бити избрисани након наведеног броја дана. Неке објаве се можда неће моћи опоравити. Сви повезани обележивачи, омиљени и подржавања ће такође бити изгубљени и немогуће је опозвати радњу. + custom_css: Можете да примените прилагођене стилове на веб верзији Mastodon-а. + mascot: Замењује илустрацију у напредном веб окружењу. media_cache_retention_period: Када се постави на позитивну вредност, преузете медијске датотеке ће бити избрисане након наведеног броја дана, и поново преузете на захтев. + peers_api_enabled: Листа домена са којима се овај сервер сусрео у федиверзуму. Овде нису садржани подаци о томе да ли се Ваш сервер федерише са другим серверима, већ само да Ваш сервер зна за њих. Ове информације користе сервиси који прикупљају податке и воде статистику о федерацији у ширем смислу. profile_directory: Директоријум профила наводи све кориснике који су се определили да буду видљиви. - require_invite_text: Када регистрације захтевају ручно одобрење, постави да унос текста „Зашто желиш да се придружиш?“ буде обавезан, а не опциони - site_contact_email: Како корисници могу да те контактирају за правна питања или питања у вези подршке. - site_contact_username: Како корисници могу да те контактирају на Мастодону. - site_extended_description: Било која додатна информација која може бити корисне посетиоцима и твојим корисницима. Може се структурирати помоћу Markdown синтаксе. - site_short_description: Кратак опис помоћу кога се на јединствен начин идентификује твој сервер. Ко га одржава, коме је намењен? - site_terms: Користи сопствену политику приватности или остави празно да би се користила подразумевана. Може се структурирати помоћу Markdown синтаксе. - site_title: Начин на моји може да се позове на твој сервер осим назива његовог домена. + require_invite_text: Када регистрације захтевају ручно одобрење, поставите да одговор на „Зашто желите да се придружите?“ буде обавезан, а не опционалан + site_contact_email: Како корисници могу да контактирају са Вама за правна питања или питања у вези подршке. + site_contact_username: Како корисници могу да контактирају са вама на Mastodon-у. + site_extended_description: Било какве додатне информације које могу бити корисне посетиоцима и Вашим корисницима. Могу се структурирати помоћу Markdown синтаксе. + site_short_description: Кратак опис помоћу кога се на јединствен начин идентификује Ваш сервер. Ко га одржава, коме је намењен? + site_terms: Користите сопствену политику приватности или оставите празно да би се користила подразумевана. Може се структурирати помоћу Markdown синтаксе. + site_title: Начин на који људи могу да реферишу на Ваш сервер осим назива његовог домена. + status_page_url: URL странице где људи могу да виде статус сервера док је сервер оборен theme: Тема коју виде посетиоци који нису пријављени и нови корисници. - thumbnail: Слика која се приближно 2:1 приказује поред информација о твом серверу. + thumbnail: Слика у размери од приближно 2:1 која се приказује поред информација о Вашем серверу. timeline_preview: Посетиоци који нису пријављени ће моћи да прегледају најновије јавне објаве доступне на серверу. trendable_by_default: Прескочи ручни преглед садржаја који је у тренду. Појединачне ставке се након тога и даље могу уклонити из трендова. - trends: Трендови показују које објаве, хеш ознаке и вести постају све популарнији на твом серверу. + trends: Трендови показују које објаве, хеш ознаке и вести постају све популарније на Вашем серверу. + trends_as_landing_page: Прикажи садржај у тренду одјављеним корисницима и посетиоцима уместо описа овог сервера. Захтева да трендови буду омогућени. form_challenge: - current_password: Улазиш у безбедно подручје + current_password: Улазите у безбедно подручје imports: - data: CSV фајл извезен са друге Мастодонт инстанце + data: CSV фајл извезен са друге Mastodon инстанце invite_request: - text: Ово ће нам помоћи да прегледамо твоју пријаву + text: Ово ће нам помоћи да прегледамо Вашу пријаву ip_block: - comment: Опционо. Запамти зашто си додао ово правило. + comment: Опционо. Запамтите зашто сте додали ово правило. expires_in: IP адресе су ограничени ресурс, понекад се деле и често мењају корисника. Због тога се IP блокови на неограничено време не препоручују. - ip: Унеси IPv4 или IPv6 адресу. Можеш блокирати читаве опсеге користећи CIDR синтаксу. Води рачуна да себе не закључаш! + ip: Унесите IPv4 или IPv6 адресу. Можете блокирати читаве опсеге користећи CIDR синтаксу. Водите рачуна да се не закључате! severities: no_access: Блокирај приступ свим ресурсима - sign_up_block: Нове пријаве неће бити могуће - sign_up_requires_approval: Нове пријаве ће захтевати твоје одобрење - severity: Изабери шта ће се десити са захтевима са ове IP адресе + sign_up_block: Нове регистрације неће бити могуће + sign_up_requires_approval: Нове регистрације ће захтевати Ваше одобрење + severity: Изаберите шта ће се десити са захтевима са ове IP адресе rule: - text: Опиши правило или захтев за кориснике на овом серверу. Потруди се да опис буде кратак и једноставан + text: Опишите правило или услов за кориснике на овом серверу. Потрудите се да опис буде кратак и једноставан sessions: otp: 'Унесите двофакторски код са Вашег телефона или користите један од кодова за опоравак:' - webauthn: Ако је то USB кључ, обавезно га убаци и, ако је потребно, притисни га. + webauthn: Ако је у питању USB кључ, обавезно га убаците и, ако је потребно, притисните га. + settings: + indexable: Страница вашег профила се може појавити у резултатима претраге на Google-у, Bing-у и осталима. + show_application: Увек ћете моћи да видите која је апликација објавила вашу објаву. tag: - name: Могу се само променити мала слова у велика, на пример, да би било читљивије + name: Могу се само променити мала слова у велика или обрнуто, на пример, да би било читљивије user: - chosen_languages: Када означите, трубе у изабраним језицима ће се приказати на јавној временској линији + chosen_languages: Када је означено, објаве у изабраним језицима ће бити приказане на јавној временској линији role: Улога контролише које дозволе корисник има user_role: - color: Боја која ће се користити за улогу у целом корисничком интерфејсу, као RGB, у хексадецималном формату + color: Боја која ће се користити за улогу у целом корисничком окружењу, као RGB у хексадецималном формату highlighted: Ово чини улогу јавно видљивом name: Јавни назив улоге, ако је улога подешена да се приказује као значка permissions_as_keys: Корисници са овом улогом ће имати приступ... position: Виша улога одлучује о решавању сукоба у одређеним ситуацијама. Одређене радње се могу извршити само на улогама са нижим приоритетом webhook: events: Изаберите догађаје за слање + template: Саставите сопствени JSON корисних података користећи променљиву интерполацију. Оставите празно за подразумевани JSON. url: Где ће се догађаји слати labels: account: + discoverable: Истакни функције и објаве у алгоритмима откривања fields: name: Етикета value: Садржај + indexable: Укључи јавне објаве у резултатима претраге + show_collections: Прикажи праћења и пратиоце на профилу + unlocked: Аутоматски прихвати нове пратиоце account_alias: acct: Ручица (@) старог налога account_migration: @@ -160,51 +176,46 @@ sr: text: Објасни зашто ову одлуку треба поништити defaults: autofollow: Позовите да прати ваш налог - avatar: Аватар - bot: Ово је налог бота + avatar: Профилна слика + bot: Ово је аутоматизовани налог chosen_languages: Филтрирај језике confirm_new_password: Потврдите нову лозинку confirm_password: Потврдите лозинку context: Филтрирај контексте current_password: Тренутна лозинка data: Подаци - discoverable: Наведите овај налог у фасцикли display_name: Име за приказ email: Адреса е-поште expires_in: Истиче након - fields: Метаподаци налога - header: Заглавље + fields: Додатна поља + header: Слика у заглављу honeypot: "%{label} (не попуњавај)" inbox_url: URL од релејног пријемног сандучета irreversible: Испустити уместо сакрити locale: Језик - locked: Захтевај захтеве за праћење max_uses: Максимални број коришћења new_password: Нова лозинка note: Биографија otp_attempt: Двофакторски код password: Лозинка phrase: Кључна реч или фраза - setting_advanced_layout: Омогући напредни веб интерфејс + setting_advanced_layout: Омогући напредно веб окружење setting_aggregate_reblogs: Групиши дељења у временским линијама setting_always_send_emails: Увек шаљи обавештења е-поштом - setting_auto_play_gif: Аутоматски пуштај анимиране GIF-ове + setting_auto_play_gif: Аутоматски репродукуј анимиране GIF-ове setting_boost_modal: Прикажи дијалог за потврду пре давања подршке - setting_crop_images: Изрежи слике у непроширеним објавама на 16x9 setting_default_language: Језик објављивања setting_default_privacy: Приватност објава setting_default_sensitive: Увек означи мултимедију као осетљиву - setting_delete_modal: Прикажи дијалог за потврду пре брисања тута + setting_delete_modal: Прикажи дијалог за потврду пре брисања објаве setting_disable_swiping: Онемогући покрете превлачења setting_display_media: Приказ медија setting_display_media_default: Подразумевано setting_display_media_hide_all: Сакриј све setting_display_media_show_all: Прикажи све - setting_expand_spoilers: Увек прошити трубе које су означене упозорењем садржаја + setting_expand_spoilers: Увек прошири објаве које су означене упозорењем садржаја setting_hide_network: Сакриј своју мрежу - setting_noindex: Одјави се од индексирања search engine-а setting_reduce_motion: Смањи покрете у анимацијама - setting_show_application: Откриј апликацију која се користи за слање постова setting_system_font_ui: Користи системски фонт setting_theme: Тема сајта setting_trends: Прикажи данашње трендове @@ -227,6 +238,7 @@ sr: hide: Сакриј у потпуности warn: Сакриј уз упозорење form_admin_settings: + activity_api_enabled: Објави прикупљену статистику о корисничкој активности у API backups_retention_period: Период чувања корисничке архиве bootstrap_timeline_accounts: Увек препоручи ове налоге новим корисницима closed_registrations_message: Прилагођена порука када пријаве нису могуће @@ -234,6 +246,7 @@ sr: custom_css: Прилагођени CSS mascot: Прилагођена маскота (наслеђе) media_cache_retention_period: Период чувања кеша медија + peers_api_enabled: Објавите листу откривених сервера у API profile_directory: Омогући директоријум профила registrations_mode: Ко може да се пријави require_invite_text: Затражи разлог за приступање @@ -245,11 +258,13 @@ sr: site_short_description: Опис сервера site_terms: Политика приватности site_title: Име сервера + status_page_url: URL статусне странице theme: Подразумевана тема thumbnail: Сличица сервера timeline_preview: Дозволи неауторизован приступ јавним временским осама trendable_by_default: Дозволи трендове без претходног прегледа trends: Омогући трендове + trends_as_landing_page: Користите трендове као страницу дочека interactions: must_be_follower: Блокирај обавештења од корисника који ме не прате must_be_following: Блокирај обавештења од људи које не пратим @@ -276,9 +291,18 @@ sr: pending_account: Нови налог треба прегледати reblog: Шаљи е-пошту када неко подржи Ваш статус report: Поднета је нова пријава + software_updates: + all: Обавести о свим ажурирањима + critical: Обавести само о критичним ажурирањима + label: Доступна је нова верзија Mastodon-а + none: Никада не обавештавај о ажурирањима (не препоручује се) + patch: Обавести о исправкама грешака trending_tag: Нови тренд треба прегледати rule: text: Правило + settings: + indexable: Укључи страницу профила у претраживаче + show_application: Прикажи из које апликације сте послали објаву tag: listable: Дозволи да се ова хеш ознака појављује у претрагама и предлозима name: Хеш ознака @@ -286,6 +310,7 @@ sr: usable: Дозволи објавама да користе ову хеш ознаку user: role: Улога + time_zone: Временска зона user_role: color: Боја беџа highlighted: Прикажи улогу и беџ на профилима корисника @@ -294,9 +319,11 @@ sr: position: Приоритет webhook: events: Омогућени догађаји + template: Шаблон корисних података url: URL крајње тачке 'no': Не not_recommended: Није препоручено + overridden: Замењено recommended: Препоручено required: mark: "*" diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml index ede921615c..b01436b415 100644 --- a/config/locales/simple_form.sv.yml +++ b/config/locales/simple_form.sv.yml @@ -2,6 +2,14 @@ sv: simple_form: hints: + account: + discoverable: Dina offentliga inlägg och din profil kan komma att presenteras eller rekommenderas inom olika områden av Mastodon och din profil kan komma att föreslås till andra användare. + display_name: Ditt fullständiga namn eller ditt roliga namn. + fields: Din hemsida, ditt pronomen, din ålder, vadhelst du vill. + indexable: Dina offentliga inlägg kan visas i sökresultat på Mastodon. Personer som har interagerat med dina inlägg kan söka dem oavsett. + note: 'Du kan @nämna andra personer eller #hashtaggar.' + show_collections: Andra kan se vem du följer och vem som följer dig. De du följer kan alltid se att du följer dem. + unlocked: Andra kommer att kunna följa dig utan att begära godkännande. Avmarkera om du vill granska följeslagare och välja om du vill acceptera eller avvisa nya följare. account_alias: acct: Ange användarnamn@domän för kontot som du vill flytta från account_migration: @@ -18,6 +26,8 @@ sv: disable: Förhindra användaren från att använda sitt konto, men radera eller dölj inte innehållet. none: Använd det här för att skicka en varning till användaren, utan att vidta någon ytterligare åtgärd. sensitive: Tvinga alla denna användares mediebilagor till att flaggas som känsliga. + silence: Hindra användaren från att kunna göra offentliga inlägg, göm deras inlägg och notiser från folk som inte följer dem. Stänger alla anmälningar mot detta kontot. + suspend: Förhindrar all interaktion från eller till detta konto och ta bort dess innehåll. Går att ångra inom 30 dagar. Stänger alla anmälningar mot detta konto. warning_preset_id: Valfri. Du kan lägga till anpassad text i slutet av förinställningen announcement: all_day: När det är markerat visas endast datum för tidsintervallet @@ -35,14 +45,11 @@ sv: current_password: Av säkerhetsskäl krävs lösenordet till det nuvarande kontot current_username: Ange det nuvarande kontots användarnamn för att bekräfta digest: Skickas endast efter en lång period av inaktivitet och endast om du har fått några personliga meddelanden i din frånvaro - discoverable: Tillåt att ditt konto upptäcks av främlingar genom rekommendationer, trender och andra funktioner email: Du kommer att få ett bekräftelsemeddelande via e-post - fields: Du kan ha upp till 4 objekt visade som en tabell på din profil header: PNG, GIF eller JPG. Högst %{size}. Kommer att skalas ner till %{dimensions}px inbox_url: Kopiera webbadressen från hemsidan av det ombud du vill använda irreversible: Filtrerade inlägg kommer att försvinna oåterkalleligt, även om filter tas bort senare locale: Språket för användargränssnittet, e-postmeddelanden och push-aviseringar - locked: Kräver att du manuellt godkänner följare password: Använd minst 8 tecken phrase: Matchas oavsett användande i text eller innehållsvarning för ett inlägg scopes: 'Vilka API: er applikationen kommer tillåtas åtkomst till. Om du väljer en omfattning på högstanivån behöver du inte välja individuella sådana.' @@ -52,12 +59,9 @@ sv: setting_display_media_default: Dölj media markerad som känslig setting_display_media_hide_all: Dölj alltid all media setting_display_media_show_all: Visa alltid media markerad som känslig - setting_hide_network: Vem du följer och vilka som följer dig kommer inte att visas på din profilsida - setting_noindex: Påverkar din offentliga profil och statussidor - setting_show_application: Applikationen du använder för att göra inlägg kommer visas i detaljvyn för dina inlägg setting_use_blurhash: Gradienter är baserade på färgerna av de dolda objekten men fördunklar alla detaljer setting_use_pending_items: Dölj tidslinjeuppdateringar bakom ett klick istället för att automatiskt bläddra i flödet - username: Ditt användarnamn måste vara unikt på %{domain} + username: Du kan använda bokstäver, siffror och understreck whole_word: När sökordet eller frasen endast är alfanumerisk, kommer det endast att tillämpas om det matchar hela ordet domain_allow: domain: Denna domän kommer att kunna hämta data från denna server och inkommande data från den kommer att behandlas och lagras @@ -72,6 +76,7 @@ sv: hide: Dölj det filtrerade innehållet helt (beter sig som om det inte fanns) warn: Dölj det filtrerade innehållet bakom en varning som visar filtrets rubrik form_admin_settings: + activity_api_enabled: Antalet lokalt publicerade inlägg, aktiva användare och nya registrerade konton per vecka backups_retention_period: Behåll genererade användararkiv i 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 @@ -79,6 +84,7 @@ sv: custom_css: Du kan använda anpassade stilar på webbversionen av Mastodon. mascot: Åsidosätter illustrationen i det avancerade webbgränssnittet. media_cache_retention_period: Nedladdade mediefiler kommer raderas efter det angivna antalet dagar, om inställt till ett positivt värde, och laddas ned på nytt vid behov. + peers_api_enabled: En lista över domänen den här servern har stött på i fediversum. Ingen data inkluderas om du har federerat med servern, bara att din server känner till den. Detta används av tjänster som samlar statistik om federering i allmänhet. profile_directory: Profilkatalogen visar alla användare som har samtyckt till att bli upptäckbara. require_invite_text: Gör fältet "Varför vill du gå med?" obligatoriskt när nyregistreringar kräver manuellt godkännande site_contact_email: Hur människor kan nå dig för juridiska spörsmål eller supportfrågor. @@ -87,11 +93,13 @@ sv: site_short_description: En kort beskrivning för att unikt identifiera din server. Vem är det som driver den, vilka är den till för? site_terms: Använd din egen sekretesspolicy eller lämna tomt för att använda standardinställningen. Kan struktureras med Markdown-syntax. site_title: Hur folk kan hänvisa till din server förutom med dess domännamn. + status_page_url: URL till en sida där personer kan se serverns status under ett driftavbrott theme: Tema som utloggade besökare och nya användare ser. thumbnail: En bild i cirka 2:1-proportioner som visas tillsammans med din serverinformation. timeline_preview: Utloggade besökare kommer kunna bläddra bland de senaste offentliga inläggen som finns på servern. trendable_by_default: Hoppa över manuell granskning av trendande innehåll. Enskilda objekt kan ändå raderas från trender retroaktivt. trends: Trender visar vilka inlägg, hashtaggar och nyheter det pratas om på din server. + trends_as_landing_page: Visa trendande innehåll för utloggade användare och besökare istället för en beskrivning om servern. Kräver att trender är aktiverat. form_challenge: current_password: Du går in i ett säkert område imports: @@ -112,6 +120,9 @@ sv: sessions: otp: 'Ange tvåfaktorskoden som genererades av din telefonapp, eller använd någon av dina återställningskoder:' webauthn: Om det är en USB-nyckel se till att sätta in den och, om nödvändigt, tryck på den. + settings: + indexable: Din profilsida kan visas i sökresultat på Google, Bing och andra sökmotorer. + show_application: Du kommer alltid att kunna se vilken app som publicerat ditt inlägg oavsett. tag: name: Du kan bara ändra skriftläget av bokstäverna, till exempel, för att göra det mer läsbart user: @@ -125,12 +136,17 @@ sv: position: Högre roll avgör konfliktlösning i vissa situationer. Vissa åtgärder kan endast utföras på roller med lägre prioritet webhook: events: Välj händelser att skicka + template: Skriv din egen JSON-nyttolast med variabel interpolation. Lämna tomt för förvald JSON. url: Dit händelser kommer skickas labels: account: + discoverable: Presentera profil och inlägg med upptäcktsalgoritmer fields: name: Etikett value: Innehåll + indexable: Inkludera offentliga inlägg i sökresultaten + show_collections: Göm följare och följeslagare på profilen + unlocked: Godkänn nya följare automatiskt account_alias: acct: Namnet på det gamla kontot account_migration: @@ -168,7 +184,6 @@ sv: context: Filtrera sammanhang current_password: Nuvarande lösenord data: Data - discoverable: Föreslå konto för andra display_name: Visningsnamn email: E-postadress expires_in: Utgår efter @@ -178,7 +193,6 @@ sv: inbox_url: Webbadress för ombudsinkorg irreversible: Släng istället för att dölja locale: Språk för gränssnittet - locked: Kräv följförfrågningar max_uses: Max antal användningar new_password: Nytt lösenord note: Biografi @@ -190,7 +204,6 @@ sv: setting_always_send_emails: Skicka alltid e-postnotiser setting_auto_play_gif: Spela upp GIF:ar automatiskt setting_boost_modal: Visa bekräftelsedialog innan boostning - setting_crop_images: Beskär bilder i icke-utökade inlägg till 16x9 setting_default_language: Inläggsspråk setting_default_privacy: Inläggsintegritet setting_default_sensitive: Markera alltid media som känsligt @@ -202,9 +215,7 @@ sv: setting_display_media_show_all: Visa alla setting_expand_spoilers: Utöka alltid tutningar markerade med innehållsvarningar setting_hide_network: Göm ditt nätverk - setting_noindex: Uteslutning av sökmotorindexering setting_reduce_motion: Minska rörelser i animationer - setting_show_application: Visa programmet som används för att skicka tutningar setting_system_font_ui: Använd systemets standardfont setting_theme: Sidans tema setting_trends: Visa dagens trender @@ -227,6 +238,7 @@ sv: hide: Dölj helt warn: Dölj med en varning form_admin_settings: + activity_api_enabled: Publicera aggregerad statistik om användaraktivitet i API:et backups_retention_period: Lagringsperiod för användararkivet bootstrap_timeline_accounts: Rekommendera alltid dessa konton till nya användare closed_registrations_message: Anpassat meddelande när nyregistreringar inte är tillgängliga @@ -234,6 +246,7 @@ sv: custom_css: Anpassad CSS mascot: Anpassad maskot (tekniskt arv) media_cache_retention_period: Tid för bibehållande av mediecache + peers_api_enabled: Publicera lista över upptäckta servrar i API:et profile_directory: Aktivera profilkatalog registrations_mode: Vem kan registrera sig require_invite_text: Kräv anledning för att gå med @@ -245,11 +258,13 @@ sv: site_short_description: Serverbeskrivning site_terms: Integritetspolicy site_title: Servernamn + status_page_url: URL för statussida theme: Standardtema thumbnail: Serverns tumnagelbild timeline_preview: Tillåt oautentiserad åtkomst till offentliga tidslinjer trendable_by_default: Tillåt trender utan föregående granskning trends: Aktivera trender + trends_as_landing_page: Använd trender som landningssida interactions: must_be_follower: Blockera notiser från icke-följare must_be_following: Blockera notiser från personer du inte följer @@ -276,9 +291,18 @@ sv: pending_account: Ett nytt konto behöver granskas reblog: Någon boostade ditt inlägg report: En ny rapport har skickats + software_updates: + all: Meddela om alla uppdateringar + critical: Meddela endast om kritiska uppdateringar + label: En ny version av Mastodon är tillgänglig + none: Meddela inte om uppdateringar (rekommenderas inte) + patch: Meddela vid buggfix-uppdateringar trending_tag: En ny trend kräver granskning rule: text: Regel + settings: + indexable: Inkludera profilsidan i sökmotorer + show_application: Visa från vilket program du skickade ett inlägg tag: listable: Tillåt denna hashtagg att visas i sökningar och förslag name: Hashtagg @@ -286,6 +310,7 @@ sv: usable: Tillåt inlägg att använda denna hashtagg user: role: Roll + time_zone: Tidszon user_role: color: Emblemsfärg highlighted: Visa roll som emblem på användarprofiler @@ -294,9 +319,11 @@ sv: position: Prioritet webhook: events: Aktiverade händelser + template: Lastmall url: Slutpunkts-URL 'no': Nej not_recommended: Rekommenderas inte + overridden: Åsidosatt recommended: Rekommenderad required: mark: "*" diff --git a/config/locales/simple_form.ta.yml b/config/locales/simple_form.ta.yml index 3dbea2009d..a3819e5eb5 100644 --- a/config/locales/simple_form.ta.yml +++ b/config/locales/simple_form.ta.yml @@ -53,11 +53,9 @@ ta: context: அமைப்பு current_password: தற்போதைய கடவுச்சொல் data: தரவு - discoverable: கோப்பகத்தில் இந்த கணக்கை பட்டியலிடுங்கள் email: மின்னஞ்சல் முகவரி header: தலைப்பு locale: பயனர் இடைமுக மொழி - locked: கணக்கைப் பூட்டு max_uses: பயன்பாடுகளின் அதிகபட்ச எண்ணிக்கை new_password: புதிய கடவுச்சொல் note: சுயசரிதை diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml index ed111ecc90..c388001888 100644 --- a/config/locales/simple_form.th.yml +++ b/config/locales/simple_form.th.yml @@ -2,6 +2,14 @@ th: simple_form: hints: + account: + discoverable: อาจแสดงหรือแนะนำโพสต์และโปรไฟล์สาธารณะของคุณในพื้นที่ต่าง ๆ ของ Mastodon และอาจเสนอแนะโปรไฟล์ของคุณให้กับผู้ใช้อื่น ๆ + display_name: ชื่อเต็มของคุณหรือชื่อแบบสนุกสนานของคุณ + fields: หน้าแรก, สรรพนาม, อายุของคุณ สิ่งใดก็ตามที่คุณต้องการ + indexable: โพสต์สาธารณะของคุณอาจปรากฏในผลลัพธ์การค้นหาใน Mastodon ผู้คนที่ได้โต้ตอบกับโพสต์ของคุณอาจสามารถค้นหาโพสต์เหล่านั้นได้ไม่ว่าอย่างไรก็ตาม + note: 'คุณสามารถ @กล่าวถึง ผู้คนอื่น ๆ หรือ #แฮชแท็ก' + show_collections: ผู้คนจะสามารถเรียกดูการติดตามและผู้ติดตามของคุณ ผู้คนที่คุณติดตามจะเห็นว่าคุณติดตามเขาไม่ว่าอย่างไรก็ตาม + unlocked: ผู้คนจะสามารถติดตามคุณได้โดยไม่ต้องขอการอนุมัติ เลิกกาเครื่องหมายหากคุณต้องการตรวจทานคำขอติดตามและเลือกว่าจะยอมรับหรือปฏิเสธผู้ติดตามใหม่ account_alias: acct: ระบุ username@domain ของบัญชีที่คุณต้องการย้ายจาก account_migration: @@ -31,22 +39,19 @@ th: text: คุณสามารถอุทธรณ์การดำเนินการได้เพียงครั้งเดียวเท่านั้น defaults: autofollow: ผู้คนที่ลงทะเบียนผ่านคำเชิญจะติดตามคุณโดยอัตโนมัติ - avatar: PNG, GIF หรือ JPG สูงสุด %{size} จะถูกย่อขนาดเป็น %{dimensions}px + avatar: PNG, GIF หรือ JPG สูงสุด %{size} จะได้รับการย่อขนาดเป็น %{dimensions}px bot: ส่งสัญญาณให้ผู้อื่นว่าบัญชีทำการกระทำแบบอัตโนมัติเป็นหลักและอาจไม่ได้รับการสังเกตการณ์ context: หนึ่งหรือหลายบริบทที่ตัวกรองควรนำไปใช้ current_password: เพื่อวัตถุประสงค์ด้านความปลอดภัย โปรดป้อนรหัสผ่านของบัญชีปัจจุบัน current_username: เพื่อยืนยัน โปรดป้อนชื่อผู้ใช้ของบัญชีปัจจุบัน digest: ส่งเฉพาะหลังจากไม่มีการใช้งานเป็นเวลานานและในกรณีที่คุณได้รับข้อความส่วนบุคคลใด ๆ เมื่อคุณไม่อยู่เท่านั้น - discoverable: อนุญาตให้คนแปลกหน้าค้นพบบัญชีของคุณได้ผ่านคำแนะนำ, แนวโน้ม และคุณลักษณะอื่น ๆ - email: คุณจะได้รับอีเมลยืนยัน - fields: คุณสามารถมีได้มากถึง 4 รายการแสดงเป็นตารางในโปรไฟล์ของคุณ - header: PNG, GIF หรือ JPG สูงสุด %{size} จะถูกย่อขนาดเป็น %{dimensions}px + email: คุณจะได้รับอีเมลการยืนยัน + header: PNG, GIF หรือ JPG สูงสุด %{size} จะได้รับการย่อขนาดเป็น %{dimensions}px inbox_url: คัดลอก URL จากหน้าแรกของรีเลย์ที่คุณต้องการใช้ irreversible: โพสต์ที่กรองอยู่จะหายไปอย่างถาวร แม้ว่าจะเอาตัวกรองออกในภายหลังก็ตาม locale: ภาษาของส่วนติดต่อผู้ใช้, อีเมล และการแจ้งเตือนแบบผลัก - locked: ควบคุมผู้ที่สามารถติดตามคุณด้วยตนเองได้โดยอนุมัติคำขอติดตาม password: ใช้อย่างน้อย 8 ตัวอักษร - phrase: จะถูกจับคู่โดยไม่คำนึงถึงตัวพิมพ์ใหญ่เล็กในข้อความหรือคำเตือนเนื้อหาของโพสต์ + phrase: จะได้รับการจับคู่โดยไม่คำนึงถึงตัวพิมพ์ใหญ่เล็กในข้อความหรือคำเตือนเนื้อหาของโพสต์ scopes: API ใดที่จะอนุญาตให้แอปพลิเคชันเข้าถึง หากคุณเลือกขอบเขตระดับบนสุด คุณไม่จำเป็นต้องเลือกขอบเขตแต่ละรายการ setting_aggregate_reblogs: ไม่แสดงการดันใหม่สำหรับโพสต์ที่เพิ่งดัน (มีผลต่อการดันที่ได้รับใหม่เท่านั้น) setting_always_send_emails: โดยปกติจะไม่ส่งการแจ้งเตือนอีเมลเมื่อคุณกำลังใช้ Mastodon อยู่ @@ -54,12 +59,9 @@ th: setting_display_media_default: ซ่อนสื่อที่มีการทำเครื่องหมายว่าละเอียดอ่อน setting_display_media_hide_all: ซ่อนสื่อเสมอ setting_display_media_show_all: แสดงสื่อเสมอ - setting_hide_network: จะซ่อนผู้ที่คุณติดตามและผู้ที่ติดตามคุณในโปรไฟล์ของคุณ - setting_noindex: มีผลต่อโปรไฟล์สาธารณะและหน้าโพสต์ของคุณ - setting_show_application: จะแสดงแอปพลิเคชันที่คุณใช้ในการโพสต์ในมุมมองโดยละเอียดของโพสต์ของคุณ - setting_use_blurhash: การไล่ระดับสีอิงตามสีของภาพที่ซ่อนอยู่แต่ทำให้รายละเอียดใด ๆ คลุมเครือ + setting_use_blurhash: อิงการไล่ระดับสีตามสีของภาพที่ซ่อนอยู่แต่ทำให้รายละเอียดใด ๆ คลุมเครือ setting_use_pending_items: ซ่อนการอัปเดตเส้นเวลาไว้หลังการคลิกแทนที่จะเลื่อนฟีดโดยอัตโนมัติ - username: ชื่อผู้ใช้ของคุณจะไม่ซ้ำกันใน %{domain} + username: คุณสามารถใช้ตัวอักษร, ตัวเลข และขีดล่าง whole_word: เมื่อคำสำคัญหรือวลีเป็นตัวอักษรและตัวเลขเท่านั้น จะนำไปใช้กับคำสำคัญหรือวลีหากตรงกันทั้งคำเท่านั้น domain_allow: domain: โดเมนนี้จะสามารถดึงข้อมูลจากเซิร์ฟเวอร์นี้และจะประมวลผลและจัดเก็บข้อมูลขาเข้าจากโดเมน @@ -78,7 +80,7 @@ th: backups_retention_period: เก็บการเก็บถาวรผู้ใช้ที่สร้างขึ้นตามจำนวนวันที่ระบุ bootstrap_timeline_accounts: จะปักหมุดบัญชีเหล่านี้ไว้ด้านบนสุดของคำแนะนำการติดตามของผู้ใช้ใหม่ closed_registrations_message: แสดงเมื่อมีการปิดการลงทะเบียน - content_cache_retention_period: จะลบโพสต์จากเซิร์ฟเวอร์อื่น ๆ หลังจากจำนวนวันที่ระบุเมื่อตั้งเป็นค่าบวก นี่อาจย้อนกลับไม่ได้ + content_cache_retention_period: จะลบโพสต์และการดันทั้งหมดจากเซิร์ฟเวอร์อื่น ๆ หลังจากจำนวนวันที่ระบุ โพสต์บางส่วนอาจไม่สามารถกู้คืนได้ ที่คั่นหน้า, รายการโปรด และการดันที่เกี่ยวข้องทั้งหมดจะสูญหายและไม่สามารถเลิกทำได้เช่นกัน custom_css: คุณสามารถนำไปใช้ลักษณะที่กำหนดเองใน Mastodon รุ่นเว็บ mascot: เขียนทับภาพประกอบในส่วนติดต่อเว็บขั้นสูง media_cache_retention_period: จะลบไฟล์สื่อที่ดาวน์โหลดหลังจากจำนวนวันที่ระบุเมื่อตั้งเป็นค่าบวก และดาวน์โหลดใหม่ตามความต้องการ @@ -95,7 +97,7 @@ th: theme: ชุดรูปแบบที่ผู้เยี่ยมชมที่ออกจากระบบและผู้ใช้ใหม่เห็น thumbnail: แสดงภาพ 2:1 โดยประมาณควบคู่ไปกับข้อมูลเซิร์ฟเวอร์ของคุณ timeline_preview: ผู้เยี่ยมชมที่ออกจากระบบจะสามารถเรียกดูโพสต์สาธารณะล่าสุดที่มีในเซิร์ฟเวอร์ - trendable_by_default: ข้ามการตรวจทานเนื้อหาที่กำลังนิยมด้วยตนเอง ยังคงสามารถเอารายการแต่ละรายการออกจากแนวโน้มได้หลังเกิดเหตุ + trendable_by_default: ข้ามการตรวจทานเนื้อหาที่กำลังนิยมด้วยตนเอง ยังคงสามารถเอารายการแต่ละรายการออกจากแนวโน้มได้หลังจากเกิดเหตุ trends: แนวโน้มแสดงว่าโพสต์, แฮชแท็ก และเรื่องข่าวใดกำลังได้รับความสนใจในเซิร์ฟเวอร์ของคุณ trends_as_landing_page: แสดงเนื้อหาที่กำลังนิยมแก่ผู้ใช้และผู้เยี่ยมชมที่ออกจากระบบแทนที่จะเป็นคำอธิบายของเซิร์ฟเวอร์นี้ ต้องมีการเปิดใช้งานแนวโน้ม form_challenge: @@ -118,25 +120,33 @@ th: sessions: otp: 'ป้อนรหัสสองปัจจัยที่สร้างโดยแอปในโทรศัพท์ของคุณหรือใช้หนึ่งในรหัสกู้คืนของคุณ:' webauthn: หากกุญแจความปลอดภัยเป็นกุญแจ USB ตรวจสอบให้แน่ใจว่าได้เสียบกุญแจ และหากจำเป็น ให้แตะกุญแจ + settings: + indexable: หน้าโปรไฟล์ของคุณอาจปรากฏในผลลัพธ์การค้นหาใน Google, Bing และอื่น ๆ + show_application: คุณจะสามารถเห็นได้เสมอว่าแอปใดเผยแพร่โพสต์ของคุณไม่ว่าอย่างไรก็ตาม tag: name: คุณสามารถเปลี่ยนได้เฉพาะตัวพิมพ์ใหญ่เล็กของตัวอักษรเท่านั้น ตัวอย่างเช่น เพื่อทำให้ตัวอักษรอ่านได้ง่ายขึ้น user: chosen_languages: เมื่อกาเครื่องหมาย จะแสดงเฉพาะโพสต์ในภาษาที่เลือกในเส้นเวลาสาธารณะเท่านั้น role: บทบาทควบคุมว่าสิทธิอนุญาตใดที่ผู้ใช้มี user_role: - color: สีที่ใช้สำหรับบทบาททั่วทั้ง UI เป็น RGB ในรูปแบบฐานสิบหก + color: ใช้สีสำหรับบทบาททั่วทั้ง UI เป็น RGB ในรูปแบบฐานสิบหก highlighted: สิ่งนี้ทำให้บทบาทปรากฏเป็นสาธารณะ - name: ชื่อสาธารณะของบทบาท หากมีการตั้งบทบาทให้แสดงเป็นป้าย + name: ชื่อสาธารณะของบทบาท หากมีการตั้งให้แสดงบทบาทเป็นป้าย permissions_as_keys: ผู้ใช้ที่มีบทบาทนี้จะสามารถเข้าถึง... position: บทบาทที่สูงขึ้นตัดสินใจการแก้ปัญหาข้อขัดแย้งในบางสถานการณ์ การกระทำบางอย่างสามารถทำได้เฉพาะกับบทบาทที่มีระดับความสำคัญต่ำกว่าเท่านั้น webhook: events: เลือกเหตุการณ์ที่จะส่ง + template: เขียนส่วนข้อมูล JSON ของคุณเองโดยใช้การสอดแทรกตัวแปร เว้นว่างไว้สำหรับ JSON เริ่มต้น url: ที่ซึ่งจะส่งเหตุการณ์ไปยัง labels: account: + discoverable: แสดงโปรไฟล์และโพสต์ในอัลกอริทึมการค้นพบ fields: name: ป้ายชื่อ value: เนื้อหา + indexable: รวมโพสต์สาธารณะในผลลัพธ์การค้นหา + show_collections: แสดงการติดตามและผู้ติดตามในโปรไฟล์ + unlocked: ยอมรับผู้ติดตามใหม่โดยอัตโนมัติ account_alias: acct: นามของบัญชีเก่า account_migration: @@ -166,25 +176,23 @@ th: text: อธิบายเหตุผลที่ควรกลับการตัดสินใจนี้ defaults: autofollow: เชิญให้ติดตามบัญชีของคุณ - avatar: ภาพประจำตัว - bot: นี่คือบัญชีบอต + avatar: รูปภาพโปรไฟล์ + bot: นี่คือบัญชีอัตโนมัติ chosen_languages: กรองภาษา confirm_new_password: ยืนยันรหัสผ่านใหม่ confirm_password: ยืนยันรหัสผ่าน context: บริบทตัวกรอง current_password: รหัสผ่านปัจจุบัน data: ข้อมูล - discoverable: แนะนำบัญชีให้ผู้อื่น display_name: ชื่อที่แสดง email: ที่อยู่อีเมล expires_in: หมดอายุหลังจาก - fields: ข้อมูลอภิพันธุ์โปรไฟล์ - header: ส่วนหัว + fields: ช่องพิเศษ + header: รูปภาพส่วนหัว honeypot: "%{label} (ไม่ต้องกรอก)" inbox_url: URL ของกล่องขาเข้าของรีเลย์ irreversible: ลบแทนที่จะซ่อน locale: ภาษาส่วนติดต่อ - locked: ต้องมีคำขอติดตาม max_uses: จำนวนการใช้งานสูงสุด new_password: รหัสผ่านใหม่ note: ชีวประวัติ @@ -196,7 +204,6 @@ th: setting_always_send_emails: ส่งการแจ้งเตือนอีเมลเสมอ setting_auto_play_gif: เล่น GIF แบบเคลื่อนไหวโดยอัตโนมัติ setting_boost_modal: แสดงกล่องโต้ตอบการยืนยันก่อนดัน - setting_crop_images: ครอบตัดภาพในโพสต์ที่ไม่ได้ขยายเป็น 16x9 setting_default_language: ภาษาของการโพสต์ setting_default_privacy: ความเป็นส่วนตัวของการโพสต์ setting_default_sensitive: ทำเครื่องหมายสื่อว่าละเอียดอ่อนเสมอ @@ -208,9 +215,7 @@ th: setting_display_media_show_all: แสดงทั้งหมด setting_expand_spoilers: ขยายโพสต์ที่มีการทำเครื่องหมายด้วยคำเตือนเนื้อหาเสมอ setting_hide_network: ซ่อนกราฟทางสังคมของคุณ - setting_noindex: เลือกไม่รับการทำดัชนีโดยเครื่องมือค้นหา setting_reduce_motion: ลดการเคลื่อนไหวในภาพเคลื่อนไหว - setting_show_application: เปิดเผยแอปพลิเคชันที่ใช้ในการส่งโพสต์ setting_system_font_ui: ใช้แบบอักษรเริ่มต้นของระบบ setting_theme: ชุดรูปแบบไซต์ setting_trends: แสดงแนวโน้มของวันนี้ @@ -263,7 +268,7 @@ th: interactions: must_be_follower: ปิดกั้นการแจ้งเตือนจากผู้ที่ไม่ใช่ผู้ติดตาม must_be_following: ปิดกั้นการแจ้งเตือนจากผู้คนที่คุณไม่ได้ติดตาม - must_be_following_dm: ปิดกั้นข้อความโดยตรงจากผู้คนที่คุณไม่ได้ติดตาม + must_be_following_dm: ปิดกั้นข้อความโดยตรงจากผู้คนที่คุณไม่ติดตาม invite: comment: ความคิดเห็น invite_request: @@ -286,9 +291,18 @@ th: pending_account: บัญชีใหม่จำเป็นต้องมีการตรวจทาน reblog: ใครสักคนได้ดันโพสต์ของคุณ report: มีการส่งรายงานใหม่ + software_updates: + all: แจ้งเตือนการอัปเดตทั้งหมด + critical: แจ้งเตือนเฉพาะการอัปเดตสำคัญเท่านั้น + label: มีรุ่น Mastodon ใหม่พร้อมใช้งาน + none: ไม่แจ้งเตือนการอัปเดตเลย (ไม่แนะนำ) + patch: แจ้งเตือนการอัปเดตการแก้ไขข้อบกพร่อง trending_tag: แนวโน้มใหม่ต้องการการตรวจทาน rule: text: กฎ + settings: + indexable: รวมหน้าโปรไฟล์ในเครื่องมือค้นหา + show_application: แสดงว่าคุณได้ส่งโพสต์จากแอปใด tag: listable: อนุญาตให้แฮชแท็กนี้ปรากฏในการค้นหาและข้อเสนอแนะ name: แฮชแท็ก @@ -296,6 +310,7 @@ th: usable: อนุญาตให้โพสต์ใช้แฮชแท็กนี้ user: role: บทบาท + time_zone: โซนเวลา user_role: color: สีป้าย highlighted: แสดงบทบาทเป็นป้ายในโปรไฟล์ผู้ใช้ @@ -304,9 +319,11 @@ th: position: ระดับความสำคัญ webhook: events: เหตุการณ์ที่เปิดใช้งาน + template: แม่แบบส่วนข้อมูล url: URL ปลายทาง 'no': ไม่ not_recommended: ไม่แนะนำ + overridden: เขียนทับแล้ว recommended: แนะนำ required: mark: "*" diff --git a/config/locales/simple_form.tr.yml b/config/locales/simple_form.tr.yml index a2f42e2596..7d16531eae 100644 --- a/config/locales/simple_form.tr.yml +++ b/config/locales/simple_form.tr.yml @@ -2,6 +2,14 @@ tr: simple_form: hints: + account: + discoverable: Herkese açık gönderileriniz ve profiliniz Mastodon'un çeşitli kısımlarında öne çıkarılabilir veya önerilebilir ve profiliniz başka kullanıcılara önerilebilir. + display_name: Tam adınız veya kullanıcı adınız. + fields: Ana sayfanız, zamirleriniz, yaşınız, istediğiniz herhangi bir şey. + indexable: Herkese açık gönderileriniz Mastodon arama sonuçlarında görünebilir. Gönderilerinizle etkileşen kullanıcılar her halükarda onları arayabilirler. + note: 'Diğer insanlara @değinebilir veya #etiketler kullanabilirsiniz.' + show_collections: İnsanlar takip ettiklerinize ve takipçilerinize göz gezdirebilir. Takip ettiğiniz kişiler sizin onları takip ettiğinizi her halükarda görecektir. + unlocked: İnsanlar sizi onayınızı almadan takip edebileceklerdir. Takip isteklerini gözden geçirmek ve yeni takipçileri kabul veya reddetmek istiyorsanız seçimi kaldırın. account_alias: acct: Taşımak istediğiniz hesabı kullanıcıadı@alanadı şeklinde belirtin account_migration: @@ -37,14 +45,11 @@ tr: current_password: Güvenlik nedeniyle lütfen şu anki hesabın parolasını girin current_username: Onaylamak için lütfen şu anki hesabın kullanıcı adını girin digest: Sadece uzun bir süre hareketsiz kaldıktan sonra ve yalnızca yokluğunuzda herhangi bir kişisel mesaj aldıysanız gönderilir - discoverable: Hesabınızın öneriler, trendler ve diğer özellikler aracılığıyla yabancılar tarafından keşfedilmesine izin verin email: Onay e-postası gönderilir - fields: Profilinizde tablo olarak görüntülenen en fazla 4 ögeye sahip olabilirsiniz header: PNG, GIF ya da JPG. En fazla %{size}. %{dimensions}px boyutuna küçültülecek inbox_url: Kullanmak istediğiniz aktarıcının ön sayfasından URL'yi kopyalayın irreversible: Filtrelenmiş gönderiler, filtre daha sonra kaldırılsa bile, geri dönüşümsüz biçimde kaybolur locale: Kullanıcı arayüzünün dili, e-postalar ve push bildirimleri - locked: Takipçilerinizi manuel olarak kabul etmenizi ve gönderilerinizi varsayılan olarak sadece takipçilerinizin göreceği şekilde paylaşmanızı sağlar. password: En az 8 karakter kullanın phrase: Metnin büyük/küçük harf durumundan veya gönderinin içerik uyarısından bağımsız olarak eşleştirilecek scopes: Uygulamanın erişmesine izin verilen API'ler. Üst seviye bir kapsam seçtiyseniz, bireysel kapsam seçmenize gerek yoktur. @@ -54,12 +59,9 @@ tr: setting_display_media_default: Hassas olarak işaretlenmiş medyayı gizle setting_display_media_hide_all: Medyayı her zaman gizle setting_display_media_show_all: Medyayı her zaman göster - setting_hide_network: Takip ettiğiniz ve sizi takip eden kişiler profilinizde gösterilmeyecek - setting_noindex: Herkese açık profilinizi ve durum sayfalarınızı etkiler - setting_show_application: Gönderi gönderimi için kullandığınız uygulama, gönderilerinizin ayrıntılı görünümünde gösterilecektir setting_use_blurhash: Gradyenler gizli görsellerin renklerine dayanır, ancak detayları gizler setting_use_pending_items: Akışı otomatik olarak kaydırmak yerine, zaman çizelgesi güncellemelerini tek bir tıklamayla gizleyin - username: Kullanıcı adınız %{domain} alanında benzersiz olacak + username: Harfleri, sayıları veya alt çizgi kullanabilirsiniz whole_word: Anahtar kelime veya kelime öbeği yalnızca alfasayısal olduğunda, yalnızca tüm sözcükle eşleşirse uygulanır domain_allow: domain: Bu alan adı, bu sunucudan veri alabilecek ve ondan gelen veri işlenecek ve saklanacaktır @@ -118,6 +120,9 @@ tr: sessions: otp: Telefonunuzdaki two-factor kodunuzu giriniz veya kurtarma kodlarınızdan birini giriniz. webauthn: Bir USB anahtarıysa, taktığınızdan ve gerekirse üzerine tıkladığınızdan emin olun. + settings: + indexable: Profil sayfanız Google, Bing ve diğerlerindeki arama sonuçlarında görüntülenebilir. + show_application: Ne olursa olsun gönderinizi yayınlayan uygulamayı her zaman görebileceksiniz. tag: name: Harflerin, örneğin daha okunabilir yapmak için, sadece büyük/küçük harf durumlarını değiştirebilirsiniz user: @@ -131,12 +136,17 @@ tr: position: Belirli durumlarda çatışmayı çözmek için daha yüksek rol belirleyicidir. Bazı eylemler ancak daha düşük öncelikteki rollere uygulanabilir webhook: events: Gönderilecek etkinlikleri seçin + template: Değişken değerleme kullanarak kendi JSON yükünüzü oluşturun. Varsayılan JSON için boş bırakın. url: Olayların gönderileceği yer labels: account: + discoverable: Profil ve gönderileri keşif algoritmalarında kullan fields: name: Etiket value: İçerik + indexable: Herkese açık gönderileri arama sonuçlarına ekle + show_collections: Takipleri ve takipçileri profilde göster + unlocked: Yeni takipçileri otomatik olarak kabul et account_alias: acct: Eski hesabın tanıtıcısı account_migration: @@ -174,7 +184,6 @@ tr: context: İçeriği filtrele current_password: Güncel parola data: Veri - discoverable: Bu hesabı dizinde listele display_name: Görünen isim email: E-posta adresi expires_in: Bitiş tarihi @@ -184,7 +193,6 @@ tr: inbox_url: Aktarıcı gelen kutusunun URL'si irreversible: Gizlemek yerine benim için sil locale: Arayüz dili - locked: Hesabı kilitle max_uses: Maksimum kullanım sayısı new_password: Yeni parola note: Kişisel bilgiler @@ -196,7 +204,6 @@ tr: setting_always_send_emails: Her zaman e-posta bildirimleri gönder setting_auto_play_gif: Hareketli GIF'leri otomatik oynat setting_boost_modal: Boostlamadan önce onay iletişim kutusu göster - setting_crop_images: Genişletilmemiş gönderilerdeki resimleri 16x9 olarak kırp setting_default_language: Gönderi dili setting_default_privacy: Gönderi gizliliği setting_default_sensitive: Medyayı her zaman hassas olarak işaretle @@ -208,9 +215,7 @@ tr: setting_display_media_show_all: Tümünü göster setting_expand_spoilers: İçerik uyarılarıyla işaretli gönderileri her zaman genişlet setting_hide_network: Sosyal grafiğini gizle - setting_noindex: Arama motoru dizinine eklemeyi iptal et setting_reduce_motion: Animasyonlarda hareketi azalt - setting_show_application: Gönderileri göndermek için kullanılan uygulamayı belirt setting_system_font_ui: Sistemin varsayılan yazı tipini kullan setting_theme: Site teması setting_trends: Bugünün gündemini göster @@ -286,9 +291,18 @@ tr: pending_account: Yeni hesabın incelenmesi gerekiyor reblog: Birisi gönderini boostladı report: Yeni rapor gönderildi + software_updates: + all: Tüm güncellemeleri bildir + critical: Sadece kritik güncellemeleri bildir + label: Yeni bir Mastodon sürümü mevcut + none: Güncellemeleri hiç bir zaman bildirme (önerilmiyor) + patch: Yama güncellemelerini bildir trending_tag: Yeni eğilimin gözden geçmesi gerekiyor rule: text: Kural + settings: + indexable: Arama motorları profil sayfasını içersin + show_application: Gönderiyi hangi uygulamadan gönderdiğiniz görüntülensin tag: listable: Bu etiketin aramalarda ve profil dizininde görünmesine izin ver name: Etiket @@ -296,6 +310,7 @@ tr: usable: Gönderilerin bu etiketi kullanmasına izin ver user: role: Rol + time_zone: Zaman dilimi user_role: color: Rozet rengi highlighted: Rolü kullanıcıların profilinde rozet olarak görüntüle @@ -304,9 +319,11 @@ tr: position: Öncelik webhook: events: Etkin olaylar + template: Yük şablonu url: Uç nokta URL’si 'no': Hayır not_recommended: Önerilmez + overridden: Geçersiz kılındı recommended: Önerilen required: mark: "*" diff --git a/config/locales/simple_form.tt.yml b/config/locales/simple_form.tt.yml index d4e44c0db2..656ded8cf3 100644 --- a/config/locales/simple_form.tt.yml +++ b/config/locales/simple_form.tt.yml @@ -2,29 +2,60 @@ tt: simple_form: labels: + account: + fields: + name: Билге + value: Эчтәлек account_warning_preset: title: Исем admin_account_action: - type: Ğämäl + type: Гамәл types: + disable: Туңдыру + none: Кисәтү җибәрү sensitive: Sizmäle + silence: Яшерү suspend: Искә алмау + announcement: + starts_at: Чараның башы defaults: avatar: Аватар data: Мәгълүмат email: Почта адресы header: Башлам - password: Парол + note: Шәхси мәгълүмат + otp_attempt: Ике-факторлы код + password: Серсүз setting_display_media_default: Töpcay + setting_use_pending_items: Әкрен режим + title: Башлам username: Кулланучы исеме featured_tag: name: Хэштег + form_admin_settings: + custom_css: Махсус CSS + site_contact_email: Элемтә эл. почтасы + site_terms: Хосусыйлык Сәясәте invite: comment: Аңлатма ip_block: comment: Аңлатма ip: ІР + severities: + sign_up_block: Теркәлүләрне блоклау + severity: Кагыйдә + rule: + text: Кагыйдә + tag: + name: Хэштег + user: + role: Роль + user_role: + color: Бейдж төсе + name: Исем + permissions_as_keys: Рөхсәтләр 'no': Юк + recommended: Тәкъдим ителгән required: mark: "*" 'yes': Әйе diff --git a/config/locales/simple_form.uk.yml b/config/locales/simple_form.uk.yml index be4d4b764c..aa64ecfdb7 100644 --- a/config/locales/simple_form.uk.yml +++ b/config/locales/simple_form.uk.yml @@ -2,6 +2,14 @@ uk: simple_form: hints: + account: + discoverable: Ваші дописи та профіль можуть бути рекомендовані в різних частинах Mastodon і ваш профіль може бути запропонований іншим користувачам. + display_name: Ваше повне ім'я або ваш псевдонім. + fields: Ваша домашня сторінка, займенники, вік, все, що вам заманеться. + indexable: Ваші загальнодоступні дописи можуть з'явитися в результатах пошуку на Mastodon. Люди, які взаємодіяли з вашими дописами зможуть знаходити їх незалежно від цих налаштувань. + note: 'Ви можете @згадувати інших людей або #гештеґи.' + show_collections: Люди зможуть переглядати ваші підписки та підписників. Люди, за якими ви слідкуєте, бачитимуть, що ви слідкуєте за ними. + unlocked: Люди зможуть слідкувати за вами без схвалення запиту. Приберіть прапорець, якщо ви хочете розглядати запити та затверджувати або відхиляти нових підписників. account_alias: acct: Вкажіть ім'я користувача@домен облікового запису, з якого ви хочете здійснити перенесення account_migration: @@ -37,14 +45,11 @@ uk: current_password: Для цілей безпеки, будь ласка, введіть пароль поточного облікового запису current_username: Для підтвердження, будь ласка, введіть ім'я користувача поточного облікового запису digest: Буде послано тільки після довгого періоду неактивності, та тільки якщо ви отримаєте персональне повідомлення у цей період - discoverable: Дозволити знаходити ваш обліковий запис стороннім людям за допомогою рекомендацій, трендів та інших функцій email: Вам надійде електронний лист з підтвердженням - fields: У вашому профілі може бути показано таблицю з 4 елементів header: PNG, GIF, або JPG. Максимум - %{size}. Буде зменшено до %{dimensions}px inbox_url: Скопіюйте інтернет-адресу з титульної сторінки ретранслятора irreversible: Відфільтровані дописи зникнуть назавжди, навіть якщо фільтр потім буде вилучено locale: Мова інтерфейсу, електронних листів та push-сповіщень - locked: Вручну контролюйте, хто може слідкувати за вами, затверджуючи запити на стеження password: Не менше 8 символів phrase: Шукає без врахування регістру у тексті допису або у його попередженні про вміст scopes: Які API додатку буде дозволено використовувати. Якщо ви виберете самий верхній, нижчестоящі будуть обрані автоматично. @@ -54,12 +59,9 @@ uk: setting_display_media_default: Приховувати медіа, позначені як делікатними setting_display_media_hide_all: Завжди приховувати медіа setting_display_media_show_all: Завжди показувати медіа - setting_hide_network: У вашому профілі не буде показано підписки та підписників - setting_noindex: Впливає на ваш загальнодоступний профіль і сторінки дописів - setting_show_application: Застосунок, за допомогою якого ви зробили допис, буде показано серед подробиць допису setting_use_blurhash: Градієнти, що базуються на кольорах прихованих медіа, але роблять нерозрізненними будь-які деталі setting_use_pending_items: Не додавати нові повідомлення до стрічок миттєво, показувати лише після додаткового клацання - username: Ваше ім'я користувача буде унікальним у %{domain} + username: Можна використовувати літери, цифри та підкреслення whole_word: Якщо пошукове слово або фраза містить лише літери та цифри, воно має збігатися цілком domain_allow: domain: Цей домен зможе отримувати дані з цього сервера. Вхідні дані будуть оброблені та збережені @@ -78,7 +80,10 @@ uk: backups_retention_period: Зберігати створені архіви користувача вказану кількість днів. bootstrap_timeline_accounts: Ці облікові записи будуть закріплені в топі пропозицій для нових користувачів. closed_registrations_message: Показується, коли реєстрація закрита - content_cache_retention_period: Матеріали з інших серверів будуть видалені після вказаної кількості днів, коли встановлено позитивне значення. Ця дія може бути незворотна. + content_cache_retention_period: |- + Матеріали з інших серверів будуть видалені після вказаної кількості днів, коли встановлено позитивне значення. Ця дія може бути незворотна. + + Матеріали з інших серверів будуть видалені після вказаної кількості днів. Ця дія може бути незворотна. Усі пов'язані з ними закладки та поширення також будуть втрачені. custom_css: Ви можете застосувати користувацькі стилі у вебверсії Mastodon. mascot: Змінює ілюстрацію в розширеному вебінтерфейсі. media_cache_retention_period: Завантажені медіафайли будуть видалені після вказаної кількості днів після встановлення додатного значення та повторного завантаження за запитом. @@ -118,6 +123,9 @@ uk: sessions: otp: 'Введіть код двофакторної автентифікації, згенерований вашим мобільним застосунком, або скористайтеся одним з ваших кодів відновлення:' webauthn: Якщо це USB ключ, вставте його і, якщо необхідно, натисніть на нього. + settings: + indexable: Ваша сторінка профілю може показуватися в результатах пошуку Google, Bing та інших. + show_application: Ви завжди зможете побачити, з якого застосунку опубліковано ваш допис. tag: name: Тут ви можете лише змінювати регістр літер, щоб підвищити читабельність user: @@ -131,12 +139,17 @@ uk: position: Вища роль розв'язує конфлікти у певних ситуаціях. Певні дії можуть бути виконані лише щодо ролей з нижчим пріоритетом webhook: events: Оберіть події для надсилання + template: Створіть власний JSON payload, використовуючи інтерполяцію змінної. Залиште поле порожнім для типового JSON. url: Куди надсилатимуться події labels: account: + discoverable: Функції профілю та дописів у алгоритмах виявлення fields: name: Мітка value: Вміст + indexable: Включити загальнодоступні дописи в результати пошуку + show_collections: Показати підписки та підписників в профілі + unlocked: Автоматично приймати нових підписників account_alias: acct: Оброблювач старого облікового запису account_migration: @@ -166,7 +179,7 @@ uk: text: Поясніть, чому це рішення слід скасувати defaults: autofollow: Запросити слідкувати за вашим обліковим записом - avatar: Аватар + avatar: Зображення профілю bot: Це обліковий запис бота chosen_languages: Фільтрувати мови confirm_new_password: Підтвердіть новий пароль @@ -174,17 +187,15 @@ uk: context: Фільтр контексту current_password: Поточний пароль data: Дані - discoverable: Оприлюднити обліковий запис у каталозі display_name: Ім'я email: Адреса е-пошти expires_in: Закінчується після - fields: Метадані профілю - header: Заголовок + fields: Додаткові поля + header: Зображення заголовка honeypot: "%{label} (не заповнюйте)" inbox_url: URL поштової скриньки ретранслятора irreversible: Видалити назавжди, а не просто сховати locale: Мова - locked: Зробити обліковий запис приватним max_uses: Максимальна кількість використань new_password: Новий пароль note: Про Вас @@ -196,7 +207,6 @@ uk: setting_always_send_emails: Завжди надсилати сповіщення електронною поштою setting_auto_play_gif: Автоматично відтворювати анімовані GIF setting_boost_modal: Показувати діалог підтвердження під час поширення - setting_crop_images: Обрізати зображення в нерозгорнутих дописах до 16x9 setting_default_language: Мова дописів setting_default_privacy: Видимість дописів setting_default_sensitive: Позначати медіа делікатними @@ -208,9 +218,7 @@ uk: setting_display_media_show_all: Показати всі setting_expand_spoilers: Завжди розгортати дописи з попередженнями про вміст setting_hide_network: Сховати вашу мережу - setting_noindex: Відмовитися від індексування пошуковими системами setting_reduce_motion: Менше руху в анімаціях - setting_show_application: Показувати застосунки, з яких створюються дописи setting_system_font_ui: Використовувати типовий системний шрифт setting_theme: Тема сайту setting_trends: Показувати популярні сьогодні дописи @@ -286,9 +294,18 @@ uk: pending_account: Надсилати електронного листа, коли новий обліковий запис потребує розгляду reblog: Коли хтось поширює ваш допис report: Нову скаргу надіслано + software_updates: + all: Сповіщати про всі оновлення + critical: Сповіщати лише про критичні оновлення + label: Доступна нова версія Mastodon + none: Ніколи не сповіщати про оновлення (не рекомендовано) + patch: Сповіщати про оновлення з виправленнями trending_tag: Нове популярне вимагає розгляду rule: text: Правило + settings: + indexable: Включити сторінку профілю в пошукові системи + show_application: Показувати з якого застосунку ви надіслали допис tag: listable: Дозволити появу цього хештеґа у каталозі пошуку і пропозицій name: Хештеґ @@ -296,6 +313,7 @@ uk: usable: Дозволити дописам використовувати цей хештег user: role: Роль + time_zone: Часовий пояс user_role: color: Колір відзнаки highlighted: Показувати роль у вигляді відзнаки у профілях користувачів @@ -304,9 +322,11 @@ uk: position: Пріоритет webhook: events: Увімкнені події + template: Шаблон корисного навантаження url: URL кінцевої точки 'no': Ні not_recommended: Не рекомендовано + overridden: Перевизначено recommended: Рекомендовано required: mark: "*" diff --git a/config/locales/simple_form.vi.yml b/config/locales/simple_form.vi.yml index b5da24dd16..8943527b16 100644 --- a/config/locales/simple_form.vi.yml +++ b/config/locales/simple_form.vi.yml @@ -2,6 +2,14 @@ vi: simple_form: hints: + account: + discoverable: Các tút và hồ sơ công khai của bạn có thể được giới thiệu hoặc đề xuất ở nhiều khu vực khác nhau của Mastodon và hồ sơ của bạn có thể được đề xuất cho những người dùng khác. + display_name: Tên đầy đủ hoặc biệt danh đều được. + fields: Trang blog của bạn, nghề nghiệp, tuổi hoặc bất cứ thứ gì. + indexable: Tút công khai của bạn sẽ xuất hiện khi tìm kiếm trên Mastodon. Những người đã tương tác với tút của bạn có thể tìm kiếm chúng. + note: 'Bạn có thể @nhắnriêng ai đó hoặc #hashtags.' + show_collections: Mọi người sẽ biết những bạn theo dõi và người theo dõi bạn. Những người bạn theo dõi sẽ vẫn thấy rằng bạn theo dõi họ. + unlocked: Mọi người sẽ theo dõi bạn mà không cần bạn cho phép. account_alias: acct: Nhập tên_người_dùng@máy chủ của tài khoản cũ account_migration: @@ -15,9 +23,9 @@ vi: text_html: Tùy chọn. Bạn nên dùng mẫu có sẵn để tiết kiệm thời gian type_html: Chọn làm gì với %{acct} types: - disable: Tạm khóa đăng nhập tài khoản, nhưng không xóa hoặc ẩn tút. + disable: Tạm không cho đăng nhập tài khoản. none: Cảnh cáo tài khoản này, không áp đặt trừng phạt. - sensitive: Mọi tập tin của tài khoản này tải lên đều sẽ bị gắn nhãn nhạy cảm. + sensitive: Tất cả media tải lên sẽ bị gắn nhãn nhạy cảm. silence: Cấm người này đăng tút công khai, ẩn tút của họ hiện ra với những người chưa theo dõi họ. suspend: Vô hiệu hóa và xóa sạch dữ liệu của tài khoản này. Có thể khôi phục trước 30 ngày. warning_preset_id: Tùy chọn. Bạn vẫn có thể thêm chú thích riêng @@ -37,29 +45,23 @@ vi: current_password: Vì mục đích bảo mật, vui lòng nhập mật khẩu của tài khoản hiện tại current_username: Để xác nhận, vui lòng nhập tên người dùng của tài khoản hiện tại digest: Chỉ gửi sau một thời gian dài không hoạt động hoặc khi bạn nhận được tin nhắn (trong thời gian vắng mặt) - discoverable: Cho phép tài khoản của bạn xuất hiện trong gợi ý theo dõi, thịnh hành và những tính năng khác - email: Bạn sẽ được gửi một email xác nhận - fields: Được phép thêm tối đa 4 mục trên trang hồ sơ của bạn + email: Bạn sẽ được gửi một email xác minh header: PNG, GIF hoặc JPG, tối đa %{size}. Sẽ bị nén xuống %{dimensions}px inbox_url: Sao chép URL của máy chủ mà bạn muốn dùng irreversible: Các tút đã lọc sẽ không thể phục hồi, kể cả sau khi xóa bộ lọc locale: Ngôn ngữ của giao diện, email và thông báo đẩy - locked: Tự bạn sẽ phê duyệt người theo dõi password: Dùng ít nhất 8 ký tự phrase: Sẽ được hiện thị trong văn bản hoặc cảnh báo nội dung của một tút - scopes: API nào ứng dụng sẽ được phép truy cập. Nếu bạn chọn quyền hạn cấp cao nhất, bạn không cần chọn từng phạm vi. + scopes: Ứng dụng sẽ được phép truy cập những API nào. Nếu bạn chọn quyền cấp cao nhất, không cần chọn quyền nhỏ. setting_aggregate_reblogs: Nếu một tút đã được đăng lại thì những lượt đăng lại sau sẽ không hiện trên bảng tin nữa - setting_always_send_emails: Bình thường thì email thông báo sẽ không gửi khi bạn đang dùng Mastodon - setting_default_sensitive: Mặc định là nội dung nhạy cảm và chỉ hiện nếu nhấn vào - setting_display_media_default: Làm mờ nội dung nhạy cảm - setting_display_media_hide_all: Ẩn - setting_display_media_show_all: Luôn hiển thị - setting_hide_network: Ẩn những người bạn theo dõi và những người theo dõi bạn - setting_noindex: Ảnh hưởng đến trang cá nhân và tút của bạn - setting_show_application: Tên ứng dụng bạn dùng để đăng tút sẽ hiện trong chi tiết của tút - setting_use_blurhash: Lớp phủ mờ dựa trên màu sắc của hình ảnh nhạy cảm + setting_always_send_emails: Bình thường thì sẽ không gửi khi bạn đang dùng Mastodon + setting_default_sensitive: Bắt buộc nhấn vào mới có thể xem + setting_display_media_default: Click để xem + setting_display_media_hide_all: Luôn ẩn + setting_display_media_show_all: Luôn hiện + setting_use_blurhash: Phủ lớp màu làm nhòe đi hình ảnh nhạy cảm setting_use_pending_items: Dồn lại toàn bộ tút mới và chỉ hiển thị khi nhấn vào - username: Tên người dùng của bạn sẽ là duy nhất trên %{domain} + username: Chỉ dùng ký tự, số và dấu gạch dưới whole_word: Khi từ khóa hoặc cụm từ là chữ và số, nó sẽ chỉ hiện ra những từ chính xác như vậy domain_allow: domain: Máy chủ này sẽ tiếp nhận dữ liệu, rồi sau đó xử lý và lưu trữ @@ -71,7 +73,7 @@ vi: filters: action: Chọn hành động sẽ thực hiện khi một tút khớp với bộ lọc actions: - hide: Ẩn hoàn toàn nội dung đã lọc, hoạt động như thể nó không tồn tại + hide: Ẩn hoàn toàn nội dung đã lọc, như thể nó không tồn tại warn: Ẩn nội dung đã lọc đằng sau một cảnh báo đề cập đến tiêu đề của bộ lọc form_admin_settings: 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 @@ -95,9 +97,9 @@ vi: theme: Chủ đề mà khách truy cập đăng xuất và người mới nhìn thấy. thumbnail: 'Một hình ảnh tỉ lệ 2: 1 được hiển thị cùng với thông tin máy chủ của bạn.' timeline_preview: Khách truy cập đã đăng xuất sẽ có thể xem các tút công khai gần đây nhất trên máy chủ. - trendable_by_default: Bỏ qua việc duyệt thủ công nội dung thịnh hành. Các mục riêng lẻ vẫn có thể bị xóa khỏi xu hướng sau này. + trendable_by_default: Bỏ qua việc duyệt thủ công nội dung xu hướng. Các mục riêng lẻ vẫn có thể bị xóa khỏi xu hướng sau này. trends: Hiển thị những tút, hashtag và tin tức đang được thảo luận nhiều trên máy chủ của bạn. - trends_as_landing_page: Hiển thị nội dung thịnh hành cho người dùng đã đăng xuất và khách truy cập thay vì mô tả về máy chủ này. Yêu cầu xu hướng được kích hoạt. + trends_as_landing_page: Hiển thị nội dung xu hướng cho người dùng chưa đăng nhập thay vì mô tả về máy chủ này. Yêu cầu xu hướng được kích hoạt. form_challenge: current_password: Biểu mẫu này an toàn imports: @@ -118,10 +120,13 @@ vi: sessions: otp: 'Nhập mã xác minh 2 bước được tạo bởi ứng dụng điện thoại của bạn hoặc dùng một trong các mã khôi phục của bạn:' webauthn: Nếu đây là USB key, hãy cắm vào và thử xoay chiều. + settings: + indexable: Trang của bạn có thể xuất hiện trong kết quả tìm kiếm trên Google, Bing và các nơi khác. + show_application: Bạn sẽ luôn có thể xem ứng dụng nào đã đăng tút của mình. tag: name: Bạn có thể thay đổi cách viết hoa các chữ cái để giúp nó dễ đọc hơn user: - chosen_languages: Chỉ hiển thị những tút viết bằng các ngôn ngữ được chọn sau + chosen_languages: Chỉ hiển thị những tút viết bằng các ngôn ngữ sau role: Vai trò kiểm soát những quyền mà người dùng có user_role: color: Màu được sử dụng cho vai trò trong toàn bộ giao diện người dùng, dưới dạng RGB ở định dạng hex @@ -131,12 +136,17 @@ vi: position: Vai trò cao hơn sẽ có quyền quyết định xung đột trong các tình huống. Các vai trò có mức độ ưu tiên thấp hơn chỉ có thể thực hiện một số hành động nhất định webhook: events: Chọn sự kiện để gửi + template: Soạn JSON payload của riêng bạn bằng phép nội suy biến. Để trống để dùng JSON mặc định. url: Nơi những sự kiện được gửi đến labels: account: + discoverable: Cho phép khám phá hồ sơ fields: name: Nhãn value: Nội dung + indexable: Cho phép hiện tút công khai trong kết quả tìm kiếm + show_collections: Hiện lượt theo dõi và người theo dõi + unlocked: Duyệt tự động người theo dõi mới account_alias: acct: Tài khoản cũ account_migration: @@ -174,7 +184,6 @@ vi: context: Áp dụng current_password: Mật khẩu hiện tại data: Dữ liệu - discoverable: Đề xuất tài khoản display_name: Biệt danh email: Địa chỉ email expires_in: Hết hạn sau @@ -184,7 +193,6 @@ vi: inbox_url: Hộp thư relay irreversible: Xóa bỏ vĩnh viễn locale: Ngôn ngữ - locked: Yêu cầu theo dõi max_uses: Số lần dùng tối đa new_password: Mật khẩu mới note: Giới thiệu @@ -195,27 +203,24 @@ vi: setting_aggregate_reblogs: Không hiện lượt đăng lại trùng lặp setting_always_send_emails: Luôn gửi email thông báo setting_auto_play_gif: Tự động phát ảnh GIF - setting_boost_modal: Yêu cầu xác nhận trước khi đăng lại tút - setting_crop_images: Hiển thị ảnh theo tỉ lệ 16x9 + setting_boost_modal: Hỏi trước khi đăng lại tút setting_default_language: Ngôn ngữ đăng setting_default_privacy: Kiểu đăng - setting_default_sensitive: Ảnh/video là nội dung nhạy cảm - setting_delete_modal: Yêu cầu xác nhận trước khi xóa tút - setting_disable_swiping: Vô hiệu hóa vuốt màn hình - setting_display_media: Nội dung nhạy cảm + setting_default_sensitive: Đánh dấu media nhạy cảm + setting_delete_modal: Hỏi trước khi xóa tút + setting_disable_swiping: Không dùng chuyển động vuốt + setting_display_media: Media nhạy cảm setting_display_media_default: Mặc định setting_display_media_hide_all: Ẩn toàn bộ setting_display_media_show_all: Hiện toàn bộ - setting_expand_spoilers: Luôn hiển thị tút có nội dung ẩn + setting_expand_spoilers: Luôn mở rộng tút chứa nội dung ẩn setting_hide_network: Ẩn quan hệ của bạn - setting_noindex: Không xuất hiện trong công cụ tìm kiếm setting_reduce_motion: Giảm chuyển động ảnh GIF - setting_show_application: Hiện ứng dụng đã dùng để đăng tút - setting_system_font_ui: Dùng phông chữ mặc định của hệ thống + setting_system_font_ui: Dùng phông chữ mặc định hệ thống setting_theme: Giao diện - setting_trends: Hiển thị thịnh hành hôm nay - setting_unfollow_modal: Yêu cầu xác nhận trước khi ngưng theo dõi ai đó - setting_use_blurhash: Làm mờ trước ảnh/video nhạy cảm + setting_trends: Hiển thị xu hướng trong ngày + setting_unfollow_modal: Hỏi trước khi bỏ theo dõi ai đó + setting_use_blurhash: Phủ màu media nhạy cảm setting_use_pending_items: Không tự động cập nhật bảng tin severity: Mức độ nghiêm trọng sign_in_token_attempt: Mã an toàn @@ -257,13 +262,13 @@ vi: theme: Chủ đề mặc định thumbnail: Hình thu nhỏ của máy chủ timeline_preview: Cho phép truy cập vào dòng thời gian công khai - trendable_by_default: Cho phép thịnh hành mà không cần duyệt trước - trends: Bật thịnh hành - trends_as_landing_page: Dùng trang thịnh hành làm trang chào mừng + trendable_by_default: Cho phép lên xu hướng mà không cần duyệt trước + trends: Bật xu hướng + trends_as_landing_page: Dùng trang xu hướng làm trang chào mừng interactions: - must_be_follower: Chặn thông báo từ những người không theo dõi bạn - must_be_following: Chặn thông báo từ những người bạn không theo dõi - must_be_following_dm: Chặn tin nhắn từ những người bạn không theo dõi + must_be_follower: Những người không theo dõi bạn + must_be_following: Những người bạn không theo dõi + must_be_following_dm: Những người bạn không theo dõi (nhắn riêng) invite: comment: Bình luận invite_request: @@ -286,16 +291,26 @@ vi: pending_account: Phê duyệt tài khoản mới reblog: Ai đó đăng lại tút của bạn report: Ai đó gửi báo cáo + software_updates: + all: Thông báo về mọi bản cập nhật + critical: Chỉ thông báo bản cập nhật quan trọng + label: Đã có phiên bản Mastodon mới + none: Không bao giờ thông báo (không đề xuất) + patch: Thông báo bản cập sửa lỗi trending_tag: Phê duyệt nội dung nổi bật mới rule: text: Nội quy + settings: + indexable: Cho phép hiện hồ sơ trong công cụ tìm kiếm + show_application: Cho phép hiện ứng dụng dùng để đăng tút tag: listable: Cho phép xuất hiện trong tìm kiếm và đề xuất name: Hashtag - trendable: Cho phép hashtag này thịnh hành + trendable: Cho phép hashtag này lên xu hướng usable: Cho phép dùng trong tút user: role: Vai trò + time_zone: Múi giờ user_role: color: Màu huy hiệu highlighted: Hiển thị huy hiệu vai trò trên hồ sơ người dùng @@ -304,13 +319,15 @@ vi: position: Mức độ ưu tiên webhook: events: Những sự kiện đã bật + template: Mẫu payload url: URL endpoint 'no': Tắt not_recommended: Không đề xuất + overridden: Đã ghi đè recommended: Đề xuất required: mark: "*" - text: yêu cầu + text: Bắt buộc title: sessions: webauthn: Dùng một trong những khóa bảo mật của bạn để đăng nhập diff --git a/config/locales/simple_form.zgh.yml b/config/locales/simple_form.zgh.yml index 1d55f34b52..7ba82b1bf2 100644 --- a/config/locales/simple_form.zgh.yml +++ b/config/locales/simple_form.zgh.yml @@ -18,7 +18,6 @@ zgh: data: ⵉⴼⵙⴽⴰ email: ⵜⴰⵏⵙⴰ ⵉⵎⴰⵢⵍ locale: ⵜⵓⵜⵍⴰⵢⵜ ⵏ ⵓⵏⴳⵔⵓⴷⵎ - locked: ⵔⴳⵍ ⴰⵎⵉⴹⴰⵏ new_password: ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵜⴰⵎⴰⵢⵏⵓⵜ note: ⵜⴰⵔⵉⴷⵉⵔⵜ password: ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml index 18ba22921c..7a56fa2559 100644 --- a/config/locales/simple_form.zh-CN.yml +++ b/config/locales/simple_form.zh-CN.yml @@ -2,6 +2,14 @@ zh-CN: simple_form: hints: + account: + discoverable: 您的公开嘟文和个人资料可能会在 Mastodon 的多个位置展示,您的个人资料可能会被推荐给其他用户。 + display_name: 您的全名或昵称。 + fields: 你的主页、人称代词、年龄,以及任何你想要添加的内容。 + indexable: 您的公开嘟文会出现在 Mastodon 的搜索结果中。无论是否勾选,与您的嘟文有过交互的人都可能通过搜索找到它们。 + note: '您可以提及 @其他人 或 #标签 。' + show_collections: 人们将能够浏览您的关注和追随者。您关注的人会看到您关注他们。 + unlocked: 人们将能够在不请求批准的情况下关注您。如果您希望审核关注请求并选择接受或拒绝新的粉丝,请取消勾选此项。 account_alias: acct: 指定你想要迁移过来的原账号:用户名@站点域名 account_migration: @@ -37,14 +45,11 @@ zh-CN: current_password: 为了安全起见,请输入当前账号的密码 current_username: 请输入当前账号的用户名以确认 digest: 仅在你长时间未登录,且收到了私信时发送 - discoverable: 允许他人通过推荐、热门和其他途径发现你的账户 email: 我们会向你发送一封确认邮件 - fields: 这将会在个人资料页上以表格的形式展示,最多 4 个项目 header: 文件大小限制 %{size},只支持 PNG、GIF 或 JPG 格式。图片分辨率将会压缩至 %{dimensions}px inbox_url: 从你想要使用的中继站的主页上复制 URL irreversible: 已过滤的嘟文会不可逆转地消失,即便移除过滤器之后也一样 locale: 用户界面、电子邮件和推送通知中使用的语言 - locked: 你需要手动审核所有关注请求 password: 至少需要8个字符 phrase: 匹配将忽略嘟文或内容警告里的字母大小写 scopes: 哪些 API 被允许使用。如果你勾选了更高一级的范围,就不用单独选中子项目了。 @@ -52,14 +57,11 @@ zh-CN: setting_always_send_emails: 一般情况下,如果您活跃使用 Mastodon,我们不会给您发送电子邮件通知 setting_default_sensitive: 敏感内容默认隐藏,并在点击后显示 setting_display_media_default: 隐藏被标记为敏感内容的媒体 - setting_display_media_hide_all: 隐藏所有媒体 - setting_display_media_show_all: 显示所有的媒体 - setting_hide_network: 你的关注者和你关注的人将不会在你的个人资料页上展示 - setting_noindex: 此设置会影响到你的公开个人资料以及嘟文页面 - setting_show_application: 你用来发表嘟文的应用程序将会在你嘟文的详细内容中显示 + setting_display_media_hide_all: 始终隐藏媒体 + setting_display_media_show_all: 始终显示媒体 setting_use_blurhash: 渐变是基于模糊后的隐藏内容生成的 setting_use_pending_items: 关闭自动滚动更新,时间轴会在点击后更新 - username: 你的用户名在 %{domain} 上是唯一的 + username: 您只能使用字母、数字和下划线 whole_word: 如果关键词只包含字母和数字,将只在词语完全匹配时才会应用 domain_allow: domain: 该站点将能够从该服务器上拉取数据,并处理和存储收到的数据。 @@ -69,12 +71,12 @@ zh-CN: featured_tag: name: 以下是你最近使用过的标签: filters: - action: 选择在帖子匹配过滤器时要执行的操作 + action: 选择在嘟文命中过滤器时要执行的操作 actions: hide: 彻底屏蔽过滤内容,犹如它不曾存在过一般 warn: 在警告中提及过滤器标题后,隐藏过滤内容 form_admin_settings: - activity_api_enabled: 本地发布的帖子、 活跃用户和每周的注册数 + activity_api_enabled: 本站每周的嘟文数、活跃用户数和新注册用户数 backups_retention_period: 将在指定天数内保留生成的用户存档。 bootstrap_timeline_accounts: 这些账号将在新用户关注推荐中置顶。 closed_registrations_message: 在关闭注册时显示 @@ -116,8 +118,11 @@ zh-CN: rule: text: 描述这个服务器上的用户规则或要求。尽量确保简洁、清晰易懂 sessions: - otp: 输入你手机应用上生成的双重认证码,或者任意一个恢复代码: + otp: 输入你手机应用上生成的双因素认证代码,或者任意一个恢复代码: webauthn: 如果是 USB 密钥,请确保将其插入,如有必要,请点击它。 + settings: + indexable: 您的个人资料页面可能会出现在Google、Bing等搜索结果中。 + show_application: 无论如何,您始终可以看到是哪个应用发布了您的嘟文。 tag: name: 你只能改变字母的大小写,让它更易读 user: @@ -131,12 +136,17 @@ zh-CN: position: 用于在特定情况下处理决策冲突。一些特定操作只能对优先级更低的角色执行 webhook: events: 选择要发送的事件 + template: 使用变量插值来构建自己的JSON负载。如果要使用默认的JSON,请留空。 url: 事件将被发往的目的地 labels: account: + discoverable: 在发现算法中展示您的个人资料和嘟文 fields: name: 标签 value: 内容 + indexable: 将公开嘟文纳入搜索范围 + show_collections: 在个人资料中显示关注和关注者 + unlocked: 自动接受新关注者 account_alias: acct: 处理旧账号 account_migration: @@ -171,10 +181,9 @@ zh-CN: chosen_languages: 语言过滤 confirm_new_password: 确认新密码 confirm_password: 确认密码 - context: 过滤器环境 + context: 过滤环境 current_password: 当前密码 data: 数据文件 - discoverable: 在本站用户目录中收录此账号 display_name: 昵称 email: 电子邮件地址 expires_in: 失效时间 @@ -184,11 +193,10 @@ zh-CN: inbox_url: 中继站收件箱的 URL irreversible: 丢弃而非隐藏 locale: 界面语言 - locked: 保护你的账户(锁嘟) max_uses: 最大使用次数 new_password: 新密码 note: 简介 - otp_attempt: 双重认证代码 + otp_attempt: 双因素认证代码 password: 密码 phrase: 关键词 setting_advanced_layout: 启用高级 Web 界面 @@ -196,21 +204,18 @@ zh-CN: setting_always_send_emails: 总是发送电子邮件通知 setting_auto_play_gif: 自动播放 GIF 动画 setting_boost_modal: 在转嘟前询问我 - setting_crop_images: 把未展开嘟文中的图片裁剪到 16x9 setting_default_language: 发布语言 setting_default_privacy: 嘟文默认可见范围 - setting_default_sensitive: 总是将我发送的媒体文件标记为敏感内容 + setting_default_sensitive: 始终标记媒体为敏感内容 setting_delete_modal: 在删除嘟文前询问我 setting_disable_swiping: 禁用滑动动作 - setting_display_media: 媒体展示 + setting_display_media: 媒体显示 setting_display_media_default: 默认 setting_display_media_hide_all: 隐藏全部 setting_display_media_show_all: 显示全部 - setting_expand_spoilers: 始终展开具有内容警告的嘟文 + setting_expand_spoilers: 一律展开具有内容警告的嘟文 setting_hide_network: 隐藏你的社交网络 - setting_noindex: 禁止搜索引擎建立索引 setting_reduce_motion: 降低过渡动画效果 - setting_show_application: 展示你用来发嘟的应用 setting_system_font_ui: 使用系统默认字体 setting_theme: 站点主题 setting_trends: 显示今日热门 @@ -253,7 +258,7 @@ zh-CN: site_short_description: 本站简介 site_terms: 隐私政策 site_title: 本站名称 - status_page_url: 静态页面地址 + status_page_url: 状态页网址 theme: 默认主题 thumbnail: 本站缩略图 timeline_preview: 时间轴预览 @@ -286,9 +291,18 @@ zh-CN: pending_account: 在有账号需要审核时,发送电子邮件提醒我 reblog: 当有用户转嘟了我的嘟文时,发送电子邮件提醒我 report: 新举报已提交 + software_updates: + all: 通知所有更新 + critical: 仅在有关键更新时通知 + label: 有新的 Mastodon 版本可用 + none: 从不通知更新(不推荐) + patch: 通知错误修复更新 trending_tag: 新热门待审核 rule: text: 规则 + settings: + indexable: 允许搜索引擎索引个人资料页面 + show_application: 显示您发嘟所用的应用 tag: listable: 允许这个话题标签在用户目录中显示 name: 话题标签 @@ -296,6 +310,7 @@ zh-CN: usable: 允许嘟文使用此话题标签 user: role: 角色 + time_zone: 时区 user_role: color: 徽章颜色 highlighted: 在用户资料中显示角色徽章 @@ -304,9 +319,11 @@ zh-CN: position: 优先级 webhook: events: 已启用事件 + template: 载荷模板 url: 对端 URL 'no': 否 not_recommended: 不推荐 + overridden: 已覆盖 recommended: 推荐 required: mark: "*" diff --git a/config/locales/simple_form.zh-HK.yml b/config/locales/simple_form.zh-HK.yml index 16ece9d2ca..ad963b32b6 100644 --- a/config/locales/simple_form.zh-HK.yml +++ b/config/locales/simple_form.zh-HK.yml @@ -2,6 +2,14 @@ zh-HK: simple_form: hints: + account: + discoverable: 你的公開帖文和個人檔案可能會在 Mastodon 的各處被推薦或設為精選,並且可能把你的檔案推薦給其他使用者。 + display_name: 你的全名或暱稱。 + fields: 你的主頁、代名詞、年齡,任何你想顯示的資訊。 + indexable: 你的公開帖文可能會出現在 Mastodon 的搜尋結果中。無論如何,與你帖文互動過的人都能搜尋到它。 + note: '你可以 @提及他人 或使用 #主題標籤。' + show_collections: 大家可瀏覽你追蹤的人和你的追蹤者。你追蹤的人無論如何都會看到你追蹤了他們。 + unlocked: 大家毋須獲得批准即可追蹤你。如果你想審核追蹤請求,來接受或拒絕新追蹤者,請取消勾選。 account_alias: acct: 指定欲移動之帳戶的「使用者名稱@域名」 account_migration: @@ -18,6 +26,8 @@ zh-HK: disable: 禁止該使用者使用他們的帳號,但是不刪除或隱藏他們的內容。 none: 用這個來警告該使用者,而不進行其他操作。 sensitive: 強制標記此用戶的所有媒體附件為敏感內容。 + silence: 禁止該使用者發佈公開帖文,沒有追蹤他們的人不會看到其帖文和通知。關閉所有對該帳號的檢舉報告。 + suspend: 禁止與該帳號的所有互動,並移除其內容。可於 30 天內撤銷此動作。關閉所有對此帳號的檢舉報告。 warning_preset_id: 選用。你仍可在預設訊息的結尾加入自訂文字 announcement: all_day: 勾選後,只會顯示出時間範圍中的日期部分 @@ -35,14 +45,11 @@ zh-HK: current_password: 基於保安緣故,請輸入目前帳號的密碼 current_username: 請輸入目前帳戶的使用者名稱以確認 digest: 僅在你長時間未登錄,且收到了私信時發送 - discoverable: 允許陌生人從推薦、趨勢及其他功能發現你的帳號 email: 你將收到一封確認電郵 - fields: 個人資料頁可顯示多至 4 個項目 header: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px inbox_url: 在你想要使用的中繼站首頁,複製它的網址 irreversible: 文章過濾是不可還原的,即使日後過濾器被移除,也無法重新看到被它濾走的文章 locale: 使用者介面、電郵和通知的語言 - locked: 你必須手動審核每個人對你的關注請求 password: 使用至少 8 個字元 phrase: 過濾器會閱讀文章和內容警告標語的字眼,然後決定過濾與否 scopes: 選擇應用程式可以存取的 API。 若你選擇最高階的權限範圍,則無須選擇個別項目。 @@ -52,12 +59,9 @@ zh-HK: setting_display_media_default: 隱藏標為敏感的媒體 setting_display_media_hide_all: 總是隱藏所有媒體 setting_display_media_show_all: 總是顯示標為敏感的媒體 - setting_hide_network: 你所關注的人,和關注你的人,將不會在你的個人資料頁上顯示 - setting_noindex: 此設定會影響到你的公開個人資料以及文章頁面 - setting_show_application: 你用來發表文章的應用程式,將會顯示在你文章的詳細檢視中 setting_use_blurhash: 漸變圖樣會基於隱藏媒體內容產生,但所有細節會變得模糊 setting_use_pending_items: 關閉自動滾動更新,時間軸會在點擊後更新 - username: 你的使用者名稱在 %{domain} 將是獨一無二的 + username: 你可以使用字母、數字及底線 whole_word: 如果關鍵字或詞組僅有字母與數字,則其將只在符合整個單字的時候才會套用 domain_allow: domain: 此網域將能從此站獲取資料,而此站發出的數據也會被處理和存儲。 @@ -72,6 +76,7 @@ zh-HK: hide: 完全隱藏被篩選的內容,猶如它不存在般。 warn: 將已篩選的內容隱藏在篩選器標題的警告後面。 form_admin_settings: + activity_api_enabled: 每週本站發佈的帖文、活躍使用者及新註冊的數量 backups_retention_period: 繼續封存生成的使用者到指定的天數。 bootstrap_timeline_accounts: 這些帳號會被置頂在新使用者的追蹤建議上。 closed_registrations_message: 關閉註冊時顯示 @@ -79,6 +84,7 @@ zh-HK: custom_css: 你可以在 Mastodon 網頁版套用自訂樣式。 mascot: 覆蓋進階網頁介面中的插圖。 media_cache_retention_period: 當設定為正數時,已下載的媒體檔案將在指定天數後被刪除,並視乎需要重新下載。 + peers_api_enabled: 本伺服器於聯邦宇宙相遇的網域名單。這裏不包括你與某伺服器有否聯網的數據,僅表示你的伺服器已知的網域。這是供收集一般跨站數據的服務使用。 profile_directory: 個人檔案目錄羅列了所有選擇被發現的使用者。 require_invite_text: 如果需要手動審核註冊,請將「為何你想加入?」文字欄設定為必填,而非選填。 site_contact_email: 大家如何聯絡你有關法律或支援的查詢。 @@ -87,11 +93,13 @@ zh-HK: site_short_description: 用作辨別你的伺服器的一段簡短描述。誰營運它,它為誰服務的? site_terms: 使用你的私隱政策,或者留空使用預設的,可以用 Markdown 語法編寫。 site_title: 除了域名以外,其他人會如何指稱你的伺服器。 + status_page_url: 可在服務中斷期間,查看此伺服器狀態的網頁網址 theme: 未登入訪客和新使用者看到的主題。 thumbnail: 一幅約 2:1 的圖片顯示在你的伺服器資訊的旁邊。 timeline_preview: 未登入的訪客能夠瀏覽伺服器上最新的公開帖文。 trendable_by_default: 跳過對趨勢內容的手動審查,事後仍可從趨勢中刪除個別項目。 trends: 趨勢顯示哪些帖文、標籤和新聞故事在你的伺服器上較有吸引力。 + trends_as_landing_page: 向未登入的使用者及訪客展示趨勢內容,而非只有此伺服器的描述。需要啟用趨勢。 form_challenge: current_password: 你正要進入安全區域 imports: @@ -112,6 +120,9 @@ zh-HK: sessions: otp: 輸入你手機上生成的雙重認證碼,或者任意一個恢復代碼: webauthn: 如果它是 USB 安全鑰匙的話,請先插入電腦。如鑰匙設計有需要,請按鍵啟用。 + settings: + indexable: 你的個人檔案可能會出現在 Google 和 Bing 等搜尋引擎的搜尋結果中。 + show_application: 你總能看到哪個應用程式發佈你的帖文。 tag: name: 你只能變更大小寫(以使其更易讀)。 user: @@ -125,12 +136,17 @@ zh-HK: position: 在某些情況下,由較高階的角色決定如何解決衝突。某些動作只能對優先度較低的角色執行 webhook: events: 選取要傳送的事件 + template: 使用變量插值撰寫你的 JSON payload。若要使用預設的 JSON,請留空。 url: 事件將被傳送至何處 labels: account: + discoverable: 探索演算法推薦的個人檔案和帖文 fields: name: 標籤 value: 內容 + indexable: 搜尋結果包含公開帖文 + show_collections: 於個人檔案顯示追蹤中及追蹤者 + unlocked: 自動接受新追蹤者 account_alias: acct: 舊帳號名稱 account_migration: @@ -168,7 +184,6 @@ zh-HK: context: 所過濾情境 current_password: 目前密碼 data: 資料 - discoverable: 在目錄列出此帳號 display_name: 顯示名稱 email: 電郵地址 expires_in: 失效時間 @@ -178,7 +193,6 @@ zh-HK: inbox_url: 中繼收件匣的 URL irreversible: 丟棄而非隱藏 locale: 介面語言 - locked: 將帳號轉為「私人」 max_uses: 最大使用次數 new_password: 新密碼 note: 簡介 @@ -190,7 +204,6 @@ zh-HK: setting_always_send_emails: 總是傳送電郵通知 setting_auto_play_gif: 自動播放 GIF setting_boost_modal: 在轉推前詢問我 - setting_crop_images: 將未展開文章中的圖片裁剪到 16x9 setting_default_language: 文章語言 setting_default_privacy: 文章預設為 setting_default_sensitive: 預設我的內容為敏感內容 @@ -202,9 +215,7 @@ zh-HK: setting_display_media_show_all: 全部顯示 setting_expand_spoilers: 永遠展開標有內容警告的文章 setting_hide_network: 隱藏你的社交網絡 - setting_noindex: 聲明本站不希望搜尋器讓外界搜尋 setting_reduce_motion: 減少動畫效果 - setting_show_application: 顯示用來發表文章的應用程式 setting_system_font_ui: 使用系統預設字型 setting_theme: 網站主題 setting_trends: 顯示今天的趨勢 @@ -227,6 +238,7 @@ zh-HK: hide: 完全隱藏 warn: 警告並隱藏 form_admin_settings: + activity_api_enabled: 在 API 中發佈使用者活動的匯總統計數據 backups_retention_period: 封存使用者保留期 bootstrap_timeline_accounts: 總是向新使用者推薦這些帳號 closed_registrations_message: 無法註冊時的自訂訊息 @@ -234,6 +246,7 @@ zh-HK: custom_css: 自訂 CSS mascot: 自訂吉祥物 (舊版) media_cache_retention_period: 媒體快取保留期 + peers_api_enabled: 在 API 中發佈已知的伺服器名單 profile_directory: 啟用個人檔案目錄 registrations_mode: 誰能註冊 require_invite_text: 提供一個加入的理由 @@ -245,11 +258,13 @@ zh-HK: site_short_description: 伺服器描述 site_terms: 私隱政策 site_title: 伺服器名稱 + status_page_url: 狀態頁網址 theme: 預設主題 thumbnail: 伺服器縮圖 timeline_preview: 允許未經認證的人存取公共時間軸 trendable_by_default: 允許未經審核的趨勢 trends: 啟用趨勢 + trends_as_landing_page: 使用趨勢作為登陸頁面 interactions: must_be_follower: 隱藏你關注者以外的人的通知 must_be_following: 隱藏你不關注的人的通知 @@ -276,9 +291,18 @@ zh-HK: pending_account: 有新帳號需要審核時 reblog: 當有人轉推你的文章時 report: 新檢舉已提交 + software_updates: + all: 通知所有更新 + critical: 只通知關鍵更新 + label: 有新的 Mastodon 版本 + none: 永不通知更新(不推薦) + patch: 通知除錯更新 trending_tag: 新趨勢須經過審核 rule: text: 規則 + settings: + indexable: 在搜尋引擎中顯示個人檔案 + show_application: 顯示發佈帖文所用的應用程式 tag: listable: 允許此主題標籤在搜尋及個人檔案目錄中顯示 name: 主題標籤 @@ -286,6 +310,7 @@ zh-HK: usable: 允許文章使用此主題標籤 user: role: 角色 + time_zone: 時區 user_role: color: 徽章顏色 highlighted: 在使用者個人檔案上以徽章顯示角色 @@ -294,9 +319,11 @@ zh-HK: position: 優先權 webhook: events: 已啟用事件 + template: Payload 範本 url: 端點網址 'no': 否 not_recommended: 不推薦 + overridden: 已覆寫 recommended: 建議 required: mark: "*" diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index 855c402423..5108a97452 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -2,6 +2,14 @@ zh-TW: simple_form: hints: + account: + discoverable: 公開嘟文及個人檔案可能於各 Mastodon 功能中被推薦,並且您的個人檔案可能被推薦至其他使用者。 + display_name: 完整名稱或暱稱。 + fields: 烘培雞,自我認同代稱,年齡,及任何您想分享的。 + indexable: 您的公開嘟文可能會顯示於 Mastodon 之搜尋結果中。曾與您嘟文互動過的人可能無論如何都能搜尋它們。 + note: '您可以 @mention 其他人或者使用 #主題標籤。' + show_collections: 人們將能瀏覽您跟隨中及跟隨者帳號。您所跟隨之人能得知您正在跟隨其帳號。 + unlocked: 人們將無需額外請求您的同意便能跟隨您的帳號。取消勾選以審查跟隨請求並選擇是否同意或拒絕新跟隨者。 account_alias: acct: 指定要移動的帳號的「使用者名稱@網域名稱」 account_migration: @@ -17,7 +25,7 @@ zh-TW: types: disable: 禁止該使用者使用他們的帳號,但是不刪除或隱藏他們的內容。 none: 使用這個寄送警告給該使用者,而不進行其他動作。 - sensitive: 強制標記此使用者所有媒體為敏感內容。 + sensitive: 強制標記此使用者所有多媒體附加檔案為敏感內容。 silence: 禁止該使用者發公開嘟文,從無跟隨他們的帳號中隱藏嘟文和通知。關閉所有對此帳號之檢舉報告。 suspend: 禁止所有對該帳號任何互動,並且刪除其內容。三十天內可以撤銷此動作。關閉所有對此帳號之檢舉報告。 warning_preset_id: 選用。您仍可在預設的結尾新增自訂文字 @@ -33,39 +41,33 @@ zh-TW: autofollow: 通過邀請網址註冊的使用者將自動跟隨您 avatar: 支援 PNG、GIF 或 JPG 圖片格式,檔案最大為 %{size},會等比例縮減至 %{dimensions} 像素 bot: 此帳號主要執行自動化操作且可能未受人為監控 - context: 應該套用過濾器的一項或多項內容 + context: 此過濾器應套用於以下一項或多項情境 current_password: 因安全因素,請輸入目前帳號的密碼 current_username: 請輸入目前帳號的使用者名稱以確認 digest: 僅在您長時間未登入且在未登入期間收到私訊時傳送 - discoverable: 允許陌生人透過推薦、熱門趨勢及其他功能發現您的帳號 email: 您將收到一封確認電子郵件 - fields: 您可在個人檔案上有至多 4 個以表格形式顯示的項目 header: 支援 PNG、GIF 或 JPG 圖片格式,檔案最大為 %{size},會等比例縮減至 %{dimensions} 像素 inbox_url: 從您想要使用的中繼首頁複製網址 irreversible: 已過濾的嘟文將會不可逆地消失,即便之後移除過濾器也一樣 locale: 使用者介面、電子郵件和推播通知的語言 - locked: 需要您手動批准跟隨請求 password: 使用至少 8 個字元 phrase: 無論是嘟文的本文或是內容警告都會被過濾 scopes: 允許讓應用程式存取的 API。 若您選擇最高階範圍,則無須選擇個別項目。 setting_aggregate_reblogs: 請勿顯示最近已被轉嘟之嘟文的最新轉嘟(只影響最新收到的嘟文) - setting_always_send_emails: 一般情況下若您活躍使用 Mastodon ,我們不會寄送 e-mail 通知 + setting_always_send_emails: 一般情況下若您活躍使用 Mastodon ,我們不會寄送電子郵件通知 setting_default_sensitive: 敏感內容媒體預設隱藏,且按一下即可重新顯示 setting_display_media_default: 隱藏標為敏感內容的媒體 setting_display_media_hide_all: 總是隱藏所有媒體 - setting_display_media_show_all: 總是顯示標為敏感的媒體 - setting_hide_network: 您跟隨的人與跟隨您的人將不會在您的個人檔案頁面上顯示 - setting_noindex: 會影響您的公開個人檔案與嘟文頁面 - setting_show_application: 您用來發嘟文的應用程式將會在您嘟文的詳細檢視顯示 + setting_display_media_show_all: 總是顯示標為敏感內容的媒體 setting_use_blurhash: 彩色漸層圖樣是基於隱藏媒體內容顏色產生,所有細節會變得模糊 setting_use_pending_items: 關閉自動捲動更新,時間軸只會在點擊後更新 - username: 您的使用者名稱將在 %{domain} 是獨一無二的 + username: 您可以使用字幕、數字與底線 whole_word: 如果關鍵字或詞組僅有字母與數字,則其將只在符合整個單字的時候才會套用 domain_allow: - domain: 此域名將能夠攫取本站資料,而自域名該發出的資料也會於本站處理和留存。 + domain: 此網域將能夠攫取本站資料,而自該網域發出的資料也會於本站處理和留存。 email_domain_block: - domain: 這可以是顯示在電子郵件中的網域名稱,或是其使用的 MX 紀錄。其將在註冊時檢查。 - with_dns_records: Mastodon 會嘗試解析所給域名的 DNS 記錄,解析結果一致者將一併封鎖 + domain: 這可以是顯示在電子郵件中的網域名稱,或是其使用的 MX 紀錄。其將於註冊時檢查。 + with_dns_records: Mastodon 會嘗試解析所給網域的 DNS 記錄,解析結果一致者將一併封鎖 featured_tag: name: 這些是您最近使用的一些主題標籤: filters: @@ -78,7 +80,7 @@ zh-TW: backups_retention_period: 將已產生的使用者封存資料保存特定天數。 bootstrap_timeline_accounts: 這些帳號將被釘選於新帳號跟隨推薦之上。 closed_registrations_message: 於註冊關閉時顯示 - content_cache_retention_period: 當設定成正值時,從其他伺服器而來的嘟文會於指定天數後被刪除。這項操作可能是不可逆的。 + content_cache_retention_period: 所有來自其他伺服器之嘟文及轉嘟將於指定天數後被刪除。這項操作可能是不可逆的。所有相關之書籤、最愛、轉嘟將會遺失並且無法回復。 custom_css: 您於 Mastodon 網頁版本中能套用客製化風格。 mascot: 覆寫進階網頁介面中的圖例。 media_cache_retention_period: 當設定成正值時,已下載的多媒體檔案會於指定天數後被刪除,並且視需要重新下載。 @@ -107,7 +109,7 @@ zh-TW: ip_block: comment: 可選的,但請記得您為何添加這項規則。 expires_in: IP 位址是經常共用或轉手的有限資源,不建議無限期地封鎖特定 IP 位址。 - ip: 請輸入 IPv4 或 IPv6 位址,亦可以用 CIDR 語法以封鎖整個 IP 區段。小心不要把自己給一併封鎖掉囉! + ip: 請輸入 IPv4 或 IPv6 位址,亦可以用 CIDR 語法以封鎖整個 IP 區段。小心不要將自己給一併封鎖掉囉! severities: no_access: 封鎖對所有資源存取 sign_up_block: 無法註冊新帳號 @@ -118,6 +120,9 @@ zh-TW: sessions: otp: 請輸入產生自您手機 App 的兩階段驗證碼,或輸入其中一個備用驗證碼: webauthn: 如果它是 USB 安全金鑰的話,請確認已正確插入,如有需要請觸擊。 + settings: + indexable: 個人檔案可能出現於 Google、Bing、或其他搜尋引擎。 + show_application: 將總是顯示您發嘟文之應用程式 tag: name: 您只能變更大小寫,例如,以使其更易讀。 user: @@ -131,12 +136,17 @@ zh-TW: position: 在某些情況下,衝突的解決方式由更高階的角色決定。某些動作只能由優先程度較低的角色執行 webhook: events: 請選擇要傳送的事件 + template: 使用變數代換組合您自己的 JSON payload。留白以使用預設 JSON 。 url: 事件會被傳送至何處 labels: account: + discoverable: 於探索演算法中推薦個人檔案及嘟文 fields: name: 標籤 value: 內容 + indexable: 允許公開嘟文顯示於搜尋結果中 + show_collections: 於個人檔案中顯示跟隨中及跟隨者 + unlocked: 自動同意新跟隨者 account_alias: acct: 舊帳號名稱 account_migration: @@ -174,17 +184,15 @@ zh-TW: context: 過濾情境 current_password: 目前密碼 data: 資料 - discoverable: 在目錄列出此帳號 display_name: 顯示名稱 email: 電子郵件地址 expires_in: 失效時間 - fields: 個人檔案詮釋資料 + fields: 額外欄位 header: 封面圖片 honeypot: "%{label} (請勿填寫)" - inbox_url: 中繼收件匣的 URL + inbox_url: 中繼收件匣 URL irreversible: 放棄而非隱藏 locale: 介面語言 - locked: 鎖定帳號 max_uses: 最大使用次數 new_password: 新密碼 note: 個人簡介 @@ -193,10 +201,9 @@ zh-TW: phrase: 關鍵字或片語 setting_advanced_layout: 啟用進階網頁介面 setting_aggregate_reblogs: 時間軸中的群組轉嘟 - setting_always_send_emails: 總是發送 e-mail 通知 + setting_always_send_emails: 總是發送電子郵件通知 setting_auto_play_gif: 自動播放 GIF 動畫 setting_boost_modal: 轉嘟前先詢問我 - setting_crop_images: 將未展開嘟文中的圖片裁剪至 16x9 setting_default_language: 嘟文語言 setting_default_privacy: 嘟文可見範圍 setting_default_sensitive: 總是將媒體標記為敏感內容 @@ -208,9 +215,7 @@ zh-TW: setting_display_media_show_all: 全部顯示 setting_expand_spoilers: 永遠展開標有內容警告的嘟文 setting_hide_network: 隱藏您的社交網路 - setting_noindex: 阻止搜尋引擎建立索引 setting_reduce_motion: 減少過渡動畫效果 - setting_show_application: 顯示用來傳送嘟文的應用程式 setting_system_font_ui: 使用系統預設字型 setting_theme: 佈景主題 setting_trends: 顯示本日熱門趨勢 @@ -227,7 +232,7 @@ zh-TW: email_domain_block: with_dns_records: 包括網域的 MX 記錄和 IP 位址 featured_tag: - name: "「#」標籤" + name: "「#」主題標籤" filters: actions: hide: 完全隱藏 @@ -279,16 +284,25 @@ zh-TW: notification_emails: appeal: 有人對管理員的決定提出上訴 digest: 傳送摘要電子郵件 - favourite: 當有使用者喜歡您的嘟文時,傳送電子郵件通知 + favourite: 當有使用者將您的嘟文加入最愛時,傳送電子郵件通知 follow: 當有使用者跟隨您時,傳送電子郵件通知 follow_request: 當有使用者請求跟隨您時,傳送電子郵件通知 mention: 當有使用者在嘟文提及您時,傳送電子郵件通知 - pending_account: 需要審核的新帳號 + pending_account: 有新的帳號需要審核 reblog: 當有使用者轉嘟您的嘟文時,傳送電子郵件通知 report: 新回報已遞交 + software_updates: + all: 通知所有更新 + critical: 僅通知重要更新 + label: 有可取得的 Mastodon 新版本 + none: 永不通知更新(不建議) + patch: 通知錯誤修正更新 trending_tag: 新熱門趨勢需要審核 rule: text: 規則 + settings: + indexable: 於搜尋引擎中包含個人檔案頁面 + show_application: 顯示您發嘟文之應用程式 tag: listable: 允許此主題標籤在搜尋及個人檔案目錄中顯示 name: 主題標籤 @@ -296,6 +310,7 @@ zh-TW: usable: 允許嘟文使用此主題標籤 user: role: 角色 + time_zone: 時區 user_role: color: 識別顏色 highlighted: 在使用者個人檔案上將角色顯示為徽章 @@ -304,9 +319,11 @@ zh-TW: position: 優先權 webhook: events: 已啟用的事件 + template: Payload 樣板 url: 端點 URL 'no': 否 not_recommended: 不建議 + overridden: 已覆寫 recommended: 建議 required: mark: "*" diff --git a/config/locales/sk.yml b/config/locales/sk.yml index c453ee125f..78b9b87db3 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -5,7 +5,7 @@ sk: contact_missing: Nezadaný contact_unavailable: Neuvedený/á hosted_on: Mastodon hostovaný na %{domain} - title: O + title: Ohľadom accounts: follow: Nasleduj followers: @@ -95,6 +95,7 @@ sk: moderation: active: Aktívny/a all: Všetko + disabled: Blokovaný pending: Čakajúci silenced: Obmedzený suspended: Vylúčený/á @@ -117,14 +118,13 @@ sk: redownloaded_msg: Úspešne obnovený profil %{username} z pôvodného reject: Zamietni rejected_msg: Úspešne zamietnutá prihláška %{username} + remote_suspension_irreversible: Údaje tohto účtu boli nenávratne zmazané. remove_avatar: Vymaž avatar remove_header: Vymaž záhlavie removed_avatar_msg: Úspešne odstránený obrázok avatara %{username} removed_header_msg: Úspešne odstránený obrázok hlavičky %{username} resend_confirmation: already_confirmed: Tento užívateľ je už potvrdený - send: Odošli potvrdzovací email znovu - success: Potvrdzujúci email bol úspešne odoslaný! reset: Resetuj reset_password: Obnov heslo resubscribe: Znovu odoberaj @@ -132,6 +132,7 @@ sk: search: Hľadaj search_same_email_domain: Iní užívatelia s tou istou emailovou doménou search_same_ip: Ostatní užívatelia s rovnakou IP adresou + security: Zabezpečenie security_measures: only_password: Iba heslo password_and_2fa: Heslo a dvoj-faktorové overovanie @@ -173,6 +174,7 @@ sk: confirm_user: Potvrď užívateľa create_account_warning: Vytvor výstrahu create_announcement: Vytvor oboznámenie + create_canonical_email_block: Vytvor blokovanie emailu create_custom_emoji: Vytvor vlastné emotikony create_domain_allow: Vytvor povolenie pre doménu create_domain_block: Vytvor zákaz domény @@ -211,22 +213,45 @@ sk: unsilence_account: Zvráť obmedzenie účtu unsuspend_account: Odblokuj účet update_announcement: Aktualizuj oboznámenie + update_custom_emoji: Aktualizuj vlastné emotikony update_domain_block: Aktualizuj zákaz domény update_ip_block: Aktualizovať IP pravidlo update_status: Aktualizuj stav update_user_role: Aktualizovať rolu actions: + approve_appeal_html: "%{name} odsúhlasil/a námietku na moderátorské rozhodnutie od %{target}" + approve_user_html: "%{name} odsúhlasil/a registráciu od %{target}" assigned_to_self_report_html: "%{name} pridelil/a hlásenie užívateľa %{target} sebe" change_email_user_html: "%{name} zmenil/a emailovú adresu užívateľa %{target}" + change_role_user_html: "%{name} zmenil/a rolu pre %{target}" confirm_user_html: "%{name} potvrdil/a emailovú adresu používateľa %{target}" create_account_warning_html: "%{name} poslal/a upozornenie užívateľovi %{target}" + create_announcement_html: "%{name} vytvoril/a nové oboznámenie %{target}" + create_custom_emoji_html: "%{name} nahral/a novú emotikonu %{target}" + create_domain_block_html: "%{name} zablokoval/a doménu %{target}" + create_email_domain_block_html: "%{name} zablokoval/a e-mailovú doménu %{target}" + create_user_role_html: "%{name} vytvoril/a rolu pre %{target}" demote_user_html: "%{name} degradoval/a užívateľa %{target}" + destroy_announcement_html: "%{name} vymazal/a oboznámenie %{target}" destroy_canonical_email_block_html: "%{name} odblokoval/i email z hašom %{target}" + destroy_custom_emoji_html: "%{name} vymazal/a emotikonu %{target}" destroy_domain_allow_html: "%{name} zakázal/a federáciu s doménou %{target}" destroy_domain_block_html: "%{name} odblokoval/i doménu %{target}" + destroy_email_domain_block_html: "%{name} odblokoval/a e-mailovú doménu %{target}" destroy_ip_block_html: "%{name} vymazal/a pravidlo pre IP %{target}" destroy_status_html: "%{name} zmazal/a príspevok od %{target}" + destroy_user_role_html: "%{name} vymazal/a rolu pre %{target}" + memorialize_account_html: "%{name} zmenil/a účet %{target} na pamätnú stránku" reject_appeal_html: "%{name} zamietol/la námietku moderovacieho rozhodnutia od %{target}" + reopen_report_html: "%{name} znovu otvoril/a nahlásenie %{target}" + resend_user_html: "%{name} znovu odoslal/a potvrdzovací email pre %{target}" + reset_password_user_html: "%{name} resetoval/a heslo používateľa %{target}" + resolve_report_html: "%{name} vyriešil/a nahlásenie %{target}" + sensitive_account_html: "%{name} označil médium od %{target} za chúlostivé" + silence_account_html: "%{name} obmedzil/a účet %{target}" + suspend_account_html: "%{name} zablokoval/a účet používateľa %{target}" + unassigned_report_html: "%{name} odobral/a report od %{target}" + update_user_role_html: "%{name} zmenil/a rolu pre %{target}" deleted_account: zmazaný účet empty: Žiadne záznamy nenájdené. filter_by_action: Filtruj podľa úkonu @@ -247,6 +272,8 @@ sk: scheduled_msg: Oboznámenie bolo naplánované na zverejnenie! title: Oboznámenia unpublish: Zruš zverejnenie + updated_msg: Oboznámenie úspešne aktualizované! + critical_update_pending: Čaká kritická aktualizácia custom_emojis: assign_category: Priraď kategóriu by_domain: Doména @@ -307,6 +334,10 @@ sk: undo: Odober zo zoznamu povolených domain_blocks: add_new: Blokuj novú doménu + confirm_suspension: + cancel: Zruš + confirm: Vylúč + title: Potvrď blokovanie domény %{domain} created_msg: Doména je v štádiu blokovania destroyed_msg: Blokovanie domény bolo zrušené domain: Doména @@ -344,6 +375,7 @@ sk: create: Pridaj doménu resolve: Preveď doménu title: Nový email na zablokovanie + not_permitted: Nepovolená resolved_through_html: Prevedená cez %{domain} title: Blokované emailové adresy export_domain_allows: @@ -387,12 +419,16 @@ sk: instance_accounts_dimension: Najsledovanejšie účty instance_accounts_measure: uložené účty instance_follows_measure: ich sledovatelia tu + instance_languages_dimension: Najpopulárnejšie jazyky + instance_media_attachments_measure: uložené mediálne prílohy + instance_reports_measure: hlásenia o nich instance_statuses_measure: uložené príspevky delivery: all: Všetko failing: Zlyhávajúce unavailable: Nedostupné delivery_available: Je v dosahu doručovania + empty: Nenájdené žiadne domény. moderation: all: Všetky limited: Obmedzené @@ -403,7 +439,7 @@ sk: total_blocked_by_us: Nami blokované total_followed_by_them: Nimi sledované total_followed_by_us: Nami sledované - total_reported: Nahlásenia o nich + total_reported: Hlásenia o nich total_storage: Mediálne prílohy invites: deactivate_all: Pozastav všetky @@ -450,6 +486,12 @@ sk: created_msg: Poznámka o nahlásení úspešne vytvorená! destroyed_msg: Poznámka o nahlásení úspešne vymazaná! reports: + account: + notes: + few: "%{count} poznámok" + many: "%{count} poznámok" + one: "%{count} poznámka" + other: "%{count} poznámky" action_taken_by: Zákrok vykonal/a actions: suspend_description_html: Tento účet a všetok jeho obsah bude nedostupný a nakoniec zmazaný, interaktovať s ním bude nemožné. Zvrátiteľné v rámci 30 dní. Uzatvára všetky hlásenia voči tomuto účtu. @@ -458,9 +500,11 @@ sk: assign_to_self: Priraď sebe assigned: Priradený moderátor by_target_domain: Doména nahláseného účtu + cancel: Zruš category: Kategória comment: none: Žiadne + confirm: Potvrď created_at: Nahlásené delete_and_resolve: Vymaž príspevky forwarded: Preposlané @@ -483,15 +527,19 @@ sk: reported_by: Nahlásené užívateľom resolved: Vyriešené resolved_msg: Hlásenie úspešne vyriešené! + skip_to_actions: Prejsť na akcie status: Stav statuses: Nahlásený obsah summary: + action_preambles: + suspend_html: 'Chystáš sa vylúčiť účet @%{acct}. To urobí:' actions: delete_html: Vymaž pohoršujúce príspevky mark_as_sensitive_html: Označ médiá pohoršujúcich príspevkov za chúlostivé close_report: 'Označ hlásenie #%{id} za vyriešené' title: Hlásenia unassign: Odober + unknown_action_msg: 'Neznáma akcia: %{action}' unresolved: Nevyriešené updated_at: Aktualizované view_profile: Zobraz profil @@ -508,13 +556,20 @@ sk: moderation: Moderácia delete: Vymaž edit: Uprav postavenie %{name} + everyone: Východzie oprávnenia privileges: administrator: Správca delete_user_data: Vymaž užívateľské dáta invite_users: Pozvi užívateľov manage_announcements: Spravuj oboznámenia manage_appeals: Spravuj námietky + manage_blocks: Spravuj blokovania + manage_federation: Spravuj federáciu + manage_invites: Spravuj pozvánky + manage_reports: Spravuj hlásenia manage_roles: Spravuj postavenia + manage_rules: Spravuj pravidlá + manage_settings: Spravuj nastavenia manage_users: Spravuj užívateľov title: Postavenia rules: @@ -524,9 +579,13 @@ sk: empty: Žiadne pravidlá servera ešte neboli určené. title: Serverové pravidlá settings: + about: + title: Ohľadom appearance: title: Vzhľad discovery: + follow_recommendations: Odporúčania pre nasledovanie + profile_directory: Katalóg profilov public_timelines: Verejné časové osi publish_discovered_servers: Zverejni objavené servery publish_statistics: Zverejni štatistiky @@ -543,7 +602,6 @@ sk: approved: Pre registráciu je nutné povolenie none: Nikto sa nemôže registrovať open: Ktokoľvek sa môže zaregistrovať - title: Nastavenia servera site_uploads: delete: Vymaž nahratý súbor destroyed_msg: Nahratie bolo zo stránky úspešne vymazané! @@ -570,10 +628,15 @@ sk: with_media: S médiami strikes: appeal_approved: Namietnuté + appeal_rejected: Námietka zamietnutá system_checks: rules_check: action: Spravuj serverové pravidlá message_html: Neurčil/a si žiadne serverové pravidlá. + upload_check_privacy_error: + action: Pozri tu pre viac informácií + upload_check_privacy_error_object_storage: + action: Pozri tu pre viac informácií tags: review: Prehodnoť stav updated_msg: Nastavenia haštagov boli úspešne aktualizované @@ -594,10 +657,14 @@ sk: title: Zverejňovatelia rejected: Odmietnuté statuses: + allow: Povoľ príspevok + allow_account: Povoľ autora disallow: Zakáž príspevok disallow_account: Zakáž autora title: Populárne príspevky tags: + dashboard: + tag_uses_measure: užívateľov celkovo title: Populárne štítky trending_rank: 'Populárne #%{rank}' usable: Môže byť použitý @@ -626,6 +693,8 @@ sk: title: Populárne odkazy new_trending_statuses: title: Populárne príspevky + new_trending_tags: + title: Populárne haštagy aliases: add_new: Vytvor alias created_msg: Nový alias úspešne vytvorený. Teraz môžeš začať presun zo starého účtu. @@ -641,29 +710,31 @@ sk: body: Mastodon je prekladaný dobrovoľníkmi. guide_link_text: Prispievať môže každý. sensitive_content: Chúlostivý obsah - toot_layout: Rozloženie príspevkov application_mailer: notification_preferences: Zmeň emailové voľby settings: 'Zmeň emailové voľby: %{link}' + unsubscribe: Prestaň odoberať view: 'Zobraziť:' view_profile: Zobraz profil view_status: Zobraz status applications: created: Aplikácia bola vytvorená úspešne destroyed: Aplikáciu sa podarilo odstrániť + logout: Odhlás sa regenerate_token: Znovu vygeneruj prístupový token token_regenerated: Prístupový token bol úspešne vygenerovaný znova warning: Na tieto údaje dávaj ohromný pozor. Nikdy ich s nikým nezďieľaj! your_token: Tvoj prístupový token auth: - change_password: Heslo + apply_for_account: Vyžiadaj si účet + captcha_confirmation: + title: Bezpečnostná kontrola delete_account: Vymaž účet delete_account_html: Pokiaľ chceš svoj účet odtiaľto vymazať, môžeš tak urobiť tu. Budeš požiadaný/á o potvrdenie tohto kroku. description: prefix_invited_by_user: "@%{name} ťa pozýva na tento Mastodon server!" prefix_sign_up: Zaregistruj sa na Mastodone už dnes! suffix: S pomocou účtu budeš môcť nasledovať ľudí, posielať príspevky, a vymieňať si správy s užívateľmi na hocijakom Mastodon serveri, ale aj na iných serveroch! - didnt_get_confirmation: Neobdržal/a si kroky na potvrdenie? forgot_password: Zabudnuté heslo? invalid_reset_password_token: Token na obnovu hesla vypršal. Prosím vypítaj si nový. log_in_with: Prihlás sa s @@ -672,33 +743,27 @@ sk: migrate_account: Presúvam sa na iný účet migrate_account_html: Ak si želáš presmerovať tento účet na nejaký iný, môžeš si to nastaviť tu. or_log_in_with: Alebo prihlás s + progress: + confirm: Potvrď email register: Zaregistruj sa registration_closed: "%{instance} neprijíma nových členov" - resend_confirmation: Zašli potvrdzujúce pokyny znovu + resend_confirmation: Odošli potvrdzovací odkaz znovu reset_password: Obnov heslo + rules: + accept: Prijať + back: Späť + title_invited: Bol/a si pozvaný/á. security: Zabezpečenie set_new_password: Nastav nové heslo setup: - email_below_hint_html: Ak je nižšie uvedená emailová adresa nesprávna, môžeš ju zmeniť a dostať nový potvrdzovací email. - email_settings_hint_html: Potvrdzovací email bol odoslaný na %{email}. Ak táto emailová adresa nieje správna, môžeš si ju zmeniť v nastaveniach účtu. - title: Nastavenie + link_not_received: Nedostal/a si odkaz? + title: Skontroluj svoju schránku status: account_status: Stav účtu confirming: Čaká sa na dokončenie potvrdenia emailom. pending: Tvoja žiadosť čaká na schvílenie od nášho týmu. Môže to chviľu potrvať. Ak bude tvoja žiadosť schválená, dostaneš o tom email. redirecting_to: Tvoj účet je neaktívny, lebo v súčasnosti presmerováva na %{acct}. use_security_key: Použi bezpečnostný kľúč - authorize_follow: - already_following: Tento účet už nasleduješ - error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu - follow: Nasleduj - follow_request: 'Poslal/a si žiadosť nasledovať užívateľa:' - following: 'Podarilo sa! Teraz nasleduješ užívateľa:' - post_follow: - close: Alebo môžeš iba zatvoriť toto okno. - return: Ukáž užívateľov profil - web: Prejdi do siete - title: Nasleduj %{acct} challenge: confirm: Pokračuj hint_html: "Tip: Hodinu nebudeme znovu vyžadovať tvoje heslo." @@ -741,6 +806,8 @@ sk: appeals: submit: Pošli námietku approve_appeal: Schváľ námietku + created_at: Dátumom + recipient: Adresované pre title_actions: none: Varovanie silence: Obmedzenie účtu @@ -781,7 +848,7 @@ sk: featured_tags: add_new: Pridaj nový errors: - limit: Už si si predvolil/a najvyšší možný počet obľúbených haštagov + limit: Už si si predvolil/a najvyšší možný počet haštagov filters: contexts: account: Profily @@ -799,8 +866,6 @@ sk: title: Triedenia new: title: Pridaj nové triedenie - footer: - trending_now: Teraz populárne generic: all: Všetko changes_saved_msg: Zmeny boli úspešne uložené! @@ -813,8 +878,6 @@ sk: many: Niečo ešte nieje celkom v poriadku! Prosím skontroluj %{count} chýb uvedených nižšie one: Niečo ešte nieje celkom v poriadku! Prosím skontroluj chybu uvedenú nižšie other: Niečo ešte nieje celkom v poriadku! Prosím skontroluj %{count} chyby uvedené nižšie - html_validator: - invalid_markup: 'obsahuje neplatný HTML kód: %{error}' imports: errors: over_rows_processing_limit: obsahuje viac než %{count} riadkov @@ -825,6 +888,8 @@ sk: overwrite_long: Nahraď súčasné záznamy novými preface: Môžeš nahrať dáta ktoré si exportoval/a z iného Mastodon serveru, ako sú napríklad zoznamy ľudí ktorých sleduješ, alebo blokuješ. success: Tvoje dáta boli nahraté úspešne, a teraz budú spracované v danom čase + type_groups: + constructive: Sledovania a záložky types: blocking: Zoznam blokovaných bookmarks: Záložky @@ -858,7 +923,7 @@ sk: title: Pozvi ľudí lists: errors: - limit: Dosiahli ste maximálny možný počet zoznamov + limit: Dosiahli ste maximálny počet zoznamov login_activities: authentication_methods: password: heslom @@ -907,9 +972,9 @@ sk: carry_mutes_over_text: Tento užívateľ sa presunul z účtu %{acct}, ktorý si mal/a stíšený. notification_mailer: favourite: - body: 'Tvoj príspevok bol uložený medzi obľúbené užívateľa %{name}:' + body: 'Tvoj príspevok bol obľúbený užívateľom %{name}:' subject: "%{name} si obľúbil/a tvoj príspevok" - title: Nové obľúbené + title: Novo obľúbené follow: body: "%{name} ťa teraz následuje!" subject: "%{name} ťa teraz nasleduje" @@ -960,6 +1025,8 @@ sk: other: Ostatné posting_defaults: Východiskové nastavenia príspevkov public_timelines: Verejné časové osi + privacy: + title: Súkromie a dosah reactions: errors: limit_reached: Maximálny počet rôznorodých reakcií bol dosiahnutý @@ -1001,6 +1068,7 @@ sk: otter: Prehliadač Otter qq: QQ Prehliadač safari: Apple Safari + unknown_browser: Neznámy prehliadač weibo: Sina/Tencent Weibo current_session: Aktuálna sezóna description: "%{browser} na %{platform}" @@ -1010,7 +1078,7 @@ sk: ios: Apple iOS linux: GNU/Linux mac: MacOSX - other: neznáma platforma + unknown_platform: Neznáma platforma windows: Microsoft Windows revoke: Zamietni revoke_success: Sezóna úspešne zamietnutá @@ -1051,7 +1119,7 @@ sk: one: 'obsahoval nepovolený haštag: %{tags}' other: 'obsahoval nepovolené haštagy: %{tags}' errors: - in_reply_not_found: Príspevok, na ktorý sa snažíš odpovedať, už pravdepodobne neexistuje. + in_reply_not_found: Príspevok, na ktorý sa snažíš odpovedať, pravdepodobne neexistuje. open_in_web: Otvor v okne na webe over_character_limit: limit %{max} znakov bol presiahnutý pin_errors: @@ -1072,7 +1140,6 @@ sk: vote: Hlasuj show_more: Ukáž viac show_thread: Ukáž diskusné vlákno - sign_in_to_participate: Prihlás sa pre zapojenie do diskusie title: '%{name}: „%{quote}"' visibilities: private: Iba pre sledovateľov @@ -1086,8 +1153,6 @@ sk: keep_pinned_hint: Nevymaže žiadne s tvojich pripnutých príspevkov keep_self_bookmark: Ponechaj príspevky, ktoré sú záložkami stream_entries: - pinned: Pripnutý príspevok - reblogged: vyzdvihli sensitive_content: Senzitívny obsah tags: does_not_match_previous_name: nezhoduje sa s predošlým názvom @@ -1098,6 +1163,9 @@ sk: time: formats: default: "%b %d, %R, %H:%M" + translation: + errors: + too_many_requests: V poslednej dobe bolo na prekladateľskú službu vykonaných priveľa požiadaviek. two_factor_authentication: disable: Zakáž enabled: Dvojfázové overovanie je povolené @@ -1140,5 +1208,4 @@ sk: seamless_external_login: Si prihlásená/ý cez externú službu, takže nastavenia hesla a emailu ti niesú prístupné. signed_in_as: 'Prihlásená/ý ako:' verification: - explanation_html: 'Môžeš sa overiť ako majiteľ odkazov v metadátach tvojho profilu. Na to ale musí odkazovaná stránka obsahovať odkaz späť na tvoj Mastodon profil. Tento spätný odkaz musí mať prívlastok rel="me". Na texte odkazu nezáleží. Tu je príklad:' verification: Overenie diff --git a/config/locales/sl.yml b/config/locales/sl.yml index e2f712d7f8..35230ceddb 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -95,6 +95,7 @@ sl: moderation: active: Dejaven all: Vse + disabled: Onemogočeno pending: Na čakanju silenced: Omejeno suspended: Suspendiran @@ -130,8 +131,8 @@ sl: removed_header_msg: Uspešno odstranjena naslovna slika uporabnika %{username} resend_confirmation: already_confirmed: Ta uporabnik je že potrjen - send: Ponovno pošlji potrditveno e-sporočilo - success: Potrditveno e-sporočilo je uspešno poslano! + send: Ponovno pošlji potrditveno povezavo + success: Potrditvena povezava je uspešno poslana! reset: Ponastavi reset_password: Ponastavi geslo resubscribe: Ponovno se naroči @@ -139,6 +140,7 @@ sl: search: Iskanje search_same_email_domain: Drugi uporabniki z isto e-poštno domeno search_same_ip: Drugi uporabniki z istim IP + security: Varnost security_measures: only_password: Samo geslo password_and_2fa: Geslo in 2FA @@ -313,6 +315,7 @@ sl: unpublish: Umakni iz objave unpublished_msg: Obvestilo je bilo uspešno umaknjeno! updated_msg: Obvestilo je bilo uspešno posodobljeno! + critical_update_pending: Nujna posodobitev v teku custom_emojis: assign_category: Dodeli kategorijo by_domain: Domena @@ -394,6 +397,13 @@ sl: undo: Odstrani iz belega seznama domain_blocks: add_new: Dodaj nov domenski blok + confirm_suspension: + cancel: Prekliči + confirm: Suspendiraj + permanent_action: Z razveljavitvijo suzpenza ne boste obnovili nobenih podatkov ali razmerij. + remove_all_data: S tem boste odstranili celotno vsebino, medijske vsebine ter podatke iz profila za rčune te domene na vašem strežniku. + stop_communication: Vaš strežnik bo prenehal komunicirati s temi strežniki. + title: Potrdi domenski blok za %{domain} created_msg: Domenski blok se sedaj obdeluje destroyed_msg: Domenski blok je bil razveljavljen domain: Domena @@ -443,6 +453,7 @@ sl: resolve: Razreši domeno title: Nov vnos e-pošte na črni seznam no_email_domain_block_selected: Nobena domena e-računa ni bila spremenjena, ker nobena ni bila izbrana + not_permitted: Ni dovoljeno resolved_dns_records_hint_html: Ime domene se razreši na naslednje domene MX, ki so končno odgovorne za sprejemanje e-pošte. Blokiranje domene MX bo blokiralo prijave s poljubnega e-poštnega naslova, ki uporablja isto domeno MX, tudi če je vidno ime domene drugačno. Pazite, da ne blokirate večjih ponudnikov e-pošte. resolved_through_html: Razrešeno prek %{domain} title: Črni seznam e-pošt @@ -493,6 +504,7 @@ sl: content_policies: comment: Interna opomba description_html: Določite lahko pravila (t.i. politike), ki bodo veljale za vse račune te domene ter vseh njenih poddomen. + limited_federation_mode_description_html: Izberete lahko, ali dovolite federacijo s to domeno. policies: reject_media: Zavrni večpredstavnost reject_reports: Zavrni prijave @@ -609,11 +621,13 @@ sl: assign_to_self: Dodeli meni assigned: Dodeljen moderator by_target_domain: Domena prijavljenega računa + cancel: Prekliči category: Kategorija category_description_html: Razlog, zakaj je ta račun in/ali vsebina prijavljena, bo naveden v komunikaciji z računom iz prijave comment: none: Brez comment_description_html: 'V pojasnilo je %{name} zapisal/a:' + confirm: Potrdi confirm_action: Potrdite dejanje moderiranja proti @%{acct} created_at: Prijavljeno delete_and_resolve: Izbriši objave @@ -780,10 +794,23 @@ sl: approved: Potrebna je odobritev za prijavo none: Nihče se ne more prijaviti open: Vsakdo se lahko prijavi + security: + authorized_fetch_overridden_hint: Trenutno ne morete spremeniti te nastavitve, ker jo preglasi okoljska spremenljivka. title: Nastavitve strežnika site_uploads: delete: Izbriši naloženo datoteko destroyed_msg: Prenos na strežnik uspešno izbrisan! + software_updates: + critical_update: Kritično — čim prej posodobite + documentation_link: Več o tem + release_notes: Opombe ob izdaji + title: Razpoložljive posodobitve + type: Vrsta + types: + major: Osrednja izdaja + minor: Izdaja z manjšimi spremembami + patch: Izdaja popravkov - popravki hroščev in enostavne spremembe v kodi + version: Različica statuses: account: Avtor application: Program @@ -820,9 +847,14 @@ sl: suspend: "%{name} je suspendiral/a račun uporabnika %{target}" appeal_approved: Pritoženo appeal_pending: Čakajoč na ugovor + appeal_rejected: Pritožba zavrnjena system_checks: database_schema_check: message_html: Na čakanju so migracije zbirke podatkov. Prosimo, izvedite jih, da zagotovite, da se program vede pričakovano + elasticsearch_preset: + action: Glejte dokumentacijo + elasticsearch_preset_single_node: + action: Glejte dokumentacijo elasticsearch_running_check: message_html: Povezava z Elasticsearch ni uspela. Preverite, da deluje, ali onemogočite iskanje po vsem besedilu elasticsearch_version_check: @@ -833,6 +865,17 @@ sl: message_html: Nobenih pravil strežnika niste določili. sidekiq_process_check: message_html: Noben proces Sidekiq ne poteka za %{value} vrst. Preglejte svojo prilagoditev Sidekiq + software_version_critical_check: + action: Glejte razpoložljive posodobitve + software_version_patch_check: + action: Glejte razpoložljive posodobitve + message_html: Na voljo je posodobitev Mastodona s popravki hroščev. + upload_check_privacy_error: + action: Preverite tukaj za več informacij + message_html: "Vaš spletni strežnik je napačno nastavljen. Zasebnost vaših uporabnikov je izpostavljena tveganjem." + upload_check_privacy_error_object_storage: + action: Preverite tukaj za več informacij + message_html: "Vaša predmetna shramba je napačno nastavljena. Zasebnost vaših uporabnikov je izpostavljena tveganjem." tags: review: Stanje pregleda updated_msg: Nastavitve ključnikov uspešno posodobljene @@ -857,6 +900,7 @@ sl: two: Delili %{count} osebi v zadnjem tednu title: Povezave v trendu usage_comparison: Danes deljeno %{today}-krat, včeraj pa %{yesterday}-krat + not_allowed_to_trend: Ni dovoljeno, da bi bilo v trendu only_allowed: Samo dovoljeni pending_review: Čakajoče na pregled preview_card_providers: @@ -983,24 +1027,26 @@ sl: guide_link: https://crowdin.com/project/mastodon guide_link_text: Vsakdo lahko prispeva. sensitive_content: Občutljiva vsebina - toot_layout: Postavitev objave application_mailer: notification_preferences: Spremenite e-poštne nastavitve salutation: "%{name}," settings: 'Spremenite e-poštne nastavitve: %{link}' + unsubscribe: Odjavi od naročnine view: 'Pogled:' view_profile: Ogled profila view_status: Pokaži objavo applications: created: Aplikacija je bila uspešno ustvarjena destroyed: Aplikacija je bila uspešno izbrisana + logout: Odjava regenerate_token: Obnovite dostopni žeton token_regenerated: Dostopni žeton je bil uspešno regeneriran warning: Bodite zelo previdni s temi podatki. Nikoli jih ne delite z nikomer! your_token: Vaš dostopni žeton auth: apply_for_account: Zaprosite za račun - change_password: Geslo + captcha_confirmation: + title: Varnostno preverjanje confirmations: wrong_email_hint: Če ta e-poštni naslov ni pravilen, ga lahko spremenite v nastavitvah računa. delete_account: Izbriši račun @@ -1009,7 +1055,7 @@ sl: prefix_invited_by_user: "@%{name} vas vabi, da se pridružite temu strežniku Mastodon!" prefix_sign_up: Še danes se priključite Mastodonu! suffix: Z računom boste lahko sledili osebam, objavljali posodobitve in izmenjevali sporočila z uporabniki s poljubnega strežnika Mastodon in še veliko več! - didnt_get_confirmation: Niste prejeli navodil za potrditev? + didnt_get_confirmation: Ali niste prejeli potrditvene povezave? dont_have_your_security_key: Ali imate svoj varnostni ključ? forgot_password: Ste pozabili svoje geslo? invalid_reset_password_token: Žeton za ponastavitev gesla je neveljaven ali je potekel. Zahtevajte novo. @@ -1022,26 +1068,37 @@ sl: migrate_account_html: Če želite ta račun preusmeriti na drugega, ga lahko nastavite tukaj. or_log_in_with: Ali se prijavite z privacy_policy_agreement_html: Prebral_a sem in se strinjam s pravilnikom o zasebnosti. + progress: + confirm: Potrdi e-pošto + details: Vaši podatki + review: Naš pregled + rules: Sprejmi pravila providers: cas: CAS saml: SAML register: Vpis registration_closed: "%{instance} ne sprejema novih članov" - resend_confirmation: Ponovno pošlji navodila za potrditev + resend_confirmation: Ponovno pošlji potrditveno povezavo reset_password: Ponastavi geslo rules: + accept: Sprejmi + back: Nazaj preamble: Slednje določajo in njihovo spoštovanje zagotavljajo moderatorji %{domain}. title: Nekaj osnovnih pravil. + title_invited: Ste povabljeni. security: Varnost set_new_password: Nastavi novo geslo setup: - email_below_hint_html: Če spodnji e-poštni naslov ni pravilen, ga lahko spremenite tukaj in prejmete novo potrditveno e-pošto. - email_settings_hint_html: Potrditvena e-pošta je bila poslana na %{email}. Če ta e-poštni naslov ni pravilen, ga lahko spremenite v nastavitvah računa. - title: Nastavitev + email_below_hint_html: Poglejte v mapo neželene pošte ali zaprosite za novega. Če ste podali napačen e-naslov, ga lahko popravite. + email_settings_hint_html: Kliknite povezavo, ki smo vam jo poslali, da overite %{email}. Počakali bomo. + link_not_received: Ali ste prejeli povezavo? + new_confirmation_instructions_sent: Čez nekaj minut boste prejeli novo e-sporočilo s potrditveno povezavo! + title: Preverite svojo dohodno e-pošto sign_in: preamble_html: Prijavite se s svojimi poverilnicami %{domain}. Če vaš račun gostuje na drugem strežniku, se tukaj ne boste mogli prijaviti. title: Vpiši se v %{domain} sign_up: + manual_review: Registracije na %{domain} ročno pregledajo naši moderatorji. Da nam olajšate obdelavo vaše prijave, zapišite kaj o sebi in zakaj si želite račun na %{domain}. preamble: Z računom na strežniku Mastodon boste lahko sledili vsem drugim v tem omrežju, ne glede na to, kje gostuje njihov račun. title: Naj vas namestimo na %{domain}. status: @@ -1053,18 +1110,6 @@ sl: view_strikes: Pokaži pretekle ukrepe proti mojemu računu too_fast: Obrazec oddan prehitro, poskusite znova. use_security_key: Uporabi varnostni ključ - authorize_follow: - already_following: Temu računu že sledite - already_requested: Temu računu ste že poslali zahtevo po sledenju - error: Na žalost je prišlo do napake pri iskanju oddaljenega računa - follow: Sledi - follow_request: 'Prošnjo za sledenje se poslali:' - following: 'Uspeh! Zdaj sledite:' - post_follow: - close: Lahko pa tudi zaprete to okno. - return: Prikaži uporabnikov profil - web: Pojdi na splet - title: Sledi %{acct} challenge: confirm: Nadaljuj hint_html: "Namig: naslednjo uro vas ne bomo več vprašali po vašem geslu." @@ -1141,6 +1186,9 @@ sl: your_appeal_rejected: Vaša pritožba je bila zavržena domain_validator: invalid_domain: ni veljavno ime domene + edit_profile: + basic_information: Osnovni podatki + other: Drugo errors: '400': Zahteva, ki ste jo oddali, je neveljavna ali nepravilno oblikovana. '403': Nimate dovoljenja za ogled te strani. @@ -1227,8 +1275,6 @@ sl: index: hint: Ta filter se nanaša na posamezne objave ne glede na druge pogoje. Filtru lahko dodate več objav prek spletnega vmesnika. title: Filtrirane objave - footer: - trending_now: Zdaj v trendu generic: all: Vse all_items_on_page_selected_html: @@ -1241,7 +1287,9 @@ sl: one: Izbran je %{count} element, ki ustreza vašemu iskanju. other: Izbranih je %{count} elementov, ki ustrezajo vašemu iskanju. two: Izbrana sta %{count} elementa, ki ustrezata vašemu iskanju. + cancel: Prekliči changes_saved_msg: Spremembe so uspešno shranjene! + confirm: Potrdi copy: Kopiraj delete: Izbriši deselect: Prekliči ves izbor @@ -1259,24 +1307,48 @@ sl: one: Nekaj še ni čisto v redu! Spodaj si oglejte napako other: Nekaj še ni čisto v redu! Spodaj si oglejte %{count} napak two: Nekaj še ni čisto v redu! Spodaj si oglejte %{count} napaki - html_validator: - invalid_markup: 'vsebuje neveljavno oznako HTML: %{error}' imports: errors: + empty: Prazna datoteka CSV + incompatible_type: Nezdružljivo z izbrano vrsto uvoza invalid_csv_file: 'Neveljavna datoteka CSV. Napaka: %{error}' over_rows_processing_limit: vsebuje več kot %{count} vrstic + too_large: Datoteka je prevelika + failures: Neuspehi + imported: Uvoženo + mismatched_types_warning: Kaže, da ste izbrali napačno vrsto za ta uvoz; preverite svoj izbor. modes: merge: Združi merge_long: Ohrani obstoječe zapise in dodaj nove overwrite: Prepiši overwrite_long: Zamenjaj trenutne zapise z novimi preface: Podatke, ki ste jih izvozili iz drugega strežnika, lahko uvozite. Na primer seznam oseb, ki jih spremljate ali blokirate. + recent_imports: Nedavni uvozi + states: + finished: Končano + in_progress: V teku + scheduled: Načrtovano + unconfirmed: Nepotrjeno + status: Stanje success: Vaši podatki so bili uspešno naloženi in bodo zdaj pravočasno obdelani + time_started: Začetek ob + titles: + blocking: Uvažanje blokiranih računov + bookmarks: Uvažanje zaznamkov + domain_blocking: Uvažanje blokiranih domen + following: Uvažanje sledenih računov + lists: Uvažanje seznamov + muting: Uvažanje utišanih računov + type: Vrsta uvoza + type_groups: + constructive: Sledenje in zaznamki + destructive: Blokiranja in utišanja types: blocking: Seznam blokiranih bookmarks: Zaznamki domain_blocking: Seznam blokiranih domen following: Seznam uporabnikov, katerim sledite + lists: Seznami muting: Seznam utišanih upload: Pošlji invites: @@ -1317,6 +1389,19 @@ sl: failed_sign_in_html: Spodletela prijava z metodo %{method} iz %{ip} (%{browser}) successful_sign_in_html: Uspešna prijava z metodo %{method} iz %{ip} (%{browser}) title: Zgodovina overjanja + mail_subscriptions: + unsubscribe: + action: Da, odjavi me + complete: Odjavljeni + emails: + notification_emails: + favourite: e-sporočil z obvestili o priljubljenosti + follow: e-sporočil z obvestili o sledenju + follow_request: e-sporočil o zahtevah za sledenje + mention: e-sporočil z obvestili o omembah + reblog: e-sporočil z obvestili o izpostavljanju + success_html: Nič več ne boste prejemali %{type} za Mastodon na %{domain} na svoj e-naslov %{email}. + title: Odjavi od naročnine media_attachments: validations: images_and_video: Videoposnetka ni mogoče priložiti objavi, ki že vsebuje slike @@ -1396,6 +1481,7 @@ sl: update: subject: "%{name} je uredil(a) objavo" notifications: + administration_emails: E-poštna obvestila skrbnika email_events: Dogodki za e-obvestila email_events_hint: 'Izberite dogodke, za katere želite prejmati obvestila:' other_settings: Druge nastavitve obvestil @@ -1432,12 +1518,18 @@ sl: expired: Glasovanje se je že zaključilo invalid_choice: Izbrana možnost glasovanja ne obstaja over_character_limit: ne more biti daljše od %{max} znakov + self_vote: Ne morete glasovati v lastnih anketah too_few_options: mora imeti več kot en element too_many_options: ne more vsebovati več kot %{max} elementov preferences: other: Ostalo posting_defaults: Privzete nastavitev objavljanja public_timelines: Javne časovnice + privacy: + privacy: Zasebnost + reach: Dosegljivost + search: Iskanje + title: Zasebnost in dosegljivost privacy_policy: title: Pravilnik o zasebnosti reactions: @@ -1450,6 +1542,7 @@ sl: confirm_remove_selected_followers: Ali ste prepričani, da želite odstraniti izbrane sledilce? confirm_remove_selected_follows: Ali ste prepričani, da želite odstraniti izbrana sledenja? dormant: Skrit + follow_failure: Nekaterim od izbranih računov ni bilo mogoče slediti. follow_selected_followers: Sledi izbranim sledilcem followers: Sledilci following: Sledi @@ -1489,6 +1582,7 @@ sl: electron: Electron firefox: Firefox generic: Neznan brskalnik + huawei_browser: Brskalnik Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Brskalnik Nokia S40 Ovi @@ -1498,6 +1592,7 @@ sl: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Neznan brskalnik weibo: Weibo current_session: Trenutna seja description: "%{browser} na %{platform}" @@ -1510,9 +1605,10 @@ sl: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: neznana platforma + unknown_platform: Neznana platforma windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1595,7 +1691,6 @@ sl: show_newer: Pokaži novejše show_older: Pokaži starejše show_thread: Pokaži nit - sign_in_to_participate: Prijavite se, če želite sodelovati v pogovoru title: "%{name}: »%{quote}«" visibilities: direct: Neposredno @@ -1637,12 +1732,10 @@ sl: '7889238': 3 mesece min_age_label: Starostna meja min_favs: Obrži objave priljubljene vsaj - min_favs_hint: Ne izbriše nobene od vaših objav, ki je prejela vsaj takšno količino priljubljenih. Pustite prazno, če želite izbrisati objave ne glede na število všečkov + min_favs_hint: Ne izbriše nobene od vaših objav, ki je prejela vsaj takšno število priljubljenih. Pustite prazno, če želite izbrisati objave ne glede na število všečkov min_reblogs: Obdrži objave izpostavljene vsaj min_reblogs_hint: Ne izbriše nobene od vaših objav, ki je bila vsaj tolikokrat podprta. Pustite prazno, če želite izbrisati objave ne glede na število izpostavitev stream_entries: - pinned: Pripeta objava - reblogged: izpostavljeno sensitive_content: Občutljiva vsebina strikes: errors: @@ -1658,6 +1751,7 @@ sl: default: "%b %d %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d. %b. %Y %H:%M %Z" two_factor_authentication: add: Dodaj disable: Onemogoči @@ -1737,13 +1831,16 @@ sl: title: Dobrodošli, %{name}! users: follow_limit_reached: Ne morete spremljati več kot %{limit} ljudi + go_to_sso_account_settings: Pojdite na nastavitve svojega računa ponudnika identitete invalid_otp_token: Neveljavna dvofaktorska koda otp_lost_help_html: Če ste izgubili dostop do obeh, stopite v stik z %{email} seamless_external_login: Prijavljeni ste prek zunanje storitve, tako da nastavitve gesla in e-pošte niso na voljo. signed_in_as: 'Vpisani kot:' verification: - explanation_html: 'V metapodatkih svojega profila se lahko potrdite kot lastnik povezav. Za to mora povezano spletno mesto vsebovati povezavo do vašega Mastodon profila. Povezava mora imeti atribut el="me". Vsebina besedila povezave ni pomembna. Tukaj je primer:' + here_is_how: Kako to poteka + instructions_html: Spodnjo kodo kopirajte in prilepite v HTML svojega spletnega mesta. Nato dodajte naslov svoje spletne strani v eno od dodatnih polj v svojem profilu v zavihku »Uredi profil« in shranite spremembe. verification: Potrditev + verified_links: Vaše preverjene povezave webauthn_credentials: add: Dodaj nov varnostni ključ create: diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 961a14d47e..6cdfa268db 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -91,6 +91,7 @@ sq: moderation: active: Aktiv all: Krejt + disabled: I çaktivizuar pending: Pezull silenced: I kufizuar suspended: Të pezulluara @@ -124,8 +125,8 @@ sq: removed_header_msg: U hoq me sukses figura e kryes për %{username} resend_confirmation: already_confirmed: Ky përdorues është i ripohuar tashmë - send: Ridërgo email ripohimi - success: Email-i i ripohimit u dërgua me sukses! + send: Ridërgo lidhje ripohimi + success: Lidhja e ripohimit u dërgua me sukses! reset: Riktheje te parazgjedhjet reset_password: Ricaktoni fjalëkalimin resubscribe: Ripajtohuni @@ -133,6 +134,7 @@ sq: search: Kërkoni search_same_email_domain: Të tjerë përdorues me të njëjtën përkatësi email-i search_same_ip: Të tjerë përdorues me të njëjtën IP + security: Siguri security_measures: only_password: Vetëm fjalëkalim password_and_2fa: Fjalëkalim dhe 2FA @@ -307,6 +309,7 @@ sq: unpublish: Hiqi publikimin unpublished_msg: Lajmërimi u botua me sukses! updated_msg: Lajmërimi u përditësua me sukses! + critical_update_pending: Përditësim kritik pezull custom_emojis: assign_category: Caktojini kategori by_domain: Përkatësi @@ -380,6 +383,15 @@ sq: undo: Hiqe nga listë lejimesh domain_blocks: add_new: Shtoni bllokim të ri përkatësie + confirm_suspension: + cancel: Anuloje + confirm: Pezulloje + permanent_action: Prapakthimi i pezullimit s’do të rikthejë ndonjë të dhënë apo marrëdhënie. + preamble_html: Ju ndan një hap nga pezullim i %{domain} dhe përkatësive të saj. + remove_all_data: Kjo do të sjellë heqjen nga shërbyesii juaj të krejt lëndës, medias dhe të dhënave të profilit për llogaritë e kësaj përkatësie. + stop_communication: Shërbyesi juaj do të reshtë së komunikuar me këta shërbyes. + title: Ripohoni bllokim përkatësie për %{domain} + undo_relationships: Kjo do të zhbëjë farëdo marrëdhënie ndjekjeje mes llogarive të këtyre shërbyesve dhe tuajit. created_msg: Bllokimi i përkatësisë tani po përpunohet destroyed_msg: Bllokimi i përkatësisë u hoq domain: Përkatësi @@ -427,6 +439,7 @@ sq: resolve: Ftilloje përkatësinë title: Zë i ri email në listë bllokimesh no_email_domain_block_selected: S’u ndryshuan blloqe përkatësish email, ngaqë s’qe përzgjedhur ndonjë + not_permitted: Jo i lejuar resolved_dns_records_hint_html: Emri i përkatësisë jep u përket përkatësive vijuese MX, që janë përgjegjëset për pranim email-esh. Bllokimi i një përkatësie MX do të bllokojë regjistrime nga çfarëdo adrese email që përdor të njëjtën përkatësi MX, edhe nëse emri i dukshëm i përkatësisë është i ndryshëm. Jini i kujdesshëm të mos bllokoni shërbime të njohur email-esh. resolved_through_html: Zgjidhur përmes %{domain} title: Listë bllokimesh email-esh @@ -472,6 +485,7 @@ sq: content_policies: comment: Shënim i brendshëm description_html: Mund të përkufizoni rregulla lënde që do të zbatohen mbi krejt llogaritë prej kësaj përkatësie dhe cilësdo nënpërkatësi të saj. + limited_federation_mode_description_html: Mund të zgjidhni të lejohet ose jo federimi me këtë përkatësi. policies: reject_media: Mos prano media reject_reports: Hidh tej raportimet @@ -584,11 +598,13 @@ sq: assign_to_self: Caktojani vetes assigned: Iu caktua moderator by_target_domain: Përkatësi e llogarisë së raportuar + cancel: Anuloje category: Kategori category_description_html: Arsyeja pse kjo llogari dhe/ose lëndë raportohet do të citohet te komunikimi me llogarinë e raportuar comment: none: Asnjë comment_description_html: 'Për të dhënë më tepër informacion, %{name} shkroi:' + confirm: Ripohojeni confirm_action: Ripohoni veprim moderimi kundër @%{acct} created_at: Raportuar më delete_and_resolve: Fshiji postimet @@ -722,6 +738,9 @@ sq: branding: preamble: Elementët e markës të shërbyesit tuaj e dallojnë atë nga shërbyes të tjerë në rrjet. Këto hollësi mund të shfaqen në një larmi mjedisesh, bie fjala, në ndërfaqen web të Mastodon-it, aplikacione për platforma të ndryshme, në paraparje lidhjesh në sajte të tjerë dhe brenda aplikacionesh për shkëmbim mesazhesh, e me radhë. Për këtë arsyes, më e mira është që këto hollësi të jenë të qarta, të shkurtra dhe të kursyera. title: Elementë marke + captcha_enabled: + desc_html: Kjo bazohet në programthe të jashtëm prej hCaptcha, çka mund të përbëjë një shqetësim për sigurinë dhe privatësinë. Veç kësaj, kjo mund ta bëjë procesin e regjistrimit në shkallë të madhe më pak të përdorshëm për disa persona (veçanërisht ata me paaftësi). Për këto arsye, ju lutemi, shihni mundësinë e masave alternative, fjala vjen, bazuar në miratim, ose regjistrim vetëm me ftesa. + title: Kërko prej përdoruesve të rinj të zgjidhin një CAPTCHA, si ripohim të llogarisë të tyre content_retention: preamble: Kontrolloni se si depozitohen në Mastodon lënda e prodhuar nga përdoruesit. title: Mbajtje lënde @@ -749,10 +768,27 @@ sq: approved: Për regjistrim, lypset miratimi none: S’mund të regjistrohet ndokush open: Mund të regjistrohet gjithkush - title: Rregullime Shërbyesi + security: + authorized_fetch: Kërko doemos mirëfilltësim prej shërbyes të federuar + authorized_fetch_hint: Kërkimi doemos i kryerjes së mirëfilltësimit për shërbyes të federuar aktivizon detyrim më strikt të bllokimeve si në shkallë përdoruesi, ashtu edhe në shkallë shërbyesi. Por kjo vjen me koston e një keqësimi të funksionimit, redukton përhapjen e përgjigjeve tuaja dhe mund të sjellë probleme përputhshmërie me disa shërbime të federuara. Veç kësaj, kjo s’do t’ua pengojë, aktorëve vënë kësaj, të sjellin postimet dhe llogaritë tuaja publike. + authorized_fetch_overridden_hint: Aktualisht s’jeni në gjendje të ndryshoni këtë rregullim, ngaqë anashkalohet nga një ndryshore mjedisi. + federation_authentication: Detyrim mirëfilltësimi të federuarish + title: Rregullime shërbyesi site_uploads: delete: Fshi kartelën e ngarkuar destroyed_msg: Ngarkimi në sajt u fshi me sukses! + software_updates: + critical_update: Kritik — ju lutemi, përditësojeni pa humbur kohë + description: Rekomandohet ta mbani të përditësuar instalimin tuaj të Mastodon-it, që të përfitoni nga ndreqjet dhe veçoritë më të reja. Për më tej, ndonjëherë është kritike të përditësohet Mastodon-i në kohën e duhur, për të shmangur probleme sigurie. Për këto arsye, Mastodon-i kontrollon për përditësime çdo 30 minuta dhe do t’ju njoftojë, sipas parapëlqimeve tuaja për njoftime me email. + documentation_link: Mësoni më tepër + release_notes: Shënime hedhjeje në qarkullim + title: Përditësime të gatshme + type: Lloj + types: + major: Hedhje e rëndësishme në qarkullim + minor: Hedhje e vockël në qarkullim + patch: Hedhje në qarkullim arnimesh — ndreqje të meash dhe ndryshime të lehta për t’u aplikuar + version: Version statuses: account: Autor application: Aplikacion @@ -789,9 +825,24 @@ sq: suspend: "%{name} e pezulloi llogarinë e %{target}" appeal_approved: Apeluar appeal_pending: Apelim pezull + appeal_rejected: Apelimi u hodh poshtë system_checks: database_schema_check: message_html: Ka migrime bazash të dhënash pezull. Ju lutemi, kryejini, për të qenë të sigurt se aplikacioni sillet siç priteet + elasticsearch_health_red: + message_html: Grupi juaj i instancave Elasticsearch s’është i shëndetshëm (gjendje e verdhë), s’mund të përdoren veçoritë e kërkimit + elasticsearch_health_yellow: + message_html: Grupi juaj i instancave Elasticsearch s’është i shëndetshëm (gjendje e verdhë), mund të doni të hetoni shkakun + elasticsearch_index_mismatch: + message_html: Përshoqërimet e treguesit të Elasticsearch-it janë të vjetruara. Ju lutemi, xhironi tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Shihni documentimin + message_html: Grupi i instancave tuaja Elasticsearch ka më shumë se një nyjë, por Mastodon-i s’është formësuar t’i përdorë ato. + elasticsearch_preset_single_node: + action: Shihni documentimin + message_html: Grupi i instancave tuaja Elasticsearch ka vetëm një nyjë, ES_PRESET i duhet dhënë vlera single_node_cluster. + elasticsearch_reset_chewy: + message_html: Treguesi juaj i sistemit Elasticsearch është i vjetruar, për shkak të një ndryshimi rregullimesh. Për ta përditësuar, ju lutemi, xhironi tootctl search deploy --reset-chewy. elasticsearch_running_check: message_html: S’u lidh dot me Elasticsearch. Ju lutemi, kontrolloni nëse ky xhiron, ose çaktivizoni kërkimin në tërë tekstin elasticsearch_version_check: @@ -802,6 +853,18 @@ sq: message_html: S’keni përcaktuar ndonjë rregull shërbyesi. sidekiq_process_check: message_html: S’ka proces Sidekiq në punë për %{value} radhë. Ju lutemi, shqyrtoni formësimin tuaj për Sidekiq-un + software_version_critical_check: + action: Shihni përditësimet e gatshme + message_html: Ka të gatshëm një përditësim kritik të Mastodon-it, ju lutemi, përditësojeni sa më shpejt të jetë e mundur. + software_version_patch_check: + action: Shihni përditësimet e gatshme + message_html: Ka të gatshëm një përditësim ndreqjeje të metash Mastodon-i. + upload_check_privacy_error: + action: Për më tepër hollësi, shihni këtu + message_html: "Shërbyesi juaj është formësuar keq. Privatësia e përdoruesve tuaj është në rrezik." + upload_check_privacy_error_object_storage: + action: Për më tepër hollësi, shihni këtu + message_html: "Depozita juaj e objekteve është e formësuar keq. Privatësia e përdoruesve tuaj është në rrezik." tags: review: Gjendje rishikimi updated_msg: Rregullimet për hashtag-ët u përditësuan me sukses @@ -907,6 +970,9 @@ sq: body: "%{target} po apelon një vendim moderimi nga %{action_taken_by} të marrë më %{date}, që qe %{type}. Shkruan:" next_steps: Apelimin mund të miratoni, që të zhbëhet vendimi i marrë, ose ta shpërfillni. subject: "%{username} po apelon një vendim moderimi te %{instance}" + new_critical_software_updates: + body: Janë hedhur në qarkullim versione të rinj të Mastodon-it, mund të donit ta përditësonit sa më shpejt të jetë e mundur! + subject: Për %{instance} ka përditësime kritike Mastodon-i! new_pending_account: body: Hollësitë e llogarisë së re gjenden më poshtë. Mund ta miratoni ose hidhni poshtë këtë aplikim. subject: Llogari e re për shqyrtim në %{instance} (%{username}) @@ -914,6 +980,9 @@ sq: body: "%{reporter} ka raportuar %{target}" body_remote: Dikush nga %{domain} ka raportuar %{target} subject: Raportim i ri për %{instance} (#%{id}) + new_software_updates: + body: Janë hedhur në qarkullim versione të rinj Mastodon-i, mund të donit ta përditësoni! + subject: Për %{instance} ka të gatshëm versione të rinj Mastodon-i! new_trends: body: 'Gjërat vijuese lypin një shqyrtim, përpara se të mund të shfaqen publikisht:' new_trending_links: @@ -942,24 +1011,28 @@ sq: guide_link: https://crowdin.com/project/mastodon guide_link_text: Çdokush mund të kontribuojë. sensitive_content: Lëndë rezervat - toot_layout: Skemë mesazhesh application_mailer: notification_preferences: Ndryshoni parapëlqime email-i salutation: "%{name}," settings: 'Ndryshoni parapëlqime email-i: %{link}' + unsubscribe: Shpajtohuni view: 'Parje:' view_profile: Shihni profilin view_status: Shihini gjendjen applications: created: Aplikimi u krijua me sukses destroyed: Aplikimi u fshi me sukses + logout: Dalje regenerate_token: Riprodho token hyrjesh token_regenerated: Token-i i hyrjeve u riprodhua me sukses warning: Bëni shumë kujdes me ato të dhëna. Mos ia jepni kurrë njeriu! your_token: Token-i juaj për hyrje auth: apply_for_account: Kërkoni një llogari - change_password: Fjalëkalim + captcha_confirmation: + help_html: Nëse keni probleme me zgjidhjen e CAPTCHA-s, mund të lidheni me ne përmes %{email} dhe mund t’ju ndihmojmë. + hint_html: Edhe një gjë tjetër! Na duhet të ripohoni se jeni qenie njerëzore (që të mbajmë larg mesazhe të padëshiruar!). Zgjidhni CAPTCHA-n më poshtë dhe klikoni mbi “Vazhdo”. + title: Kontroll sigurie confirmations: wrong_email_hint: Nëse ajo adresë email s’është e saktë, mund ta ndryshoni te rregullimet e llogarisë. delete_account: Fshije llogarinë @@ -968,7 +1041,7 @@ sq: prefix_invited_by_user: "@%{name} ju fton të bëheni pjesë e këtij shërbyesi Mastodon!" prefix_sign_up: Regjistrohuni në Mastodon që sot! suffix: Me një llogari, do të jeni në gjendje të ndiqni persona, përditësime postimesh dhe të shkëmbeni mesazhe me përdorues nga cilido shërbyes Mastodon, etj! - didnt_get_confirmation: S’morët udhëzime ripohimi? + didnt_get_confirmation: S’morët një lidhje ripohimi? dont_have_your_security_key: S’i keni kyçet tuaj të sigurisë? forgot_password: Harruat fjalëkalimin tuaj? invalid_reset_password_token: Token-i i ricaktimit të fjalëkalimit është i pavlefshëm ose ka skaduar. Ju lutemi, kërkoni një të ri. @@ -981,26 +1054,39 @@ sq: migrate_account_html: Nëse doni ta ridrejtoni këtë llogari te një tjetër, këtë mund ta formësoni këtu. or_log_in_with: Ose bëni hyrjen me privacy_policy_agreement_html: I kam lexuar dhe pajtohem me rregullat e privatësisë + progress: + confirm: Email ripohimi + details: Hollësitë tuaja + review: Shqyrtimi ynë + rules: Pranoni rregulla providers: cas: CAS saml: SAML register: Regjistrohuni registration_closed: "%{instance} s’pranon anëtarë të rinj" - resend_confirmation: Ridërgo udhëzime ripohimi + resend_confirmation: Ridërgo lidhje ripohimi reset_password: Ricaktoni fjalëkalimin rules: + accept: Pranoje + back: Mbrapsht + invited_by: 'Mund të bëheni pjesë e %{domain} falë ftesës që morët prej:' preamble: Këto vendosen dhe zbatimi i tyre është nën kujdesin e moderatorëve të %{domain}. + preamble_invited: Para se të vazhdoni më tej, ju lutemi, shihni rregullat bazë të vendosura nga moderatorët e %{domain}. title: Disa rregulla bazë. + title_invited: Jeni ftuar. security: Siguri set_new_password: Caktoni fjalëkalim të ri setup: - email_below_hint_html: Nëse adresa email më poshtë s’është e saktë, mund ta ndryshoni këtu dhe të merrni një email të ri ripohimi. - email_settings_hint_html: Email-i i ripohimit u dërgua te %{email}. Nëse ajo adresë email s’është e saktë, mund ta ndryshoni që nga rregullimet e llogarisë. - title: Ujdisje + email_below_hint_html: Shihni te dosja juaj e të padëshiruara, ose kërkoni një tjetër. Mund të ndreqni adresën tuaj email, nëse është e gabuar. + email_settings_hint_html: Që të verifikoni %{email}, klikoni lidhjen që ju dërguam. Do të presim këtu. + link_not_received: S’morët lidhje? + new_confirmation_instructions_sent: Pas pak minutash do të merrni një email të ri me lidhjen e ripohimit! + title: Shihni te email-et tuaj sign_in: preamble_html: Hyni me kredencialet tuaja për te %{domain}. Nëse llogaria juaj strehohet në një tjetër shërbyes, s’do të jeni në gjendje të bëni hyrjen këtu. title: Bëni hyrjen te %{domain} sign_up: + manual_review: Regjistrimet te %{domain} kalojnë një shqyrtim dorazi nga moderatorët tanë. Që të na ndihmoni të përfundojmë regjistrimin tuaj, na shkruani pakëz mbi veten dhe pse doni një llogari në %{domain}. preamble: Me një llogari në këtë shërbyes Mastodon, do të jeni në gjendje të ndiqni cilindo person tjetër në rrjet, pavarësisht se ku strehohet llogaria e tyre. title: Le të ujdisim llogarinë tuaj në %{domain}. status: @@ -1012,18 +1098,6 @@ sq: view_strikes: Shihni paralajmërime të dikurshme kundër llogarisë tuaj too_fast: Formulari u parashtrua shumë shpejt, riprovoni. use_security_key: Përdor kyç sigurie - authorize_follow: - already_following: E ndiqni tashmë këtë llogari - already_requested: Keni dërguar tashmë një kërkesë ndjekjeje te ajo llogari - error: Mjerisht, pati një gabim gjatë kërkimit të llogarisë së largët - follow: Ndiqeni - follow_request: 'Keni dërguar një kërkesë ndjekjeje te:' - following: 'Sukses! Tani e ndiqni:' - post_follow: - close: Ose, thjesht mund të mbyllni këtë dritare. - return: Shfaq profilin e përdoruesit - web: Kalo në web - title: Ndiq %{acct} challenge: confirm: Vazhdo hint_html: "Ndihmëz: S’do t’ju pyesim për fjalëkalimin tuaj sërish, për një orë." @@ -1100,6 +1174,10 @@ sq: your_appeal_rejected: Apelimi juaj është hedhur poshtë domain_validator: invalid_domain: s’është emër i vlefshëm përkatësie + edit_profile: + basic_information: Hollësi elementare + hint_html: "Përshtatni ç’shohin njerëzit në profilin tuaj publik dhe në krah të postimeve tuaja. Personat e tjerë ka më shumë gjasa t’ju ndjekin dhe ndërveprojnë me ju, kur keni të plotësuar profilin dhe një foto profili." + other: Tjetër errors: '400': Kërkesa që parashtruar qe e pavlefshme ose e keqformuar. '403': S’keni leje të shihni këtë faqe. @@ -1136,7 +1214,7 @@ sq: featured_tags: add_new: Shtoni të re errors: - limit: Keni përdorur tashmë si të zgjedhur sasinë maksimum të hashtag-ëve + limit: Keni përdorur tashmë numrin maksimum të hashtag-ëve hint_html: "Çfarë janë hashtag-ët e zgjedhur? Këta shfaqen dukshëm te profili juaj publik dhe u lejojnë të tjerëve të shfletojnë postime tuajt publikë posaçërisht nën këta hashtag-ë. Janë një mjet i goditur për të ndjekur punë krijuese ose projekte afatgjata." filters: contexts: @@ -1180,8 +1258,6 @@ sq: index: hint: Ky filtër aplikohet për të përzgjedhur postime individuale, pavarësisht kriteresh të tjera. Që nga ndërfaqja web mund të shtoni më tepër postime te ky filtër. title: Postime të filtruar - footer: - trending_now: Prirjet e tashme generic: all: Krejt all_items_on_page_selected_html: @@ -1190,7 +1266,9 @@ sq: all_matching_items_selected_html: one: Është përzgjedhur %{count} objekt me përkim me kërkimin tuaj. other: Janë përzgjedhur krejt %{count} objektet me përkim me kërkimin tuaj. + cancel: Anuloje changes_saved_msg: Ndryshimet u ruajtën me sukses! + confirm: Ripohojeni copy: Kopjoje delete: Fshije deselect: Shpërzgjidhi krejt @@ -1204,24 +1282,62 @@ sq: validation_errors: one: Diçka s’është ende si duhet! Ju lutemi, shqyrtoni gabimin më poshtë other: Diçka s’është ende si duhet! Ju lutemi, shqyrtoni %{count} gabimet më poshtë - html_validator: - invalid_markup: 'përmban elementë HTML të pavlefshëm: %{error}' imports: errors: + empty: Kartelë CSV e zbrazët + incompatible_type: E papërputhshme me llojin e përzgjedhur për importim invalid_csv_file: 'Kartelë CSV e pavlefshme. Gabim: %{error}' over_rows_processing_limit: përmban më shumë se %{count} rreshta + too_large: Kartela është shumë e madhe + failures: Dështime + imported: Të importuar + mismatched_types_warning: Duket të keni përzgjedhur llojin e gabuar për këtë importim, ju lutemi, rikontrollojeni. modes: merge: Përzieji merge_long: Mbaji zërat ekzistues dhe shto të rinjtë overwrite: Mbishkruaje overwrite_long: Zëvendësoji zërat ekzistues me të rinjtë + overwrite_preambles: + blocking_html: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimeve me %{total_items} llogari nga %{filename}. + bookmarks_html: Ju ndan një hap nga zëvendësimi i faqerojtësve tuaj me %{total_items} postime nga %{filename}. + domain_blocking_html: Ju ndan një hap nga zëvendësimi i listës tuaj të bllokimit të përkatësive me %{total_items} përkatësi nga %{filename}. + following_html: Ju ndan një hap nga ndjekja e %{total_items} llogarive nga %{filename} dhe reshtja së ndjekuri këdo tjetër. + lists_html: Ju ndan një hap nga zëvendësimi i listave tuaja me lëndë nga %{filename}. Te listat e reja do të shtohen deri në %{total_items} llogari. + muting_html: Ju ndan një hpa nga zëvendësimi i listës suaj të llogarive të heshtuara me %{total_items} llogari nga %{filename}. + preambles: + blocking_html: Ju ndan një hap nga bllokimi i %{total_items} llogarive nga %{filename}. + bookmarks_html: Ju ndan një hap nga shtimi te faqerojtësit tuaj i %{total_items} postimeve nga %{filename}. + domain_blocking_html: Ju ndan një hap nga bllokimi i %{total_items} përkatësive nga %{filename}. + following_html: Ju ndan një hap nga ndjekja e %{total_items} llogarive nga %{filename}. + lists_html: Jui nda një hap nga shtimi te listat tuaja i deri %{total_items} llogarive nga %{filename}. Nëse s’ka listë ku të shtohen, do të krijohen lista të reja. + muting_html: Ju ndan një hap nga heshtimi i %{total_items} llogarive nga %{filename}. preface: Mund të importoni të dhëna që keni eksportuar nga një shërbyes tjetër, bie fjala, një listë të personave që ndiqni ose bllokoni. + recent_imports: Importime së fundi + states: + finished: Të përfunduar + in_progress: Në kryerje e sipër + scheduled: Të planifikuar + unconfirmed: Të paripohuar + status: Gjendje success: Të dhënat tuaja u ngarkuan me sukses dhe tani do të përpunohet në kohë + time_started: Filluar më + titles: + blocking: Po importohen llogari të bllokuara + bookmarks: Po importohen faqerojtës + domain_blocking: Po importohen përkatësi të bllokuara + following: Po importohen llogari të ndjekura + lists: Po importohen lista + muting: Po importohen llogari të heshtuara + type: Lloj importimi + type_groups: + constructive: Ndjekje & Faqerojtës + destructive: Bllokime & heshtime types: blocking: Listë bllokimesh bookmarks: Faqerojtës domain_blocking: Listë bllokimesh përkatësish following: Listë ndjekjesh + lists: Lista muting: Listë heshtimesh upload: Ngarkoje invites: @@ -1248,7 +1364,7 @@ sq: title: Ftoni njerëz lists: errors: - limit: Keni mbërritur në numrin maksimum të sasisë së listave + limit: Keni mbërritur në numrin maksimum të listave login_activities: authentication_methods: otp: aplikacion mirëfilltësimi dyfaktorësh @@ -1260,6 +1376,21 @@ sq: failed_sign_in_html: Dështoi përpjekje hyrjeje me %{method} nga %{ip} (%{browser}) successful_sign_in_html: Hyrje e suksesshme me %{method} nga %{ip} (%{browser}) title: Historik mirëfilltësimesh + mail_subscriptions: + unsubscribe: + action: Po, shpajtomëni + complete: U shpajtuat + confirmation_html: Jeni i sigurt se doni të shpajtoheni prej marrjes së %{type} për Mastodon në %{domain} te email-i juaj në %{email}? Mundeni përherë të ripajtoheni, që prej rregullimeve tuaja për njoftime me email. + emails: + notification_emails: + favourite: email-e njoftimesh për të parapëlqyer + follow: email-e njoftimi ndjekjesh + follow_request: email-e kërkesash për ndjekje + mention: email-e njoftimi përmendjesh + reblog: email-e njoftimi përforcimesh + resubscribe_html: Nëse u shpajtuat gabimisht, mund të ripajtoheni që nga rregullimet tuaja për njoftime me email. + success_html: S’do të merrni më %{type} për Mastodon në %{domain} te email juaj %{email}. + title: Shpajtohuni media_attachments: validations: images_and_video: S’mund të bashkëngjitet video te një gjendje që përmban figura tashmë @@ -1339,6 +1470,7 @@ sq: update: subject: "%{name} përpunoi një postim" notifications: + administration_emails: Njoftime email për përgjegjësin email_events: Akte për njoftim me email email_events_hint: 'Përzgjidhni akte për të cilët doni të merrni njoftime:' other_settings: Rregullimet të tjera njoftimesh @@ -1375,12 +1507,22 @@ sq: expired: Pyetësori ka përfunduar tashmë invalid_choice: Mundësia e zgjedhur për votën nuk ekziston over_character_limit: s’mund të jetë më i gjatë se %{max} shenja secili + self_vote: S’mund të votoni në pyetësorët tuaj too_few_options: duhet të ketë më tepër se një element too_many_options: s’mund të përmbajë më tepër se %{max} elementë preferences: other: Tjetër posting_defaults: Parazgjedhje postimesh public_timelines: Rrjedha kohore publike + privacy: + hint_html: "Përshtatni mënyrën se si dëshironi të gjenden prej të tjerëve profili dhe postimet tuaja. Një larmi veçorish të Mastodon-it mund t’ju ndihmojnë të shtriheni në një publik më të gjerë, kur aktivizohen. Ndaluni një çast t’i shqyrtoni këto rregullime, për t’u siguruar se i përshtaten rastit tuaj." + privacy: Privatësi + privacy_hint_html: Kontrolloni sa doni të tregoni prej vetes për të mirën e të tjerëve. Njerëzit zbulojnë profile interensante dhe aplikacione të lezetshme duke shfletuar ndjekjet e personave të tjerë dhe duke parë se prej cilëve aplikacione postuan, por mund të parapëlqeni ta mbani të fshehur këtë. + reach: Shtrirje + reach_hint_html: Kontrolloni zbulimin dhe ndjekjen tuaj nga persona të rinj. Doni që postimet tuaja të shfaqen në skenën Exploroni? Doni që persona të tjerë t’ju shohin te rekomandimet për ndjekje prej tyre? Doni të pranohen automatikisht ndjekësit e rinj, apo të keni kontroll të imët mbi secilin rast? + search: Kërkim + search_hint_html: Kontrolloni mënyrën se si do t’ju gjejnë. Doni që njerëzit t’ju gjejnë përmes çka keni postuar botërisht? Doni që njerëz jashtë Mastodon-it ta gjejnë profilin tuaj kur kërkojnë në internet? Ju lutemi, kini parasysh se për informacione publike s’mund të garantohet përjashtimi tërësor nga krejt motorët e kërkimeve. + title: Privatësi dhe shtrirje privacy_policy: title: Rregulla Privatësie reactions: @@ -1393,6 +1535,7 @@ sq: confirm_remove_selected_followers: Jeni i sigurt se doni të hiqen ndjekësit e përzgjedhur? confirm_remove_selected_follows: Jeni i sigurt se doni të hiqen ndjekjet e përzgjedhura? dormant: Në gjumë + follow_failure: S’u ndoqën dot disa nga llogaritë e përzgjedhura. follow_selected_followers: Ndiq ndjekësit e përzgjedhur followers: Ndjekës following: Ndjek @@ -1432,6 +1575,7 @@ sq: electron: Electron firefox: Firefox generic: Shfletues i panjohur + huawei_browser: Shfletues Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: Shfletues Nokia S40 Ovi @@ -1441,6 +1585,7 @@ sq: qq: QQ Browser safari: Safari uc_browser: Shfletues UC + unknown_browser: Shfletues i Panjohur weibo: Weibo current_session: Sesioni i tanishëm description: "%{browser} në %{platform}" @@ -1453,9 +1598,10 @@ sq: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: platformë e panjohur + unknown_platform: Platformë e Panjohur windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1526,7 +1672,6 @@ sq: show_newer: Shfaq më të reja show_older: Shfaq më të vjetra show_thread: Shfaq rrjedhën - sign_in_to_participate: Bëni hyrjen, që të merrni pjesë te biseda title: '%{name}: "%{quote}"' visibilities: direct: I drejtpërdrejtë @@ -1568,12 +1713,10 @@ sq: '7889238': 3 muaj min_age_label: Prag moshe min_favs: Mbaji postimet e parapëlqyera më shumë se - min_favs_hint: Nuk fshihet ndonjë nga postimet tuaja që kanë marrë më shumë se sa ky numër parapëlqimesh. Lëreni të zbrazët për të fshirë postimet, pavarësisht të numrit të parapëlqimeve për to + min_favs_hint: Mos fshini ndonjë nga postimet tuaja që kanë marrë të paktën këtë numër si të parapëlqyer. Lëreni të zbrazët, që të fshihen postime pavarësisht nga numri se sa herë janë të parapëlqyer min_reblogs: Mbaji postimet e përforcuara më shumë se min_reblogs_hint: Nuk fshihet ndonjë nga postimet tuaja që kanë marrë më shumë se sa ky numër përforcimesh. Lëreni të zbrazët për të fshirë postimet, pavarësisht të numrit të përforcimeve për to stream_entries: - pinned: Mesazh i fiksuar - reblogged: të përforcuara sensitive_content: Lëndë rezervat strikes: errors: @@ -1589,6 +1732,11 @@ sq: default: "%d %b, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Është tejkaluar kuota e përdorimit për shërbimin e përkthimit në krejt shërbyesin. + too_many_requests: Tani së fundi ka patur shumë kërkesa ndaj shërbimit të përkthimit. two_factor_authentication: add: Shtoje disable: Çaktivizoje @@ -1668,13 +1816,18 @@ sq: title: Mirë se vini, %{name}! users: follow_limit_reached: S’mund të ndiqni më tepër se %{limit} persona + go_to_sso_account_settings: Kaloni te rregullime llogarie te shërbimi juaj i identitetit invalid_otp_token: Kod dyfaktorësh i pavlefshëm otp_lost_help_html: Nëse humbët hyrjen te të dy, mund të lidheni me %{email} seamless_external_login: Jeni futur përmes një shërbimi të jashtëm, ndaj s’ka rregullime fjalëkalimi dhe email. signed_in_as: 'I futur si:' verification: - explanation_html: 'Mundeni të verifikoni veten si i zoti i lidhjeve te tejtëdhënat e profilit tuaj. Për këtë, sajti i lidhur duhet të përmbajë një lidhje për te profili juaj Mastodon. Lidhje për te ajo duhet të ketë një atribut rel="me". Lënda tekst e lidhjes nuk ngre peshë. Ja një shembull:' + extra_instructions_html: Ndihmëz: Lidhja te sajti juaj mund të jetë e padukshme. Pjesa e rëndësishme është rel="me", e cila pengon të hiqen gjoja në sajte me lëndë të prodhuar nga përdorues. Mundeni edhe të përdorni një etiketë link te kryet e faqes, në vend se a, por HTML-ja duhet të jetë e përdorshme pa ekzekutim JavaScript-i. + here_is_how: Ja se si + hint_html: "Verifikimi i identitetit të secilit në Mastodon është për këdo. Bazuar në standarde web të hapët, falas për so dhe për mot. Krejt ç’ju duhet është një sajt personal me të cilin ju njohin njerëzit. Kur bëni lidhjen me këtë sajt që nga profili juaj, do të kontrollojmë nëse sajti përgjigjet me një lidhje për te profili juaj dhe shfaq një tregues në të." + instructions_html: Kopjoni dhe ngjitni në HTML-në e sajtit tuaj kodin më poshtë. Mandej shtoni adresën e sajtit tuaj te një nga fushat shtesë në profilin tuaj, që nga skeda “Përpunoni profil” dhe ruani ndryshimet. verification: Verifikim + verified_links: Lidhjet tuaja të verifikuara webauthn_credentials: add: Shtoni kyç të ri sigurie create: diff --git a/config/locales/sr-Latn.rb b/config/locales/sr-Latn.rb deleted file mode 100644 index fc2dafc94c..0000000000 --- a/config/locales/sr-Latn.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'rails_i18n/common_pluralizations/romanian' - -::RailsI18n::Pluralization::Romanian.with_locale(:'sr-Latn') diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 1a4a2b7b1e..82fbbff49e 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1,237 +1,1374 @@ --- sr-Latn: about: - about_mastodon_html: Mastodont je društvena mreža bazirana na otvorenim protokolima i slobodnom softveru otvorenog koda. Decentralizovana je kao što je decentralizovana e-pošta. + about_mastodon_html: 'Društvena mreža budućnosti: bez reklama, bez korporativnog praćenja, etički dizajn, i decentralizacija! Posedujte svoje podatke sa Mastodon-om!' contact_missing: Nije postavljeno - hosted_on: Mastodont hostovan na %{domain} + contact_unavailable: Nije dostupno + hosted_on: Mastodon hostovan na %{domain} + title: O instanci accounts: - nothing_here: Ovde nema ništa! + follow: Zaprati + followers: + few: Pratioca + one: Pratilac + other: Pratilaca + following: Pratim + instance_actor_flash: Ovaj nalog je virtuelni akter koji ne predstavlja nijednog korisnika lično, već sâm server. Koristi se u svrhu federacije i ne treba ga suspendovati. + last_active: najskorija aktivnost + link_verified_on: Vlasništvo nad ovom vezom je provereno %{date} + nothing_here: Ovde nema ničega! + pin_errors: + following: Morate pratiti osobu koju želite da preporučite + posts: + few: Objave + one: Objava + other: Objava + posts_tab_heading: Objave admin: + account_actions: + action: Izvršite radnju + title: Izvršite moderatorske radnje na %{acct} account_moderation_notes: - create: Napravi + create: Ostavite belešku created_msg: Moderatorska beleška uspešno napravljena! destroyed_msg: Moderatorska beleška uspešno obrisana! accounts: + add_email_domain_block: Blokiraj domen e-pošte + approve: Odobri + approved_msg: Zahtev za registraciju korisnika %{username} je uspešno odobren are_you_sure: Da li ste sigurni? + avatar: Avatar by_domain: Domen + change_email: + changed_msg: E-pošta naloga uspešno promenjena! + current_email: Trenutna adresa e-pošte + label: Promenite adresu e-pošte + new_email: Nova adresa e-pošte + submit: Promenite adresu e-pošte + title: Promenite adresu e-pošte za %{username} + change_role: + changed_msg: Uloga uspešno promenjena! + label: Promeni ulogu + no_role: Nema ulogu + title: Promeni ulogu za %{username} confirm: Potvrdi confirmed: Potvrđeno - confirming: Potvrđujući + confirming: Potvrđivanje + custom: Proizvoljno + delete: Obriši podatke + deleted: Izbrisano demote: Ražaluj - disable: Isključi + destroyed_msg: Podaci korisnika %{username} su nepovratno stavljeni u red za brisanje + disable: Zamrzni + disable_sign_in_token_auth: Onemogući imejl autentifikaciju disable_two_factor_authentication: Isključi 2FA - disabled: Isključena - display_name: Prikazano ime + disabled: Zamrznut + display_name: Ime za prikaz domain: Domen edit: Izmeni email: E-pošta email_status: Status e-pošte - enable: Uključi - enabled: Uključeno + enable: Omogući + enable_sign_in_token_auth: Omogući imejl autentifikaciju + enabled: Omogućen + enabled_msg: Uspešno odleđen nalog korisnika %{username} followers: Pratioci follows: Praćeni + header: Zaglavlje inbox_url: Adresa sandučeta + invite_request_text: Razlozi za pridruživanje + invited_by: Pozvan od strane + ip: IP + joined: Pridružio/-la se location: all: Sve - local: Lokalne - remote: Udaljene + local: Lokalni + remote: Udaljeni title: Lokacija login_status: Status prijave media_attachments: Multimedijalni prilozi memorialize: Prebaci u in memoriam + memorialized: Podignut spomenik + memorialized_msg: "%{username} je uspešno pretvoren u memorijalni nalog" moderation: + active: Aktivan all: Svi + disabled: Isključen + pending: Na čekanju + silenced: Ograničeno suspended: Suspendovani title: Moderacija moderation_notes: Moderatorske beleške most_recent_activity: Najskorija aktivnost most_recent_ip: Najskorija IP adresa + no_account_selected: Nijedan nalog nije promenjen jer nijedan nije izabran + no_limits_imposed: Nema ograničenja + no_role_assigned: Nijedna uloga nije dodeljena not_subscribed: Nije pretplaćen - perform_full_suspension: Izvrši kompletno isključenje + pending: Čeka na pregled + perform_full_suspension: Suspenduj + previous_strikes: Prethodni prekršaji + previous_strikes_description_html: + few: Ovaj nalog ima %{count} prekršaja. + one: Ovaj nalog ima jedan prekršaj. + other: Ovaj nalog ima %{count} prekršaja. promote: Unapredi protocol: Protokol public: Javno - redownload: Osveži avatar - remote_suspension_reversible_hint_html: Налог је суспендован на њиховом серверу, а подаци ће бити у потпуности уклоњени %{date}. До тада, удаљени сервер може вратити овај налог без икаквих негативних ефеката. Ако желите одмах да уклоните све податке налога, то можете учинити у наставку. + push_subscription_expires: PuSH pretplata ističe + redownload: Osveži profil + redownloaded_msg: Uspešno osvežen profil korisnika %{username} iz izvora + reject: Odbij + rejected_msg: Zahtev za registraciju korisnika %{username} je uspešno odbijen + remote_suspension_irreversible: Podaci ovog naloga su nepovratno izbrisani. + remote_suspension_reversible_hint_html: Nalog je suspendovan sa svog servera i njegovi podaci će biti izbrisani datuma %{date}. Do tada, udaljeni server može da vrati ovaj nalog bez ikakvih promena. Ukoliko želite da odmah obrišete sve podatke naloga, možete to učiniti ispod. + remove_avatar: Ukloni avatar + remove_header: Odstrani zaglavlje + removed_avatar_msg: Slika avatara korisnika %{username} je uspešno uklonjena + removed_header_msg: Uspešno obrisana slika zaglavlja korisnika %{username} resend_confirmation: already_confirmed: Ovaj korisnik je već potvrđen - send: Ponovo pošaljite e-poruku za potvrdu - success: E-mail potvrde je uspešno poslat! + send: Ponovo pošalji vezu za potvrdu + success: Veza za potvrdu je uspešno poslata! reset: Resetuj reset_password: Resetuj lozinku resubscribe: Ponovo se pretplati + role: Uloga search: Pretraga + search_same_email_domain: Ostali korisnici sa istim domenom e-pošte + search_same_ip: Ostali korisnici sa istom IP adresom + security: Bezbednost + security_measures: + only_password: Samo lozinka + password_and_2fa: Lozinka i dvofaktorska autentifikacija + sensitive: Označi kao osetljiv + sensitized: Označeno kao osetljivo shared_inbox_url: Adresa deljenog sandučeta show: - created_reports: Prijave koje je napravio ovaj nalog - targeted_reports: Prijave napravljene o ovom nalogu + created_reports: Podnete prijave + targeted_reports: Prijave od strane drugih silence: Ućutkaj - statuses: Statusi + silenced: Ućutkan + statuses: Objave + strikes: Prethodni prestupi subscribe: Pretplati se + suspend: Suspenduj + suspended: Suspendovani + suspension_irreversible: Podaci ovog naloga su nepovratno izbrisani. Možete odsuspendovati ovaj nalog čime će on postati upotrebljiv, ali se podaci prethodno sadržani na nalogu neće vratiti. + suspension_reversible_hint_html: Nalog je suspendovan i njegovi podaci će biti izbrisani datuma %{date}. Do tada, ovaj nalog može biti vraćen bez ikakvih promena. Ukoliko želite da odmah obrišete sve podatke naloga, možete to učiniti ispod. title: Nalozi + unblock_email: Odblokiraj adresu e-pošte + unblocked_email_msg: Uspešno odblokirana imejl adresa korisnika %{username} + unconfirmed_email: Nepotvrđena adresa e-pošte + undo_sensitized: Ukloni oznaku „osetljiv” undo_silenced: Ukini ćutanje undo_suspension: Ukini suspenziju + unsilenced_msg: Uspešno poništeno ograničenje naloga %{username} unsubscribe: Ukini pretplatu + unsuspended_msg: Uspešno poništena suspenzija naloga %{username} username: Korisničko ime + view_domain: Pročitaj opis domena + warn: Upozori web: Veb + whitelisted: Dozvoljena federacija action_logs: + action_types: + approve_appeal: Uvaži žalbu + approve_user: Odobri korisnika + assigned_to_self_report: Dodeli prijavu + change_email_user: Promeni e-adresu korisnika + change_role_user: Promeni ulogu korisnika + confirm_user: Potvrdi korisnika + create_account_warning: Kreiraj upozorenje + create_announcement: Kreiraj najavu + create_canonical_email_block: Kreiraj blok e-pošte + create_custom_emoji: Napravi prilagođeni emodži + create_domain_allow: Dodaj dozvoljeni domen + create_domain_block: Dodaj blokirani domen + create_email_domain_block: Blokiraj imejl domen + create_ip_block: Napravi IP uslov + create_unavailable_domain: Dodaj domen kao nedostupan + create_user_role: Kreiraj ulogu + demote_user: Smanji ovlašćenja korisnika + destroy_announcement: Izbriši najavu + destroy_canonical_email_block: Izbriši blok e-pošte + destroy_custom_emoji: Obriši prilagođeni emodži + destroy_domain_allow: Obriši dozvoljeni domen + destroy_domain_block: Obriši blokirani domen + destroy_email_domain_block: Izbriši blok e-pošte + destroy_instance: Očisti domen + destroy_ip_block: Obriši IP uslov + destroy_status: Izbriši post + destroy_unavailable_domain: Obriši nedostupan domen + destroy_user_role: Uništi poziciju + disable_2fa_user: Onemogući dvofaktorsku autentifikaciju + disable_custom_emoji: Onemogući prilagođene emodžije + disable_sign_in_token_auth_user: Onemogući imejl autentifikaciju za korisnika + disable_user: Onemogući korisnika + enable_custom_emoji: Omogući prilagođene emodžije + enable_sign_in_token_auth_user: Omogući imejl autentifikaciju za korisnika + enable_user: Omogući korisnika + memorialize_account: Pretvori u memorijalni nalog + promote_user: Unapredi korisnika + reject_appeal: Odbij žalbu + reject_user: Odbaci korisnika + remove_avatar_user: Ukloni avatar + reopen_report: Ponovo otvori prijavu + resend_user: Ponovo pošalji mejl za potvrdu + reset_password_user: Resetuj lozinku + resolve_report: Zatvori prijavu + sensitive_account: Označi nalog kao osetljiv + silence_account: Ograniči nalog + suspend_account: Obustavi nalog + unassigned_report: Povuci prijavu + unblock_email_account: Odblokiraj imejl adresu + unsensitive_account: Ukloni dodeljenu oznaku „osetljiv” + unsilence_account: Povuci ograničenje naloga + unsuspend_account: Povuci suspenziju naloga + update_announcement: Saopštenje o ažuriranju + update_custom_emoji: Ažuriraj prilagođene emodžije + update_domain_block: Ažuriraj domen blok + update_ip_block: Ažuriraj IP uslov + update_status: Uredi objavu + update_user_role: Uredi ulogu + actions: + approve_appeal_html: "%{name} je uvažio žalbu korisnika %{target} na odluku moderatora" + approve_user_html: "%{name} je odobrio/-la registraciju korisnika %{target}" + assigned_to_self_report_html: "%{name} je sebi dodelio/-la prijavu %{target}" + change_email_user_html: "%{name} je promenio/-la imejl adresu korisnika %{target}" + change_role_user_html: "%{name} je promenio/-la ovlašćenja korisnika %{target}" + confirm_user_html: "%{name} je potvrdio/-la imejl adresu korisnika %{target}" + create_account_warning_html: "%{name} je poslao/-la upozorenje korisniku %{target}" + create_announcement_html: "%{name} je napravio/-la novo saopštenje %{target}" + create_canonical_email_block_html: "%{name} je blokirao/-la imejl adresu sa hešom %{target}" + create_custom_emoji_html: "%{name} je otpremio/-la nove emodžije %{target}" + create_domain_allow_html: "%{name} je dozvolio/-la federaciju sa domenom %{target}" + create_domain_block_html: "%{name} je blokirao/-la domen %{target}" + create_email_domain_block_html: "%{name} je blokirao/-la imejl domen %{target}" + create_ip_block_html: "%{name} je napravio/-la uslov za IP adrese %{target}" + create_unavailable_domain_html: "%{name} je obustavio/-la isporučivanje domenu %{target}" + create_user_role_html: "%{name} je napravio/-la %{target} poziciju" + demote_user_html: "%{name} je smanjio ovlašćenja korisnika %{target}" + destroy_announcement_html: "%{name} je obrisao/-la saopštenje %{target}" + destroy_canonical_email_block_html: "%{name} je odblokirao/-la imejl adresu sa hešom %{target}" + destroy_custom_emoji_html: "%{name} je obrisao/-la emodži %{target}" + destroy_domain_allow_html: "%{name} je zabranio/-la federaciju sa domenom %{target}" + destroy_domain_block_html: "%{name} je odblokirao/-la domen %{target}" + destroy_email_domain_block_html: "%{name} je odblokirao/-la imejl domen %{target}" + destroy_instance_html: "%{name} je očistio/-la domen %{target}" + destroy_ip_block_html: "%{name} je obrisao/-la uslov za IP adrese %{target}" + destroy_status_html: "%{name} je izbrisao/-la objavu korisnika %{target}" + destroy_unavailable_domain_html: "%{name} je ponovo uspostavio/-la isporučivanje domenu %{target}" + destroy_user_role_html: "%{name} je izbrisao/-la %{target} poziciju" + disable_2fa_user_html: "%{name} je onemogućio/-la dvofaktorsku autentifikaciju za korisnika %{target}" + disable_custom_emoji_html: "%{name} je onemogućio/-la emodži %{target}" + disable_sign_in_token_auth_user_html: "%{name} je onemogućio/-la imejl autentifikaciju za korisnika %{target}" + disable_user_html: "%{name} je onemogućio/-la prijavljivanje za korisnika %{target}" + enable_custom_emoji_html: "%{name} je omogućio/-la emodži %{target}" + enable_sign_in_token_auth_user_html: "%{name} je omogućio/-la imejl autentifikaciju za %{target}" + enable_user_html: "%{name} je omogućio/-la prijavljivanje korisniku %{target}" + memorialize_account_html: "%{name} je pretvorio/-la nalog korisnika %{target} u memorijalnu stranicu" + promote_user_html: "%{name} je unapredio/-la korisnika %{target}" + reject_appeal_html: "%{name} je odbio/-la žalbu na moderacijsku odluku koju je priložio korisnik %{target}" + reject_user_html: "%{name} je odbio/-la registraciju korisnika %{target}" + remove_avatar_user_html: "%{name} je uklonio avatar korisnika %{target}" + reopen_report_html: "%{name} je ponovo otvorio/-la prijavu %{target}" + resend_user_html: "%{name} je ponovo poslao/-la imejl za potvrdu korisniku %{target}" + reset_password_user_html: "%{name} je resetovao/-la lozinku korisnika %{target}" + resolve_report_html: "%{name} je rešio/-la prijavu %{target}" + sensitive_account_html: "%{name} je označio/-la medije naloga %{target} kao osetljive" + silence_account_html: "%{name} je ograničio/-la nalog %{target}" + suspend_account_html: "%{name} je suspendovao/-la nalog %{target}" + unassigned_report_html: "%{name} je povukao/-la dodelu prijave %{target}" + unblock_email_account_html: "%{name} je odblokirao/-la imejl adresu korisnika %{target}" + unsensitive_account_html: "%{name} je uklonio/-la oznaku „osetljivo” sa medija naloga %{target}" + unsilence_account_html: "%{name} je povukao/-la ograničenje naloga %{target}" + unsuspend_account_html: "%{name} je povukao/-la suspenziju naloga %{target}" + update_announcement_html: "%{name} je ažurirao/-la saopštenje %{target}" + update_custom_emoji_html: "%{name} je ažurirao/-la emodži %{target}" + update_domain_block_html: "%{name} je ažurirao/-la blok domena %{target}" + update_ip_block_html: "%{name} je promenio/-la IP uslov za %{target}" + update_status_html: "%{name} je ažurirao/-la objavu korisnika %{target}" + update_user_role_html: "%{name} je promenio/-la poziciju %{target}" + deleted_account: obrisan nalog + empty: Nije pronađen nijedan log. + filter_by_action: Filtriraj po aktivnosti + filter_by_user: Filtriraj po korisniku title: Zapisnik + announcements: + destroyed_msg: Saopštenje je uspešno obrisano! + edit: + title: Uredi najavu + empty: Nijedna najava nije pronađena. + live: Uživo + new: + create: Kreiraj najavu + title: Nova najava + publish: Objavi + published_msg: Najava uspešno objavljena! + scheduled_for: Zakazano za %{time} + scheduled_msg: Saopštenje je zakazano za objavljivanje! + title: Najave + unpublish: Povuci objavu + unpublished_msg: Objava saopštenja je uspešno povučena! + updated_msg: Saopštenje je uspešno ažurirano! + critical_update_pending: Kritično ažuriranje je na čekanju custom_emojis: + assign_category: Dodeli kategoriju by_domain: Domen - copied_msg: Uspešno napravljena lokalna kopija emotikona + copied_msg: Uspešno napravljena lokalna kopija emodžija copy: Kopiraj - copy_failed_msg: Ne mogu da napravim lokalnu kopiju tog emotikona - created_msg: Emotikon uspešno napravljen! + copy_failed_msg: Ne mogu da napravim lokalnu kopiju tog emotidžija + create_new_category: Kreiraj novu kategoriju + created_msg: Emodži uspešno napravljen! delete: Obriši - destroyed_msg: Emotikon uspešno obrisan! + destroyed_msg: Emodži uspešno obrisan! disable: Onemogući - disabled_msg: Emotikon uspešno onemogućen - emoji: Emotikon + disabled: Onemogućeno + disabled_msg: Emodži uspešno onemogućen + emoji: Emodži enable: Omogući - enabled_msg: Emotikon uspešno omogućen + enabled: Omogućeno + enabled_msg: Emodži uspešno omogućen + image_hint: PNG ili GIF fajl veličine do %{size} + list: Lista listed: Izlistan new: - title: Dodaj novi proizvoljni emotikon + title: Dodaj novi proizvoljni emodži + no_emoji_selected: Nijedan emodži nije promenjen jer nijedan nije izabran + not_permitted: Niste ovlašćeni da obavljate ovu radnju overwrite: Prepiši shortcode: Prečica shortcode_hint: Najmanje 2 karaktera, dozvoljeni su samo slova, brojevi i donje crte - title: Proizvoljni emotikoni + title: Proizvoljni emotidžiji + uncategorized: Nekategorizovano + unlist: Neizlistan unlisted: Neizlistan - update_failed_msg: Ne mogu da ažuriram ovaj emotikon - updated_msg: emotikon uspešno ažuriran! + update_failed_msg: Ne mogu da ažuriram ovaj emodži + updated_msg: Emodži uspešno ažuriran! upload: Otpremi + dashboard: + active_users: aktivni korisnici + interactions: interakcije + media_storage: Multimedijalno skladište + new_users: novi korisnici + opened_reports: otvorene prijave + pending_appeals_html: + few: "%{count} žalbe na čekanju" + one: "%{count} žalba na čekanju" + other: "%{count} žalbi na čekanju" + pending_reports_html: + few: "%{count} prijave na čekanju" + one: "%{count} prijava na čekanju" + other: "%{count} prijava na čekanju" + pending_tags_html: + few: "%{count} heš oznake na čekanju" + one: "%{count} heš oznaka na čekanju" + other: "%{count} heš oznaka na čekanju" + pending_users_html: + few: "%{count} korisnika na čekanju" + one: "%{count} korisnik na čekanju" + other: "%{count} korisnika na čekanju" + resolved_reports: rešene prijave + software: Softver + sources: Izvori registracija + space: Korišćenje prostora + title: Komandna tabla + top_languages: Najzastupljeniji jezici + top_servers: Najaktivniji serveri + website: Vebsajt + disputes: + appeals: + empty: Nijedna žalba nije pronađena. + title: Žalbe + domain_allows: + add_new: Dozvoli federaciju sa domenom + created_msg: Domen je uspešno odobren za federaciju + destroyed_msg: Domen je odbijen za federaciju + export: Izvoz + import: Uvoz + undo: Zabrani federaciju sa domenom domain_blocks: - add_new: Dodaj novi + add_new: Dodaj novi blok domena + confirm_suspension: + cancel: Otkaži + confirm: Obustavi + permanent_action: Poništavanje obustave neće vratiti nikakve podatke ili odnos. + preamble_html: Obustavićete %{domain} i njegove poddomene. + remove_all_data: Ovo će ukloniti sav sadržaj, medije i podatke profila za naloge ovog domena sa vašeg servera. + stop_communication: Vaš server će prestati da komunicira sa ovim serverima. + title: Potvrdi blokiranje domena za %{domain} + undo_relationships: Ovo će poništiti svaki odnos praćenja između naloga ovih servera i vašeg. created_msg: Blokiranje domena se obrađuje destroyed_msg: Blokiranje domena je opozvano domain: Domen + edit: Izmeni blok domena + existing_domain_block: Već ste uspostavili stroža ograničenja prema korisniku %{name}. + existing_domain_block_html: Već ste uspostavili stroža ograničenja prema %{name}, potrebno je da ga prvo odblokirate. + export: Izvoz + import: Uvoz new: create: Napravi blokadu hint: Blokiranje domena neće sprečiti pravljenje naloga u bazi, ali će retroaktivno i automatski primeniti određene moderatorske metode nad tim nalozima. severity: + desc_html: "Ograničenje će sakriti objave naloga sa ovog domena od svakog ko ih ne prati. Suspenzija će obrisati sav sadržaj, medije i podatke profila sa naloga ovog domena sa Vašeg servera. Koristite Ništa ukoliko samo želite da odbijete medijske fajlove." noop: Ništa + silence: Ograniči suspend: Suspenzija title: Novo blokiranje domena + no_domain_block_selected: Nijedan blok domena nije promenjen jer nijedan nije izabran + not_permitted: Niste ovlašćeni da obavljate ovu radnju + obfuscate: Sakrij ime domena + obfuscate_hint: Delimično sakrij ime domena na listi ako je reklamiranje liste ograničenih domena omogućeno + private_comment: Privatni komentar + private_comment_hint: Komentar o ograničenju ovog domena za internu upotrebu od strane moderatora. + public_comment: Javni komentar + public_comment_hint: Komentar o ograničenju ovog domena za javnost, ukoliko je reklamiranje liste ograničenih domena omogućeno. reject_media: Odbaci multimediju - reject_media_hint: Uklanja lokalno uskladištene multimedijske fajlove i odbija da ih skida na dalje. Nebitno je za suspenziju - undo: Poništi + reject_media_hint: Uklanja lokalno uskladištene multimedijske fajlove i odbija da ih skida ubuduće. Nebitno je za suspenziju + reject_reports: Odbaci izveštaj + reject_reports_hint: Ignoriši sve izveštaje koji dolaze sa ovog domena. Nebitno je za suspenzije + undo: Poništi blok domena + view: Pročitaj blok domena email_domain_blocks: - add_new: Dodaj novuAdd new - created_msg: Uspešno dodao domen e-pošte na crnu listu - delete: Ukloni + add_new: Dodaj novi + attempts_over_week: + few: "%{count} pokušaja tokom prethodne nedelje" + one: "%{count} pokušaj tokom prethodne nedelje" + other: "%{count} pokušaja registracije tokom prethodne nedelje" + created_msg: Uspešno dodao domen E-pošte na crnu listu + delete: Obriši + dns: + types: + mx: MX izveštaj domain: Domen new: create: Dodaj domen - title: Nova stavka u crnoj listi e-pošti - title: Crna lista adresa e-pošte + resolve: Pretvori domen + title: Nova stavka e-pošte u crnoj listi + no_email_domain_block_selected: Nijedan blok imejl domena nije promenjen jer nijedan nije izabran + not_permitted: Nije dozvoljeno + resolved_dns_records_hint_html: Ime domena se pretvara u sledeće MX domene, koji su naposletku odgovorni za prihvatanje elektronske pošte. Blokiranje MX domena će blokirati registracije sa svake imejl adrese koja koristi taj MX domen, čak i u slučaju kada se vidljivo ime domena razlikuje. Vodite računa o tome da ne blokirate velike imejl provajdere. + resolved_through_html: Preusmereno kroz %{domain} + title: Crna lista E-pošte + export_domain_allows: + new: + title: Uvezi dozvoljene domene + no_file: Nijedan fajl nije odabran + export_domain_blocks: + import: + description_html: Upravo ćete uvesti listu blokiranih domena. Molimo Vas, vrlo pažljivo pregledajte ovu listu, posebno ukoliko je niste sami napravili. + existing_relationships_warning: Postojeći odnosi u obliku praćenja + private_comment_description_html: 'Da bi Vam pomogli da pratite odakle su blokovi uvezeni, uvezeni blokovi će biti napravljeni sa sledećim privatnim komentarom: %{comment}' + private_comment_template: Uvezeno sa izvora %{source} na datum %{date} + title: Uvezi blokirane domene + invalid_domain_block: 'Jedan ili više blokova domena je preskočen zbog sledeće greške tj. grešaka: %{error}' + new: + title: Uvezi blokirane domene + no_file: Nijedan fajl nije odabran + follow_recommendations: + description_html: "Predlozi za praćenje pomažu novim korisnicima da brzo pronađu zanimljiv sadržaj. Kada korisnik nije dovoljno komunicirao sa drugima da bi se za njega formirali personalizovani predlozi za praćenje, ovi nalozi će biti preporučeni umesto toga. Oni se generišu na dnevnoj bazi iz skupa naloga sa najviše nedavnih angažovanja i najviše lokalnih pratilaca za jedan jezik." + language: Za jezik + status: Status + suppress: Potisni preporuke za praćenje + suppressed: Potisnuto + title: Preporuke za praćenje + unsuppress: Vrati preporuku za praćenje instances: - title: Poznate instance + availability: + description_html: + few: Ukoliko isporuka domenu ne uspe nijednom tokom %{count} različitih dana, dalji pokušaji isporuke neće biti inicirani osim ukoliko se ne primi isporuka sa domena. + one: Ako isporuka domenu ne uspe nijednom u vremenskom periodu od %{count} dana, dalji pokušaji isporuke se neće inicirati osim ukoliko se ne primi isporuka sa domena. + other: Ukoliko isporuka domenu ne uspe nijednom tokom %{count} različitih dana, dalji pokušaji isporuke se neće inicirati osim ukoliko se ne primi isporuka sa domena. + failure_threshold_reached: Prag neuspeha dostignut datuma %{date}. + failures_recorded: + few: Neuspeli pokušaji tokom %{count} različita dana. + one: Neuspeli pokušaj tokom %{count} dana. + other: Neuspeli pokušaji tokom %{count} različitih dana. + no_failures_recorded: Bez zabeleženih neuspeha. + title: Dostupnost + warning: Poslednji pokušaj povezivanja sa ovim serverom je bio neuspešan + back_to_all: Sve + back_to_limited: Ograničeno + back_to_warning: Upozorenje + by_domain: Domen + confirm_purge: Da li ste sigurni da želite da trajno uklonite podatke sa ovog domena? + content_policies: + comment: Interna beleška + description_html: Možete da definišete politiku sadržaja koja će važiti za sve naloge na ovom domenu i svakom od njegovih poddomena. + limited_federation_mode_description_html: Možete da odlučite da li da dopustite federaciju sa ovim domenom. + policies: + reject_media: Odbij multimediju + reject_reports: Odbij prijave + silence: Ograniči + suspend: Suspenduj + policy: Politika + reason: Javni razlog + title: Politika sadržaja + dashboard: + instance_accounts_dimension: Najpraćeniji nalozi + instance_accounts_measure: uskladišteni nalozi + instance_followers_measure: naši pratioci ovde + instance_follows_measure: njihovi pratioci ovde + instance_languages_dimension: Najzastupljeniji jezici + instance_media_attachments_measure: uskladišteni multimedijalni prilozi + instance_reports_measure: prijave protiv njih + instance_statuses_measure: uskladištene objave + delivery: + all: Sve + clear: Očisti greške prilikom isporuke + failing: Bez uspeha + restart: Započni isporuku ponovo + stop: Obustavi isporuku + unavailable: Nedostupno + delivery_available: Dostava je dostupna + delivery_error_days: Dani neuspešnih isporuka + delivery_error_hint: Ukoliko isporuka nije moguća %{count} dana, automatski će biti obeležena kao neisporučiva. + destroyed_msg: Podaci sa %{domain} su sada u redu za čekanje za izvesno brisanje. + empty: Nijedan domen nije pronađen. + known_accounts: + few: "%{count} poznata naloga" + one: "%{count} poznat nalog" + other: "%{count} poznatih naloga" + moderation: + all: Sve + limited: Ograničeno + title: Moderacija + private_comment: Privatni komentar + public_comment: Javni komentar + purge: Čistka + purge_description_html: Ukoliko verujete da je ovaj domen trajno ugašen, možete da obrišete sve zapise naloga i srodne podatke ovog domena sa svog skladišta. Ovo može da potraje. + title: Federacija + total_blocked_by_us: Blokirano od strane nas + total_followed_by_them: Praćeni od strane njih + total_followed_by_us: Praćeni od strane nas + total_reported: Prijave vezane za njih + total_storage: Multimedijalni prilozi + totals_time_period_hint_html: Ukupne vrednosti prikazane ispod uključuju podatke za sva vremena. invites: + deactivate_all: Deaktiviraj sve filter: all: Sve - available: Aktivne - expired: Istekle + available: Dostupni + expired: Istekli + title: Filter title: Pozivnice + ip_blocks: + add_new: Napravi pravilo + created_msg: Uspešno je dodato novo IP pravilo + delete: Izbriši + expires_in: + '1209600': 2 nedelje + '15778476': 6 meseci + '2629746': 1 mesec + '31556952': 1 godina + '86400': 1 dan + '94670856': 3 godine + new: + title: Kreiraj novo IP pravilo + no_ip_block_selected: Nijedno IP pravilo nije promenjeno jer nijedno nije izabrano + title: IP pravila + relationships: + title: Odnosi korisnika %{acct} + relays: + add_new: Dodaj novi relej + delete: Obriši + description_html: "Federalni relej je posrednički server koji razmenjuje velike količine javnih truba između servera na koji je pretplaćen i na koji objavljuje.Može pomoći malim i srednjim serverima da otkriju sadržaj iz fediversa, koji inače zahteva od lokalnih korisnika da ručno pratiti ostale ljude na udaljenim serverima." + disable: Isključi + disabled: Isključen + enable: Uključi + enable_hint: Kada se omogući, vaš server će biti pretplaćen na sve javne objave sa ovog releja, i počeće da šalje javne objave ovog servera na njega. + enabled: Uključen + inbox_url: URL Releja + pending: Čeka se odobrenje releja + save_and_enable: Sačuvaj i omogući + setup: Podesi vezu releja + signatures_not_enabled: Prenosi možda neće raditi ispravno dok je uključen bezbedni režim ili režim ograničene federacije + status: Status + title: Releji + report_notes: + created_msg: Beleška prijave uspešno napravljena! + destroyed_msg: Beleška prijave uspešno izbrisana! reports: + account: + notes: + few: "%{count} beleške" + one: "%{count} beleška" + other: "%{count} beležaka" + action_log: Zapisnik action_taken_by: Akciju izveo + actions: + delete_description_html: Prijavljene objave će biti obrisane i prekršaj će biti upisan da bi Vam olakšali intervenciju prilikom budućih prestupa sa istog naloga. + mark_as_sensitive_description_html: Multimedijalni sadržaj sa prijavljenih objava će biti označen kao osetljiv i prekršaj će biti upisan radi lakše intervencije u slučaju daljih prekršaja sa istog naloga. + other_description_html: Pogledajte više opcija za kontrolisanje ponašanja naloga i prilagodite komunikaciju sa prijavljenim nalogom. + resolve_description_html: Nijedna radnja neće biti preduzeta protiv prijavljenog naloga, nijedan prestup nije upisan i prijava će biti zatvorena. + silence_description_html: Nalog će biti vidljiv samo onima koji ga već prate ili koji ga ručno potraže, što će značajno ograničiti njegov domet. Ograničenje se može povući u svakom trenutku. Zatvara sve prijave podnete protiv ovog naloga. + suspend_description_html: Nalog i svi njegovi sadržaji će postati nedostupni i u jednom trenutku izbrisani, a interakcija sa nalogom više neće biti moguća. Suspenzija se može povući u roku od 30 dana. Zatvara sve prijave podnete protiv ovog naloga. + actions_description_html: Odlučite koju radnju da sprovedete radi rešavanja ove prijave. Ukoliko sprovedete kaznenu radnju protiv prijavljenog naloga, vlasnik naloga će biti obavešten putem i-mejla, osim ukoliko oznaka „Nepoželjne poruke” nije odabrana. + actions_description_remote_html: Odlučite koju radnju da preduzmete radi rešavanja ove prijave. Ovo će uticati samo na to kako Vaš server komunicira sa ovim udaljenim nalogom i obrađuje njegov sadržaj. + add_to_report: Dodaj još u prijavu are_you_sure: Da li ste sigurni? + assign_to_self: Dodeli meni + assigned: Dodeljeni moderator + by_target_domain: Domen prijavljenog naloga + cancel: Otkaži + category: Kategorija + category_description_html: Razlog zbog kog je ovaj nalog i/ili sadržaj prijavljen će biti obrazložen u komunikaciji sa prijavljenim nalogom comment: none: Ništa - mark_as_resolved: Označi kao rešen + comment_description_html: 'Radi pružanja više informacija, %{name} je napisao/-la:' + confirm: Potvrdi + confirm_action: Potvrdi moderacijsku radnju prema @%{acct} + created_at: Prijavljena + delete_and_resolve: Obriši objave + forwarded: Prosleđeno + forwarded_to: Prosleđeno ka %{domain} + mark_as_resolved: Označi kao rešenu + mark_as_sensitive: Obeleži kao osetljivo + mark_as_unresolved: Označi kao nerešenu + no_one_assigned: Niko + notes: + create: Dodaj belešku + create_and_resolve: Reši sa beleškom + create_and_unresolve: Otvori ponovo sa beleškom + delete: Obriši + placeholder: Opišite kakve su radnje preduzete, ili bilo kakve povezane novosti... + title: Beleške + notes_description_html: Pročitajte i ostavite napomene drugim moderatorima i sebi u budućnosti + processed_msg: 'Prijava #%{id} uspešno obrađena' + quick_actions_description_html: 'Preduzmite brzu radnju ili se spustite niže da biste videli prijavljeni sadržaj:' + remote_user_placeholder: udaljeni korisnik sa %{instance} + reopen: Otvori prijavu ponovo report: 'Prijava #%{id}' reported_account: Prijavljeni nalog reported_by: Prijavio - resolved: Rešeni + resolved: Rešena + resolved_msg: Prijava uspešno razrešena! + skip_to_actions: Preskoči do radnji + status: Status + statuses: Prijavljeni sadržaj + statuses_description_html: Sporni sadržaj će biti naveden u komunikaciji sa prijavljenim nalogom + summary: + action_preambles: + delete_html: 'Upravo ćete obrisati neke od objava korisnika @%{acct}. Ovo će:' + mark_as_sensitive_html: 'Upravo ćete označiti neke objave korisnika @%{acct} kao osetljive. Ovo će:' + silence_html: 'Upravo ćete ograničiti nalog korisnika @%{acct}. Ovo će:' + suspend_html: 'Upravo ćete suspendovati nalog korisnika @%{acct}. Ovo će:' + actions: + delete_html: Obrišite sporne objave + mark_as_sensitive_html: Obeležite medije spornih objava kao osetljive + silence_html: Žestoko ograničite domet korisnika @%{acct} tako što ćete učiniti njegov profil i sadržaje vidljive samo ljudima koji ih već prate i ljudima koji ručno potraže profil + suspend_html: Suspendujte korisnika @%{acct}, što će učiniti njegov profil i sadržaje nedostupnim za pristup i interakciju + close_report: 'Označite prijavu #%{id} kao rešenu' + close_reports_html: Označi sve prijave protiv @%{acct} kao rešene + delete_data_html: Obriši profil i sadržaje korisnika @%{acct} za 30 dana osim ukoliko suspenzija bude povučena u međuvremenu + preview_preamble_html: "@%{acct} će primiti upozorenje sledeće sadržine:" + record_strike_html: Upišite prekršaj na ime @%{acct} da bi Vam bilo lakše da u budućnosti intervenišete prilikom daljih prestupa sa ovog naloga + send_email_html: Pošalji imejl upozorenja korisniku @%{acct} + warning_placeholder: Opciono dodatno obrazloženje za moderacijsku radnju. + target_origin: Poreklo prijavljenog naloga title: Prijave - unresolved: Nerešeni + unassign: Ukloni dodelu + unknown_action_msg: 'Nepoznata radnja: %{action}' + unresolved: Nerešene + updated_at: Ažurirana + view_profile: Pogledaj profil + roles: + add_new: Dodaj ulogu + assigned_users: + few: "%{count} korisnika" + one: "%{count} korisnik" + other: "%{count} korisnika" + categories: + administration: Administracija + devops: DevOps + invites: Pozivnice + moderation: Moderacija + special: Posebno + delete: Izbriši + description_html: Pomoću korisničkih uloga možete da podesite kojim funkcijama i delovima Mastodon-a vaši korisnici mogu da pristupe. + edit: Izmeni ulogu '%{name}' + everyone: Podrazumevana ovlašćenja + everyone_full_description_html: Ovo je osnovna uloga koja se odnosi na sve korisnike, čak i one kojima nije dodeljena uloga. Sve druge uloge nasleđuju ovlašćenja od osnovne uloge. + permissions_count: + few: "%{count} dozvole" + one: "%{count} dozvola" + other: "%{count} dozvola" + privileges: + administrator: Administrator + administrator_description: Korisnici sa ovom privilegijom mogu da zaobiđu sva druga ograničenja + delete_user_data: Izbriši podatke korisnika + delete_user_data_description: Dopušta korisnicima da izbrišu podatke drugih korisnika bez odlaganja + invite_users: Pozovi korisnike + invite_users_description: Dopušta korisnicima da pozove nove ljude na server + manage_announcements: Upravljaj obaveštenjima + manage_announcements_description: Dopušta korisnicima da rukovode saopštenjima na serveru + manage_appeals: Nadgledanje žalbi + manage_appeals_description: Dopušta korisnicima da pregledaju žalbe na moderacijske radnje + manage_blocks: Nadgledanje blokova + manage_blocks_description: Dopušta korisnicima da blokiraju imejl provajdere i IP adrese + manage_custom_emojis: Nadležnost nad prilagođenim emodžijima + manage_custom_emojis_description: Daje korisnicima kontrolu nad prilagođenim emodžijima na serveru + manage_federation: Nadgledanje federacije + manage_federation_description: Dopušta korisnicima da blokiraju ili dozvole federaciju sa drugim domenima i kontrolišu isporučivanje podataka drugim serverima + manage_invites: Nadgledanje pozivnica + manage_invites_description: Dopušta korisnicima da pretražuju i deaktiviraju pozivnice + manage_reports: Nadgledanje prijava + manage_reports_description: Dopušta korisnicima da pregledaju prijave i izvršavaju moderacijske radnje nad njima + manage_roles: Upravljaj ulogama + manage_roles_description: Dopušta korisnicima da nadgledaju i dodeljuju uloge sa nižim ovlašćenjima od njihove + manage_rules: Upravljaj pravilima + manage_rules_description: Dozvoli korisnicima da menjaju pravila servera + manage_settings: Upravljaj postavkama + manage_settings_description: Dozvoli korisnicima da menjaju postavke sajta + manage_taxonomies: Nadgledanje taksonomija + manage_taxonomies_description: Dopušta korisnicima da pregledaju sadržaj u trendu i ažuriraju postavke heš oznaka + manage_user_access: Nadležnost nad korisničkim pristupom + manage_user_access_description: Dopušta korisnicima da onemoguće dvofaktorsku autentifikaciju drugih korisnika, menjaju im imejl adrese i resetuju im lozinke + manage_users: Nadležnost nad korisnicima + manage_users_description: Dopušta korisnicima da pročitaju detalje drugih korisnika i izvršavaju moderacijske radnje nad njima + manage_webhooks: Nadležnost nad webhook elementima + manage_webhooks_description: Dopušta korisnicima da uspostave webhook elemente za administrativne radnje + view_audit_log: Pročitaj zapisnik revizija + view_audit_log_description: Dopušta korisnicima da vide istoriju administrativnih radnji na serveru + view_dashboard: Pogledaj kontrolni panel + view_dashboard_description: Dopušta korisnicima da pristupe kontrolnom panelu i raznim metrikama + view_devops: DevOps + view_devops_description: Dopušta korisnicima da pristupe Sidekiq i pgHero kontrolnim panelima + title: Uloge + rules: + add_new: Dodaj pravilo + delete: Izbriši + description_html: Dok većina tvrdi da je pročitala i slaže se sa uslovima korišćenja, ljudi ih obično ne čitaju sve dok se ne javi problem. Učinite pravila Vašeg servera čitljivijim i pristupačnijim tako što ćete ih izložiti u formi liste. Potrudite se da pojedinačna pravila budu kratka i jednostavna, ali pokušajte i da ih ne iscepkate u previše odvojenih stavki. + edit: Uredi pravilo + empty: Nijedno pravilo servera još nije definisano. + title: Pravila servera + settings: + about: + manage_rules: Upravljanje pravilima servera + preamble: Pružite detaljne informacije o tome kako se server vodi, moderira i finansira. + rules_hint: Postoji predviđeno mesto za pravila koja se od korisnika očekuje da poštuju. + title: Naziv + appearance: + preamble: Prilagodite veb okruženje Mastodon-a. + title: Izgled + branding: + preamble: Brendiranje Vašeg servera ga izdvaja od drugih servera na mreži. Ove informacije mogu biti prikazane u raznim okruženjima, poput Mastodon-ovog veb okruženja, nativnih aplikacija, u pregledima linkova na drugim serverima i u aplikacijama za razmenu poruka, itd. Iz ovog razloga, najbolje je da ove informacije budu kratke, jasne i koncizne. + title: Brendiranje + captcha_enabled: + desc_html: Ovo se oslanja na eksterne skripte iz hCaptcha, što može predstavljati zabrinutost za bezbednost i privatnost. Pored toga, ovo može učiniti proces registracije znatno manje dostupnim nekim (posebno osobama sa invaliditetom). Iz ovih razloga, razmotrite alternativne mere kao što je registracija zasnovana na odobrenju ili na pozivu. + title: Zahtevaj od novih korisnika da reše CAPTCHA da bi potvrdili svoj nalog + content_retention: + preamble: Kontrolišite kako se sadržaj generisan od strane korisnika skladišti na Mastodon-u. + title: Zadržavanje sadržaja + default_noindex: + desc_html: Utiče na sve korisnike koji nisu sami promenili ovu postavku + title: Podrazumevano isključi korisnike iz indeksiranja pretraživača + discovery: + follow_recommendations: Preporuke za praćenje + preamble: Održavanje zanimljivih sadržaja na površini je ključno u privlačenju novih korisnika koji možda ne znaju nikoga na Mastodon-u. Kontrolišite kako različiti načini istraživanja funkcionišu na vašem serveru. + profile_directory: Direktorijum profilâ + public_timelines: Javne vremenske linije + publish_discovered_servers: Objavi otkrivene servere + publish_statistics: Objavi statistiku + title: Otkrivanje + trends: Trendovi + domain_blocks: + all: Svima + disabled: Nikome + users: Prijavljenim lokalnim korisnicima + registrations: + preamble: Kontrolišite ko sme da napravi nalog na Vašem serveru. + title: Registracije + registrations_mode: + modes: + approved: Odobrenje neophodno za registraciju + none: Niko ne može da se registruje + open: Bilo ko može da se registruje + security: + authorized_fetch: Zahtevaj autentifikaciju sa združenih servera + authorized_fetch_hint: Zahtevanje autentifikacije sa združenih servera omogućuje strožiju primenu blokova i na nivou korisnika i na nivou servera. Međutim, ovo dolazi po cenu smanjenja performansi, smanjuje domet vaših odgovora i može dovesti do problema kompatibilnosti sa nekim združenim uslugama. Pored toga, ovo neće sprečiti posvećene aktere da preuzimaju vaše javne objave i naloge. + authorized_fetch_overridden_hint: Trenutno ne možete da promenite ovo podešavanje jer ga zamenjuje promenljiva okruženja. + federation_authentication: Sprovođenje združene autentifikacije + title: Podešavanja servera + site_uploads: + delete: Obriši otpremljeni fajl + destroyed_msg: Otpremanje uspešno obrisano! + software_updates: + critical_update: Kritično — ažurirajte brzo + description: Preporučuje se da svoju Mastodon instalaciju održavate ažurnom kako biste imali koristi od najnovijih ispravki i funkcija. Štaviše, ponekad je ključno ažurirati Mastodon na vreme kako bi se izbegli bezbednosni problemi. Iz ovih razloga, Mastodon proverava da li postoje ažuriranja svakih 30 minuta, i obavestiće vas u skladu sa vašim podešavanjima obaveštenja putem e-pošte. + documentation_link: Saznajte više + release_notes: Beleške o izdanju + title: Dostupna ažuriranja + type: Tip + types: + major: Glavno izdanje + minor: Manje izdanje + patch: Izdanje zakrpe — ispravke grešaka i promene koje se lako primenjuju + version: Verzija statuses: + account: Autor + application: Aplikacija back_to_account: Nazad na stranu naloga + back_to_report: Nazad na stranicu sa prijavama + batch: + remove_from_report: Uklonite iz prijave + report: Prijavi + deleted: Obrisano + favourites: Omiljeno + history: Istorija verzijâ + in_reply_to: Odgovor na + language: Jezik media: title: Multimedija + metadata: Meta podaci + no_status_selected: Nijedan status nije promenjen jer nijedan nije izabran + open: Otvori objavu + original_status: Originalna objava + reblogs: Deljenja + status_changed: Objava promenjena title: Statusi naloga + trending: U trendu + visibility: Vidljivost with_media: Sa multimedijom + strikes: + actions: + delete_statuses: "%{name} je obrisao/-la objave %{target}" + disable: "%{name} je zamrznuo nalog korisnika %{target}" + mark_statuses_as_sensitive: "%{name} je označio/-la objave korisnika %{target} kao osetljive" + none: "%{name} je poslao/-la upozorenje korisniku %{target}" + sensitive: "%{name} je obeležio/-la nalog %{target} kao osetljiv" + silence: "%{name} je ograničio/-la nalog %{target}" + suspend: "%{name} je suspendovao/-la nalog %{target}" + appeal_approved: Žalba uvažena + appeal_pending: Žalba u razmatranju + appeal_rejected: Žalba odbijena + system_checks: + database_schema_check: + message_html: Selidbe bazâ podataka su na čekanju. Molimo Vas obavite ih da bi se aplikacija ponašala kako treba + elasticsearch_health_red: + message_html: Elasticsearch klaster je nezdrav (crveni status), funkcije pretrage su nedostupne + elasticsearch_health_yellow: + message_html: Elasticsearch klaster je nezdrav (žuti status), možda biste želeli da istražite razlog + elasticsearch_index_mismatch: + message_html: Elasticsearch mapiranja indeksa su zastarela. Pokrenite tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Pogledaj dokumentaciju + message_html: Vaš Elasticsearch klaster ima više od jednog čvora, ali Mastodon nije konfigurisan da ih koristi. + elasticsearch_preset_single_node: + action: Pogledaj dokumentaciju + message_html: Vaš Elasticsearch klaster ima samo jedan čvor, ES_PRESETtreba postaviti nasingle_node_cluster. + elasticsearch_reset_chewy: + message_html: Vaš Elasticsearch klaster ima samo jedan čvor, ES_PRESETtreba postaviti nasingle_node_cluster. + elasticsearch_running_check: + message_html: Povezivanje na Elasticsearch nije bilo moguće. Molimo Vas proverite da li je pokrenut, ili onemogućite pretragu celog teksta + elasticsearch_version_check: + message_html: 'Neusklađena Elasticsearch verzija: %{value}' + version_comparison: Elasticsearch %{running_version} je instaliran a %{required_version} je neophodan + rules_check: + action: Upravljanje pravilima servera + message_html: Niste definisali nijedno pravilo servera. + sidekiq_process_check: + message_html: Nijedan Sidekiq proces nije pokrenut za red(ove) %{value}. Molimo Vas pregledajte svoju Sidekiq konfiguraciju + software_version_critical_check: + action: Pogledajte dostupna ažuriranja + message_html: Dostupno je kritično ažuriranje za Mastodon, ažurirajte ga što je pre moguće. + software_version_patch_check: + action: Pogledajte dostupna ažuriranja + message_html: Dostupna je ispravka grešaka za Mastodon. + upload_check_privacy_error: + action: Proverite ovde za više informacija + message_html: "Vaš veb server je pogrešno konfigurisan. Privatnost vaših korisnika je izložena riziku." + upload_check_privacy_error_object_storage: + action: Proverite ovde za više informacija + message_html: "Vaše skladište objekta je pogrešno konfigurisano. Privatnost vaših korisnika je izložena riziku." + tags: + review: Pregledaj status + updated_msg: Podešavanja heš oznaka uspešno ažurirana title: Administracija + trends: + allow: Dozvoli + approved: Odobreno + disallow: Zabrani + links: + allow: Dozvoli link + allow_provider: Dozvoli izdavača + description_html: Ovo su linkovi koji se trenutno često dele među nalozima koje Vaš server vidi. Može pomoći Vašim korisnicima da saznaju šta se dešava u svetu. Nijedan link nije javno prikazan sve dok Vi ne odobrite izdavača. Takođe možete da dozvolite ili odbijete zasebne linkove. + disallow: Zabrani link + disallow_provider: Zabrani izdavača + no_link_selected: Nijedan link nije promenjen jer nijedan nije izabran + publishers: + no_publisher_selected: Nijedan izdavač nije promenjen jer nijedan nije izabran + shared_by_over_week: + few: Podeljen od strane %{count} osobe tokom prethodne nedelje + one: Podeljen od strane jedne osobe tokom prethodne nedelje + other: Podeljen od strane %{count} osoba tokom prethodne nedelje + title: Linkovi u trendu + usage_comparison: Podeljeno %{today} puta danas, u poređenju sa %{yesterday} puta juče + not_allowed_to_trend: Nije odobreno za trend + only_allowed: Samo dozvoljeno + pending_review: Pregled na čekanju + preview_card_providers: + allowed: Linkovi sa ovog izvora mogu da budu „u trendu” + description_html: Ovo su domeni čiji se linkovi često dele na Vašem serveru. Linkovi neće biti javno prikazani kao „u trendu” osim ukoliko je domen linkova odobren. Vaše odobrenje (ili odbijanje) se prenosi i na poddomene. + rejected: Linkovi sa ovog izvora neće biti „u trendu” + title: Izdavači + rejected: Odbijen + statuses: + allow: Dozvoli objavu + allow_account: Odobri autora + description_html: Ovo su objave za koje Vaš server zna, a koje se trenutno često dele i koje korisnici često stavljaju u „omiljene”. Mogu pomoći Vašim novim korisnicima i povratnicima da pronađu još ljudi za praćenje. Nijedna objava nije prikazana javno sve dok Vi ne odobrite autora, odnosno dok autor ne dozvoli da njegov/njen nalog bude preporučen drugima. Takođe možete da odobrite ili odbijete zasebne objave. + disallow: Zabrani objavu + disallow_account: Zabrani autora + no_status_selected: Nijedna objava u trendu nije promenjena jer nijedna nije izabrana + not_discoverable: Autor nije dao saglasnost da bude preporučen + shared_by: + few: Podeljeno i stavljeno u „omiljene” %{friendly_count} puta + one: Podeljeno ili stavljeno u „omiljene” jednom + other: Podeljeno i stavljeno u „omiljene” %{friendly_count} puta + title: Objave u trendu + tags: + current_score: Trenutna vrednost %{score} + dashboard: + tag_accounts_measure: jedinstvene upotrebe + tag_languages_dimension: Najzastupljeniji jezici + tag_servers_dimension: Najaktivniji serveri + tag_servers_measure: različiti serveri + tag_uses_measure: ukupno upotreba + description_html: Ovo su heš oznake koje se trenutno često pojavljuju u objavama koje Vaš server vidi. Mogu pomoći Vašim korisnicima da otkriju o čemu se trenutno najviše govori. Nijedna heš oznaka nije prikazana javno sve dok Vi to ne odobrite. + listable: Može se preporučiti + no_tag_selected: Nijedna oznaka nije izmenjena jer nijedna nije izabrana + not_listable: Neće biti preporučeno + not_trendable: Neće se pojavljivati u trendovima + not_usable: Ne može se koristiti + peaked_on_and_decaying: Vrhunac dostignut datuma %{date}, od tada u opadanju + title: Heš oznake u trendu + trendable: Može da se pojavi pod trendovima + trending_rank: 'U trendu #%{rank}' + usable: Može se koristiti + usage_comparison: Upotrebljeno %{today} puta danas, u poređenju sa %{yesterday} puta juče + used_by_over_week: + few: Korišćeno od strane %{count} osobe tokom prethodne nedelje + one: Korišćeno od strane jedne osobe tokom prethodne nedelje + other: Korišćeno od strane %{count} ljudi tokom prethodne nedelje + title: Trendovi + trending: U trendu + warning_presets: + add_new: Dodaj novi + delete: Izbriši + edit_preset: Uredi preset upozorenja + empty: Još uvek niste definisali nijedan šablon upozorenja. + title: Upravljaj presetima upozorenja + webhooks: + add_new: Dodaj krajnju tačku + delete: Izbriši + description_html: "Webhook omogućava Mastodon-u da vašoj aplikaciji isporučuje obaveštenja u realnom vremenu o odabranim događajima, tako da vaša aplikacija može da automatski izazove reakciju." + disable: Onemogući + disabled: Onemogućeno + edit: Izmeni krajnju tačku + empty: Još uvek nemate nijednu konfigurisanu webhook krajnju tačku. + enable: Omogući + enabled: Aktivno + enabled_events: + few: "%{count} omogućena događaja" + one: 1 omogućen događaj + other: "%{count} omogućenih događaja" + events: Događaji + new: Novi webhook + rotate_secret: Rotacija tajni + secret: Tajno potpisivanje + status: Status + title: Veb-presretač + webhook: Veb-presretač admin_mailer: + new_appeal: + actions: + delete_statuses: obrisati objave korisnika + disable: zamrznuti nalog korisnika + mark_statuses_as_sensitive: označiti objave korisnika kao osetljive + none: upozorenje + sensitive: označiti nalog kao osetljiv + silence: ograničiti nalog + suspend: suspendovati nalog + body: "%{target} prilaže žalbu na moderacijsku odluku korisnika %{action_taken_by} od %{date}, koja je glasila %{type}. U žalbi piše:" + next_steps: Možete uvažiti žalbu da biste povukli moderacijsku odluku, ili je možete ignorisati. + subject: "%{username} prilaže žalbu na moderacijsku odluku sa %{instance}" + new_critical_software_updates: + body: Objavljene su nove kritične verzije Mastodon-a, možda ćete želeti da ažurirate što je pre moguće! + subject: Kritična Mastodon ažuriranja su dostupna za %{instance}! + new_pending_account: + body: Detalji novog naloga su navedeni dole. Možete odobriti ili odbiti ovaj zahtev. + subject: Nov nalog za pregled na %{instance} (%{username}) new_report: body: "%{reporter} je prijavio %{target}" + body_remote: Neka sa domena %{domain} je prijavio %{target} subject: Nova prijava za %{instance} (#%{id}) + new_software_updates: + body: Objavljene su nove verzije Mastodon-a, možda ćete želeti da ažurirate! + subject: Nove Mastodon verzije su dostupne za %{instance}}! + new_trends: + body: 'Sledeće stavke je potrebno pregledati pre nego što mogu javno da se prikažu:' + new_trending_links: + title: Linkovi u trendu + new_trending_statuses: + title: Objave u trendu + new_trending_tags: + no_approved_tags: Trenutno nema odobrenih heš oznaka u trendu. + requirements: 'Bilo koji od sledećih kandidata bi mogao prevazići #%{rank} odobrenu heš oznaku u trendu, koja je trenutno #%{lowest_tag_name} sa vrednošću %{lowest_tag_score}.' + title: Heš oznake u trendu + subject: Novi trendovi za pregled na %{instance} + aliases: + add_new: Napravi pseudonim + created_msg: Uspešno je napravljen novi pseudonim. Sada možete inicirati preseljenje sa starog naloga. + deleted_msg: Uspešno je uklonjen pseudonim. Premeštanje sa tog naloga na ovaj više neće biti moguće. + empty: Nemate nijedan pseudonim. + hint_html: Ako želite da se preselite sa drugog naloga na ovaj, ovde možete napraviti pseudonim, koji je neophodan pre nego što možete nastaviti sa prebacivanjem pratilaca sa starog naloga na ovaj. Ova radnja sama po sebi je bezopasna i reverzibilna. Preseljenje naloga se inicira sa starog naloga. + remove: Odveži pseudonim + appearance: + advanced_web_interface: Napredno veb okruženje + advanced_web_interface_hint: 'Ako želite da iskoristite celu širinu ekrana, napredno veb okruženje vam omogućuje da konfigurišete mnogo različitih kolona da biste videli onoliko informacija u isto vreme koliko želite: početnu stranicu, obaveštenja, združenu vremensku liniju, bilo koji broj lista i heš oznaka.' + animations_and_accessibility: Animacije i pristupačnost + confirmation_dialogs: Dijalozi potvrde + discovery: Otkrivanje + localization: + body: Mastodon prevode dobrovoljci. + guide_link: https://crowdin.com/project/mastodon + guide_link_text: Svako može doprineti. + sensitive_content: Osetljiv sadržaj application_mailer: + notification_preferences: Promeni preference E-pošte + salutation: Poštovani %{name}, settings: 'Promeni podešavanja e-pošte: %{link}' + unsubscribe: Odjavi se view: 'Pogledaj:' + view_profile: Pogledaj nalog + view_status: Pogledaj status applications: created: Aplikacija uspešno napravljena destroyed: Aplikacija uspešno obrisana + logout: Odjava regenerate_token: Rekreiraj pristupni token token_regenerated: Pristupni token uspešno rekreiran warning: Oprezno sa ovim podacima. Nikad je ne delite ni sa kim! your_token: Vaš pristupni token auth: - delete_account: Obriši nalog - delete_account_html: Ako želite da obrišete Vaš nalog, možete nastaviti ovde. Bićete upitani da potvrdite. - didnt_get_confirmation: Niste dobili poruku sa uputstvima za potvrdu naloga? + apply_for_account: Zatražite nalog + captcha_confirmation: + help_html: Ako imate problema sa rešavanjem CAPTCHA, možete nas kontaktirati preko %{email} i možemo vam pomoći. + hint_html: Samo još jedna stvar! Moramo da potvrdimo da ste ljudsko biće (ovo je da bismo sprečili neželjenu poštu!). Rešite CAPTCHA ispod i kliknite na „Nastavi”. + title: Bezbedonosna provera + confirmations: + wrong_email_hint: Ako ta imejl adresa nije ispravna, možete je promeniti u podešavanjima naloga. + delete_account: Brisanje naloga + delete_account_html: Ako želite da izbrišete vaš nalog, možete nastaviti ovde. Od vas će se tražiti potvrda. + description: + prefix_invited_by_user: "@%{name} vas poziva da se pridružite ovom serveru Mastodon-a!" + prefix_sign_up: Pridružite se Mastodon-u danas! + suffix: Sa nalogom, moći ćete da pratite ljude, objavljujete novosti i razmenjujete poruke sa korisnicima bilo kog Mastodon servera i više! + didnt_get_confirmation: Niste primili vezu za potvrdu? + dont_have_your_security_key: Nemate sigurnosni ključ? forgot_password: Zaboravili ste lozinku? invalid_reset_password_token: Token za resetovanje lozinke je neispravan ili je istekao. Zatražite novi. + link_to_otp: Unesite dvofaktorski kod sa svog telefona ili rezervni kod + link_to_webauth: Koristite svoj sigurnosni ključ + log_in_with: Prijavite se pomoću login: Prijavi se logout: Odjava - migrate_account: Pomeri u drugi nalog + migrate_account: Premeštanje u drugi nalog migrate_account_html: Ako želite da preusmerite ovaj nalog na neki drugi, možete to podesiti ovde. + or_log_in_with: Ili se prijavite sa + privacy_policy_agreement_html: Pročitao/-la sam i saglasan/-a sam sa politikom privatnosti + progress: + confirm: Potvrdite e-poštu + details: Vaši detalji + review: Naš pregled + rules: Prihvatite pravila + providers: + cas: CAS-om + saml: SAML-om register: Registruj se - resend_confirmation: Pošalji poruku sa uputstvima o potvrdi naloga ponovo + registration_closed: "%{instance} ne prima nove članove" + resend_confirmation: Ponovo pošalji vezu za potvrdu reset_password: Resetuj lozinku + rules: + accept: Prihvati + back: Nazad + invited_by: 'Možete se pridružiti %{domain} zahvaljujući pozivnici koju ste dobili od:' + preamble: Ovo su pravila koja su uspostavili i koja sprovode moderatori servera %{domain}. + preamble_invited: Pre nego što nastavite, razmotrite osnovna pravila koja su postavili moderatori %{domain}. + title: Neka osnovna pravila. + title_invited: Pozvani ste. security: Bezbednost set_new_password: Postavi novu lozinku - authorize_follow: - error: Nažalost, desila se greška pri traženju udaljenog naloga - follow: Zaprati - follow_request: 'Poslali ste zahtev za praćenjen za:' - following: 'Sjajno! Sada pratite:' - post_follow: - close: Ili možete zatvoriti ovaj prozor. - return: Vrati se na profil ovog korisnika - web: Idi na veb - title: Zaprati %{acct} + setup: + email_below_hint_html: Proverite svoju fasciklu neželjene pošte ili zatražite drugu. Možete da ispravite svoju adresu e-pošte ako je pogrešna. + email_settings_hint_html: Kliknite na vezu koji smo vam poslali da verifikujete %{email}. Čekaćemo ovde. + link_not_received: Niste dobili vezu? + new_confirmation_instructions_sent: Za nekoliko minuta primićete novu e-poruku sa vezom za potvrdu! + title: Proverite svoje prijemno sanduče + sign_in: + preamble_html: Prijavite se sa svojim podacima za %{domain}. Ako se Vaš nalog nalazi na drugom serveru, nećete moći da se prijavite ovde. + title: Prijavite se na %{domain} + sign_up: + manual_review: Naši moderatori ručno pregledaju registracije na %{domain}. Da biste nam pomogli da obradimo vašu registraciju, napišite nešto o sebi i zašto želite nalog na %{domain}. + preamble: Sa nalogom na ovom Mastodon serveru, moći ćete da pratite bilo koga sa mreže, bez obzira na to na kom serveru se njegov/njen nalog nalazi. + title: Hajde da Vam namestimo nalog na %{domain}. + status: + account_status: Status naloga + confirming: Čekanje na potvrdu putem imejla. + functional: Vaš nalog je potpuno operativan. + pending: Vaš zahtev je na čekanju za pregled od strane našeg osoblja. Ovo može potrajati neko vreme. Primićete imejl poruku ukoliko Vam zahtev bude odobren. + redirecting_to: Vaš nalog je neaktivan jer preusmerava na %{acct}. + view_strikes: Pogledajte prethodne prestupe upisane na Vaše ime + too_fast: Formular je podnet prebrzo, pokušajte ponovo. + use_security_key: Koristite sigurnosni ključ + challenge: + confirm: Nastavi + hint_html: "Savet: Nećemo Vas pitati za lozinku ponovo u narednih sat vremena." + invalid_password: Neispravna lozinka + prompt: Potvrdite lozinku za nastavak + crypto: + errors: + invalid_key: nije validan Ed25519 ili Curve25519 ključ + invalid_signature: nije validan Ed25519 potpis + date: + formats: + default: "%d. %b. %Y." + with_month_name: "%d. %B %Y." datetime: distance_in_words: + about_x_hours: "%{count} č." about_x_months: "%{count}mesec" about_x_years: "%{count}god" almost_x_years: "%{count}god" half_a_minute: Upravo sad + less_than_x_minutes: "%{count} min." less_than_x_seconds: Upravo sad over_x_years: "%{count}god" + x_days: "%{count}d" + x_minutes: "%{count} min." x_months: "%{count}mesec" + x_seconds: "%{count} sek." deletes: - confirm_password: Unesite trenutnu lozinku da bismo proverili Vaš identitet + challenge_not_passed: Lozinka koju ste uneli nije bila ispravna + confirm_password: Unesite trenutnu lozinku za verifikaciju vašeg identiteta + confirm_username: Unesite svoje korisničko ime da biste potvrdili proceduru proceed: Obriši nalog success_msg: Vaš nalog je uspešno obrisan + warning: + before: 'Pre nego što nastavite, molimo Vas pažljivo pročitajte sledeće napomene:' + caches: Sadržaj koji je keširan na drugim serverima može da ostane netaknut + data_removal: Vaše objave i drugi podaci će biti trajno izbrisani + email_change_html: Možete promeniti svoju imejl adresu bez brisanja svog naloga + email_contact_html: Ako poruka i dalje ne stiže, možete poslati mejl na %{email} za pomoć + email_reconfirmation_html: Ukoliko Vam imejl za potvrdu ne stiže, možete ga ponovo zatražiti + irreversible: Nećete biti u mogućnosti da vratite ili reaktivirate svoj nalog + more_details_html: Za više detalja, pogledajte politiku privatnosti. + username_available: Vaše korisničko ime će ponovo postati dostupno + username_unavailable: Vaše korisničko ime će ostati nedostupno + disputes: + strikes: + action_taken: Radnja preduzeta + appeal: Žalba + appeal_approved: Žalba na ovaj prestup je uvažena i prestup više nije validan + appeal_rejected: Žalba je odbijena + appeal_submitted_at: Žalba je priložena + appealed_msg: Vaša žalba je priložena. Bićete obavešteni ukoliko ona bude bila uvažena. + appeals: + submit: Priloži žalbu + approve_appeal: Uvaži žalbu + associated_report: Srodna prijava + created_at: Datum + description_html: Ovo su radnje preduzete protiv Vašeg naloga i upozorenja koja su Vam poslali članovi osoblja %{instance}. + recipient: Usmereno prema + reject_appeal: Odbij žalbu + status: 'Objava #%{id}' + status_removed: Objava je već uklonjena iz sistema + title: "%{action} od %{date}" + title_actions: + delete_statuses: Brisanje objava + disable: Zamrzavanje naloga + mark_statuses_as_sensitive: Označavanje objava kao osetljivih + none: Upozorenje + sensitive: Označavanje naloga kao osetljivog + silence: Ograničenje naloga + suspend: Suspenzija naloga + your_appeal_approved: Vaša žalba je uvažena + your_appeal_pending: Priložili ste žalbu + your_appeal_rejected: Vaša žalba je odbijena + domain_validator: + invalid_domain: nelegitimno ime domena + edit_profile: + basic_information: Osnovne informacije + hint_html: "Prilagodite šta ljudi vide na vašem javnom profilu i pored vaših objava. Veća je verovatnoća da će vas drugi pratiti i komunicirati sa vama kada imate popunjen profil i sliku profila." + other: Ostalo errors: - '400': The request you submitted was invalid or malformed. + '400': Zahtev koji ste podneli je bio nelegitiman ili u pogrešnom formatu. '403': Nemate dozvola da vidite ovu stranu. '404': Strana koju ste tražili ne postoji. - '406': This page is not available in the requested format. + '406': Ova stranica nije dostupna u izabranom formatu. '410': Strana koju ste tražili više ne postoji. + '422': + content: Bezbedonosna verifikacija nije uspela. Da li blokirate kolačiće? + title: Bezbedonosna verifikacija nije uspela '429': Uspored '500': content: Izvinjavamo se, nešto je pošlo po zlu sa ove strane. title: Strana nije ispravna - '503': The page could not be served due to a temporary server failure. - noscript_html: Da biste koristili Mastodont veb aplikaciju, omogućite JavaScript. U suprotnom, probajte neku od originalnih aplikacija za Mastodont za Vašu platformu. + '503': Stranicu nije bilo moguće dostaviti usled privremenog pada servera. + noscript_html: Da biste koristili Mastodon veb aplikaciju, omogućite JavaScript. U suprotnom, probajte neku od originalnih aplikacija za Mastodon za vašu platformu. + existing_username_validator: + not_found: nije bilo moguće pronaći lokalnog korisnika sa tim korisničkim imenom + not_found_multiple: nije bilo moguće pronaći %{usernames} exports: + archive_takeout: + date: Datum + download: Preuzmite Vašu arhivu + hint_html: Možete zatražiti arhivu vaših objava i otpremljenih medija. Izvezeni podaci će biti u ActivityPub formatu, koji može čitati bilo koji kompatibilan softver. Arhivu možete zatražiti svakih 7 dana. + in_progress: Sastavljanje vaše arhive... + request: Zatražite svoju arhivu + size: Veličina blocks: Blokirali ste - mutes: Ućutkali ste + bookmarks: Obeleživači + csv: CSV + domain_blocks: Blokovi domena + lists: Liste + mutes: Ignorišete storage: Multimedijalno skladište + featured_tags: + add_new: Dodaj novu + errors: + limit: Već ste istakli maksimalan broj heš oznaka + hint_html: "Istaknite najvažnije heš oznake na svom profilu. Odličan alat za praćenje vaših kreativnih radova i dugoročnih projekata, istaknute heš oznake su istaknute na vašem profilu i omogućuju brz pristup vašim objavama." + filters: + contexts: + account: Profili + home: Početna stranica i liste + notifications: Obaveštenja + public: Javne vremenske linije + thread: Razgovori + edit: + add_keyword: Dodaj ključnu reč + keywords: Ključne reči + statuses: Zasebne objave + statuses_hint_html: Ovaj filter važi za odabrane zasebne objave bez obzira na to da li sadrže ključne reči navedene ispod. Pregledajte ili uklonite objave iz filtera. + title: Izmeni filter + errors: + deprecated_api_multiple_keywords: Ovi parametri ne mogu biti promenjeni u ovoj aplikaciji zato što se odnose na više od jedne ključne reči. Koristite ažurniju aplikaciju ili veb interfejs. + invalid_context: Nijedan ili nevažeći kontekst isporučen + index: + contexts: Filtrira u %{contexts} + delete: Izbriši + empty: Nemate filtere. + expires_in: Ističe za %{distance} + expires_on: Ističe datuma %{date} + keywords: + few: "%{count} ključne reči" + one: "%{count} ključna reč" + other: "%{count} ključnih reči" + statuses: + few: "%{count} objave" + one: "%{count} objava" + other: "%{count} objava" + statuses_long: + few: "%{count} zasebne objave sakrivene" + one: "%{count} zasebna objava sakrivena" + other: "%{count} zasebnih objava sakriveno" + title: Filteri + new: + save: Sačuvaj novi filter + title: Dodaj novi filter + statuses: + back_to_filter: Nazad na filter + batch: + remove: Ukloni iz filtera + index: + hint: Ovaj filter važi za odabrane zasebne objave bez obzira na druge kriterijume. Možete da dodate više objava u ovaj filter putem veb interfejsa. + title: Filtrirane objave generic: - changes_saved_msg: Izmene uspešno sačuvane! - save_changes: Snimi izmene + all: Svi + all_items_on_page_selected_html: + few: Sve %{count} stavke sa ove stranice su izabrane. + one: "%{count} stavka sa ove stranice je izabrana." + other: Svih %{count} stavki sa ove stranice je izabrano. + all_matching_items_selected_html: + few: Sve %{count} stavke koje se poklapaju sa Vašom pretragom su izabrane. + one: "%{count} stavka koja se poklapa sa Vašom pretragom je izabrana." + other: Svih %{count} stavki koje se poklapaju sa Vašom pretragom su izabrane. + cancel: Otkaži + changes_saved_msg: Promene su uspešno sačuvane! + confirm: Potvrdi + copy: Kopiraj + delete: Izbriši + deselect: Poništi sve izbore + none: Nijedna + order_by: Sortiraj prema + save_changes: Sačuvaj promene + select_all_matching_items: + few: Odaberite sve %{count} stavke koje se poklapaju sa Vašom pretragom. + one: Odaberite %{count} stavku koja se poklapa sa Vašom pretragom. + other: Odaberite svih %{count} stavki koje se poklapaju sa Vašom pretragom. + today: danas validation_errors: few: Nešto nije baš kako treba! Pregledajte %{count} greške ispod one: Nešto nije baš kako treba! Pregledajte greške ispod other: Nešto nije baš kako treba! Pregledajte %{count} grešaka ispod imports: + errors: + empty: Prazna CSV datoteka + incompatible_type: Nekompatibilno sa izabranim tipom uvoza + invalid_csv_file: 'Neispravan CSV fajl. Greška: %{error}' + over_rows_processing_limit: sadrži više od %{count} redova + too_large: Datoteka je prevelika + failures: Neuspesi + imported: Uvezeno + mismatched_types_warning: Izgleda da ste možda izabrali pogrešan tip za ovaj uvoz, proverite još jednom. + modes: + merge: Stapanje + merge_long: Zadržite postojeće zapise i dodajte nove + overwrite: Zameni + overwrite_long: Zameni trenutne zapise novima + overwrite_preambles: + blocking_html: Upravo ćete zameniti svoju listu blokiranih sa do %{total_items} naloga iz %{filename}. + bookmarks_html: Upravo ćete zameniti svoje obeleživače sa do %{total_items} objava iz %{filename}. + domain_blocking_html: Upravo ćete zameniti svoju listu blokiranih domena sa do %{total_items} domena iz %{filename}. + following_html: Upravo ćete pratiti do %{total_items} naloga iz %{filename} and i prestati sa praćenjem bilo koga drugog. + lists_html: Spremate se da zamenite svoje liste sadržajem od %{filename}. Do %{total_items} naloga će biti dodato na nove liste. + muting_html: Upravo ćete zameniti svoju listu ignorisanih naloga sa do %{total_items} naloga iz %{filename}. + preambles: + blocking_html: Upravo ćete blokirati do %{total_items} naloga iz %{filename}. + bookmarks_html: Upravo ćete dodati do %{total_items} objava iz %{filename} u vaše obeleživače. + domain_blocking_html: Upravo ćete blokirati do %{total_items} domena iz %{filename}. + following_html: Upravo ćete pratiti do %{total_items} naloga iz %{filename}. + lists_html: Spremate se da dodate do %{total_items} naloga od %{filename} na svoje liste. Nove liste će biti kreirane ako ne postoji lista za dodavanje. + muting_html: Upravo ćete ignorisati do %{total_items} naloga iz %{filename}. preface: Možete uvesti podatke koje ste izvezli sa druge instance, kao što su liste ljudi koje ste pratili ili blokirali. + recent_imports: Nedavni uvozi + states: + finished: Završeno + in_progress: U toku + scheduled: Planirano + unconfirmed: Nepotvrđeno + status: Status success: Vaši podaci su uspešno otpremljeni i biće obrađeni uskoro + time_started: Započeto u + titles: + blocking: Uvoz blokiranih naloga + bookmarks: Uvoz obeleživača + domain_blocking: Uvoz blokiranih domena + following: Uvoz praćenih naloga + lists: Uvoz lista + muting: Uvoz ignorisanih naloga + type: Tip uvoza + type_groups: + constructive: Praćenja i obeleživači + destructive: Blokiranja i ignorisanja types: blocking: Lista blokiranja + bookmarks: Obeleživači + domain_blocking: Lista blokiranih domena following: Lista pratilaca + lists: Liste muting: Lista ućutkanih upload: Otpremi invites: @@ -242,10 +1379,11 @@ sr-Latn: '21600': 6 sati '3600': 1 sad '43200': 12 sati - '604800': 1 week + '604800': 1 nedelja '86400': 1 dan expires_in_prompt: Nikad generate: Generiši + invited_by: 'Pozvao Vas je:' max_uses: few: "%{count} korišćenja" one: 1 korišćenje @@ -255,107 +1393,493 @@ sr-Latn: table: expires_at: Ističe uses: Korišćenja - title: Pozovi ljude + title: Pozovite ljude lists: errors: - limit: Dostigli ste limit broja listi + limit: Dostigli ste maksimalni broj listâ + login_activities: + authentication_methods: + otp: aplikacija za dvofaktorsku autentifikaciju + password: lozinka + sign_in_token: imejl sigurnosni kod + webauthn: sigurnosni ključevi + description_html: Ukoliko primetite aktivnost koju ne prepoznajete, razmislite o tome da promenite svoju lozinku i uključite dvofaktorsku autentifikaciju. + empty: Istorija autentifikacije nije dostupna + failed_sign_in_html: Neuspešan pokušaj prijavljivanja putem %{method} sa %{ip} (%{browser}) + successful_sign_in_html: Uspešan pokušaj prijavljivanja putem %{method} sa %{ip} (%{browser}) + title: Istorija autentifikacije + mail_subscriptions: + unsubscribe: + action: Da, odjavi me + complete: Odjavljen + confirmation_html: Da li ste sigurni da želite da se odjavite od primanja %{type} za Mastodon na %{domain} na svoju e-poštu na %{email}? Uvek možete ponovo da se prijavite u svojim podešavanjima obaveštenja putem e-pošte. + emails: + notification_emails: + favourite: omiljene e-pošte za obaveštenja + follow: omiljene e-pošte za praćenja + follow_request: e-pošte za zahteve za praćenja + mention: e-pošte za obaveštenje pominjanja + reblog: e-pošte za obaveštenje podržavanja + resubscribe_html: Ako ste se greškom odjavili, možete ponovo da se prijavite u svojim podešavanjima obaveštenja putem e-pošte. + success_html: Više nećete dobijati %{type} za Mastodon na %{domain} na svoju e-poštu na %{email}. + title: Odjavi se media_attachments: validations: images_and_video: Ne može da se prikači video na status koji već ima slike + not_ready: Ne mogu se priložiti fajlovi koji još uvek nisu obrađeni. Pokušajte ponovo za koji trenutak! too_many: Ne može se prikačiti više od 4 fajla migrations: acct: korisnik@domen novog naloga + cancel: Otkaži preusmerenje + cancel_explanation: Otkazivanje preusmerenja će ponovo aktivirati Vaš sadašnji nalog, ali neće vratiti pratioce koji su premešteni na drugi nalog. + cancelled_msg: Uspešno je otkazano preusmerenje. + errors: + already_moved: već ste se preselili na isti nalog + missing_also_known_as: nije pseudonim ovog naloga + move_to_self: ne možete se preseliti na sadašnji nalog + not_found: nije bilo moguće pronaći nalog + on_cooldown: Pod ograničenjem ste + followers_count: Pratioci u trenutku premeštaja + incoming_migrations: Premeštanje iz drugog naloga + incoming_migrations_html: Da biste prešli sa drugog naloga na ovaj, prvo morate kreirate pseudonim naloga. + moved_msg: Vaš nalog sada preusmerava na %{acct} i Vaši pratioci se trenutno prebacuju. + not_redirecting: Vaš nalog trenutno ne preusmerava ni na jedan drugi nalog. + on_cooldown: Nedavno ste se preselili na novi nalog. Ova funkcija će Vam ponovo postati dostupna za %{count} dana. + past_migrations: Prethodne selidbe + proceed_with_move: Prebacite pratioce + redirected_msg: Vaš nalog sada preusmerava na %{acct}. + redirecting_to: Vaš nalog preusmerava na %{acct}. + set_redirect: Postavi preusmerenje + warning: + backreference_required: Novi nalog prvo mora biti konfigurisan tako da referiše na ovaj nalog + before: 'Pre nego što nastavite, molimo Vas pažljivo pročitajte sledeće napomene:' + cooldown: Nakon preseljenja potrebno je da prođe određeno vreme pre nego što ćete ponovo moći da se preselite + 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 + move_handler: + carry_blocks_over_text: Ovaj korisnik se preselio sa naloga %{acct}, koji ste blokirali. + carry_mutes_over_text: Ovaj korisnik se preselio sa naloga %{acct}, koji ste utišali. + copy_account_note_text: 'Ovaj korisnik se preselio sa naloga %{acct}, o kome ste zapisali sledeće beleške:' + navigation: + toggle_menu: Prikaži/sakrij meni notification_mailer: + admin: + report: + subject: "%{name} je podneo/-la prijavu" + sign_up: + subject: "%{name} se registrovao/-la" favourite: - body: "%{name} je postavio kao omiljen Vaš status:" - subject: "%{name} je postavio kao omiljen Vaš status" + body: "%{name} je označio kao omiljenu vašu objavu:" + subject: "%{name} je označio kao omiljenu vašu objavu" + title: Novi omiljeni follow: body: "%{name} Vas je zapratio!" subject: "%{name} Vas je zapratio" + title: Novi pratioc follow_request: + action: Upravljajte zahtevima za praćenje body: "%{name} je zatražio da Vas zaprati" subject: 'Pratioci na čekanju: %{name}' + title: Novi zahtev za praćenje mention: + action: Odgovori body: "%{name} Vas je pomenuo u:" subject: "%{name} Vas je pomenuo" + title: Novo spominjanje + poll: + subject: Anketa korisnika %{name} se završila reblog: - body: "%{name} Vam je podržao(la) status:" - subject: "%{name} je podržao(la) Vaš status" + body: "%{name} Vam je podržao/la status:" + subject: "%{name} je podržao/la Vaš status" + title: Nova podrška + status: + subject: "%{name} je upravo postavio/-la objavu" + update: + subject: "%{name} je izmenio/-la objavu" + notifications: + administration_emails: Obaveštenja e-poštom od administratora + email_events: Događaji za obaveštenja e-poštom + email_events_hint: 'Izaberite dešavanja za koja želite da primate obaveštenja:' + other_settings: Ostala podešavanja obaveštenja + number: + human: + decimal_units: + format: "%n %u" + units: + billion: mlrd. + million: mil. + quadrillion: tril. + thousand: hilj. + trillion: bil. + otp_authentication: + code_hint: Ukucajte kod generisan u Vašoj aplikaciji za autentifikaciju da biste potvrdili + description_html: Ako uključite dvofaktorsku autentifikaciju putem aplikacije za autentifikaciju, moraćete da budete pri telefonu prilikom prijavljivanja da biste imali pristup generisanim kodovima za prijavu. + enable: Omogući + instructions_html: "Skenirajte ovaj QR kod pomoću Google autentifikatora ili slične aplikacije na svom telefonu. Od sada pa ubuduće, ta aplikacija će generisati pristupne kodove koje ćete morati da unesete prilikom prijavljivanja." + manual_instructions: 'Ako ne možete da skenirate QR kod i morate da ga unesete ručno, evo njegove tekstualne šifre:' + setup: Instalacija + wrong_code: Uneseni kod je bio neispravan! Da li su vreme servera i vreme uređaja ispravni? pagination: - next: Sledeći + newer: Novije + next: Sledeće + older: Starije prev: Prethodni + truncate: "…" + polls: + errors: + already_voted: Već ste glasali u ovoj anketi + duplicate_options: sadrži duplikate + duration_too_long: previše je daleko u budućnosti + duration_too_short: previše je skoro + expired: Anketa je već završena + invalid_choice: Izabrana opcija ne postoji + over_character_limit: ne može biti duže od po %{max} karaktera + self_vote: Ne možete glasati u sopstvenim anketama + too_few_options: mora imati više od jedne opcije + too_many_options: ne može da sadrži više od %{max} opcija preferences: - other: Ostali - posting_defaults: Posting defaults - public_timelines: Public timelines + other: Ostalo + posting_defaults: Podrazumevana podešavanja objavljivanja + public_timelines: Javne vremenske linije + privacy: + hint_html: "Prilagodite način na koji želite da vaš profil i vaše objave budu pronađeni. Različite funkcije u Mastodon-u mogu vam pomoći da dosegnete širu publiku kada su omogućene. Odvojite malo vremena da pregledate ova podešavanja kako biste bili sigurni da odgovaraju vašem slučaju upotrebe." + privacy: Privatnost + privacy_hint_html: Kontrolišite koliko želite da otkrijete u korist drugih. Ljudi otkrivaju zanimljive profile i aplikacije tako što pregledaju pratioce drugih ljudi i vide iz kojih aplikacija objavljuju, ali možda ćete radije da to držite skrivenim. + reach: Doseg + reach_hint_html: Kontrolišite da li želite da vas otkrivaju i prate novi ljudi. Da li želite da se vaše objave pojavljuju na ekranu za istraživanje? Da li želite da vas drugi ljudi vide u svojim preporukama? Da li želite da automatski prihvatite sve nove pratioce ili da imate detaljnu kontrolu nad svakim od njih? + search: Pretraga + search_hint_html: Kontrolišite kako želite da budete pronađeni. Da li želite da vas ljudi pronađu po onome o čemu ste javno objavili? Da li želite da ljudi izvan Mastodon-a pronađu vaš profil kada pretražuju veb? Imajte na umu da se za javne informacije ne može garantovati potpuno isključenje iz svih pretraživača. + title: Privatnost i doseg + privacy_policy: + title: Politika privatnosti + reactions: + errors: + limit_reached: Dostignuto je ograničenje različitih reakcija + unrecognized_emoji: nije prepoznat emodži + relationships: + activity: Aktivnost naloga + confirm_follow_selected_followers: Da li ste sigurni da želite da pratite izabrane pratioce? + confirm_remove_selected_followers: Da li ste sigurni da želite da uklonite izabrane pratioce? + confirm_remove_selected_follows: Da li ste sigurni da želite da uklonite izabrana praćenja? + dormant: Neaktivan + follow_failure: Nije moguće pratiti neke od izabranih naloga. + follow_selected_followers: Prati izabrane pratioce + followers: Pratioci + following: Praćenja + invited: Pozvan + last_active: Poslednji put aktivan + most_recent: Najnoviji + moved: Premešten + mutual: Zajednički + primary: Primarni + relationship: Odnos + remove_selected_domains: Ukloni sve pratioce sa izabranih domena + remove_selected_followers: Ukloni izabrane pratioce + remove_selected_follows: Otprati izabrane korisnike + status: Status naloga remote_follow: missing_resource: Ne mogu da nađem zahtevanu adresu preusmeravanja za Vaš nalog + reports: + errors: + invalid_rules: ne referiše na legitimna pravila + rss: + content_warning: 'Upozorenje o sadržaju:' + descriptions: + account: Javne objave sa @%{acct} + tag: 'Javne objave označene sa #%{hashtag}' + scheduled_statuses: + over_daily_limit: Prekoračili ste granicu od %{limit} planiranih objava za danas + over_total_limit: Prekoračili ste granicu od %{limit} planiranih objava + too_soon: Planirani datum mora biti u budućnosti sessions: activity: Poslednja aktivnost browser: Veb čitač browsers: - chrome: Hrom + alipay: Alipej + blackberry: Blekberi + chrome: Chrome + edge: Majkrosoft Edž + electron: Elektron + firefox: Fajerfoks generic: Nepoznati veb čitač + huawei_browser: Huawei pregledač + ie: Internet Eksplorer + micro_messenger: MajkroMesendžer + nokia: Nokija S40 Ovi Pretraživač + opera: Opera + otter: Oter + phantom_js: FantomDžejEs + qq: KjuKju Pretraživač + safari: Safari + uc_browser: UC Browser + unknown_browser: Nepoznati pregledač + weibo: Veibo current_session: Trenutna sesija description: "%{browser} sa %{platform}" - explanation: Ovo su trenutno prijavljeni veb čitači na Vaš Mastodont nalog. + explanation: Ovo su veb pretraživači koji su trenutno prijavljeni na vaš Mastodon nalog. + ip: IP platforms: - adobe_air: Adobe Air-a + adobe_air: Adob Er-a android: Androida + blackberry: Blekberi + chrome_os: ChromeOS firefox_os: Fajerfoks OS-a + ios: iOS-a + kai_os: KaiOS linux: Linuksa - mac: Mac-a - other: nepoznate platforme - windows: Vindouza - windows_mobile: Vindouz mobilnog - windows_phone: Vindouz telefona + mac: Meka + unknown_platform: Nepoznata platforma + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone revoke: Opozovi revoke_success: Sesija uspešno opozvana title: Sesije + view_authentication_history: Pogledajte istoriju autentifikacije vašeg naloga settings: + account: Nalog + account_settings: Podešavanja naloga + aliases: Pseudonimi naloga + appearance: Izgled authorized_apps: Autorizovane aplikacije - back: Nazad na Mastodonta + back: Nazad na Mastodon delete: Brisanje naloga development: Razvoj - edit_profile: Izmena profila + edit_profile: Uređivanje profila export: Izvoz podataka + featured_tags: Istaknute heš oznake import: Uvoz + import_and_export: Uvoz i izvoz migrate: Prebacivanje naloga notifications: Obaveštenja preferences: Podešavanja + profile: Javni profil + relationships: Praćenja i pratioci + statuses_cleanup: Automatsko brisanje objava + strikes: Moderacijski prestupi two_factor_authentication: Dvofaktorska identifikacija + webauthn_authentication: Sigurnosni ključevi statuses: + attached: + audio: + few: "%{count} audio zapisa" + one: "%{count} audio zapis" + other: "%{count} audio zapisa" + description: 'U prilogu: %{attached}' + image: + few: "%{count} slika" + one: "%{count} sliku" + other: "%{count} slika" + video: + few: "%{count} video zapisa" + one: "%{count} video zapis" + other: "%{count} video zapisa" + boosted_from_html: Podržano od %{acct_link} + content_warning: 'Upozorenje na sadržaj: %{warning}' + default_language: Isto kao jezik okruženja + disallowed_hashtags: + few: 'sadrži zabranjene heš oznake: %{tags}' + one: 'sadrži zabranjenu heš oznaku: %{tags}' + other: 'sadrži zabranjene heš oznake: %{tags}' + edited_at_html: Izmenjeno %{date} + errors: + in_reply_not_found: Objava na koju pokušavate da odgovorite naizgled ne postoji. open_in_web: Otvori u vebu over_character_limit: ograničenje od %{max} karaktera prekoračeno pin_errors: - limit: Već imate prikačen najveći broj tutova - ownership: Tuđi tutovi ne mogu da se prikače + direct: Objave koje su vidljive samo pomenutim korisnicima ne mogu biti prikačene + limit: Već ste zakačili maksimalan broj objava + ownership: Tuđa objava se ne može zakačiti reblog: Podrška ne može da se prikači + poll: + total_people: + few: "%{count} osobe" + one: "%{count} osoba" + other: "%{count} ljudi" + total_votes: + few: "%{count} glasa" + one: "%{count} glas" + other: "%{count} glasova" + vote: Glasajte show_more: Prikaži još + show_newer: Nikad ne prikazuj + show_older: Prikaži starije + show_thread: Prikaži niz + title: "%{name}: „%{quote}”" visibilities: + direct: Direktno private: Samo pratioci - private_long: Samo prikaži pratiocima + private_long: Prikaži samo pratiocima public: Javno public_long: Svako može da vidi unlisted: Neizlistano - unlisted_long: Svako može da vidi, ali nije izlistano na javnim lajnama + unlisted_long: Svako može da vidi, ali nije izlistano na javnim vremenskim linijama + statuses_cleanup: + enabled: Automatski izbriši stare objave + enabled_hint: Automatski briše vaše objave kada dostignu određeni starosni prag, osim ako se ne podudaraju sa jednim od izuzetaka u nastavku + exceptions: Izuzeci + explanation: Pošto je brisanje objava skupa operacija, ovo se radi polako tokom vremena kada server inače nije zauzet. Iz tog razloga, vaše objave mogu biti izbrisane neko vreme nakon što dostignu starosni prag. + ignore_favs: Ignoriši omiljene + ignore_reblogs: Ignoriši podržavanja + interaction_exceptions: Izuzeci zasnovani na interakcijama + interaction_exceptions_explanation: Imajte na umu da ne postoji garancija da će objave biti izbrisane ako broj označavanja kao omiljenih ili broj podržavanja padne ispod praga nakon što ga premaše. + keep_direct: Zadrži direktne poruke + keep_direct_hint: Ne briše nijednu od vaših direktnih poruka + keep_media: Zadrži objave sa medijskim prilozima + keep_media_hint: Ne briše nijednu od vaših objava koje imaju medijske priloge + keep_pinned: Zadrži zakačene objave + keep_pinned_hint: Ne briše nijednu od vaših zakačenih objava + keep_polls: Zadrži ankete + keep_polls_hint: Ne briše nijednu od vaših anketa + keep_self_bookmark: Zadrži objave koje ste dodali u obeleživače + keep_self_bookmark_hint: Ne briše vaše sopstvene objave ako ste ih dodlai u obeleživače + keep_self_fav: Zadrži omiljene objave + keep_self_fav_hint: Ne briše vaše sopstvene objave ako ste ih označili kao omiljene + min_age: + '1209600': 2 sedmice + '15778476': 6 meseci + '2629746': 1 mesec + '31556952': 1 godina + '5259492': 2 meseca + '604800': 1 sedmica + '63113904': 2 godine + '7889238': 3 meseca + min_age_label: Starosni prag + min_favs: Zadrži objave označene kao omiljene najmanje + min_favs_hint: Ne briše nijednu vašu objavu koja je dobila najmanje ovaj broj omiljenih. Ostavite prazno za brisanje objava bez obzira na njihov broj omiljenih + min_reblogs: Zadrži objave podržane barem + min_reblogs_hint: Ne briše nijednu vašu objavu koja je bila podržana najmanje ovoliko puta. Ostavite prazno za brisanje objava bez obzira na njihov broj podržavanja stream_entries: - pinned: Prikačeni tut - reblogged: podržano sensitive_content: Osetljiv sadržaj + strikes: + errors: + too_late: Istekao je rok za podnošenje žalbe na zabeležen prestup + tags: + does_not_match_previous_name: ne poklapa se sa prethodnim imenom themes: - default: Mastodont + contrast: Veliki kontrast + default: Mastodon (tamno) + mastodon-light: Mastodon (svetlo) + time: + formats: + default: "%d %b %Y, %H:%M" + month: "%b %Y" + time: "%H:%M" + with_time_zone: "%d. %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Prekoračena je kvota korišćenja usluge prevođenja na celom serveru. + too_many_requests: Nedavno je bilo previše zahteva za uslugu prevođenja. two_factor_authentication: + add: Dodaj disable: Isključi + disabled_success: Dvofaktorska autentifikacija je uspešno onemogućena + edit: Izmeni enabled: Dvofaktorska identifikacija je uključena enabled_success: Dvofaktorska identifikacija je uspešno uključena generate_recovery_codes: Generiši kodove za oporavak - lost_recovery_codes: Kodovi za oporavak Vam omogućavaju da povratite pristup nalogu ako izgubite telefon. Ako izgubite kodove za oporavak, možete ih regenerisati ovde. Od tog trenutka, stari kodovi za oporavak više ne važe. + lost_recovery_codes: Kodovi za oporavak Vam omogućavaju da povratite pristup nalogu ako izgubite telefon. Ako izgubite kodove za oporavak, možete ih re-generisati ovde. Od tog trenutka, stari kodovi za oporavak više ne važe. + methods: Metode dvofaktorske autentifikacije + otp: Aplikacija za autentifikaciju recovery_codes: Napravite rezervu kodova za oporavak - recovery_codes_regenerated: Kodovi za oporavak uspešno regenerisani + recovery_codes_regenerated: Kodovi za oporavak uspešno re-generisani recovery_instructions_html: Ako ikada izgubite pristup telefonu, možete iskoristiti kodove za oporavak date ispod da povratite pristup nalogu. Držite kodove za oporavak na sigurnom. Na primer, odštampajte ih i čuvajte ih sa ostalim važnim dokumentima. + webauthn: Sigurnosni ključevi + user_mailer: + appeal_approved: + action: Idite na svoj nalog + explanation: Žalba podneta datuma %{appeal_date} na upisan prestup na Vaše ime datuma %{strike_date} je uvažena. Vaš nalog je ponovo u povoljnom položaju. + subject: Vaša žalba podneta %{date} je uvažena + title: Žalba uvažena + appeal_rejected: + explanation: Žalba podneta datuma %{appeal_date} na upisan prestup na Vaše ime datuma %{strike_date} je odbijena. + subject: Vaša žalba podneta %{date} je odbijena + title: Žalba odbijena + backup_ready: + explanation: Tražili ste potpunu rezervnu kopiju vašeg Mastodon naloga. Spremna je za preuzimanje! + subject: Vaša arhiva je spremna za preuzimanje + title: Izvoz arhive + suspicious_sign_in: + change_password: promenite svoju lozinku + details: 'Evo detalja o prijavi:' + explanation: Primetili smo prijavu na Vaš nalog sa nepoznate IP adrese. + further_actions_html: Ukoliko to niste bili Vi, preporučujemo da odmah %{action} i uključite dvofaktorsku autentifikaciju da biste održali bezbednost svog naloga. + subject: Vašem nalogu je pristupljeno sa nepozate IP adrese + title: Novo prijavljivanje + warning: + appeal: Priložite žalbu + appeal_description: Ukoliko verujete da je u pitanju greška, možete priložiti žalbu osoblju %{instance}. + categories: + spam: Neželjena pošta + violation: Sadržaj krši sledeća pravila zajednice + explanation: + delete_statuses: Za neke od Vaših objava je ustanovljeno da krše jedno ili više pravila zajednice i usled toga su uklonjene od strane moderatora %{instance}. + disable: Više ne možete da koristite svoj nalog, ali Vaš profil i drugi podaci ostaju netaknuti. Možete da zatražite rezervnu kopiju svojih podataka, promenite podešavanja naloga ili obrišete svoj nalog. + mark_statuses_as_sensitive: Neke od Vaših objava su označene kao osetljive od strane moderatora %{instance}. Ovo znači da će ljudi morati da kliknu na multimedije u objavama pre nego što mogu da ih vide. Ubuduće možete sami da označite svoju multimediju kao osetljivu prilikom sastavljanja objave. + sensitive: Od sada će svi Vaši otpremljeni multimedijalni fajlovi biti označeni kao osetljivi i sakriveni iza tastera upozorenja. + silence: I dalje možete koristiti svoj nalog ali samo ljudi koji Vas već prate će videti Vaše objave na ovom serveru, i možda ćete biti isključeni iz raznih mehanizama otkrivanja. Međutim, drugi ljudi i dalje mogu ručno da Vas zaprate. + suspend: Više ne možete da koristite svoj nalog, i Vaš profil i ostali podaci Vam više nisu dostupni. I dalje možete da se prijavite da biste zatražili rezervnu kopiju svojih podataka sve dok se Vaši podaci trajno ne izbrišu za oko 30 dana, s tim što ćemo zadržati neke osnovne podatke da bismo Vas sprečili u eventualnom zaobilaženju suspenzije. + reason: 'Obrazloženje:' + statuses: 'Citirane objave:' + subject: + delete_statuses: Vaše objave sa %{acct} su izbrisane + disable: Vaš nalog %{acct} je zamrznut + mark_statuses_as_sensitive: Vaše objave sa %{acct} su obeležene kao osetljive + none: Upozorenje za %{acct} + sensitive: Vaše objave sa %{acct} će ubuduće biti označene kao osetljive + silence: Vaš nalog %{acct} je ograničen + suspend: Vaš nalog %{acct} je suspendovan + title: + delete_statuses: Objave su obrisane + disable: Nalog zamrznut + mark_statuses_as_sensitive: Objave su označene kao osetljive + none: Upozorenje + sensitive: Nalog je označen kao osetljiv + silence: Nalog ograničen + suspend: Nalog suspendovan + welcome: + edit_profile_action: Podesi nalog + edit_profile_step: Možete prilagoditi svoj profil tako što ćete postaviti profilnu sliku, promeniti ime za prikaz i tako dalje. Možete dati saglasnost da pregledate nove pratioce pre nego što im dozvolite da Vas zaprate. + explanation: Evo nekoliko saveta za početak + final_action: Počnite objavljivati + final_step: 'Počnite da objavljujete! Čak i bez pratilaca, Vaše javne objave su vidljive drugim ljudima, na primer na lokalnoj vremenskoj liniji ili u heš oznakama. Možda želite da se predstavite sa heš oznakom #introductions ili #predstavljanja.' + full_handle: Vaš pun nadimak + full_handle_hint: Ovo biste rekli svojim prijateljima kako bi vam oni poslali poruku, ili zapratili sa druge instance. + subject: Dobrodošli na Mastodon + title: Dobrodošli, %{name}! users: + follow_limit_reached: Ne možete pratiti više od %{limit} ljudi + go_to_sso_account_settings: Idite na podešavanja naloga svog dobavljača identiteta invalid_otp_token: Neispravni dvofaktorski kod - signed_in_as: 'Prijavljen kao:' + otp_lost_help_html: Ako izgubite pristup za oba, možete stupiti u kontakt sa %{email} + seamless_external_login: Prijavljeni ste putem spoljašnje usluge, tako da lozinka i podešavanja E-pošte nisu dostupni. + signed_in_as: 'Prijavljen/a kao:' + verification: + extra_instructions_html: Savet:Veza na vašem veb sajtu može da bude nevidljiva. Važan deo je rel="me" koji sprečava lažno predstavljanje na veb sajtovima sa sadržajem koji generiše korisnik. Možete čak da koristite oznaku veze u zaglavlju stranice umesto a, ali HTML mora biti dostupan bez izvršavanja JavaScript-a. + here_is_how: Evo kako + hint_html: "Verifikacija vašeg identiteta na Mastodon-u je za svakoga. Zasnovano na otvorenim veb standardima, sada i zauvek besplatno. Sve što vam treba je lični veb sajt po kome vas ljudi prepoznaju. Kada se povežete sa ovim veb sajtom sa svog profila, proverićemo da li je veb sajt povezan sa vašim profilom i na njemu ćemo prikazati vizuelni indikator." + instructions_html: Kopirajte i nalepite kod ispod u HTML svog veb sajta. Zatim dodajte adresu svog veb sajta u jedno od dodatnih polja na svom profilu sa kartice „Uredi profil” i sačuvajte promene. + verification: Verifikacija + verified_links: Vaše verifikovane veze + webauthn_credentials: + add: Dodajte novi sigurnosni ključ + create: + error: Iskrsao je problem prilikom dodavanja Vašeg sigurnosnog ključa. Molimo Vas pokušajte ponovo. + success: Vaš sigurnosni ključ je uspešno dodat. + delete: Izbriši + delete_confirmation: Da li ste sigurni da želite da izbrišete ovaj sigurnosni ključ? + description_html: Ako uključite autentifikaciju sigurnosnim ključem, moraćete da koristite jedan od svojih sigurnosnih ključeva prilikom prijavljivanja. + destroy: + error: Iskrsao je problem prilikom brisanja Vašeg sigurnosnog ključa. Molimo Vas pokušajte ponovo. + success: Vaš sigurnosni ključ je uspešno obrisan. + invalid_credential: Neispravan sigurnosni ključ + nickname_hint: Unesite nadimak svog novog sigurnosnog ključa + not_enabled: Još uvek niste omogućili WebAuthn + not_supported: Ovaj pretraživač ne podržava sigurnosne ključeve + otp_required: Da biste koristili sigurnosne ključeve, molimo Vas prvo uključite dvofaktorsku autentifikaciju. + registered_on: Registrovan/-a %{date} diff --git a/config/locales/sr.rb b/config/locales/sr.rb deleted file mode 100644 index 86b89a07e1..0000000000 --- a/config/locales/sr.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'rails_i18n/common_pluralizations/romanian' - -::RailsI18n::Pluralization::Romanian.with_locale(:sr) diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 656b6f7638..ffddab8697 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -1,23 +1,24 @@ --- sr: about: - about_mastodon_html: Мастодон је друштвена мрежа базирана на отвореним протоколима и слободном софтверу отвореног кода. Децентрализована је као што је децентрализована е-пошта. + about_mastodon_html: 'Друштвена мрежа будућности: без реклама, без корпоративног праћења, етички дизајн, и децентрализација! Поседујте своје податке са Mastodon-ом!' contact_missing: Није постављено contact_unavailable: Није доступно - hosted_on: Мастодон хостован на %{domain} - title: О + hosted_on: Mastodon хостован на %{domain} + title: О инстанци accounts: - follow: Прати + follow: Запрати followers: - few: Пратиоци - one: Пратиоц - other: Пратиоци + few: Пратиоца + one: Пратилац + other: Пратилаца following: Пратим - last_active: последњи пут активни + instance_actor_flash: Овај налог је виртуелни актер који не представља ниједног корисника лично, већ сâм сервер. Користи се у сврху федерације и не треба га суспендовати. + last_active: најскорија активност link_verified_on: Власништво над овом везом је проверено %{date} - nothing_here: Овде нема ништа! + nothing_here: Овде нема ничега! pin_errors: - following: Морате пратити ову особу ако хоћете да потврдите + following: Морате пратити особу коју желите да препоручите posts: few: Објаве one: Објава @@ -34,16 +35,17 @@ sr: accounts: add_email_domain_block: Блокирај домен е-поште approve: Одобри + approved_msg: Захтев за регистрацију корисника %{username} је успешно одобрен are_you_sure: Да ли сте сигурни? avatar: Аватар by_domain: Домен change_email: changed_msg: Е-пошта налога успешно промењена! - current_email: Тренутна е-пошта - label: Промените е-пошту - new_email: Нова e-пошта - submit: Промените e-пошту - title: Промените e-пошту за %{username} + current_email: Тренутна адреса е-поште + label: Промените адресу е-поште + new_email: Нова адреса e-поште + submit: Промените адресу e-поште + title: Промените адресу e-поште за %{username} change_role: changed_msg: Улога успешно промењена! label: Промени улогу @@ -51,21 +53,25 @@ sr: title: Промени улогу за %{username} confirm: Потврди confirmed: Потврђено - confirming: Потврдување + confirming: Потврђивање custom: Произвољно delete: Обриши податке deleted: Избрисано demote: Ражалуј - disable: Искључи + destroyed_msg: Подаци корисника %{username} су неповратно стављени у ред за брисање + disable: Замрзни + disable_sign_in_token_auth: Онемогући имејл аутентификацију disable_two_factor_authentication: Искључи 2FA - disabled: Искључена - display_name: Приказано име + disabled: Замрзнут + display_name: Име за приказ domain: Домен edit: Измени email: Е-пошта email_status: Статус е-поште enable: Омогући - enabled: Укључено + enable_sign_in_token_auth: Омогући имејл аутентификацију + enabled: Омогућен + enabled_msg: Успешно одлеђен налог корисника %{username} followers: Пратиоци follows: Праћени header: Заглавље @@ -73,18 +79,21 @@ sr: invite_request_text: Разлози за придруживање invited_by: Позван од стране ip: IP - joined: Придружио се + joined: Придружио/-ла се location: all: Све - local: Локалне - remote: Удаљене + local: Локални + remote: Удаљени title: Локација login_status: Статус пријаве media_attachments: Мултимедијални прилози memorialize: Пребаци у in memoriam + memorialized: Подигнут споменик + memorialized_msg: "%{username} је успешно претворен у меморијални налог" moderation: active: Активан all: Сви + disabled: Искључен pending: На чекању silenced: Ограничено suspended: Суспендовани @@ -92,75 +101,202 @@ sr: moderation_notes: Модераторске белешке most_recent_activity: Најскорија активност most_recent_ip: Најскорија IP адреса + no_account_selected: Ниједан налог није промењен јер ниједан није изабран no_limits_imposed: Нема ограничења no_role_assigned: Ниједна улога није додељена not_subscribed: Није претплаћен pending: Чека на преглед - perform_full_suspension: Искључи + perform_full_suspension: Суспендуј + previous_strikes: Претходни прекршаји + previous_strikes_description_html: + few: Овај налог има %{count} прекршаја. + one: Овај налог има један прекршај. + other: Овај налог има %{count} прекршаја. promote: Унапреди protocol: Протокол public: Јавно push_subscription_expires: PuSH претплата истиче - redownload: Освежи налог - reject: Одбаци + redownload: Освежи профил + redownloaded_msg: Успешно освежен профил корисника %{username} из извора + reject: Одбиј + rejected_msg: Захтев за регистрацију корисника %{username} је успешно одбијен + remote_suspension_irreversible: Подаци овог налога су неповратно избрисани. + remote_suspension_reversible_hint_html: Налог је суспендован са свог сервера и његови подаци ће бити избрисани датума %{date}. До тада, удаљени сервер може да врати овај налог без икаквих промена. Уколико желите да одмах обришете све податке налога, можете то учинити испод. remove_avatar: Уклони аватар remove_header: Одстрани заглавље + removed_avatar_msg: Слика аватара корисника %{username} је успешно уклоњена + removed_header_msg: Успешно обрисана слика заглавља корисника %{username} resend_confirmation: - already_confirmed: Овој корисник е веќе потврден - send: Препрати го е-мајлот за потврда - success: Е-пошта за потврда успешно испратена! + already_confirmed: Овај корисник је већ потврђен + send: Поново пошаљи везу за потврду + success: Веза за потврду је успешно послата! reset: Ресетуј reset_password: Ресетуј лозинку resubscribe: Поново се претплати role: Улога search: Претрага + search_same_email_domain: Остали корисници са истим доменом е-поште + search_same_ip: Остали корисници са истом IP адресом + security: Безбедност security_measures: only_password: Само лозинка + password_and_2fa: Лозинка и двофакторска аутентификација + sensitive: Означи као осетљив sensitized: Означено као осетљиво shared_inbox_url: Адреса дељеног сандучета show: - created_reports: Направљени извештаји + created_reports: Поднете пријаве targeted_reports: Пријаве од стране других silence: Ућуткај silenced: Ућуткан - statuses: Статуси + statuses: Објаве + strikes: Претходни преступи subscribe: Претплати се suspend: Суспендуј suspended: Суспендовани + suspension_irreversible: Подаци овог налога су неповратно избрисани. Можете одсуспендовати овај налог чиме ће он постати употребљив, али се подаци претходно садржани на налогу неће вратити. + suspension_reversible_hint_html: Налог је суспендован и његови подаци ће бити избрисани датума %{date}. До тада, овај налог може бити враћен без икаквих промена. Уколико желите да одмах обришете све податке налога, можете то учинити испод. title: Налози unblock_email: Одблокирај адресу е-поште - unconfirmed_email: Непотврђена е-пошта + unblocked_email_msg: Успешно одблокирана имејл адреса корисника %{username} + unconfirmed_email: Непотврђена адреса е-поште + undo_sensitized: Уклони ознаку „осетљив” undo_silenced: Укини ћутање undo_suspension: Укини суспензију + unsilenced_msg: Успешно поништено ограничење налога %{username} unsubscribe: Укини претплату + unsuspended_msg: Успешно поништена суспензија налога %{username} username: Корисничко име + view_domain: Прочитај опис домена warn: Упозори web: Веб + whitelisted: Дозвољена федерација action_logs: action_types: + approve_appeal: Уважи жалбу approve_user: Одобри корисника + assigned_to_self_report: Додели пријаву change_email_user: Промени e-адресу корисника change_role_user: Промени улогу корисника confirm_user: Потврди корисника create_account_warning: Креирај упозорење create_announcement: Креирај најаву create_canonical_email_block: Креирај блок е-поште + create_custom_emoji: Направи прилагођени емоџи + create_domain_allow: Додај дозвољени домен + create_domain_block: Додај блокирани домен + create_email_domain_block: Блокирај имејл домен + create_ip_block: Направи IP услов + create_unavailable_domain: Додај домен као недоступан create_user_role: Креирај улогу + demote_user: Смањи овлашћења корисника destroy_announcement: Избриши најаву destroy_canonical_email_block: Избриши блок е-поште + destroy_custom_emoji: Обриши прилагођени емоџи + destroy_domain_allow: Обриши дозвољени домен + destroy_domain_block: Обриши блокирани домен + destroy_email_domain_block: Избриши блок е-поште + destroy_instance: Очисти домен + destroy_ip_block: Обриши IP услов destroy_status: Избриши пост + destroy_unavailable_domain: Обриши недоступан домен + destroy_user_role: Уништи позицију + disable_2fa_user: Онемогући двофакторску аутентификацију + disable_custom_emoji: Онемогући прилагођене емоџије + disable_sign_in_token_auth_user: Онемогући имејл аутентификацију за корисника disable_user: Онемогући корисника + enable_custom_emoji: Омогући прилагођене емоџије + enable_sign_in_token_auth_user: Омогући имејл аутентификацију за корисника enable_user: Омогући корисника + memorialize_account: Претвори у меморијални налог + promote_user: Унапреди корисника + reject_appeal: Одбиј жалбу reject_user: Одбаци корисника + remove_avatar_user: Уклони аватар + reopen_report: Поново отвори пријаву + resend_user: Поново пошаљи мејл за потврду + reset_password_user: Ресетуј лозинку + resolve_report: Затвори пријаву + sensitive_account: Означи налог као осетљив silence_account: Ограничи налог suspend_account: Обустави налог + unassigned_report: Повуци пријаву + unblock_email_account: Одблокирај имејл адресу + unsensitive_account: Уклони додељену ознаку „осетљив” + unsilence_account: Повуци ограничење налога + unsuspend_account: Повуци суспензију налога + update_announcement: Саопштење о ажурирању + update_custom_emoji: Ажурирај прилагођене емоџије + update_domain_block: Ажурирај домен блок + update_ip_block: Ажурирај IP услов update_status: Уреди објаву update_user_role: Уреди улогу + actions: + approve_appeal_html: "%{name} је уважио жалбу корисника %{target} на одлуку модератора" + approve_user_html: "%{name} је одобрио/-ла регистрацију корисника %{target}" + assigned_to_self_report_html: "%{name} је себи доделио/-ла пријаву %{target}" + change_email_user_html: "%{name} је променио/-ла имејл адресу корисника %{target}" + change_role_user_html: "%{name} је променио/-ла овлашћења корисника %{target}" + confirm_user_html: "%{name} је потврдио/-ла имејл адресу корисника %{target}" + create_account_warning_html: "%{name} је послао/-ла упозорење кориснику %{target}" + create_announcement_html: "%{name} је направио/-ла ново саопштење %{target}" + create_canonical_email_block_html: "%{name} је блокирао/-ла имејл адресу са хешом %{target}" + create_custom_emoji_html: "%{name} је отпремио/-ла нове емоџије %{target}" + create_domain_allow_html: "%{name} је дозволио/-ла федерацију са доменом %{target}" + create_domain_block_html: "%{name} је блокирао/-ла домен %{target}" + create_email_domain_block_html: "%{name} је блокирао/-ла имејл домен %{target}" + create_ip_block_html: "%{name} је направио/-ла услов за IP адресе %{target}" + create_unavailable_domain_html: "%{name} је обуставио/-ла испоручивање домену %{target}" + create_user_role_html: "%{name} је направио/-ла %{target} позицију" + demote_user_html: "%{name} је смањио овлашћења корисника %{target}" + destroy_announcement_html: "%{name} је обрисао/-ла саопштење %{target}" + destroy_canonical_email_block_html: "%{name} је одблокирао/-ла имејл адресу са хешом %{target}" + destroy_custom_emoji_html: "%{name} је обрисао/-ла емоџи %{target}" + destroy_domain_allow_html: "%{name} је забранио/-ла федерацију са доменом %{target}" + destroy_domain_block_html: "%{name} је одблокирао/-ла домен %{target}" + destroy_email_domain_block_html: "%{name} је одблокирао/-ла имејл домен %{target}" + destroy_instance_html: "%{name} је очистио/-ла домен %{target}" + destroy_ip_block_html: "%{name} је обрисао/-ла услов за IP адресе %{target}" + destroy_status_html: "%{name} је избрисао/-ла објаву корисника %{target}" + destroy_unavailable_domain_html: "%{name} је поново успоставио/-ла испоручивање домену %{target}" + destroy_user_role_html: "%{name} је избрисао/-ла %{target} позицију" + disable_2fa_user_html: "%{name} је онемогућио/-ла двофакторску аутентификацију за корисника %{target}" + disable_custom_emoji_html: "%{name} је онемогућио/-ла емоџи %{target}" + disable_sign_in_token_auth_user_html: "%{name} је онемогућио/-ла имејл аутентификацију за корисника %{target}" + disable_user_html: "%{name} је онемогућио/-ла пријављивање за корисника %{target}" + enable_custom_emoji_html: "%{name} је омогућио/-ла емоџи %{target}" + enable_sign_in_token_auth_user_html: "%{name} је омогућио/-ла имејл аутентификацију за %{target}" + enable_user_html: "%{name} је омогућио/-ла пријављивање кориснику %{target}" + memorialize_account_html: "%{name} је претворио/-ла налог корисника %{target} у меморијалну страницу" + promote_user_html: "%{name} је унапредио/-ла корисника %{target}" + reject_appeal_html: "%{name} је одбио/-ла жалбу на модерацијску одлуку коју је приложио корисник %{target}" + reject_user_html: "%{name} је одбио/-ла регистрацију корисника %{target}" + remove_avatar_user_html: "%{name} је уклонио аватар корисника %{target}" + reopen_report_html: "%{name} је поново отворио/-ла пријаву %{target}" + resend_user_html: "%{name} је поново послао/-ла имејл за потврду кориснику %{target}" + reset_password_user_html: "%{name} је ресетовао/-ла лозинку корисника %{target}" + resolve_report_html: "%{name} је решио/-ла пријаву %{target}" + sensitive_account_html: "%{name} је означио/-ла медије налога %{target} као осетљиве" + silence_account_html: "%{name} је ограничио/-ла налог %{target}" + suspend_account_html: "%{name} је суспендовао/-ла налог %{target}" + unassigned_report_html: "%{name} је повукао/-ла доделу пријаве %{target}" + unblock_email_account_html: "%{name} је одблокирао/-ла имејл адресу корисника %{target}" + unsensitive_account_html: "%{name} је уклонио/-ла ознаку „осетљиво” са медија налога %{target}" + unsilence_account_html: "%{name} је повукао/-ла ограничење налога %{target}" + unsuspend_account_html: "%{name} је повукао/-ла суспензију налога %{target}" + update_announcement_html: "%{name} је ажурирао/-ла саопштење %{target}" + update_custom_emoji_html: "%{name} је ажурирао/-ла емоџи %{target}" + update_domain_block_html: "%{name} је ажурирао/-ла блок домена %{target}" + update_ip_block_html: "%{name} је променио/-ла IP услов за %{target}" + update_status_html: "%{name} је ажурирао/-ла објаву корисника %{target}" + update_user_role_html: "%{name} је променио/-ла позицију %{target}" deleted_account: обрисан налог + empty: Није пронађен ниједан лог. filter_by_action: Филтрирај по активности filter_by_user: Филтрирај по кориснику title: Записник announcements: + destroyed_msg: Саопштење је успешно обрисано! edit: title: Уреди најаву empty: Ниједна најава није пронађена. @@ -170,7 +306,13 @@ sr: title: Нова најава publish: Објави published_msg: Најава успешно објављена! + scheduled_for: Заказано за %{time} + scheduled_msg: Саопштење је заказано за објављивање! title: Најаве + unpublish: Повуци објаву + unpublished_msg: Објава саопштења је успешно повучена! + updated_msg: Саопштење је успешно ажурирано! + critical_update_pending: Критично ажурирање је на чекању custom_emojis: assign_category: Додели категорију by_domain: Домен @@ -188,82 +330,221 @@ sr: enable: Омогући enabled: Омогућено enabled_msg: Емоџи успешно омогућен + image_hint: PNG или GIF фајл величине до %{size} + list: Листа listed: Излистан new: title: Додај нови произвољни емоџи + no_emoji_selected: Ниједан емоџи није промењен јер ниједан није изабран + not_permitted: Нисте овлашћени да обављате ову радњу overwrite: Препиши shortcode: Пречица shortcode_hint: Најмање 2 карактера, дозвољени су само слова, бројеви и доње црте title: Произвољни емотиџији + uncategorized: Некатегоризовано + unlist: Неизлистан unlisted: Неизлистан update_failed_msg: Не могу да ажурирам овај емоџи updated_msg: Емоџи успешно ажуриран! upload: Отпреми dashboard: + active_users: активни корисници + interactions: интеракције + media_storage: Мултимедијално складиште + new_users: нови корисници + opened_reports: отворене пријаве + pending_appeals_html: + few: "%{count} жалбе на чекању" + one: "%{count} жалба на чекању" + other: "%{count} жалби на чекању" + pending_reports_html: + few: "%{count} пријаве на чекању" + one: "%{count} пријава на чекању" + other: "%{count} пријава на чекању" + pending_tags_html: + few: "%{count} хеш ознаке на чекању" + one: "%{count} хеш ознака на чекању" + other: "%{count} хеш ознака на чекању" + pending_users_html: + few: "%{count} корисника на чекању" + one: "%{count} корисник на чекању" + other: "%{count} корисника на чекању" + resolved_reports: решене пријаве software: Софтвер + sources: Извори регистрација space: Коришћење простора title: Командна табла + top_languages: Најзаступљенији језици + top_servers: Најактивнији сервери + website: Вебсајт + disputes: + appeals: + empty: Ниједна жалба није пронађена. + title: Жалбе domain_allows: + add_new: Дозволи федерацију са доменом + created_msg: Домен је успешно одобрен за федерацију + destroyed_msg: Домен је одбијен за федерацију export: Извоз import: Увоз + undo: Забрани федерацију са доменом domain_blocks: add_new: Додај нови блок домена + confirm_suspension: + cancel: Откажи + confirm: Обустави + permanent_action: Поништавање обуставе неће вратити никакве податке или однос. + preamble_html: Обуставићете %{domain} и његове поддомене. + remove_all_data: Ово ће уклонити сав садржај, медије и податке профила за налоге овог домена са вашег сервера. + stop_communication: Ваш сервер ће престати да комуницира са овим серверима. + title: Потврди блокирање домена за %{domain} + undo_relationships: Ово ће поништити сваки однос праћења између налога ових сервера и вашег. created_msg: Блокирање домена се обрађује destroyed_msg: Блокирање домена је опозвано domain: Домен + edit: Измени блок домена + existing_domain_block: Већ сте успоставили строжа ограничења према кориснику %{name}. + existing_domain_block_html: Већ сте успоставили строжа ограничења према %{name}, потребно је да га прво одблокирате. export: Извоз import: Увоз new: create: Направи блокаду hint: Блокирање домена неће спречити прављење налога у бази, али ће ретроактивно и аутоматски применити одређене модераторске методе над тим налозима. severity: + desc_html: "Ограничење ће сакрити објаве налога са овог домена од сваког ко их не прати. Суспензија ће обрисати сав садржај, медије и податке профила са налога овог домена са Вашег сервера. Користите Ништа уколико само желите да одбијете медијске фајлове." noop: Ништа + silence: Ограничи suspend: Суспензија title: Ново блокирање домена + no_domain_block_selected: Ниједан блок домена није промењен јер ниједан није изабран + not_permitted: Нисте овлашћени да обављате ову радњу + obfuscate: Сакриј име домена + obfuscate_hint: Делимично сакриј име домена на листи ако је рекламирање листе ограничених домена омогућено private_comment: Приватни коментар + private_comment_hint: Коментар о ограничењу овог домена за интерну употребу од стране модератора. public_comment: Јавни коментар + public_comment_hint: Коментар о ограничењу овог домена за јавност, уколико је рекламирање листе ограничених домена омогућено. reject_media: Одбаци мултимедију reject_media_hint: Уклања локално ускладиштене мултимедијске фајлове и одбија да их скида убудуће. Небитно је за суспензију reject_reports: Одбаци извештај reject_reports_hint: Игнориши све извештаје који долазе са овог домена. Небитно је за суспензије undo: Поништи блок домена + view: Прочитај блок домена email_domain_blocks: add_new: Додај нови + attempts_over_week: + few: "%{count} покушаја током претходне недеље" + one: "%{count} покушај током претходне недеље" + other: "%{count} покушаја регистрације током претходне недеље" created_msg: Успешно додао домен Е-поште на црну листу delete: Обриши + dns: + types: + mx: MX извештај domain: Домен new: create: Додај домен + resolve: Претвори домен title: Нова ставка е-поштe у црној листи + no_email_domain_block_selected: Ниједан блок имејл домена није промењен јер ниједан није изабран + not_permitted: Није дозвољено + resolved_dns_records_hint_html: Име домена се претвара у следеће MX домене, који су напослетку одговорни за прихватање електронске поште. Блокирање MX домена ће блокирати регистрације са сваке имејл адресе која користи тај MX домен, чак и у случају када се видљиво име домена разликује. Водите рачуна о томе да не блокирате велике имејл провајдере. + resolved_through_html: Преусмерено кроз %{domain} title: Црна листа E-поште + export_domain_allows: + new: + title: Увези дозвољене домене + no_file: Ниједан фајл није одабран + export_domain_blocks: + import: + description_html: Управо ћете увести листу блокираних домена. Молимо Вас, врло пажљиво прегледајте ову листу, посебно уколико је нисте сами направили. + existing_relationships_warning: Постојећи односи у облику праћења + private_comment_description_html: 'Да би Вам помогли да пратите одакле су блокови увезени, увезени блокови ће бити направљени са следећим приватним коментаром: %{comment}' + private_comment_template: Увезено са извора %{source} на датум %{date} + title: Увези блокиране домене + invalid_domain_block: 'Један или више блокова домена је прескочен због следеће грешке тј. грешака: %{error}' + new: + title: Увези блокиране домене + no_file: Ниједан фајл није одабран follow_recommendations: + description_html: "Предлози за праћење помажу новим корисницима да брзо пронађу занимљив садржај. Када корисник није довољно комуницирао са другима да би се за њега формирали персонализовани предлози за праћење, ови налози ће бити препоручени уместо тога. Они се генеришу на дневној бази из скупа налога са највише недавних ангажовања и највише локалних пратилаца за један језик." + language: За језик status: Статус + suppress: Потисни препоруке за праћење + suppressed: Потиснуто + title: Препоруке за праћење + unsuppress: Врати препоруку за праћење instances: + availability: + description_html: + few: Уколико испорука домену не успе ниједном током %{count} различитих дана, даљи покушаји испоруке неће бити иницирани осим уколико се не прими испорука са домена. + one: Ако испорука домену не успе ниједном у временском периоду од %{count} дана, даљи покушаји испоруке се неће иницирати осим уколико се не прими испорука са домена. + other: Уколико испорука домену не успе ниједном током %{count} различитих дана, даљи покушаји испоруке се неће иницирати осим уколико се не прими испорука са домена. + failure_threshold_reached: Праг неуспеха достигнут датума %{date}. + failures_recorded: + few: Неуспели покушаји током %{count} различита дана. + one: Неуспели покушај током %{count} дана. + other: Неуспели покушаји током %{count} различитих дана. + no_failures_recorded: Без забележених неуспеха. + title: Доступност + warning: Последњи покушај повезивања са овим сервером је био неуспешан back_to_all: Све back_to_limited: Ограничено back_to_warning: Упозорење by_domain: Домен + confirm_purge: Да ли сте сигурни да желите да трајно уклоните податке са овог домена? content_policies: + comment: Интерна белешка + description_html: Можете да дефинишете политику садржаја која ће важити за све налоге на овом домену и сваком од његових поддомена. + limited_federation_mode_description_html: Можете да одлучите да ли да допустите федерацију са овим доменом. policies: + reject_media: Одбиј мултимедију + reject_reports: Одбиј пријаве silence: Ограничи suspend: Суспендуј policy: Политика reason: Јавни разлог + title: Политика садржаја + dashboard: + instance_accounts_dimension: Најпраћенији налози + instance_accounts_measure: ускладиштени налози + instance_followers_measure: наши пратиоци овде + instance_follows_measure: њихови пратиоци овде + instance_languages_dimension: Најзаступљенији језици + instance_media_attachments_measure: ускладиштени мултимедијални прилози + instance_reports_measure: пријаве против њих + instance_statuses_measure: ускладиштене објаве delivery: all: Све + clear: Очисти грешке приликом испоруке + failing: Без успеха + restart: Започни испоруку поново + stop: Обустави испоруку unavailable: Недоступно delivery_available: Достава је доступна + delivery_error_days: Дани неуспешних испорука + delivery_error_hint: Уколико испорука није могућа %{count} дана, аутоматски ће бити обележена као неиспоручива. + destroyed_msg: Подаци са %{domain} су сада у реду за чекање за извесно брисање. + empty: Ниједан домен није пронађен. + known_accounts: + few: "%{count} позната налога" + one: "%{count} познат налог" + other: "%{count} познатих налога" moderation: all: Све limited: Ограничено title: Модерација private_comment: Приватни коментар public_comment: Јавни коментар + purge: Чистка + purge_description_html: Уколико верујете да је овај домен трајно угашен, можете да обришете све записе налога и сродне податке овог домена са свог складишта. Ово може да потраје. title: Федерација total_blocked_by_us: Блокирано од стране нас total_followed_by_them: Праћени од стране њих total_followed_by_us: Праћени од стране нас total_reported: Пријаве везане за њих + total_storage: Мултимедијални прилози + totals_time_period_hint_html: Укупне вредности приказане испод укључују податке за сва времена. invites: deactivate_all: Деактивирај све filter: @@ -273,6 +554,9 @@ sr: title: Филтер title: Позивнице ip_blocks: + add_new: Направи правило + created_msg: Успешно је додато ново IP правило + delete: Избриши expires_in: '1209600': 2 недеље '15778476': 6 месеци @@ -283,6 +567,9 @@ sr: new: title: Креирај ново IP правило no_ip_block_selected: Ниједно IP правило није промењено јер ниједно није изабрано + title: IP правила + relationships: + title: Односи корисника %{acct} relays: add_new: Додај нови релеј delete: Обриши @@ -290,208 +577,798 @@ sr: disable: Искључи disabled: Искључен enable: Укључи - enable_hint: Када се омогући, Ваш сервер ће бити претплаћен на све јавне трубе са овог релеја, и почеће да шаље своје јавне трубу на њега. + enable_hint: Када се омогући, ваш сервер ће бити претплаћен на све јавне објаве са овог релеја, и почеће да шаље јавне објаве овог сервера на њега. enabled: Укључен inbox_url: URL Релеја pending: Чека се одобрење релеја save_and_enable: Сачувај и омогући setup: Подеси везу релеја + signatures_not_enabled: Преноси можда неће радити исправно док је укључен безбедни режим или режим ограничене федерације status: Статус title: Релеји report_notes: created_msg: Белешка пријаве успешно направљена! destroyed_msg: Белешка пријаве успешно избрисана! reports: + account: + notes: + few: "%{count} белешке" + one: "%{count} белешка" + other: "%{count} бележака" + action_log: Записник action_taken_by: Акцију извео + actions: + delete_description_html: Пријављене објаве ће бити обрисане и прекршај ће бити уписан да би Вам олакшали интервенцију приликом будућих преступа са истог налога. + mark_as_sensitive_description_html: Мултимедијални садржај са пријављених објава ће бити означен као осетљив и прекршај ће бити уписан ради лакше интервенције у случају даљих прекршаја са истог налога. + other_description_html: Погледајте више опција за контролисање понашања налога и прилагодите комуникацију са пријављеним налогом. + resolve_description_html: Ниједна радња неће бити предузета против пријављеног налога, ниједан преступ није уписан и пријава ће бити затворена. + silence_description_html: Налог ће бити видљив само онима који га већ прате или који га ручно потраже, што ће значајно ограничити његов домет. Ограничење се може повући у сваком тренутку. Затвара све пријаве поднете против овог налога. + suspend_description_html: Налог и сви његови садржаји ће постати недоступни и у једном тренутку избрисани, а интеракција са налогом више неће бити могућа. Суспензија се може повући у року од 30 дана. Затвара све пријаве поднете против овог налога. + actions_description_html: Одлучите коју радњу да спроведете ради решавања ове пријаве. Уколико спроведете казнену радњу против пријављеног налога, власник налога ће бити обавештен путем и-мејла, осим уколико ознака „Непожељне поруке” није одабрана. + actions_description_remote_html: Одлучите коју радњу да предузмете ради решавања ове пријаве. Ово ће утицати само на то како Ваш сервер комуницира са овим удаљеним налогом и обрађује његов садржај. + add_to_report: Додај још у пријаву are_you_sure: Да ли сте сигурни? assign_to_self: Додели мени assigned: Додељени модератор + by_target_domain: Домен пријављеног налога + cancel: Откажи + category: Категорија + category_description_html: Разлог због ког је овај налог и/или садржај пријављен ће бити образложен у комуникацији са пријављеним налогом comment: none: Ништа + comment_description_html: 'Ради пружања више информација, %{name} је написао/-ла:' + confirm: Потврди + confirm_action: Потврди модерацијску радњу према @%{acct} created_at: Пријављена + delete_and_resolve: Обриши објаве + forwarded: Прослеђено + forwarded_to: Прослеђено ка %{domain} mark_as_resolved: Означи као решену + mark_as_sensitive: Обележи као осетљиво mark_as_unresolved: Означи као нерешену + no_one_assigned: Нико notes: create: Додај белешку create_and_resolve: Реши са белешком create_and_unresolve: Отвори поново са белешком delete: Обриши placeholder: Опишите какве су радње предузете, или било какве повезане новости... + title: Белешке + notes_description_html: Прочитајте и оставите напомене другим модераторима и себи у будућности + processed_msg: 'Пријава #%{id} успешно обрађена' + quick_actions_description_html: 'Предузмите брзу радњу или се спустите ниже да бисте видели пријављени садржај:' + remote_user_placeholder: удаљени корисник са %{instance} reopen: Отвори пријаву поново report: 'Пријава #%{id}' reported_account: Пријављени налог reported_by: Пријавио resolved: Решена resolved_msg: Пријава успешно разрешена! + skip_to_actions: Прескочи до радњи status: Статус + statuses: Пријављени садржај + statuses_description_html: Спорни садржај ће бити наведен у комуникацији са пријављеним налогом + summary: + action_preambles: + delete_html: 'Управо ћете обрисати неке од објава корисника @%{acct}. Ово ће:' + mark_as_sensitive_html: 'Управо ћете означити неке објаве корисника @%{acct} као осетљиве. Ово ће:' + silence_html: 'Управо ћете ограничити налог корисника @%{acct}. Ово ће:' + suspend_html: 'Управо ћете суспендовати налог корисника @%{acct}. Ово ће:' + actions: + delete_html: Обришите спорне објаве + mark_as_sensitive_html: Обележите медије спорних објава као осетљиве + silence_html: Жестоко ограничите домет корисника @%{acct} тако што ћете учинити његов профил и садржаје видљиве само људима који их већ прате и људима који ручно потраже профил + suspend_html: Суспендујте корисника @%{acct}, што ће учинити његов профил и садржаје недоступним за приступ и интеракцију + close_report: 'Означите пријаву #%{id} као решену' + close_reports_html: Означи све пријаве против @%{acct} као решене + delete_data_html: Обриши профил и садржаје корисника @%{acct} за 30 дана осим уколико суспензија буде повучена у међувремену + preview_preamble_html: "@%{acct} ће примити упозорење следеће садржине:" + record_strike_html: Упишите прекршај на име @%{acct} да би Вам било лакше да у будућности интервенишете приликом даљих преступа са овог налога + send_email_html: Пошаљи имејл упозорења кориснику @%{acct} + warning_placeholder: Опционо додатно образложење за модерацијску радњу. + target_origin: Порекло пријављеног налога title: Пријаве unassign: Уклони доделу + unknown_action_msg: 'Непозната радња: %{action}' unresolved: Нерешене updated_at: Ажурирана view_profile: Погледај профил roles: add_new: Додај улогу + assigned_users: + few: "%{count} корисника" + one: "%{count} корисник" + other: "%{count} корисника" categories: administration: Администрација + devops: DevOps + invites: Позивнице moderation: Модерација + special: Посебно delete: Избриши + description_html: Помоћу корисничких улога можете да подесите којим функцијама и деловима Mastodon-а ваши корисници могу да приступе. + edit: Измени улогу '%{name}' + everyone: Подразумевана овлашћења + everyone_full_description_html: Ово је основна улога која се односи на све кориснике, чак и оне којима није додељена улога. Све друге улоге наслеђују овлашћења од основне улоге. + permissions_count: + few: "%{count} дозволе" + one: "%{count} дозвола" + other: "%{count} дозвола" privileges: administrator: Администратор + administrator_description: Корисници са овом привилегијом могу да заобиђу сва друга ограничења delete_user_data: Избриши податке корисника + delete_user_data_description: Допушта корисницима да избришу податке других корисника без одлагања invite_users: Позови кориснике + invite_users_description: Допушта корисницима да позове нове људе на сервер manage_announcements: Управљај обавештењима + manage_announcements_description: Допушта корисницима да руководе саопштењима на серверу + manage_appeals: Надгледање жалби + manage_appeals_description: Допушта корисницима да прегледају жалбе на модерацијске радње + manage_blocks: Надгледање блокова + manage_blocks_description: Допушта корисницима да блокирају имејл провајдере и IP адресе + manage_custom_emojis: Надлежност над прилагођеним емоџијима + manage_custom_emojis_description: Даје корисницима контролу над прилагођеним емоџијима на серверу + manage_federation: Надгледање федерације + manage_federation_description: Допушта корисницима да блокирају или дозволе федерацију са другим доменима и контролишу испоручивање података другим серверима + manage_invites: Надгледање позивница + manage_invites_description: Допушта корисницима да претражују и деактивирају позивнице + manage_reports: Надгледање пријава + manage_reports_description: Допушта корисницима да прегледају пријаве и извршавају модерацијске радње над њима manage_roles: Управљај улогама + manage_roles_description: Допушта корисницима да надгледају и додељују улоге са нижим овлашћењима од њихове manage_rules: Управљај правилима manage_rules_description: Дозволи корисницима да мењају правила сервера manage_settings: Управљај поставкама manage_settings_description: Дозволи корисницима да мењају поставке сајта + manage_taxonomies: Надгледање таксономија + manage_taxonomies_description: Допушта корисницима да прегледају садржај у тренду и ажурирају поставке хеш ознака + manage_user_access: Надлежност над корисничким приступом + manage_user_access_description: Допушта корисницима да онемогуће двофакторску аутентификацију других корисника, мењају им имејл адресе и ресетују им лозинке + manage_users: Надлежност над корисницима + manage_users_description: Допушта корисницима да прочитају детаље других корисника и извршавају модерацијске радње над њима + manage_webhooks: Надлежност над webhook елементима + manage_webhooks_description: Допушта корисницима да успоставе webhook елементе за административне радње + view_audit_log: Прочитај записник ревизија + view_audit_log_description: Допушта корисницима да виде историју административних радњи на серверу + view_dashboard: Погледај контролни панел + view_dashboard_description: Допушта корисницима да приступе контролном панелу и разним метрикама + view_devops: DevOps + view_devops_description: Допушта корисницима да приступе Sidekiq и pgHero контролним панелима + title: Улоге rules: add_new: Додај правило delete: Избриши + description_html: Док већина тврди да је прочитала и слаже се са условима коришћења, људи их обично не читају све док се не јави проблем. Учините правила Вашег сервера читљивијим и приступачнијим тако што ћете их изложити у форми листе. Потрудите се да појединачна правила буду кратка и једноставна, али покушајте и да их не исцепкате у превише одвојених ставки. edit: Уреди правило empty: Ниједно правило сервера још није дефинисано. title: Правила сервера settings: + about: + manage_rules: Управљање правилима сервера + preamble: Пружите детаљне информације о томе како се сервер води, модерира и финансира. + rules_hint: Постоји предвиђено место за правила која се од корисника очекује да поштују. + title: Назив appearance: + preamble: Прилагодите веб окружење Mastodon-а. title: Изглед + branding: + preamble: Брендирање Вашег сервера га издваја од других сервера на мрежи. Ове информације могу бити приказане у разним окружењима, попут Mastodon-овог веб окружења, нативних апликација, у прегледима линкова на другим серверима и у апликацијама за размену порука, итд. Из овог разлога, најбоље је да ове информације буду кратке, јасне и концизне. + title: Брендирање + captcha_enabled: + desc_html: Ово се ослања на екстерне скрипте из hCaptcha, што може представљати забринутост за безбедност и приватност. Поред тога, ово може учинити процес регистрације знатно мање доступним неким (посебно особама са инвалидитетом). Из ових разлога, размотрите алтернативне мере као што је регистрација заснована на одобрењу или на позиву. + title: Захтевај од нових корисника да реше CAPTCHA да би потврдили свој налог + content_retention: + preamble: Контролишите како се садржај генерисан од стране корисника складишти на Mastodon-у. + title: Задржавање садржаја default_noindex: desc_html: Утиче на све кориснике који нису сами променили ову поставку title: Подразумевано искључи кориснике из индексирања претраживача discovery: + follow_recommendations: Препоруке за праћење + preamble: Одржавање занимљивих садржаја на површини је кључно у привлачењу нових корисника који можда не знају никога на Mastodon-у. Контролишите како различити начини истраживања функционишу на вашем серверу. + profile_directory: Директоријум профилâ public_timelines: Јавне временске линије + publish_discovered_servers: Објави откривене сервере + publish_statistics: Објави статистику + title: Откривање + trends: Трендови + domain_blocks: + all: Свима + disabled: Никоме + users: Пријављеним локалним корисницима + registrations: + preamble: Контролишите ко сме да направи налог на Вашем серверу. + title: Регистрације + registrations_mode: + modes: + approved: Одобрење неопходно за регистрацију + none: Нико не може да се региструје + open: Било ко може да се региструје + security: + authorized_fetch: Захтевај аутентификацију са здружених сервера + authorized_fetch_hint: Захтевање аутентификације са здружених сервера омогућује строжију примену блокова и на нивоу корисника и на нивоу сервера. Међутим, ово долази по цену смањења перформанси, смањује домет ваших одговора и може довести до проблема компатибилности са неким здруженим услугама. Поред тога, ово неће спречити посвећене актере да преузимају ваше јавне објаве и налоге. + authorized_fetch_overridden_hint: Тренутно не можете да промените ово подешавање јер га замењује променљива окружења. + federation_authentication: Спровођење здружене аутентификације + title: Подешавања сервера + site_uploads: + delete: Обриши отпремљени фајл + destroyed_msg: Отпремање успешно обрисано! + software_updates: + critical_update: Критично — ажурирајте брзо + description: Препоручује се да своју Mastodon инсталацију одржавате ажурном како бисте имали користи од најновијих исправки и функција. Штавише, понекад је кључно ажурирати Mastodon на време како би се избегли безбедносни проблеми. Из ових разлога, Mastodon проверава да ли постоје ажурирања сваких 30 минута, и обавестиће вас у складу са вашим подешавањима обавештења путем е-поште. + documentation_link: Сазнајте више + release_notes: Белешке о издању + title: Доступна ажурирања + type: Тип + types: + major: Главно издање + minor: Мање издање + patch: Издање закрпе — исправке грешака и промене које се лако примењују + version: Верзија statuses: + account: Аутор + application: Апликација back_to_account: Назад на страну налога + back_to_report: Назад на страницу са пријавама + batch: + remove_from_report: Уклоните из пријаве + report: Пријави + deleted: Обрисано + favourites: Омиљено + history: Историја верзијâ + in_reply_to: Одговор на + language: Језик media: title: Мултимедија + metadata: Мета подаци no_status_selected: Ниједан статус није промењен јер ниједан није изабран + open: Отвори објаву + original_status: Оригинална објава + reblogs: Дељења + status_changed: Објава промењена title: Статуси налога + trending: У тренду + visibility: Видљивост with_media: Са мултимедијом + strikes: + actions: + delete_statuses: "%{name} је обрисао/-ла објаве %{target}" + disable: "%{name} је замрзнуо налог корисника %{target}" + mark_statuses_as_sensitive: "%{name} је означио/-ла објаве корисника %{target} као осетљиве" + none: "%{name} је послао/-ла упозорење кориснику %{target}" + sensitive: "%{name} је обележио/-ла налог %{target} као осетљив" + silence: "%{name} је ограничио/-ла налог %{target}" + suspend: "%{name} је суспендовао/-ла налог %{target}" + appeal_approved: Жалба уважена + appeal_pending: Жалба у разматрању + appeal_rejected: Жалба одбијена + system_checks: + database_schema_check: + message_html: Селидбе базâ података су на чекању. Молимо Вас обавите их да би се апликација понашала како треба + elasticsearch_health_red: + message_html: Elasticsearch кластер је нездрав (црвени статус), функције претраге су недоступне + elasticsearch_health_yellow: + message_html: Elasticsearch кластер је нездрав (жути статус), можда бисте желели да истражите разлог + elasticsearch_index_mismatch: + message_html: Elasticsearch мапирања индекса су застарела. Покрените tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Погледај документацију + message_html: Ваш Elasticsearch кластер има више од једног чвора, али Mastodon није конфигурисан да их користи. + elasticsearch_preset_single_node: + action: Погледај документацију + message_html: Ваш Elasticsearch кластер има само један чвор, ES_PRESETтреба поставити наsingle_node_cluster. + elasticsearch_reset_chewy: + message_html: Ваш Elasticsearch кластер има само један чвор, ES_PRESETтреба поставити наsingle_node_cluster. + elasticsearch_running_check: + message_html: Повезивање на Elasticsearch није било могуће. Молимо Вас проверите да ли је покренут, или онемогућите претрагу целог текста + elasticsearch_version_check: + message_html: 'Неусклађена Elasticsearch верзија: %{value}' + version_comparison: Elasticsearch %{running_version} је инсталиран а %{required_version} је неопходан + rules_check: + action: Управљање правилима сервера + message_html: Нисте дефинисали ниједно правило сервера. + sidekiq_process_check: + message_html: Ниједан Sidekiq процес није покренут за ред(ове) %{value}. Молимо Вас прегледајте своју Sidekiq конфигурацију + software_version_critical_check: + action: Погледајте доступна ажурирања + message_html: Доступно је критично ажурирање за Mastodon, ажурирајте га што је пре могуће. + software_version_patch_check: + action: Погледајте доступна ажурирања + message_html: Доступна је исправка грешака за Mastodon. + upload_check_privacy_error: + action: Проверите овде за више информација + message_html: "Ваш веб сервер је погрешно конфигурисан. Приватност ваших корисника је изложена ризику." + upload_check_privacy_error_object_storage: + action: Проверите овде за више информација + message_html: "Ваше складиште објекта је погрешно конфигурисано. Приватност ваших корисника је изложена ризику." + tags: + review: Прегледај статус + updated_msg: Подешавања хеш ознака успешно ажурирана title: Администрација + trends: + allow: Дозволи + approved: Одобрено + disallow: Забрани + links: + allow: Дозволи линк + allow_provider: Дозволи издавача + description_html: Ово су линкови који се тренутно често деле међу налозима које Ваш сервер види. Може помоћи Вашим корисницима да сазнају шта се дешава у свету. Ниједан линк није јавно приказан све док Ви не одобрите издавача. Такође можете да дозволите или одбијете засебне линкове. + disallow: Забрани линк + disallow_provider: Забрани издавача + no_link_selected: Ниједан линк није промењен јер ниједан није изабран + publishers: + no_publisher_selected: Ниједан издавач није промењен јер ниједан није изабран + shared_by_over_week: + few: Подељен од стране %{count} особе током претходне недеље + one: Подељен од стране једне особе током претходне недеље + other: Подељен од стране %{count} особа током претходне недеље + title: Линкови у тренду + usage_comparison: Подељено %{today} пута данас, у поређењу са %{yesterday} пута јуче + not_allowed_to_trend: Није одобрено за тренд + only_allowed: Само дозвољено + pending_review: Преглед на чекању + preview_card_providers: + allowed: Линкови са овог извора могу да буду „у тренду” + description_html: Ово су домени чији се линкови често деле на Вашем серверу. Линкови неће бити јавно приказани као „у тренду” осим уколико је домен линкова одобрен. Ваше одобрење (или одбијање) се преноси и на поддомене. + rejected: Линкови са овог извора неће бити „у тренду” + title: Издавачи + rejected: Одбијен + statuses: + allow: Дозволи објаву + allow_account: Одобри аутора + description_html: Ово су објаве за које ваш сервер зна, а које се тренутно често деле и стављају у омиљене. Могу помоћи вашим новим корисницима и повратницима да пронађу још људи за праћење. Ниједна објава се не приказује јавно док ви не одобрите аутора, односно док аутор не дозволи да његов налог буде препоручен другима. Такође можете одобрити или одбити појединачне објаве. + disallow: Забрани објаву + disallow_account: Забрани аутора + no_status_selected: Ниједна објава у тренду није промењена јер ниједна није изабрана + not_discoverable: Аутор није дао сагласност да буде препоручен + shared_by: + few: Подељено или означено као омиљено %{friendly_count} пута + one: Подељено или означено као омиљено %{friendly_count} пут + other: Подељено или означено као омиљено %{friendly_count} пута + title: Објаве у тренду + tags: + current_score: Тренутна вредност %{score} + dashboard: + tag_accounts_measure: јединствене употребе + tag_languages_dimension: Најзаступљенији језици + tag_servers_dimension: Најактивнији сервери + tag_servers_measure: различити сервери + tag_uses_measure: укупно употреба + description_html: Ово су хеш ознаке које се тренутно често појављују у објавама које Ваш сервер види. Могу помоћи Вашим корисницима да открију о чему се тренутно највише говори. Ниједна хеш ознака није приказана јавно све док Ви то не одобрите. + listable: Може се препоручити + no_tag_selected: Ниједна ознака није измењена јер ниједна није изабрана + not_listable: Неће бити препоручено + not_trendable: Неће се појављивати у трендовима + not_usable: Не може се користити + peaked_on_and_decaying: Врхунац достигнут датума %{date}, од тада у опадању + title: Хеш ознаке у тренду + trendable: Може да се појави под трендовима + trending_rank: 'У тренду #%{rank}' + usable: Може се користити + usage_comparison: Употребљено %{today} пута данас, у поређењу са %{yesterday} пута јуче + used_by_over_week: + few: Коришћено од стране %{count} особе током претходне недеље + one: Коришћено од стране једне особе током претходне недеље + other: Коришћено од стране %{count} људи током претходне недеље + title: Трендови + trending: У тренду warning_presets: add_new: Додај нови delete: Избриши edit_preset: Уреди пресет упозорења + empty: Још увек нисте дефинисали ниједан шаблон упозорења. title: Управљај пресетима упозорења + webhooks: + add_new: Додај крајњу тачку + delete: Избриши + description_html: "Webhook омогућава Mastodon-у да вашој апликацији испоручује обавештења у реалном времену о одабраним догађајима, тако да ваша апликација може да aутоматски изазове реакцију." + disable: Онемогући + disabled: Онемогућено + edit: Измени крајњу тачку + empty: Још увек немате ниједну конфигурисану webhook крајњу тачку. + enable: Омогући + enabled: Активно + enabled_events: + few: "%{count} омогућена догађаја" + one: 1 омогућен догађај + other: "%{count} омогућених догађаја" + events: Догађаји + new: Нови webhook + rotate_secret: Ротација тајни + secret: Тајно потписивање + status: Статус + title: Веб-пресретач + webhook: Веб-пресретач admin_mailer: + new_appeal: + actions: + delete_statuses: обрисати објаве корисника + disable: замрзнути налог корисника + mark_statuses_as_sensitive: означити објаве корисника као осетљиве + none: упозорење + sensitive: означити налог као осетљив + silence: ограничити налог + suspend: суспендовати налог + body: "%{target} прилаже жалбу на модерацијску одлуку корисника %{action_taken_by} од %{date}, која је гласила %{type}. У жалби пише:" + next_steps: Можете уважити жалбу да бисте повукли модерацијску одлуку, или је можете игнорисати. + subject: "%{username} прилаже жалбу на модерацијску одлуку са %{instance}" + new_critical_software_updates: + body: Објављене су нове критичне верзије Mastodon-а, можда ћете желети да ажурирате што је пре могуће! + subject: Критична Mastodon ажурирања су доступна за %{instance}! + new_pending_account: + body: Детаљи новог налога су наведени доле. Можете одобрити или одбити овај захтев. + subject: Нов налог за преглед на %{instance} (%{username}) new_report: body: "%{reporter} је пријавио %{target}" body_remote: Нека са домена %{domain} је пријавио %{target} subject: Нова пријава за %{instance} (#%{id}) + new_software_updates: + body: Објављене су нове верзије Mastodon-а, можда ћете желети да ажурирате! + subject: Нове Mastodon верзије су доступне за %{instance}}! + new_trends: + body: 'Следеће ставке је потребно прегледати пре него што могу јавно да се прикажу:' + new_trending_links: + title: Линкови у тренду + new_trending_statuses: + title: Објаве у тренду + new_trending_tags: + no_approved_tags: Тренутно нема одобрених хеш ознака у тренду. + requirements: 'Било који од следећих кандидата би могао превазићи #%{rank} одобрену хеш ознаку у тренду, која је тренутно #%{lowest_tag_name} са вредношћу %{lowest_tag_score}.' + title: Хеш ознаке у тренду + subject: Нови трендови за преглед на %{instance} + aliases: + add_new: Направи псеудоним + created_msg: Успешно је направљен нови псеудоним. Сада можете иницирати пресељење са старог налога. + deleted_msg: Успешно је уклоњен псеудоним. Премештање са тог налога на овај више неће бити могуће. + empty: Немате ниједан псеудоним. + hint_html: Ако желите да се преселите са другог налога на овај, овде можете направити псеудоним, који је неопходан пре него што можете наставити са пребацивањем пратилаца са старог налога на овај. Ова радња сама по себи је безопасна и реверзибилна. Пресељење налога се иницира са старог налога. + remove: Одвежи псеудоним + appearance: + advanced_web_interface: Напредно веб окружење + advanced_web_interface_hint: 'Ако желите да искористите целу ширину екрана, напредно веб окружење вам омогућује да конфигуришете много различитих колона да бисте видели онолико информација у исто време колико желите: почетну страницу, обавештења, здружену временску линију, било који број листа и хеш ознака.' + animations_and_accessibility: Анимације и приступачност + confirmation_dialogs: Дијалози потврде + discovery: Откривање + localization: + body: Mastodon преводе добровољци. + guide_link: https://crowdin.com/project/mastodon + guide_link_text: Свако може допринети. + sensitive_content: Осетљив садржај application_mailer: notification_preferences: Промени преференце Е-поште + salutation: Поштовани %{name}, settings: 'Промени подешавања е-поште: %{link}' + unsubscribe: Одјави се view: 'Погледај:' view_profile: Погледај налог view_status: Погледај статус applications: created: Апликација успешно направљена destroyed: Апликација успешно обрисана + logout: Одјава regenerate_token: Рекреирај приступни токен token_regenerated: Приступни токен успешно рекреиран warning: Опрезно са овим подацима. Никад је не делите ни са ким! your_token: Ваш приступни токен auth: - change_password: Лозинка - delete_account: Обриши налог - delete_account_html: Ако желите да обришете Ваш налог, можете наставити овде. Бићете упитани да потврдите. - didnt_get_confirmation: Нисте добили поруку са упутствима за потврду налога? + apply_for_account: Затражите налог + captcha_confirmation: + help_html: Ако имате проблема са решавањем CAPTCHA, можете нас контактирати преко %{email} и можемо вам помоћи. + hint_html: Само још једна ствар! Морамо да потврдимо да сте људско биће (ово је да бисмо спречили нежељену пошту!). Решите CAPTCHA испод и кликните на „Настави”. + title: Безбедоносна провера + confirmations: + wrong_email_hint: Ако та имејл адреса није исправна, можете је променити у подешавањима налога. + delete_account: Брисање налога + delete_account_html: Ако желите да избришете ваш налог, можете наставити овде. Од вас ће се тражити потврда. + description: + prefix_invited_by_user: "@%{name} вас позива да се придружите овом серверу Mastodon-а!" + prefix_sign_up: Придружите се Mastodon-у данас! + suffix: Са налогом, моћи ћете да пратите људе, објављујете новости и размењујете поруке са корисницима било ког Mastodon сервера и више! + didnt_get_confirmation: Нисте примили везу за потврду? + dont_have_your_security_key: Немате сигурносни кључ? forgot_password: Заборавили сте лозинку? invalid_reset_password_token: Токен за ресетовање лозинке је неисправан или је истекао. Затражите нови. + link_to_otp: Унесите двофакторски код са свог телефона или резервни код + link_to_webauth: Користите свој сигурносни кључ + log_in_with: Пријавите се помоћу login: Пријави се logout: Одјава - migrate_account: Помери у други налог + migrate_account: Премештање у други налог migrate_account_html: Ако желите да преусмерите овај налог на неки други, можете то подесити овде. or_log_in_with: Или се пријавите са + privacy_policy_agreement_html: Прочитао/-ла сам и сагласан/-а сам са политиком приватности + progress: + confirm: Потврдите е-пошту + details: Ваши детаљи + review: Наш преглед + rules: Прихватите правила providers: cas: CAS-ом saml: SAML-ом register: Региструј се - resend_confirmation: Пошаљи поруку са упутствима о потврди налога поново + registration_closed: "%{instance} не прима нове чланове" + resend_confirmation: Поново пошаљи везу за потврду reset_password: Ресетуј лозинку + rules: + accept: Прихвати + back: Назад + invited_by: 'Можете се придружити %{domain} захваљујући позивници коју сте добили од:' + preamble: Ово су правила која су успоставили и која спроводе модератори сервера %{domain}. + preamble_invited: Пре него што наставите, размотрите основна правила која су поставили модератори %{domain}. + title: Нека основна правила. + title_invited: Позвани сте. security: Безбедност set_new_password: Постави нову лозинку - authorize_follow: - already_following: Већ пратите овај налог - error: Нажалост, десила се грешка при тражењу удаљеног налога - follow: Запрати - follow_request: 'Послали сте захтев за праћењен за:' - following: 'Сјајно! Сада пратите:' - post_follow: - close: Или можете затворити овај прозор. - return: Врати се на налог овог корисника - web: Иди на веб - title: Запрати %{acct} + setup: + email_below_hint_html: Проверите своју фасциклу нежељене поште или затражите другу. Можете да исправите своју адресу е-поште ако је погрешна. + email_settings_hint_html: Кликните на везу који смо вам послали да верификујете %{email}. Чекаћемо овде. + link_not_received: Нисте добили везу? + new_confirmation_instructions_sent: За неколико минута примићете нову е-поруку са везом за потврду! + title: Проверите своје пријемно сандуче + sign_in: + preamble_html: Пријавите се са својим подацима за %{domain}. Ако је ваш налог хостован на другом серверу, нећете моћи да се пријавите овде. + title: Пријавите се на %{domain} + sign_up: + manual_review: Наши модератори ручно прегледају регистрације на %{domain}. Да бисте нам помогли да обрадимо вашу регистрацију, напишите нешто о себи и зашто желите налог на %{domain}. + preamble: Са налогом на овом Mastodon серверу, моћи ћете да пратите било кога са мреже, без обзира на то на ком серверу се његов/њен налог налази. + title: Хајде да Вам наместимо налог на %{domain}. + status: + account_status: Статус налога + confirming: Чекање на потврду путем имејла. + functional: Ваш налог је потпуно оперативан. + pending: Ваш захтев је на чекању за преглед од стране нашег особља. Ово може потрајати неко време. Примићете имејл поруку уколико Вам захтев буде одобрен. + redirecting_to: Ваш налог је неактиван јер преусмерава на %{acct}. + view_strikes: Погледајте претходне преступе уписане на Ваше име + too_fast: Формулар је поднет пребрзо, покушајте поново. + use_security_key: Користите сигурносни кључ + challenge: + confirm: Настави + hint_html: "Савет: Нећемо Вас питати за лозинку поново у наредних сат времена." + invalid_password: Неисправна лозинка + prompt: Потврдите лозинку за наставак + crypto: + errors: + invalid_key: није валидан Ed25519 или Curve25519 кључ + invalid_signature: није валидан Ed25519 потпис + date: + formats: + default: "%d. %b. %Y." + with_month_name: "%d. %B %Y." datetime: distance_in_words: + about_x_hours: "%{count} ч." about_x_months: "%{count}месец" about_x_years: "%{count}год" almost_x_years: "%{count}год" half_a_minute: Управо сад + less_than_x_minutes: "%{count} мин." less_than_x_seconds: Управо сад over_x_years: "%{count}год" x_days: "%{count}д" + x_minutes: "%{count} мин." x_months: "%{count}месец" + x_seconds: "%{count} сек." deletes: - confirm_password: Унесите тренутну лозинку да бисмо проверили Ваш идентитет + challenge_not_passed: Лозинка коју сте унели није била исправна + confirm_password: Унесите тренутну лозинку за верификацију вашег идентитета + confirm_username: Унесите своје корисничко име да бисте потврдили процедуру proceed: Обриши налог success_msg: Ваш налог је успешно обрисан + warning: + before: 'Пре него што наставите, молимо Вас пажљиво прочитајте следеће напомене:' + caches: Садржај који је кеширан на другим серверима може да остане нетакнут + data_removal: Ваше објаве и други подаци ће бити трајно избрисани + email_change_html: Можете променити своју имејл адресу без брисања свог налога + email_contact_html: Ако порука и даље не стиже, можете послати мејл на %{email} за помоћ + email_reconfirmation_html: Уколико Вам имејл за потврду не стиже, можете га поново затражити + irreversible: Нећете бити у могућности да вратите или реактивирате свој налог + more_details_html: За више детаља, погледајте политику приватности. + username_available: Ваше корисничко име ће поново постати доступно + username_unavailable: Ваше корисничко име ће остати недоступно + disputes: + strikes: + action_taken: Радња предузета + appeal: Жалба + appeal_approved: Жалба на овај преступ је уважена и преступ више није валидан + appeal_rejected: Жалба је одбијена + appeal_submitted_at: Жалба је приложена + appealed_msg: Ваша жалба је приложена. Бићете обавештени уколико она буде била уважена. + appeals: + submit: Приложи жалбу + approve_appeal: Уважи жалбу + associated_report: Сродна пријава + created_at: Датум + description_html: Ово су радње предузете против Вашег налога и упозорења која су Вам послали чланови особља %{instance}. + recipient: Усмерено према + reject_appeal: Одбиј жалбу + status: 'Објава #%{id}' + status_removed: Објава је већ уклоњена из система + title: "%{action} од %{date}" + title_actions: + delete_statuses: Брисање објава + disable: Замрзавање налога + mark_statuses_as_sensitive: Означавање објава као осетљивих + none: Упозорење + sensitive: Означавање налога као осетљивог + silence: Ограничење налога + suspend: Суспензија налога + your_appeal_approved: Ваша жалба је уважена + your_appeal_pending: Приложили сте жалбу + your_appeal_rejected: Ваша жалба је одбијена + domain_validator: + invalid_domain: нелегитимно име домена + edit_profile: + basic_information: Основне информације + hint_html: "Прилагодите шта људи виде на вашем јавном профилу и поред ваших објава. Већа је вероватноћа да ће вас други пратити и комуницирати са вама када имате попуњен профил и слику профила." + other: Остало errors: - '400': The request you submitted was invalid or malformed. + '400': Захтев који сте поднели је био нелегитиман или у погрешном формату. '403': Немате дозвола да видите ову страну. '404': Страна коју сте тражили не постоји. - '406': This page is not available in the requested format. + '406': Ова страница није доступна у изабраном формату. '410': Страна коју сте тражили више не постоји. '422': - content: Безбедоносна провера није успела. Да не блокирате колачиће? - title: Безбедоносна провера није успела + content: Безбедоносна верификација није успела. Да ли блокирате колачиће? + title: Безбедоносна верификација није успела '429': Успоред '500': content: Извињавамо се, нешто је пошло по злу са ове стране. title: Страна није исправна - '503': The page could not be served due to a temporary server failure. - noscript_html: Да бисте користили Мастодонт веб апликацију, омогућите JavaScript. У супротном, пробајте неку од оригиналних апликација за Мастодонт за Вашу платформу. + '503': Страницу није било могуће доставити услед привременoг пада сервера. + noscript_html: Да бисте користили Mastodon веб апликацију, омогућите JavaScript. У супротном, пробајте неку од оригиналних апликација за Mastodon за вашу платформу. + existing_username_validator: + not_found: није било могуће пронаћи локалног корисника са тим корисничким именом + not_found_multiple: није било могуће пронаћи %{usernames} exports: archive_takeout: date: Датум download: Преузмите Вашу архиву - hint_html: Можете затражити архиву ваших труба и отпремљених медија. Извезени подаци ће бити у АктивитиПаб формату, који можете читати са било којим усаглашеним софтвером. Архиву можете затражити сваких 7 дана. + hint_html: Можете затражити архиву ваших објава и отпремљених медија. Извезени подаци ће бити у ActivityPub формату, који може читати било који компатибилан софтвер. Архиву можете затражити сваких 7 дана. in_progress: Састављање ваше архиве... - request: Затражите Вашу архиву + request: Затражите своју архиву size: Величина blocks: Блокирали сте + bookmarks: Обележивачи + csv: CSV domain_blocks: Блокови домена lists: Листе - mutes: Ућуткали сте + mutes: Игноришете storage: Мултимедијално складиште + featured_tags: + add_new: Додај нову + errors: + limit: Већ сте истакли максималан број хеш ознака + hint_html: "Истакните најважније хеш ознаке на свом профилу. Одличан алат за праћење ваших креативних радова и дугорочних пројеката, истакнуте хеш ознаке су истакнуте на вашем профилу и омогућују брз приступ вашим објавама." filters: contexts: - home: Временска линија почетне + account: Профили + home: Почетна страница и листе notifications: Обавештења public: Јавне временске линије thread: Разговори edit: + add_keyword: Додај кључну реч + keywords: Кључне речи + statuses: Засебне објаве + statuses_hint_html: Овај филтер важи за одабране засебне објаве без обзира на то да ли садрже кључне речи наведене испод. Прегледајте или уклоните објаве из филтера. title: Измени филтер errors: + deprecated_api_multiple_keywords: Ови параметри не могу бити промењени у овој апликацији зато што се односе на више од једне кључне речи. Користите ажурнију апликацију или веб интерфејс. invalid_context: Ниједан или неважећи контекст испоручен index: + contexts: Филтрира у %{contexts} delete: Избриши + empty: Немате филтере. + expires_in: Истиче за %{distance} + expires_on: Истиче датума %{date} + keywords: + few: "%{count} кључне речи" + one: "%{count} кључна реч" + other: "%{count} кључних речи" + statuses: + few: "%{count} објаве" + one: "%{count} објава" + other: "%{count} објава" + statuses_long: + few: "%{count} засебне објаве сакривене" + one: "%{count} засебна објава сакривена" + other: "%{count} засебних објава сакривено" title: Филтери new: + save: Сачувај нови филтер title: Додај нови филтер + statuses: + back_to_filter: Назад на филтер + batch: + remove: Уклони из филтера + index: + hint: Овај филтер важи за одабране засебне објаве без обзира на друге критеријуме. Можете да додате више објава у овај филтер путем веб интерфејса. + title: Филтриране објаве generic: - changes_saved_msg: Измене успешно сачуване! + all: Сви + all_items_on_page_selected_html: + few: Све %{count} ставке са ове странице су изабране. + one: "%{count} ставка са ове странице је изабрана." + other: Свих %{count} ставки са ове странице је изабрано. + all_matching_items_selected_html: + few: Све %{count} ставке које се поклапају са Вашом претрагом су изабране. + one: "%{count} ставка која се поклапа са Вашом претрагом је изабрана." + other: Свих %{count} ставки које се поклапају са Вашом претрагом су изабране. + cancel: Откажи + changes_saved_msg: Промене су успешно сачуване! + confirm: Потврди copy: Копирај - save_changes: Сними измене + delete: Избриши + deselect: Поништи све изборе + none: Ниједна + order_by: Сортирај према + save_changes: Сачувај промене + select_all_matching_items: + few: Одаберите све %{count} ставке које се поклапају са Вашом претрагом. + one: Одаберите %{count} ставку која се поклапа са Вашом претрагом. + other: Одаберите свих %{count} ставки које се поклапају са Вашом претрагом. + today: данас validation_errors: few: Нешто није баш како треба! Прегледајте %{count} грешке испод one: Нешто није баш како треба! Прегледајте грешке испод other: Нешто није баш како треба! Прегледајте %{count} грешака испод imports: + errors: + empty: Празна CSV датотека + incompatible_type: Некомпатибилно са изабраним типом увоза + invalid_csv_file: 'Неисправан CSV фајл. Грешка: %{error}' + over_rows_processing_limit: садржи више од %{count} редова + too_large: Датотека је превелика + failures: Неуспеси + imported: Увезено + mismatched_types_warning: Изгледа да сте можда изабрали погрешан тип за овај увоз, проверите још једном. + modes: + merge: Стапање + merge_long: Задржите постојеће записе и додајте нове + overwrite: Замени + overwrite_long: Замени тренутне записе новима + overwrite_preambles: + blocking_html: Управо ћете заменити своју листу блокираних са до %{total_items} налога из %{filename}. + bookmarks_html: Управо ћете заменити своје обележиваче са до %{total_items} објава из %{filename}. + domain_blocking_html: Управо ћете заменити своју листу блокираних домена са до %{total_items} домена из %{filename}. + following_html: Управо ћете пратити до %{total_items} налога из %{filename} and и престати са праћењем било кога другог. + lists_html: Спремате се да замените своје листе садржајем од %{filename}. До %{total_items} налога ће бити додато на нове листе. + muting_html: Управо ћете заменити своју листу игнорисаних налога са до %{total_items} налога из %{filename}. + preambles: + blocking_html: Управо ћете блокирати до %{total_items} налога из %{filename}. + bookmarks_html: Управо ћете додати до %{total_items} објава из %{filename} у ваше обележиваче. + domain_blocking_html: Управо ћете блокирати до %{total_items} домена из %{filename}. + following_html: Управо ћете пратити до %{total_items} налога из %{filename}. + lists_html: Спремате се да додате до %{total_items} налога од %{filename} на своје листе. Нове листе ће бити креиране ако не постоји листа за додавање. + muting_html: Управо ћете игнорисати до %{total_items} налога из %{filename}. preface: Можете увести податке које сте извезли са друге инстанце, као што су листе људи које сте пратили или блокирали. + recent_imports: Недавни увози + states: + finished: Завршено + in_progress: У току + scheduled: Планирано + unconfirmed: Непотврђено + status: Статус success: Ваши подаци су успешно отпремљени и биће обрађени ускоро + time_started: Започето у + titles: + blocking: Увоз блокираних налога + bookmarks: Увоз обележивача + domain_blocking: Увоз блокираних домена + following: Увоз праћених налога + lists: Увоз листа + muting: Увоз игнорисаних налога + type: Тип увоза + type_groups: + constructive: Праћења и обележивачи + destructive: Блокирања и игнорисања types: blocking: Листа блокирања + bookmarks: Обележивачи + domain_blocking: Листа блокираних домена following: Листа пратилаца + lists: Листе muting: Листа ућутканих upload: Отпреми invites: @@ -519,20 +1396,87 @@ sr: title: Позовите људе lists: errors: - limit: Достигли сте лимит броја листи + limit: Достигли сте максимални број листâ + login_activities: + authentication_methods: + otp: апликација за двофакторску аутентификацију + password: лозинка + sign_in_token: имејл сигурносни код + webauthn: сигурносни кључеви + description_html: Уколико приметите активност коју не препознајете, размислите о томе да промените своју лозинку и укључите двофакторску аутентификацију. + empty: Историја аутентификације није доступна + failed_sign_in_html: Неуспешан покушај пријављивања путем %{method} са %{ip} (%{browser}) + successful_sign_in_html: Успешан покушај пријављивања путем %{method} са %{ip} (%{browser}) + title: Историја аутентификације + mail_subscriptions: + unsubscribe: + action: Да, одјави ме + complete: Одјављен + confirmation_html: Да ли сте сигурни да желите да се одјавите од примања %{type} за Mastodon на %{domain} на своју е-пошту на %{email}? Увек можете поново да се пријавите у својим подешавањима обавештења путем е-поште. + emails: + notification_emails: + favourite: омиљене е-поште за обавештења + follow: омиљене е-поште за праћења + follow_request: е-поште за захтеве за праћења + mention: е-поште за обавештење помињања + reblog: е-поште за обавештење подржавања + resubscribe_html: Ако сте се грешком одјавили, можете поново да се пријавите у својим подешавањима обавештења путем е-поште. + success_html: Више нећете добијати %{type} за Mastodon на %{domain} на своју е-пошту на %{email}. + title: Одјави се media_attachments: validations: images_and_video: Не може да се прикачи видео на статус који већ има слике + not_ready: Не могу се приложити фајлови који још увек нису обрађени. Покушајте поново за који тренутак! too_many: Не може се прикачити више од 4 фајла migrations: acct: корисник@домен новог налога + cancel: Откажи преусмерење + cancel_explanation: Отказивање преусмерења ће поново активирати Ваш садашњи налог, али неће вратити пратиоце који су премештени на други налог. + cancelled_msg: Успешно је отказано преусмерење. + errors: + already_moved: већ сте се преселили на исти налог + missing_also_known_as: није псеудоним овог налога + move_to_self: не можете се преселити на садашњи налог + not_found: није било могуће пронаћи налог + on_cooldown: Под ограничењем сте + followers_count: Пратиоци у тренутку премештаја + incoming_migrations: Премештање из другог налога + incoming_migrations_html: Да бисте прешли са другог налога на овај, прво морате креирате псеудоним налога. + moved_msg: Ваш налог сада преусмерава на %{acct} и Ваши пратиоци се тренутно пребацују. + not_redirecting: Ваш налог тренутно не преусмерава ни на један други налог. + on_cooldown: Недавно сте се преселили на нови налог. Ова функција ће Вам поново постати доступна за %{count} дана. + past_migrations: Претходне селидбе + proceed_with_move: Пребаците пратиоце + redirected_msg: Ваш налог сада преусмерава на %{acct}. + redirecting_to: Ваш налог преусмерава на %{acct}. + set_redirect: Постави преусмерење + warning: + backreference_required: Нови налог прво мора бити конфигурисан тако да реферише на овај налог + before: 'Пре него што наставите, молимо Вас пажљиво прочитајте следеће напомене:' + cooldown: Након пресељења потребно је да прође одређено време пре него што ћете поново моћи да се преселите + disabled_account: Ваш тренутни налог више неће бити употребљив. Међутим, имаћете приступ извозу података као и реактивацији. + followers: Ова радња ће преместити све пратиоце са тренутног налога на нови налог + only_redirect_html: Уместо пресељења, можете само додати преусмеравајући линк на свој профил.. + other_data: Остали подаци неће бити аутоматски пребачени + redirect: Профил Вашег садашњег налога ће бити ажуриран са обавештењем о преусмерењу и биће искључен из претраге moderation: title: Модерација + move_handler: + carry_blocks_over_text: Овај корисник се преселио са налога %{acct}, који сте блокирали. + carry_mutes_over_text: Овај корисник се преселио са налога %{acct}, који сте утишали. + copy_account_note_text: 'Овај корисник се преселио са налога %{acct}, о коме сте записали следеће белешке:' + navigation: + toggle_menu: Прикажи/сакриј мени notification_mailer: + admin: + report: + subject: "%{name} је поднео/-ла пријаву" + sign_up: + subject: "%{name} се регистровао/-ла" favourite: - body: "%{name} је поставио као омиљен Ваш статус:" - subject: "%{name} је поставио као омиљен Ваш статус" - title: Нови омиљени + body: "%{name} је означио као омиљену вашу објаву:" + subject: "%{name} је означио као омиљену вашу објаву" + title: Ново омиљено follow: body: "%{name} Вас је запратио!" subject: "%{name} Вас је запратио" @@ -547,36 +1491,123 @@ sr: body: "%{name} Вас је поменуо у:" subject: "%{name} Вас је поменуо" title: Ново спомињање + poll: + subject: Анкета корисника %{name} се завршила reblog: body: "%{name} Вам је подржао/ла статус:" subject: "%{name} је подржао/ла Ваш статус" title: Нова подршка + status: + subject: "%{name} jе управо поставио/-ла објаву" + update: + subject: "%{name} је изменио/-ла објаву" notifications: + administration_emails: Обавештења е-поштом од администратора + email_events: Догађаји за обавештења е-поштом email_events_hint: 'Изаберите дешавања за која желите да примате обавештења:' + other_settings: Остала подешавања обавештења + number: + human: + decimal_units: + format: "%n %u" + units: + billion: млрд. + million: мил. + quadrillion: трил. + thousand: хиљ. + trillion: бил. + otp_authentication: + code_hint: Укуцајте код генерисан у Вашој апликацији за аутентификацију да бисте потврдили + description_html: Ако укључите двофакторску аутентификацију путем апликације за аутентификацију, мораћете да будете при телефону приликом пријављивања да бисте имали приступ генерисаним кодовима за пријаву. + enable: Омогући + instructions_html: "Скенирајте овај QR код помоћу Google аутентификатора или сличне апликације на свом телефону. Од сада па убудуће, та апликација ће генерисати приступне кодове које ћете морати да унесете приликом пријављивања." + manual_instructions: 'Ако не можете да скенирате QR код и морате да га унесете ручно, ево његове текстуалне шифре:' + setup: Инсталација + wrong_code: Унесени код је био неисправан! Да ли су време сервера и време уређаја исправни? pagination: newer: Новије next: Следеће older: Старије prev: Претходни + truncate: "…" + polls: + errors: + already_voted: Већ сте гласали у овој анкети + duplicate_options: садржи дупликате + duration_too_long: превише је далеко у будућности + duration_too_short: превише је скоро + expired: Анкета је већ завршена + invalid_choice: Изабрана опција не постоји + over_character_limit: не може бити дуже од по %{max} карактера + self_vote: Не можете гласати у сопственим анкетама + too_few_options: мора имати више од једне опције + too_many_options: не може да садржи више од %{max} опција preferences: other: Остало + posting_defaults: Подразумевана подешавања објављивања public_timelines: Јавне временске линије + privacy: + hint_html: "Прилагодите начин на који желите да ваш профил и ваше објаве буду пронађени. Различите функције у Mastodon-у могу вам помоћи да досегнете ширу публику када су омогућене. Одвојите мало времена да прегледате ова подешавања како бисте били сигурни да одговарају вашем случају употребе." + privacy: Приватност + privacy_hint_html: Контролишите колико желите да откријете у корист других. Људи откривају занимљиве профиле и апликације тако што прегледају пратиоце других људи и виде из којих апликација објављују, али можда ћете радије да то држите скривеним. + reach: Досег + reach_hint_html: Контролишите да ли желите да вас откривају и прате нови људи. Да ли желите да се ваше објаве појављују на екрану за истраживање? Да ли желите да вас други људи виде у својим препорукама? Да ли желите да аутоматски прихватите све нове пратиоце или да имате детаљну контролу над сваким од њих? + search: Претрага + search_hint_html: Контролишите како желите да будете пронађени. Да ли желите да вас људи пронађу по ономе о чему сте јавно објавили? Да ли желите да људи изван Mastodon-а пронађу ваш профил када претражују веб? Имајте на уму да се за јавне информације не може гарантовати потпуно искључење из свих претраживача. + title: Приватност и досег + privacy_policy: + title: Политика приватности + reactions: + errors: + limit_reached: Достигнуто је ограничење различитих реакција + unrecognized_emoji: није препознат емоџи + relationships: + activity: Активност налога + confirm_follow_selected_followers: Да ли сте сигурни да желите да пратите изабране пратиоце? + confirm_remove_selected_followers: Да ли сте сигурни да желите да уклоните изабране пратиоце? + confirm_remove_selected_follows: Да ли сте сигурни да желите да уклоните изабрана праћења? + dormant: Неактиван + follow_failure: Није могуће пратити неке од изабраних налога. + follow_selected_followers: Прати изабране пратиоце + followers: Пратиоци + following: Праћења + invited: Позван + last_active: Последњи пут активан + most_recent: Најновији + moved: Премештен + mutual: Заједнички + primary: Примарни + relationship: Однос + remove_selected_domains: Уклони све пратиоце са изабраних домена + remove_selected_followers: Уклони изабране пратиоце + remove_selected_follows: Отпрати изабране кориснике + status: Статус налога remote_follow: missing_resource: Не могу да нађем захтевану адресу преусмеравања за Ваш налог + reports: + errors: + invalid_rules: не реферише на легитимна правила + rss: + content_warning: 'Упозорење о садржају:' + descriptions: + account: Јавне објаве са @%{acct} + tag: 'Јавне објаве означене са #%{hashtag}' scheduled_statuses: - over_daily_limit: Прекорачили сте границу од %{limit} планираних труба за тај дан - over_total_limit: Прекорачили сте границу од %{limit} планираних труба + over_daily_limit: Прекорачили сте границу од %{limit} планираних објава за данас + over_total_limit: Прекорачили сте границу од %{limit} планираних објава too_soon: Планирани датум мора бити у будућности sessions: activity: Последња активност browser: Веб читач browsers: alipay: Алипеј - chrome: Хром + blackberry: Блекбери + chrome: Chrome edge: Мајкрософт Еџ electron: Електрон firefox: Фајерфокс generic: Непознати веб читач + huawei_browser: Huawei прегледач ie: Интернет Експлорер micro_messenger: МајкроМесенџер nokia: Нокија С40 Ови Претраживач @@ -585,42 +1616,60 @@ sr: phantom_js: ФантомЏејЕс qq: КјуКју Претраживач safari: Сафари + uc_browser: UC Browser + unknown_browser: Непознати прегледач weibo: Веибо current_session: Тренутна сесија description: "%{browser} са %{platform}" - explanation: Ово су веб претраживачи који су тренутно пријављени на Ваш Мастодон налог. + explanation: Ово су веб претраживачи који су тренутно пријављени на ваш Mastodon налог. + ip: IP platforms: adobe_air: Адоб Ер-а android: Андроида + blackberry: Блекбери + chrome_os: ChromeOS firefox_os: Фајерфокс ОС-а ios: иОС-а + kai_os: KaiOS linux: Линукса mac: Мека - other: непознате платформе - windows: Виндоуза - windows_mobile: Виндоуз мобилног - windows_phone: Виндоуз телефона + unknown_platform: Непозната платформа + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone revoke: Опозови revoke_success: Сесија успешно опозвана title: Сесије + view_authentication_history: Погледајте историју аутентификације вашег налога settings: + account: Налог + account_settings: Подешавања налога + aliases: Псеудоними налога appearance: Изглед authorized_apps: Ауторизоване апликације - back: Назад на Мастодон + back: Назад на Mastodon delete: Брисање налога development: Развој - edit_profile: Измена налога + edit_profile: Уређивање профила export: Извоз података + featured_tags: Истакнуте хеш ознаке import: Увоз import_and_export: Увоз и извоз migrate: Пребацивање налога notifications: Обавештења preferences: Подешавања - profile: Налог + profile: Јавни профил relationships: Праћења и пратиоци + statuses_cleanup: Аутоматско брисање објава + strikes: Модерацијски преступи two_factor_authentication: Двофакторска идентификација + webauthn_authentication: Сигурносни кључеви statuses: attached: + audio: + few: "%{count} аудио записа" + one: "%{count} аудио запис" + other: "%{count} аудио записа" description: 'У прилогу: %{attached}' image: few: "%{count} слика" @@ -632,72 +1681,205 @@ sr: other: "%{count} видео записа" boosted_from_html: Подржано од %{acct_link} content_warning: 'Упозорење на садржај: %{warning}' + default_language: Исто као језик окружења disallowed_hashtags: - few: 'садржи забрањене хештегове: %{tags}' - one: 'садржи забрањени хештег: %{tags}' - other: 'садржи забрањене хештегове: %{tags}' + few: 'садржи забрањене хеш ознаке: %{tags}' + one: 'садржи забрањену хеш ознаку: %{tags}' + other: 'садржи забрањене хеш ознаке: %{tags}' + edited_at_html: Измењено %{date} + errors: + in_reply_not_found: Објава на коју покушавате да одговорите наизглед не постоји. open_in_web: Отвори у вебу over_character_limit: ограничење од %{max} карактера прекорачено pin_errors: - limit: Већ имате прикачен највећи број труба + direct: Објаве које су видљиве само поменутим корисницима не могу бити прикачене + limit: Већ сте закачили максималан број објава ownership: Туђа објава се не може закачити reblog: Подршка не може да се прикачи + poll: + total_people: + few: "%{count} особе" + one: "%{count} особа" + other: "%{count} људи" + total_votes: + few: "%{count} гласа" + one: "%{count} глас" + other: "%{count} гласова" + vote: Гласајте show_more: Прикажи још - sign_in_to_participate: Пријавите се да учествујете у разговору + show_newer: Никад не приказуј + show_older: Прикажи старије + show_thread: Прикажи низ + title: "%{name}: „%{quote}”" visibilities: + direct: Директно private: Само пратиоци private_long: Прикажи само пратиоцима public: Јавно public_long: Свако може да види unlisted: Неизлистано unlisted_long: Свако може да види, али није излистано на јавним временским линијама + statuses_cleanup: + enabled: Аутоматски избриши старе објаве + enabled_hint: Аутоматски брише ваше објаве када достигну одређени старосни праг, осим ако се не подударају са једним од изузетака у наставку + exceptions: Изузеци + explanation: Пошто је брисање објава скупа операција, ово се ради полако током времена када сервер иначе није заузет. Из тог разлога, ваше објаве могу бити избрисане неко време након што достигну старосни праг. + ignore_favs: Игнориши омиљене + ignore_reblogs: Игнориши подржавања + interaction_exceptions: Изузеци засновани на интеракцијама + interaction_exceptions_explanation: Имајте на уму да не постоји гаранција да ће објаве бити избрисане ако падну испод прага броја означавања као омиљених или броја подржавања након што га једном премаше. + keep_direct: Задржи директне поруке + keep_direct_hint: Не брише ниједну од ваших директних порука + keep_media: Задржи објаве са медијским прилозима + keep_media_hint: Не брише ниједну од ваших објава које имају медијске прилоге + keep_pinned: Задржи закачене објаве + keep_pinned_hint: Не брише ниједну од ваших закачених објава + keep_polls: Задржи анкете + keep_polls_hint: Не брише ниједну од ваших анкета + keep_self_bookmark: Задржи објаве које сте додали у обележиваче + keep_self_bookmark_hint: Не брише ваше сопствене објаве ако сте их додлаи у обележиваче + keep_self_fav: Задржи објаве које сте означили као омиљене + keep_self_fav_hint: Не брише ваше сопствене објаве ако сте их означили као омиљене + min_age: + '1209600': 2 седмице + '15778476': 6 месеци + '2629746': 1 месец + '31556952': 1 година + '5259492': 2 месеца + '604800': 1 седмица + '63113904': 2 годинe + '7889238': 3 месеца + min_age_label: Старосни праг + min_favs: Задржи објаве означене као омиљене најмање + min_favs_hint: Не брише ниједну вашу објаву која је добила најмање овај број омиљених. Оставите празно за брисање објава без обзира на њихов број омиљених + min_reblogs: Задржи објаве подржане барем + min_reblogs_hint: Не брише ниједну вашу објаву која је била подржана најмање оволико пута. Оставите празно за брисање објава без обзира на њихов број подржавања stream_entries: - pinned: Закачена објава - reblogged: подржано sensitive_content: Осетљив садржај + strikes: + errors: + too_late: Истекао је рок за подношење жалбе на забележен преступ + tags: + does_not_match_previous_name: не поклапа се са претходним именом themes: contrast: Велики контраст - default: Мастодон - mastodon-light: Мастодон (светло) + default: Mastodon (тамно) + mastodon-light: Mastodon (светло) + time: + formats: + default: "%d %b %Y, %H:%M" + month: "%b %Y" + time: "%H:%M" + with_time_zone: "%d. %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Прекорачена је квота коришћења услуге превођења на целом серверу. + too_many_requests: Недавно је било превише захтева за услугу превођења. two_factor_authentication: + add: Додај disable: Искључи + disabled_success: Двофакторска аутентификација је успешно онемогућена + edit: Измени enabled: Двофакторска идентификација је укључена enabled_success: Двофакторска идентификација је успешно укључена generate_recovery_codes: Генериши кодове за опоравак lost_recovery_codes: Кодови за опоравак Вам омогућавају да повратите приступ налогу ако изгубите телефон. Ако изгубите кодове за опоравак, можете их ре-генерисати овде. Од тог тренутка, стари кодови за опоравак више не важе. + methods: Методе двофакторске аутентификације + otp: Апликација за аутентификацију recovery_codes: Направите резерву кодова за опоравак recovery_codes_regenerated: Кодови за опоравак успешно ре-генерисани recovery_instructions_html: Ако икада изгубите приступ телефону, можете искористити кодове за опоравак дате испод да повратите приступ налогу. Држите кодове за опоравак на сигурном. На пример, одштампајте их и чувајте их са осталим важним документима. + webauthn: Сигурносни кључеви user_mailer: + appeal_approved: + action: Идите на свој налог + explanation: Жалба поднета датума %{appeal_date} на уписан преступ на Ваше име датума %{strike_date} је уважена. Ваш налог је поново у повољном положају. + subject: Ваша жалба поднета %{date} је уважена + title: Жалба уважена + appeal_rejected: + explanation: Жалба поднета датума %{appeal_date} на уписан преступ на Ваше име датума %{strike_date} је одбијена. + subject: Ваша жалба поднета %{date} је одбијена + title: Жалба одбијена backup_ready: - explanation: Тражили сте потпуну резервну копију вашег Мастодон рачуна. Спремна за преузимање! + explanation: Тражили сте потпуну резервну копију вашег Mastodon налога. Спремна је за преузимање! subject: Ваша архива је спремна за преузимање title: Извоз архиве + suspicious_sign_in: + change_password: промените своју лозинку + details: 'Ево детаља о пријави:' + explanation: Приметили смо пријаву на Ваш налог са непознате IP адресе. + further_actions_html: Уколико то нисте били Ви, препоручујемо да одмах %{action} и укључите двофакторску аутентификацију да бисте одржали безбедност свог налога. + subject: Вашем налогу је приступљено са непозате IP адресе + title: Ново пријављивање warning: + appeal: Приложите жалбу + appeal_description: Уколико верујете да је у питању грешка, можете приложити жалбу особљу %{instance}. + categories: + spam: Нежељена пошта + violation: Садржај крши следећа правила заједнице + explanation: + delete_statuses: За неке од Ваших објава је установљено да крше једно или више правила заједнице и услед тога су уклоњене од стране модератора %{instance}. + disable: Више не можете да користите свој налог, али Ваш профил и други подаци остају нетакнути. Можете да затражите резервну копију својих података, промените подешавања налога или обришете свој налог. + mark_statuses_as_sensitive: Неке од Ваших објава су означене као осетљиве од стране модератора %{instance}. Ово значи да ће људи морати да кликну на мултимедије у објавама пре него што могу да их виде. Убудуће можете сами да означите своју мултимедију као осетљиву приликом састављања објаве. + sensitive: Од сада ће сви Ваши отпремљени мултимедијални фајлови бити означени као осетљиви и сакривени иза тастера упозорења. + silence: И даље можете користити свој налог али само људи који Вас већ прате ће видети Ваше објаве на овом серверу, и можда ћете бити искључени из разних механизама откривања. Међутим, други људи и даље могу ручно да Вас запрате. + suspend: Више не можете да користите свој налог, и Ваш профил и остали подаци Вам више нису доступни. И даље можете да се пријавите да бисте затражили резервну копију својих података све док се Ваши подаци трајно не избришу за око 30 дана, с тим што ћемо задржати неке основне податке да бисмо Вас спречили у евентуалном заобилажењу суспензије. + reason: 'Образложење:' + statuses: 'Цитиране објаве:' subject: + delete_statuses: Ваше објаве са %{acct} су избрисане disable: Ваш налог %{acct} је замрзнут + mark_statuses_as_sensitive: Ваше објаве са %{acct} су обележене као осетљиве none: Упозорење за %{acct} + sensitive: Ваше објаве са %{acct} ће убудуће бити означене као осетљиве silence: Ваш налог %{acct} је ограничен suspend: Ваш налог %{acct} је суспендован title: + delete_statuses: Објаве су обрисане disable: Налог замрзнут + mark_statuses_as_sensitive: Објаве су означене као осетљиве none: Упозорење + sensitive: Налог је означен као осетљив silence: Налог ограничен suspend: Налог суспендован welcome: edit_profile_action: Подеси налог + edit_profile_step: Можете прилагодити свој профил тако што ћете поставити профилну слику, променити име за приказ и тако даље. Можете дати сагласност да прегледате нове пратиоце пре него што им дозволите да Вас запрате. explanation: Ево неколико савета за почетак final_action: Почните објављивати + final_step: 'Почните да објављујете! Чак и без пратилаца, Ваше јавне објаве су видљиве другим људима, на пример на локалној временској линији или у хеш ознакама. Можда желите да се представите са хеш ознаком #introductions или #представљања.' full_handle: Ваш пун надимак full_handle_hint: Ово бисте рекли својим пријатељима како би вам они послали поруку, или запратили са друге инстанце. - subject: Добродошли на Мастодон + subject: Добродошли на Mastodon title: Добродошли, %{name}! users: follow_limit_reached: Не можете пратити више од %{limit} људи + go_to_sso_account_settings: Идите на подешавања налога свог добављача идентитета invalid_otp_token: Неисправни двофакторски код otp_lost_help_html: Ако изгубите приступ за оба, можете ступити у контакт са %{email} seamless_external_login: Пријављени сте путем спољашње услуге, тако да лозинка и подешавања Е-поште нису доступни. signed_in_as: 'Пријављен/а као:' verification: - explanation_html: 'Можете извршити проверу да сте Ви власник веза на Вашем налогу. Да би то радило, повезани веб сајт мора да садржи везу назад ка Вашем Мастодон налогу. Веза назад мора да има rel="me" атрибут. Текстуелни садржај везе није битан. Ево примера:' - verification: Провера + extra_instructions_html: Савет:Веза на вашем веб сајту може да буде невидљива. Важан део је rel="me" који спречава лажно представљање на веб сајтовима са садржајем који генерише корисник. Можете чак да користите ознаку везе у заглављу странице уместо а, али HTML мора бити доступан без извршавања JavaScript-а. + here_is_how: Ево како + hint_html: "Верификација вашег идентитета на Mastodon-у је за свакога. Засновано на отвореним веб стандардима, сада и заувек бесплатно. Све што вам треба је лични веб сајт по коме вас људи препознају. Када се повежете са овим веб сајтом са свог профила, проверићемо да ли је веб сајт повезан са вашим профилом и на њему ћемо приказати визуелни индикатор." + instructions_html: Копирајте и налепите код испод у HTML свог веб сајта. Затим додајте адресу свог веб сајта у једно од додатних поља на свом профилу са картице „Уреди профил” и сачувајте промене. + verification: Верификација + verified_links: Ваше верификоване везе + webauthn_credentials: + add: Додајте нови сигурносни кључ + create: + error: Искрсао је проблем приликом додавања Вашег сигурносног кључа. Молимо Вас покушајте поново. + success: Ваш сигурносни кључ је успешно додат. + delete: Избриши + delete_confirmation: Да ли сте сигурни да желите да избришете овај сигурносни кључ? + description_html: Ако укључите аутентификацију сигурносним кључем, мораћете да користите један од својих сигурносних кључева приликом пријављивања. + destroy: + error: Искрсао је проблем приликом брисања Вашег сигурносног кључа. Молимо Вас покушајте поново. + success: Ваш сигурносни кључ је успешно обрисан. + invalid_credential: Неисправан сигурносни кључ + nickname_hint: Унесите надимак свог новог сигурносног кључа + not_enabled: Још увек нисте омогућили WebAuthn + not_supported: Овај претраживач не подржава сигурносне кључеве + otp_required: Да бисте користили сигурносне кључеве, молимо Вас прво укључите двофакторску аутентификацију. + registered_on: Регистрован/-а %{date} diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 8558843d1c..3194d7a8c2 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -91,6 +91,7 @@ sv: moderation: active: Aktiv all: Alla + disabled: Inaktiverad pending: Väntande silenced: Begränsad suspended: Avstängda @@ -124,8 +125,8 @@ sv: removed_header_msg: Tog bort %{username}s sidhuvudsbild resend_confirmation: already_confirmed: Den här användaren är redan bekräftad - send: Skicka om e-postbekräftelse - success: Bekräftelsemeddelande skickades framgångsrikt! + send: Skicka bekräftelselänken igen + success: Bekräftelselänken har skickats! reset: Återställ reset_password: Återställ lösenord resubscribe: Starta en ny prenumeration @@ -133,6 +134,7 @@ sv: search: Sök search_same_email_domain: Andra användare med samma e-postdomän search_same_ip: Annan användare med samma IP-adress + security: Säkerhet security_measures: only_password: Endast lösenord password_and_2fa: Lösenord och 2FA @@ -213,7 +215,7 @@ sv: reset_password_user: Återställ lösenord resolve_report: Lös rapport sensitive_account: Markera mediet i ditt konto som känsligt - silence_account: Tysta konto + silence_account: Begränsa konto suspend_account: Stäng av konto unassigned_report: Återkalla rapport unblock_email_account: Avblockera e-postadress @@ -307,6 +309,7 @@ sv: unpublish: Avpublicera unpublished_msg: Kungörelsen raderades! updated_msg: Kungörelsen uppdaterades! + critical_update_pending: Kritisk uppdatering väntar custom_emojis: assign_category: Tilldela kategori by_domain: Domän @@ -380,6 +383,15 @@ sv: undo: Tag bort från vitlistan domain_blocks: add_new: Lägg till ny + confirm_suspension: + cancel: Avbryt + confirm: Pausa + permanent_action: Att ångra avstängningen kommer inte att återställa några uppgifter eller relationer. + preamble_html: Du håller på att stänga av %{domain} och dess underdomäner. + remove_all_data: Detta kommer att ta bort allt innehåll, all media och all profildata för domänens konton från din server. + stop_communication: Din server kommer att sluta kommunicera med dessa servrar. + title: Bekräfta blockering av domänen %{domain} + undo_relationships: Detta kommer att återställa följförhållanden mellan konton på dessa servrar och dina. created_msg: Domänblocket behandlas nu destroyed_msg: Domänblockering har återtagits domain: Domän @@ -427,6 +439,7 @@ sv: resolve: Slå upp domän title: Blockera ny e-postdomän no_email_domain_block_selected: Inga blockeringar av e-postdomäner ändrades eftersom inga valdes + not_permitted: Ej tillåtet resolved_dns_records_hint_html: Domännamnet ger uppslag till följande MX-domäner, vilka är ytterst ansvariga för att e-post tas emot. Att blockera en MX-domän blockerar även registreringar från alla e-postadresser som använder samma MX-domän, även om det synliga domännamnet är annorlunda. Var noga med att inte blockera stora e-postleverantörer. resolved_through_html: Uppslagen genom %{domain} title: Blockerade e-postdomäner @@ -473,6 +486,7 @@ sv: content_policies: comment: Intern anteckning description_html: Du kan definiera innehållspolicyer som kommer tillämpas på alla konton från denna domän samt alla dess underdomäner. + limited_federation_mode_description_html: Du kan välja om du vill tillåta federering med den här domänen. policies: reject_media: Avvisa media reject_reports: Avvisa rapporter @@ -585,11 +599,13 @@ sv: assign_to_self: Tilldela till mig assigned: Tilldelad moderator by_target_domain: Domän för rapporterat konto + cancel: Avbryt category: Kategori category_description_html: Anledningen till att kontot och/eller innehållet rapporterades kommer att visas i kommunikation med det rapporterade kontot comment: none: Ingen comment_description_html: 'För att ge mer information, skrev %{name}:' + confirm: Bekräfta confirm_action: Bekräfta modereringsåtgärd mot @%{acct} created_at: Anmäld delete_and_resolve: Ta bort inlägg @@ -628,9 +644,20 @@ sv: suspend_html: 'Du håller på att stänga av @%{acct}s konto. Detta kommer:' actions: delete_html: Ta bort kränkande inlägg + mark_as_sensitive_html: Markera de anmälda inläggens media som känslig + silence_html: Begränsa kraftigt @%{acct} räckvidd genom att göra deras profil och innehåll bara synligt till folk som redan följer dom eller som manuellt söker upp deras profil + suspend_html: Stäng av @%{acct}, vilket gör deras profil och innehåll oåtkomligt och omöjligt att interagera med + close_report: 'Markera anmälningen #%{id} som löst' + close_reports_html: Markera alla anmälningar mot @%{acct} som lösta + delete_data_html: Ta bort @%{acct}s profil och innehåll om 30 dagar ifall deras avstängning inte tagits bort under tiden + preview_preamble_html: "@%{acct} kommer få en varning med följande innehåll:" + record_strike_html: Registrera en varning mot @%{acct} för att hjälpa dig eskalera vid framtida överträdelser från detta konto + send_email_html: Skicka @%{acct} ett varningsmejl + warning_placeholder: Valfri ytterligare resonemang för modereringsåtgärd. target_origin: Ursprung för anmält konto title: Anmälningar unassign: Otilldela + unknown_action_msg: 'Okänd åtgärd: %{action}' unresolved: Olösta updated_at: Uppdaterad view_profile: Visa profil @@ -714,6 +741,9 @@ sv: branding: preamble: Din servers profilering differentierar den från andra servrar på nätverket. Denna information kan visas i en mängd olika miljöer, så som Mastodons webbgränssnitt, nativapplikationer, länkförhandsvisningar på andra webbsidor och i meddelandeapplikationer och så vidare. Av dessa anledningar är det bäst att hålla informationen tydlig, kort och koncis. title: Profilering + captcha_enabled: + desc_html: Detta bygger på externa skript från hCaptcha vilket kan vara ett säkerhets- och integritetsproblem. Dessutom,kan detta göra registreringsprocessen betydligt mindre tillgänglig för vissa personer (särskilt funktionsnedsatta). Av dessa skäl bör du överväga alternativa åtgärder såsom godkänningsbaserad eller inbjudningsbaserad registrering. + title: Kräv att nya användare löser en CAPTCHA för att erkänna sitt konto content_retention: preamble: Kontrollera hur användargenererat innehåll lagras i Mastodon. title: Bibehållande av innehåll @@ -741,10 +771,27 @@ sv: approved: Godkännande krävs för registrering none: Ingen kan registrera open: Alla kan registrera + security: + authorized_fetch: Kräv autentisering från federerade servrar + authorized_fetch_hint: Att kräva autentisering från federerade servrar möjliggör striktare tillämpning av både blockering på användarnivå och servernivå. Detta sker dock på bekostnad av prestanda, minskar räckvidden på dina svar, och kan införa kompatibilitet problem med vissa federerade tjänster. Dessutom kommer detta inte att hindra dedikerade aktörer från att hämta dina offentliga inlägg och konton. + authorized_fetch_overridden_hint: Du kan för närvarande inte ändra den här inställningen eftersom den åsidosätts av en miljövariabel. + federation_authentication: Federationen autentisering verkställighet title: Serverinställningar site_uploads: delete: Radera uppladdad fil destroyed_msg: Webbplatsuppladdningen har raderats! + software_updates: + critical_update: Kritiskt — vänligen uppdatera omgående + description: Det rekommenderas att hålla din Mastodon-installation uppdaterad för att ta nytta av de senaste fixarna och funktionerna. Dessutom är det ibland viktigt att uppdatera Mastodon i tid för att undvika säkerhetsproblem. Av dessa skäl kontrollerar Mastodon efter uppdateringar var 30:e minut och meddelar dig i enlighet med dina e-postaviseringsinställningar. + documentation_link: Läs mer + release_notes: Ändringslogg + title: Tillgängliga uppdateringar + type: Typ + types: + major: Större release + minor: Mindre release + patch: Patch release — buggfixar och enkla att tillämpa ändringar + version: Version statuses: account: Författare application: Applikation @@ -781,9 +828,24 @@ sv: suspend: "%{name} stängde av %{target}s konto" appeal_approved: Överklagad appeal_pending: Överklagande väntar + appeal_rejected: Överklagan avslagen system_checks: database_schema_check: message_html: Det finns väntande databasmigreringar. Vänligen kör dem för att säkerställa att programmet beter sig som förväntat + elasticsearch_health_red: + message_html: Elasticsearch kluster är ohälsosamt (röd status), sökfunktioner är otillgängliga + elasticsearch_health_yellow: + message_html: Elasticsearch kluster är ohälsosamt (gul status), du kanske vill undersöka orsaken + elasticsearch_index_mismatch: + message_html: Elasticsearch index mappningar är föråldrade. Vänligen kör tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Se dokumentation + message_html: Din Elasticsearch-kluster har mer än en nod, men Mastodon är inte konfigurerad att använda dem. + elasticsearch_preset_single_node: + action: Se dokumentation + message_html: Ditt Elasticsearch-kluster har bara en nod, ES_PRESET borde vara satt till single_node_cluster. + elasticsearch_reset_chewy: + message_html: Ditt systemindex för Elasticsearch är föråldrat på grund av en inställningsändring. Vänligen kör tootctl search deploy --reset-chewy för att uppdatera det. elasticsearch_running_check: message_html: Kunde inte ansluta till Elasticsearch. Kontrollera att det körs, eller inaktivera fulltextsökning elasticsearch_version_check: @@ -794,6 +856,18 @@ sv: message_html: Du har inte definierat några serverregler. sidekiq_process_check: message_html: Ingen Sidekiq-process körs för kön/köerna %{value}. Vänligen kontrollera din Sidekiq-konfiguration + software_version_critical_check: + action: Se tillgängliga uppdateringar + message_html: En kritisk uppdatering för Mastodon är tillgänglig. Uppdatera så snart som möjligt. + software_version_patch_check: + action: Se tillgängliga uppdateringar + message_html: En buggfix Mastodon-uppdatering är tillgänglig. + upload_check_privacy_error: + action: Kolla här för mer information + message_html: "Din webbserver är felkonfigurerad. Sekretessen för dina användare är i fara." + upload_check_privacy_error_object_storage: + action: Kolla här för mer information + message_html: "Din objektlagring är felkonfigurerad. Sekretessen för dina användare är i riskzonen." tags: review: Granskningsstatus updated_msg: Hashtagg-inställningarna har uppdaterats @@ -816,6 +890,7 @@ sv: other: Delad av %{count} personer under den senaste veckan title: Trendande länkar usage_comparison: Delade %{today} gånger idag, jämfört med %{yesterday} igår + not_allowed_to_trend: Inte tillåtet att trenda only_allowed: Endast tillåtna pending_review: Väntar på granskning preview_card_providers: @@ -900,6 +975,9 @@ sv: body: "%{target} överklagade ett modereringsbeslut av typen %{type}, taget av %{action_taken_by} den %{date}. De skrev:" next_steps: Du kan godkänna överklagan för att ångra modereringsbeslutet, eller ignorera det. subject: "%{username} överklagar ett modereringsbeslut på %{instance}" + new_critical_software_updates: + body: En kritisk uppdatering för Mastodon har släppts. Du bör uppdatera så snart som möjligt! + subject: Kritiska uppdateringar för Mastodon är tillgängliga för %{instance}! new_pending_account: body: Detaljerna för det nya kontot finns nedan. Du kan godkänna eller avvisa denna ansökan. subject: Nytt konto flaggat för granskning på %{instance} (%{username}) @@ -907,6 +985,9 @@ sv: body: "%{reporter} har rapporterat %{target}" body_remote: Någon från %{domain} har rapporterat %{target} subject: Ny rapport för %{instance} (#%{id}) + new_software_updates: + body: Nya Mastodon-versioner har släppts, du kanske vill uppdatera! + subject: Nya Mastodon-versioner finns tillgängliga för %{instance}! new_trends: body: 'Följande objekt behöver granskas innan de kan visas publikt:' new_trending_links: @@ -936,31 +1017,37 @@ sv: guide_link: https://crowdin.com/project/mastodon guide_link_text: Alla kan bidra. sensitive_content: Känsligt innehåll - toot_layout: Inläggslayout application_mailer: notification_preferences: Ändra e-postinställningar salutation: "%{name}," settings: 'Ändra e-postinställningar: %{link}' + unsubscribe: Avprenumerera view: 'Granska:' view_profile: Visa profil view_status: Visa inlägg applications: created: Ansökan är framgångsrikt skapad destroyed: Ansökan är framgångsrikt borttagen + logout: Logga ut regenerate_token: Regenerera access token token_regenerated: Access token lyckades regenereras warning: Var mycket försiktig med denna data. Dela aldrig den med någon! your_token: Din access token auth: apply_for_account: Ansök om konto - change_password: Lösenord + captcha_confirmation: + help_html: Om du har problem med att lösa CAPTCHA ska du kontakta oss via %{email} och vi kan hjälpa dig. + hint_html: En sista sak till! Vi måste bekräfta att du är en människa (för att hålla borta skräpinlägg!). Lös CAPTCHA nedan och klicka på "Fortsätt". + title: Säkerhetskontroll + confirmations: + wrong_email_hint: Om e-postadressen inte är rätt, kan du ändra den i kontoinställningarna. delete_account: Radera konto delete_account_html: Om du vill radera ditt konto kan du fortsätta här. Du kommer att bli ombedd att bekräfta. description: prefix_invited_by_user: "@%{name} bjuder in dig att gå med i en Mastodon-server!" prefix_sign_up: Registrera dig på Mastodon idag! suffix: Med ett konto kommer du att kunna följa personer, göra inlägg och utbyta meddelanden med användare från andra Mastodon-servrar, och ännu mer! - didnt_get_confirmation: Fick du inte instruktioner om bekräftelse? + didnt_get_confirmation: Fick du ingen bekräftelselänk? dont_have_your_security_key: Har du inte din säkerhetsnyckel? forgot_password: Glömt ditt lösenord? invalid_reset_password_token: Lösenordsåterställningstoken är ogiltig eller utgått. Vänligen be om en ny. @@ -973,26 +1060,39 @@ sv: migrate_account_html: Om du vill omdirigera detta konto till ett annat, kan du konfigurera det här. or_log_in_with: Eller logga in med privacy_policy_agreement_html: Jag har läst och godkänner integritetspolicyn + progress: + confirm: Bekräfta e-postadress + details: Dina uppgifter + review: Vår recension + rules: Acceptera regler providers: cas: CAS saml: SAML register: Registrera registration_closed: "%{instance} accepterar inte nya medlemmar" - resend_confirmation: Skicka instruktionerna om bekräftelse igen + resend_confirmation: Skicka bekräftelselänken igen reset_password: Återställ lösenord rules: + accept: Godkänn + back: Tillbaka + invited_by: 'Du kan gå med i %{domain} tack vare den inbjudan du har fått från:' preamble: Dessa bestäms och upprätthålls av moderatorerna för %{domain}. + preamble_invited: Innan du fortsätter bör du överväga grundreglerna som fastställts av moderatorerna för %{domain}. title: Några grundregler. + title_invited: Du har blivit inbjuden. security: Säkerhet set_new_password: Skriv in nytt lösenord setup: - email_below_hint_html: Om nedanstående e-postadress är felaktig kan du ändra den här, och få ett nytt bekräftelsemeddelande. - email_settings_hint_html: E-postmeddelande för verifiering skickades till %{email}. Om e-postadressen inte stämmer kan du ändra den i kontoinställningarna. - title: Ställ in + email_below_hint_html: Kolla din skräppost-mapp eller begär en annan. Du kan korrigera din e-postadress om den är fel. + email_settings_hint_html: Klicka på länken som vi har skickat till dig för att bekräfta %{email}. Vi väntar här. + link_not_received: Fick du ingen länk? + new_confirmation_instructions_sent: Du får e-post med bekräftelselänk om några minuter! + title: Kolla din inkorg sign_in: preamble_html: Logga in med dina användaruppgifter på %{domain}. Om ditt konto finns på en annan server kommer du inte att kunna logga in här. title: Logga in på %{domain} sign_up: + manual_review: Registreringar på %{domain} går igenom manuell granskning av våra moderatorer. För att hjälpa oss att hantera din registrering, skriv lite om dig själv och varför du vill ha ett konto på %{domain}. preamble: Med ett konto på denna Mastodon-server kan du följa alla andra personer på nätverket, oavsett vilken server deras konto tillhör. title: Låt oss få igång dig på %{domain}. status: @@ -1004,18 +1104,6 @@ sv: view_strikes: Visa tidigare prickar på ditt konto too_fast: Formuläret har skickats för snabbt, försök igen. use_security_key: Använd säkerhetsnyckel - authorize_follow: - already_following: Du följer redan detta konto - already_requested: Du har redan skickat en vänförfrågan till det kontot - error: Tyvärr inträffade ett fel när vi kontrollerade fjärrkontot - follow: Följ - follow_request: 'Du har skickat en följaförfrågan till:' - following: 'Succé! Du följer nu:' - post_follow: - close: Eller så kan du stänga detta fönster. - return: Visa användarens profil - web: Gå till webb - title: Följ %{acct} challenge: confirm: Fortsätt hint_html: "Tips: Vi frågar dig inte efter ditt lösenord igen under nästkommande timme." @@ -1092,6 +1180,10 @@ sv: your_appeal_rejected: Din överklagan har avvisats domain_validator: invalid_domain: är inte ett giltigt domännamn + edit_profile: + basic_information: Allmän information + hint_html: "Anpassa vad folk ser på din offentliga profil och bredvid dina inlägg. Andra personer är mer benägna att följa dig och interagera med dig när du har en ifylld profil och en profilbild." + other: Övrigt errors: '400': Förfrågningen som du skickade in var ogiltig eller felaktigt utformad. '403': Du har inte behörighet att visa den här sidan. @@ -1128,7 +1220,7 @@ sv: featured_tags: add_new: Lägg till ny errors: - limit: Du har redan det maximala antalet utvalda hashtaggar + limit: Du har redan fäst det maximala antalet hashtags hint_html: "Vad är utvalda hashtaggar? De visas tydligt på din offentliga profil och låter andra bläddra bland dina offentliga inlägg specifikt under dessa hashtaggar. De är ett bra verktyg för att hålla reda på kreativa arbeten eller långsiktiga projekt." filters: contexts: @@ -1172,8 +1264,6 @@ sv: index: hint: Detta filter gäller för att välja enskilda inlägg oavsett andra kriterier. Du kan lägga till fler inlägg till detta filter från webbgränssnittet. title: Filtrerade inlägg - footer: - trending_now: Trendar nu generic: all: Alla all_items_on_page_selected_html: @@ -1182,7 +1272,9 @@ sv: all_matching_items_selected_html: one: "%{count} objekt som matchar din sökning är valt." other: "%{count} objekt som matchar din sökning är valda." + cancel: Avbryt changes_saved_msg: Ändringar sparade! + confirm: Bekräfta copy: Kopiera delete: Radera deselect: Avmarkera alla @@ -1196,24 +1288,62 @@ sv: validation_errors: one: Något är inte riktigt rätt ännu! Kontrollera felet nedan other: Något är inte riktigt rätt ännu! Kontrollera dom %{count} felen nedan - html_validator: - invalid_markup: 'innehåller ogiltig HTML: %{error}' imports: errors: + empty: Tom CSV-fil + incompatible_type: Inkompatibel med den valda importtypen invalid_csv_file: 'Ogiltig CSV-fil. Felmeddelande: %{error}' over_rows_processing_limit: innehåller fler än %{count} rader + too_large: Filen är för stor + failures: Misslyckanden + imported: Importerade + mismatched_types_warning: Det verkar som om du har valt fel typ för denna import. Var god dubbelkolla. modes: merge: Slå ihop merge_long: Behåll befintliga uppgifter och lägg till nya overwrite: Skriv över overwrite_long: Ersätt de nuvarande uppgifterna med de nya + overwrite_preambles: + blocking_html: Du är på väg att ersätta din blockeringslista med upp till %{total_items} konton från %{filename}. + bookmarks_html: Du är på väg att ersätta din blockeringslista med upp till %{total_items} inlägg från %{filename}. + domain_blocking_html: Du är på väg att ersätta din blockeringslista med upp till %{total_items} domäner från %{filename}. + following_html: Du är på väg till följ upp till %{total_items} konton från %{filename} och sluta följa någon annan. + lists_html: Du är på väg att ersätta dina listor med innehållet i %{filename}. Upp till %{total_items} konton kommer att läggas till i nya listor. + muting_html: Du är på väg att ersätta din lista med tystade konton med upp till %{total_items} konton från %{filename}. + preambles: + blocking_html: Du är på väg att blockera med upp till %{total_items} konton från %{filename}. + bookmarks_html: Du håller på att lägga upp till %{total_items} inlägg från %{filename} till dina bokmärken. + domain_blocking_html: Du är på väg att blockera upp till %{total_items} domäner från %{filename}. + following_html: Du är på väg att följa upp till %{total_items} konton från %{filename}. + lists_html: Du håller på att lägga upp till %{total_items} konton från %{filename} till dina listor. Nya listor kommer att skapas om det inte finns någon lista att lägga till. + muting_html: Du är på väg att tysta upp till %{total_items} konton från %{filename}. preface: Du kan importera data som du exporterat från en annan instans, till exempel en lista över personer du följer eller blockerar. + recent_imports: Nyligen importerade + states: + finished: Klar + in_progress: Pågår + scheduled: Planerad + unconfirmed: Obekräftade + status: Status success: Dina uppgifter har laddats upp och kommer att behandlas snarast + time_started: Började vid + titles: + blocking: Importerar blockerade konton + bookmarks: Importerar bokmärken + domain_blocking: Importerar blockerade domäner + following: Importerar följda konton + lists: Importerar listor + muting: Importerar tystade konton + type: Typ av import + type_groups: + constructive: Följer & bokmärken + destructive: Blockeringar & tystade types: blocking: Lista av blockerade bookmarks: Bokmärken domain_blocking: Domänblockeringslista following: Lista av följare + lists: Listor muting: Lista av nertystade upload: Ladda upp invites: @@ -1252,6 +1382,21 @@ sv: failed_sign_in_html: Misslyckat inloggningsförsök med %{method} från %{ip} (%{browser}) successful_sign_in_html: Lyckad inloggning med %{method} från %{ip} (%{browser}) title: Autentiseringshistorik + mail_subscriptions: + unsubscribe: + action: Ja, avsluta prenumerationen + complete: Prenumeration avslutad + confirmation_html: Är du säker på att du vill avregistrera dig från att ta emot %{type} för Mastodon på %{domain} till din e-post på %{email}? Du kan alltid återprenumerera på dina e-postmeddelandeinställningar. + emails: + notification_emails: + favourite: favoritaviseringsmejl + follow: följaviseringsmejl + follow_request: följbegärningsmejl + mention: aviseringsmejl för inlägg där du nämns + reblog: aviseringsmejl för boostade inlägg + resubscribe_html: Om du slutat prenumerera av misstag kan du återprenumerera i dina e-postaviseringsinställningar. + success_html: Du får inte längre %{type} för Mastodon på %{domain} till din e-post på %{email}. + title: Avsluta prenumeration media_attachments: validations: images_and_video: Det går inte att bifoga en video till ett inlägg som redan innehåller bilder @@ -1331,6 +1476,7 @@ sv: update: subject: "%{name} redigerade ett inlägg" notifications: + administration_emails: Admin e-postaviseringar email_events: Händelser för e-postnotiser email_events_hint: 'Välj händelser som du vill ta emot aviseringar för:' other_settings: Andra aviseringsinställningar @@ -1367,12 +1513,22 @@ sv: expired: Undersökningen har redan avslutats invalid_choice: Det valda röstalternativet finns inte over_character_limit: kan inte vara längre än %{max} tecken var + self_vote: Du kan inte rösta i dina egna omröstningar too_few_options: måste ha mer än ett objekt too_many_options: kan inte innehålla mer än %{max} objekt preferences: other: Annat posting_defaults: Standardinställningar för inlägg public_timelines: Publika tidslinjer + privacy: + hint_html: "Anpassa hur du vill att din profil och dina inlägg ska hittas. En mängd funktioner i Mastodon kan hjälpa dig att nå en bredare publik när den är aktiverad. Ta en stund att granska dessa inställningar för att se att de passar ditt användningsfall." + privacy: Integritet + privacy_hint_html: Kontrollera hur mycket du vill avslöja till förmån för andra. Andra upptäcker intressanta profiler och coola appar genom att bläddra bland vad andra följer och se vilka appar de lägger upp från, men du kanske föredrar att hålla det dolt. + reach: Räckvidd + reach_hint_html: Kontrollera om du vill bli upptäckt och följd av nya människor. Vill du att dina inlägg ska visas på Utforska-skärmen? Vill du att andra människor ska se dig i sina rekommendationer av andra att följa? Vill du acceptera alla nya följare automatiskt, eller ha detaljerad kontroll över varenda en? + search: Sök + search_hint_html: Styr hur du vill bli funnen. Vill du att folk ska hitta dig efter vad du publicerat om? Vill du att personer utanför Mastodon ska hitta din profil när du söker på webben? Observera att total uteslutning från alla sökmotorer inte kan garanteras för offentlig information. + title: Integritet och räckvidd privacy_policy: title: Integritetspolicy reactions: @@ -1381,7 +1537,11 @@ sv: unrecognized_emoji: är inte en igenkänd emoji relationships: activity: Kontoaktivitet + confirm_follow_selected_followers: Är du säker på att du vill följa valda följare? + confirm_remove_selected_followers: Är du säker på att du vill ta bort valda följare? + confirm_remove_selected_follows: Är du säker på att du vill ta bort valda följare? dormant: Vilande + follow_failure: Kan inte följa några av de valda kontona. follow_selected_followers: Följ valda personer followers: Följare following: Följer @@ -1421,6 +1581,7 @@ sv: electron: Electron firefox: Firefox generic: Okänd browser + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1430,6 +1591,7 @@ sv: qq: QQ browser safari: Safari uc_browser: UC Browser + unknown_browser: Okänd browser weibo: Weibo current_session: Nuvarande session description: "%{browser} på %{platform}" @@ -1442,9 +1604,10 @@ sv: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: okänd plattform + unknown_platform: Okänd plattform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1515,7 +1678,6 @@ sv: show_newer: Visa nyare show_older: Visa äldre show_thread: Visa tråd - sign_in_to_participate: Logga in för att delta i konversationen title: '%{name}: "%{quote}"' visibilities: direct: Direkt @@ -1557,12 +1719,10 @@ sv: '7889238': 3 månader min_age_label: Åldersgräns min_favs: Behåll favoritmarkerade inlägg i minst - min_favs_hint: Raderar inte något av dina inlägg som har blivit favoritmarkerat minst detta antal gånger. Lämna tomt för att radera inlägg oavsett antal favoritmarkeringar + min_favs_hint: Raderar inte några av dina inlägg som har fått minst detta antalet av favoritmarkeringar. Lämna tomt för att ta bort inlägg oavsett hur många favoritmarkeringar de har fått min_reblogs: Behåll boostade inlägg i minst min_reblogs_hint: Raderar inte något av dina inlägg som har blivit boostat minst detta antal gånger. Lämna tomt för att radera inlägg oavsett antal boostar stream_entries: - pinned: Fäst inlägg - reblogged: boostad sensitive_content: Känsligt innehåll strikes: errors: @@ -1575,9 +1735,14 @@ sv: mastodon-light: Mastodon (ljust) time: formats: - default: "%b %d, %Y, %H:%M" + default: "%d %b %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Den server-omfattande användningskvoten för översättningstjänsten har överskridits. + too_many_requests: Det har nyligen kommit för många förfrågningar till översättningstjänsten. two_factor_authentication: add: Lägg till disable: Inaktivera @@ -1657,13 +1822,18 @@ sv: title: Välkommen ombord, %{name}! users: follow_limit_reached: Du kan inte följa fler än %{limit} personer + go_to_sso_account_settings: Gå till din identitetsleverantörs kontoinställningar invalid_otp_token: Ogiltig tvåfaktorskod otp_lost_help_html: Om du förlorat åtkomst till båda kan du komma i kontakt med %{email} seamless_external_login: Du är inloggad via en extern tjänst, inställningar för lösenord och e-post är därför inte tillgängliga. signed_in_as: 'Inloggad som:' verification: - explanation_html: 'Du kan verifiera dig själv som ägare av länkar i din profilmetadata, genom att på den länkade webbplatsen även länka tillbaka till din Mastodon-profil. Länken tillbaka måste ha attributet rel="me". Textinnehållet i länken spelar ingen roll. Här är ett exempel:' + extra_instructions_html: Tips: Länken på din webbplats kan vara osynlig. Den viktiga delen är rel="me" som förhindrar personifiering på webbplatser med användargenererat innehåll. Du kan även använda en länk tagg i huvudet på sidan istället för en, men HTML:en måste vara tillgänglig utan att exekvera JavaScript. + here_is_how: Så här gör du + hint_html: "Verifiera din identitet på Mastodon är för alla. Baserat på öppna webbstandarder, nu och för evigt fria. Allt du behöver är en personlig webbplats som folk känner igen dig med. När du länkar till denna webbplats från din profil kommer vi att kontrollera att webbplatsen länkar tillbaka till din profil och visa en visuell indikator på den." + instructions_html: Kopiera och klistra in koden nedan in i HTML-koden på din webbplats. Lägg sedan till adressen till din webbplats i ett av de extra fälten på din profil från fliken "Redigera profil" och spara ändringar. verification: Bekräftelse + verified_links: Dina verifierade länkar webauthn_credentials: add: Lägg till ny säkerhetsnyckel create: diff --git a/config/locales/szl.yml b/config/locales/szl.yml index 2e059c51ac..442f85d4e7 100644 --- a/config/locales/szl.yml +++ b/config/locales/szl.yml @@ -1,10 +1 @@ ---- szl: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/ta.yml b/config/locales/ta.yml index 2d2bce86ad..b035a602c2 100644 --- a/config/locales/ta.yml +++ b/config/locales/ta.yml @@ -191,20 +191,10 @@ ta: localization: body: மாஸ்டோடான் தன்னார்வலர்களால் மொழிபெயர்க்கப்படுகிறது. guide_link_text: அனைவரும் பங்களிக்கலாம். - authorize_follow: - already_requested: இக்கணக்கைப் பின்தொடரும் கோரிக்கையை நீங்கள் ஏற்கனவே அனுப்பிவிட்டீர்கள் crypto: errors: invalid_key: ஒரு முறையான Ed25519 அல்லது Curve25519 key அல்ல invalid_signature: ஒரு முறையான Ed25519 அடையாளம் அல்ல - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. filters: index: empty: தடுப்புகள் ஏதும் இல்லை. diff --git a/config/locales/tai.yml b/config/locales/tai.yml index f347ac6200..305da2e07e 100644 --- a/config/locales/tai.yml +++ b/config/locales/tai.yml @@ -1,10 +1 @@ ---- tai: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/te.yml b/config/locales/te.yml index e3b3f97ab6..a5eb8d7794 100644 --- a/config/locales/te.yml +++ b/config/locales/te.yml @@ -70,11 +70,3 @@ te: moderation_notes: మోడరేషన్ నోట్స్ most_recent_activity: ఇటీవల యాక్టివిటీ most_recent_ip: ఇటీవలి IP - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/th.yml b/config/locales/th.yml index 8081559db8..781c3df29c 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -89,6 +89,7 @@ th: moderation: active: ใช้งานอยู่ all: ทั้งหมด + disabled: ปิดใช้งานอยู่ pending: รอดำเนินการ silenced: จำกัดอยู่ suspended: ระงับอยู่ @@ -114,15 +115,15 @@ th: 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} ออกสำเร็จ removed_header_msg: เอาภาพส่วนหัวของ %{username} ออกสำเร็จ resend_confirmation: - already_confirmed: ผู้ใช้นี้ได้รับการยืนยันอยู่แล้ว - send: ส่งอีเมลยืนยันใหม่ - success: ส่งอีเมลยืนยันสำเร็จ! + already_confirmed: ผู้ใช้นี้ได้รับการยืนยันไปแล้ว + send: ส่งลิงก์การยืนยันใหม่ + success: ส่งลิงก์การยืนยันสำเร็จ! reset: รีเซ็ต reset_password: ตั้งรหัสผ่านใหม่ resubscribe: บอกรับใหม่ @@ -130,6 +131,7 @@ th: search: ค้นหา search_same_email_domain: ผู้ใช้อื่น ๆ ที่มีโดเมนอีเมลเดียวกัน search_same_ip: ผู้ใช้อื่น ๆ ที่มี IP เดียวกัน + security: ความปลอดภัย security_measures: only_password: รหัสผ่านเท่านั้น password_and_2fa: รหัสผ่านและ 2FA @@ -147,7 +149,7 @@ th: suspend: ระงับ suspended: ระงับอยู่ suspension_irreversible: ลบข้อมูลของบัญชีนี้อย่างถาวรแล้ว คุณสามารถเลิกระงับบัญชีเพื่อทำให้บัญชีใช้งานได้แต่จะไม่กู้คืนข้อมูลใด ๆ ที่บัญชีมีก่อนหน้านี้ - suspension_reversible_hint_html: ระงับบัญชีแล้ว และจะเอาข้อมูลออกอย่างสมบูรณ์ใน %{date} จนกว่าจะถึงตอนนั้น สามารถกู้คืนบัญชีได้โดยไม่มีผลร้ายใด ๆ หากคุณต้องการเอาข้อมูลของบัญชีทั้งหมดออกในทันที คุณสามารถทำได้ด้านล่าง + suspension_reversible_hint_html: ระงับบัญชีแล้ว และจะเอาข้อมูลออกอย่างสมบูรณ์ใน %{date} จนกว่าจะถึงตอนนั้น สามารถคืนค่าบัญชีได้โดยไม่มีผลร้ายใด ๆ หากคุณต้องการเอาข้อมูลของบัญชีทั้งหมดออกทันที คุณสามารถทำได้ด้านล่าง title: บัญชี unblock_email: เลิกปิดกั้นที่อยู่อีเมล unblocked_email_msg: เลิกปิดกั้นที่อยู่อีเมลของ %{username} สำเร็จ @@ -206,7 +208,7 @@ th: reject_user: ปฏิเสธผู้ใช้ remove_avatar_user: เอาภาพประจำตัวออก reopen_report: เปิดรายงานใหม่ - resend_user: ส่งจดหมายยืนยันใหม่ + resend_user: ส่งจดหมายการยืนยันใหม่ reset_password_user: ตั้งรหัสผ่านใหม่ resolve_report: แก้ปัญหารายงาน sensitive_account: บังคับให้บัญชีละเอียดอ่อน @@ -265,7 +267,7 @@ th: reject_user_html: "%{name} ได้ปฏิเสธการลงทะเบียนจาก %{target}" remove_avatar_user_html: "%{name} ได้เอาภาพประจำตัวของ %{target} ออก" reopen_report_html: "%{name} ได้เปิดรายงาน %{target} ใหม่" - resend_user_html: "%{name} ได้ส่งอีเมลยืนยันสำหรับ %{target} ใหม่" + resend_user_html: "%{name} ได้ส่งอีเมลการยืนยันสำหรับ %{target} ใหม่" reset_password_user_html: "%{name} ได้ตั้งรหัสผ่านของผู้ใช้ %{target} ใหม่" resolve_report_html: "%{name} ได้แก้ปัญหารายงาน %{target}" sensitive_account_html: "%{name} ได้ทำเครื่องหมายสื่อของ %{target} ว่าละเอียดอ่อน" @@ -304,6 +306,7 @@ th: unpublish: เลิกเผยแพร่ unpublished_msg: เลิกเผยแพร่ประกาศสำเร็จ! updated_msg: อัปเดตประกาศสำเร็จ! + critical_update_pending: รอดำเนินการการอัปเดตสำคัญ custom_emojis: assign_category: กำหนดหมวดหมู่ by_domain: โดเมน @@ -327,7 +330,7 @@ th: new: title: เพิ่มอีโมจิที่กำหนดเองใหม่ no_emoji_selected: ไม่มีการเปลี่ยนแปลงอีโมจิเนื่องจากไม่มีการเลือก - not_permitted: คุณไม่ได้รับอนุญาตให้ทำการกระทำนี้ + not_permitted: ไม่อนุญาตให้คุณทำการกระทำนี้ overwrite: เขียนทับ shortcode: รหัสย่อ shortcode_hint: อย่างน้อย 2 ตัวอักษร เฉพาะตัวอักษรและตัวเลขและขีดล่างเท่านั้น @@ -373,6 +376,15 @@ th: undo: ไม่อนุญาตการติดต่อกับภายนอกกับโดเมน domain_blocks: add_new: เพิ่มการปิดกั้นโดเมนใหม่ + confirm_suspension: + cancel: ยกเลิก + confirm: ระงับ + permanent_action: การเลิกทำการระงับจะไม่คืนค่าข้อมูลหรือความสัมพันธ์ใด ๆ + preamble_html: คุณกำลังจะระงับ %{domain} และโดเมนย่อยของโดเมน + remove_all_data: นี่จะเอาเนื้อหา, สื่อ และข้อมูลโปรไฟล์ทั้งหมดสำหรับบัญชีของโดเมนนี้ออกจากเซิร์ฟเวอร์ของคุณ + stop_communication: เซิร์ฟเวอร์ของคุณจะหยุดการสื่อสารกับเซิร์ฟเวอร์เหล่านี้ + title: ยืนยันการปิดกั้นโดเมนสำหรับ %{domain} + undo_relationships: นี่จะเลิกทำความสัมพันธ์การติดตามใด ๆ ระหว่างบัญชีของเซิร์ฟเวอร์เหล่านี้และของคุณ created_msg: ตอนนี้กำลังประมวลผลการปิดกั้นโดเมน destroyed_msg: เลิกทำการปิดกั้นโดเมนแล้ว domain: โดเมน @@ -391,9 +403,9 @@ th: suspend: ระงับ title: การปิดกั้นโดเมนใหม่ no_domain_block_selected: ไม่มีการเปลี่ยนแปลงการปิดกั้นโดเมนเนื่องจากไม่มีการเลือก - not_permitted: คุณไม่ได้รับอนุญาตให้ทำการกระทำนี้ + not_permitted: ไม่อนุญาตให้คุณทำการกระทำนี้ obfuscate: ทำให้ชื่อโดเมนคลุมเครือ - obfuscate_hint: ปิดบังชื่อโดเมนบางส่วนในรายการหากมีการเปิดใช้งานการประกาศรายการการจำกัดโดเมน + obfuscate_hint: ทำให้ชื่อโดเมนในรายการคลุมเครือบางส่วนหากมีการเปิดใช้งานการประกาศรายการการจำกัดโดเมน private_comment: ความคิดเห็นส่วนตัว private_comment_hint: ความคิดเห็นเกี่ยวกับการจำกัดโดเมนนี้สำหรับการใช้งานภายในโดยผู้ควบคุม public_comment: ความคิดเห็นสาธารณะ @@ -419,6 +431,7 @@ th: resolve: แปลงที่อยู่โดเมน title: ปิดกั้นโดเมนอีเมลใหม่ no_email_domain_block_selected: ไม่มีการเปลี่ยนแปลงการปิดกั้นโดเมนอีเมลเนื่องจากไม่มีการเลือก + not_permitted: ไม่ได้รับอนุญาต resolved_dns_records_hint_html: ชื่อโดเมนแปลงที่อยู่เป็นโดเมน MX ดังต่อไปนี้ ซึ่งท้ายที่สุดแล้วจะรับผิดชอบสำหรับการยอมรับอีเมล การปิดกั้นโดเมน MX จะปิดกั้นการลงทะเบียนจากที่อยู่อีเมลใด ๆ ซึ่งใช้โดเมน MX เดียวกัน แม้ว่าชื่อโดเมนที่ปรากฏจะแตกต่างกันก็ตาม ระวังอย่าปิดกั้นผู้ให้บริการอีเมลรายใหญ่ resolved_through_html: แปลงที่อยู่ผ่าน %{domain} title: โดเมนอีเมลที่ปิดกั้นอยู่ @@ -463,6 +476,7 @@ th: content_policies: comment: หมายเหตุภายใน description_html: คุณสามารถกำหนดนโยบายเนื้อหาที่จะนำไปใช้กับบัญชีทั้งหมดจากโดเมนนี้และโดเมนย่อยใดก็ตามของโดเมน + limited_federation_mode_description_html: คุณสามารถเลือกได้ว่าจะอนุญาตการติดต่อกับภายนอกกับโดเมนนี้หรือไม่ policies: reject_media: ปฏิเสธสื่อ reject_reports: ปฏิเสธรายงาน @@ -564,7 +578,7 @@ th: mark_as_sensitive_description_html: จะทำเครื่องหมายสื่อในโพสต์ที่รายงานว่าละเอียดอ่อนและจะบันทึกการดำเนินการเพื่อช่วยให้คุณเลื่อนระดับการละเมิดในอนาคตโดยบัญชีเดียวกัน other_description_html: ดูตัวเลือกเพิ่มเติมสำหรับการควบคุมพฤติกรรมของบัญชีและปรับแต่งการสื่อสารไปยังบัญชีที่รายงาน resolve_description_html: จะไม่ใช้การกระทำต่อบัญชีที่รายงาน ไม่มีการบันทึกการดำเนินการ และจะปิดรายงาน - silence_description_html: บัญชีจะปรากฏแก่เฉพาะผู้ที่ติดตามโปรไฟล์อยู่แล้วหรือค้นหาโปรไฟล์ด้วยตนเองเท่านั้น จำกัดการเข้าถึงโปรไฟล์อย่างมาก สามารถแปลงกลับได้เสมอ ปิดรายงานต่อบัญชีนี้ทั้งหมด + silence_description_html: บัญชีจะปรากฏแก่เฉพาะผู้ที่ติดตามโปรไฟล์อยู่แล้วหรือค้นหาโปรไฟล์ด้วยตนเองเท่านั้น จำกัดการเข้าถึงของโปรไฟล์อย่างมาก สามารถแปลงกลับได้เสมอ ปิดรายงานต่อบัญชีนี้ทั้งหมด suspend_description_html: บัญชีและเนื้อหาของบัญชีทั้งหมดจะเข้าถึงไม่ได้และได้รับการลบในที่สุด และการโต้ตอบกับบัญชีจะเป็นไปไม่ได้ แปลงกลับได้ภายใน 30 วัน ปิดรายงานต่อบัญชีนี้ทั้งหมด actions_description_html: ตัดสินใจว่าการกระทำใดที่จะใช้เพื่อแก้ปัญหารายงานนี้ หากคุณใช้การกระทำที่เป็นการลงโทษต่อบัญชีที่รายงาน จะส่งการแจ้งเตือนอีเมลถึงเขา ยกเว้นเมื่อมีการเลือกหมวดหมู่ สแปม actions_description_remote_html: ตัดสินใจว่าการกระทำใดที่จะใช้เพื่อแก้ปัญหารายงานนี้ นี่จะมีผลต่อวิธีที่เซิร์ฟเวอร์ ของคุณ สื่อสารกับบัญชีระยะไกลนี้และจัดการเนื้อหาของบัญชีเท่านั้น @@ -573,11 +587,13 @@ th: assign_to_self: มอบหมายให้ฉัน assigned: ผู้ควบคุมที่ได้รับมอบหมาย by_target_domain: โดเมนของบัญชีที่ได้รับการรายงาน + cancel: ยกเลิก category: หมวดหมู่ category_description_html: จะอ้างถึงเหตุผลที่บัญชีและ/หรือเนื้อหานี้ได้รับการรายงานในการสื่อสารกับบัญชีที่ได้รับการรายงาน comment: none: ไม่มี comment_description_html: 'เพื่อให้ข้อมูลเพิ่มเติม %{name} ได้เขียน:' + confirm: ยืนยัน confirm_action: ยืนยันการกระทำการควบคุมต่อ @%{acct} created_at: รายงานเมื่อ delete_and_resolve: ลบโพสต์ @@ -592,7 +608,7 @@ th: create_and_resolve: แก้ปัญหาโดยมีหมายเหตุ create_and_unresolve: เปิดใหม่โดยมีหมายเหตุ delete: ลบ - placeholder: อธิบายว่าการกระทำใดที่ใช้ หรือการอัปเดตที่เกี่ยวข้องอื่นใด... + placeholder: อธิบายว่ามีการใช้การกระทำใด หรือการอัปเดตที่เกี่ยวข้องอื่นใด... title: หมายเหตุ notes_description_html: ดูและฝากหมายเหตุถึงผู้ควบคุมอื่น ๆ และตัวคุณเองในอนาคต processed_msg: 'ประมวลผลรายงาน #%{id} สำเร็จ' @@ -670,7 +686,7 @@ th: manage_invites: จัดการคำเชิญ manage_invites_description: อนุญาตให้ผู้ใช้เรียกดูและปิดใช้งานลิงก์เชิญ manage_reports: จัดการรายงาน - manage_reports_description: อนุญาตให้ผู้ใช้ตรวจทานรายงานและทำการกระทำการควบคุมต่อรายงาน + manage_reports_description: อนุญาตให้ผู้ใช้ตรวจทานรายงานและทำการกระทำการควบคุมต่อรายงานเหล่านั้น manage_roles: จัดการบทบาท manage_roles_description: อนุญาตให้ผู้ใช้จัดการและกำหนดบทบาทที่ต่ำกว่าบทบาทของเขา manage_rules: จัดการกฎ @@ -682,7 +698,7 @@ th: manage_user_access: จัดการการเข้าถึงของผู้ใช้ manage_user_access_description: อนุญาตให้ผู้ใช้ปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยของผู้ใช้อื่น เปลี่ยนที่อยู่อีเมลของเขา และตั้งรหัสผ่านของเขาใหม่ manage_users: จัดการผู้ใช้ - manage_users_description: อนุญาตให้ผู้ใช้ดูรายละเอียดของผู้ใช้อื่น ๆ และทำการกระทำการควบคุมต่อผู้ใช้ + manage_users_description: อนุญาตให้ผู้ใช้ดูรายละเอียดของผู้ใช้อื่น ๆ และทำการกระทำการควบคุมต่อผู้ใช้เหล่านั้น manage_webhooks: จัดการเว็บฮุค manage_webhooks_description: อนุญาตให้ผู้ใช้ตั้งค่าเว็บฮุคสำหรับเหตุการณ์การดูแล view_audit_log: ดูรายการบันทึกการตรวจสอบ @@ -695,7 +711,7 @@ th: rules: add_new: เพิ่มกฎ delete: ลบ - description_html: ขณะที่ส่วนใหญ่อ้างว่าได้อ่านและยอมรับเงื่อนไขการให้บริการ ผู้คนมักจะไม่อ่านจนกว่าหลังจากปัญหาเกิดขึ้น ทำให้การดูกฎของเซิร์ฟเวอร์ของคุณอย่างรวดเร็วง่ายขึ้นโดยการระบุกฎของเซิร์ฟเวอร์ในรายการสัญลักษณ์แสดงหัวข้อย่อยแบบแบน พยายามทำให้กฎแต่ละข้อสั้นและเรียบง่าย แต่พยายามอย่าแบ่งกฎเป็นหลายรายการแยกเช่นกัน + description_html: ขณะที่ส่วนใหญ่อ้างว่าได้อ่านและยอมรับเงื่อนไขการให้บริการ ผู้คนมักจะไม่อ่านจนกว่าหลังจากปัญหาเกิดขึ้น ทำให้การดูกฎของเซิร์ฟเวอร์ของคุณอย่างรวดเร็วง่ายขึ้นโดยการระบุกฎเหล่านั้นในรายการสัญลักษณ์แสดงหัวข้อย่อยแบบแบน พยายามทำให้กฎแต่ละข้อสั้นและเรียบง่าย แต่พยายามอย่าแบ่งกฎเหล่านั้นเป็นหลายรายการแยกเช่นกัน edit: แก้ไขกฎ empty: ยังไม่ได้กำหนดกฎของเซิร์ฟเวอร์ title: กฎของเซิร์ฟเวอร์ @@ -709,8 +725,11 @@ th: preamble: ปรับแต่งส่วนติดต่อเว็บของ Mastodon title: ลักษณะที่ปรากฏ branding: - preamble: ตราสินค้าของเซิร์ฟเวอร์ของคุณสร้างความแตกต่างตราสินค้าของเซิร์ฟเวอร์ของคุณจากเซิร์ฟเวอร์อื่น ๆ ในเครือข่าย อาจแสดงข้อมูลนี้ข้ามสภาพแวดล้อมที่หลากหลาย เช่น ส่วนติดต่อเว็บของ Mastodon, แอปพลิเคชันเนทีฟ, ในการแสดงตัวอย่างลิงก์ในเว็บไซต์อื่น ๆ และภายในแอปการส่งข้อความ และอื่น ๆ ด้วยเหตุผลนี้ จึงเป็นการดีที่สุดที่จะทำให้ข้อมูลนี้ชัดเจน สั้น และกระชับ + preamble: ตราสินค้าของเซิร์ฟเวอร์ของคุณสร้างความแตกต่างของตราสินค้าจากเซิร์ฟเวอร์อื่น ๆ ในเครือข่าย อาจแสดงข้อมูลนี้ทั่วทั้งสภาพแวดล้อมที่หลากหลาย เช่น ส่วนติดต่อเว็บของ Mastodon, แอปพลิเคชันเนทีฟ, ในการแสดงตัวอย่างลิงก์ในเว็บไซต์อื่น ๆ และภายในแอปการส่งข้อความ และอื่น ๆ ด้วยเหตุผลนี้ จึงเป็นการดีที่สุดที่จะทำให้ข้อมูลนี้ชัดเจน สั้น และกระชับ title: ตราสินค้า + captcha_enabled: + desc_html: สิ่งนี้พึ่งพาสคริปต์ภายนอกจาก hCaptcha ซึ่งอาจเป็นข้อกังวลด้านความปลอดภัยและความเป็นส่วนตัว นอกจากนี้ สิ่งนี้สามารถทำให้กระบวนการการลงทะเบียนเข้าถึงได้น้อยลงอย่างมีนัยสำคัญสำหรับผู้คนบางส่วน (โดยเฉพาะอย่างยิ่งผู้พิการ) ด้วยเหตุผลเหล่านี้ โปรดพิจารณามาตรการทางเลือก เช่น การลงทะเบียนตามการอนุมัติหรือตามคำเชิญ + title: ต้องให้ผู้ใช้ใหม่แก้ CAPTCHA เพื่อยืนยันบัญชีของเขา content_retention: preamble: ควบคุมวิธีการจัดเก็บเนื้อหาที่ผู้ใช้สร้างขึ้นใน Mastodon title: การเก็บรักษาเนื้อหา @@ -738,10 +757,27 @@ th: approved: ต้องการการอนุมัติสำหรับการลงทะเบียน none: ไม่มีใครสามารถลงทะเบียน open: ใครก็ตามสามารถลงทะเบียน + security: + authorized_fetch: ต้องมีการรับรองความถูกต้องจากเซิร์ฟเวอร์ที่ติดต่อกับภายนอก + authorized_fetch_hint: การต้องการการรับรองความถูกต้องจากเซิร์ฟเวอร์ที่ติดต่อกับภายนอกทำให้การบังคับใช้การปิดกั้นทั้งระดับผู้ใช้และระดับเซิร์ฟเวอร์เข้มงวดขึ้น อย่างไรก็ตาม สิ่งนี้มาพร้อมกับต้นทุนที่ต้องแลกด้วยผลเสียด้านประสิทธิภาพ ลดการเข้าถึงการตอบกลับของคุณ และอาจก่อให้เกิดปัญหาความเข้ากันได้กับบริการที่ติดต่อกับภายนอกบางอย่าง นอกจากนี้ สิ่งนี้จะไม่ป้องกันตัวดำเนินการเฉพาะจากการดึงข้อมูลโพสต์และบัญชีสาธารณะของคุณ + authorized_fetch_overridden_hint: คุณไม่สามารถเปลี่ยนการตั้งค่านี้ได้ในปัจจุบันเนื่องจากมีการเขียนทับการตั้งค่าโดยตัวแปรสภาพแวดล้อม + federation_authentication: การบังคับใช้การรับรองความถูกต้องการติดต่อกับภายนอก title: การตั้งค่าเซิร์ฟเวอร์ site_uploads: delete: ลบไฟล์ที่อัปโหลด destroyed_msg: ลบการอัปโหลดไซต์สำเร็จ! + software_updates: + critical_update: สำคัญ — โปรดอัปเดตอย่างรวดเร็ว + description: ขอแนะนำให้ทำให้การติดตั้ง Mastodon ของคุณทันสมัยอยู่เสมอเพื่อรับประโยชน์จากการแก้ไขและคุณลักษณะล่าสุด ยิ่งไปกว่านั้น บางครั้งก็เป็นสิ่งสำคัญที่จะอัปเดต Mastodon ในเวลาที่เหมาะสมเพื่อหลีกเลี่ยงปัญหาความปลอดภัย ด้วยเหตุผลเหล่านี้ Mastodon จึงตรวจสอบการอัปเดตทุก 30 นาที และจะแจ้งเตือนคุณตามการกำหนดลักษณะการแจ้งเตือนอีเมลของคุณ + documentation_link: เรียนรู้เพิ่มเติม + release_notes: บันทึกประจำรุ่น + title: การอัปเดตที่พร้อมใช้งาน + type: ชนิด + types: + major: รุ่นหลัก + minor: รุ่นรอง + patch: รุ่นแพทช์ — การแก้ไขข้อบกพร่องและการเปลี่ยนแปลงที่ง่ายต่อการนำไปใช้ + version: รุ่น statuses: account: ผู้สร้าง application: แอปพลิเคชัน @@ -778,9 +814,24 @@ th: suspend: "%{name} ได้ระงับบัญชีของ %{target}" appeal_approved: อุทธรณ์แล้ว appeal_pending: รอดำเนินการการอุทธรณ์ + appeal_rejected: ปฏิเสธการอุทธรณ์แล้ว system_checks: database_schema_check: - message_html: มีการโยกย้ายฐานข้อมูลที่รอดำเนินการ โปรดเรียกใช้การโยกย้ายเพื่อให้แน่ใจว่าแอปพลิเคชันทำงานตามที่คาดไว้ + message_html: มีการโยกย้ายฐานข้อมูลที่รอดำเนินการ โปรดเรียกใช้การโยกย้ายเหล่านั้นเพื่อให้แน่ใจว่าแอปพลิเคชันทำงานตามที่คาดไว้ + elasticsearch_health_red: + message_html: คลัสเตอร์ Elasticsearch ทำงานได้ไม่ดี (สถานะสีแดง) คุณลักษณะการค้นหาไม่พร้อมใช้งาน + elasticsearch_health_yellow: + message_html: คลัสเตอร์ Elasticsearch ทำงานได้ไม่ดี (สถานะสีเหลือง) คุณอาจต้องการสืบสวนสาเหตุ + elasticsearch_index_mismatch: + message_html: การแมปดัชนี Elasticsearch ล้าสมัยแล้ว โปรดเรียกใช้ tootctl search deploy --only=%{value} + elasticsearch_preset: + action: ดูเอกสารประกอบ + message_html: คลัสเตอร์ Elasticsearch ของคุณมีมากกว่าหนึ่งโหนด แต่ไม่ได้กำหนดค่า Mastodon ให้ใช้โหนดเหล่านั้น + elasticsearch_preset_single_node: + action: ดูเอกสารประกอบ + message_html: คลัสเตอร์ Elasticsearch ของคุณมีเพียงหนึ่งโหนดเท่านั้น ควรตั้ง ES_PRESET เป็น single_node_cluster + elasticsearch_reset_chewy: + message_html: ดัชนีระบบ Elasticsearch ของคุณล้าสมัยแล้วเนื่องจากการเปลี่ยนแปลงการตั้งค่า โปรดเรียกใช้ tootctl search deploy --reset-chewy เพื่ออัปเดตดัชนี elasticsearch_running_check: message_html: ไม่สามารถเชื่อมต่อกับ Elasticsearch โปรดตรวจสอบว่าซอฟต์แวร์กำลังทำงาน หรือปิดใช้งานการค้นหาข้อความแบบเต็ม elasticsearch_version_check: @@ -791,6 +842,18 @@ th: message_html: คุณไม่ได้กำหนดกฎของเซิร์ฟเวอร์ใด ๆ sidekiq_process_check: message_html: ไม่มีกระบวนการ Sidekiq ที่กำลังทำงานสำหรับคิว %{value} โปรดตรวจทานการกำหนดค่า Sidekiq ของคุณ + software_version_critical_check: + action: ดูการอัปเดตที่พร้อมใช้งาน + message_html: มีการอัปเดต Mastodon สำคัญพร้อมใช้งาน โปรดอัปเดตโดยเร็วที่สุดเท่าที่จะทำได้ + software_version_patch_check: + action: ดูการอัปเดตที่พร้อมใช้งาน + message_html: มีการอัปเดต Mastodon ที่แก้ไขข้อบกพร่องพร้อมใช้งาน + upload_check_privacy_error: + action: ตรวจสอบที่นี่สำหรับข้อมูลเพิ่มเติม + message_html: "เว็บเซิร์ฟเวอร์ของคุณกำหนดค่าไม่ถูกต้อง ความเป็นส่วนตัวของผู้ใช้ของคุณตกอยู่ในความเสี่ยง" + upload_check_privacy_error_object_storage: + action: ตรวจสอบที่นี่สำหรับข้อมูลเพิ่มเติม + message_html: "ที่เก็บข้อมูลวัตถุของคุณกำหนดค่าไม่ถูกต้อง ความเป็นส่วนตัวของผู้ใช้ของคุณตกอยู่ในความเสี่ยง" tags: review: สถานะการตรวจทาน updated_msg: อัปเดตการตั้งค่าแฮชแท็กสำเร็จ @@ -812,6 +875,7 @@ th: other: แบ่งปันโดย %{count} คนในช่วงสัปดาห์ที่ผ่านมา title: ลิงก์ที่กำลังนิยม usage_comparison: แบ่งปัน %{today} ครั้งวันนี้ เทียบกับ %{yesterday} เมื่อวานนี้ + not_allowed_to_trend: ไม่ได้รับอนุญาตให้ขึ้นแนวโน้ม only_allowed: อนุญาตเท่านั้น pending_review: การตรวจทานที่รอดำเนินการ preview_card_providers: @@ -823,7 +887,7 @@ th: statuses: allow: อนุญาตโพสต์ allow_account: อนุญาตผู้สร้าง - description_html: นี่คือโพสต์ที่เซิร์ฟเวอร์ของคุณทราบเกี่ยวกับที่กำลังได้รับการแบ่งปันและชื่นชอบเป็นจำนวนมากในปัจจุบันในขณะนี้ โพสต์สามารถช่วยให้ผู้ใช้ใหม่และที่กลับมาของคุณค้นหาผู้คนเพิ่มเติมที่จะติดตาม จะไม่แสดงโพสต์เป็นสาธารณะจนกว่าคุณจะอนุมัติผู้สร้าง และผู้สร้างอนุญาตให้แนะนำบัญชีของเขากับผู้อื่น คุณยังสามารถอนุญาตหรือปฏิเสธโพสต์แต่ละรายการ + description_html: นี่คือโพสต์ที่เซิร์ฟเวอร์ของคุณทราบเกี่ยวกับที่กำลังได้รับการแบ่งปันและชื่นชอบเป็นจำนวนมากในปัจจุบันในขณะนี้ โพสต์สามารถช่วยให้ผู้ใช้ใหม่และที่กลับมาของคุณค้นหาผู้คนเพิ่มเติมที่จะติดตาม จะไม่แสดงโพสต์เป็นสาธารณะจนกว่าคุณจะอนุมัติผู้สร้าง และผู้สร้างอนุญาตให้เสนอแนะบัญชีของเขาแก่ผู้อื่น คุณยังสามารถอนุญาตหรือปฏิเสธโพสต์แต่ละรายการ disallow: ไม่อนุญาตโพสต์ disallow_account: ไม่อนุญาตผู้สร้าง no_status_selected: ไม่มีการเปลี่ยนแปลงโพสต์ที่กำลังนิยมเนื่องจากไม่มีการเลือก @@ -839,10 +903,10 @@ th: tag_servers_dimension: เซิร์ฟเวอร์ยอดนิยม tag_servers_measure: เซิร์ฟเวอร์ต่าง ๆ tag_uses_measure: การใช้งานทั้งหมด - description_html: นี่คือแฮชแท็กที่กำลังปรากฏในโพสต์จำนวนมากที่เซิร์ฟเวอร์ของคุณเห็นในปัจจุบัน แฮชแท็กสามารถช่วยให้ผู้ใช้ของคุณค้นหาสิ่งที่ผู้คนกำลังพูดถึงมากที่สุดในขณะนี้ จะไม่แสดงแฮชแท็กเป็นสาธารณะจนกว่าคุณจะอนุมัติแฮชแท็ก - listable: สามารถแนะนำ + description_html: นี่คือแฮชแท็กที่กำลังปรากฏในโพสต์จำนวนมากที่เซิร์ฟเวอร์ของคุณเห็นในปัจจุบัน แฮชแท็กสามารถช่วยให้ผู้ใช้ของคุณค้นหาสิ่งที่ผู้คนกำลังพูดถึงมากที่สุดในขณะนี้ จะไม่แสดงแฮชแท็กเป็นสาธารณะจนกว่าคุณจะอนุมัติแฮชแท็กเหล่านั้น + listable: สามารถเสนอแนะ no_tag_selected: ไม่มีการเปลี่ยนแปลงแท็กเนื่องจากไม่มีการเลือก - not_listable: จะไม่แนะนำ + not_listable: จะไม่เสนอแนะ not_trendable: จะไม่ปรากฏภายใต้แนวโน้ม not_usable: ไม่สามารถใช้ peaked_on_and_decaying: สูงสุดเมื่อ %{date} ตอนนี้กำลังลง @@ -893,6 +957,9 @@ th: body: "%{target} กำลังอุทธรณ์การตัดสินใจในการควบคุมโดย %{action_taken_by} จาก %{date} ซึ่งเป็น %{type} เขาเขียนว่า:" next_steps: คุณสามารถอนุมัติการอุทธรณ์เพื่อเลิกทำการตัดสินใจในการควบคุม หรือเพิกเฉยต่อการอุทธรณ์ subject: "%{username} กำลังอุทธรณ์การตัดสินใจในการควบคุมใน %{instance}" + new_critical_software_updates: + body: มีการปล่อยรุ่น Mastodon สำคัญใหม่ คุณอาจต้องการอัปเดตโดยเร็วที่สุดเท่าที่จะทำได้! + subject: การอัปเดต Mastodon สำคัญพร้อมใช้งานสำหรับ %{instance}! new_pending_account: body: รายละเอียดของบัญชีใหม่อยู่ด้านล่าง คุณสามารถอนุมัติหรือปฏิเสธใบสมัครนี้ subject: บัญชีใหม่สำหรับตรวจทานใน %{instance} (%{username}) @@ -900,6 +967,9 @@ th: body: "%{reporter} ได้รายงาน %{target}" body_remote: ใครสักคนจาก %{domain} ได้รายงาน %{target} subject: รายงานใหม่สำหรับ %{instance} (#%{id}) + new_software_updates: + body: มีการปล่อยรุ่น Mastodon ใหม่ คุณอาจต้องการอัปเดต! + subject: มีรุ่น Mastodon ใหม่พร้อมใช้งานสำหรับ %{instance}! new_trends: body: 'รายการดังต่อไปนี้จำเป็นต้องมีการตรวจทานก่อนที่จะสามารถแสดงรายการเป็นสาธารณะ:' new_trending_links: @@ -929,24 +999,28 @@ th: guide_link: https://crowdin.com/project/mastodon/th guide_link_text: ทุกคนสามารถมีส่วนร่วม sensitive_content: เนื้อหาที่ละเอียดอ่อน - toot_layout: เค้าโครงโพสต์ application_mailer: notification_preferences: เปลี่ยนการกำหนดลักษณะอีเมล salutation: "%{name}," settings: 'เปลี่ยนการกำหนดลักษณะอีเมล: %{link}' + unsubscribe: เลิกบอกรับ view: 'มุมมอง:' view_profile: ดูโปรไฟล์ view_status: ดูโพสต์ applications: created: สร้างแอปพลิเคชันสำเร็จ destroyed: ลบแอปพลิเคชันสำเร็จ + logout: ออกจากระบบ regenerate_token: สร้างโทเคนการเข้าถึงใหม่ token_regenerated: สร้างโทเคนการเข้าถึงใหม่สำเร็จ warning: ระวังเป็นอย่างสูงกับข้อมูลนี้ อย่าแบ่งปันข้อมูลกับใครก็ตาม! your_token: โทเคนการเข้าถึงของคุณ auth: apply_for_account: ขอบัญชี - change_password: รหัสผ่าน + captcha_confirmation: + help_html: หากคุณมีปัญหาในการแก้ CAPTCHA คุณสามารถติดต่อเราได้ผ่าน %{email} และเราจะสามารถช่วยคุณ + hint_html: อีกเพียงหนึ่งสิ่งเพิ่มเติม! เราจำเป็นต้องยืนยันว่าคุณเป็นมนุษย์ (นี่ก็เพื่อให้เราสามารถกันสแปมออกไป!) แก้ CAPTCHA ด้านล่างและคลิก "ดำเนินการต่อ" + title: การตรวจสอบความปลอดภัย confirmations: wrong_email_hint: หากที่อยู่อีเมลนั้นไม่ถูกต้อง คุณสามารถเปลี่ยนที่อยู่อีเมลได้ในการตั้งค่าบัญชี delete_account: ลบบัญชี @@ -954,8 +1028,8 @@ th: description: prefix_invited_by_user: "@%{name} เชิญคุณเข้าร่วมเซิร์ฟเวอร์ Mastodon นี้!" prefix_sign_up: ลงทะเบียนใน Mastodon วันนี้! - suffix: เมื่อมีบัญชี คุณจะสามารถติดตามผู้คน โพสต์การอัปเดต และแลกเปลี่ยนข้อความกับผู้ใช้จากเซิร์ฟเวอร์ Mastodon และอื่น ๆ! - didnt_get_confirmation: ไม่ได้รับคำแนะนำการยืนยัน? + suffix: ด้วยบัญชี คุณจะสามารถติดตามผู้คน โพสต์การอัปเดต และแลกเปลี่ยนข้อความกับผู้ใช้จากเซิร์ฟเวอร์ Mastodon และอื่น ๆ! + didnt_get_confirmation: ไม่ได้รับลิงก์การยืนยัน? dont_have_your_security_key: ไม่มีกุญแจความปลอดภัยของคุณ? forgot_password: ลืมรหัสผ่านของคุณ? invalid_reset_password_token: โทเคนการตั้งรหัสผ่านใหม่ไม่ถูกต้องหรือหมดอายุแล้ว โปรดขอโทเคนใหม่ @@ -968,27 +1042,40 @@ th: migrate_account_html: หากคุณต้องการเปลี่ยนเส้นทางบัญชีนี้ไปยังบัญชีอื่น คุณสามารถ กำหนดค่าบัญชีที่นี่ or_log_in_with: หรือเข้าสู่ระบบด้วย privacy_policy_agreement_html: ฉันได้อ่านและเห็นด้วยกับ นโยบายความเป็นส่วนตัว + progress: + confirm: ยืนยันอีเมล + details: รายละเอียดของคุณ + review: การตรวจทานของเรา + rules: ยอมรับกฎ providers: cas: CAS saml: SAML register: ลงทะเบียน registration_closed: "%{instance} ไม่ได้กำลังเปิดรับสมาชิกใหม่" - resend_confirmation: ส่งคำแนะนำการยืนยันใหม่ + resend_confirmation: ส่งลิงก์การยืนยันใหม่ reset_password: ตั้งรหัสผ่านใหม่ rules: + accept: ยอมรับ + back: ย้อนกลับ + invited_by: 'คุณสามารถเข้าร่วม %{domain} ได้ด้วยคำเชิญที่คุณได้รับจาก:' preamble: มีการตั้งและบังคับใช้กฎโดยผู้ควบคุมของ %{domain} + preamble_invited: ก่อนที่คุณจะดำเนินการต่อ โปรดพิจารณากฎพื้นฐานที่ตั้งโดยผู้ควบคุมของ %{domain} title: กฎพื้นฐานบางประการ + title_invited: คุณได้รับการเชิญ security: ความปลอดภัย set_new_password: ตั้งรหัสผ่านใหม่ setup: - email_below_hint_html: หากที่อยู่อีเมลด้านล่างไม่ถูกต้อง คุณสามารถเปลี่ยนที่อยู่อีเมลที่นี่และรับอีเมลยืนยันใหม่ - email_settings_hint_html: ส่งอีเมลยืนยันไปยัง %{email} แล้ว หากที่อยู่อีเมลนั้นไม่ถูกต้อง คุณสามารถเปลี่ยนที่อยู่อีเมลได้ในการตั้งค่าบัญชี - title: การตั้งค่า + email_below_hint_html: ตรวจสอบโฟลเดอร์สแปมของคุณ หรือขออีเมลอื่น คุณสามารถแก้ไขที่อยู่อีเมลของคุณหากที่อยู่อีเมลผิด + email_settings_hint_html: คลิกลิงก์ที่เราส่งถึงคุณเพื่อยืนยัน %{email} เราจะรออยู่ตรงนี้ + link_not_received: ไม่ได้รับลิงก์? + new_confirmation_instructions_sent: คุณจะได้รับอีเมลใหม่พร้อมลิงก์การยืนยันในไม่กี่นาที! + title: ตรวจสอบกล่องขาเข้าของคุณ sign_in: - preamble_html: ลงชื่อเข้าด้วยข้อมูลประจำตัว %{domain} ของคุณ หากบัญชีของคุณได้รับการโฮสต์ในเซิร์ฟเวอร์อื่น คุณจะไม่สามารถเข้าสู่ระบบได้ที่นี่ - title: ลงชื่อเข้า %{domain} + preamble_html: เข้าสู่ระบบด้วยข้อมูลประจำตัว %{domain} ของคุณ หากบัญชีของคุณได้รับการโฮสต์ในเซิร์ฟเวอร์อื่น คุณจะไม่สามารถเข้าสู่ระบบได้ที่นี่ + title: เข้าสู่ระบบ %{domain} sign_up: - preamble: เมื่อมีบัญชีในเซิร์ฟเวอร์ Mastodon นี้ คุณจะสามารถติดตามบุคคลอื่นใดในเครือข่าย โดยไม่คำนึงถึงที่ซึ่งบัญชีของเขาได้รับการโฮสต์ + manual_review: การลงทะเบียนใน %{domain} จะผ่านการตรวจทานด้วยตนเองโดยผู้ควบคุมของเรา เพื่อช่วยให้เราประมวลผลการลงทะเบียนของคุณ เขียนสักนิดเกี่ยวกับตัวคุณเองและเหตุผลที่คุณต้องการบัญชีใน %{domain} + preamble: ด้วยบัญชีในเซิร์ฟเวอร์ Mastodon นี้ คุณจะสามารถติดตามบุคคลอื่นใดในเครือข่าย โดยไม่คำนึงถึงที่ซึ่งบัญชีของเขาได้รับการโฮสต์ title: มาตั้งค่าของคุณใน %{domain} กันเลย status: account_status: สถานะบัญชี @@ -999,18 +1086,6 @@ th: view_strikes: ดูการดำเนินการที่ผ่านมาต่อบัญชีของคุณ too_fast: ส่งแบบฟอร์มเร็วเกินไป ลองอีกครั้ง use_security_key: ใช้กุญแจความปลอดภัย - authorize_follow: - already_following: คุณกำลังติดตามบัญชีนี้อยู่แล้ว - already_requested: คุณได้ส่งคำขอติดตามไปยังบัญชีนั้นไปแล้ว - error: น่าเสียดาย มีข้อผิดพลาดในการค้นหาบัญชีระยะไกล - follow: ติดตาม - follow_request: 'คุณได้ส่งคำขอติดตามไปยัง:' - following: 'สำเร็จ! ตอนนี้คุณกำลังติดตาม:' - post_follow: - close: หรือคุณสามารถปิดหน้าต่างนี้ - return: แสดงโปรไฟล์ของผู้ใช้ - web: ไปยังเว็บ - title: ติดตาม %{acct} challenge: confirm: ดำเนินการต่อ hint_html: "เคล็ดลับ: เราจะไม่ถามรหัสผ่านของคุณกับคุณสำหรับชั่วโมงถัดไป" @@ -1050,7 +1125,7 @@ th: data_removal: จะเอาโพสต์และข้อมูลอื่น ๆ ของคุณออกโดยถาวร email_change_html: คุณสามารถ เปลี่ยนที่อยู่อีเมลของคุณ ได้โดยไม่ต้องลบบัญชีของคุณ email_contact_html: หากอีเมลยังคงมาไม่ถึง คุณสามารถส่งอีเมลถึง %{email} สำหรับความช่วยเหลือ - email_reconfirmation_html: หากคุณไม่ได้รับอีเมลยืนยัน คุณสามารถ ขออีเมลอีกครั้ง + email_reconfirmation_html: หากคุณไม่ได้รับอีเมลการยืนยัน คุณสามารถ ขออีเมลอีกครั้ง irreversible: คุณจะไม่สามารถคืนค่าหรือเปิดใช้งานบัญชีของคุณใหม่ more_details_html: สำหรับรายละเอียดเพิ่มเติม ดู นโยบายความเป็นส่วนตัว username_available: ชื่อผู้ใช้ของคุณจะพร้อมใช้งานอีกครั้ง @@ -1061,7 +1136,7 @@ th: appeal: อุทธรณ์ appeal_approved: อุทธรณ์การดำเนินการนี้สำเร็จและไม่มีผลบังคับอีกต่อไป appeal_rejected: ปฏิเสธการอุทธรณ์แล้ว - appeal_submitted_at: ส่งการอุทธรณ์แล้ว + appeal_submitted_at: ส่งการอุทธรณ์เมื่อ appealed_msg: ส่งการอุทธรณ์ของคุณแล้ว หากมีการอนุมัติการอุทธรณ์ คุณจะได้รับการแจ้งเตือน appeals: submit: ส่งการอุทธรณ์ @@ -1087,6 +1162,10 @@ th: your_appeal_rejected: ปฏิเสธการอุทธรณ์ของคุณแล้ว domain_validator: invalid_domain: ไม่ใช่ชื่อโดเมนที่ถูกต้อง + edit_profile: + basic_information: ข้อมูลพื้นฐาน + hint_html: "ปรับแต่งสิ่งที่ผู้คนเห็นในโปรไฟล์สาธารณะของคุณและถัดจากโพสต์ของคุณ ผู้คนอื่น ๆ มีแนวโน้มที่จะติดตามคุณกลับและโต้ตอบกับคุณมากขึ้นเมื่อคุณมีโปรไฟล์ที่กรอกแล้วและรูปภาพโปรไฟล์" + other: อื่น ๆ errors: '400': คำขอที่คุณได้ส่งไม่ถูกต้องหรือผิดรูปแบบ '403': คุณไม่มีสิทธิอนุญาตเพื่อดูหน้านี้ @@ -1123,8 +1202,8 @@ th: featured_tags: add_new: เพิ่มใหม่ errors: - limit: คุณได้แนะนำแฮชแท็กถึงจำนวนสูงสุดไปแล้ว - hint_html: "แฮชแท็กที่แนะนำคืออะไร? จะแสดงแฮชแท็กที่แนะนำอย่างเด่นชัดในโปรไฟล์สาธารณะของคุณและอนุญาตให้ผู้คนเรียกดูโพสต์สาธารณะของคุณโดยเฉพาะภายใต้แฮชแท็กเหล่านั้น แฮชแท็กที่แนะนำเป็นเครื่องมือที่ยอดเยี่ยมสำหรับการติดตามงานสร้างสรรค์หรือโครงการระยะยาว" + limit: คุณได้แสดงแฮชแท็กถึงจำนวนสูงสุดไปแล้ว + hint_html: "แสดงแฮชแท็กที่สำคัญที่สุดของคุณในโปรไฟล์ของคุณ เครื่องมือที่ยอดเยี่ยมสำหรับการติดตามงานสร้างสรรค์และโครงการระยะยาวของคุณ จะแสดงแฮชแท็กที่น่าสนใจอย่างเด่นชัดในโปรไฟล์ของคุณและอนุญาตให้เข้าถึงโพสต์ของคุณเองได้อย่างรวดเร็ว" filters: contexts: account: โปรไฟล์ @@ -1164,15 +1243,15 @@ th: index: hint: ตัวกรองนี้นำไปใช้เพื่อเลือกโพสต์แต่ละรายการโดยไม่คำนึงถึงเกณฑ์อื่น ๆ คุณสามารถเพิ่มโพสต์เพิ่มเติมไปยังตัวกรองนี้ได้จากส่วนติดต่อเว็บ title: โพสต์ที่กรองอยู่ - footer: - trending_now: กำลังนิยม generic: all: ทั้งหมด all_items_on_page_selected_html: other: เลือกอยู่ทั้งหมด %{count} รายการในหน้านี้ all_matching_items_selected_html: other: เลือกอยู่ทั้งหมด %{count} รายการที่ตรงกับการค้นหาของคุณ + cancel: ยกเลิก changes_saved_msg: บันทึกการเปลี่ยนแปลงสำเร็จ! + confirm: ยืนยัน copy: คัดลอก delete: ลบ deselect: ไม่เลือกทั้งหมด @@ -1184,24 +1263,62 @@ th: today: วันนี้ validation_errors: other: ยังมีบางอย่างไม่ถูกต้อง! โปรดตรวจทาน %{count} ข้อผิดพลาดด้านล่าง - html_validator: - invalid_markup: 'มีมาร์กอัป HTML ที่ไม่ถูกต้อง: %{error}' imports: errors: + empty: ไฟล์ CSV ว่างเปล่า + incompatible_type: เข้ากันไม่ได้กับชนิดการนำเข้าที่เลือก invalid_csv_file: 'ไฟล์ CSV ไม่ถูกต้อง ข้อผิดพลาด: %{error}' over_rows_processing_limit: มีมากกว่า %{count} แถว + too_large: ไฟล์ใหญ่เกินไป + failures: ความล้มเหลว + imported: นำเข้าแล้ว + mismatched_types_warning: ดูเหมือนว่าคุณอาจเลือกชนิดที่ผิดสำหรับการนำเข้านี้ โปรดตรวจสอบอีกครั้ง modes: merge: ผสาน merge_long: เก็บระเบียนที่มีอยู่และเพิ่มระเบียนใหม่ overwrite: เขียนทับ overwrite_long: แทนที่ระเบียนปัจจุบันด้วยระเบียนใหม่ + overwrite_preambles: + blocking_html: คุณกำลังจะ แทนที่รายการการปิดกั้นของคุณ ด้วยมากถึง %{total_items} บัญชี จาก %{filename} + bookmarks_html: คุณกำลังจะ แทนที่ที่คั่นหน้าของคุณ ด้วยมากถึง %{total_items} โพสต์ จาก %{filename} + domain_blocking_html: คุณกำลังจะ แทนที่รายการการปิดกั้นโดเมนของคุณ ด้วยมากถึง %{total_items} โดเมน จาก %{filename} + following_html: คุณกำลังจะ ติดตาม มากถึง %{total_items} บัญชี จาก %{filename} และ หยุดการติดตามคนอื่นใด + lists_html: คุณกำลังจะ แทนที่รายการของคุณ ด้วยเนื้อหาของ %{filename} จะเพิ่มมากถึง %{total_items} บัญชี ไปยังรายการใหม่ + muting_html: คุณกำลังจะ แทนที่รายการบัญชีที่ซ่อนอยู่ของคุณ ด้วยมากถึง %{total_items} บัญชี จาก %{filename} + preambles: + blocking_html: คุณกำลังจะ ปิดกั้น มากถึง %{total_items} บัญชี จาก %{filename} + bookmarks_html: คุณกำลังจะเพิ่มมากถึง %{total_items} โพสต์ จาก %{filename} ไปยัง ที่คั่นหน้า ของคุณ + domain_blocking_html: คุณกำลังจะ ปิดกั้น มากถึง %{total_items} โดเมน จาก %{filename} + following_html: คุณกำลังจะ ติดตาม มากถึง %{total_items} บัญชี จาก %{filename} + lists_html: คุณกำลังจะเพิ่มมากถึง %{total_items} บัญชี จาก %{filename} ไปยัง รายการ ของคุณ จะสร้างรายการใหม่หากไม่มีรายการที่จะเพิ่มไปยัง + muting_html: คุณกำลังจะ ซ่อน มากถึง %{total_items} บัญชี จาก %{filename} preface: คุณสามารถนำเข้าข้อมูลที่คุณได้ส่งออกจากเซิร์ฟเวอร์อื่น เช่น รายการผู้คนที่คุณกำลังติดตามหรือกำลังปิดกั้น + recent_imports: การนำเข้าล่าสุด + states: + finished: เสร็จสิ้นแล้ว + in_progress: กำลังดำเนินการ + scheduled: จัดกำหนดการแล้ว + unconfirmed: ยังไม่ได้ยืนยัน + status: สถานะ success: อัปโหลดข้อมูลของคุณสำเร็จและจะได้รับการประมวลผลในเวลาที่ครบกำหนด + time_started: เริ่มเมื่อ + titles: + blocking: กำลังนำเข้าบัญชีที่ปิดกั้นอยู่ + bookmarks: กำลังนำเข้าที่คั่นหน้า + domain_blocking: กำลังนำเข้าโดเมนที่ปิดกั้นอยู่ + following: กำลังนำเข้าบัญชีที่ติดตาม + lists: กำลังนำเข้ารายการ + muting: กำลังนำเข้าบัญชีที่ซ่อนอยู่ + type: ชนิดการนำเข้า + type_groups: + constructive: การติดตามและที่คั่นหน้า + destructive: การปิดกั้นและการซ่อน types: - blocking: รายการปิดกั้น + blocking: รายการการปิดกั้น bookmarks: ที่คั่นหน้า - domain_blocking: รายการปิดกั้นโดเมน + domain_blocking: รายการการปิดกั้นโดเมน following: รายการติดตาม + lists: รายการ muting: รายการซ่อน upload: อัปโหลด invites: @@ -1239,6 +1356,21 @@ th: failed_sign_in_html: ความพยายามลงชื่อเข้าด้วย %{method} จาก %{ip} (%{browser}) ล้มเหลว successful_sign_in_html: ลงชื่อเข้าด้วย %{method} จาก %{ip} (%{browser}) สำเร็จ title: ประวัติการรับรองความถูกต้อง + mail_subscriptions: + unsubscribe: + action: ใช่ เลิกบอกรับ + complete: เลิกบอกรับแล้ว + confirmation_html: คุณแน่ใจหรือไม่ว่าต้องการเลิกบอกรับจากการรับ %{type} สำหรับ Mastodon ใน %{domain} ไปยังอีเมลของคุณที่ %{email}? คุณสามารถบอกรับใหม่ได้เสมอจาก การตั้งค่าการแจ้งเตือนอีเมล ของคุณ + emails: + notification_emails: + favourite: อีเมลการแจ้งเตือนการชื่นชอบ + follow: อีเมลการแจ้งเตือนการติดตาม + follow_request: อีเมลคำขอติดตาม + mention: อีเมลการแจ้งเตือนการกล่าวถึง + reblog: อีเมลการแจ้งเตือนการดัน + resubscribe_html: หากคุณได้เลิกบอกรับโดยไม่ได้ตั้งใจ คุณสามารถบอกรับใหม่ได้จาก การตั้งค่าการแจ้งเตือนอีเมล ของคุณ + success_html: คุณจะไม่ได้รับ %{type} สำหรับ Mastodon ใน %{domain} ไปยังอีเมลของคุณที่ %{email} อีกต่อไป + title: เลิกบอกรับ media_attachments: validations: images_and_video: ไม่สามารถแนบวิดีโอกับโพสต์ที่มีภาพอยู่แล้ว @@ -1318,6 +1450,7 @@ th: update: subject: "%{name} ได้แก้ไขโพสต์" notifications: + administration_emails: การแจ้งเตือนอีเมลผู้ดูแล email_events: เหตุการณ์สำหรับการแจ้งเตือนอีเมล email_events_hint: 'เลือกเหตุการณ์ที่คุณต้องการรับการแจ้งเตือน:' other_settings: การตั้งค่าการแจ้งเตือนอื่น ๆ @@ -1354,12 +1487,22 @@ th: expired: การสำรวจความคิดเห็นได้สิ้นสุดไปแล้ว invalid_choice: ไม่มีตัวเลือกการลงคะแนนที่เลือกอยู่ over_character_limit: ไม่สามารถยาวกว่า %{max} ตัวอักษรในแต่ละรายการ + self_vote: คุณไม่สามารถลงคะแนนในการสำรวจความคิดเห็นของคุณเอง too_few_options: ต้องมีมากกว่าหนึ่งรายการ too_many_options: ไม่สามารถมีมากกว่า %{max} รายการ preferences: other: อื่น ๆ posting_defaults: ค่าเริ่มต้นการโพสต์ public_timelines: เส้นเวลาสาธารณะ + privacy: + hint_html: "ปรับแต่งวิธีที่คุณต้องการให้พบโปรไฟล์ของคุณและโพสต์ของคุณ คุณลักษณะที่หลากหลายใน Mastodon สามารถช่วยให้คุณเข้าถึงผู้ชมที่กว้างขึ้นเมื่อเปิดใช้งาน ใช้เวลาสักครู่เพื่อตรวจทานการตั้งค่าเหล่านี้เพื่อให้แน่ใจว่าการตั้งค่าเหมาะสมกับกรณีการใช้งานของคุณ" + privacy: ความเป็นส่วนตัว + privacy_hint_html: ควบคุมปริมาณที่คุณต้องการเปิดเผยสำหรับประโยชน์ของผู้อื่น ผู้คนค้นพบโปรไฟล์ที่น่าสนใจและแอปเจ๋ง ๆ โดยการเรียกดูการติดตามของผู้คนอื่น ๆ และดูว่าเขาโพสต์จากแอปใด แต่คุณอาจต้องการซ่อนข้อมูลไว้ + reach: การเข้าถึง + reach_hint_html: ควบคุมว่าต้องการให้ผู้คนใหม่ ๆ ค้นพบและติดตามคุณหรือไม่ คุณต้องการให้โพสต์ของคุณปรากฏในหน้าจอสำรวจหรือไม่? คุณต้องการให้ผู้คนอื่น ๆ เห็นคุณในคำแนะนำการติดตามของเขาหรือไม่? คุณต้องการยอมรับผู้ติดตามใหม่ทั้งหมดโดยอัตโนมัติ หรือมีการควบคุมอย่างละเอียดในแต่ละผู้ติดตามหรือไม่? + search: ค้นหา + search_hint_html: ควบคุมวิธีที่ต้องการให้พบคุณ คุณต้องการให้ผู้คนค้นหาคุณโดยสิ่งที่คุณได้โพสต์เป็นสาธารณะหรือไม่? คุณต้องการให้ผู้คนภายนอก Mastodon ค้นหาโปรไฟล์ของคุณเมื่อค้นหาเว็บหรือไม่? โปรดทราบว่าไม่สามารถรับประกันการยกเว้นทั้งหมดจากเครื่องมือค้นหาทั้งหมดสำหรับข้อมูลสาธารณะ + title: ความเป็นส่วนตัวและการเข้าถึง privacy_policy: title: นโยบายความเป็นส่วนตัว reactions: @@ -1372,6 +1515,7 @@ th: confirm_remove_selected_followers: คุณแน่ใจหรือไม่ว่าต้องการเอาผู้ติดตามที่เลือกออก? confirm_remove_selected_follows: คุณแน่ใจหรือไม่ว่าต้องการเอาการติดตามที่เลือกออก? dormant: ไม่เคลื่อนไหว + follow_failure: ไม่สามารถติดตามบัญชีที่เลือกบางส่วน follow_selected_followers: ติดตามผู้ติดตามที่เลือก followers: ผู้ติดตาม following: กำลังติดตาม @@ -1390,15 +1534,15 @@ th: missing_resource: ไม่พบ URL การเปลี่ยนเส้นทางที่จำเป็นสำหรับบัญชีของคุณ reports: errors: - invalid_rules: ไม่ได้อ้างอิงกฎที่ถูกต้อง + invalid_rules: ไม่อ้างอิงกฎที่ถูกต้อง rss: content_warning: 'คำเตือนเนื้อหา:' descriptions: account: โพสต์สาธารณะจาก @%{acct} tag: 'โพสต์สาธารณะที่ได้รับการแท็ก #%{hashtag}' scheduled_statuses: - over_daily_limit: คุณมีโพสต์ที่จัดกำหนดการไว้เกินขีดจำกัดที่ %{limit} สำหรับวันนี้ - over_total_limit: คุณมีโพสต์ที่จัดกำหนดการไว้เกินขีดจำกัดที่ %{limit} + over_daily_limit: คุณมีโพสต์ที่จัดกำหนดการไว้เกินขีดจำกัดที่ %{limit} สำหรับวันนี้แล้ว + over_total_limit: คุณมีโพสต์ที่จัดกำหนดการไว้เกินขีดจำกัดที่ %{limit} แล้ว too_soon: วันที่จัดกำหนดการต้องอยู่ในอนาคต sessions: activity: กิจกรรมล่าสุด @@ -1411,6 +1555,7 @@ th: electron: Electron firefox: Firefox generic: เบราว์เซอร์ที่ไม่รู้จัก + huawei_browser: เบราว์เซอร์ Huawei ie: Internet Explorer micro_messenger: MicroMessenger nokia: เบราว์เซอร์ Nokia S40 Ovi @@ -1420,6 +1565,7 @@ th: qq: เบราว์เซอร์ QQ safari: Safari uc_browser: เบราว์เซอร์ UC + unknown_browser: เบราว์เซอร์ที่ไม่รู้จัก weibo: Weibo current_session: เซสชันปัจจุบัน description: "%{browser} ใน %{platform}" @@ -1432,9 +1578,10 @@ th: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: แพลตฟอร์มที่ไม่รู้จัก + unknown_platform: แพลตฟอร์มที่ไม่รู้จัก windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1453,13 +1600,13 @@ th: development: การพัฒนา edit_profile: แก้ไขโปรไฟล์ export: การส่งออกข้อมูล - featured_tags: แฮชแท็กที่แนะนำ + featured_tags: แฮชแท็กที่น่าสนใจ import: การนำเข้า import_and_export: การนำเข้าและการส่งออก migrate: การโยกย้ายบัญชี notifications: การแจ้งเตือน preferences: การกำหนดลักษณะ - profile: โปรไฟล์ + profile: โปรไฟล์สาธารณะ relationships: การติดตามและผู้ติดตาม statuses_cleanup: การลบโพสต์แบบอัตโนมัติ strikes: การดำเนินการการควบคุม @@ -1483,7 +1630,7 @@ th: errors: in_reply_not_found: ดูเหมือนว่าจะไม่มีโพสต์ที่คุณกำลังพยายามตอบกลับอยู่ open_in_web: เปิดในเว็บ - over_character_limit: เกินขีดจำกัดตัวอักษรที่ %{max} + over_character_limit: เกินขีดจำกัดตัวอักษรที่ %{max} แล้ว pin_errors: direct: ไม่สามารถปักหมุดโพสต์ที่ปรากฏแก่ผู้ใช้ที่กล่าวถึงเท่านั้น limit: คุณได้ปักหมุดโพสต์ถึงจำนวนสูงสุดไปแล้ว @@ -1499,7 +1646,6 @@ th: show_newer: แสดงที่ใหม่กว่า show_older: แสดงที่เก่ากว่า show_thread: แสดงกระทู้ - sign_in_to_participate: ลงชื่อเข้าเพื่อเข้าร่วมการสนทนา title: '%{name}: "%{quote}"' visibilities: direct: โดยตรง @@ -1516,8 +1662,8 @@ th: explanation: เนื่องจากการลบโพสต์เป็นการดำเนินงานที่มีค่าใช้จ่ายสูง นี่จึงทำอย่างช้า ๆ เมื่อเวลาผ่านไปเมื่อเซิร์ฟเวอร์ไม่ได้ไม่ว่างอย่างอื่น ด้วยเหตุผลนี้ อาจลบโพสต์ของคุณสักครู่หลังจากที่โพสต์ถึงค่าเกณฑ์อายุ ignore_favs: เพิกเฉยต่อรายการโปรด ignore_reblogs: เพิกเฉยต่อการดัน - interaction_exceptions: ข้อยกเว้นตามการโต้ตอบ - interaction_exceptions_explanation: โปรดทราบว่าไม่มีการรับประกันว่าจะลบโพสต์หากโพสต์ลงไปต่ำกว่าค่าเกณฑ์การชื่นชอบหรือการดันหลังจากที่ผ่านโพสต์ไปแล้วครั้งหนึ่ง + interaction_exceptions: ข้อยกเว้นโดยอิงตามการโต้ตอบ + interaction_exceptions_explanation: โปรดทราบว่าไม่มีการรับประกันว่าจะลบโพสต์หากโพสต์ลงไปต่ำกว่าค่าเกณฑ์การชื่นชอบหรือการดันหลังจากที่ผ่านโพสต์เหล่านั้นไปแล้วครั้งหนึ่ง keep_direct: เก็บข้อความโดยตรง keep_direct_hint: ไม่ลบข้อความโดยตรงใดก็ตามของคุณ keep_media: เก็บโพสต์ที่มีไฟล์แนบสื่อ @@ -1527,9 +1673,9 @@ th: keep_polls: เก็บการสำรวจความคิดเห็น keep_polls_hint: ไม่ลบการสำรวจความคิดเห็นใดก็ตามของคุณ keep_self_bookmark: เก็บโพสต์ที่คุณได้เพิ่มที่คั่นหน้า - keep_self_bookmark_hint: ไม่ลบโพสต์ของคุณเองหากคุณได้เพิ่มที่คั่นหน้าโพสต์ไว้ + keep_self_bookmark_hint: ไม่ลบโพสต์ของคุณเองหากคุณได้เพิ่มที่คั่นหน้าโพสต์เหล่านั้นไว้ keep_self_fav: เก็บโพสต์ที่คุณได้ชื่นชอบ - keep_self_fav_hint: ไม่ลบโพสต์ของคุณเองหากคุณได้ชื่นชอบโพสต์ไว้ + keep_self_fav_hint: ไม่ลบโพสต์ของคุณเองหากคุณได้ชื่นชอบโพสต์เหล่านั้นไว้ min_age: '1209600': 2 สัปดาห์ '15778476': 6 เดือน @@ -1545,8 +1691,6 @@ th: min_reblogs: เก็บโพสต์ที่ได้รับการดันอย่างน้อย min_reblogs_hint: ไม่ลบโพสต์ใดก็ตามของคุณที่ได้รับจำนวนครั้งการดันอย่างน้อยเท่านี้ เว้นว่างไว้เพื่อลบโพสต์โดยไม่คำนึงถึงจำนวนการดันของโพสต์ stream_entries: - pinned: โพสต์ที่ปักหมุด - reblogged: ดันแล้ว sensitive_content: เนื้อหาที่ละเอียดอ่อน strikes: errors: @@ -1559,9 +1703,14 @@ th: mastodon-light: Mastodon (สว่าง) time: formats: - default: "%d %b %Y, %H:%M" + default: "%d %b %Y %H:%M น." month: "%b %Y" - time: "%H:%M" + time: "%H:%M น." + with_time_zone: "%d %b %Y %H:%M น. %Z" + translation: + errors: + quota_exceeded: เกินโควตาการใช้งานทั่วทั้งเซิร์ฟเวอร์สำหรับบริการการแปลแล้ว + too_many_requests: มีคำขอมากเกินไปไปยังบริการการแปลล่าสุด two_factor_authentication: add: เพิ่ม disable: ปิดใช้งาน 2FA @@ -1570,12 +1719,12 @@ th: enabled: เปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยแล้ว enabled_success: เปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัยสำเร็จ generate_recovery_codes: สร้างรหัสกู้คืน - lost_recovery_codes: รหัสกู้คืนอนุญาตให้คุณเข้าถึงบัญชีของคุณได้อีกครั้งหากคุณทำโทรศัพท์ของคุณหาย หากคุณทำรหัสกู้คืนหาย คุณสามารถสร้างรหัสใหม่ได้ที่นี่ จะยกเลิกรหัสกู้คืนเก่าของคุณ + lost_recovery_codes: รหัสกู้คืนอนุญาตให้คุณเข้าถึงบัญชีของคุณได้อีกครั้งหากคุณทำโทรศัพท์ของคุณหาย หากคุณทำรหัสกู้คืนหาย คุณสามารถสร้างรหัสเหล่านั้นใหม่ได้ที่นี่ จะยกเลิกรหัสกู้คืนเก่าของคุณ methods: วิธีการสองปัจจัย otp: แอปตัวรับรองความถูกต้อง recovery_codes: รหัสกู้คืนข้อมูลสำรอง recovery_codes_regenerated: สร้างรหัสกู้คืนใหม่สำเร็จ - recovery_instructions_html: หากคุณสูญเสียการเข้าถึงโทรศัพท์ของคุณ คุณสามารถใช้หนึ่งในรหัสกู้คืนด้านล่างเพื่อให้เข้าถึงบัญชีของคุณได้อีกครั้ง รักษารหัสกู้คืนให้ปลอดภัย ตัวอย่างเช่น คุณสามารถพิมพ์รหัสและจัดเก็บรหัสไว้กับเอกสารสำคัญอื่น ๆ + recovery_instructions_html: หากคุณสูญเสียการเข้าถึงโทรศัพท์ของคุณ คุณสามารถใช้หนึ่งในรหัสกู้คืนด้านล่างเพื่อให้เข้าถึงบัญชีของคุณได้อีกครั้ง รักษารหัสกู้คืนให้ปลอดภัย ตัวอย่างเช่น คุณอาจพิมพ์รหัสเหล่านั้นและจัดเก็บรหัสเหล่านั้นไว้กับเอกสารสำคัญอื่น ๆ webauthn: กุญแจความปลอดภัย user_mailer: appeal_approved: @@ -1641,13 +1790,18 @@ th: title: ยินดีต้อนรับ %{name}! users: follow_limit_reached: คุณไม่สามารถติดตามมากกว่า %{limit} คน + go_to_sso_account_settings: ไปยังการตั้งค่าบัญชีของผู้ให้บริการข้อมูลประจำตัวของคุณ invalid_otp_token: รหัสสองปัจจัยไม่ถูกต้อง otp_lost_help_html: หากคุณสูญเสียการเข้าถึงทั้งสองอย่าง คุณสามารถติดต่อ %{email} seamless_external_login: คุณได้เข้าสู่ระบบผ่านบริการภายนอก ดังนั้นจึงไม่มีการตั้งค่ารหัสผ่านและอีเมล signed_in_as: 'ลงชื่อเข้าเป็น:' verification: - explanation_html: 'คุณสามารถ ยืนยันตัวคุณเองว่าเป็นเจ้าของของลิงก์ในข้อมูลอภิพันธุ์โปรไฟล์ของคุณ สำหรับสิ่งนั้น เว็บไซต์ที่เชื่อมโยงต้องมีลิงก์ย้อนกลับไปยังโปรไฟล์ Mastodon ของคุณ ลิงก์ย้อนกลับ ต้อง มีแอตทริบิวต์ rel="me" เนื้อหาข้อความของลิงก์ไม่สำคัญ นี่คือตัวอย่าง:' + extra_instructions_html: เคล็ดลับ: ลิงก์ในเว็บไซต์ของคุณสามารถเป็นแบบมองไม่เห็น ส่วนที่สำคัญคือ rel="me" ซึ่งป้องกันการแอบอ้างในเว็บไซต์ที่มีเนื้อหาที่ผู้ใช้สร้างขึ้น คุณยังสามารถใช้แท็ก link ในส่วนหัวของหน้าแทนที่จะเป็น a แต่ HTML ต้องเข้าถึงได้โดยไม่มีการประมวลผล JavaScript + here_is_how: นี่คือวิธี + hint_html: "การยืนยันตัวตนของคุณใน Mastodon มีไว้สำหรับทุกคน โดยอิงตามมาตรฐานเว็บแบบเปิด ฟรีตอนนี้และตลอดไป ทั้งหมดที่คุณจำเป็นต้องมีคือเว็บไซต์ส่วนบุคคลที่ผู้คนรู้จักคุณ เมื่อคุณเชื่อมโยงไปยังเว็บไซต์นี้จากโปรไฟล์ของคุณ เราจะตรวจสอบว่าเว็บไซต์เชื่อมโยงกลับไปยังโปรไฟล์ของคุณและแสดงตัวบ่งชี้ที่มองเห็นได้ในโปรไฟล์" + instructions_html: คัดลอกแล้ววางโค้ดด้านล่างลงใน HTML ของเว็บไซต์ของคุณ จากนั้นเพิ่มที่อยู่ของเว็บไซต์ของคุณลงในหนึ่งในช่องพิเศษในโปรไฟล์ของคุณจากแท็บ "แก้ไขโปรไฟล์" และบันทึกการเปลี่ยนแปลง verification: การตรวจสอบ + verified_links: ลิงก์ที่ยืนยันแล้วของคุณ webauthn_credentials: add: เพิ่มกุญแจความปลอดภัยใหม่ create: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index fb254e11b4..862667f3ce 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -59,25 +59,25 @@ tr: destroyed_msg: "%{username} adlı kullanıcının verilerinin silinmesi sıraya alındı" disable: Dondur disable_sign_in_token_auth: E-posta token doğrulamayı devre dışı bırak - disable_two_factor_authentication: 2 adımlı doğrulamayı kapat + disable_two_factor_authentication: 2 aşamalı doğrulamayı kapat disabled: Kapalı display_name: Görünen isim domain: Alan adı edit: Düzenle email: E-posta email_status: E-posta durumu - enable: Dondurmayı Kaldır + enable: Etkinleştir enable_sign_in_token_auth: E-posta token doğrulamayı etkinleştir enabled: Etkin enabled_msg: "%{username} hesabı başarıyla çözüldü" - followers: Takipçiler + followers: Takipçi follows: Takip edilen header: Üstbilgi inbox_url: Gelen kutusu bağlantısı invite_request_text: Katılma gerekçeleri invited_by: Tarafından davet edildi ip: IP - joined: Katıldı + joined: Katılma tarihi location: all: Hepsi local: Yerel @@ -91,9 +91,10 @@ tr: moderation: active: Etkin all: Hepsi - pending: Bekliyor + disabled: Devre dışı bırakıldı + pending: Bekleyen silenced: Sınırlı - suspended: Uzaklaştırılanlar + suspended: Askıya Alınan title: Denetim moderation_notes: Denetleme notları most_recent_activity: Son aktivite @@ -111,7 +112,7 @@ tr: promote: Yükselt protocol: Protokol public: Herkese açık - push_subscription_expires: PuSH aboneliği dolumu + push_subscription_expires: PuSH aboneliği sona erdi redownload: Profili yenile redownloaded_msg: "%{username} kullanıcısının profili kökenden başarıyla yenilendi" reject: Reddet @@ -124,8 +125,8 @@ tr: removed_header_msg: "%{username} hesabının başlık resmi başarıyla kaldırıldı" resend_confirmation: already_confirmed: Bu kullanıcı zaten onaylandı - send: Doğrulama epostasını yeniden gönder - success: Onay e-postası başarıyla gönderildi! + send: Onaylama bağlantısını tekrar gönder + success: Onaylama bağlantısı başarıyla gönderildi! reset: Sıfırla reset_password: Parolayı sıfırla resubscribe: Yeniden abone ol @@ -133,6 +134,7 @@ tr: search: Ara search_same_email_domain: Aynı e-posta alan adına sahip diğer kullanıcılar search_same_ip: Aynı IP adresine sahip diğer kullanıcılar + security: Güvenlik security_measures: only_password: Sadece parola password_and_2fa: Parola ve İki aşamalı doğrulama @@ -144,7 +146,7 @@ tr: targeted_reports: Başkaları tarafından şikayet edildi silence: Sustur silenced: Susturulmuş - statuses: Durumlar + statuses: Gönderiler strikes: Önceki eylemler subscribe: Abone ol suspend: Askıya al @@ -168,7 +170,7 @@ tr: whitelisted: Beyaz listede action_logs: action_types: - approve_appeal: İtirazı Kabul Et + approve_appeal: İtirazı Onayla approve_user: Kullanıcıyı Onayla assigned_to_self_report: Raporu Ata change_email_user: Kullanıcı E-postasını Değiştir @@ -307,6 +309,7 @@ tr: unpublish: Yayından kaldır unpublished_msg: Duyuru başarıyla yayından kaldırıldı! updated_msg: Duyuru başarıyla güncellendi! + critical_update_pending: Kritik güncelleme bekliyor custom_emojis: assign_category: Kategori ata by_domain: Alan adı @@ -380,6 +383,15 @@ tr: undo: Beyaz listeden çıkar domain_blocks: add_new: Yeni ekle + confirm_suspension: + cancel: İptal et + confirm: Askıya al + permanent_action: Askıyı kaldırmak herhangi bir veriyi veya ilişkiyi geri getirmez. + preamble_html: "%{domain} ve alt alan adlarını askıya almak üzeresiniz." + remove_all_data: Bu sunucunuzdaki bu alan adının hesaplarından tüm veriyi, içeriği, ve profil verisini kaldıracaktır. + stop_communication: Sunucunuzun bu sunucularla iletişimi durduracaktır. + title: "%{domain} için alan adı engelini doğrulayın" + undo_relationships: Bu kendi sunucularınız ve diğerlerindeki hesaplar arasındaki herhangi bir takip ilişkisini geri alacaktır. created_msg: Domain bloğu şu an işleniyor destroyed_msg: Domain bloğu silindi domain: Alan adı @@ -427,6 +439,7 @@ tr: resolve: Alan adı çözümleme title: Yeni e-posta kara liste girişi no_email_domain_block_selected: Seçim yapılmadığından hiç bir e-posta alan adı engeli değiştirilmedi + not_permitted: İzin verilmedi resolved_dns_records_hint_html: Alan adı aşağıdaki MX alan adlarına çözümleniyor, ancak hiç biri nihayetinde e-posta kabulünden sorum değil. Bir MX alan adını engellemek, görünen alan adı farklı osa bile aynı MX alan adını kullanan e-posta adreslerinden gelen kayıtları engelleyecektir. Başlıca e-posta sağlayıcıları engellememek için dikkatli olun. resolved_through_html: "%{domain} aracılığıyla çözümlendi" title: E-posta kara listesi @@ -473,6 +486,7 @@ tr: content_policies: comment: İç not description_html: Bu alan adındaki ve alt alan adlarındaki tüm hesaplara uygulanacak içerik ilkeleri belirleyebilirsiniz. + limited_federation_mode_description_html: Bu alan adıyla birleştirmeye izin verip vermediğinizi seçebilirsiniz. policies: reject_media: Medyayı reddet reject_reports: Şikayetleri reddet @@ -585,11 +599,13 @@ tr: assign_to_self: Bana ata assigned: Denetleyici atandı by_target_domain: Şikayet edilen hesabın alan adı + cancel: İptal et category: Kategori category_description_html: Bu hesap ve/veya içeriğin bildirilme gerekçesi, bildirilen hesapla iletişimde alıntılanacaktır comment: none: Yok comment_description_html: 'Daha fazla bilgi vermek için %{name} şunu yazdı:' + confirm: Onayla confirm_action: "%{acct} üzerindeki denetleme eylemini onayla" created_at: Şikayet edildi delete_and_resolve: Gönderileri sil @@ -629,11 +645,13 @@ tr: actions: delete_html: Kuralı ihlal eden gönderileri kaldır mark_as_sensitive_html: Kuralı ihlal eden gönderilerin medyasını hassas olarak işaretle + silence_html: "@%{acct} hesabının erişimini oldukça kısıtla: profili ve içeriği sadece onları halihazırda takip edenler veya manuel olarak hesabına erişenlerce mümkün olacak" suspend_html: "@%{acct} hesabını askıya al, profilini ve içeriğini erişilmez ve etkileşimi imkansız yap" close_report: "#%{id} bildirimini çözüldü olarak işaretle" close_reports_html: "@%{acct} hesabına yönelik tüm bildirimleri çözüldü olarak işaretle" delete_data_html: İlgili sürede askıdan alınması kaldırılmazsa @%{acct} hesabının profilini ve içeriğini şu andan itibaren 30 gün içinde sil preview_preamble_html: "@%{acct} aşağıdaki içerikle bir uyarı alacaktır:" + record_strike_html: "@%{acct} hesabına karşı bir eylem kaydet, böylece bu hesabın gelecekteki ihlallerini üst makama taşımanıza yardımcı olacaktır" send_email_html: "@%{acct} adlı kullanıcıya uyarı e-maili gönder" warning_placeholder: İsteğe bağlı ek nedenden denetim eylemi. target_origin: Şikayet edilen hesabın kökeni @@ -723,6 +741,9 @@ tr: branding: preamble: Sunucunuzun markalaşması ağdaki diğer sunuculardan farklıdır. Bu bilgiler Mastodon'un web arayüzü, doğal uygulamalar, diğer sitelerdeki ve ileti uygulamalarındaki bağlantı önizlemeleri, vb. gibi çeşitli ortamlarda görüntülenebilir. Bu nedenle bu bilgiyi açık, kısa ve özlü tutmak en iyisidir. title: Marka + captcha_enabled: + desc_html: Bu, güvenlik ve gizlilikle ilgili bir endişe kaynağı olabilecek hCaptcha'nın harici komut dosyalarına dayanır. Ayrıca bu, kayıt sürecini bazı (özellikle engelli) kişiler için önemli ölçüde daha az erişilebilir hale getirebilir. Bu nedenlerle, lütfen onaya dayalı veya davete dayalı kayıt gibi alternatif önlemleri göz önünde bulundurun. + title: Yeni kullanıcıların hesaplarını doğrulamaları için bir CAPTCHA çözmelerini gerektir content_retention: preamble: Kullanıcıların ürettiği içeriğin Mastodon'da nasıl saklanacağını denetleyin. title: İçerik saklama @@ -750,10 +771,27 @@ tr: approved: Kayıt için onay gerekli none: Hiç kimse kayıt olamaz open: Herkes kaydolabilir - title: Sunucu Ayarları + security: + authorized_fetch: Dağıtık sunuculardan kimlik doğrulama gerektir + authorized_fetch_hint: Dağıtık sunuculardan kimlik doğrulaması istemek, hem kullanıcı düzeyinde hem de sunucu düzeyinde blokların daha sıkı bir şekilde uygulanmasını sağlar. Ancak bu performans kaybına sebep olur, yanıtlarınızın erişimini azaltır ve bazı dağıtık hizmetlerle uyumluluk sorunları ortaya çıkarabilir. Ayrıca bu, özel aktörlerin herkese açık gönderilerinizi ve hesaplarınızı getirilmesini engellemez. + authorized_fetch_overridden_hint: Bir ortam değişkeni tarafından geçersiz kılındığı için şu anda bu ayarı değiştiremezsiniz. + federation_authentication: Dağıtık kimlik doğrulama uygulaması + title: Sunucu ayarları site_uploads: delete: Yüklenen dosyayı sil destroyed_msg: Site yüklemesi başarıyla silindi! + software_updates: + critical_update: Kritik — lütfen hemen güncelleyin + description: Son düzeltme ve özelliklerden yararlanmak için Mastodon kurulumunu güncel tutmanızı öneriyoruz. Üstelik güvenlik sorunlarından kaçınmak için Mastodon'u zamanında güncellemek kritiktir. Bu nedenlerle Mastodon her 30 dakikada bir güncellemeleri denetler ve e-posta bildirim seçeneğinize göre size haber verir. + documentation_link: Daha fazlası + release_notes: Sürüm notları + title: Mevcut güncellemeler + type: Tür + types: + major: Ana sürüm + minor: Alt sürüm + patch: Yama sürümü — hata düzeltmeleri ve uygulaması kolay değişiklikler + version: Sürüm statuses: account: Yazar application: Uygulama @@ -790,9 +828,24 @@ tr: suspend: "%{name}, %{target} kullanıcısının hesabını askıya aldı" appeal_approved: İtiraz Edildi appeal_pending: İtiraz bekliyor + appeal_rejected: İtiraz reddedildi system_checks: database_schema_check: message_html: Beklemede olan veritabanı güncellemeleri mevcut. Uygulamanın beklenildiği gibi çalışması için lütfen onları çalıştırın + elasticsearch_health_red: + message_html: Elasticsearch kümesi sağlıksız (kırmızı durum), arama özellikleri mevcut değil + elasticsearch_health_yellow: + message_html: Elasticsearch kümesi sağlıksız (sarı durum), nedenini incelemek isteyebilirsiniz + elasticsearch_index_mismatch: + message_html: Elasticsearch indeks eşlemeleri artık güncel değil. Lütfen tootctl search deploy --only=%{value} komutunu çalıştırın + elasticsearch_preset: + action: Belgelere bakın + message_html: Elasticsearch kümenizin birden fazla düğümü var ama Mastodon onları kullanmak üzere yapılandırılmamış. + elasticsearch_preset_single_node: + action: Belgelere bakın + message_html: Elasticsearch kümenizin tek bir düğümü var, ES_PRESET değişkenine single_node_cluster değeri verilmelidir. + elasticsearch_reset_chewy: + message_html: Elasticsearch sistem indeksi, bir ayar değişikliği nedeniyle güncelliğini yitirmiş. Lütfen tootctl search deploy --reset-chewy komutunu çalıştırın. elasticsearch_running_check: message_html: Elasticsearch'e bağlanılamıyor. Çalıştığından emin olun veya tüm metin aramayı devre dışı bırakın elasticsearch_version_check: @@ -803,6 +856,18 @@ tr: message_html: Herhangi bir sunucu kuralı belirlemediniz. sidekiq_process_check: message_html: "%{value} kuyruk(lar)ı için herhangi bir Sidekiq süreci çalışmıyor. Lütfen Sidekiq yapılandırmanızı gözden geçirin" + software_version_critical_check: + action: Mevcut güncellemeleri göster + message_html: Kritik bir Mastodon güncellemesi var, lütfen en kısa sürede güncelleyin. + software_version_patch_check: + action: Mevcut güncellemeleri göster + message_html: Mastodon yama güncellemesi mevcut. + upload_check_privacy_error: + action: Daha fazla bilgi için buraya tıklayın + message_html: "Web sunucunuz hatalı yapılandırılmış. Kullanıcılarınızın gizliliği tehlikede." + upload_check_privacy_error_object_storage: + action: Daha fazla bilgi için buraya göz atın + message_html: "Nesne depolamanız hatalı yapılandırılmış. Kullanıcılarınızın gizliliği tehlikede." tags: review: Durumu gözden geçir updated_msg: Etiket ayarları başarıyla güncellendi @@ -825,6 +890,7 @@ tr: other: Geçen hafta %{count} kişi paylaştı title: Öne çıkan bağlantılar usage_comparison: Bugün %{today} kere paylaşıldı, dün %{yesterday} kere paylaşılmıştı + not_allowed_to_trend: Öne çıkma izni yok only_allowed: Sadece izin verilenler pending_review: İnceleme bekliyor preview_card_providers: @@ -836,14 +902,14 @@ tr: statuses: allow: Gönderiye izin ver allow_account: Yazara izin ver - description_html: Bunlar, sunucunuzca bilinen, şu an sıklıkla paylaşılan ve beğenilen gönderilerdir. Yeni ve geri dönen kullanıcılarınızın takip etmesi için daha fazla kullanıcı bulmasına yararlar. Siz yazarı onaylamadığınız ve yazar hesabının başkalarına önerilmesine izin vermediği sürece gönderileri herkese açık olarak gösterilmez. Tekil gönderileri de onaylayabilir veya reddedebilirsiniz. + description_html: Bunlar, sunucunuzca bilinen, şu an sıklıkla paylaşılan ve favorilere eklenen gönderilerdir. Yeni ve geri dönen kullanıcılarınızın takip etmesi için daha fazla kullanıcı bulmasına yararlar. Siz yazarı onaylamadığınız ve yazar hesabının başkalarına önerilmesine izin vermediği sürece gönderileri herkese açık olarak gösterilmez. Tekil gönderileri de onaylayabilir veya reddedebilirsiniz. disallow: Gönderi iznini kaldır disallow_account: Yazar iznini kaldır no_status_selected: Hiçbiri seçilmediğinden hiçbir öne çıkan gönderi değiştirilmedi not_discoverable: Yazar keşfedilebilir olmamayı seçiyor shared_by: one: Bir defa paylaşıldı veya favorilendi - other: "%{friendly_count} defa paylaşıldı veya favorilendi" + other: "%{friendly_count} defa paylaşıldı veya beğenildi" title: Öne çıkan gönderiler tags: current_score: Mevcut puan %{score} @@ -909,6 +975,9 @@ tr: body: "%{target}, %{date} tarihinde %{action_taken_by} tarafından alınan %{type} yönetim kararına itiraz etti. Şunu yazdılar:" next_steps: Yönetim kararını geri almak için itirazı onaylayabilir veya itirazı görmezden gelebilirsiniz. subject: "%{username}, %{instance} hakkındaki bir yönetim kararına itiraz ediyor" + new_critical_software_updates: + body: Mastodon'un yeni kritik sürümleri yayınlandı, en kısa sürede güncellemek isteyebilirsiniz! + subject: "%{instance} için kritik Mastodon güncellemeleri mevcut!" new_pending_account: body: Yeni hesabın detayları aşağıdadır. Bu başvuruyu onaylayabilir ya da reddedebilirsiniz. subject: "%{instance} üzerinde gözden geçirmek için yeni hesap (%{username})" @@ -916,6 +985,9 @@ tr: body: "%{reporter}, %{target} kişisini bildirdi" body_remote: "%{domain} alan adından birisi %{target} kişisini bildirdi" subject: "%{instance} için yeni şikayet (#%{id})" + new_software_updates: + body: Yeni Mastodon sürümleri yayınlandı, güncellemek isteyebilirsiniz! + subject: "%{instance} için yeni Mastodon sürümleri mevcut!" new_trends: body: 'Aşağıdaki öğeler herkese açık olarak gösterilmeden önce gözden geçirilmelidir:' new_trending_links: @@ -945,24 +1017,28 @@ tr: guide_link: https://crowdin.com/project/mastodon guide_link_text: Herkes katkıda bulunabilir. sensitive_content: Hassas içerik - toot_layout: Gönderi düzeni application_mailer: notification_preferences: E-posta tercihlerini değiştir salutation: "%{name}," settings: 'E-posta tercihlerini değiştir: %{link}' + unsubscribe: Abonelikten çık view: 'Görüntüle:' view_profile: Profili görüntüle view_status: Durumu görüntüle applications: created: Uygulama başarıyla oluşturuldu destroyed: Uygulama başarıyla silindi + logout: Oturumu kapat regenerate_token: Erişim belirtecini yeniden oluştur token_regenerated: Erişim belirteci başarıyla oluşturuldu warning: Bu verilere çok dikkat edin. Asla kimseyle paylaşmayın! your_token: Erişim belirteciniz auth: apply_for_account: Bir hesap talep et - change_password: Parola + captcha_confirmation: + help_html: CAPTCHA'yı çözmekte sorun yaşıyorsanız bizimle %{email} üzerinden iletişime geçebilirsiniz, size yardımcı olabiliriz. + hint_html: Sadece bir şey daha! Sizin bir insan olduğunuzu doğrulamamız gerekiyor (bu, spam'i dışarıda tutabilmemiz içindir!). Aşağıdaki CAPTCHA'yı çözün ve "Devam Et" düğmesini tıklayın. + title: Güvenlik denetimi confirmations: wrong_email_hint: Eğer bu e-posta adresi doğru değilse, hesap ayarlarında değiştirebilirsiniz. delete_account: Hesabı sil @@ -971,7 +1047,7 @@ tr: prefix_invited_by_user: "@%{name} sizi bu Mastodon sunucusuna katılmaya davet ediyor!" prefix_sign_up: Bugün Mastodon'a kaydolun! suffix: Bir hesapla, kişileri takip edebilir, güncellemeler gönderebilir, herhangi bir Mastodon sunucusundan kullanıcılarla mesaj alışverişinde bulunabilir ve daha birçok şey yapabilirsin! - didnt_get_confirmation: Doğrulama talimatlarını almadınız mı? + didnt_get_confirmation: Onaylama bağlantısını almadınız mı? dont_have_your_security_key: Güvenlik anahtarınız yok mu? forgot_password: Parolanızı mı unuttunuz? invalid_reset_password_token: Parola sıfırlama belirteci geçersiz veya süresi dolmuş. Lütfen yeni bir tane talep edin. @@ -984,26 +1060,39 @@ tr: migrate_account_html: Bu hesabı başka bir hesaba yönlendirmek istiyorsan, buradan yapılandırabilirsin. or_log_in_with: 'Veya şununla oturum açın:' privacy_policy_agreement_html: Gizlilik politikasını okudum ve kabul ettim + progress: + confirm: E-postayı Onayla + details: Ayrıntılarınız + review: İncelememiz + rules: Kabul kuralları providers: cas: CAS saml: SAML register: Kaydol registration_closed: "%{instance} yeni üyeler kabul etmemektedir" - resend_confirmation: Onaylama talimatlarını tekrar gönder + resend_confirmation: Onaylama bağlantısını tekrar gönder reset_password: Parolayı sıfırla rules: + accept: Onayla + back: Geri + invited_by: 'Aşağıdakinden aldığınız davet sayesinde %{domain} sunucusuna katılabilirsiniz:' preamble: Bunlar, %{domain} moderatörleri tarafından ayarlanmış ve uygulanmıştır. + preamble_invited: Devam etmeden önce, %{domain} yöneticileri tarafından belirlenmiş temel kuralları gözden geçirin. title: Bazı temel kurallar. + title_invited: Davet edildiniz. security: Güvenlik set_new_password: Yeni parola belirle setup: - email_below_hint_html: Eğer aşağıdaki e-posta adresi yanlışsa, onu burada değiştirebilir ve yeni bir doğrulama e-postası alabilirsiniz. - email_settings_hint_html: Onaylama e-postası %{email} adresine gönderildi. Eğer bu e-posta adresi doğru değilse, hesap ayarlarından değiştirebilirsiniz. - title: Kurulum + email_below_hint_html: İstenmeyenler dizininize bakın veya başka bir onay bağlantısı isteyin. Eğer yanlışsa e-posta adresinizi de düzeltebilirsiniz. + email_settings_hint_html: "%{email} adresinizi doğrulamak için size gönderdiğimiz bağlantıya tıklayın. Biz burada bekliyoruz." + link_not_received: Bağlantı gelmedi mi? + new_confirmation_instructions_sent: Birkaç dakika içerisinde onaylama bağlantısını içeren yeni bir e-posta alacaksınız! + title: Gelen kutunuzu kontrol edin sign_in: preamble_html: "%{domain} kimlik bilgilerinizi kullanarak giriş yapın. Eğer hesabınız başka bir sunucuda barındırılıyorsa, burada giriş yapamazsınız." title: "%{domain} giriş yapın" sign_up: + manual_review: "%{domain} kayıtları moderatörler tarafından manuel olarak inceleniyor. Kaydınızı işlememizi kolaylaştırmak için kendiniz ve %{domain} sunucusundan neden hesap istediğiniz hakkında biraz bilgi verin." preamble: Bu Mastodon sunucusu üzerinden bir hesap ile ağdaki herhangi bir kişiyi, hesabı hangi sunucuda saklanırsa saklansın, takip edebilirsiniz. title: "%{domain} için kurulumunuzu yapalım." status: @@ -1015,18 +1104,6 @@ tr: view_strikes: Hesabınıza yönelik eski eylemleri görüntüleyin too_fast: Form çok hızlı gönderildi, tekrar deneyin. use_security_key: Güvenlik anahtarını kullan - authorize_follow: - already_following: Bu hesabı zaten takip ediyorsunuz - already_requested: Bu hesaba zaten takip isteği gönderdiniz - error: Uzak hesap aranırken bir hata oluştu - follow: Takip et - follow_request: 'Şuna takip isteği gönderdiniz:' - following: 'Başarılı! Artık şunu takip ediyorsunuz:' - post_follow: - close: Ya da, sadece bu pencereyi kapatabilirsiniz. - return: Kullanıcının profilini göster - web: Web'e git - title: "%{acct} takip et" challenge: confirm: Devam et hint_html: "İpucu: Önümüzdeki saat boyunca sana parolanı sormayacağız." @@ -1103,6 +1180,10 @@ tr: your_appeal_rejected: İtirazınız reddedildi domain_validator: invalid_domain: geçerli bir alan adı değil + edit_profile: + basic_information: Temel bilgiler + hint_html: "İnsanlara herkese açık profilinizde ve gönderilerinizin yanında ne göstermek istediğinizi düzenleyin. Dolu bir profile ve bir profil resmine sahip olduğunuzda diğer insanlar daha yüksek ihtimalle sizi takip etmek ve sizinle etkileşime geçmek isteyeceklerdir." + other: Diğer errors: '400': Gönderdiğiniz istek geçersiz veya hatalı biçimlendirilmiş. '403': Bu sayfayı görmek için izniniz yok. @@ -1139,7 +1220,7 @@ tr: featured_tags: add_new: Yeni ekle errors: - limit: Zaten azami hashtag miktarı belirlediniz + limit: Zaten azami etiket sayısını öne çıkardınız hint_html: "Öne çıkan etiketler nelerdir? Genel profilinizde belirgin bir şekilde görüntülenirler ve kişilerin genel yayınlarınıza özellikle bu etiketler altında göz atmalarına izin verir. Yaratıcı çalışmaları veya uzun vadeli projeleri takip etmek için harika bir araçtır." filters: contexts: @@ -1183,8 +1264,6 @@ tr: index: hint: Bu filtre diğer ölçütlerden bağımsız olarak tekil gönderileri seçmek için uygulanıyor. Web arayüzünü kullanarak bu filtreye daha fazla gönderi ekleyebilirsiniz. title: Filtrelenmiş gönderiler - footer: - trending_now: Şu an gündemde generic: all: Tümü all_items_on_page_selected_html: @@ -1193,7 +1272,9 @@ tr: all_matching_items_selected_html: one: Aramanızla eşleşen %{count} öğe seçilmiş. other: Aramanızla eşleşen tüm %{count} öğe seçilmiş. + cancel: İptal changes_saved_msg: Değişiklikler başarıyla kaydedildi! + confirm: Onayla copy: Kopyala delete: Sil deselect: Hiçbirini seçme @@ -1207,24 +1288,62 @@ tr: validation_errors: one: Bir şeyler ters gitti! Lütfen aşağıdaki hatayı gözden geçiriniz other: Bir şeyler ters gitti! Lütfen aşağıdaki %{count} hatayı gözden geçiriniz - html_validator: - invalid_markup: 'geçersiz HTML markup içermektedir: %{error}' imports: errors: + empty: Boş CSV Dosyası + incompatible_type: Seçilen içe aktarma türüyle uyumsuz invalid_csv_file: 'Geçersiz CSV dosyası. Hata: %{error}' over_rows_processing_limit: "%{count} satırdan fazlasını içeriyor" + too_large: Dosya çok büyük + failures: Başarısızlıklar + imported: İçe aktarılan + mismatched_types_warning: Bu içe aktarma için hatalı türü seçmiş gibi gözüküyor, lütfen tekrar denetleyin. modes: merge: Birleştir merge_long: Mevcut kayıtları sakla ve yenileri ekle overwrite: Üzerine yaz overwrite_long: Mevcut kayıtları yenileriyle değiştir + overwrite_preambles: + blocking_html: "Engel listenizi, %{filename} dosyasından, %{total_items} hesapla değiştirmek üzeresiniz." + bookmarks_html: "Yerimlerinizi, %{filename} dosyasından, %{total_items} gönderiyle değiştirmek üzeresiniz." + domain_blocking_html: "Alan adı engel listenizi, %{filename} dosyasından, %{total_items} alan adıyla değiştirmek üzeresiniz." + following_html: "%{filename} dosyasından %{total_items} hesabı takip etmeye başlamak ve diğer herkesi takipten çıkmak üzeresiniz." + lists_html: Listelerinizi %{filename} içeriğiyle değiştirmek üzeresiniz. Yeni listelere en fazla %{total_items} hesap eklenecek. + muting_html: "Sessize alınmış hesaplar listenizi, %{filename} dosyasından, %{total_items} hesapla değiştirmek üzeresiniz." + preambles: + blocking_html: "%{filename} dosyasından %{total_items} hesabı engellemek üzeresiniz." + bookmarks_html: "%{filename} dosyasından %{total_items} gönderiyi yerimlerinize eklemek üzeresiniz." + domain_blocking_html: "%{filename} dosyasından %{total_items} alan adını engellemek üzeresiniz." + following_html: "%{filename} dosyasından %{total_items} hesabı takip etmek üzeresiniz." + lists_html: "Listelerinize %{filename} dosyasından en fazla %{total_items} hesap eklemek üzeresiniz. Eklenecek bir liste olmaması durumunda yeni listeler oluşturulacaktır." + muting_html: "%{filename} dosyasından %{total_items} hesabı sessize almak üzeresiniz." preface: Diğer sunucudan alarak oluşturduğunuz dosyalar sayesinde, bu sunucudaki hesabınıza takipçilerinizi aktarabilir veya istemediğiniz kişileri otomatik olarak engelleyebilirsiniz. + recent_imports: Son içe aktarmalar + states: + finished: Bitti + in_progress: Sürüyor + scheduled: Zamanlanmış + unconfirmed: Onaylanmamış + status: Durum success: Verileriniz başarıyla yüklendi ve zaman içinde işlenecek + time_started: Başlangıç + titles: + blocking: Engellenmiş hesaplar içe aktarılıyor + bookmarks: Yer işaretleri içe aktarılıyor + domain_blocking: Engellenmiş alan adları içe aktarılıyor + following: Takip edilen hesaplar içe aktarılıyor + lists: Listeleri içe aktarma + muting: Sessize alınmış hesaplar içe aktarılıyor + type: İçe aktarma türü + type_groups: + constructive: Takipler ve Yerimleri + destructive: Engellenenler ve sessize alınanlar types: blocking: Engellenenler listesi bookmarks: Yer imleri domain_blocking: Alan adı engelleme listesi following: Takip edilenler listesi + lists: Listeler muting: Susturulanlar listesi upload: Yükle invites: @@ -1251,7 +1370,7 @@ tr: title: İnsanları davet et lists: errors: - limit: En yüksek liste sayısına ulaştınız + limit: Azami liste sayısına ulaştınız login_activities: authentication_methods: otp: iki aşamalı kimlik doğrulama uygulaması @@ -1263,6 +1382,21 @@ tr: failed_sign_in_html: "%{method} yöntemiyle %{ip} (%{browser}) adresinden başarısız oturum açma girişimi" successful_sign_in_html: "%{method} yöntemiyle %{ip} (%{browser}) adresinden başarılı oturum açma" title: Kimlik doğrulama geçmişi + mail_subscriptions: + unsubscribe: + action: Evet, abonelikten çık + complete: Abonelikten çık + confirmation_html: '%{domain} üzerindeki Mastodon için %{type} almayı durdurarak %{email} adresindeki aboneliğinizi iptal etmek istediğinizden emin misiniz? e-posta bildirim ayarlarınızdan her zaman yeniden abone olabilirsiniz.' + emails: + notification_emails: + favourite: bildirim e-postalarını favorile + follow: bildirim e-postalarını takip et + follow_request: istek e-postalarını takip et + mention: bildirim e-postalarına değin + reblog: bildirim e-postalarını yükselt + resubscribe_html: Abonelikten yanlışlıkla çıktıysanız, e-posta bildirim ayarlarınızdan yeniden abone olabilirsiniz. + success_html: Artık %{email} adresindeki e-postanıza %{domain} üzerindeki Mastodon için %{type} almayacaksınız. + title: Abonelikten çık media_attachments: validations: images_and_video: Zaten resim içeren bir duruma video eklenemez @@ -1342,6 +1476,7 @@ tr: update: subject: "%{name} bir gönderiyi düzenledi" notifications: + administration_emails: Yönetici e-posta bildirimleri email_events: E-posta bildirimi gönderilecek etkinlikler email_events_hint: 'Bildirim almak istediğiniz olayları seçin:' other_settings: Diğer bildirim ayarları @@ -1378,12 +1513,22 @@ tr: expired: Anket çoktan sona erdi invalid_choice: Seçilen oylama seçeneği mevcut değil over_character_limit: her biri %{max} karakterden daha uzun olamaz + self_vote: Kendi anketlerinizde oy kullanamazsınız too_few_options: birden fazla öğeye sahip olmalı too_many_options: "%{max} öğeden fazla öğe içeremez" preferences: other: Diğer posting_defaults: Gönderi varsayılanları public_timelines: Genel zaman çizelgeleri + privacy: + hint_html: "Profilinizin ve gönderilerinizin nasıl bulunmasını istediğinizi yapılandırın. Mastodon'daki çeşitli özellik etkinleştirildiklerinde çok daha geniş bir izleyici kitlesine ulaşmanıza yardımcı olabilir. Durumunuza uyup uymadığını anlamak için bu ayarlara bir göz atın." + privacy: Gizlilik + privacy_hint_html: Başkalarına ne kadar bilgi göstermek istediğinizi denetleyin. İnsanlar ilginç profilleri ve havalı uygulamaları diğer kişilerin takiplerine ve gönderileri paylaştıkları uygulamalara bakarak keşfederler, ama belki de gizli tutmak isteyebilirsiniz. + reach: Erişim + reach_hint_html: Yeni insanlar tarafından ne kadar keşfedilmek ve takip edilmek istediğinizi denetleyin. Gönderilerinizin Keşfet ekranında görüntülenmesini istiyor musunuz? Başkalarının takip önerileri listesinde görünmek istiyor musunuz? Tüm yeni takipçileri otomatik olarak kabul etmek mi yoksa her bir istek üzerinden ayrıntılı denetim mi istiyorsunuz? + search: Ara + search_hint_html: Nasıl bulunmak istediğinizi denetleyin. Herkese açık gönderileriniz aracılığıyla daha fazla insanın sizi bulmasını istiyor musunuz? Mastodon dışındaki kişilerin webte arama yaptığında profilinizi bulmasını istiyor musunuz? Tüm arama motorlarından tamamen çıkmanın herkese açık bilgiler için garanti olmadığını lütfen unutmayın. + title: Gizlilik ve erişim privacy_policy: title: Gizlilik Politikası reactions: @@ -1396,6 +1541,7 @@ tr: confirm_remove_selected_followers: Seçili takipçileri kaldırmak istediğinizden emin misiniz? confirm_remove_selected_follows: Seçili takipleri kaldırmak istediğinizden emin misiniz? dormant: Uykuda + follow_failure: Seçilen hesaplardan bazıları takip edilemedi. follow_selected_followers: Seçili takipçileri takip et followers: Takipçiler following: Takip edilenler @@ -1435,6 +1581,7 @@ tr: electron: Electron firefox: Firefox generic: Bilinmeyen tarayıcı + huawei_browser: Huawei Tarayıcı ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1444,6 +1591,7 @@ tr: qq: QQ Browser safari: Safari uc_browser: UC Browser + unknown_browser: Bilinmeyen Tarayıcı weibo: Weibo current_session: Geçerli oturum description: "%{platform} - %{browser}" @@ -1456,9 +1604,10 @@ tr: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: bilinmeyen platform + unknown_platform: Bilinmeyen Platform windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1529,7 +1678,6 @@ tr: show_newer: Yenileri göster show_older: Eskileri göster show_thread: Konuyu göster - sign_in_to_participate: Sohbete katılmak için oturum açın title: '%{name}: "%{quote}"' visibilities: direct: Doğrudan @@ -1571,12 +1719,10 @@ tr: '7889238': 3 ay min_age_label: Zaman eşiği min_favs: Şundan daha fazla beğenilen gönderileri sakla - min_favs_hint: Bu belirtilenden daha fazla beğeni alan gönderilerinizin herhangi birini silmez. Beğeni sayısından bağımsız olarak gönderilerin silinmesi için burayı boş bırakın + min_favs_hint: En az bu belirtilen kadar beğeni alan gönderilerinizin herhangi birini silmez. Beğeni sayısından bağımsız olarak gönderilerin silinmesi için burayı boş bırakın min_reblogs: Şundan daha fazla teşvik edilen gönderileri sakla min_reblogs_hint: Bu belirtilenden daha fazla teşvik edilen gönderilerinizin herhangi birini silmez. Teşvik sayısından bağımsız olarak gönderilerin silinmesi için burayı boş bırakın stream_entries: - pinned: Sabitlenmiş gönderi - reblogged: boostladı sensitive_content: Hassas içerik strikes: errors: @@ -1592,6 +1738,11 @@ tr: default: "%d %b %Y %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d.%m.%Y %H:%M %Z" + translation: + errors: + quota_exceeded: Çeviri hizmetinin sunucu kapsamındaki kullanım kotası aşıldı. + too_many_requests: Çeviri hizmetine son zamanlarda çok fazla istek yapıldı. two_factor_authentication: add: Ekle disable: 2FA'yı devre dışı bırak @@ -1671,13 +1822,18 @@ tr: title: Gemiye hoşgeldin, %{name}! users: follow_limit_reached: "%{limit} kişiden daha fazlasını takip edemezsiniz" + go_to_sso_account_settings: Kimlik sağlayıcı hesap ayarlarına gidin invalid_otp_token: Geçersiz iki adımlı doğrulama kodu otp_lost_help_html: Her ikisine de erişiminizi kaybettiyseniz, %{email} ile irtibata geçebilirsiniz seamless_external_login: Harici bir servis aracılığıyla oturum açtınız, bu nedenle parola ve e-posta ayarları mevcut değildir. signed_in_as: 'Oturum açtı:' verification: - explanation_html: 'Profil meta verisindeki bağlantıların sahibi olarak kendinizi doğrulayabilirsiniz. Bunun için, link verilen web sitesi Mastodon profilinize geri bir link içermelidir. Geri link bir rel="me" özelliğine sahip olmalıdır. Bağlantının metin içeriği önemli değildir. İşte bir örnek:' + extra_instructions_html: İpucu: Web sitenizdeki bağlantı görünmez olabilir. Önemli olan, kullanıcı tarafından oluşturulan içeriğe sahip web sitelerinde kimliğe bürünmeyi önleyen rel="me"'dir. Sayfa başlığında a yerine bir bağlantı etiketi de kullanabilirsiniz, ancak HTML'ye JavaScript çalıştırılmadan erişilebilir olmalıdır. + here_is_how: İşte yapmanın yolu + hint_html: "Mastodon'da kendini doğrulamak herkese açık. Açık web standartlarına dayanır, şimdi ve her zaman ücretsizdir. Tüm gereken insanların sizi onunla tanımladığı bir kişisel websitesidir. Profilinizde bu websitesinin bağlantısını verdiğinizde, websitesinizin profilinize bağlantı verip vermediğini denetleyip üzerinde görsel bir işaret koyacağız." + instructions_html: Aşağıdaki kodu kopyalayın ve websitenizin HTML'sine yapıştırın. Daha sonra "Profil Düzenle" sekmesini kullanarak profilinizdeki ek sahalardan birine websitenizin adresini ekleyin ve değişiklikleri kaydedin. verification: Doğrulama + verified_links: Doğrulanmış bağlantılarınız webauthn_credentials: add: Yeni güvenlik anahtarı ekle create: diff --git a/config/locales/tt.yml b/config/locales/tt.yml index 01b491b11b..845b33a021 100644 --- a/config/locales/tt.yml +++ b/config/locales/tt.yml @@ -2,69 +2,192 @@ tt: about: contact_unavailable: Юк + title: Проект турында accounts: follow: Языл + followers: + other: Язылучы following: Язылгансыз + posts: + other: Язма + posts_tab_heading: Язмалар admin: + account_moderation_notes: + create: Искәрмә өстәү accounts: + approve: Хуплау + are_you_sure: Раслыйсызмы? avatar: Аватар by_domain: Домен change_email: + changed_msg: Эл. почта уңышлы үзгәртелде! + current_email: Агымдагы эл. почта label: Emailны үзгәртү + new_email: Яңа эл. почта submit: Emailны үзгәртү + title: "%{username} өчен эл. почтаны үзгәртү" + change_role: + changed_msg: Роль уңышлы үзгәртелде! + label: Рольне үзгәртү + no_role: Рольсез + title: "%{username} өчен рольне үзгәртү" confirm: Раслау + confirmed: Расланды + delete: Мәгълүматны бетерү deleted: Бетерелде + disable_two_factor_authentication: 2FA-ны cүндерү + display_name: Күрсәтелгән исем domain: Домен edit: Үзгәртү email: Эл. почта + email_status: Эл. почта халәте header: Башлам + inbox_url: Килгән хатлар URL + invited_by: Тарафыннан чакырылды ip: ІР + joined: Кушылды location: all: Бөтенесе local: Җирле title: Урын + login_status: Логин халәте + memorialized: Һәйкәлгә әйләнде moderation: active: Актив all: Бөтенесе + disabled: Cүндерелгән + pending: Көтелә + silenced: Чикләнгән + suspended: Туктатып торылган + title: Модерация perform_full_suspension: Искә алмау + promote: Күтәрү + protocol: Протокол + public: Һәркемгә ачык + redownload: Профильне яңарту + reject: Кире кагу + remove_avatar: Аватарны бетерү + remove_header: Башламаны бетерү + removed_avatar_msg: "%{username} хисабының аватар рәсеме уңышлы бетерелде" + removed_header_msg: "%{username} хисабының башлам рәсеме уңышлы бетерелде" + resend_confirmation: + success: Тикшерү сылтамасы уңышлы җибәрелде! reset: Ташлату + reset_password: Серсүзне алыштыру + resubscribe: Яңадан язылу + role: Роль search: Эзләү + security: Иминлек + security_measures: + only_password: Серсүз генә + password_and_2fa: Серсүз һәм 2FA sensitive: Sizmäle + silence: Чикләү + silenced: Чикләнгән + statuses: Язмалар + subscribe: Язылу + suspended: Туктатып торылган + title: Аккаунтлар username: Кулланучы исеме + warn: Кисәтү web: Веб action_logs: action_types: + create_user_role: Роль булдыру + destroy_instance: Домены чистарту + destroy_ip_block: IP кагыйдәсен бетерү + destroy_status: Язманы бетерү + destroy_user_role: Рольне бетерү disable_2fa_user: 2FA cүндерү + memorialize_account: Хисапны һәйкәлгә әйләндерү + remove_avatar_user: Аватарны бетерү + reopen_report: Шикаятьне яңадан ачу + reset_password_user: Серсүзне алыштыру + suspend_account: Хисапны туктатып тору + unsuspend_account: Хисапны туктатып тормау + deleted_account: бетерелгән хисап + title: Аудит журналы + announcements: + destroyed_msg: Белдерү уңышлы бетерелде! + live: Турыдан-туры + published_msg: Белдерү уңышлы бастырылды! + title: Белдерүләр + unpublish: Нәшер итмәү + unpublished_msg: Белдерү уңышлы бастырылмады! + updated_msg: Белдерү уңышлы яңартылды! custom_emojis: by_domain: Домен + copied_msg: Локаль эмодзинең күчермәсе уңышлы ясалды copy: Күчереп алу + created_msg: Эмодзи уңышлы ясалды! delete: Бетерү + destroyed_msg: Эмодзи уңышлы юк ителде! disable: Cүндерү - disabled: Cүндерелгән - enable: Кабызу + disabled: Cүнек + disabled_msg: Бу эмодзи уңышлы сүндерелде + emoji: Эмодзи + enable: Кушу + enabled_msg: Бу эмодзи уңышлы кабызылды list: Исемлек - upload: Йөкләү + overwrite: Яңадан язу + shortcode: Кыска код + updated_msg: Эмодзи уңышлы яңартылды! + upload: Йөкләтү + dashboard: + new_users: яңа кулланучылар + software: Программа тәэминаты + title: Идарә аслыгы + website: Вебсайт + domain_allows: + export: Экспортлау + import: Импортлау domain_blocks: domain: Домен + export: Экспортлау + import: Импортлау new: severity: noop: Бернинди дә + silence: Чикләү suspend: Искә алмау email_domain_blocks: + created_msg: Эл. почта домены уңышлы блокланды delete: Бетерү + dns: + types: + mx: MX язмасы domain: Домен + new: + create: Домен өстәү follow_recommendations: + language: Тел өчен status: Халәт + suppressed: Тәэсире киметелгән instances: + availability: + title: Мөмкинлек + back_to_all: Барысы да + back_to_warning: Игътибар by_domain: Домен + content_policies: + policies: + reject_media: Медиа-файлны кире кагу + silence: Чикләү + delivery: + all: Барысы да moderation: all: Бөтенесе + title: Модерация + purge: Чистарту + title: Федерация invites: filter: all: Бөтенесе + available: Мөмкин expired: Гамәлдән чыкты title: Sözgeç ip_blocks: + created_msg: Яңа IP кагыйдәсе уңышлы өстәлде delete: Бетерү expires_in: '1209600': 2 атна @@ -79,37 +202,143 @@ tt: disable: Cүндерү disabled: Cүндерелгән enable: Кабызу + inbox_url: Ретранслятор URL-ы + save_and_enable: Саклау һәм кабызу status: Халәт + report_notes: + created_msg: Шикаять язмасы уңышлы ясалды! + destroyed_msg: Шикаять язмасы уңышлы бетерелде! reports: + account: + notes: + other: "%{count} искәрмә" + action_log: Аудит журналы + are_you_sure: Моны раслыйсызмы? + cancel: Баш тарту + category: Категория comment: none: Бернинди дә + confirm: Раслау + delete_and_resolve: Язмаларны бетерү + forwarded: Тапшырылган notes: create: Язу кушу delete: Бетерү + title: Искәрмәләр + reopen: Шикаятьне яңадан ачу + report: 'Шикаять #%{id}' + resolved_msg: Шикаять уңышлы чишелде! status: Халәт + unresolved: Танылмаган updated_at: Яңартылды + view_profile: Профильне ачу + roles: + assigned_users: + other: "%{count} кулланучы" + categories: + devops: DevOps + moderation: Модерация + delete: Бетерү + privileges: + administrator: Администратор + invite_users: Кулланучыларны чакыру + manage_roles: Рольләр белән идарә итү + manage_rules: Кагыйдәләр белән идарә итү + manage_users: Кулланучылар белән идарә итү + view_devops: DevOps + title: Рольләр rules: delete: Бетерү + edit: Кагыйдәне үзгәртү + title: Сервер кагыйдәләре + settings: + about: + title: Хакында + appearance: + title: Кыяфәт + discovery: + trends: Мөһим вакыйгалар + domain_blocks: + disabled: Һичкемгә + site_uploads: + destroyed_msg: Сайтны йөкләү уңышлы бетерелде! statuses: + account: Автор + application: Кушымта + batch: + report: Шикаять итү deleted: Бетерелде + favourites: Сайланмалар + history: Версия тарихы + language: Тел media: title: Медиа + metadata: Метамәгълүматлар + open: Язманы ачу + original_status: Башлангыч язма + status_changed: Язма үзгәртелде + visibility: Күренүчәнлек + with_media: Медиа-файл белән + tags: + updated_msg: Хәштәг көйләүләре уңышлы яңартылды trends: allow: Рөхсәт итү + links: + allow: Сылтаманы рөхсәт итү + preview_card_providers: + title: Нәширләр + rejected: Кире кагылган + statuses: + allow: Язманы рөхсәт итү + tags: + dashboard: + tag_languages_dimension: Иң популяр телләр + tag_servers_dimension: Иң популяр серверлар + usable: Кулланырга мөмкин + title: Мөһим вакыйгалар warning_presets: delete: Бетерү + webhooks: + delete: Бетерү + disable: Cүндерү + disabled: Cүндерелгән + enable: Кабызу + events: Вакыйгалар + new: Яңа вебхук + status: Халәт + title: Вебхуклар + webhook: Вебхук + admin_mailer: + new_appeal: + actions: + none: кисәтү application_mailer: salutation: "%{name}," + view: 'Карау:' + view_profile: Профильне ачу + view_status: Язманы карау + applications: + created: Кушымта уңышлы ясалды + destroyed: Кушымта уңышлы бетерелде + logout: Чыгу auth: - change_password: Парол + log_in_with: Аның белән керү login: Керү + logout: Чыгу + or_log_in_with: Яки аның белән керү + progress: + confirm: Эл. почтаны раслагыз providers: cas: САS saml: SАML register: Теркәлү + reset_password: Серсүзне алыштыру + rules: + accept: Кабул итү + back: Кире security: Хәвефсезлек - authorize_follow: - follow: Язылу + status: + account_status: Хисап халәте challenge: confirm: Дәвам итү date: @@ -130,35 +359,57 @@ tt: x_minutes: "%{count}м" x_months: "%{count}ай" x_seconds: "%{count}сек" - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. + deletes: + success_msg: Хисабыгыз уңышлы бетерелде + disputes: + strikes: + appeal: Апелляция + created_at: Дата + title_actions: + none: Игътибар exports: archive_takeout: date: Көне - size: Olılıq + size: Зурлык bookmarks: Кыстыргычлар csv: СSV + lists: Исемлекләр + storage: Медиа-файллар саклагычы + featured_tags: + add_new: Яңа өстәү filters: contexts: + notifications: Искәртүләр thread: Әңгәмәләр + edit: + add_keyword: Ачкыч сүз өстәү + keywords: Ачкыч сүзләр index: delete: Бетерү title: Сөзгечләр generic: all: Бөтенесе + cancel: Баш тарту + changes_saved_msg: Үзгәрешләр уңышлы сакланды! + confirm: Раслау copy: Күчереп алу delete: Бетерү + deselect: Берсен дә сайламаска + none: Бернинди дә + save_changes: Үзгәрешләрне саклау today: бүген imports: + errors: + empty: Буш CSV файлы + modes: + merge: Берләштерү + overwrite: Яңадан язу + states: + scheduled: Җәдвәлләнгән + status: Халәт types: bookmarks: Кыстыргычлар - upload: Йөкләү + upload: Йөкләтү invites: expired: Гамәлдән чыкты expires_in: @@ -169,30 +420,63 @@ tt: '604800': 1 атна '86400': 1 көн expires_in_prompt: Беркайчан да + max_uses: + other: "%{count} кулланылыш" + table: + uses: Куллана + login_activities: + authentication_methods: + password: серсүз + moderation: + title: Модерация + notification_mailer: + mention: + action: Җавап бирү + title: Яңа искә алу number: human: decimal_units: - format: "%n%u" + format: "%n %u" + units: + billion: Млрд + million: Млн + quadrillion: Квадрлн + thousand: Мең + trillion: Трлн otp_authentication: - enable: Кабызу + enable: Кушу + setup: Көйләү pagination: + newer: Яңарак next: Киләсе + older: Искерәк prev: Алдыгы truncate: "…" preferences: other: Башка - posting_defaults: Posting defaults - public_timelines: Public timelines + privacy_policy: + title: Хосусыйлык Сәясәте relationships: - following: Язылгансыз + dormant: Актив түгел + followers: Язылучылар + following: Язылулар + invited: Чакырылды + most_recent: Иң соңгы + moved: Күчерелде + mutual: Үзара + primary: Төп + relationship: Бәйләнеш sessions: browser: Браузер browsers: alipay: Аlipay + blackberry: BlackBerry chrome: Chrоme edge: Microsоft Edge electron: Electrоn firefox: Firеfox + generic: Билгесез браузер + huawei_browser: Huawei Browser ie: Internet Explоrer micro_messenger: MicroMеssenger nokia: Nokia S40 Ovi Brоwser @@ -201,42 +485,66 @@ tt: phantom_js: PhаntomJS qq: QQ Brоwser safari: Safаri + uc_browser: UC Browser + unknown_browser: Билгесез Браузер weibo: Weibо - description: "%{browser} - %{platform}" + current_session: Агымдагы сессия + description: "%{platform} платформасында %{browser}" ip: ІР platforms: adobe_air: Adobе Air android: Andrоid + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firеfox OS ios: iОS + kai_os: KaiOS linux: Lіnux mac: macOS windows: Windоws windows_mobile: Windows Mоbile windows_phone: Windоws Phone + revoke: Кире алу settings: - account: Хисап язмасы - appearance: Küreneş - development: Эшләнмә - edit_profile: Профильны үзгәртү + account: Аккаунт + appearance: Тышкы кыяфәт + development: Ясаучылар өчен + edit_profile: Профильне үзгәртү import: Импортлау + notifications: Искәртүләр preferences: Caylaw profile: Профиль + two_factor_authentication: Ике-факторлы авторизация statuses: attached: + audio: + other: "%{count} аудио" + image: + other: "%{count} рәсем" video: other: "%{count} видео" + edited_at_html: "%{date} көнне төзәтте" + open_in_web: Веб-та ачу + poll: + total_people: + other: "%{count} кеше" + vote: Тавыш бирү + show_more: Күбрәк күрсәтү title: '%{name}: "%{quote}"' + visibilities: + private: Ияртүчеләр генә + public: Һәркемгә ачык statuses_cleanup: min_age: '1209600': 2 атна - '15778476': 6 months '2629746': 1 ай '31556952': 1 ел '5259492': 2 ай '604800': 1 атна '63113904': 2 ел '7889238': 3 ай + themes: + default: Mastodon (Караңгы) time: formats: default: "%d %b %Y, %H:%M" @@ -245,11 +553,17 @@ tt: two_factor_authentication: add: Өстәү disable: 2FA cүндерү + disabled_success: Ике-факторлы аутентификация уңышлы сүндерелде edit: Үзгәртү + enabled_success: Ике-факторлы аутентификация уңышлы кабызылды user_mailer: warning: - reason: 'Сәбаб:' + categories: + spam: Спам + reason: 'Сәбәп:' title: none: Игътибар + verification: + verification: Раслау webauthn_credentials: delete: Бетерү diff --git a/config/locales/ug.yml b/config/locales/ug.yml index ea5bdb5c88..289acf2418 100644 --- a/config/locales/ug.yml +++ b/config/locales/ug.yml @@ -1,10 +1 @@ ---- ug: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/uk.yml b/config/locales/uk.yml index dd6d42daaa..93cdc04174 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -54,7 +54,7 @@ uk: no_role: Немає ролі title: Змінити роль для %{username} confirm: Зберегти - confirmed: Збережено + confirmed: Підтвердити ел.адресу confirming: Зберігається custom: Власне delete: Видалити дані @@ -89,12 +89,13 @@ uk: title: Розміщення login_status: Стан входу media_attachments: Мультимедійні вкладення - memorialize: Зробити пам'ятником + memorialize: Меморіалізувати memorialized: Перетворено на пам'ятник memorialized_msg: "%{username} успішно перетворено на пам'ятний обліковий запис" moderation: active: Активний all: Усі + disabled: Вимкнено pending: Очікують silenced: Обмежені suspended: Призупинені @@ -130,7 +131,7 @@ uk: removed_header_msg: Зображення обкладинки %{username} вилучено resend_confirmation: already_confirmed: Цей користувач уже підтверджений - send: Надіслати електронний лист-підтвердження ще раз + send: Повторно надіслати підтвердження на електронну пошту success: Електронний лист-підтвердження успішно надіслано! reset: Скинути reset_password: Скинути пароль @@ -139,6 +140,7 @@ uk: search: Пошук search_same_email_domain: Інші користувачі з тим самим поштовим доменом search_same_ip: Інші користувачі з тим самим IP + security: Безпека security_measures: only_password: Лише пароль password_and_2fa: Пароль та 2FA @@ -148,7 +150,7 @@ uk: show: created_reports: Скарги, створені цим обліковим записом targeted_reports: Скарги на цей обліковий запис - silence: Глушення + silence: Обмежити silenced: Заглушені statuses: Дописи strikes: Попередні попередження @@ -162,7 +164,7 @@ uk: unblocked_email_msg: Адреса електронної пошти %{username} успішно розблокована unconfirmed_email: Непідтверджена адреса електронної пошти undo_sensitized: Скасувати позначення делікатним - undo_silenced: Зняти глушення + undo_silenced: Зняти обмеження undo_suspension: Зняти призупинення unsilenced_msg: Успішно знято обмеження з облікового запису %{username} unsubscribe: Відписатися @@ -209,7 +211,7 @@ uk: enable_custom_emoji: Увімкнути користувацькі емодзі enable_sign_in_token_auth_user: Увімкнути автентифікацію за допомогою е-пошти для користувача enable_user: Активувати користувача - memorialize_account: Зробити обліковий запис меморіалом + memorialize_account: Меморіалізувати акаунт promote_user: Підвищити користувача reject_appeal: Відхилити апеляцію reject_user: Відхилити користувача @@ -313,6 +315,7 @@ uk: unpublish: Скасувати публікацію unpublished_msg: Оголошення успішно приховано! updated_msg: Оголошення успішно оновлено! + critical_update_pending: Очікується критичне оновлення custom_emojis: assign_category: Призначити категорію by_domain: Домен @@ -394,6 +397,15 @@ uk: undo: Видалити з білого списку domain_blocks: add_new: Додати нове + confirm_suspension: + cancel: Скасувати + confirm: Призупинити + permanent_action: Скасування призупинення не відновить жодних даних або відносин. + preamble_html: Ви збираєтеся призупинити %{domain} і його піддомени. + remove_all_data: Це вилучить усі дані вмісту, медіа та профілів для облікових записів цього домену із вашого сервера. + stop_communication: Ваш сервер перестане взаємодіяти з цими серверами. + title: Підтвердити блокування домену для %{domain} + undo_relationships: Це призведе до скасування всіх взаємозв'язків між обліковими записами цих серверів і вашими. created_msg: Блокування домену обробляється destroyed_msg: Блокування домену знято domain: Домен @@ -443,6 +455,7 @@ uk: resolve: Розв'язати домен title: Нове блокування поштового домену no_email_domain_block_selected: Жодні налаштування блокування доменів електронної пошти не було змінено, оскільки жоден з них не було обрано + not_permitted: Не дозволено resolved_dns_records_hint_html: Ім'я домену резолвиться в наступні домени MX, які в кінцевому рахунку відповідають за прийняття електронної пошти. Блокування домену MX заблокує реєстрацію з будь-якої e-mail адреси, яка використовує однаковий домен MX, навіть якщо доменне ім'я буде інакше. Будьте обережні, щоб не блокувати великих поштових провайдерів. resolved_through_html: Розв'язано через %{domain} title: Чорний список поштових доменів @@ -493,6 +506,7 @@ uk: content_policies: comment: Внутрішня примітка description_html: Ви можете визначити правила вмісту що буде застосовано до всіх облікових записів із цього домену та будь-якого з його піддоменів. + limited_federation_mode_description_html: Ви можете вибрати, чи дозволити федерацію з цим доменом. policies: reject_media: Відхилити медіа reject_reports: Відхилити скарги @@ -609,11 +623,13 @@ uk: assign_to_self: Призначити мені assigned: Призначений модератор by_target_domain: Домен облікового запису, на який скаржаться + cancel: Скасувати category: Категорія category_description_html: Причина скарги на цей обліковий запис та/або вміст, яку буде вказано у звіті comment: none: Немає comment_description_html: 'Щоб надати більше відомостей, %{name} пише:' + confirm: Підтвердити confirm_action: Підтвердьте модераційну дію щодо @%{acct} created_at: Створено delete_and_resolve: Видалити дописи @@ -753,6 +769,9 @@ uk: branding: preamble: Брендинг вашого сервера відрізняє його від інших серверів в мережі. Ця інформація може показуватися в різних середовищах, таких як вебінтерфейс Mastodon, застосунки, у попередньому перегляді посилань на інші вебсайти та в застосунках обміну повідомленнями. Тому краще, щоб ця інформація була чіткою, короткою та лаконічною. title: Брендинг + captcha_enabled: + desc_html: Це залежить від зовнішніх скриптів hCaptcha, що може становити загрозу безпеці та приватності. Крім того, це може зробити процес реєстрації значно менш доступним для деяких людей (особливо з обмеженими можливостями). З цих причин, будь ласка, розгляньте альтернативні заходи, такі як реєстрація на основі схвалення або на основі запрошення. + title: Вимагати нових користувачів розв'язувати CAPTCHA для підтвердження облікового запису content_retention: preamble: Контролюйте, як зберігаються користувацькі матеріали в Mastodon. title: Зберігання вмісту @@ -780,10 +799,27 @@ uk: approved: Для входу потрібне схвалення none: Ніхто не може увійти open: Будь-хто може увійти + security: + authorized_fetch: Вимагати аутентифікацію з федеративних серверів + authorized_fetch_hint: Вимога автентифікації від федеративних серверів забезпечує суворіше застосування блокування як на рівні користувача, так і на рівні сервера. Однак це призводить до зниження продуктивності, зменшує охоплення ваших відповідей і може спричинити проблеми сумісності з деякими федеративними сервісами. Крім того, це не завадить зловмисникам отримувати ваші загальнодоступні дописи та облікові записи. + authorized_fetch_overridden_hint: Наразі ви не можете змінити це налаштування, тому що воно перевизначене змінною середовища. + federation_authentication: Впровадження автентифікації у федерації title: Налаштування сервера site_uploads: delete: Видалити завантажений файл destroyed_msg: Завантаження сайту успішно видалено! + software_updates: + critical_update: Критично — оновіться якнайшвидше + description: Радимо постійно оновлювати інсталяцію Mastodon, щоб мати змогу користуватися найновішими виправленнями та функціями. На додаток, іноді дуже важливо вчасно оновлювати Mastodon, щоб уникнути проблем з безпекою. З цих причин Mastodon перевіряє наявність оновлень що 30 хвилин і сповіщає вас про це відповідно до ваших налаштувань сповіщень на електронну пошту. + documentation_link: Докладніше + release_notes: Примітки до випуску + title: Доступні оновлення + type: Тип + types: + major: Головний випуск + minor: Проміжний випуск + patch: Випуск виправлень — виправлення помилок і прості у застосуванні зміни + version: Версія statuses: account: Автор application: Застосунок @@ -820,9 +856,24 @@ uk: suspend: "%{name} заморожує обліковий запис %{target}" appeal_approved: Оскаржено appeal_pending: Оскарження в очікуванні + appeal_rejected: Апеляцію відхилено system_checks: database_schema_check: message_html: Існують відкладені перенесення бази даних. Запустіть їх, щоб забезпечити очікувану роботу програми + elasticsearch_health_red: + message_html: Кластер Elasticsearch нездоровий (червоний статус), функції пошуку недоступні + elasticsearch_health_yellow: + message_html: Кластер Elasticsearch нездоровий (жовтий статус), можливо, вам потрібно дослідити причину + elasticsearch_index_mismatch: + message_html: Зіставлення індексів Elasticsearch застаріли. Запустіть tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Дивись документацію + message_html: У вашому кластері Elasticsearch більше ніж один вузол, але Mastodon не сконфігуровано на їх застосування. + elasticsearch_preset_single_node: + action: Дивись документацію + message_html: Ваш кластер Elasticsearch має лише один вузол, ES_PRESET слід налаштувати на single_node_cluster. + elasticsearch_reset_chewy: + message_html: Ваш індекс системи Elasticsearch застарілий через зміну налаштувань. Запустіть tootctl search deploy --reset-chewy, щоб оновити його. elasticsearch_running_check: message_html: Не вдалося під'єднатися до Elasticsearch. Перевірте, чи він запущений або вимкніть повнотекстовий пошук elasticsearch_version_check: @@ -833,6 +884,18 @@ uk: message_html: Ви не визначили будь-які правила сервера. sidekiq_process_check: message_html: Не працює процес Sidekiq для %{value} черги. Перегляньте конфігурації вашого Sidekiq + software_version_critical_check: + action: Переглянути доступні оновлення + message_html: Виявлено критичне оновлення Mastodon. Оновіться якнайшвидше. + software_version_patch_check: + action: Переглянути доступні оновлення + message_html: Доступне оновлення Mastodon з виправленням помилок. + upload_check_privacy_error: + action: Перегляньте подробиці тут + message_html: "Ваш вебсервер неправильно налаштований. Приватність ваших користувачів піддається ризику" + upload_check_privacy_error_object_storage: + action: Перегляньте подробиці тут + message_html: "Ваше сховище об'єктів неправильно налаштоване. Приватність ваших користувачів піддається ризику" tags: review: Переглянути допис updated_msg: Параметри хештеґів успішно оновлені @@ -857,6 +920,7 @@ uk: other: Поширили %{count} людей за останній тиждень title: Популярні посилання usage_comparison: Сьогодні поширено %{today} разів, у порівнянні з %{yesterday} вчора + not_allowed_to_trend: Не допускається тенденція only_allowed: Тільки дозволене pending_review: Очікує перевірки preview_card_providers: @@ -947,6 +1011,9 @@ uk: body: "%{target} оскаржує модерацію %{action_taken_by} від %{date}, яка була %{type}. Вони написали:" next_steps: Ви можете схвалити апеляцію, щоб скасувати рішення про модерацію або проігнорувати її. subject: "%{username} апелює до рішення про модерацію на %{instance}" + new_critical_software_updates: + body: Вийшли нові критичні оновлені версії Mastodon, можливо, ви захочете оновитися якнайшвидше! + subject: Критичні оновлення Mastodon доступні для %{instance}! new_pending_account: body: Деталі нового облікового запису наведено нижче. Ви можете схвалити або відхилити цю заяву. subject: Новий обліковий запис надіслано на розгляд на %{instance} (%{username}) @@ -954,6 +1021,9 @@ uk: body: "%{reporter} поскаржився на %{target}" body_remote: Хтось з домену %{domain} поскаржився на %{target} subject: Нова скарга до %{instance} (#%{id}) + new_software_updates: + body: Випущено нові версії Mastodon, можливо, ви захочете оновитися! + subject: Нові версії Mastodon доступні для %{instance}! new_trends: body: 'Ці елементи потребують розгляду перед оприлюдненням:' new_trending_links: @@ -983,24 +1053,28 @@ uk: guide_link: https://uk.crowdin.com/project/mastodon guide_link_text: Кожен може взяти участь. sensitive_content: Дражливий зміст - toot_layout: Зовнішній вигляд дописів application_mailer: notification_preferences: Змінити налаштування електронної пошти salutation: "%{name}," settings: 'Змінити налаштування електронної пошти: %{link}' + unsubscribe: Відписатися view: 'Перегляд:' view_profile: Показати профіль view_status: Показати допис applications: created: Застосунок успішно створений destroyed: Застосунок успішно видалений + logout: Вийти regenerate_token: Перегенерувати токен доступу token_regenerated: Токен доступу успішне перегенеровано warning: Будьте дуже обережні з цими даними. Ніколи не діліться ними ні з ким! your_token: Ваш токен доступу auth: apply_for_account: Запит облікового запису - change_password: Пароль + captcha_confirmation: + help_html: Якщо у вас виникли проблеми з вирішенням CAPTCHA, ви можете зв'язатися з нами через %{email} і ми можемо вам допомогти. + hint_html: Ще одне! Ми повинні пересвідчитись, що ви людина (щоб ми могли уникнути спаму!). Розв'яжіть CAPTCHA внизу і натисніть кнопку "Продовжити". + title: Перевірка безпеки confirmations: wrong_email_hint: Якщо ця адреса електронної пошти неправильна, можна змінити її в налаштуваннях облікового запису. delete_account: Видалити обліковий запис @@ -1009,7 +1083,7 @@ uk: prefix_invited_by_user: "@%{name} запрошує вас приєднатися до цього сервера Mastodon!" prefix_sign_up: Зареєструйтеся на Mastodon сьогодні! suffix: Маючи обліковий запис, ви зможете підписуватися на людей, публікувати дописи та листуватися з користувачами будь-якого сервера Mastodon! - didnt_get_confirmation: Не отримали інструкції з підтвердження? + didnt_get_confirmation: Не отримали посилання для підтвердження? dont_have_your_security_key: Не маєте ключа безпеки? forgot_password: Забули пароль? invalid_reset_password_token: Токен скидання паролю неправильний або просрочений. Спробуйте попросити новий. @@ -1022,26 +1096,39 @@ uk: migrate_account_html: Якщо ви бажаєте переспрямувати цей обліковий запис на інший, ви можете налаштувати це тут. or_log_in_with: Або увійдіть з privacy_policy_agreement_html: Мною прочитано і я погоджуюся з політикою приватності + progress: + confirm: Підтвердити електронну адресу + details: Ваші дані + review: Наш відгук + rules: Погодитися з правилами providers: cas: CAS saml: SAML register: Зареєструватися registration_closed: "%{instance} не приймає нових членів" - resend_confirmation: Повторно відправити інструкції з підтвердження + resend_confirmation: Повторно надіслати підтвердження на електронну пошту reset_password: Скинути пароль rules: + accept: Прийняти + back: Назад + invited_by: 'Ви можете приєднатися до %{domain} завдяки запрошенню, яке ви отримали від:' preamble: Вони налаштовані та закріплені модераторами %{domain}. + preamble_invited: Перед тим як продовжити ознайомтеся з основними правилами, встановленими модераторами %{domain}. title: Деякі основні правила. + title_invited: Вас запрошено. security: Зміна паролю set_new_password: Встановити новий пароль setup: - email_below_hint_html: Якщо ця електронна адреса не є вірною, ви можете змінити її тут та отримати новий лист для підтвердження. - email_settings_hint_html: Електронний лист-підтвердження було вислано на %{email}. Якщо ця адреса електронної пошти не правильна, ви можете змінити її в налаштуваннях облікового запису. - title: Налаштування + email_below_hint_html: Перевірте теку "Спам", або зробіть ще один запит. Ви можете виправити свою електронну адресу, якщо вона неправильна. + email_settings_hint_html: Натисніть на посилання, яке ми надіслали вам, щоб підтвердити %{email}. Ми чекатимемо прямо тут. + link_not_received: Не отримали посилання? + new_confirmation_instructions_sent: Ви отримаєте новий лист із посиланням на підтвердження протягом декількох хвилин! + title: Перевірте вашу поштову скриньку sign_in: preamble_html: Увійдіть за допомогою облікових даних %{domain}. Якщо ваш обліковий запис розміщений на іншому сервері, ви не зможете увійти тут. title: Увійти до %{domain} sign_up: + manual_review: Реєстрація на %{domain} проходить через ручний розгляд нашими модераторами. Щоб допомогти нам завершити вашу реєстрацію, напишіть трохи про себе і чому ви хочете зареєструватися на %{domain}. preamble: За допомогою облікового запису на цьому сервері Mastodon, ви зможете слідкувати за будь-якою іншою людиною в мережі, не зважаючи на те, де розміщений обліковий запис. title: Налаштуймо вас на %{domain}. status: @@ -1053,18 +1140,6 @@ uk: view_strikes: Переглянути попередні попередження вашому обліковому запису too_fast: Форму подано занадто швидко, спробуйте ще раз. use_security_key: Використовувати ключ безпеки - authorize_follow: - already_following: Ви вже слідкуєте за цим обліковим записом - already_requested: Ви вже надіслали запит на підписку до цього облікового запису - error: На жаль, під час пошуку віддаленого облікового запису сталася помилка - follow: Підписатися - follow_request: 'Вам надіслали запит на підписку:' - following: 'Ура! Ви тепер підписані на:' - post_follow: - close: Або, ви можете просто закрити вікно. - return: Перейти до профілю користувача - web: Перейти до вебу - title: Підписатися на %{acct} challenge: confirm: Далі hint_html: "Підказка: ми не будемо запитувати ваш пароль впродовж наступної години." @@ -1141,6 +1216,10 @@ uk: your_appeal_rejected: Вашу апеляцію було відхилено domain_validator: invalid_domain: не є допустимим ім'ям домену + edit_profile: + basic_information: Основна інформація + hint_html: "Налаштуйте те, що люди бачитимуть у вашому загальнодоступному профілі та поруч із вашими дописами. Інші люди з більшою ймовірністю підпишуться на вас та взаємодіятимуть з вами, якщо у вас є заповнений профіль та зображення профілю." + other: Інше errors: '400': Ваш запит був недійсним або неправильним. '403': У Вас немає доступу до перегляду даної сторінки. @@ -1178,7 +1257,7 @@ uk: add_new: Додати новий errors: limit: Ви досягли максимальної кількості хештеґів - hint_html: "Що таке виділені хештеґи? Це ті, що показуються на видному місці у вашому загальнодоступному профілі. Вони дають змогу людям фільтрувати ваші загальнодоступні дописи за цими хештеґами. Це дуже корисно для стеження з мистецькими творами та довготривалими проєктами." + hint_html: "Що таке виділені хештеги? Чудовий інструмент для відстеження ваших творчих робіт і довготривалих проєктів, рекомендовані хештеги показані першими у вашому профілі та дозволяють швидко отримати доступ до ваших власних повідомлень." filters: contexts: account: Профілі @@ -1227,8 +1306,6 @@ uk: index: hint: Цей фільтр застосовується для вибору окремих дописів, незалежно від інших критеріїв. Ви можете додавати більше дописів до цього фільтра з вебінтерфейсу. title: Відфільтровані дописи - footer: - trending_now: Актуальні generic: all: Усі all_items_on_page_selected_html: @@ -1241,7 +1318,9 @@ uk: many: Усі %{count} елементів, що збігаються з вашим пошуком вибрано. one: "%{count} елемент, що збігається з вашим пошуком вибрано." other: Усі %{count} елементи, що збігаються з вашим пошуком вибрано. + cancel: Скасувати changes_saved_msg: Зміни успішно збережені! + confirm: Підтвердити copy: Копіювати delete: Видалити deselect: Скасувати вибір @@ -1259,24 +1338,62 @@ uk: many: Щось досі не гаразд! Перегляньте %{count} повідомлень про помилки one: Щось досі не гаразд! Перегляньте повідомлення про помилку other: Щось досі не гаразд! Перегляньте %{count} повідомлень про помилки - html_validator: - invalid_markup: 'містить неприпустиму HTML розмітку: %{error}' imports: errors: + empty: Порожній CSV-файл + incompatible_type: Несумісний з обраним типом імпорту invalid_csv_file: 'Хибний файл CSV. Помилка: %{error}' over_rows_processing_limit: містить більше ніж %{count} рядків + too_large: Файл завеликий + failures: Невдачі + imported: Імпортовано + mismatched_types_warning: Схоже, ви обрали неправильний тип для цього імпорту, перевірте його ще раз. modes: merge: Злиття merge_long: Зберегти наявні записи та додати нові overwrite: Перезаписувати overwrite_long: Замінити наявні записи новими + overwrite_preambles: + blocking_html: Ви збираєтеся замінити ваш список блокування з %{total_items} обліковими записами з %{filename}. + bookmarks_html: Ви збираєтеся замінити ваші закладки з %{total_items} дописами з %{filename}. + domain_blocking_html: Ви збираєтеся замінити ваш список блокування доменів з %{total_items} доменами з %{filename}. + following_html: Ви збираєтеся слідкувати за %{total_items} обліковими записами з %{filename} і перестати слідкувати за всіма іншими. + lists_html: Ви збираєтеся замінити ваші списки вмістом з %{filename}. До нових списків буде додано до %{total_items} облікових записів. + muting_html: Ви збираєтеся замінити ваш список ігнорованих облікових записів з %{total_items} обліковими записами з %{filename}. + preambles: + blocking_html: Ви збираєтеся заблокувати %{total_items} облікових записів з %{filename}. + bookmarks_html: Ви збираєтеся додати %{total_items} дописів з %{filename} до ваших закладок. + domain_blocking_html: Ви збираєтеся заблокувати %{total_items} доменів з %{filename}. + following_html: Ви збираєтеся слідкувати за %{total_items} обліковими записами з %{filename}. + lists_html: Ви збираєтеся додати до %{total_items} облікових записів з %{filename} до ваших списків. Нові списки будуть створені, якщо немає списку для додавання. + muting_html: Ви збираєтеся ігнорувати %{total_items} облікових записів з %{filename}. preface: Ви можете імпортувати дані, які ви експортували з іншого сервера, наприклад, список людей, яких ви відстежуєте або блокуєте. + recent_imports: Останні імпорти + states: + finished: Завершені + in_progress: Тривають + scheduled: Заплановані + unconfirmed: Непідтверджені + status: Стан success: Ваші дані завантажено та буде оброблено найближчим часом + time_started: Розпочато о + titles: + blocking: Імпортування заблокованих облікових записів + bookmarks: Імпортування закладок + domain_blocking: Імпортування заблокованих доменів + following: Імпортування відстежуваних облікових записів + lists: Імпортування списків + muting: Імпортування ігнорованих облікових записів + type: Тип імпорту + type_groups: + constructive: Підписки та закладки + destructive: Блокування та ігнорування types: blocking: Список блокувань bookmarks: Закладки domain_blocking: Список заблокованих сайтів following: Підписки + lists: Списки muting: Список глушення upload: Завантажити invites: @@ -1317,6 +1434,21 @@ uk: failed_sign_in_html: Не вдалося увійти з %{method} з %{ip} (%{browser}) successful_sign_in_html: Успішний вхід з %{method} з %{ip} (%{browser}) title: Історія входів + mail_subscriptions: + unsubscribe: + action: Так, відписатися + complete: Відписалися + confirmation_html: Ви впевнені, що хочете відписатися від отримання %{type} для Mastodon на %{domain} до своєї скриньки %{email}? Ви можете повторно підписатися у налаштуваннях сповіщень електронною поштою. + emails: + notification_emails: + favourite: отримувати сповіщення про вподобання електронною поштою + follow: отримувати сповіщення про підписки електронною поштою + follow_request: отримувати сповіщення про запити на стеження електронною поштою + mention: отримувати сповіщення про згадки електронною поштою + reblog: отримувати сповіщення про поширення електронною поштою + resubscribe_html: Якщо ви відписалися помилково, ви можете повторно підписатися в налаштуваннях сповіщень електронною поштою. + success_html: Ви більше не отримуватимете %{type} для Mastodon %{domain} на адресу %{email}. + title: Відписатися media_attachments: validations: images_and_video: Не можна додати відео до допису з зображеннями @@ -1396,6 +1528,7 @@ uk: update: subject: "%{name} змінює допис" notifications: + administration_emails: Сповіщення е-пошти адміністратора email_events: Події, про які сповіщати електронною поштою email_events_hint: 'Оберіть події, про які ви хочете отримувати сповіщення:' other_settings: Інші налаштування сповіщень @@ -1432,12 +1565,22 @@ uk: expired: Це опитування вже завершено invalid_choice: Обраного варіанту голосування не існує over_character_limit: не може бути довше ніж %{max} символів кожен + self_vote: Ви не можете голосувати у власному опитуванні too_few_options: має містити більше ніж один варіант too_many_options: не може мати більше ніж %{max} варіантів preferences: other: Інше posting_defaults: Усталені налаштування дописів public_timelines: Глобальні стрічки + privacy: + hint_html: "Налаштуйте, як ви хочете, щоб знаходили ваш профіль і ваші дописи. Різноманітні функції Mastodon можуть допомогти вам охопити ширшу аудиторію, якщо їх увімкнути. Перегляньте ці налаштування, щоб переконатися, що вони підходять для вашого випадку користування." + privacy: Приватність + privacy_hint_html: Контролюйте, що ви хочете розкрити для інших. Люди виявляють цікаві профілі та класні застосунки, переглядаючи дописи тих, за ким слідкують інші, але ви можете стежити за ними приховано. + reach: Досяжність + reach_hint_html: Контролюйте, чи хочете, щоб вас знаходили та за вами могли стежити нові люди. Ви хочете, щоб ваші дописи з'явились на головному екрані? Ви хочете, щоб інші люди бачили вас у подальших рекомендаціях? Ви дійсно хочете автозатвердження всіх нових підписників чи погоджувати кожний запис окремо? + search: Пошук + search_hint_html: Контролюйте, свою виявність. Ви хочете, щоб люди знаходили вас за вашими загальнодоступними дописами? Чи хочете, щоб люди поза межами Mastodon знаходили ваш профіль під час пошуку в інтернеті? Не забувайте, що загальнодоступна інформація не гарантує загальне виключення з усіх пошукових систем. + title: Приватність і досяжність privacy_policy: title: Політика конфіденційності reactions: @@ -1450,6 +1593,7 @@ uk: confirm_remove_selected_followers: Ви дійсно бажаєте видалити вибраних підписників? confirm_remove_selected_follows: Ви дійсно хочете вилучити вибрані підписки? dormant: Неактивні + follow_failure: Не вдалося підписатися на деякі вибрані облікові записи. follow_selected_followers: Стежити за вибраними підписниками followers: Підписники following: Підписник @@ -1489,6 +1633,7 @@ uk: electron: Electron firefox: Firefox generic: Невідомий браузер + huawei_browser: Huawei Браузер ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser @@ -1498,6 +1643,7 @@ uk: qq: QQ Browser safari: Сафарі uc_browser: UC Browser + unknown_browser: Невідомий браузер weibo: Weibo current_session: Поточний сеанс description: "%{browser} на %{platform}" @@ -1510,9 +1656,10 @@ uk: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: macOS - other: невідома платформа + unknown_platform: Невідома Платформа windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1537,7 +1684,7 @@ uk: migrate: Міграція облікового запису notifications: Сповіщення preferences: Налаштування - profile: Профіль + profile: Загальнодоступний профіль relationships: Підписки та підписники statuses_cleanup: Автовидалення допису strikes: Попередження модераторів @@ -1595,7 +1742,6 @@ uk: show_newer: Показати новіші show_older: Показати давніші show_thread: Відкрити обговорення - sign_in_to_participate: Увійдіть, щоб брати участь у бесіді title: '%{name}: "%{quote}"' visibilities: direct: Особисто @@ -1637,12 +1783,10 @@ uk: '7889238': 3 місяці min_age_label: Поріг давності min_favs: Залишати дописи в обраному більше ніж - min_favs_hint: Не видаляти ваших дописів, що отримали більше вказаної кількості додавання до закладок. Залиште порожнім, щоб видаляти дописи незалежно від кількості їхнього додавання до обраних + min_favs_hint: Не видаляти ваших дописів, що були поширені більш ніж вказану кількість разів. Залиште порожнім, щоб видаляти дописи, попри кількість їхніх поширень min_reblogs: Залишати дописи, поширені більше ніж min_reblogs_hint: Не видаляти ваших дописів, що були поширені більш ніж вказану кількість разів. Залиште порожнім, щоб видаляти дописи, попри кількість їхніх поширень stream_entries: - pinned: Закріплений допис - reblogged: поширив sensitive_content: Дражливий зміст strikes: errors: @@ -1658,6 +1802,11 @@ uk: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Перевищено квоту використання на весь сервер для служби перекладу. + too_many_requests: Останнім часом було забагато запитів на переклад до служби перекладу. two_factor_authentication: add: Додати disable: Вимкнути @@ -1737,13 +1886,18 @@ uk: title: Ласкаво просимо, %{name}! users: follow_limit_reached: Не можна слідкувати більш ніж за %{limit} людей + go_to_sso_account_settings: Перейдіть до налаштувань облікового запису постачальника ідентифікації invalid_otp_token: Введено неправильний код otp_lost_help_html: Якщо ви втратили доступ до обох, ви можете отримати доступ з %{email} seamless_external_login: Ви увійшли за допомогою зовнішнього сервісу, тому налаштування паролю та електронної пошти недоступні. signed_in_as: 'Ви увійшли як:' verification: - explanation_html: 'Ви можете підтвердити володіння посиланнями в метаданих вашого профілю. Для цього на зазначеному сайті повинне міститися посилання на ваш профіль Mastodon. Посилання повинне мати атрибут rel="me". Текстовий вміст посилання не має значення. Ось приклад:' + extra_instructions_html: Порада: Посилання на ваш сайт може бути невидимим. Важлива частина — це rel="me", яка не запобігає видаванню себе за іншу особу на вебсайтах з користувацьким наповненням. Ви навіть можете використовувати тег link у заголовку сторінки замість a, але HTML має бути доступним без виконання JavaScript. + here_is_how: Ось, як це зробити + hint_html: "Підтвердження особи на Mastodon доступне всім. Базуючись на відкритих вебстандартах, тепер і завжди безплатно. Все, що вам потрібно, — це особистий сайт, на якому вас впізнають. Після пов'язування цього сайту з вашим профілем, ми ще раз перевіримо, чи є на сайті посилання і чи видно візуальний індикатор на ньому." + instructions_html: Скопіюйте та вставте наведений нижче код у HTML-код вашого сайту. Потім додайте адресу свого сайту в одне з додаткових полів вашого профілю на вкладці «Редагувати профіль» і збережіть зміни. verification: Підтвердження + verified_links: Ваші підтверджені посилання webauthn_credentials: add: Додати новий ключ безпеки create: diff --git a/config/locales/ur.yml b/config/locales/ur.yml index a5ae83fd42..2cace5883d 100644 --- a/config/locales/ur.yml +++ b/config/locales/ur.yml @@ -1,10 +1 @@ ---- ur: - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/uz.yml b/config/locales/uz.yml index caed654ec7..403ffd33cf 100644 --- a/config/locales/uz.yml +++ b/config/locales/uz.yml @@ -39,11 +39,3 @@ uz: most_recent_ip: Eng oxirgi IP perform_full_suspension: To'xtatilgan reject: Rad etish - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 3417761099..73222a6047 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -31,7 +31,7 @@ vi: accounts: add_email_domain_block: Chặn tên miền email approve: Phê duyệt - approved_msg: Đã phê duyệt %{username} đăng ký thành công + approved_msg: Đã phê duyệt đăng ký %{username} are_you_sure: Bạn có chắc không? avatar: Ảnh đại diện by_domain: Máy chủ @@ -89,6 +89,7 @@ vi: moderation: active: Hoạt động all: Tất cả + disabled: Đã tắt pending: Chờ silenced: Hạn chế suspended: Vô hiệu hóa @@ -121,8 +122,8 @@ vi: removed_header_msg: Đã xóa bỏ ảnh bìa của %{username} resend_confirmation: already_confirmed: Người này đã được xác minh - send: Gửi lại email xác nhận - success: Email xác nhận đã gửi thành công! + send: Gửi lại email xác minh + success: Xác nhận đã được gửi đi thành công! reset: Đặt lại reset_password: Đặt lại mật khẩu resubscribe: Đăng ký lại @@ -130,6 +131,7 @@ vi: search: Tìm kiếm search_same_email_domain: Tra cứu email search_same_ip: Tra cứu IP + security: Bảo mật security_measures: only_password: Chỉ mật khẩu password_and_2fa: Mật khẩu và 2FA @@ -166,14 +168,14 @@ vi: action_logs: action_types: approve_appeal: Chấp nhận kháng cáo - approve_user: Chấp nhận người dùng + approve_user: Chấp nhận đăng ký assigned_to_self_report: Tự xử lý báo cáo change_email_user: Đổi email - change_role_user: Thay đổi vai trò + change_role_user: Đổi vai trò confirm_user: Xác minh create_account_warning: Cảnh cáo create_announcement: Tạo thông báo mới - create_canonical_email_block: Tạo chặn tên miền email mới + create_canonical_email_block: Tạo chặn tên miền email create_custom_emoji: Tạo emoji create_domain_allow: Cho phép máy chủ create_domain_block: Chặn máy chủ @@ -185,7 +187,7 @@ vi: destroy_announcement: Xóa thông báo destroy_canonical_email_block: Bỏ chặn tên miền email destroy_custom_emoji: Xóa emoji - destroy_domain_allow: Bỏ cho phép máy chủ + destroy_domain_allow: Bỏ thanh trừng máy chủ destroy_domain_block: Bỏ chặn máy chủ destroy_email_domain_block: Bỏ chặn tên miền email destroy_instance: Thanh trừng máy chủ @@ -203,10 +205,10 @@ vi: memorialize_account: Đánh dấu tưởng niệm promote_user: Chỉ định vai trò reject_appeal: Từ chối kháng cáo - reject_user: Từ chối người dùng + reject_user: Từ chối đăng ký remove_avatar_user: Xóa ảnh đại diện reopen_report: Mở lại báo cáo - resend_user: Gửi lại email xác nhận + resend_user: Gửi lại email xác minh reset_password_user: Đặt lại mật khẩu resolve_report: Xử lý báo cáo sensitive_account: Áp đặt nhạy cảm @@ -265,7 +267,7 @@ vi: reject_user_html: "%{name} đã từ chối đăng ký từ %{target}" remove_avatar_user_html: "%{name} đã xóa ảnh đại diện của %{target}" reopen_report_html: "%{name} mở lại báo cáo %{target}" - resend_user_html: "%{name} gửi lại email xác nhận cho %{target}" + resend_user_html: "%{name} gửi lại email xác minh cho %{target}" reset_password_user_html: "%{name} đã đặt lại mật khẩu của %{target}" resolve_report_html: "%{name} đã xử lý báo cáo %{target}" sensitive_account_html: "%{name} đánh dấu nội dung của %{target} là nhạy cảm" @@ -304,6 +306,7 @@ vi: unpublish: Hủy đăng unpublished_msg: Xóa bỏ thông báo thành xong! updated_msg: Cập nhật thông báo thành công! + critical_update_pending: Cập nhật quan trọng đang chờ custom_emojis: assign_category: Xếp vào danh mục by_domain: Máy chủ @@ -341,9 +344,9 @@ vi: dashboard: active_users: người hoạt động interactions: tương tác - media_storage: Dung lượng lưu trữ + media_storage: Media new_users: người mới - opened_reports: tổng báo cáo + opened_reports: báo cáo pending_appeals_html: other: "%{count} kháng cáo đang chờ" pending_reports_html: @@ -355,7 +358,7 @@ vi: resolved_reports: báo cáo đã xử lí software: Phần mềm sources: Nguồn đăng ký - space: Dung lượng lưu trữ + space: Lưu trữ title: Thống kê top_languages: Ngôn ngữ phổ biến top_servers: Máy chủ phổ biến @@ -367,12 +370,21 @@ vi: domain_allows: add_new: Cho phép liên hợp với máy chủ created_msg: Máy chủ đã được kích hoạt liên hợp thành công - destroyed_msg: Máy chủ đã bị ngưng liên hợp + destroyed_msg: Máy chủ đã bị dừng liên hợp export: Xuất import: Nhập undo: Xóa khỏi danh sách trắng domain_blocks: add_new: Chặn máy chủ + confirm_suspension: + cancel: Hủy bỏ + confirm: Vô hiệu hóa + permanent_action: Bỏ vô hiệu hóa sẽ không khôi phục bất kỳ dữ liệu hoặc mối quan hệ nào. + preamble_html: Bạn sắp vô hiệu hóa %{domain} và các tên miền phụ của nó. + remove_all_data: Thao tác này sẽ xóa tất cả nội dung, media và dữ liệu hồ sơ cho các tài khoản của máy chủ này khỏi máy chủ của bạn. + stop_communication: Máy chủ của bạn sẽ ngừng giao tiếp với các máy chủ này. + title: Xác nhận chặn máy chủ %{domain} + undo_relationships: Thao tác này sẽ hoàn tác mọi mối quan hệ theo dõi giữa tài khoản của các máy chủ này và của bạn. created_msg: Đang tiến hành chặn máy chủ destroyed_msg: Đã thôi chặn máy chủ domain: Máy chủ @@ -419,6 +431,7 @@ vi: resolve: Xử lý tên miền title: Chặn tên miền email mới no_email_domain_block_selected: Không có chặn e-mail nào thay đổi vì không có mục nào được chọn + not_permitted: Không cho phép resolved_dns_records_hint_html: Tên miền phân giải thành các tên miền MX sau, các tên miền này chịu trách nhiệm cuối cùng trong việc chấp nhận email. Chặn tên miền MX sẽ chặn đăng ký từ bất kỳ địa chỉ email nào sử dụng cùng một tên miền MX, ngay cả khi tên miền hiển thị là khác. Cẩn thận đừng chặn những dịch vụ email lớn. resolved_through_html: Đã xử lý thông qua %{domain} title: Tên miền email đã chặn @@ -438,7 +451,7 @@ vi: title: Nhập máy chủ chặn no_file: Không có tập tin nào được chọn follow_recommendations: - description_html: "Gợi ý theo dõi là cách giúp những người mới nhanh chóng tìm thấy những nội dung thú vị. Khi một người chưa đủ tương tác với những người khác để hình thành các đề xuất theo dõi được cá nhân hóa, thì những người này sẽ được đề xuất. Nó bao gồm những người có số lượt tương tác gần đây cao nhất và số lượng người theo dõi cao nhất cho một ngôn ngữ nhất định trong máy chủ." + description_html: "Gợi ý theo dõi giúp những người mới nhanh chóng tìm thấy những nội dung thú vị. Khi một người chưa đủ tương tác với những người khác để hình thành các đề xuất theo dõi được cá nhân hóa, thì những người này sẽ được đề xuất. Nó bao gồm những người có số lượt tương tác gần đây cao nhất và số lượng người theo dõi cao nhất cho một ngôn ngữ nhất định trong máy chủ." language: Theo ngôn ngữ status: Trạng thái suppress: Tắt gợi ý theo dõi @@ -463,6 +476,7 @@ vi: content_policies: comment: Lưu ý nội bộ description_html: Bạn có thể xác định các chính sách nội dung sẽ được áp dụng cho tất cả các tài khoản trên máy chủ này và bất kỳ tên miền phụ nào của nó. + limited_federation_mode_description_html: Bạn có thể chọn nếu muốn cho phép liên hợp với máy chủ này. policies: reject_media: Từ chối media reject_reports: Từ chối báo cáo @@ -573,11 +587,13 @@ vi: assign_to_self: Giao cho tôi assigned: Người xử lý by_target_domain: Tên tài khoản bị báo cáo + cancel: Hủy bỏ category: Phân loại category_description_html: Lý do tài khoản hoặc nội dung này bị báo cáo sẽ được trích dẫn khi giao tiếp với họ comment: none: Không có mô tả comment_description_html: "%{name} cho biết thêm:" + confirm: Xác nhận confirm_action: Xác nhận kiểm duyệt với %{acct} created_at: Báo cáo lúc delete_and_resolve: Xóa tút @@ -678,7 +694,7 @@ vi: manage_settings: Quản lý thiết lập manage_settings_description: Cho phép thay đổi thiết lập máy chủ manage_taxonomies: Quản lý phân loại - manage_taxonomies_description: Cho phép đánh giá nội dung thịnh hành và cập nhật cài đặt hashtag + manage_taxonomies_description: Cho phép đánh giá nội dung xu hướng và cập nhật cài đặt hashtag manage_user_access: Quản lý người truy cập manage_user_access_description: Cho phép vô hiệu hóa xác thực hai bước của người khác, thay đổi địa chỉ email và đặt lại mật khẩu của họ manage_users: Quản lý người @@ -711,6 +727,9 @@ vi: branding: preamble: Thương hiệu máy chủ của bạn phân biệt nó với các máy chủ khác trong mạng. Thông tin này có thể được hiển thị trên nhiều môi trường khác nhau, chẳng hạn như giao diện web của Mastodon, các ứng dụng gốc, trong bản xem trước liên kết trên các trang web khác và trong các ứng dụng nhắn tin, v.v. Vì lý do này, cách tốt nhất là giữ cho thông tin này rõ ràng, ngắn gọn và súc tích. title: Thương hiệu + captcha_enabled: + desc_html: Điều này phụ thuộc vào các mã lệnh bên ngoài từ hCaptcha, đây có thể là mối lo ngại về bảo mật và quyền riêng tư. Thêm vào đó, điều này có thể làm cho quá trình đăng ký khó hơn đối với một số người (đặc biệt là người khuyết tật). Vì những lý do này, vui lòng xem xét các biện pháp thay thế như duyệt đăng ký thủ công hoặc tạo thư mời. + title: Yêu cầu người dùng mới dùng CAPTCHA để xác minh tài khoản của họ content_retention: preamble: Kiểm soát cách lưu trữ nội dung cá nhân trong Mastodon. title: Lưu giữ nội dung @@ -725,7 +744,7 @@ vi: publish_discovered_servers: Công khai các máy chủ được phát hiện publish_statistics: Công khai số liệu thống kê title: Khám phá - trends: Thịnh hành + trends: Xu hướng domain_blocks: all: Tới mọi người disabled: Không ai @@ -738,10 +757,27 @@ vi: approved: Yêu cầu phê duyệt để đăng ký none: Không ai có thể đăng ký open: Bất cứ ai cũng có thể đăng ký + security: + authorized_fetch: Yêu cầu xác thực từ các máy chủ liên hợp + authorized_fetch_hint: Yêu cầu xác thực từ các máy chủ liên hợp cho phép thực thi chặt chẽ hơn việc chặn cấp độ người dùng và cấp độ máy chủ. Tuy nhiên, điều này phải trả giá bằng một hình phạt về hiệu suất, làm giảm phạm vi tiếp cận của các lượt trả lời của bạn và có thể gây ra các vấn đề về khả năng tương thích với một số dịch vụ được liên hợp. Ngoài ra, điều này sẽ không ngăn cản các tác nhân chuyên dụng tìm nạp các tút và tài khoản công khai của bạn. + authorized_fetch_overridden_hint: Hiện tại, bạn không thể thay đổi cài đặt này vì nó bị ghi đè bởi biến môi trường. + federation_authentication: Thực thi xác thực liên hợp title: Cài đặt máy chủ site_uploads: delete: Xóa tập tin đã tải lên destroyed_msg: Đã xóa tập tin tải lên thành công! + software_updates: + critical_update: Quan trọng — vui lòng cập nhật sớm + description: Bạn nên cập nhật Mastodon phiên bản mới nhất để được hưởng lợi từ các bản sửa lỗi và thêm tính năng mới. Hơn nữa, quan trọng là phải cập nhật Mastodon kịp thời để tránh các vấn đề bảo mật. Vì những lý do này, Mastodon sẽ kiểm tra các bản cập nhật 30 phút một lần và sẽ thông báo cho bạn theo tùy chọn thông báo qua email của bạn. + documentation_link: Tìm hiểu thêm + release_notes: Có gì mới? + title: Bản cập nhật mới + type: Loại + types: + major: Bản cập nhật lớn + minor: Bản cập nhật nhỏ + patch: Bản vá - sửa lỗi và dễ dàng áp dụng các thay đổi + version: Phiên bản statuses: account: Tác giả application: Ứng dụng @@ -764,7 +800,7 @@ vi: reblogs: Lượt đăng lại status_changed: Tút đã thay đổi title: Toàn bộ tút - trending: Thịnh hành + trending: Xu hướng visibility: Hiển thị with_media: Có media strikes: @@ -778,9 +814,24 @@ vi: suspend: "%{name} đã vô hiệu hóa %{target}" appeal_approved: Đã khiếu nại appeal_pending: Đang kháng cáo + appeal_rejected: Khiếu nại bị từ chối system_checks: database_schema_check: message_html: Có cơ sở dữ liệu đang chờ xử lý. Xin khởi động nó để ứng dụng có thể hoạt động một cách ổn định nhất + elasticsearch_health_red: + message_html: Cụm Elaticsearch không tốt (trạng thái đỏ), tính năng tìm kiếm không khả dụng + elasticsearch_health_yellow: + message_html: Cụm Elaticsearch không tốt (trạng thái vàng), bạn có thể muốn biết lý do + elasticsearch_index_mismatch: + message_html: Mapping chỉ mục Elaticsearch đã lỗi thời. Hãy chạy tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Xem tài liệu + message_html: Cụm Elaticsearch của bạn có nhiều node nhưng Mastodon không được định cấu hình để sử dụng chúng. + elasticsearch_preset_single_node: + action: Xem tài liệu + message_html: Cụm Elaticsearch của bạn chỉ có một node, ES_PRESET nên đặt thành single_node_cluster. + elasticsearch_reset_chewy: + message_html: Chỉ mục hệ thống Elaticsearch của bạn đã lỗi thời do thay đổi cài đặt. Hãy chạy tootctl search deploy --reset-chewy để cập nhật. elasticsearch_running_check: message_html: Không thể kết nối Elasticsearch. Hãy kiểm tra xem nó có đang chạy, hay tìm kiếm full-text bị tắt elasticsearch_version_check: @@ -791,6 +842,18 @@ vi: message_html: Bạn chưa cập nhật nội quy máy chủ. sidekiq_process_check: message_html: Sidekiq không hoạt động khi truy vấn %{value}. Hãy kiểm tra lại cấu hình Sidekiq + software_version_critical_check: + action: Bản cập nhật mới + message_html: Có bản cập nhật quan trọng của Mastodon, vui lòng cập nhật nhanh nhất có thể. + software_version_patch_check: + action: Bản cập nhật mới + message_html: Có bản cập nhật sửa lỗi Mastodon. + upload_check_privacy_error: + action: Nhấn vào đây để biết thêm thông tin + message_html: "Máy chủ web của bạn bị cấu hình sai. Có nguy cơ ảnh hưởng bảo mật của người dùng." + upload_check_privacy_error_object_storage: + action: Nhấn vào đây để biết thêm thông tin + message_html: "Lưu trữ đối tượng của bạn bị cấu hình sai. Có nguy cơ ảnh hưởng bảo mật của người dùng." tags: review: Phê duyệt updated_msg: Hashtag đã được cập nhật thành công @@ -810,27 +873,28 @@ vi: no_publisher_selected: Không có nguồn đăng nào thay đổi vì không có nguồn đăng nào được chọn shared_by_over_week: other: "%{count} người chia sẻ tuần rồi" - title: Liên kết nổi bật + title: Tin tức nổi bật usage_comparison: Chia sẻ %{today} lần hôm nay, so với %{yesterday} lần hôm qua + not_allowed_to_trend: Không được phép thành xu hướng only_allowed: Chỉ cho phép pending_review: Đang chờ preview_card_providers: - allowed: Liên kết từ nguồn đăng này có thể nổi bật - description_html: Đây là những nguồn mà từ đó các liên kết thường được chia sẻ trên máy chủ của bạn. Các liên kết sẽ không thể thịnh hành trừ khi bạn cho phép nguồn. Sự cho phép (hoặc cấm) của bạn áp dụng luôn cho các tên miền phụ. - rejected: Liên kết từ nguồn đăng không thể nổi bật + allowed: Tin tức từ nguồn này có thể lên xu hướng + description_html: Đây là những nguồn mà từ đó các liên kết thường được chia sẻ trên máy chủ của bạn. Các liên kết sẽ không thể lên xu hướng trừ khi bạn cho phép nguồn. Sự cho phép (hoặc cấm) của bạn áp dụng luôn cho các tên miền phụ. + rejected: Tin tức từ nguồn này không thể lên xu hướng title: Nguồn đăng rejected: Đã cấm statuses: allow: Cho phép tút allow_account: Cho phép người đăng - description_html: Đây là những tút đang được đăng lại và yêu thích rất nhiều trên máy chủ của bạn. Nó có thể giúp người mới và người cũ tìm thấy nhiều người hơn để theo dõi. Không có tút nào được hiển thị công khai cho đến khi bạn cho phép người đăng và người cho phép đề xuất tài khoản của họ cho người khác. Bạn cũng có thể cho phép hoặc từ chối từng tút riêng. + description_html: Đây là những tút đang được chia sẻ và yêu thích rất nhiều trên máy chủ của bạn. Nó có thể giúp người mới và người cũ tìm thấy nhiều người hơn để theo dõi. Không có tút nào được hiển thị công khai cho đến khi bạn cho phép người đăng và người cho phép đề xuất tài khoản của họ cho người khác. Bạn cũng có thể cho phép hoặc từ chối từng tút riêng. disallow: Cấm tút disallow_account: Cấm người đăng - no_status_selected: Không có tút thịnh hành nào thay đổi vì không có tút nào được chọn + no_status_selected: Không có tút xu hướng nào thay đổi vì không có tút nào được chọn not_discoverable: Tác giả đã chọn không tham gia mục khám phá shared_by: other: Được thích và đăng lại %{friendly_count} lần - title: Tút nổi bật + title: Tút xu hướng tags: current_score: Chỉ số gần đây %{score} dashboard: @@ -841,20 +905,20 @@ vi: tag_uses_measure: tổng lượt dùng description_html: Đây là những hashtag đang xuất hiện trong rất nhiều tút trên máy chủ của bạn. Nó có thể giúp mọi người tìm ra những gì đang được quan tâm nhiều nhất vào lúc này. Không có hashtag nào được hiển thị công khai cho đến khi bạn cho phép chúng. listable: Có thể đề xuất - no_tag_selected: Không có hashtag thịnh hành nào thay đổi vì không có hashtag nào được chọn + no_tag_selected: Không có hashtag xu hướng nào thay đổi vì không có hashtag nào được chọn not_listable: Không thể đề xuất - not_trendable: Không cho thịnh hành + not_trendable: Không cho lên xu hướng not_usable: Không được phép dùng peaked_on_and_decaying: Đỉnh điểm %{date}, giờ đang giảm title: Hashtag nổi bật - trendable: Cho phép thịnh hành + trendable: Cho phép lên xu hướng trending_rank: 'Nổi bật #%{rank}' usable: Có thể dùng usage_comparison: Dùng %{today} lần hôm nay, so với %{yesterday} hôm qua used_by_over_week: other: "%{count} người dùng tuần rồi" title: Xu hướng - trending: Thịnh hành + trending: Xu hướng warning_presets: add_new: Thêm mới delete: Xóa bỏ @@ -893,6 +957,9 @@ vi: body: "%{target} đã khiếu nại vì bị %{action_taken_by} %{type} vào %{date}. Họ cho biết:" next_steps: Bạn có thể chấp nhận kháng cáo để hủy kiểm duyệt hoặc bỏ qua. subject: "%{username} đang khiếu nại quyết định kiểm duyệt trên %{instance}" + new_critical_software_updates: + body: Các phiên bản quan trọng mới của Mastodon đã được phát hành, bạn nên cập nhật càng sớm càng tốt! + subject: Các bản cập nhật quan trọng của Mastodon cho %{instance}! new_pending_account: body: Thông tin chi tiết của tài khoản mới ở phía dưới. Bạn có thể phê duyệt hoặc từ chối người này. subject: Tài khoản chờ xét duyệt trên %{instance} (%{username}) @@ -900,10 +967,13 @@ vi: body: "%{reporter} vừa báo cáo %{target}" body_remote: Ai đó từ %{domain} đã báo cáo %{target} subject: "(%{instance}) Báo cáo #%{id}" + new_software_updates: + body: Phiên bản Mastodon mới đã được phát hành, bạn nên cập nhật! + subject: Các bản cập nhật mới của Mastodon cho %{instance}! new_trends: body: 'Các mục sau đây cần được xem xét trước khi chúng hiển thị công khai:' new_trending_links: - title: Liên kết nổi bật + title: Tin tức nổi bật new_trending_statuses: title: Tút nổi bật new_trending_tags: @@ -920,8 +990,8 @@ vi: remove: Bỏ liên kết bí danh appearance: advanced_web_interface: Bố cục - advanced_web_interface_hint: 'Bố cục nhiều cột cho phép bạn chuyển bố cục hiển thị thành nhiều cột khác nhau. Bao gồm: Bảng tin, thông báo, thế giới, cũng như danh sách và hashtag. Thích hợp nếu bạn đang dùng màn hình rộng.' - animations_and_accessibility: Bảng tin + advanced_web_interface_hint: Bố cục nhiều cột cho phép bạn chuyển bố cục hiển thị thành nhiều cột khác nhau. Thích hợp với màn hình rộng. + animations_and_accessibility: Hiệu ứng confirmation_dialogs: Hộp thoại xác nhận discovery: Khám phá localization: @@ -929,24 +999,28 @@ vi: guide_link: https://crowdin.com/project/mastodon guide_link_text: Ai cũng có thể đóng góp. sensitive_content: Nội dung nhạy cảm - toot_layout: Tút application_mailer: notification_preferences: Thay đổi tùy chọn email salutation: "%{name}," settings: 'Thay đổi tùy chọn email: %{link}' + unsubscribe: Hủy đăng ký view: 'Chi tiết:' view_profile: Xem trang hồ sơ view_status: Xem tút applications: - created: Đơn đăng ký được tạo thành công + created: Đã gửi yêu cầu đăng ký destroyed: Đã xóa đơn đăng ký + logout: Đăng xuất regenerate_token: Tạo lại mã truy cập token_regenerated: Mã truy cập được tạo lại thành công warning: Hãy rất cẩn thận với dữ liệu này. Không bao giờ chia sẻ nó với bất cứ ai! your_token: Mã truy cập của bạn auth: apply_for_account: Xin đăng ký - change_password: Mật khẩu + captcha_confirmation: + help_html: Nếu có vấn đề khi nhập CAPTCHA, hãy liên hệ %{email} để được hỗ trợ. + hint_html: Còn một xíu nữa! Chúng tôi cần xác minh bạn là con người (để chúng tôi có thể ngăn chặn thư rác!). Nhập CAPTCHA bên dưới và nhấn "Tiếp tục". + title: Kiểm tra an toàn confirmations: wrong_email_hint: Nếu địa chỉ email đó không chính xác, bạn có thể thay đổi nó trong cài đặt tài khoản. delete_account: Xóa tài khoản @@ -955,7 +1029,7 @@ vi: prefix_invited_by_user: "@%{name} mời bạn tham gia máy chủ Mastodon này!" prefix_sign_up: Tham gia Mastodon ngay hôm nay! suffix: Với tài khoản, bạn sẽ có thể theo dõi mọi người, đăng tút và nhắn tin với người từ bất kỳ máy chủ Mastodon khác! - didnt_get_confirmation: Gửi lại email xác minh? + didnt_get_confirmation: Không nhận được email xác minh? dont_have_your_security_key: Bạn có khóa bảo mật chưa? forgot_password: Quên mật khẩu invalid_reset_password_token: Mã đặt lại mật khẩu không hợp lệ hoặc hết hạn. Vui lòng yêu cầu một cái mới. @@ -968,28 +1042,41 @@ vi: migrate_account_html: Nếu bạn muốn bỏ tài khoản này để dùng một tài khoản khác, bạn có thể thiết lập tại đây. or_log_in_with: Hoặc đăng nhập bằng privacy_policy_agreement_html: Tôi đã đọc và đồng ý chính sách bảo mật + progress: + confirm: Xác minh email + details: Điền thông tin + review: Đợi duyệt + rules: Đọc nội quy providers: cas: CAS saml: SAML register: Đăng ký - registration_closed: "%{instance} tạm ngưng đăng ký mới" + registration_closed: "%{instance} tạm dừng đăng ký mới" resend_confirmation: Gửi lại email xác minh reset_password: Đặt lại mật khẩu rules: + accept: Chấp nhận + back: Quay lại + invited_by: 'Bạn có thể tham gia %{domain} với thư mời từ:' preamble: Được ban hành và áp dụng bởi quản trị máy chủ %{domain}. + preamble_invited: Trước khi tiếp tục, hãy đọc nội quy của %{domain}. title: Nội quy máy chủ. + title_invited: Bạn vừa được mời. security: Bảo mật set_new_password: Đặt mật khẩu mới setup: - email_below_hint_html: Nếu địa chỉ email dưới đây không chính xác, bạn có thể thay đổi địa chỉ tại đây và nhận email xác nhận mới. - email_settings_hint_html: Email xác minh đã được gửi tới %{email}. Nếu địa chỉ email đó không chính xác, bạn có thể thay đổi nó trong cài đặt tài khoản. - title: Thiết lập + email_below_hint_html: Kiểm tra hộp thư rác hoặc yêu cầu gửi lại. Bạn có thể sửa địa chỉ email của mình nếu sai. + email_settings_hint_html: Nhấn vào liên kết chúng tôi vừa gửi để xác minh %{email}. Nhanh nhé bạn. + link_not_received: Không nhận được mã? + new_confirmation_instructions_sent: Bạn sẽ nhận được một email mới với liên kết xác minh sau vài phút! + title: Kiểm tra email của bạn sign_in: - preamble_html: Đăng nhập bằng tài khoản %{domain}. Nếu tài khoản của bạn được lưu trữ trên một máy chủ khác, bạn sẽ không thể đăng nhập tại đây. + preamble_html: Đăng nhập bằng tài khoản %{domain}. Nếu đăng ký trên một máy chủ khác, bạn sẽ không thể đăng nhập tại đây. title: Đăng nhập %{domain} sign_up: - preamble: Với tài khoản trên máy chủ Mastodon này, bạn sẽ có thể theo dõi bất kỳ người nào trên các máy chủ khác, bất kể tài khoản của họ ở đâu. - title: Cho phép bạn đăng ký trên %{domain}. + manual_review: "%{domain} sẽ duyệt đăng ký thủ công. Để giúp chúng tôi duyệt nhanh, hãy viết một chút về bản thân và lý do bạn muốn có một tài khoản trên %{domain}." + preamble: Với tài khoản trên máy chủ Mastodon này, bạn sẽ có thể theo dõi bất kỳ người nào thuộc các máy chủ khác. + title: Đang đăng ký trên %{domain}. status: account_status: Trạng thái tài khoản confirming: Đang chờ xác minh email. @@ -999,18 +1086,6 @@ vi: view_strikes: Xem những lần cảnh cáo cũ too_fast: Nghi vấn đăng ký spam, xin thử lại. use_security_key: Dùng khóa bảo mật - authorize_follow: - already_following: Bạn đang theo dõi người này - already_requested: Bạn vừa gửi một yêu cầu theo dõi tới người này - error: Rất tiếc, đã xảy ra lỗi khi tìm kiếm tài khoản từ nơi khác - follow: Theo dõi - follow_request: Bạn đã gửi yêu cầu theo dõi tới - following: Chúc mừng! Bạn đã trở thành người theo dõi - post_follow: - close: Bạn có thể đóng cửa sổ này rồi. - return: Xem trang hồ sơ - web: Mở trong Mastodon - title: Theo dõi %{acct} challenge: confirm: Tiếp tục hint_html: "Mẹo: Chúng tôi sẽ không hỏi lại mật khẩu của bạn sau này." @@ -1050,7 +1125,7 @@ vi: data_removal: Bài viết của bạn và dữ liệu khác sẽ bị xóa vĩnh viễn email_change_html: Bạn có thể thay đổi địa chỉ email mà không cần phải xóa tài khoản email_contact_html: Nếu vẫn không nhận được, bạn có thể liên hệ %{email} để được giúp đỡ - email_reconfirmation_html: Nếu bạn không nhận được email xác nhận, hãy thử yêu cầu lại + email_reconfirmation_html: Nếu bạn không nhận được email xác minh, hãy thử yêu cầu lại irreversible: Bạn sẽ không thể khôi phục hoặc kích hoạt lại tài khoản của mình more_details_html: Đọc chính sách bảo mật để biết thêm chi tiết. username_available: Tên người dùng của bạn sẽ có thể đăng ký lại @@ -1087,6 +1162,10 @@ vi: your_appeal_rejected: Khiếu nại của bạn bị từ chối domain_validator: invalid_domain: không phải là một tên miền hợp lệ + edit_profile: + basic_information: Thông tin cơ bản + hint_html: "Tùy chỉnh những gì mọi người nhìn thấy trên hồ sơ công khai và bên cạnh tút của bạn. Mọi người sẽ muốn theo dõi và tương tác với bạn hơn nếu bạn có ảnh đại diện và một hồ sơ hoàn chỉnh." + other: Khác errors: '400': Yêu cầu bạn gửi không hợp lệ hoặc sai hình thức. '403': Bạn không có quyền xem trang này. @@ -1124,13 +1203,13 @@ vi: add_new: Thêm mới errors: limit: Bạn đã đạt tới số lượng hashtag tối đa - hint_html: "Hashtag thường dùng là gì? Chúng là những hashtag sẽ được hiển thị nổi bật trên trang hồ sơ của bạn, cho phép mọi người tìm kiếm các bài đăng công khai của bạn có chứa các hashtag đó. Tính năng này có thể dùng để đánh dấu chuỗi tác phẩm sáng tạo hoặc dự án dài hạn." + hint_html: "Làm nổi bật những hashtag thường dùng. Một công cụ tuyệt vời để theo dõi các tác phẩm sáng tạo và dự án dài hạn của bạn, các hashtag thường dùng sẽ hiển thị nổi bật trên hồ sơ của bạn và cho phép truy cập nhanh vào các tút." filters: contexts: account: Trang hồ sơ - home: Bảng tin + home: Trang chính và danh sách notifications: Thông báo - public: Tin công khai + public: Tút công khai thread: Thảo luận edit: add_keyword: Thêm từ khoá @@ -1164,44 +1243,82 @@ vi: index: hint: Bộ lọc này áp dụng để chọn các tút riêng lẻ bất kể các tiêu chí khác. Bạn có thể thêm các tút khác vào bộ lọc này từ giao diện web. title: Những tút đã lọc - footer: - trending_now: Thịnh hành generic: all: Tất cả all_items_on_page_selected_html: other: Toàn bộ %{count} mục trong trang này đã được chọn. all_matching_items_selected_html: other: Toàn bộ %{count} mục trùng khớp với tìm kiếm đã được chọn. + cancel: Hủy bỏ changes_saved_msg: Đã lưu thay đổi! + confirm: Xác nhận copy: Sao chép delete: Xóa deselect: Bỏ chọn tất cả none: Trống - order_by: Sắp xếp + order_by: Xếp theo save_changes: Lưu thay đổi select_all_matching_items: other: Chọn tất cả%{count} mục trùng hợp với tìm kiếm của bạn. today: hôm nay validation_errors: other: Đã có %{count} lỗi xảy ra! Xem chi tiết bên dưới - html_validator: - invalid_markup: 'chứa đánh dấu HTML không hợp lệ: %{error}' imports: errors: + empty: File CSV trống + incompatible_type: Không tương thích với loại nhập đã chọn invalid_csv_file: 'Tập tin CSV không hợp lệ. Lỗi: %{error}' over_rows_processing_limit: chứa nhiều hơn %{count} hàng + too_large: Tập tin quá lớn + failures: Thất bại + imported: Đã nhập + mismatched_types_warning: Có vẻ như bạn đã chọn sai loại cho lần nhập này, vui lòng kiểm tra lại. modes: merge: Hợp nhất merge_long: Giữ hồ sơ hiện có và thêm hồ sơ mới overwrite: Ghi đè overwrite_long: Thay thế các bản ghi hiện tại bằng những cái mới - preface: Bạn có thể nhập dữ liệu mà bạn đã xuất từ một máy chủ khác, chẳng hạn như danh sách những người bạn đang theo dõi hoặc chặn. + overwrite_preambles: + blocking_html: Bạn sắp thay thế danh sách chặn với %{total_items} tài khoản từ %{filename}. + bookmarks_html: Bạn sắp thay thế lượt lưu với %{total_items} tút từ %{filename}. + domain_blocking_html: Bạn sắp thay thế danh sách máy chủ chặn với %{total_items} máy chủ từ %{filename}. + following_html: Bạn sắp theo dõi với %{total_items} người từ %{filename}ngừng theo dõi bất kỳ ai. + lists_html: Bạn sắp thay thế các danh sách bằng nội dung từ %{filename}. Hơn %{total_items} tài khoản sẽ được thêm vào những danh sách mới. + muting_html: Bạn sắp thay thế danh sách ẩn với %{total_items} người từ %{filename}. + preambles: + blocking_html: Bạn sắp chặn tới %{total_items} người từ %{filename}. + bookmarks_html: Bạn sắp thêm vào %{total_items} tút từ %{filename} vào lượt lưu. + domain_blocking_html: Bạn sắp chặn tới %{total_items} máy chủ từ %{filename}. + following_html: Bạn sắp theo dõi tới %{total_items} người từ %{filename}. + lists_html: Bạn sắp thêm %{total_items} tài khoản từ %{filename} vào danh sách của bạn. Những danh sách mới sẽ được tạo nếu bạn chưa có danh sách nào. + muting_html: Bạn sắp ẩn lên tới %{total_items} người từ %{filename}. + preface: Bạn có thể nhập dữ liệu mà bạn đã xuất từ một máy chủ khác, chẳng hạn danh sách những người đang theo dõi hoặc chặn. + recent_imports: Đã nhập gần đây + states: + finished: Đã hoàn thành + in_progress: Đang xử lý + scheduled: Đã xếp lịch + unconfirmed: Chưa xác nhận + status: Trạng thái success: Dữ liệu của bạn đã được tải lên thành công và hiện đang xử lý + time_started: Bắt đầu lúc + titles: + blocking: Đang nhập tài khoản đã chặn + bookmarks: Đang nhập lượt lưu + domain_blocking: Đang nhập máy chủ đã chặn + following: Đang nhập người theo dõi + lists: Nhập danh sách + muting: Đang nhập người đã ẩn + type: Kiểu nhập + type_groups: + constructive: Lượt theo dõi và những thứ đã lưu + destructive: Lượt chặn và ẩn types: blocking: Danh sách chặn bookmarks: Tút đã lưu domain_blocking: Danh sách máy chủ đã chặn following: Danh sách người theo dõi + lists: Danh sách muting: Danh sách người đã ẩn upload: Tải lên invites: @@ -1239,6 +1356,21 @@ vi: failed_sign_in_html: Đăng nhập thất bại bằng %{method} từ %{ip} (%{browser}) successful_sign_in_html: Đăng nhập thành công bằng %{method} từ %{ip} (%{browser}) title: Lịch sử đăng nhập + mail_subscriptions: + unsubscribe: + action: Đúng, hủy đăng ký + complete: Đã hủy đăng ký + confirmation_html: Bạn có có chắc muốn hủy đăng ký %{type} Mastodon trên %{domain} cho %{email}? Bạn có thể đăng ký lại từ cài đặt thông báo email. + emails: + notification_emails: + favourite: email thông báo lượt thích + follow: email thông báo theo dõi + follow_request: email thông báo yêu cầu theo dõi + mention: email thông báo lượt nhắc đến + reblog: email thông báo lượt đăng lại + resubscribe_html: Nếu đổi ý, bạn có thể đăng ký lại từ cài đặt thông báo email. + success_html: Bạn sẽ không còn nhận %{type} Mastodon trên %{domain} cho %{email}. + title: Hủy đăng ký media_attachments: validations: images_and_video: Không thể đính kèm video vào tút đã chứa hình ảnh @@ -1318,9 +1450,10 @@ vi: update: subject: "%{name} đã sửa một tút" notifications: + administration_emails: Email thông báo admin email_events: Email email_events_hint: 'Chọn những hoạt động sẽ gửi thông báo qua email:' - other_settings: Thông báo khác + other_settings: Chặn thông báo từ number: human: decimal_units: @@ -1333,7 +1466,7 @@ vi: trillion: T otp_authentication: code_hint: Nhập mã được tạo bởi ứng dụng xác minh của bạn để xác nhận - description_html: Nếu kích hoạt xác minh 2 bước thông qua ứng dụng, bạn sẽ đăng nhập bằng mã token được tạo bởi chính điện thoại của bạn. + description_html: Bạn sẽ đăng nhập bằng mã token được tạo ra bởi điện thoại của bạn. enable: Kích hoạt instructions_html: "Quét mã QR bằng Google Authenticator hoặc một ứng dụng TOTP tương tự trên điện thoại của bạn. Kể từ bây giờ, ứng dụng đó sẽ tạo những token để bạn đăng nhập." manual_instructions: 'Nếu bạn không thể quét mã QR, đây sẽ là dòng chữ gợi ý:' @@ -1354,12 +1487,22 @@ vi: expired: Cuộc bình chọn đã kết thúc invalid_choice: Lựa chọn không tồn tại over_character_limit: độ dài tối đa %{max} ký tự + self_vote: Bạn không thể bình chọn cho tút của chính bạn too_few_options: phải có nhiều hơn một mục too_many_options: tối đa %{max} lựa chọn preferences: other: Khác posting_defaults: Mặc định cho tút public_timelines: Bảng tin + privacy: + hint_html: "Tùy chỉnh cách mọi người tìm thấy hồ sơ và các tút của bạn. Nhiều tính năng trong Mastodon có thể giúp bạn tiếp cận nhiều đối tượng hơn khi được bật. Hãy xem lại các cài đặt này để đảm bảo chúng phù hợp với bạn." + privacy: Riêng tư + privacy_hint_html: Kiểm soát mức độ chi tiết bạn muốn tiết lộ. Mọi người khám phá các hồ sơ thú vị và các ứng dụng thú vị bằng cách theo dõi những người khác và xem họ đăng từ ứng dụng nào, nhưng có thể bạn muốn ẩn nó đi. + reach: Tiếp cận + reach_hint_html: Kiểm soát cách bạn được khám phá và theo dõi. Bạn có muốn tút của mình xuất hiện trên màn hình Khám phá không? Bạn có muốn người khác nhìn thấy bạn trong các đề xuất theo dõi của họ không? Bạn muốn tự động chấp nhận tất cả những người theo dõi mới hay tự duyệt từng người theo dõi? + search: Tìm kiếm + search_hint_html: Kiểm soát cách tìm thấy bạn. Bạn có muốn mọi người tìm thấy bạn bằng những gì bạn đã đăng công khai không? Bạn có muốn những người bên ngoài Mastodon tìm thấy hồ sơ của bạn khi tìm kiếm trên web không? Xin lưu ý rằng không thể đảm bảo loại trừ hoàn toàn khỏi tất cả các công cụ tìm kiếm đối với thông tin công khai. + title: Riêng tư và tiếp cận privacy_policy: title: Chính sách bảo mật reactions: @@ -1370,22 +1513,23 @@ vi: activity: Tương tác confirm_follow_selected_followers: Bạn có chắc muốn theo dõi những người đã chọn? confirm_remove_selected_followers: Bạn có chắc muốn bỏ theo dõi những người đã chọn? - confirm_remove_selected_follows: Bạn có chắc muốn xoá những người theo dõi bạn đã chọn không? + confirm_remove_selected_follows: Bạn có chắc muốn xóa những người theo dõi bạn đã chọn không? dormant: Chưa + follow_failure: Không thể theo dõi một số tài khoản đã chọn. follow_selected_followers: Theo dõi những người đã chọn followers: Người theo dõi following: Đang theo dõi invited: Đã mời last_active: Hoạt động lần cuối most_recent: Mới nhất - moved: Đã xóa + moved: Đã chuyển mutual: Đồng thời - primary: Hoạt động + primary: Còn relationship: Quan hệ remove_selected_domains: Xóa hết người theo dõi từ các máy chủ đã chọn remove_selected_followers: Xóa những người theo dõi đã chọn - remove_selected_follows: Ngưng theo dõi những người đã chọn - status: Trạng thái của họ + remove_selected_follows: Bỏ theo dõi những người đã chọn + status: Trạng thái remote_follow: missing_resource: Không tìm thấy URL chuyển hướng cho tài khoản của bạn reports: @@ -1402,7 +1546,7 @@ vi: too_soon: Ngày lên lịch phải trong tương lai sessions: activity: Gần đây nhất - browser: Trình duyệt + browser: Ứng dụng browsers: alipay: Alipay blackberry: BlackBerry @@ -1410,7 +1554,8 @@ vi: edge: Edge electron: Electron firefox: Firefox - generic: Trình duyệt khác + generic: Chưa rõ + huawei_browser: Huawei Browser ie: Internet Explorer micro_messenger: MicroMes hành khách nokia: Trình duyệt Nokia S40 Ovi @@ -1420,10 +1565,11 @@ vi: qq: QQ safari: Safari uc_browser: UC Browser + unknown_browser: Trình duyệt khác weibo: Weibo current_session: Phiên hiện tại description: "%{browser} trên %{platform}" - explanation: Đây là các trình duyệt web đã từng đăng nhập vào tài khoản Mastodon của bạn. + explanation: Đây là các ứng dụng đã từng đăng nhập vào tài khoản Mastodon của bạn. ip: IP platforms: adobe_air: Adobe Air @@ -1432,9 +1578,10 @@ vi: chrome_os: ChromeOS firefox_os: Hệ điều hành Firefox ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: nền tảng khác + unknown_platform: Nền tảng khác windows: Windows windows_mobile: Windows Mobile windows_phone: Điện thoại Windows @@ -1498,8 +1645,7 @@ vi: show_more: Đọc thêm show_newer: Mới hơn show_older: Cũ hơn - show_thread: Trích nguyên văn - sign_in_to_participate: Đăng nhập để trả lời tút này + show_thread: Nội dung gốc title: '%{name}: "%{quote}"' visibilities: direct: Nhắn riêng @@ -1545,8 +1691,6 @@ vi: min_reblogs: Giữ những tút đã đăng lại lâu hơn min_reblogs_hint: Những tút có lượt đăng lại nhiều hơn số này sẽ không bị xóa. Để trống nếu bạn muốn xóa hết stream_entries: - pinned: Tút đã ghim - reblogged: đăng lại sensitive_content: NSFW strikes: errors: @@ -1554,7 +1698,7 @@ vi: tags: does_not_match_previous_name: không khớp với tên trước themes: - contrast: Mastodon (Độ tương phản cao) + contrast: Mastodon (Tương phản) default: Mastodon (Tối) mastodon-light: Mastodon (Sáng) time: @@ -1562,6 +1706,11 @@ vi: default: "%-d.%m.%Y %H:%M" month: "%B %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: Đã vượt quá hạn ngạch sử dụng trên toàn máy chủ cho dịch vụ dịch thuật. + too_many_requests: Gần đây có quá nhiều yêu cầu dịch vụ dịch thuật. two_factor_authentication: add: Thêm disable: Vô hiệu hóa @@ -1641,13 +1790,18 @@ vi: title: Xin chào %{name}! users: follow_limit_reached: Bạn chỉ có thể theo dõi tối đa %{limit} người + go_to_sso_account_settings: Thiết lập tài khoản nhà cung cấp danh tính invalid_otp_token: Mã xác minh 2 bước không hợp lệ otp_lost_help_html: Nếu bạn mất quyền truy cập vào cả hai, bạn có thể đăng nhập bằng %{email} seamless_external_login: Bạn đã đăng nhập thông qua một dịch vụ bên ngoài, vì vậy mật khẩu và email không khả dụng. - signed_in_as: 'Đăng nhập với tư cách là:' + signed_in_as: 'Đăng nhập bằng:' verification: - explanation_html: 'Bạn có thể xác minh mình là chủ sở hữu của các trang web ở đầu trang hồ sơ của bạn. Để xác minh, trang web phải chèn mã rel="me". Văn bản thay thế cho liên kết không quan trọng. Đây là một ví dụ:' + extra_instructions_html: Mẹo: Liên kết trên trang web của bạn có thể ẩn. Phần quan trọng là rel="me" ngăn chặn việc mạo danh trên các trang web có nội dung do người dùng tạo. Bạn thậm chí có thể sử dụng một thẻ link trên header của trang thay vì a, nhưng HTML phải có thể truy cập được mà không cần thực thi JavaScript. + here_is_how: Cách thực hiện + hint_html: "Xác minh danh tính trên Mastodon là dành cho tất cả mọi người. Dựa trên các tiêu chuẩn web mở, miễn phí bây giờ và mãi mãi. Tất cả những gì bạn cần là một trang web cá nhân để mọi người nhận ra bạn. Khi bạn liên kết đến trang web này từ hồ sơ của mình, chúng tôi sẽ kiểm tra xem trang web đó có liên kết lại với hồ sơ của bạn hay không và hiển thị một chỉ báo trực quan trên đó." + instructions_html: Sao chép và dán mã bên dưới vào mã nguồn trang web của bạn. Sau đó, thêm địa chỉ trang web của bạn vào một trong các trường metadata trên hồ sơ của bạn từ tab "Sửa hồ sơ" và lưu thay đổi. verification: Xác minh + verified_links: Những liên kết bạn đã xác minh webauthn_credentials: add: Thêm khóa bảo mật mới create: diff --git a/config/locales/zgh.yml b/config/locales/zgh.yml index 4750a6cee5..1db573369a 100644 --- a/config/locales/zgh.yml +++ b/config/locales/zgh.yml @@ -48,7 +48,6 @@ zgh: ip_blocks: delete: ⴽⴽⵙ expires_in: - '1209600': 2 weeks '15778476': 6 ⵡⴰⵢⵢⵓⵔⵏ '2629746': ⴰⵢⵢⵓⵔ '31556952': ⴰⵙⴳⴳⵯⴰⵙ @@ -70,7 +69,6 @@ zgh: application_mailer: view_profile: ⵙⴽⵏ ⵉⴼⵔⵙ auth: - change_password: ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ forgot_password: ⵜⴻⵜⵜⵓⴷ ⵜⴰⴳⵓⵔⵉ ⵏ ⵓⵣⵔⴰⵢ ⵏⵏⴽ? login: ⴽⵛⵎ logout: ⴼⴼⵖ @@ -78,19 +76,8 @@ zgh: register: ⵣⵎⵎⴻⵎ status: account_status: ⴰⴷⴷⴰⴷ ⵏ ⵓⵎⵉⴹⴰⵏ - authorize_follow: - follow: ⴹⴼⵕ - title: ⴹⴼⵕ %{acct} deletes: proceed: ⴽⴽⵙ ⴰⵎⵉⴹⴰⵏ - errors: - '400': The request you submitted was invalid or malformed. - '403': You don't have permission to view this page. - '404': The page you are looking for isn't here. - '406': This page is not available in the requested format. - '410': The page you were looking for doesn't exist here anymore. - '429': Too many requests - '503': The page could not be served due to a temporary server failure. exports: archive_takeout: date: ⴰⵣⵎⵣ diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 78b0f5d133..51baaf7a4e 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -4,7 +4,7 @@ zh-CN: about_mastodon_html: 来自未来的社交网络:无广告、无监视、去中心化、合乎道德!使用 Mastodon 夺回你的数据! contact_missing: 未设定 contact_unavailable: 未公开 - hosted_on: 运行在 %{domain} 上的 Mastodon 站点 + hosted_on: 运行在 %{domain} 上的 Mastodon 实例 title: 关于本站 accounts: follow: 关注 @@ -25,8 +25,8 @@ zh-CN: action: 执行操作 title: 在 %{acct} 上执行管理操作 account_moderation_notes: - create: 新增记录 - created_msg: 管理记录已创建! + create: 新建记录 + created_msg: 管理记录创建成功! destroyed_msg: 管理记录删除成功! accounts: add_email_domain_block: 封禁电子邮箱域名 @@ -41,7 +41,7 @@ zh-CN: label: 更改电子邮箱 new_email: 新的电子邮箱 submit: 更改电子邮件地址 - title: 为 %{username} 更改电子邮箱 + title: 更改 %{username} 的电子邮箱 change_role: changed_msg: 已成功更改角色! label: 更改角色 @@ -57,12 +57,12 @@ zh-CN: destroyed_msg: "%{username} 的数据已被安排至删除队列" disable: 冻结 disable_sign_in_token_auth: 禁用电子邮件令牌认证 - disable_two_factor_authentication: 停用双重认证 + disable_two_factor_authentication: 停用双因素认证 disabled: 已冻结 display_name: 昵称 domain: 域名 edit: 编辑 - email: 电子邮件地址 + email: 电子邮箱地址 email_status: 电子邮件地址状态 enable: 解冻 enable_sign_in_token_auth: 启用电子邮件令牌认证 @@ -89,11 +89,12 @@ zh-CN: moderation: active: 活跃 all: 全部 + disabled: 已禁用 pending: 待审核 silenced: 受限 suspended: 已封禁 title: 管理 - moderation_notes: 管理员备注 + moderation_notes: 管理记录 most_recent_activity: 最后一次活跃的时间 most_recent_ip: 最后一次活跃的 IP 地址 no_account_selected: 因为没有选中任何账号,所以没有更改 @@ -121,8 +122,8 @@ zh-CN: removed_header_msg: 成功删除了 %{username} 的横幅图片 resend_confirmation: already_confirmed: 该用户已被确认 - send: 重发确认邮件 - success: 确认邮件发送成功! + send: 重新发送确认链接 + success: 确认链接发送成功! reset: 重置 reset_password: 重置密码 resubscribe: 重新订阅 @@ -130,9 +131,10 @@ zh-CN: search: 搜索 search_same_email_domain: 其他具有相同电子邮箱域名的用户 search_same_ip: 具有相同IP的其他用户 + security: 安全性 security_measures: only_password: 仅密码 - password_and_2fa: 密码和双重认证 + password_and_2fa: 密码和双因素认证 sensitive: 敏感内容 sensitized: 已标记为敏感内容 shared_inbox_url: 公用收件箱(Shared Inbox)URL @@ -193,7 +195,7 @@ zh-CN: destroy_status: 删除嘟文 destroy_unavailable_domain: 删除不可用域名 destroy_user_role: 销毁角色 - disable_2fa_user: 停用双重认证 + disable_2fa_user: 停用双因素认证 disable_custom_emoji: 禁用自定义表情符号 disable_sign_in_token_auth_user: 为用户禁用电子邮件令牌认证 disable_user: 禁用用户 @@ -252,7 +254,7 @@ zh-CN: destroy_status_html: "%{name} 删除了 %{target} 的嘟文" destroy_unavailable_domain_html: "%{name} 恢复了向域名 %{target} 的投递" destroy_user_role_html: "%{name} 删除了 %{target} 角色" - disable_2fa_user_html: "%{name} 停用了用户 %{target} 的双重认证" + disable_2fa_user_html: "%{name} 停用了用户 %{target} 的双因素认证" disable_custom_emoji_html: "%{name} 停用了自定义表情 %{target}" disable_sign_in_token_auth_user_html: "%{name} 已为 %{target} 禁用电子邮件令牌认证" disable_user_html: "%{name} 将用户 %{target} 设置为禁止登录" @@ -304,13 +306,14 @@ zh-CN: unpublish: 取消发布 unpublished_msg: 公告已取消发布! updated_msg: 公告已成功更新! + critical_update_pending: 紧急更新待处理 custom_emojis: - assign_category: 指定分类 + assign_category: 指定类别 by_domain: 域名 copied_msg: 已成功将表情复制到本站 copy: 复制 copy_failed_msg: 无法将表情复制到本站 - create_new_category: 新建分类 + create_new_category: 新建类别 created_msg: 表情添加成功! delete: 删除 destroyed_msg: 表情删除成功! @@ -352,7 +355,7 @@ zh-CN: other: "%{count} 个待处理话题标签" pending_users_html: other: "%{count} 个待处理用户" - resolved_reports: 已解决的举报 + resolved_reports: 已处理的举报 software: 软件 sources: 注册来源 space: 存储使用情况 @@ -373,6 +376,15 @@ zh-CN: undo: 不允许和该域名跨站交互 domain_blocks: add_new: 添加新屏蔽域名 + confirm_suspension: + cancel: 取消 + confirm: 封禁 + permanent_action: 撤销暂停不会恢复任何数据或关系。 + preamble_html: 您将要暂停 %{domain} 及其子域。 + remove_all_data: 这将从您的实例上删除此域名下账户的所有内容、媒体和个人资料数据。 + stop_communication: 您的实例将停止与这些实例的通信。 + title: 确认对 %{domain} 的封锁 + undo_relationships: 这将解除你的实例与这些实例上账户之间的任何关注。 created_msg: 正在进行域名屏蔽 destroyed_msg: 域名屏蔽已撤销 domain: 域名 @@ -419,6 +431,7 @@ zh-CN: resolve: 解析域名 title: 添加电子邮件域名屏蔽 no_email_domain_block_selected: 没有任何项目被选中,因此未能更改电子邮件域名屏蔽列表 + not_permitted: 未允许 resolved_dns_records_hint_html: 该域名解析的 MX 记录所指向的域名如下,这些域名被用于接收电子邮件。 即使电子邮件地址域名与 MX 域名不同,屏蔽一个 MX 域名意味着阻止任何使用相同 MX 域名的电子邮件地址注册本站账户。 请小心不要误屏蔽主要的电子邮件提供商。 resolved_through_html: 通过 %{domain} 解析 title: 电子邮件域名屏蔽 @@ -463,6 +476,7 @@ zh-CN: content_policies: comment: 内部备注 description_html: 你可以设置应用于此域名所有账号和其所有子域名的内容策略。 + limited_federation_mode_description_html: 您可以选择是否允许与该联邦联合。 policies: reject_media: 拒收媒体 reject_reports: 拒收举报 @@ -573,19 +587,21 @@ zh-CN: assign_to_self: 接管 assigned: 已接管的监察员 by_target_domain: 被举报账户的域名 + cancel: 取消 category: 类别 category_description_html: 在与被举报账户的通信时,将引用该账号和/或内容被举报的原因 comment: none: 没有 comment_description_html: "%{name} 补充道:" + confirm: 确认 confirm_action: 确认对 @%{acct} 的管理操作 created_at: 举报时间 delete_and_resolve: 删除嘟文 forwarded: 已转发 forwarded_to: 转发举报至 %{domain} - mark_as_resolved: 标记为“已处理” + mark_as_resolved: 标记为已处理 mark_as_sensitive: 标记为敏感内容 - mark_as_unresolved: 标记为“未处理” + mark_as_unresolved: 标记为未处理 no_one_assigned: 未分派 notes: create: 添加记录 @@ -610,13 +626,13 @@ zh-CN: statuses_description_html: 在与该账号的通信中将引用违规内容 summary: action_preambles: - delete_html: 您即将删除 @%{acct} 的一些帖子。 这将: + delete_html: 您即将删除 @%{acct} 的一些嘟文。 这将: mark_as_sensitive_html: 您即将 标记 @%{acct} 的帖一些子为 敏感。这将: silence_html: 您即将限制 @%{acct} 的帐户。 这将: suspend_html: 您即将暂停 @%{acct} 的帐户。 这将: actions: - delete_html: 删除违规帖子 - mark_as_sensitive_html: 将违规帖子的媒体标记为敏感 + delete_html: 删除违规嘟文 + mark_as_sensitive_html: 将违规嘟文的媒体标记为敏感 silence_html: 严格限制 @%{acct} 的影响力,方法是让他们的个人资料和内容仅对已经关注他们的人可见,或手动查找其个人资料时 suspend_html: 暂停 @%{acct},使他们的个人资料和内容无法访问,也无法与之互动 close_report: '将报告 #%{id} 标记为已解决' @@ -680,7 +696,7 @@ zh-CN: manage_taxonomies: 管理分类 manage_taxonomies_description: 允许用户查看热门内容并更新标签设置 manage_user_access: 管理访问 - manage_user_access_description: 允许用户禁用其他用户的双重身份验证, 更改他们的电子邮件地址, 并重置他们的密码 + manage_user_access_description: 允许用户禁用其他用户的双因素认证、更改他们的电子邮件地址,以及重置他们的密码 manage_users: 管理用户 manage_users_description: 允许用户查看其他用户的信息并执行管理操作 manage_webhooks: 管理 Webhooks @@ -711,6 +727,9 @@ zh-CN: branding: preamble: 你的服务器与网络中其他服务器的招牌区别。此信息将可能在多种环境下显示,包括 Mastodon 网页界面、原生应用和其他网站的链接预览等。因此应尽量简明扼要。 title: 招牌 + captcha_enabled: + desc_html: 这依赖于来自hCaptcha的外部脚本,可能会带来安全和隐私问题。此外,这可能使注册过程对某些人(尤其是残疾人)的注册简易程度大幅下降。出于这些原因,请考虑采取其他措施,如基于批准或邀请的注册方式。 + title: 要求新用户输入验证码以确认他们的账户 content_retention: preamble: 控制用户生成的内容在 Mastodon 中如何存储。 title: 内容保留 @@ -738,10 +757,27 @@ zh-CN: approved: 注册时需要批准 none: 关闭注册 open: 开放注册 + security: + authorized_fetch: 需要跨站认证 + authorized_fetch_hint: 要求外站请求通过验证能够使用户级别与服务器级别的封锁更为严格。然而,这将带来额外的性能负担、减少回复触达范围、并可能导致与一些联邦宇宙服务的兼容性问题。此外,这并不能阻止他人针对性地获取公开嘟文与账户。 + authorized_fetch_overridden_hint: 由于此设置被环境变量覆盖,目前无法更改。 + federation_authentication: 强制跨站认证 title: 服务器设置 site_uploads: delete: 删除已上传的文件 destroyed_msg: 站点上传的文件已经成功删除! + software_updates: + critical_update: 紧急 — 请尽快更新 + description: 建议您及时更新Mastodon实例,以便获得最新修复和功能。此外,为避免安全问题,有时候及时更新Mastodon是至关重要的。出于这些原因,Mastodon每30分钟检查一次更新,并根据您的电子邮件通知偏好向您发送通知。 + documentation_link: 了解详情 + release_notes: 更新日志 + title: 可用的更新 + type: 类型 + types: + major: 大版本更新 + minor: 小版本更新 + patch: 补丁级更新 - 修复了错误并进行了易于应用的更改 + version: 版本 statuses: account: 作者 application: 应用 @@ -778,9 +814,24 @@ zh-CN: suspend: "%{name} 封禁了用户 %{target}" appeal_approved: 已申诉 appeal_pending: 申诉待处理 + appeal_rejected: 申诉已驳回 system_checks: database_schema_check: message_html: 有待处理的数据库迁移。请运行它们以确保应用程序正常运行。 + elasticsearch_health_red: + message_html: Elasticsearch 集群状态不健康(红色),搜索功能不可用 + elasticsearch_health_yellow: + message_html: Elasticsearch 集群不健康(黄色状态),您可能想要调查原因 + elasticsearch_index_mismatch: + message_html: Elasticsearch索引映射已过时。请运行tootctl search deploy --only=%{value}。 + elasticsearch_preset: + action: 查看文档 + message_html: 您的Elasticsearch集群有多个节点,但Mastodon未配置好使用它们。 + elasticsearch_preset_single_node: + action: 查看文档 + message_html: 您的Elasticsearch集群只有一个节点,ES_PRESET应该设置为single_node_cluster。 + elasticsearch_reset_chewy: + message_html: 您的Elasticsearch系统索引已过时,可能是由于设置更改导致的。请运行tootctl search deploy --reset-chewy命令来更新它。 elasticsearch_running_check: message_html: 无法连接到 Elasticsearch。请检查它是否正在运行,或禁用全文搜索 elasticsearch_version_check: @@ -791,6 +842,18 @@ zh-CN: message_html: 你没有定义任何服务器规则。 sidekiq_process_check: message_html: "%{value} 队列未运行任何 Sidekiq 进程。请检查你的 Sidekiq 配置" + software_version_critical_check: + action: 查看可用更新 + message_html: 有一个紧急Mastodon紧急更新可用,请尽快更新。 + software_version_patch_check: + action: 查看可用更新 + message_html: 有一个Mastodon错误修复更新可用。 + upload_check_privacy_error: + action: 点击这里查看更多信息 + message_html: "您的网站服务器配置错误,您用户的隐私处于危险中。" + upload_check_privacy_error_object_storage: + action: 点击这里查看更多信息 + message_html: "您的对象存储空间配置错误,您用户的隐私处于危险中。" tags: review: 审核状态 updated_msg: 话题标签设置更新成功 @@ -812,6 +875,7 @@ zh-CN: other: 过去一周内被 %{count} 个人分享过 title: 热门链接 usage_comparison: 今日被分享 %{today} 次,前一日为 %{yesterday} 次 + not_allowed_to_trend: 不允许的趋势 only_allowed: 仅显示已允许的内容 pending_review: 待审核 preview_card_providers: @@ -893,6 +957,9 @@ zh-CN: body: "%{target} 对 %{action_taken_by} 于 %{date} 做出的 %{type} 审核结果提出申诉,写道:" next_steps: 你可以批准此申诉并撤销该审核结果,也可以忽略此申诉。 subject: "%{username} 对 %{instance} 的审核结果提出了申诉" + new_critical_software_updates: + body: 新的紧急更新版本Mastodon已经发布,您可能希望尽快更新! + subject: 适用于 %{instance} 的Mastodon紧急更新已经可用。 new_pending_account: body: 新账户的详细信息如下。你可以批准或拒绝此申请。 subject: 在 %{instance} 上有新账号 (%{username}) 需要审核 @@ -900,6 +967,9 @@ zh-CN: body: "%{reporter} 举报了用户 %{target}" body_remote: 来自 %{domain} 的用户举报了用户 %{target} subject: 来自 %{instance} 的用户举报(#%{id}) + new_software_updates: + body: 新的 Mastodon 版本已发布,您可能想要更新! + subject: 适用于 %{instance} 的Mastodon版本更新已经可用! new_trends: body: 以下项目需要审核才能公开显示: new_trending_links: @@ -929,24 +999,28 @@ zh-CN: guide_link: https://crowdin.com/project/mastodon guide_link_text: 每个人都可以参与翻译。 sensitive_content: 敏感内容 - toot_layout: 嘟文布局 application_mailer: notification_preferences: 更改电子邮件首选项 salutation: "%{name}:" settings: 使用此链接更改你的电子邮件首选项:%{link} + unsubscribe: 取消订阅 view: 点此链接查看详情: view_profile: 查看个人资料页 view_status: 查看嘟文 applications: created: 应用创建成功 destroyed: 应用删除成功 + logout: 退出登录 regenerate_token: 重置访问令牌 token_regenerated: 访问令牌重置成功 warning: 一定小心,千万不要把它分享给任何人! your_token: 你的访问令牌 auth: apply_for_account: 申请账号 - change_password: 密码 + captcha_confirmation: + help_html: 如果您在输入验证码时遇到问题,可以通过%{email} 与我们联系,我们将为您提供帮助。 + hint_html: 只剩最后一件事了!我们需要确认您是一个人类(这样我们才能阻止恶意访问!)。请输入下面的验证码,然后点击“继续”。 + title: 安全检查 confirmations: wrong_email_hint: 如果该电子邮件地址不正确,您可以在帐户设置中进行更改。 delete_account: 删除帐户 @@ -955,40 +1029,53 @@ zh-CN: prefix_invited_by_user: "@%{name} 邀请你加入这个Mastodon服务器!" prefix_sign_up: 现在就注册 Mastodon! suffix: 注册一个账号,你就可以关注他人、发布嘟文、并和其它任何 Mastodon 服务器上的用户交流,而且还有其它更多功能! - didnt_get_confirmation: 没有收到确认邮件? + didnt_get_confirmation: 没有收到确认链接? dont_have_your_security_key: 没有你的安全密钥? forgot_password: 忘记密码? invalid_reset_password_token: 密码重置令牌无效或已过期。请重新发起重置密码请求。 - link_to_otp: 输入从手机中获得的两步验证代码或恢复代码 + link_to_otp: 输入从手机中获得的双因素认证代码或恢复代码 link_to_webauth: 使用你的安全密钥设备 log_in_with: 通过外部服务登录 login: 登录 - logout: 登出 + logout: 退出登录 migrate_account: 迁移到另一个账户 migrate_account_html: 如果你希望引导他人关注另一个账号,请点击这里进行设置。 or_log_in_with: 或通过外部服务登录 privacy_policy_agreement_html: 我已阅读并同意 隐私政策 + progress: + confirm: 确认电子邮件地址 + details: 您的详情 + review: 我们的复审 + rules: 接受规则 providers: cas: CAS saml: SAML register: 注册 registration_closed: "%{instance} 目前不接收新成员" - resend_confirmation: 重新发送确认邮件 + resend_confirmation: 重新发送确认链接 reset_password: 重置密码 rules: + accept: 接受 + back: 返回 + invited_by: 你可以加入%{domain},这是由于你收到了他人的邀请,邀请来自: preamble: 这些由 %{domain} 监察员设置和执行。 + preamble_invited: 在您继续之前,请考虑 %{domain} 的管理员设定的基本规则。 title: 一些基本规则。 + title_invited: 您已经被邀请。 security: 账户安全 set_new_password: 设置新密码 setup: - email_below_hint_html: 如果下面的电子邮箱地址是错误的,你可以在这里修改并重新发送新的确认邮件。 - email_settings_hint_html: 确认邮件已经发送到%{email}。如果该邮箱地址不对,你可以在账号设置里面修改。 - title: 初始设置 + email_below_hint_html: 请检查的垃圾邮件文件夹,或请求再次发送一次。如果您的电子邮件地址不对,您可以更正您的电子邮件地址。 + email_settings_hint_html: 请点击我们发送给 %{email} 地址中的确认链接。我在这儿等着您。 + link_not_received: 没有收到链接? + new_confirmation_instructions_sent: 您将在几分钟内收到一封带有确认链接的新邮件! + title: 请检查你的电子邮件收件箱 sign_in: preamble_html: 使用您在 %{domain} 的账户和密码登录。如果您的账户托管在其他的服务器上,您将无法在此登录。 title: 登录到 %{domain} sign_up: - preamble: 使用此 Mastodon 服务器上的帐号,您将能够关注网络上的任何其他人,无论他们的帐号托管在哪里的主机。 + manual_review: 您在 %{domain} 上的注册需要经由管理人员手动审核。 为了帮助我们处理您的注册,请稍微介绍一下您为什么想在 %{domain} 上注册。 + preamble: 有了这个Mastodon服务器上的账户,您就可以关注Mastodon网络上的任何其他人,无论他们的账户在哪里。 title: 让我们在 %{domain} 上开始。 status: account_status: 账户状态 @@ -999,18 +1086,6 @@ zh-CN: view_strikes: 查看针对你账号的记录 too_fast: 表单提交过快,请重试。 use_security_key: 使用安全密钥 - authorize_follow: - already_following: 你已经在关注此用户了 - already_requested: 你已经向那个账户发送过关注请求了 - error: 对不起,寻找这个跨站用户时出错 - follow: 关注 - follow_request: 关注请求已发送给: - following: 成功!你正在关注: - post_follow: - close: 你也可以直接关闭这个窗口。 - return: 查看用户个人资料 - web: 返回本站 - title: 关注 %{acct} challenge: confirm: 继续 hint_html: "注意:接下来一小时内我们不会再次要求你输入密码。" @@ -1026,18 +1101,18 @@ zh-CN: with_month_name: "%Y年%m月%d日" datetime: distance_in_words: - about_x_hours: "%{count}时" - about_x_months: "%{count}个月" - about_x_years: "%{count}年" - almost_x_years: "%{count}年" + about_x_hours: "%{count}小时前" + about_x_months: "%{count}个月前" + about_x_years: "%{count}年前" + almost_x_years: "%{count}年前" half_a_minute: 刚刚 - less_than_x_minutes: "%{count}分" + less_than_x_minutes: "%{count}分钟前" less_than_x_seconds: 刚刚 - over_x_years: "%{count}年" - x_days: "%{count}天" - x_minutes: "%{count}分" - x_months: "%{count}个月" - x_seconds: "%{count}秒" + over_x_years: "%{count}年前" + x_days: "%{count}天前" + x_minutes: "%{count}分钟前" + x_months: "%{count}个月前" + x_seconds: "%{count}秒前" deletes: challenge_not_passed: 你输入的信息不正确 confirm_password: 输入你当前的密码来验证身份 @@ -1087,6 +1162,10 @@ zh-CN: your_appeal_rejected: 你的申诉已被驳回 domain_validator: invalid_domain: 不是一个有效的域名 + edit_profile: + basic_information: 基本信息 + hint_html: "自定义公开资料和嘟文旁边显示的内容。当您填写完整的个人资料并设置了头像时,其他人更有可能关注您并与您互动。" + other: 其他 errors: '400': 你提交的请求无效或格式不正确。 '403': 你没有访问这个页面的权限。 @@ -1123,7 +1202,7 @@ zh-CN: featured_tags: add_new: 添加新条目 errors: - limit: 你所推荐的话题标签数已达上限 + limit: 您所推荐的话题标签数已达上限 hint_html: "什么是精选话题标签? 它们被显示在你的公开个人资料中的突出位置,人们可以在这些标签下浏览你的公共嘟文。 它们是跟踪创作或长期项目的进度的重要工具。" filters: contexts: @@ -1140,7 +1219,7 @@ zh-CN: title: 编辑过滤器 errors: deprecated_api_multiple_keywords: 这些参数不能从此应用程序更改,因为它们应用于一个以上的过滤关键字。 使用较新的应用程序或网页界面。 - invalid_context: 过滤器场景没有或无效 + invalid_context: 提供的过滤器环境没有或无效 index: contexts: 在 %{contexts} 中的过滤器 delete: 删除 @@ -1158,21 +1237,21 @@ zh-CN: save: 保存新过滤器 title: 添加新的过滤器 statuses: - back_to_filter: 返回至过滤器 + back_to_filter: 返回过滤器 batch: remove: 从过滤器中移除 index: hint: 无论其他条件如何,此过滤器适用于选用个别嘟文。你可以从网页界面中向此过滤器加入更多嘟文。 title: 过滤的嘟文 - footer: - trending_now: 现在流行 generic: all: 全部 all_items_on_page_selected_html: other: 此页面上的所有 %{count} 项目已被选中。 all_matching_items_selected_html: other: 所有 %{count} 匹配您搜索的项目都已被选中。 + cancel: 取消 changes_saved_msg: 更改保存成功! + confirm: 确认 copy: 复制 delete: 删除 deselect: 取消全选 @@ -1184,24 +1263,62 @@ zh-CN: today: 今天 validation_errors: other: 出错啦!检查一下下面 %{count} 处出错的地方吧 - html_validator: - invalid_markup: '包含无效的 HTML 标记: %{error}' imports: errors: + empty: CSV 文件为空 + incompatible_type: 与所选导入类型不兼容 invalid_csv_file: '无效的 CSV 文件。错误: %{error}' over_rows_processing_limit: 包含行数超过了 %{count} + too_large: 文件过大 + failures: 失败 + imported: 已导入 + mismatched_types_warning: 您似乎选择了导入错误的类型,请再次检查。 modes: merge: 合并 merge_long: 保留现有记录并添加新的记录 overwrite: 覆盖 overwrite_long: 将当前记录替换为新记录 + overwrite_preambles: + blocking_html: 您即将使用来自 %{filename} 的最多 %{total_items} 个账户替换您的屏蔽列表。 + bookmarks_html: 您即将使用来自 %{filename} %{total_items} 篇嘟文替换您的书签。 + domain_blocking_html: 您即将使用来自 %{filename} 的最多 %{total_items} 个域名替换您的域名屏蔽列表。 + following_html: 您即将从 %{filename} 关注 %{total_items} 个账户,并停止关注其他任何人。 + lists_html: 你即将用 %{filename} 的内容替换你的列表。新列表中将添加 %{total_items} 个账户。 + muting_html: 您即将使用来自 %{filename} 的最多 %{total_items} 个账户替换您已隐藏的账户列表。 + preambles: + blocking_html: 您即将从 %{filename} 封锁多达 %{total_items} 个账户。 + bookmarks_html: 您即将把来自 %{filename} %{total_items} 篇嘟文添加到您的书签中。 + domain_blocking_html: 您即将从 %{filename} 屏蔽 %{total_items} 个域名。 + following_html: 您即将从 %{filename} 关注最多 %{total_items} 个账户。 + lists_html: 你即将从 %{filename} 中添加最多 %{total_items} 个账户到你的列表中。如果没有可用列表,将创建新的列表。 + muting_html: 您即将从 %{filename} 隐藏 %{total_items} 个账户。 preface: 你可以在此导入你在其他实例导出的数据,比如你所关注或屏蔽的用户列表。 + recent_imports: 最近导入 + states: + finished: 已完成 + in_progress: 导入中 + scheduled: 已预定 + unconfirmed: 未确认 + status: 状态 success: 数据上传成功,正在处理中 + time_started: 开始于 + titles: + blocking: 正在导入被屏蔽的账户 + bookmarks: 正在导入书签 + domain_blocking: 正在导入被屏蔽的域名 + following: 正在导入关注的账户 + lists: 导入列表 + muting: 正在导入隐藏的账户 + type: 导入类型 + type_groups: + constructive: 关注和书签 + destructive: 屏蔽和隐藏 types: blocking: 屏蔽列表 bookmarks: 书签 domain_blocking: 域名屏蔽列表 following: 关注列表 + lists: 列表 muting: 隐藏列表 upload: 上传 invites: @@ -1227,7 +1344,7 @@ zh-CN: title: 邀请用户 lists: errors: - limit: 你所建立的列表数量已经达到上限 + limit: 您已达到列表数量的上限 login_activities: authentication_methods: otp: 双因素认证应用 @@ -1239,6 +1356,21 @@ zh-CN: failed_sign_in_html: 失败的 %{method} 登录尝试,来自 %{ip} (%{browser}) successful_sign_in_html: 通过 %{method} 成功登录,来自 %{ip} (%{browser}) title: 认证历史 + mail_subscriptions: + unsubscribe: + action: 是,取消订阅 + complete: 已取消订阅 + confirmation_html: 您确定要取消订阅来自 %{domain} 上的 Mastodon 的 %{type} 到您的邮箱 %{email} 吗?您可以随时在电子邮件通知设置重新订阅。 + emails: + notification_emails: + favourite: 嘟文被点赞邮件通知 + follow: 账户被关注邮件通知 + follow_request: 关注请求邮件通知 + mention: 账户被提及邮件通知 + reblog: 被转嘟邮件通知 + resubscribe_html: 如果您不小心取消订阅,可以从您的电子邮件通知设置重新订阅。 + success_html: 您将不会在您的邮箱 %{email} 中收到 %{domain} 上的 Mastodon的 %{type} + title: 取消订阅 media_attachments: validations: images_and_video: 无法在嘟文中同时插入视频和图片 @@ -1279,7 +1411,7 @@ zh-CN: title: 运营 move_handler: carry_blocks_over_text: 这个用户迁移自你屏蔽过的 %{acct} - carry_mutes_over_text: 这个用户迁移自你隐藏过的 %{acct} + carry_mutes_over_text: 这个用户由你隐藏过的 %{acct} 迁移而来 copy_account_note_text: 这个用户迁移自 %{acct},你曾为其添加备注: navigation: toggle_menu: 隐藏/显示菜单 @@ -1314,10 +1446,11 @@ zh-CN: subject: "%{name} 转嘟了你的嘟文" title: 新的转嘟 status: - subject: "%{name} 刚刚发嘟" + subject: "%{name} 刚刚发布嘟文" update: subject: "%{name} 编辑了嘟文" notifications: + administration_emails: 管理员电子邮件通知 email_events: 电子邮件通知事件 email_events_hint: 选择你想要收到通知的事件: other_settings: 其它通知设置 @@ -1333,7 +1466,7 @@ zh-CN: trillion: T otp_authentication: code_hint: 输入认证应用生成的代码以确认操作 - description_html: 如果你使用身份验证应用启用了 双重身份验证, 登录将需要用到你的手机,它将生成你需要的令牌。 + description_html: 如果你使用身份验证应用并启用了双因素认证,登录时将需要用到你的手机,由它生成所需的令牌。 enable: 启用 instructions_html: "请使用 Google 身份验证器或其他的TOTP双重认证手机应用扫描此处的二维码。启用双重认证后,在登录时,你需要输入该应用生成的代码。" manual_instructions: 如果你无法扫描二维码,请手动输入下列文本: @@ -1349,17 +1482,27 @@ zh-CN: errors: already_voted: 你已经在这里投过票了 duplicate_options: 包含重复的项目 - duration_too_long: 持续时间过长 - duration_too_short: 持续时间过短 + duration_too_long: 期限过长 + duration_too_short: 期限过短 expired: 投票已经结束 invalid_choice: 被选中的投票选项不存在 over_character_limit: 每条不能超过 %{max} 个字符 + self_vote: 您不能参与自己发起的投票 too_few_options: 至少需要两个选项 too_many_options: 不能超过 %{max} 项 preferences: other: 其他 posting_defaults: 发布默认值 public_timelines: 公共时间轴 + privacy: + hint_html: "自定义您希望如何找到您的个人资料和嘟文。启用Mastodon中的各种功能可以帮助您扩大受众范围。请花点时间查看这些设置,确保它们适合您的使用情况。" + privacy: 隐私 + privacy_hint_html: 控制你愿意向他人透露多少信息。通过浏览他人的关注列表和查看他们发嘟所用的应用,人们可以发现有趣的用户和酷炫的应用,但你可能更喜欢将其隐藏起来。 + reach: 范围 + reach_hint_html: 控制您是否希望被新人发现和关注。您是否希望您的嘟文出现在“探索”页面上?您是否希望其他人在关注推荐中看到您?您是想自动接受所有新粉丝,还是对每个粉丝都进行仔细的筛选? + search: 搜索 + search_hint_html: 控制你希望被找到的方式。你想让人们通过你公开发布的内容来找到你吗?当在网络上搜索时,你是否希望Mastodon之外的人能够找到你的个人资料?请注意,我们无法保证完全排除所有搜索引擎对公开信息的索引。 + title: 隐私与可达性 privacy_policy: title: 隐私政策 reactions: @@ -1372,6 +1515,7 @@ zh-CN: confirm_remove_selected_followers: 您确定想要取关所选的关注者吗? confirm_remove_selected_follows: 您确定要删除选定的关注着吗? dormant: 休眠 + follow_failure: 无法关注选中的部分账户。 follow_selected_followers: 关注选中的关注者 followers: 关注者 following: 正在关注 @@ -1409,8 +1553,9 @@ zh-CN: chrome: Chrome edge: 微软 Edge electron: Electron - firefox: 火狐 + firefox: Firefox generic: 未知浏览器 + huawei_browser: 华为浏览器 ie: IE 浏览器 micro_messenger: 微信 nokia: Nokia S40 Ovi 浏览器 @@ -1420,6 +1565,7 @@ zh-CN: qq: QQ浏览器 safari: Safari uc_browser: UC 浏览器 + unknown_browser: 未知浏览器 weibo: 新浪微博 current_session: 当前会话 description: "%{platform} 上的 %{browser}" @@ -1432,9 +1578,10 @@ zh-CN: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: 未知平台 + unknown_platform: 未知平台 windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1463,7 +1610,7 @@ zh-CN: relationships: 关注管理 statuses_cleanup: 自动删除嘟文 strikes: 操作记录 - two_factor_authentication: 双重认证 + two_factor_authentication: 双因素认证 webauthn_authentication: 安全密钥 statuses: attached: @@ -1499,7 +1646,6 @@ zh-CN: show_newer: 显示更新内容 show_older: 显示更早内容 show_thread: 显示全部对话 - sign_in_to_participate: 登录以加入对话 title: "%{name}:“%{quote}”" visibilities: direct: 私信 @@ -1528,7 +1674,7 @@ zh-CN: keep_polls_hint: 不会删除你的任何投票 keep_self_bookmark: 保存被你加入书签的嘟文 keep_self_bookmark_hint: 如果你已将自己的嘟文添加书签,就不会删除这些嘟文 - keep_self_fav: 保留你喜欢的嘟文 + keep_self_fav: 保留你点赞的嘟文 keep_self_fav_hint: 如果你喜欢了自己的嘟文,则不会删除这些嘟文 min_age: '1209600': 2周 @@ -1540,13 +1686,11 @@ zh-CN: '63113904': 两年 '7889238': 3个月 min_age_label: 过期阈值 - min_favs: 保留如下嘟文:喜欢数超过 - min_favs_hint: 喜欢数超过该阈值的的嘟文不会被删除。如果留空,则无论嘟文获得多少喜欢,都将被删除。 + min_favs: 保留如下嘟文:点赞数超过 + min_favs_hint: 点赞数超过该阈值的的嘟文都不会被删除。如果留空,则无论嘟文获得多少点赞,都将被删除。 min_reblogs: 保留如下嘟文:转嘟数超过 min_reblogs_hint: 转嘟数超过该阈值的的嘟文不会被删除。如果留空,则无论嘟文获得多少转嘟,都将被删除。 stream_entries: - pinned: 置顶嘟文 - reblogged: 转嘟 sensitive_content: 敏感内容 strikes: errors: @@ -1562,16 +1706,21 @@ zh-CN: default: "%Y年%m月%d日 %H:%M" month: "%Y年%m月" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: 服务器的翻译服务使用配额已超过限制。 + too_many_requests: 最近向翻译服务发起的请求过多。 two_factor_authentication: add: 添加 - disable: 停用双重认证 - disabled_success: 双重身份验证成功禁用 + disable: 停用双因素认证 + disabled_success: 已成功禁用双因素认证 edit: 编辑 - enabled: 双重认证已启用 - enabled_success: 双重认证启用成功 + enabled: 已启用双因素认证 + enabled_success: 已成功启用双因素认证 generate_recovery_codes: 生成恢复代码 lost_recovery_codes: 如果你的手机不慎丢失,你可以使用恢复代码来重新获得对账户的访问权。如果你遗失了恢复代码,可以在此处重新生成。之前使用的恢复代码将会失效。 - methods: 双重认证 + methods: 双因素认证方式 otp: 身份验证应用 recovery_codes: 备份恢复代码 recovery_codes_regenerated: 恢复代码重新生成成功 @@ -1595,7 +1744,7 @@ zh-CN: change_password: 更改密码 details: 以下是该次登录的详细信息: explanation: 我们检测到有新 IP 地址登录了您的账号。 - further_actions_html: 如果不是您自己的操作,我们建议您立即 %{action} 并启用双重验证,确保账号安全。 + further_actions_html: 如果不是您本人操作,我们建议您立即 %{action} 并启用双因素认证,以确保账号安全。 subject: 已有新 IP 地址访问了您的账号 title: 新登录 warning: @@ -1607,7 +1756,7 @@ zh-CN: explanation: delete_statuses: 你的一些嘟文被发现违反了一条或多条社区准则,并已被 %{instance} 的监察员删除。 disable: 你不能再使用你的账户,但你的个人资料和其他数据保持不变。你可以请求数据备份,更改账户设置或删除账户。 - mark_statuses_as_sensitive: 你的一些嘟文已经被 %{instance} 检察员标记为敏感内容。这意味着别人需要在嘟文中点击媒体,才能显示媒体预览。你可以在今后发嘟时自行将媒体标记为敏感内容。 + mark_statuses_as_sensitive: 你的一些嘟文已经被 %{instance} 检察员标记为敏感内容。这意味着别人需要在嘟文中点击媒体,才能显示媒体预览。你可以在今后发布嘟文时自行将媒体标记为敏感内容。 sensitive: 即刻起,你上传的所有媒体文件都将被标记为敏感内容并隐藏,在点击警告后才能查看。 silence: 你可以继续使用你的账号,但只有已关注你的人才能在看到你在此服务器上的嘟文,并且你会被排除在各类公共列表之外。其他用户仍可以手动关注你。 suspend: 你不能再使用你的账户,并且你的个人资料和其他数据都将无法访问。在大约30天内,你仍可以登录并请求数据备份,之后相关数据将被完全删除。我们会保留一些基础数据以避免封禁失效。 @@ -1634,20 +1783,25 @@ zh-CN: edit_profile_step: 您可以通过上传个人资料图片、更改您的昵称等来自定义您的个人资料。 您可以选择在新关注者关注您之前对其进行审核。 explanation: 下面是几个小贴士,希望它们能帮到你 final_action: 开始嘟嘟 - final_step: '开始发嘟! 即使没有关注者,您的公开嘟文也可能会被其他人看到,例如在本地时间轴或话题标签中。 您可能想在 #introductions 话题标签上介绍自己。' + final_step: '开始发布嘟文! 即使没有关注者,您的公开嘟文也可能会被其他人看到,例如在本地时间轴或话题标签中。 您可能想在 #introductions 话题标签上介绍自己。' full_handle: 你的完整用户地址 full_handle_hint: 你需要把这个告诉你的朋友们,这样他们就能从另一台服务器向你发送信息或者关注你。 subject: 欢迎来到 Mastodon title: "%{name},欢迎你的加入!" users: follow_limit_reached: 你不能关注超过 %{limit} 个人 - invalid_otp_token: 输入的双重认证代码无效 + go_to_sso_account_settings: 转到您的身份提供商进行账户设置 + invalid_otp_token: 输入的双因素认证代码无效 otp_lost_help_html: 如果你不慎丢失了所有的代码,请联系 %{email} 寻求帮助 seamless_external_login: 因为你是通过外部服务登录的,所以密码和电子邮件地址设置都不可用。 signed_in_as: 当前登录的账户: verification: - explanation_html: 你可以 验证自己是个人资料元数据中的某个链接的所有者。 为此,被链接网站必须包含一个到你的 Mastodon 主页的链接。链接中 必须 包括 rel="me" 属性。链接的文本内容可以随意填写。例如: + extra_instructions_html: 提示:您网站上的链接可能是不可见的。重要的部分是 rel="me",它可以防止在具有用户生成内容的网站上冒充身份。您甚至可以在页面头部使用 link 标签而不是 a,但 HTML 必须能够在不执行 JavaScript 的情况下访问。 + here_is_how: 具体方法如下: + hint_html: "在Mastodon上验证您的身份对每个人都是必要的。基于开放网络标准,现在和将来永远免费。您只需要一个被人们认可的个人网站。当您在个人资料中链接到这个网站时,我们会检查该网站是否回链到您的资料,并显示一个指示符号。" + instructions_html: 将下面的代码复制并粘贴到您网站的HTML中。然后在“编辑个人资料”选项卡中的附加字段之一添加您网站的地址,并保存更改。 verification: 验证 + verified_links: 您已验证的链接 webauthn_credentials: add: 添加新的安全密钥 create: @@ -1663,5 +1817,5 @@ zh-CN: nickname_hint: 输入你的新安全密钥的昵称 not_enabled: 你尚未启用WebAuthn not_supported: 此浏览器不支持安全密钥 - otp_required: 要使用安全密钥,请先启用两步验证。 + otp_required: 要使用安全密钥,请先启用双因素认证。 registered_on: 注册于 %{date} diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index 3400405d46..626cf22e71 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -89,6 +89,7 @@ zh-HK: moderation: active: 活躍 all: 全部 + disabled: 已停用 pending: 處理中 silenced: 受限 suspended: 已停權 @@ -121,8 +122,8 @@ zh-HK: removed_header_msg: 成功刪除 %{username} 的頁面頂端圖片 resend_confirmation: already_confirmed: 這個使用者先前已經被確認過 - send: 重寄確認郵件 - success: 確認電郵發送成功! + send: 重寄確認連結 + success: 成功寄送確認連結! reset: 重設 reset_password: 重設密碼 resubscribe: 重新訂閱 @@ -130,6 +131,7 @@ zh-HK: search: 搜尋 search_same_email_domain: 其他有相同電郵網域的使用者 search_same_ip: 其他有相同 IP 位址的使用者 + security: 安全性 security_measures: only_password: 僅密碼 password_and_2fa: 密碼和兩步認證 @@ -304,6 +306,7 @@ zh-HK: unpublish: 未發佈 unpublished_msg: 成功取消發布公告! updated_msg: 成功更新公告! + critical_update_pending: 待處理重要更新 custom_emojis: assign_category: 指定分類 by_domain: 網域 @@ -373,6 +376,15 @@ zh-HK: undo: 從白名單移除 domain_blocks: add_new: 新增域名阻隔規則 + confirm_suspension: + cancel: 取消 + confirm: 停權 + permanent_action: 撤銷停權不會恢復任何資料和追蹤關係。 + preamble_html: 你將停權 %{domain} 及其所有子網域。 + remove_all_data: 這將會從你的伺服器中移除該網域帳號的所有內容、媒體和個人檔案資料。 + stop_communication: 你的伺服器將停止與這些伺服器通訊。 + title: 確認封鎖網域 %{domain} + undo_relationships: 你伺服器上的帳號將取消追蹤這些伺服器上的帳號。 created_msg: 正處理阻隔域名的請求 destroyed_msg: 已撤銷域名阻隔 domain: 域名阻隔 @@ -419,6 +431,7 @@ zh-HK: resolve: 解析網域 title: 新增電郵網域阻隔 no_email_domain_block_selected: 未選取任何電郵網域限制,因此並未變更 + not_permitted: 無權限 resolved_dns_records_hint_html: 域名解析為以下 MX 網域,這些網域主要用來接收電子郵件。封鎖一個 MX 網域,即使域名看起來不同,也會阻止任何用相同 MX 網域的電郵地址進行註冊。注意不要封鎖主要的電子郵件供應商。 resolved_through_html: 透過 %{domain} 解析 title: 電郵網域阻隔 @@ -433,6 +446,7 @@ zh-HK: private_comment_description_html: 為了幫助你追蹤匯入封鎖的源頭,匯入的封鎖會在建立時將會有以下的私密備註:%{comment} private_comment_template: 於 %{date} 從 %{source} 匯入 title: 匯入封鎖的網域 + invalid_domain_block: 由於以下錯誤,已略過一個或多個域名封鎖:%{error} new: title: 匯入封鎖的網域 no_file: 未選擇檔案 @@ -462,6 +476,7 @@ zh-HK: content_policies: comment: 內部備註 description_html: 你可以自行制訂內容政策,政策將用於此網域和其子網域的所有帳號。 + limited_federation_mode_description_html: 你可選擇是否允許此網域加入跨站。 policies: reject_media: 拒絕接收媒體 reject_reports: 拒絕檢舉 @@ -563,17 +578,23 @@ zh-HK: mark_as_sensitive_description_html: 被檢舉的帖文中的媒體會被標記為敏感內容,並記錄一次警告,以便日後加快處理同一帳號的違規行為。 other_description_html: 查看更多控制帳號行為,以及自訂與被檢舉帳號溝通的選項。 resolve_description_html: 不會對被檢舉的帳號採取任何動作,也不會記錄警告,檢舉報告將會結案。 + silence_description_html: 此帳號將會只有追蹤者或手動搜尋它的人才可以看見,大幅限制了它的曝光。你可隨時恢復它。關閉所有對此帳號的檢舉報告。 + suspend_description_html: 此帳號及其所有內容將不可再被存取,並且最終會被刪除,無法再進行互動。可於 30 天內撤銷此動作。關閉所有對此帳號的檢舉報告。 actions_description_html: 決定對此檢舉採取哪種措施。如果對被檢舉帳號採取懲罰措施,除非選取了垃圾訊息分類,否則將向他們發送一封電郵通知。 + actions_description_remote_html: 決定對此檢舉採取哪種動作。這只會影響你的伺服器與此遠端帳號的通訊和處理其內容的方式。 add_to_report: 加入更多到檢舉 are_you_sure: 你確認嗎? assign_to_self: 指派給自己 assigned: 指派版主 by_target_domain: 被舉報帳號的域名 + cancel: 取消 category: 分類 category_description_html: 此帳號及/或內容被檢舉的原因,將會被引用在與被檢舉帳號的通訊中。 comment: none: 沒有 comment_description_html: 為了提供更多資訊,%{name} 寫道: + confirm: 確定 + confirm_action: 確認對 @%{acct} 執行管理操作 created_at: 日期 delete_and_resolve: 刪除帖文 forwarded: 已轉寄 @@ -590,6 +611,7 @@ zh-HK: placeholder: 記錄已執行的動作,或其他相關的更新…… title: 筆記 notes_description_html: 查看並給其他管理員和日後的自己留下筆記 + processed_msg: '已成功處理檢舉報告 #%{id}' quick_actions_description_html: 採取快捷操作或向下捲動以查看檢舉內容: remote_user_placeholder: 來自 %{instance} 的遠端使用者 reopen: 重開舉報個案 @@ -602,9 +624,28 @@ zh-HK: status: 狀態 statuses: 被檢舉的內容 statuses_description_html: 違規內容將被引用在被檢舉帳號的通訊中 + summary: + action_preambles: + delete_html: 你即將移除 @%{acct} 的部份帖文。這會: + mark_as_sensitive_html: 你即將把 @%{acct} 的部份帖文標記敏感內容。這會: + silence_html: 你即將限制 @%{acct} 的帳號。這會: + suspend_html: 你即將把 @%{acct} 的帳號停權。這會: + actions: + delete_html: 移除違規帖文 + mark_as_sensitive_html: 將違規帖文的媒體標記為敏感內容 + silence_html: 僅讓 @%{acct} 的追蹤者和手動搜尋其個人檔案的人看到他的個人檔案和內容,從而大幅限制其曝光。 + suspend_html: 把 @%{acct} 停權,使其個人檔案和內容無法被存取和互動。 + close_report: '將檢舉報告 #%{id} 標記為已解決' + close_reports_html: 將針對 @%{acct}所有檢舉報告標記為已解決 + delete_data_html: 從現在起 30 天後移除 @%{acct} 的個人檔案和內容,除非在此期間撤銷對他們的停權。 + preview_preamble_html: "@%{acct} 將收到警告,內容如下:" + record_strike_html: 記錄對 @%{acct} 的警告,有助你加快處理此帳號日後的違規行為 + send_email_html: 向 @%{acct} 發送警告郵件 + warning_placeholder: 選填審核動作的補充理由。 target_origin: 被檢舉帳號來源 title: 舉報 unassign: 取消指派 + unknown_action_msg: 未知的動作:%{action} unresolved: 未處理 updated_at: 更新 view_profile: 查看個人檔案 @@ -686,6 +727,9 @@ zh-HK: branding: preamble: 你的伺服器的品牌使它與網絡上的其他伺服器區分開來。這些資訊可能會在各種情境下顯示,如 Mastodon 的網頁介面、原生應用程式,以及其他網站和通訊應用程式內的連結預覽等。因此,請盡量保持資訊簡短精煉。 title: 品牌 + captcha_enabled: + desc_html: 這倚賴 hCaptcha 的外部腳本,或會引起安全和私隱疑慮。此外,此註冊流程亦可能對特定人士(尤其是殘疾人士)有較多障礙。有鑑於此,請考慮使用其他以審核或邀請的註冊方式。 + title: 要求新使用者解答 CAPTCHA 以驗證帳號 content_retention: preamble: 控制使用者生成的內容如何儲存在 Mastodon。 title: 內容留存 @@ -697,6 +741,8 @@ zh-HK: preamble: 呈現有趣的內容有助於吸引不認識 Mastodon 的使用者新手上路。控制各種探索功能在你的伺服器上的運作方式。 profile_directory: 個人檔案目錄 public_timelines: 公共時間軸 + publish_discovered_servers: 公開已知的伺服器 + publish_statistics: 公佈統計數據 title: 探索 trends: 熱門 domain_blocks: @@ -711,10 +757,27 @@ zh-HK: approved: 註冊需要核准 none: 沒有人可註冊 open: 任何人皆能註冊 + security: + authorized_fetch: 要求跨站驗證 + authorized_fetch_hint: 要求跨站驗證可更嚴謹地執行使用者級及伺服器級的封鎖。然而,這會犧牲性能,降低你回覆的觸及範圍,跨站服務亦可能出現兼容問題。此外,這並無法阻止他人蓄意擷取你的公開帖文和帳號。 + authorized_fetch_overridden_hint: 由於此設定被某環境變數覆寫,因此你目前無法更改此設定。 + federation_authentication: 強制跨站驗證 title: 伺服器設定 site_uploads: delete: 刪除上傳的檔案 destroyed_msg: 成功刪除站台的上傳項目! + software_updates: + critical_update: 重要 — 請盡快更新 + description: 建議保持安裝最新的 Mastodon,以獲取最新的修正和功能。此外,及時更新 Mastodon 對於保安至關重要。有鑑於此,Mastodon 每 30 分鐘會檢查更新,並根據你的電郵通知偏好通知你。 + documentation_link: 了解更多 + release_notes: 版本資訊 + title: 可用的更新 + type: 類型 + types: + major: 主要版本更新 + minor: 次要版本更新 + patch: 修正發佈 — 除錯及些微修改 + version: 版本 statuses: account: 作者 application: 應用程式 @@ -751,9 +814,24 @@ zh-HK: suspend: "%{name} 將 %{target} 的帳號停權" appeal_approved: 已申訴 appeal_pending: 申訴待審中 + appeal_rejected: 申訴被駁回 system_checks: database_schema_check: message_html: 有待處理的資料庫轉移 (database migration) 。請執行以確保應用程式行為合乎預期 + elasticsearch_health_red: + message_html: Elasticsearch 叢集狀態不健康(紅色狀態),無法使用搜尋功能 + elasticsearch_health_yellow: + message_html: Elasticsearch 叢集狀態不健康(黃色狀態),你可能需要調查其原因 + elasticsearch_index_mismatch: + message_html: Elasticsearch 索引配置已過期。請執行tootctl search deploy --only=%{value} + elasticsearch_preset: + action: 查看文檔 + message_html: 你的 Elasticsearch 叢集有多個節點,但 Mastodon 並未配置來使用它們。 + elasticsearch_preset_single_node: + action: 查看文檔 + message_html: 你的 Elasticsearch 叢集只有一個節點,ES_PRESET應設定為single_node_cluster。 + elasticsearch_reset_chewy: + message_html: 由於設定變更,你的 Elasticsearch 系統索引已過期。請執行tootctl search deploy --reset-chewy來更新它。 elasticsearch_running_check: message_html: 無法連接到 Elasticsearch。請檢查它是否運行中,或停用全文搜索。 elasticsearch_version_check: @@ -764,6 +842,18 @@ zh-HK: message_html: 您尚未定義任何伺服器規則 sidekiq_process_check: message_html: 沒有 %{value} 佇列的 Sidekiq 處理程序。請檢查 Sidekiq 設定檔案 + software_version_critical_check: + action: 查看可用的更新 + message_html: 有重要的 Mastodon 更新可用,請盡快更新。 + software_version_patch_check: + action: 查看可用的更新 + message_html: 有可用的 Mastodon 除錯更新。 + upload_check_privacy_error: + action: 在此查看更多資訊 + message_html: "你的網絡伺服器配置錯誤。你的使用者的私隱有危險。" + upload_check_privacy_error_object_storage: + action: 在此查看更多資訊 + message_html: "你的對象儲存配置錯誤。你的使用者的私隱有危險。" tags: review: 審核文章 updated_msg: 成功更新主題標籤設定 @@ -785,6 +875,7 @@ zh-HK: other: 上週有 %{count} 人分享 title: 熱門連結 usage_comparison: 今天被分享了 %{today} 次,相較於昨天 %{yesterday} 次 + not_allowed_to_trend: 不允許登上趨勢 only_allowed: 僅允許 pending_review: 等待審核中 preview_card_providers: @@ -866,6 +957,9 @@ zh-HK: body: "%{target} 對 %{action_taken_by} 於 %{date} 做出的 %{type} 審核裁決提出申訴。他們寫道:" next_steps: 您可以批准此申訴以撤銷審核裁決,又或者忽略它。 subject: "%{username} 對 %{instance} 上的審核裁決提出申訴" + new_critical_software_updates: + body: 全新關鍵性 Mastodon 版本已釋出,你也許想盡快更新! + subject: "%{instance} 有關鍵的 Mastodon 更新可用!" new_pending_account: body: 以下是新帳戶的資訊。你可以審核這項申請。 subject: 在 %{instance} 上未審核的新用戶(%{username}) @@ -873,6 +967,9 @@ zh-HK: body: "%{reporter} 舉報了 %{target}" body_remote: 來自 %{domain} 的人舉報了 %{target} subject: 針對 %{instance} 的舉報(#%{id}) + new_software_updates: + body: 已推出全新 Mastodon 版本,你或許想要更新它! + subject: "%{instance} 有全新的 Mastodon 版本可用!" new_trends: body: 以下項目需要經過審核才能公開顯示: new_trending_links: @@ -902,31 +999,37 @@ zh-HK: guide_link: https://crowdin.com/project/mastodon guide_link_text: 每個人都能貢獻。 sensitive_content: 敏感內容 - toot_layout: 發文介面 application_mailer: notification_preferences: 更改電郵設定 salutation: "%{name}:" settings: 修改電郵設定︰%{link} + unsubscribe: 取消訂閱 view: 進入瀏覽︰ view_profile: 檢視個人資料頁 view_status: 檢視文章 applications: created: 已建立應用程式 destroyed: 已刪除應用程式 + logout: 登出 regenerate_token: 重設 token token_regenerated: 已重設 token warning: 警告,不要把它分享給任何人! your_token: token auth: apply_for_account: 申請帳號 - change_password: 密碼 + captcha_confirmation: + help_html: 如果用 CAPTCHA 時遇到問題,你可以透過 %{email} 與我們聯絡,我們會協助你。 + hint_html: 還有最後一步!我們需要確認你是人類(這樣我們才能杜絕垃圾郵件!)。解答下方的 CAPTCHA,然後點擊「繼續」。 + title: 安全檢查 + confirmations: + wrong_email_hint: 如果該電郵地址不正確,你可以在帳號設定中修改。 delete_account: 刪除帳號 delete_account_html: 如果你想刪除你的帳號,請點擊這裡繼續。你需要確認你的操作。 description: prefix_invited_by_user: "@%{name} 邀請你加入這個 Mastodon 服務站!" prefix_sign_up: 立即註冊 Mastodon! suffix: 有了一個帳戶,就可以從任何Mastodon服務器關注任何人,發佈更新並與任何Mastodon服務器的用戶交流! - didnt_get_confirmation: 沒有收到確認指示電郵? + didnt_get_confirmation: 沒有收到確認連結嗎? dont_have_your_security_key: 找不到安全密鑰? forgot_password: 忘記了密碼? invalid_reset_password_token: 密碼重置 token 無效或已過期。請重新重設密碼。 @@ -939,26 +1042,39 @@ zh-HK: migrate_account_html: 想要將這個帳號指向另一個帳號可到這裡設定。 or_log_in_with: 或登入於 privacy_policy_agreement_html: 我已閱讀且同意私隱政策 + progress: + confirm: 確認電郵 + details: 你的資料 + review: 我們的審核 + rules: 接受規則 providers: cas: CAS saml: SAML register: 登記 registration_closed: "%{instance} 並不接受新成員請求" - resend_confirmation: 重發確認指示電郵 + resend_confirmation: 重寄確認連結 reset_password: 重設密碼 rules: + accept: 接受 + back: 返回 + invited_by: 你可以藉着收到的邀請加入 %{domain},該邀請來自: preamble: 這些是由 %{domain} 管理員制訂和執行的。 + preamble_invited: 在你繼續之前,請細閱 %{domain} 管理員擬訂的基本規則。 title: 一些基本規則。 + title_invited: 你已被邀請。 security: 登入資訊 set_new_password: 設定新密碼 setup: - email_below_hint_html: 如果下面的電郵地址不正確,你可在此修改,然後接收電郵進行確認。 - email_settings_hint_html: 確認電郵已發送至 %{email}。電郵地址不正確的話,你可以在帳戶設置中進行更改。 - title: 設定 + email_below_hint_html: 請檢查你的垃圾郵件資料夾,或請求發送另一封郵件。如果你的電郵地址有誤,你可以更正它。 + email_settings_hint_html: 請點擊我們發送給你的連結來驗證 %{email}。我們會等着你。 + link_not_received: 收不到連結嗎? + new_confirmation_instructions_sent: 你將在幾分鐘內收到附有確認連結的新電郵! + title: 檢查你的信箱 sign_in: preamble_html: 請使用 %{domain} 的資料登入。如果您的帳戶託管在其他的伺服器,您將無法在此登入。 title: 登入 %{domain} sign_up: + manual_review: "%{domain} 的註冊均需要我們的管理員手動審核。為了幫助我們處理你的註冊,請填寫一些關於你的資訊,以及為何想在 %{domain} 上開設帳號。" preamble: 有了這個 Mastodon 伺服器的帳號,無論將帳號託管在何處,你都可以追蹤網絡上任何人。 title: 讓我為你在 %{domain} 上設定好。 status: @@ -970,18 +1086,6 @@ zh-HK: view_strikes: 查看針對你的帳戶的過往警告 too_fast: 你太快遞交了,請再試一次。 use_security_key: 使用安全密鑰裝置 - authorize_follow: - already_following: 你已經關注了這個帳號 - already_requested: 你先前已向該帳號發送關注請求 - error: 對不起,尋找這個跨站用戶的過程發生錯誤 - follow: 關注 - follow_request: 關注請求已發送给: - following: 成功!你正在關注: - post_follow: - close: 你也可以直接關閉這個頁面。 - return: 顯示個人資料頁 - web: 返回本站 - title: 關注 %{acct} challenge: confirm: 繼續 hint_html: "温馨提示 我們在未來一小時內不會再要求你填寫密碼。" @@ -1058,6 +1162,10 @@ zh-HK: your_appeal_rejected: 你的申訴已被駁回 domain_validator: invalid_domain: 不是一個可用域名 + edit_profile: + basic_information: 基本資料 + hint_html: "自訂你的公開個人檔案和帖文內容。當你有完整的個人檔案和頭像時,其他人更願意追蹤你和與你互動。" + other: 其他 errors: '400': 你的請求無效或格式不正確。 '403': 你沒有觀看本頁的權限。 @@ -1094,7 +1202,7 @@ zh-HK: featured_tags: add_new: 新增 errors: - limit: 你所推薦的標籤數量已經達到上限 + limit: 你推薦的標籤數量已達上限 hint_html: "甚麼是推薦主題標籤? 它們會被顯示在你的個人資料頁面,讓其他人可以根據標籤瀏覽你的公開文章,令人們更易找到你創作或者長期作品!" filters: contexts: @@ -1135,15 +1243,15 @@ zh-HK: index: hint: 不管其他條件如何,此篩選器會套用於所選的個別帖文。你可以在網頁介面上加入更多帖文到此篩選器。 title: 篩選帖文 - footer: - trending_now: 今期流行 generic: all: 全部 all_items_on_page_selected_html: other: 已選取此頁面上的 %{count} 個項目。 all_matching_items_selected_html: other: 已選取符合你搜尋的 %{count} 個項目。 + cancel: 取消 changes_saved_msg: 已成功儲存修改。 + confirm: 確定 copy: 複製 delete: 刪除 deselect: 取消全選 @@ -1155,24 +1263,62 @@ zh-HK: today: 今天 validation_errors: other: 提交的資料有 %{count} 項問題 - html_validator: - invalid_markup: 含有無效的HTML標記:%{error} imports: errors: + empty: 空白 CSV 檔案 + incompatible_type: 與選擇的匯入類型不相符 invalid_csv_file: 無效的 CSV 檔案。錯誤:%{error} over_rows_processing_limit: 包含超過 %{count} 行 + too_large: 檔案太大 + failures: 失敗 + imported: 已匯入 + mismatched_types_warning: 看來你選擇了不正確的類型來匯入,請再檢查一次。 modes: merge: 合併 merge_long: 留下舊有記錄並添加新的資訊 overwrite: 覆蓋 overwrite_long: 用新記錄覆蓋當前記錄 + overwrite_preambles: + blocking_html: 你將以%{filename}的最多%{total_items}個帳號,來取代你現有的封鎖列表。 + bookmarks_html: 你將以%{filename}的最多%{total_items}個帳號,來取代你現有的書籤。 + domain_blocking_html: 你將以%{filename}的最多%{total_items} 個帳號,來取代你現有的網域封鎖列表。 + following_html: 你將從%{filename}追蹤最多%{total_items} 個帳號,並取消追蹤其他人。 + lists_html: 你將根據%{filename}的內容取代的你列表。最多新增 %{total_items} 個帳號 到新列表。 + muting_html: 你將根據%{filename}中最多 %{total_items} 個帳號取代你的靜音帳號列表。 + preambles: + blocking_html: 你將根據%{filename}封鎖最多 %{total_items} 個帳號。 + bookmarks_html: 你將加入 %{filename} 中最多 %{total_items} 篇帖文到你的書籤中。 + domain_blocking_html: 你將封鎖來自%{filename}的最多 %{total_items} 個網域。 + following_html: 你將追蹤 來自 %{filename} 最多 %{total_items} 個帳號。 + lists_html: 你將加入來自%{filename}最多 %{total_items} 個帳號到你的列表中。如果現時沒有列表,將會建立新列表。 + muting_html: 你將靜音來自%{filename}的最多 %{total_items} 個帳號。 preface: 你可以在此匯入你在其他服務站所匯出的資料檔,包括︰你所關注的用戶,被你封鎖的用戶。 + recent_imports: 最近的匯入 + states: + finished: 完成 + in_progress: 進行中 + scheduled: 已排程 + unconfirmed: 未確認 + status: 狀態 success: 你已成功上載資料檔,我們正將資料匯入,請稍候 + time_started: 開始於 + titles: + blocking: 正在匯入已封鎖帳號 + bookmarks: 正在匯入書籤 + domain_blocking: 正在匯入已封鎖網域 + following: 正在匯入已追蹤帳號 + lists: 正在匯入列表 + muting: 正在匯入已靜音帳號 + type: 匯入類型 + type_groups: + constructive: 追蹤與書籤 + destructive: 封鎖與靜音 types: blocking: 被你封鎖的用戶名單 bookmarks: 書籤 domain_blocking: 域名封鎖名單 following: 你所關注的用戶名單 + lists: 列表 muting: 靜音名單 upload: 上載 invites: @@ -1198,7 +1344,7 @@ zh-HK: title: 邀請用戶 lists: errors: - limit: 你所建立的列表數量已經達到上限 + limit: 你已達到列表數量的上限 login_activities: authentication_methods: otp: 兩步認證軟體 @@ -1210,6 +1356,21 @@ zh-HK: failed_sign_in_html: 以 %{method} 從 %{ip} (%{browser}) 登入失敗 successful_sign_in_html: 以 %{method} 從 %{ip} (%{browser}) 成功登入 title: 驗證操作歷史 + mail_subscriptions: + unsubscribe: + action: 沒錯,取消訂閱 + complete: 已取消訂閱 + confirmation_html: 你確定要取消接收 Mastodon 在%{domain}上的%{type}到你的電郵 %{email} 嗎?你隨時可以從 電郵通知設定重新訂閱。 + emails: + notification_emails: + favourite: 最愛電郵通知 + follow: 追蹤電郵通知 + follow_request: 追蹤請求電郵 + mention: 提及電郵通知 + reblog: 轉推電郵通知 + resubscribe_html: 如果你不小心取消訂閱,你可以從電郵通知設定重新訂閱。 + success_html: 你將不再收到 Mastodon 在%{domain}上的%{type}到你的電郵 %{email}。 + title: 取消訂閱 media_attachments: validations: images_and_video: 不能在已有圖片的文章上加入影片 @@ -1289,6 +1450,7 @@ zh-HK: update: subject: "%{name} 編輯了帖文" notifications: + administration_emails: 管理員電郵通知 email_events: 電郵通知活動 email_events_hint: 選擇你想接收通知的活動: other_settings: 其他通知設定 @@ -1325,12 +1487,22 @@ zh-HK: expired: 投票已結束 invalid_choice: 你所選的投票選項不存在 over_character_limit: 不能多於 %{max} 個字符 + self_vote: 你不能在自己建立的投票活動中投票 too_few_options: 一定要多於一個項目 too_many_options: 不能多於 %{max} 個項目 preferences: other: 其他 posting_defaults: 發佈預設值 public_timelines: 公共時間軸 + privacy: + hint_html: "自訂個人檔案和帖文被他人找到的方式。啟用 Mastodon 一系列的功能助你觸及更多受眾。花點時間查閱這些設定並確保它符合你的用法。" + privacy: 私隱 + privacy_hint_html: 控制你欲向他人透露的資訊。透過瀏覽他人的追蹤可發現有趣的個人檔案,展示發佈所用的媒介也幫助他人發掘酷炫的應用程式,但你也能選擇隱藏它們。 + reach: 觸及 + reach_hint_html: 控制你是否被使用者發現和追蹤。你希望自己的帖文出現在探索中嗎?想讓他人在追蹤推薦中看到你嗎?自動接受新追蹤者,還是逐一設定? + search: 搜尋 + search_hint_html: 控制你被發現的方式。你想他人從你公開發佈的內容找到你嗎?想讓 Mastodon 以外的人們在網站搜尋中找到你的個人檔案?請注意,公開資訊無法被搜尋引擎全部排除。 + title: 私隱及觸及 privacy_policy: title: 私隱政策 reactions: @@ -1339,7 +1511,11 @@ zh-HK: unrecognized_emoji: 不能識別這個emoji relationships: activity: 帳戶活動 + confirm_follow_selected_followers: 你確定要追蹤選取的追蹤者嗎? + confirm_remove_selected_followers: 你確定要移除選取的追蹤者嗎? + confirm_remove_selected_follows: 你確定要移除選取的追蹤者嗎? dormant: 潛在 + follow_failure: 無法追蹤部份已選的帳號。 follow_selected_followers: 關注所選的追隨者 followers: 追隨者 following: 正在關注 @@ -1379,6 +1555,7 @@ zh-HK: electron: Electron 瀏覽器 firefox: Firefox 瀏覽器 generic: 未知的瀏覽器 + huawei_browser: 華為瀏覽器 ie: Internet Explorer 瀏覽器 micro_messenger: 微信 nokia: Nokia S40 Ovi 瀏覽器 @@ -1388,6 +1565,7 @@ zh-HK: qq: QQ瀏覽器 safari: Safari 瀏覽器 uc_browser: UC 瀏覽器 + unknown_browser: 未知的瀏覽器 weibo: 新浪微博 current_session: 目前的作業階段 description: "%{platform} 上的 %{browser}" @@ -1400,9 +1578,10 @@ zh-HK: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: 未知平台 + unknown_platform: 未知平台 windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1467,7 +1646,6 @@ zh-HK: show_newer: 顯示較新嘟文 show_older: 顯示較舊嘟文 show_thread: 顯示討論串 - sign_in_to_participate: 登入以加入討論 title: "%{name}:「%{quote}」" visibilities: direct: 私人訊息 @@ -1509,12 +1687,10 @@ zh-HK: '7889238': 3 個月 min_age_label: 按時間篩選 min_favs: 保留超過嘟文最愛門檻 - min_favs_hint: 如果您嘟文已收到超過最愛門檻則不會刪除。留白表示不論最愛數量皆刪除嘟文。 + min_favs_hint: 收到此數量或更多最愛的帖文將不會被刪除。 留空可無視最愛數量刪除帖子 min_reblogs: 保留超過嘟文轉嘟門檻 min_reblogs_hint: 如果您嘟文已收到超過轉嘟門檻則不會刪除。留白表示不論轉嘟數量皆刪除嘟文。 stream_entries: - pinned: 置頂文章 - reblogged: 轉推 sensitive_content: 敏感內容 strikes: errors: @@ -1530,6 +1706,10 @@ zh-HK: default: "%Y年%-m月%d日 %H:%M" month: "%b %Y" time: "%H:%M" + translation: + errors: + quota_exceeded: 已超出伺服器範圍的翻譯服務之使用配額。 + too_many_requests: 最近翻譯服務的請求太多。 two_factor_authentication: add: 新增 disable: 停用 @@ -1609,13 +1789,18 @@ zh-HK: title: 歡迎 %{name} 加入! users: follow_limit_reached: 你不能關注多於%{limit} 人 + go_to_sso_account_settings: 前往你身份提供者的帳號設定 invalid_otp_token: 雙重認證碼不正確 otp_lost_help_html: 如果這兩者你均無法登入,你可以聯繫 %{email} seamless_external_login: 因為你正在使用第三方服務登入,所以不能設定密碼和電郵。 signed_in_as: 目前登入的帳戶: verification: - explanation_html: 你可以認證個人資料頁面的元數據 (Metadata) 連結是屬於你的。要認證,那些連結的目的地網站必須有一條回到你 Mastodon 個人頁面的連結,而且連結必須具有rel="me"屬性。連結的文字內容都不會影響認證。這裏有一個例子: + extra_instructions_html: 提示:你是可以隱藏網站上的連結的。重點是rel="me",它可以防止有用戶生成內容的網站假冒身份。你甚至可以在頁面標頭 (header) 使用 link 標籤,而非 a,但你必須確保沒有執行 Javascript 下也可存取 HTML。 + here_is_how: 驗證方法 + hint_html: "所有人都可以在 Mastodon 上驗證身份。基於開放網絡標準,不論是現在還是以後也是免費的。你只需要一個可以識別你的個人網站。當你連接個人檔案到該網站時,我們會檢查該網站是否有反向連結到個人檔案,若成功偵測便會在個人檔案標示它。" + instructions_html: 複製並貼上以下的程式碼到你網站的 HTML 中,然後在個人檔案的「修改個人檔案」頁籤中的額外欄位加入你該網址,並儲存變更。 verification: 驗證 + verified_links: 已驗證的連結 webauthn_credentials: add: 新增安全密鑰裝置 create: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 97169cfde2..33870c0bb2 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -11,10 +11,10 @@ zh-TW: followers: other: 跟隨者 following: 正在跟隨 - instance_actor_flash: 這個帳號是一個用來代表此伺服器的虛擬執行者,而非真實使用者。它用途為聯邦宇宙且不應被停權。 + instance_actor_flash: 此帳號是用來代表此伺服器的虛擬執行者,而非個別使用者。它的用途為維繫聯邦宇宙,且不應被停權。 last_active: 上次活躍時間 link_verified_on: 此連結的所有權已在 %{date} 檢查過 - nothing_here: 暫時沒有內容可供顯示! + nothing_here: 暫時沒有內容可供顯示! pin_errors: following: 您只能推薦您正在跟隨的使用者。 posts: @@ -25,15 +25,15 @@ zh-TW: action: 執行動作 title: 對 %{acct} 執行站務動作 account_moderation_notes: - create: 記錄 - created_msg: 已新增管理備忘! - destroyed_msg: 成功刪除管理備忘! + create: 新增站務記錄 + created_msg: 已成功新增管理備註! + destroyed_msg: 已成功刪除管理備註! accounts: add_email_domain_block: 將電子郵件網域加入黑名單 approve: 批准 - approved_msg: 成功審核了%{username} 的新帳號申請 - are_you_sure: 您確定嗎? - avatar: 頭像 + approved_msg: 已成功審核 %{username} 的新帳號申請 + are_you_sure: 您確定嗎? + avatar: 大頭貼 by_domain: 站點 change_email: changed_msg: 電子郵件已成功變更! @@ -54,7 +54,7 @@ zh-TW: delete: 刪除資料 deleted: 已刪除 demote: 降級 - destroyed_msg: 即將刪除 %{username} 的數據 + destroyed_msg: 即將刪除 %{username} 的資料 disable: 停用 disable_sign_in_token_auth: 停用電子郵件 token 驗證 disable_two_factor_authentication: 停用兩階段認證 @@ -71,7 +71,7 @@ zh-TW: followers: 跟隨者 follows: 正在跟隨 header: 開頭 - inbox_url: 收件箱 (Inbox) URL + inbox_url: 收件匣 (Inbox) URL invite_request_text: 加入原因 invited_by: 邀請者 ip: IP 位址 @@ -82,21 +82,22 @@ zh-TW: remote: 遠端 title: 位置 login_status: 登入狀態 - media_attachments: 多媒體附件 + media_attachments: 多媒體附加檔案 memorialize: 設定為追悼帳號 memorialized: 被悼念的 memorialized_msg: 成功將%{username} 的帳號變為追悼帳號 moderation: active: 活躍 all: 全部 + disabled: 已停用 pending: 等待中 silenced: 受限的 suspended: 已停權 title: 站務 - moderation_notes: 管理備忘 + moderation_notes: 站務備註 most_recent_activity: 最近活動 most_recent_ip: 最近 IP 位址 - no_account_selected: 未選取任何帳號,因此未變更 + no_account_selected: 因未選取任何帳號,所以什麼事都沒發生 no_limits_imposed: 未受限制 no_role_assigned: 未指派角色 not_subscribed: 未訂閱 @@ -112,17 +113,17 @@ zh-TW: redownload: 重新整理個人檔案 redownloaded_msg: 成功重新載入%{username} 的個人檔案頁面 reject: 拒絕 - rejected_msg: 成功拒絕了%{username} 的新帳號申請 + rejected_msg: 已成功婉拒 %{username} 的新帳號申請 remote_suspension_irreversible: 此帳號之資料已被不可逆地刪除。 remote_suspension_reversible_hint_html: 這個帳號已於此伺服器被停權,所有資料將會於 %{date} 被刪除。在此之前,遠端伺服器可以完全回復此的帳號。如果您想即時刪除這個帳號的資料,您可以在下面進行操作。 remove_avatar: 取消大頭貼 remove_header: 移除開頭 - removed_avatar_msg: 成功刪除了 %{username} 的大頭貼 - removed_header_msg: 成功刪除了 %{username} 的封面圖片 + removed_avatar_msg: 已成功刪除 %{username} 的大頭貼 + removed_header_msg: 已成功刪除 %{username} 的封面圖片 resend_confirmation: already_confirmed: 此使用者已被確認 - send: 重新發送驗證信 - success: 驗證信發送成功! + send: 重新傳送確認連結 + success: 已成功傳送確認連結! reset: 重設 reset_password: 重設密碼 resubscribe: 重新訂閱 @@ -130,14 +131,15 @@ zh-TW: search: 搜尋 search_same_email_domain: 其他有同個電子郵件網域的使用者 search_same_ip: 其他有同個 IP 的使用者 + security: 安全性 security_measures: only_password: 僅使用密碼 - password_and_2fa: 密碼及二重因素驗證 - sensitive: 敏感内容 + password_and_2fa: 密碼及兩階段驗證 (2FA) + sensitive: 強制標記為敏感内容 sensitized: 已標記為敏感內容 - shared_inbox_url: 共享收件箱網址 + shared_inbox_url: 共享收件匣 URL show: - created_reports: 建立檢舉 + created_reports: 新增檢舉 targeted_reports: 由其他人檢舉 silence: 靜音 silenced: 已靜音 @@ -146,18 +148,18 @@ zh-TW: subscribe: 訂閱 suspend: 停權 suspended: 已停權 - suspension_irreversible: 已永久刪除這個帳號的數據。雖然這個帳號的數據已被永久刪除,但是您仍然可以取消暫停這個帳號。 - suspension_reversible_hint_html: 這個帳號已被暫停,所有數據將會在 %{date} 被刪除。在此之前,您可以完全回復您的帳號。如果您想即時刪除這個帳號的數據,您可以在下面進行操作。 + suspension_irreversible: 已永久刪除此帳號的資料。您可以取消這個帳號的停權狀態,但無法還原已刪除的資料。 + suspension_reversible_hint_html: 這個帳號已被暫停,所有數據將於 %{date} 被刪除。在此之前,您可以完全回復您的帳號。如果您想即時刪除這個帳號的數據,您可以在下面進行操作。 title: 帳號 unblock_email: 解除封鎖電子郵件地址 unblocked_email_msg: 成功解除封鎖 %{username} 的電子郵件地址 unconfirmed_email: 未確認的電子郵件地址 - undo_sensitized: 取消敏感狀態 + undo_sensitized: 取消強制標記為敏感內容 undo_silenced: 取消靜音 undo_suspension: 取消停權 unsilenced_msg: 成功解除 %{username} 的帳號限制 unsubscribe: 取消訂閱 - unsuspended_msg: 成功取消暫停 %{username} 的帳號 + unsuspended_msg: 已成功取消停權 %{username} 的帳號 username: 使用者名稱 view_domain: 查看站台概要 warn: 警告 @@ -171,23 +173,23 @@ zh-TW: change_email_user: 變更使用者的電子郵件地址 change_role_user: 變更使用者角色 confirm_user: 確認使用者 - create_account_warning: 建立警告 - create_announcement: 建立公告 + create_account_warning: 新增警告 + create_announcement: 新增公告 create_canonical_email_block: 新增 E-mail 封鎖 - create_custom_emoji: 建立自訂顏文字 - create_domain_allow: 建立允許網域 - create_domain_block: 建立阻擋網域 + create_custom_emoji: 新增自訂顏文字 + create_domain_allow: 新增允許網域 + create_domain_block: 新增網域封鎖 create_email_domain_block: 新增電子郵件網域封鎖 create_ip_block: 新增IP規則 create_unavailable_domain: 新增無法存取的網域 - create_user_role: 建立角色 - demote_user: 把用戶降級 + create_user_role: 新增角色 + demote_user: 將用戶降級 destroy_announcement: 刪除公告 destroy_canonical_email_block: 刪除 E-mail 封鎖 destroy_custom_emoji: 刪除自訂顏文字 destroy_domain_allow: 刪除允許網域 - destroy_domain_block: 刪除阻擋網域 - destroy_email_domain_block: 刪除阻擋電郵網域 + destroy_domain_block: 刪除網域封鎖 + destroy_email_domain_block: 刪除電子郵件網域封鎖 destroy_instance: 清除網域 destroy_ip_block: 刪除 IP 規則 destroy_status: 刪除狀態 @@ -201,87 +203,87 @@ zh-TW: enable_sign_in_token_auth_user: 啟用使用者電子郵件 token 驗證 enable_user: 啓用帳號 memorialize_account: 設定成追悼帳號 - promote_user: 把用戶升級 + promote_user: 將用戶升級 reject_appeal: 駁回申訴 reject_user: 回絕使用者 remove_avatar_user: 刪除大頭貼 - reopen_report: 重開舉報 + reopen_report: 重新開啟檢舉報告 resend_user: 重新發送驗證信 reset_password_user: 重設密碼 - resolve_report: 消除舉報 - sensitive_account: 把您的帳號的媒體標記為敏感內容 + resolve_report: 解決檢舉報告 + sensitive_account: 將媒體強制標記為敏感內容 silence_account: 靜音帳號 suspend_account: 停權帳號 - unassigned_report: 取消指派舉報 + unassigned_report: 取消指派檢舉報告 unblock_email_account: 解除封鎖電子郵件地址 - unsensitive_account: 取消把您的帳號的媒體設定為敏感內容 + unsensitive_account: 取消將媒體強制標記為敏感內容 unsilence_account: 取消帳號的靜音狀態 unsuspend_account: 取消帳號的暫停狀態 update_announcement: 更新公告 update_custom_emoji: 更新自訂顏文字 - update_domain_block: 更新封鎖網域 + update_domain_block: 更新網域封鎖 update_ip_block: 更新 IP 規則 update_status: 更新狀態 update_user_role: 更新角色 actions: - approve_appeal_html: "%{name} 批准了來自 %{target} 的審核決定申訴" - approve_user_html: "%{name} 批准了從 %{target} 而來的註冊" + approve_appeal_html: "%{name} 已批准來自 %{target} 的審核決定申訴" + approve_user_html: "%{name} 已批准從 %{target} 而來的註冊" assigned_to_self_report_html: "%{name} 將報告 %{target} 指派給自己" - change_email_user_html: "%{name} 變更了使用者 %{target} 的電子郵件地址" - change_role_user_html: "%{name} 變更了 %{target} 的角色" - confirm_user_html: "%{name} 確認了使用者 %{target} 的電子郵件位址" + change_email_user_html: "%{name} 已變更使用者 %{target} 的電子郵件地址" + change_role_user_html: "%{name} 已變更 %{target} 的角色" + confirm_user_html: "%{name} 已確認使用者 %{target} 的電子郵件位址" create_account_warning_html: "%{name} 已對 %{target} 送出警告" - create_announcement_html: "%{name} 新增了公告 %{target}" - create_canonical_email_block_html: "%{name} 已封鎖了 hash 為 %{target} 之 e-mail" - create_custom_emoji_html: "%{name} 上傳了新自訂表情符號 %{target}" + create_announcement_html: "%{name} 已新增公告 %{target}" + create_canonical_email_block_html: "%{name} 已封鎖 hash 為 %{target} 的 e-mail" + create_custom_emoji_html: "%{name} 已上傳新自訂表情符號 %{target}" create_domain_allow_html: "%{name} 允許 %{target} 網域加入聯邦宇宙" - create_domain_block_html: "%{name} 封鎖了網域 %{target}" - create_email_domain_block_html: "%{name} 封鎖了電子郵件網域 %{target}" - create_ip_block_html: "%{name} 已經設定了IP %{target} 的規則" + create_domain_block_html: "%{name} 已封鎖網域 %{target}" + create_email_domain_block_html: "%{name} 已封鎖電子郵件網域 %{target}" + create_ip_block_html: "%{name} 已設定 IP %{target} 的規則" create_unavailable_domain_html: "%{name} 停止發送至網域 %{target}" - create_user_role_html: "%{name} 建立了 %{target} 角色" + create_user_role_html: "%{name} 已新增 %{target} 角色" demote_user_html: "%{name} 將使用者 %{target} 降級" - destroy_announcement_html: "%{name} 刪除了公告 %{target}" - destroy_canonical_email_block_html: "%{name} 取消了 hash 為 %{target} 之 e-mail 的封鎖" - destroy_custom_emoji_html: "%{name} 刪除了表情符號 %{target}" + destroy_announcement_html: "%{name} 已刪除公告 %{target}" + destroy_canonical_email_block_html: "%{name} 已解除封鎖 hash 為 %{target} 的電子郵件" + destroy_custom_emoji_html: "%{name} 已刪除表情符號 %{target}" destroy_domain_allow_html: "%{name} 不允許與網域 %{target} 加入聯邦宇宙" - destroy_domain_block_html: "%{name} 取消了對網域 %{target} 的封鎖" - destroy_email_domain_block_html: "%{name} 取消了對電子郵件網域 %{target} 的封鎖" - destroy_instance_html: "%{name} 清除了網域 %{target}" - destroy_ip_block_html: "%{name} 刪除了 IP %{target} 的規則" - destroy_status_html: "%{name} 刪除了 %{target} 的嘟文" - destroy_unavailable_domain_html: "%{name} 恢復了對網域 %{target} 的發送" - destroy_user_role_html: "%{name} 刪除了 %{target} 角色" - disable_2fa_user_html: "%{name} 停用了使用者 %{target} 的兩階段認證" - disable_custom_emoji_html: "%{name} 停用了自訂表情符號 %{target}" - disable_sign_in_token_auth_user_html: "%{name} 停用了 %{target} 之使用者電子郵件 token 驗證" + destroy_domain_block_html: "%{name} 已解除封鎖網域 %{target}" + destroy_email_domain_block_html: "%{name} 已解除封鎖電子郵件網域 %{target}" + destroy_instance_html: "%{name} 已清除網域 %{target}" + destroy_ip_block_html: "%{name} 已刪除 IP %{target} 的規則" + destroy_status_html: "%{name} 已刪除 %{target} 的嘟文" + destroy_unavailable_domain_html: "%{name} 已恢復對網域 %{target} 的發送" + destroy_user_role_html: "%{name} 已刪除 %{target} 角色" + disable_2fa_user_html: "%{name} 已停用使用者 %{target} 的兩階段認證 (2FA) " + disable_custom_emoji_html: "%{name} 已停用自訂表情符號 %{target}" + disable_sign_in_token_auth_user_html: "%{name} 已停用 %{target} 之使用者電子郵件 token 驗證" disable_user_html: "%{name} 將使用者 %{target} 設定為禁止登入" - enable_custom_emoji_html: "%{name} 啟用了自訂表情符號 %{target}" - enable_sign_in_token_auth_user_html: "%{name} 啟用了 %{target} 之使用者電子郵件 token 驗證" + enable_custom_emoji_html: "%{name} 已啟用自訂表情符號 %{target}" + enable_sign_in_token_auth_user_html: "%{name} 已啟用 %{target} 之使用者電子郵件 token 驗證" enable_user_html: "%{name} 將使用者 %{target} 設定為允許登入" memorialize_account_html: "%{name} 將 %{target} 設定為追悼帳號" - promote_user_html: "%{name} 對使用者 %{target} 進行了晉級操作" - reject_appeal_html: "%{name} 回絕了來自 %{target} 的審核決定申訴" - reject_user_html: "%{name} 回絕了從 %{target} 而來的註冊" - remove_avatar_user_html: "%{name} 移除了 %{target} 的大頭貼" + promote_user_html: "%{name} 對使用者 %{target} 已進行晉級操作" + reject_appeal_html: "%{name} 已回絕來自 %{target} 的審核決定申訴" + reject_user_html: "%{name} 已回絕從 %{target} 而來的註冊" + remove_avatar_user_html: "%{name} 已移除 %{target} 的大頭貼" reopen_report_html: "%{name} 重新開啟 %{target} 的檢舉" resend_user_html: "%{name} 已重新發送驗證信給 %{target}" - reset_password_user_html: "%{name} 重新設定了使用者 %{target} 的密碼" - resolve_report_html: "%{name} 處理了 %{target} 的檢舉" + reset_password_user_html: "%{name} 已重新設定使用者 %{target} 的密碼" + resolve_report_html: "%{name} 已處理 %{target} 的檢舉" sensitive_account_html: "%{name} 將 %{target} 的媒體檔案標記為敏感內容" - silence_account_html: "%{name} 靜音了使用者 %{target}" - suspend_account_html: "%{name} 停權了使用者 %{target}" + silence_account_html: "%{name} 已靜音使用者 %{target}" + suspend_account_html: "%{name} 已停權 %{target} 的帳號" unassigned_report_html: "%{name} 取消指派 %{target} 的檢舉" - unblock_email_account_html: "%{name} 解除封鎖了 %{target} 的電子郵件地址" - unsensitive_account_html: "%{name} 將 %{target} 的媒體檔案的敏感狀態取消" - unsilence_account_html: "%{name} 取消了使用者 %{target} 的靜音狀態" - unsuspend_account_html: "%{name} 取消了使用者 %{target} 的停權狀態" - update_announcement_html: "%{name} 更新了公告 %{target}" - update_custom_emoji_html: "%{name} 更新了自訂表情符號 %{target}" - update_domain_block_html: "%{name} 更新了 %{target} 之網域封鎖" - update_ip_block_html: "%{name} 已經更新了 IP %{target} 之規則" - update_status_html: "%{name} 更新了 %{target} 的嘟文" - update_user_role_html: "%{name} 變更了 %{target} 角色" + unblock_email_account_html: "%{name} 已解除封鎖 %{target} 的電子郵件地址" + unsensitive_account_html: "%{name} 將 %{target} 的媒體檔案取消標記為敏感內容" + unsilence_account_html: "%{name} 已取消使用者 %{target} 的靜音狀態" + unsuspend_account_html: "%{name} 已取消停權 %{target} 的帳號" + update_announcement_html: "%{name} 已更新公告 %{target}" + update_custom_emoji_html: "%{name} 已更新自訂表情符號 %{target}" + update_domain_block_html: "%{name} 已更新 %{target} 之網域封鎖" + update_ip_block_html: "%{name} 已變更 IP %{target} 之規則" + update_status_html: "%{name} 已更新 %{target} 的嘟文" + update_user_role_html: "%{name} 已變更 %{target} 角色" deleted_account: 已刪除帳號 empty: 找不到 log filter_by_action: 按動作過濾 @@ -294,7 +296,7 @@ zh-TW: empty: 找不到公告。 live: 直播 new: - create: 建立公告 + create: 新增公告 title: 新增公告 publish: 發布 published_msg: 成功發布公告! @@ -304,29 +306,30 @@ zh-TW: unpublish: 取消發布 unpublished_msg: 成功取消發布公告! updated_msg: 成功更新公告! + critical_update_pending: 重要更新待升級 custom_emojis: assign_category: 指定分類 by_domain: 站點 - copied_msg: 成功將表情複製到本地 + copied_msg: 成功建立 emoji 表情符號之本地備份 copy: 複製 copy_failed_msg: 無法將表情複製到本地 create_new_category: 建立新分類 - created_msg: 已新增表情符號! + created_msg: 已新增表情符號! delete: 刪除 - destroyed_msg: 已刪除表情符號! + destroyed_msg: 已刪除表情符號! disable: 停用 disabled: 已停用 - disabled_msg: 已停用表情符號 + disabled_msg: 已停用該表情符號 emoji: 表情符號 enable: 啟用 enabled: 已啟用 - enabled_msg: 已啟用表情符號 + enabled_msg: 已啟用該表情符號 image_hint: 檔案大小最大至 %{size} 之 PNG 或 GIF list: 列表 listed: 已顯示 new: title: 加入新的自訂表情符號 - no_emoji_selected: 未選取任何 emoji,因此未變更 + no_emoji_selected: 未選取任何 emoji,所以什麼事都沒發生 not_permitted: 您無權執行此操作 overwrite: 覆蓋 shortcode: 短代碼 @@ -336,7 +339,7 @@ zh-TW: unlist: 不公開 unlisted: 已隱藏 update_failed_msg: 無法更新表情符號 - updated_msg: 已更新表情符號! + updated_msg: 已更新表情符號! upload: 上傳新的表情符號 dashboard: active_users: 活躍使用者 @@ -372,13 +375,22 @@ zh-TW: import: 匯入 undo: 從聯邦宇宙白名單移除 domain_blocks: - add_new: 新增欲封鎖域名 + add_new: 新增網域黑名單 + confirm_suspension: + cancel: 取消 + confirm: 停權 + permanent_action: 撤銷停權將不會回復任何資料或跟隨關係 + preamble_html: 您將要停權 %{domain} 及其子網域。 + remove_all_data: 此操作將從您伺服器移除所有來自此網域帳號之內容、媒體、個人檔案資料。 + stop_communication: 您伺服器將停止與這些伺服器交流。 + title: 確認對 %{domain} 網域之封鎖 + undo_relationships: 此操作將撤銷任何您伺服器與此伺服器帳號間之跟隨關係。 created_msg: 正在進行網域封鎖 destroyed_msg: 已撤銷網域封鎖 domain: 站點 edit: 更改封鎖的站台 - existing_domain_block: 您已對 %{name} 施加了更嚴格的限制。 - existing_domain_block_html: 您已經對 %{name} 施加了更嚴格的限制,您需要先把他取消封鎖。 + existing_domain_block: 您已對 %{name} 施加更嚴格的限制。 + existing_domain_block_html: 您已對 %{name} 施加更嚴格的限制,您需要先 解除封鎖。 export: 匯出 import: 匯入 new: @@ -389,21 +401,21 @@ zh-TW: noop: 無 silence: 靜音 suspend: 停權 - title: 新增封鎖站點 - no_domain_block_selected: 因未選取項目,而未更改網域黑名單 + title: 新增網域黑名單 + no_domain_block_selected: 因未選取網域黑名單,所以什麼事都沒發生 not_permitted: 您無權執行此操作 obfuscate: 混淆網域名稱 obfuscate_hint: 若啟用網域廣告列表限制,於列表部份混淆網域名稱 private_comment: 私人留言 - private_comment_hint: 請提供更多有關此站台限制的資訊以供版主作內部參考。 + private_comment_hint: 請提供更多有關此站台限制的資訊以供管理員作內部參考。 public_comment: 公開留言 public_comment_hint: 如果您已經啟用站台限制列表的公告,請為一般大眾提供更多有關此站台限制的資訊。 reject_media: 拒絕媒體檔案 reject_media_hint: 刪除本地快取的媒體檔案,並且不再接收來自該站點的任何媒體檔案。與停權無關 reject_reports: 拒絕檢舉 reject_reports_hint: 忽略所有來自此網域的檢舉。與停權無關 - undo: 復原欲封鎖域名 - view: 顯示阻擋的網域 + undo: 撤銷網域封鎖 + view: 顯示已封鎖網域 email_domain_blocks: add_new: 加入新項目 attempts_over_week: @@ -418,7 +430,8 @@ zh-TW: create: 新增網域 resolve: 解析網域 title: 新增電子郵件黑名單項目 - no_email_domain_block_selected: 因未選取項目,而未更改電子郵件網域黑名單 + no_email_domain_block_selected: 因未選取電子郵件網域黑名單,所以什麼事都沒發生 + not_permitted: 無權限 resolved_dns_records_hint_html: 網域名稱解析為以下 MX 網域,這些網域最終負責接收電子郵件。封鎖 MX 網域將會封鎖任何來自使用相同 MX 網域的電子郵件註冊,即便可見的域名是不同的也一樣。請注意,不要封鎖主要的電子郵件服務提供商。 resolved_through_html: 透過 %{domain} 解析 title: 電子郵件黑名單 @@ -439,7 +452,7 @@ zh-TW: no_file: 尚未選擇檔案 follow_recommendations: description_html: |- - 跟隨建議幫助新使用者們快速找到有趣的內容. 當使用者沒有與其他帳號有足夠多的互動以建立個人化跟隨建議時,這些帳號將會被推荐。這些帳號將基於某選定語言之高互動和高本地跟隨者數量帳號而 + 跟隨建議幫助新使用者們快速找到有趣的內容。當使用者沒有與其他帳號有足夠多的互動以建立個人化跟隨建議時,這些帳號將會被推薦。這些帳號將基於某選定語言之高互動和高本地跟隨者數量帳號而 每日重新更新。 language: 對於語言 status: 狀態 @@ -465,6 +478,7 @@ zh-TW: content_policies: comment: 內部備註 description_html: 您可以定義對所有此網域帳號及其子網域所實施之內容政策。 + limited_federation_mode_description_html: 您可以選擇是否允許此網域加入聯邦宇宙。 policies: reject_media: 拒絕多媒體 reject_reports: 拒絕檢舉 @@ -508,8 +522,8 @@ zh-TW: total_blocked_by_us: 被我們封鎖 total_followed_by_them: 被他們跟隨 total_followed_by_us: 被我們跟隨 - total_reported: 關於他們的舉報 - total_storage: 多媒體附檔 + total_reported: 關於他們的檢舉報告 + total_storage: 多媒體附加檔案 totals_time_period_hint_html: 以下顯示之總和包含所有時間的資料。 invites: deactivate_all: 全部停用 @@ -532,7 +546,7 @@ zh-TW: '94670856': 3 年 new: title: 建立新的 IP 規則 - no_ip_block_selected: 因為沒有選擇任何 IP 規則,所以什麼事都沒發生 + no_ip_block_selected: 因未選取任何 IP 規則,所以什麼事都沒發生 title: IP 規則 relationships: title: "%{acct} 的關係" @@ -545,7 +559,7 @@ zh-TW: enable: 啟用 enable_hint: 啟用後,您的伺服器將訂閱該中繼的所有公開文章,並將會此伺服器的公開文章發送給它。 enabled: 已啟用 - inbox_url: 中繼URL + inbox_url: 中繼 URL pending: 等待中繼站審核 save_and_enable: 儲存並啟用 setup: 設定中繼連結 @@ -553,8 +567,8 @@ zh-TW: status: 狀態 title: 中繼 report_notes: - created_msg: 檢舉記錄建立成功! - destroyed_msg: 檢舉記錄刪除成功! + created_msg: 已成功新增檢舉備註! + destroyed_msg: 已成功刪除檢舉備註! reports: account: notes: @@ -571,15 +585,17 @@ zh-TW: actions_description_html: 決定應對此報告採取何種行動。若您對檢舉之帳號採取懲罰措施,則將對他們發送 e-mail 通知,如非選擇了 垃圾郵件 類別。 actions_description_remote_html: 決定將對此檢舉報告採取何種動作。這將僅作用於您的伺服器與此遠端帳號及其內容之通訊行為。 add_to_report: 加入更多至報告 - are_you_sure: 您確定嗎? + are_you_sure: 您確定嗎? assign_to_self: 指派給自己 - assigned: 指派負責人 + assigned: 指派站務 by_target_domain: 檢舉帳號之網域 + cancel: 取消 category: 分類 category_description_html: 此帳號及/或被檢舉內容之原因會被引用在檢舉帳號通知中 comment: none: 無 comment_description_html: 提供更多資訊,%{name} 寫道: + confirm: 確認 confirm_action: 確認對 @%{acct} 執行站務動作 created_at: 日期 delete_and_resolve: 刪除嘟文 @@ -590,13 +606,13 @@ zh-TW: mark_as_unresolved: 標記為「未解決」 no_one_assigned: 沒有人 notes: - create: 建立記錄 - create_and_resolve: 建立記錄並標記為「已解決」 - create_and_unresolve: 建立記錄並標記「未解決」 + create: 新增備註 + create_and_resolve: 新增備註並標記為「已解決」 + create_and_unresolve: 新增備註並標記「未解決」 delete: 刪除 placeholder: 記錄已執行的動作,或其他相關的更新... - title: 註記 - notes_description_html: 檢視及留下些給其他管理員和未來的自己的註記 + title: 備註 + notes_description_html: 檢視及留下些給其他管理員和未來的自己的備註 processed_msg: '檢舉報告 #%{id} 已被成功處理' quick_actions_description_html: 採取一個快速行動,或者下捲以檢視檢舉內容: remote_user_placeholder: 來自 %{instance} 之遠端使用者 @@ -605,7 +621,7 @@ zh-TW: reported_account: 被檢舉使用者 reported_by: 檢舉人 resolved: 已解決 - resolved_msg: 檢舉已處理! + resolved_msg: 檢舉報告已處理完成! skip_to_actions: 跳過行動 status: 嘟文 statuses: 被檢舉的內容 @@ -615,12 +631,12 @@ zh-TW: delete_html: 您將要 移除 某些 @%{acct} 之嘟文。此將會: mark_as_sensitive_html: 您將要 標記 某些 @%{acct} 之嘟文為 敏感內容 。此將會: silence_html: 您將要 限制 @%{acct} 之帳號。此將會: - suspend_html: 您將要 暫停 @%{acct} 之帳號。此將會: + suspend_html: 您將要 停權 @%{acct} 之帳號。此將會: actions: delete_html: 移除違反規則之嘟文 mark_as_sensitive_html: 將違反規則之嘟文多媒體標記為敏感內容 silence_html: 藉由標記他們的個人檔案與內容為僅可見於已跟隨帳號或手動查詢此個人檔案,此將嚴格地限制 @%{acct} 之觸及率 - suspend_html: 暫停 @%{acct},將他們的個人檔案與內容標記為無法存取及無法與之互動 + suspend_html: 停權 @%{acct},將他們的個人檔案與內容標記為無法存取及無法與之互動 close_report: '將檢舉報告 #%{id} 標記為已處理' close_reports_html: 將 所有 對於 @%{acct} 之檢舉報告標記為已處理 delete_data_html: 於即日起 30 天後刪除 @%{acct}之個人檔案與內容,除非他們於期限前被解除暫停 @@ -713,6 +729,11 @@ zh-TW: branding: preamble: 您的伺服器品牌使之從聯邦宇宙網路中其他伺服器間凸顯自己。此資訊可能於各種不同的環境中顯示,例如 Mastodon 網頁介面、原生應用程式、其他網頁上的連結預覽或是其他通訊應用程式等等。因此,請盡可能保持此資訊簡潔明朗。 title: 品牌化 + captcha_enabled: + desc_html: |- + 此功能依賴於來自 hCaptcha 之外部腳本,其可能有安全及隱私顧慮。 + 此外,這將大幅降低註冊流程對某些族群之易用性,特別是無障礙需求人士。基於此因,請考慮其他替代性方案,例如審核制或是邀請制之註冊流程。 + title: 要求新使用者完成 CAPTCHA 挑戰以確認帳號 content_retention: preamble: 控制使用者產生內容如何儲存於 Mastodon 上。 title: 內容保留期間 @@ -740,10 +761,27 @@ zh-TW: approved: 註冊需要核准 none: 沒有人可註冊 open: 任何人皆能註冊 + security: + authorized_fetch: 要求自聯邦宇宙伺服器之驗證 + authorized_fetch_hint: 要求聯邦宇宙伺服器進行驗證將更嚴格地執行使用者層級及伺服器層級之封鎖。然而,這將會帶來一些性能損失、減少您的回嘟觸及量、並可能會引入與某些聯邦宇宙伺服器之相容性問題。 此外,這無法阻止專門服務抓取您的公開嘟文及帳號資料。 + authorized_fetch_overridden_hint: 由於環境變數之設定值覆寫,您目前無法變更此設定。 + federation_authentication: 強制聯邦宇宙伺服器驗證 title: 伺服器設定 site_uploads: delete: 刪除上傳的檔案 destroyed_msg: 成功刪除站台的上傳項目! + software_updates: + critical_update: 重要 — 請儘速升級 + description: 建議將您的 Mastodon 伺服器升級至最新狀態,以獲得最新錯誤修正及功能更新。此外,即時更新 Mastodon 以避免偶發之安全問題非常重要。因此,Mastodon 每 30 分鐘將檢查一次更新,並依據您的電子郵件通知設定通知您。 + documentation_link: 了解更多 + release_notes: 版本資訊 + title: 可取得的更新 + type: 類型 + types: + major: 主要版本更新 (major release) + minor: 次要版本更新 (minor release) + patch: 修正版本 (patch release) — 錯誤修正及易於套用之變更 + version: 版本 statuses: account: 作者 application: 應用程式 @@ -760,7 +798,7 @@ zh-TW: media: title: 媒體檔案 metadata: 詮釋資料 - no_status_selected: 因未選擇嘟文而未變更。 + no_status_selected: 因未選取嘟文,所以什麼事都沒發生。 open: 公開嘟文 original_status: 原始嘟文 reblogs: 轉嘟 @@ -771,28 +809,55 @@ zh-TW: with_media: 含有媒體檔案 strikes: actions: - delete_statuses: "%{name} 刪除了 %{target} 的嘟文" - disable: "%{name} 凍結了 %{target} 的帳號" + delete_statuses: "%{name} 已刪除 %{target} 的嘟文" + disable: "%{name} 已凍結 %{target} 的帳號" mark_statuses_as_sensitive: "%{name} 將 %{target} 的嘟文標記為敏感內容" none: "%{name} 已對 %{target} 送出警告" sensitive: "%{name} 將 %{target} 的帳號標記為含有敏感內容" - silence: "%{name} 限制了 %{target} 的帳號" - suspend: "%{name} 將 %{target} 的帳號停權" + silence: "%{name} 已限制 %{target} 的帳號" + suspend: "%{name} 已將 %{target} 的帳號停權" appeal_approved: 已申訴 appeal_pending: 申訴待審中 + appeal_rejected: 申訴被駁回 system_checks: database_schema_check: - message_html: 有挂起的数据库迁移,请运行它们以确保应用程序按照预期运行。 + message_html: 發現尚待處理的資料庫遷移 (database migration)。請執行它們以確保應用程式如期運行。 + elasticsearch_health_red: + message_html: Elasticsearch 叢集健康狀態異常 (紅色),無法提供搜尋功能 + elasticsearch_health_yellow: + message_html: Elasticsearch 叢集健康狀態異常 (黃色),您可能想進一步調查原因 + elasticsearch_index_mismatch: + message_html: Elasticsearch 索引對應 (index mappings) 已過期。請執行 tootctl search deploy --only=%{value} + elasticsearch_preset: + action: 檢視文件 + message_html: 您的 Elasticsaerch 叢集由多個節點構成,但 Mastodon 並沒有設定使用它們。 + elasticsearch_preset_single_node: + action: 檢視文件 + message_html: 您的 Elasticsearch 叢集只有一個節點,ES_PRESET 應設定為 single_node_cluster。 + elasticsearch_reset_chewy: + message_html: 您的 Elasticsearch 系統索引 (index) 已過期並需執行設定變更。請執行 tootctl search deploy --reset-chewy 以更新它。 elasticsearch_running_check: message_html: 無法連接 Elasticsearch。請檢查是否正在執行中,或者已關閉全文搜尋。 elasticsearch_version_check: message_html: 不相容的 Elasticsearch 版本:%{value} version_comparison: Elasticsearch %{running_version} 版正在執行,需要 %{required_version} 版。 rules_check: - action: 管理服务器规则 - message_html: 您没有定義任何伺服器規則。 + action: 管理伺服器規則 + message_html: 您尚未定義任何伺服器規則。 sidekiq_process_check: message_html: 沒有佇列 %{value} 的 Sidekiq 行程,請檢查您的 Sidekiq 設定組態 + software_version_critical_check: + action: 檢視可取得的更新 + message_html: 有可取得的重要 Mastodon 更新,請立即升級。 + software_version_patch_check: + action: 檢視可取得的更新 + message_html: 有可取得的 Mastodon 錯誤修正更新。 + upload_check_privacy_error: + action: 檢查這裡以取得更多資訊 + message_html: "您的網頁伺服器設定錯誤。您的使用者隱私正暴露於風險之中。" + upload_check_privacy_error_object_storage: + action: 檢查這裡以取得更多資訊 + message_html: "您的物件資料儲存空間 (object storage) 設定錯誤。您的使用者隱私正暴露於風險之中。" tags: review: 審核嘟文 updated_msg: 成功更新主題標籤設定 @@ -807,13 +872,14 @@ zh-TW: description_html: 這些連結是正在被您伺服器上看到該嘟文之帳號大量分享。這些連結可以幫助您的使用者探索現在世界上正在發生的事情。除非您核准該發行者,連結將不被公開展示。您也可以核准或駁回個別連結。 disallow: 不允許連結 disallow_provider: 不允許發行者 - no_link_selected: 未選取任何鏈結,因此未變更 + no_link_selected: 因未選取任何連結,所以什麼事都沒發生 publishers: - no_publisher_selected: 未選取任何發行者,因此未變更 + no_publisher_selected: 因未選取任何發行者,所以什麼事都沒發生 shared_by_over_week: other: 上週被 %{count} 名使用者分享 title: 熱門連結 usage_comparison: 於今日被 %{today} 人分享,相較於昨日 %{yesterday} 人 + not_allowed_to_trend: 不允許登上熱門 only_allowed: 僅允許 pending_review: 等待審核中 preview_card_providers: @@ -828,7 +894,7 @@ zh-TW: description_html: 這些是您伺服器上已知被正在大量分享及加入最愛之嘟文。這些嘟文能幫助您伺服器上舊雨新知發現更多帳號來跟隨。除非您核准該作者且作者允許他們的帳號被推薦至其他人,嘟文將不被公開展示。您可以核准或駁回個別嘟文。 disallow: 不允許嘟文 disallow_account: 不允許作者 - no_status_selected: 未選取任何熱門嘟文,因此未變更 + no_status_selected: 因未選取任何熱門嘟文,所以什麼事都沒發生 not_discoverable: 嘟文作者選擇不被發現 shared_by: other: 分享過或/及收藏過 %{friendly_count} 次 @@ -843,7 +909,7 @@ zh-TW: tag_uses_measure: 總使用次數 description_html: 這些主題標籤正在您的伺服器上大量嘟文中出現。這些主題標籤能幫助您的使用者發現人們正集中討論的內容。除非您核准,主題標籤將不被公開展示。 listable: 能被建議 - no_tag_selected: 未選取任何主題標籤,因此未變更 + no_tag_selected: 因未選取任何主題標籤,所以什麼事都沒發生 not_listable: 不能被建議 not_trendable: 不會登上熱門 not_usable: 不可被使用 @@ -861,7 +927,7 @@ zh-TW: add_new: 新增 delete: 刪除 edit_preset: 編輯預設警告 - empty: 您未曾定義任何預設警告 + empty: 您尚未定義任何預設警告。 title: 管理預設警告 webhooks: add_new: 新增端點 @@ -895,13 +961,19 @@ zh-TW: body: "%{target} 正在就 %{date} 的 %{action_taken_by} 做出的審核決定提出申訴,該決定是 %{type}。他們寫道:" next_steps: 您可以批准申訴以還原審核決定,或是忽略它。 subject: "%{username} 正在申訴 %{instance} 上的審核決定" + new_critical_software_updates: + body: 有可取得的重要 Mastodon 新版本,請立即升級! + subject: "%{instance} 有可取得的重要 Mastodon 更新!" new_pending_account: body: 以下是新帳號的詳細資訊。您可以同意或拒絕這項申請。 subject: "%{instance} 上有新帳號 (%{username}) 待審核" new_report: - body: "%{reporter} 檢舉了使用者 %{target}" - body_remote: 來自 %{domain} 的使用者檢舉了使用者 %{target} + body: "%{reporter} 已檢舉使用者 %{target}" + body_remote: 來自 %{domain} 的使用者已檢舉使用者 %{target} subject: 來自 %{instance} 的使用者檢舉(#%{id}) + new_software_updates: + body: Mastodon 新版本已發佈,您可能想升級! + subject: "%{instance} 有可取得的 Mastodon 新版本!" new_trends: body: 以下項目需要經過審核才能公開顯示: new_trending_links: @@ -922,7 +994,7 @@ zh-TW: remove: 取消連結別名 appearance: advanced_web_interface: 進階網頁介面 - advanced_web_interface_hint: 進階網頁界面可讓您設定許多不同的欄位來善用螢幕空間,依需要同時查看許多不同的資訊如:首頁、通知、聯邦時間軸、任意數量的列表和主題標籤。 + advanced_web_interface_hint: 進階網頁介面可讓您設定許多不同的欄位來善用螢幕空間,依需要同時查看許多不同的資訊如:首頁、通知、聯邦宇宙時間軸、任意數量的列表和主題標籤。 animations_and_accessibility: 動畫與無障礙設定 confirmation_dialogs: 確認對話框 discovery: 探索 @@ -931,33 +1003,37 @@ zh-TW: guide_link: https://crowdin.com/project/mastodon guide_link_text: 每個人都能貢獻。 sensitive_content: 敏感內容 - toot_layout: 嘟文排版 application_mailer: notification_preferences: 變更電子郵件設定 salutation: "%{name}、" settings: 變更電子郵件設定︰%{link} - view: '進入瀏覽:' + unsubscribe: 取消訂閱 + view: 進入瀏覽: view_profile: 檢視個人檔案 view_status: 檢視嘟文 applications: - created: 已建立應用 - destroyed: 已刪除應用 - regenerate_token: 重設 token - token_regenerated: 已重設 token - warning: 警告,不要把它分享給任何人! + created: 已建立應用程式 + destroyed: 已刪除應用程式 + logout: 登出 + regenerate_token: 重新產生存取 token + token_regenerated: 已重新產生存取 token + warning: 警告,不要將它分享給任何人! your_token: 您的 access token auth: apply_for_account: 申請帳號 - change_password: 密碼 + captcha_confirmation: + help_html: 若您完成 CAPTCHA 挑戰時遇到問題,您可藉由 %{email} 與我們聯繫,我們將提供協助。 + hint_html: 僅再一步!我們必須確認您是位人類(這是防止垃圾訊息濫用)。請完成以下 CAPTCHA 挑戰並點擊「繼續」。 + title: 安全性檢查 confirmations: wrong_email_hint: 若電子郵件地址不正確,您可以於帳號設定中更改。 delete_account: 刪除帳號 delete_account_html: 如果您欲刪除您的帳號,請點擊這裡繼續。您需要再三確認您的操作。 description: prefix_invited_by_user: "@%{name} 邀請您加入這個 Mastodon 伺服器!" - prefix_sign_up: 現在就註冊 Mastodon 帳號吧! + prefix_sign_up: 馬上註冊 Mastodon 帳號吧! suffix: 有了帳號,就可以從任何 Mastodon 伺服器跟隨任何人、發發廢嘟,並且與任何 Mastodon 伺服器的使用者交流,以及更多! - didnt_get_confirmation: 沒有收到驗證信? + didnt_get_confirmation: 沒有收到確認連結嗎? dont_have_your_security_key: 找不到您的安全金鑰? forgot_password: 忘記密碼? invalid_reset_password_token: 密碼重設 token 無效或已過期。請重新設定密碼。 @@ -970,49 +1046,50 @@ zh-TW: migrate_account_html: 如果您希望引導他人跟隨另一個帳號,請 到這裡設定。 or_log_in_with: 或透過其他方式登入 privacy_policy_agreement_html: 我已閱讀且同意 隱私權政策 + progress: + confirm: 確認電子郵件 + details: 您的個人資料 + review: 我們的審核 + rules: 接受規則 providers: cas: CAS saml: SAML register: 註冊 registration_closed: "%{instance} 現在不開放新成員" - resend_confirmation: 重新寄送確認指引 + resend_confirmation: 重新傳送確認連結 reset_password: 重設密碼 rules: + accept: 接受 + back: 上一頁 + invited_by: 您可以藉由來自此處之邀請而加入 %{domain} preamble: 這些被 %{domain} 的管管們制定以及實施。 + preamble_invited: 在您繼續之前,請考慮由 %{domain} 管理員設立的伺服器規則。 title: 一些基本守則。 + title_invited: 我們誠摯地邀請您。 security: 登入資訊 set_new_password: 設定新密碼 setup: - email_below_hint_html: 如果此電子郵件地址不正確,您可於此修改並接收郵件進行認證。 - email_settings_hint_html: 請確認 e-mail 是否傳送到 %{email} 。如果不對的話,可以從帳號設定修改。 - title: 設定 + email_below_hint_html: 請檢查您的垃圾郵件資料夾,或是請求另一個。如果是錯的,您可以更正您的電子郵件地址。 + email_settings_hint_html: 請點擊我們寄給您連結以驗證 %{email}。我們將於此稍候。 + link_not_received: 無法取得連結嗎? + new_confirmation_instructions_sent: 您將會在幾分鐘之內收到新的包含確認連結的電子郵件! + title: 請檢查您的收件匣 sign_in: - preamble_html: 請登入您於 %{domain} 之帳號密碼。若您的帳號託管於其他伺服器,您將無法於此登入。 + preamble_html: 請使用您於 %{domain} 的帳號密碼登入。若您的帳號託管於其他伺服器,您將無法在此登入。 title: 登入 %{domain} sign_up: + manual_review: "%{domain} 上的註冊由我們的管理員進行人工審核。為協助我們處理您的註冊,請寫一些關於您自己的資訊以及您想要在 %{domain} 上註冊帳號的原因。" preamble: 於此 Mastodon 伺服器擁有帳號的話,您將能跟隨聯邦宇宙網路中任何一份子,無論他們的帳號託管於何處。 title: 讓我們一起設定 %{domain} 吧! status: account_status: 帳號狀態 confirming: 等待電子郵件確認完成。 functional: 您的帳號可以正常使用了。 - pending: 管管們正在處理您的申請,這可能需要一點時間處理。我們將在申請通過後以電子郵件方式通知您。 + pending: 管管們正在處理您的申請,這可能需要一點時間處理。我們將於申請通過後以電子郵件方式通知您。 redirecting_to: 您的帳號因目前重定向至 %{acct} 而被停用。 view_strikes: 檢視針對您帳號過去的警示 too_fast: 送出表單的速度太快跟不上,請稍後再試。 use_security_key: 使用安全金鑰 - authorize_follow: - already_following: 您已經跟隨了這個使用者 - already_requested: 您早已向該帳號寄送跟隨請求 - error: 對不起,搜尋其他站點使用者出現錯誤 - follow: 跟隨 - follow_request: 跟隨請求已發送給: - following: 成功!您正在跟隨: - post_follow: - close: 您可以直接關閉此頁面。 - return: 顯示個人檔案 - web: 返回本站 - title: 跟隨 %{acct} challenge: confirm: 繼續 hint_html: "温馨小提醒: 我們在接下來一小時內不會再要求您輸入密碼。" @@ -1088,11 +1165,15 @@ zh-TW: your_appeal_pending: 您已遞交申訴 your_appeal_rejected: 您的申訴已被駁回 domain_validator: - invalid_domain: 並非一個有效域名 + invalid_domain: 並非一個有效網域 + edit_profile: + basic_information: 基本資訊 + hint_html: "自訂人們可以於您個人檔案及嘟文內容。當您完成填寫個人檔案以及設定大頭貼後,其他人們比較願意跟隨您並與您互動。" + other: 其他 errors: '400': 您所送出的請求無效或格式不正確。 '403': 您沒有檢視這個頁面的權限。 - '404': 您所尋找的網頁不存在。 + '404': 您要找的頁面不存在。 '406': 此頁面無法以請求的格式顯示。 '410': 您所尋找的網頁此處已不存在。 '422': @@ -1118,15 +1199,15 @@ zh-TW: blocks: 您封鎖的使用者 bookmarks: 書籤 csv: CSV - domain_blocks: 域名封鎖 + domain_blocks: 網域封鎖 lists: 列表 mutes: 您靜音的使用者 - storage: 儲存空間大小 + storage: 匯出檔案大小 featured_tags: add_new: 新增 errors: - limit: 您所推薦的標籤數量已經達到上限 - hint_html: "推薦主題標籤是什麼? 這些主題標籤將顯示於您的公開個人檔案頁,訪客可以藉此閱覽您標示了這些標籤的嘟文,拿來展示創意作品或者長期更新的專案很好用唷!" + limit: 您所推薦之主題標籤數量已達上限 + hint_html: "於個人檔案上推薦您的推薦主題標籤 展示創意作品或者長期更新的專案的絕佳工具,推薦主題標籤於您個人資料頁面顯眼地展示,並且能快速存取您自己的嘟文。" filters: contexts: account: 個人檔案 @@ -1166,44 +1247,82 @@ zh-TW: index: hint: 此過濾器會套用至所選之各別嘟文,不管它們有無符合其他條件。您可以從網頁介面中將更多嘟文加入至此過濾器。 title: 已過濾之嘟文 - footer: - trending_now: 現正熱門 generic: all: 全部 all_items_on_page_selected_html: other: 已選取此頁面上 %{count} 個項目。 all_matching_items_selected_html: other: 已選取符合您搜尋的 %{count} 個項目。 - changes_saved_msg: 已成功儲存修改! + cancel: 取消 + changes_saved_msg: 已成功儲存變更! + confirm: 確認 copy: 複製 delete: 刪除 deselect: 取消選擇全部 none: 無 order_by: 排序 - save_changes: 儲存修改 + save_changes: 儲存變更 select_all_matching_items: other: 選取 %{count} 個符合您搜尋的項目。 today: 今天 validation_errors: - other: 唔…這是什麼鳥?請檢查以下 %{count} 項錯誤 - html_validator: - invalid_markup: 含有無效的 HTML 語法:%{error} + other: 恩...似乎不太對勁耶?請檢查以下 %{count} 項錯誤 imports: errors: + empty: 空的 CSV 檔案 + incompatible_type: 與所選的匯入類型不相容 invalid_csv_file: 無效的 CSV 檔案。錯誤訊息:%{error} over_rows_processing_limit: 含有超過 %{count} 行 + too_large: 檔案大小過大 + failures: 失敗 + imported: 已匯入 + mismatched_types_warning: 您似乎選擇錯誤的匯入類型,請再次確認。 modes: merge: 合併 merge_long: 保留現有記錄並新增紀錄 overwrite: 覆蓋 overwrite_long: 以新的紀錄覆蓋目前紀錄 + overwrite_preambles: + blocking_html: 您將要自 %{filename} 中之 %{total_items} 個帳號取代您的封鎖帳號列表。 + bookmarks_html: 您將要自 %{filename} 中之 %{total_items} 個嘟文取代您的書籤。 + domain_blocking_html: 您將要自 %{filename} 中之 %{total_items} 個網域取代您的封鎖網域列表。 + following_html: 您將要 跟隨%{filename} 中之 %{total_items} 個帳號 並且 取消跟隨其他所有人。 + lists_html: 您將以 %{filename} 之內容取代您的列表。這將會新增 %{total_items} 個帳號至新列表。 + muting_html: 您將要自 %{filename} 中之 %{total_items} 個帳號取代您的靜音帳號列表。 + preambles: + blocking_html: 您將要 封鎖%{filename} 中之 %{total_items} 個帳號。 + bookmarks_html: 您將要自 %{filename} 中之 %{total_items} 個嘟文加入至您的書籤。 + domain_blocking_html: 您將要 封鎖%{filename} 中之 %{total_items} 個網域。 + following_html: 您將要 跟隨%{filename} 中之 %{total_items} 個帳號。 + lists_html: 您將自 %{filename} 新增 %{total_items} 個帳號至您的列表。若不存在列表用以新增帳號,則會建立新列表。 + muting_html: 您將要 靜音%{filename} 中之 %{total_items} 個帳號。 preface: 您可以在此匯入您在其他伺服器所匯出的資料檔,包括跟隨的使用者、封鎖的使用者名單。 - success: 資料檔上傳成功,正在匯入,請稍候 + recent_imports: 最近匯入的 + states: + finished: 已完成 + in_progress: 處理中 + scheduled: 已排程 + unconfirmed: 未確認 + status: 狀態 + success: 資料上傳成功,正在匯入,請稍候 + time_started: 開始於 + titles: + blocking: 正在匯入已封鎖帳號 + bookmarks: 正在匯入書籤 + domain_blocking: 正在匯入已封鎖網域 + following: 正在匯入已封鎖帳號 + lists: 匯入列表 + muting: 正在匯入已靜音帳號 + type: 匯入類型 + type_groups: + constructive: 跟隨者與書籤 + destructive: 封鎖與靜音 types: - blocking: 您封鎖的使用者名單 + blocking: 您封鎖的使用者列表 bookmarks: 書籤 - domain_blocking: 域名封鎖名單 - following: 您跟隨的使用者名單 + domain_blocking: 網域封鎖列表 + following: 您跟隨的使用者列表 + lists: 列表 muting: 您靜音的使用者名單 upload: 上傳 invites: @@ -1222,14 +1341,14 @@ zh-TW: max_uses: other: "%{count} 則" max_uses_prompt: 無限制 - prompt: 建立分享連結,邀請他人在本伺服器註冊 + prompt: 建立分享連結,邀請他人於本伺服器註冊 table: expires_at: 失效時間 uses: 已使用次數 title: 邀請使用者 lists: errors: - limit: 您所建立的列表數量已經達到上限 + limit: 您所建立的列表數量已達上限 login_activities: authentication_methods: otp: 兩階段驗證應用程式 @@ -1241,9 +1360,24 @@ zh-TW: failed_sign_in_html: 使用來自 %{ip} (%{browser}) 的 %{method} 登入嘗試失敗 successful_sign_in_html: 使用來自 %{ip} (%{browser}) 的 %{method} 登入成功 title: 認證歷史紀錄 + mail_subscriptions: + unsubscribe: + action: 是的,取消訂閱 + complete: 取消訂閱 + confirmation_html: 您確定要取要取消訂閱自 Mastodon 上 %{domain} 之 %{type} 至您電子郵件 %{email} 嗎?您隨時可以自電子郵件通知設定重新訂閱。 + emails: + notification_emails: + favourite: 最愛通知電子郵件 + follow: 跟隨通知電子郵件 + follow_request: 跟隨請求通知電子郵件 + mention: 提及通知電子郵件 + reblog: 轉嘟通知電子郵件 + resubscribe_html: 若您不慎錯誤地取消訂閱,您可以自電子郵件通知設定重新訂閱。 + success_html: 您將不再收到來自 Mastodon 上 %{domain} 之 %{type} 至您電子郵件 %{email}。 + title: 取消訂閱 media_attachments: validations: - images_and_video: 無法在已有圖片的文章上加入影片 + images_and_video: 無法於已有圖片之嘟文中加入影片 not_ready: 修但幾勒!不能附加未完成處理的檔案欸,咁按呢? too_many: 無法加入超過 4 個檔案 migrations: @@ -1262,7 +1396,7 @@ zh-TW: incoming_migrations_html: 要從其他帳號移動到此帳號的話,首先您必須建立帳號別名。 moved_msg: 您的帳號正被重新導向到 %{acct},您的跟隨者也會同步轉移至該帳號。 not_redirecting: 您的帳號目前尚未重新導向到任何其他帳號。 - on_cooldown: 您最近已轉移過您的帳號。此功能將在 %{count} 天後可再度使用。 + on_cooldown: 您最近已轉移過您的帳號。此功能將於 %{count} 天後可再度使用。 past_migrations: 以往的轉移紀錄 proceed_with_move: 移動跟隨者 redirected_msg: 您的帳號現在指向 %{acct} @@ -1273,7 +1407,7 @@ zh-TW: before: 在進行下一步驟之前,請詳細閱讀以下説明: cooldown: 在轉移帳號後會有一段等待時間,在等待時間內您將無法再次轉移 disabled_account: 之後您的目前帳號將完全無法使用。但您可以存取資料匯出與重新啟用。 - followers: 此動作將會把目前帳號的所有跟隨者轉移至新帳號 + followers: 此動作將會將目前帳號的所有跟隨者轉移至新帳號 only_redirect_html: 或者,您也可以僅在您的個人檔案中設定重新導向。 other_data: 其他資料並不會自動轉移 redirect: 您目前的帳號將會在個人檔案頁面新增重新導向公告,並會被排除在搜尋結果之外 @@ -1288,7 +1422,7 @@ zh-TW: notification_mailer: admin: report: - subject: "%{name} 送出了一則檢舉報告" + subject: "%{name} 已送出一則檢舉報告" sign_up: subject: "%{name} 已進行註冊" favourite: @@ -1313,13 +1447,14 @@ zh-TW: subject: 由 %{name} 發起的投票已結束 reblog: body: 您的嘟文被 %{name} 轉嘟: - subject: "%{name} 轉嘟了您的嘟文" + subject: "%{name} 已轉嘟您的嘟文" title: 新的轉嘟 status: subject: "%{name} 剛剛嘟文" update: - subject: "%{name} 編輯了嘟文" + subject: "%{name} 已編輯嘟文" notifications: + administration_emails: 管理員電子郵件通知 email_events: 電子郵件通知設定 email_events_hint: 選取您想接收通知的事件: other_settings: 其他通知設定 @@ -1356,12 +1491,24 @@ zh-TW: expired: 投票已結束 invalid_choice: 您所選的投票選項並不存在 over_character_limit: 不能多於 %{max} 個字元 + self_vote: 您無法於您的嘟文投票 too_few_options: 必須包含至少一個項目 too_many_options: 不能包含多於 %{max} 個項目 preferences: other: 其他 posting_defaults: 嘟文預設值 public_timelines: 公開時間軸 + privacy: + hint_html: |- + 自訂您希望如何讓您的個人檔案及嘟文被找到。 + 藉由啟用一系列 Mastodon 功能以幫助您觸及更廣的受眾。煩請花些時間確認您是否欲啟用這些設定。 + privacy: 隱私權 + privacy_hint_html: 控制您希望向其他人揭露之內容。人們透過瀏覽其他人的跟隨者與其發嘟之應用程式發現有趣的個人檔案和酷炫的 Mastodon 應用程式,但您能選擇將其隱藏。 + reach: 觸及 + reach_hint_html: 控制您希望被新使用者探索或跟隨之方式。想讓您的嘟文出現於探索頁面嗎?想讓其他人透過他們的跟隨建議找到您嗎?想自動接受所有新跟隨者嗎?或是想逐一控制跟隨請求嗎? + search: 搜尋 + search_hint_html: 控制您希望如何被發現。您想透過您的公開嘟文被人們發現嗎?您想透過網頁搜尋被 Mastodon 以外的人找到您的個人檔案嗎?請注意,公開資訊可能無法全面地被所有搜尋引擎所排除。 + title: 隱私權及觸及 privacy_policy: title: 隱私權政策 reactions: @@ -1370,11 +1517,12 @@ zh-TW: unrecognized_emoji: 並非一個可識別的 emoji relationships: activity: 帳號動態 - confirm_follow_selected_followers: 您確定要跟隨這些選取的跟隨者嗎? - confirm_remove_selected_followers: 您確定要移除這些選取的跟隨者嗎? - confirm_remove_selected_follows: 您確定要移除這些選取的正在跟隨您的帳號嗎? + confirm_follow_selected_followers: 您確定要跟隨選取的跟隨者嗎? + confirm_remove_selected_followers: 您確定要移除選取的跟隨者嗎? + confirm_remove_selected_follows: 您確定要取消跟隨這些選取的使用者嗎? dormant: 潛水中 - follow_selected_followers: 跟隨所選的跟隨者 + follow_failure: 無法跟隨某些所選取的帳號。 + follow_selected_followers: 跟隨選取的跟隨者 followers: 跟隨者 following: 跟隨中 invited: 已邀請 @@ -1384,9 +1532,9 @@ zh-TW: mutual: 跟隨彼此 primary: 主要 relationship: 關係 - remove_selected_domains: 從所選網域中移除所有跟隨者 - remove_selected_followers: 移除所選的跟隨者 - remove_selected_follows: 取消跟隨所選使用者 + remove_selected_domains: 從所選取網域中移除所有跟隨者 + remove_selected_followers: 移除選取的跟隨者 + remove_selected_follows: 取消跟隨選取的使用者 status: 帳號狀態 remote_follow: missing_resource: 無法找到資源 @@ -1400,7 +1548,7 @@ zh-TW: tag: '帶有 #%{hashtag} 之公開嘟文' scheduled_statuses: over_daily_limit: 您已經超過了本日排定發嘟的限額 (%{limit}) - over_total_limit: 您已經超過了排定發嘟的限額 (%{limit}) + over_total_limit: 您已經超過排程發嘟的限額 (%{limit}) too_soon: 嘟文不可以改變過去哦,只能預定未來 (咦) sessions: activity: 最近活動 @@ -1413,6 +1561,7 @@ zh-TW: electron: Electron 瀏覽器 firefox: Firefox 瀏覽器 generic: 未知的瀏覽器 + huawei_browser: 華為瀏覽器 ie: Internet Explorer 瀏覽器 micro_messenger: 微信 nokia: Nokia S40 Ovi 瀏覽器 @@ -1422,6 +1571,7 @@ zh-TW: qq: QQ 瀏覽器 safari: Safari 瀏覽器 uc_browser: UC 瀏覽器 + unknown_browser: 未知的瀏覽器 weibo: 新浪微博 current_session: 目前的 session description: "%{platform} 上的 %{browser}" @@ -1434,9 +1584,10 @@ zh-TW: chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS + kai_os: KaiOS linux: Linux mac: Mac - other: 不明平台 + unknown_platform: 未知的平台 windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone @@ -1455,7 +1606,7 @@ zh-TW: development: 開發者 edit_profile: 編輯個人檔案 export: 匯出 - featured_tags: 推薦標籤 + featured_tags: 推薦主題標籤 import: 匯入 import_and_export: 匯入及匯出 migrate: 帳號搬遷 @@ -1485,10 +1636,10 @@ zh-TW: errors: in_reply_not_found: 您嘗試回覆的嘟文看起來不存在。 open_in_web: 以網頁開啟 - over_character_limit: 超過了 %{max} 字的限制 + over_character_limit: 已超過 %{max} 字的限制 pin_errors: direct: 無法釘選只有僅提及使用者可見之嘟文 - limit: 您所置頂的嘟文數量已經達到上限 + limit: 釘選嘟文的數量已達上限 ownership: 不能釘選他人的嘟文 reblog: 不能釘選轉嘟 poll: @@ -1501,7 +1652,6 @@ zh-TW: show_newer: 顯示較新嘟文 show_older: 顯示較舊嘟文 show_thread: 顯示討論串 - sign_in_to_participate: 登入以加入討論 title: "%{name}:「%{quote}」" visibilities: direct: 私訊 @@ -1516,14 +1666,14 @@ zh-TW: enabled_hint: 一旦達到指定的保存期限,就會自動刪除您的嘟文,除非該嘟文符合下列例外 exceptions: 例外 explanation: 因為刪除嘟文是耗費資源的操作,當伺服器不那麼忙碌時才會慢慢完成。因此,您的嘟文會在到達保存期限後一段時間才會被刪除。 - ignore_favs: 忽略最愛 - ignore_reblogs: 忽略轉嘟 + ignore_favs: 忽略最愛數 + ignore_reblogs: 忽略轉嘟數 interaction_exceptions: 基於互動的例外規則 interaction_exceptions_explanation: 請注意嘟文是無法保證被刪除的,如果在一次處理過後嘟文低於最愛或轉嘟的門檻。 keep_direct: 保留私訊 keep_direct_hint: 不會刪除任何您的私訊 - keep_media: 保留包含媒體內容的嘟文 - keep_media_hint: 不會刪除您包含媒體內容之嘟文 + keep_media: 保留包含多媒體附加檔案之嘟文 + keep_media_hint: 不會刪除您包含多媒體附加檔案之嘟文 keep_pinned: 保留釘選嘟文 keep_pinned_hint: 不會刪除您的釘選嘟文 keep_polls: 保留投票 @@ -1547,8 +1697,6 @@ zh-TW: min_reblogs: 保留超過嘟文轉嘟門檻 min_reblogs_hint: 如果您嘟文已收到超過轉嘟門檻則不會刪除。留白表示不論轉嘟數量皆刪除該嘟文。 stream_entries: - pinned: 釘選嘟文 - reblogged: 轉嘟 sensitive_content: 敏感內容 strikes: errors: @@ -1564,20 +1712,25 @@ zh-TW: default: "%Y 年 %b 月 %d 日 %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" + translation: + errors: + quota_exceeded: 伺服器之翻譯服務使用容量已逾上限。 + too_many_requests: 最近對翻譯服務之請求過多。 two_factor_authentication: add: 新增 - disable: 停用 + disable: 停用兩階段驗證 disabled_success: 已成功啟用兩階段驗證 edit: 編輯 enabled: 兩階段認證已啟用 enabled_success: 已成功啟用兩階段認證 generate_recovery_codes: 產生備用驗證碼 - lost_recovery_codes: 讓您可以在遺失手機時,使用備用驗證碼登入。若您遺失了備用驗證碼,可以在這裏產生一批新的,舊有的備用驗證碼將會失效。 + lost_recovery_codes: 讓您可以在遺失手機時,使用備用驗證碼登入。若您已遺失備用驗證碼,可於此產生一批新的,舊有的備用驗證碼將會失效。 methods: 兩步驟方式 otp: 驗證應用程式 recovery_codes: 備份備用驗證碼 recovery_codes_regenerated: 成功產生新的備用驗證碼 - recovery_instructions_html: 若您的手機無法使用,您可以使用下列任意一個備用驗證碼來重新獲得帳號的訪問權。請妥善保管好您的備用驗證碼(例如,可以將它們列印出來,與您的其他重要文件放在一起)。 + recovery_instructions_html: 若您的手機無法使用,您可以使用下列任意一個備用驗證碼來重新獲得帳號的存取權。請妥善保管好您的備用驗證碼(例如,可以將它們列印出來,與您的其他重要文件放在一起)。 webauthn: 安全金鑰 user_mailer: appeal_approved: @@ -1607,11 +1760,11 @@ zh-TW: spam: 垃圾訊息 violation: 該內容違反以下社群規章 explanation: - delete_statuses: 您的某些嘟文被發現違反了一項或多項社群準則,隨後已被 %{instance} 的管理員刪除。 + delete_statuses: 您的某些嘟文被發現已違反一項或多項社群準則,隨後已被 %{instance} 的管理員刪除。 disable: 您無法繼續使用您的帳號,但您的個人頁面及其他資料內容保持不變。您可以要求一份您的資料備份,帳號異動設定,或是刪除帳號。 mark_statuses_as_sensitive: 您的部份嘟文已被 %{instance} 的管理員標記為敏感內容。這代表了人們必須在顯示預覽前點擊嘟文中的媒體。您可以在將來嘟文時自己將媒體標記為敏感內容。 sensitive: 由此刻起,您所有上傳的媒體檔案將被標記為敏感內容,並且隱藏於點擊警告之後。 - silence: 您仍然可以使用您的帳號,但僅有已跟隨您的人才能看到您在此伺服器的嘟文,您也可能會從各式探索功能中被排除。但其他人仍可手動跟隨您。 + silence: 您仍然能使用您的帳號,但僅有已跟隨您的人才能見到您於此伺服器之嘟文,您也可能會從各式探索功能中被排除。但其他人仍可手動跟隨您。 suspend: 您將不能使用您的帳號,您的個人檔案頁面及其他資料將不再能被存取。您仍可於約 30 日內資料被完全刪除前要求下載您的資料,但我們仍會保留一部份基本資料,以防止有人規避停權處罰。 reason: 原因: statuses: 引用的嘟文: @@ -1630,7 +1783,7 @@ zh-TW: none: 警告 sensitive: 帳號已標記為敏感內容 silence: 帳號已被限制 - suspend: 帳號己被停用 + suspend: 帳號己被停權 welcome: edit_profile_action: 設定個人檔案 edit_profile_step: 您可以設定您的個人檔案,包括上傳大頭貼、變更顯示名稱等等。您也可以選擇在新的跟隨者跟隨前,先對他們進行審核。 @@ -1638,18 +1791,23 @@ zh-TW: final_action: 開始嘟嘟 final_step: '開始嘟嘟吧!即使您現在沒有跟隨者,其他人仍然能在本站時間軸、主題標籤等地方,看到您的公開嘟文。試著用 #introductions 這個主題標籤介紹一下自己吧。' full_handle: 您的完整帳號名稱 - full_handle_hint: 您需要把這告訴您的朋友們,這樣他們就能從另一個伺服器向您發送訊息或著跟隨您。 + full_handle_hint: 您需要將這告訴您的朋友們,這樣他們就能從另一個伺服器向您發送訊息或跟隨您。 subject: 歡迎來到 Mastodon title: "%{name} 誠摯歡迎您的加入!" users: follow_limit_reached: 您無法跟隨多於 %{limit} 個人 + go_to_sso_account_settings: 前往您的身分提供商 (identity provider) 之帳號設定 invalid_otp_token: 兩階段認證碼不正確 - otp_lost_help_html: 如果您無法訪問這兩者,可以透過 %{email} 與我們聯繫 + otp_lost_help_html: 如果您無法存取這兩者,您可以透過 %{email} 與我們聯繫 seamless_external_login: 由於您是由外部系統登入,所以不能設定密碼與電子郵件。 signed_in_as: 目前登入的帳號: verification: - explanation_html: 您在 Mastodon 個人檔案頁上所列出的連結,可以用此方式驗證您確實掌控該連結網頁的內容。您可以在連結的網頁上加上一個連回 Mastodon 個人檔案頁面的連結,該連結的原始碼 必須包含rel="me"屬性。連結的顯示文字可自由發揮,以下為範例: + extra_instructions_html: 小撇步:您網站上之此連結可以是不可見的。其重要的部分是 rel="me" ,防止透過使用者產生內容模擬。您甚至能使用頁面標頭之 link 標籤取代頁面中的 a 標籤,但 HTML 必須能於不執行 JavaScript 情況下所存取。 + here_is_how: 如此這般 + hint_html: "驗證您 Mastodon 上的身分!基於開放網路標準,永久免費。您唯一需準備的是所有人皆能夠識別您之個人網站。當您自個人檔案連結此網站時,我們會檢查其至您個人檔案之反向連結,並於您個人檔案展現圖形標示。" + instructions_html: 複製及貼上以下程式碼至您個人網站之 HTML 中。接著透過「編輯個人檔案」將您網站網址加入您個人網站之額外欄位中,並儲存變更。 verification: 驗證連結 + verified_links: 已驗證連結 webauthn_credentials: add: 新增安全金鑰 create: @@ -1657,7 +1815,7 @@ zh-TW: success: 您已成功加入安全金鑰。 delete: 刪除 delete_confirmation: 您確定要移除這把安全金鑰嗎? - description_html: 如果您啟用安全金鑰驗證的話,您將在登入時需要使用其中一把安全金鑰。 + description_html: 如果您啟用安全金鑰驗證的話,您將於登入時需要使用其中一把安全金鑰。 destroy: error: 移除安全金鑰時出現了問題。請再試一次。 success: 您已成功將安全金鑰移除。 diff --git a/config/navigation.rb b/config/navigation.rb index 30817d0252..4ea88fb4f2 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -4,10 +4,9 @@ SimpleNavigation::Configuration.run do |navigation| navigation.items do |n| n.item :web, safe_join([fa_icon('chevron-left fw'), t('settings.back')]), root_path - n.item :profile, safe_join([fa_icon('user fw'), t('settings.profile')]), settings_profile_path, if: -> { current_user.functional? } do |s| - s.item :profile, safe_join([fa_icon('pencil fw'), t('settings.appearance')]), settings_profile_path - s.item :featured_tags, safe_join([fa_icon('hashtag fw'), t('settings.featured_tags')]), settings_featured_tags_path - end + n.item :software_updates, safe_join([fa_icon('exclamation-circle fw'), t('admin.critical_update_pending')]), admin_software_updates_path, if: -> { ENV['UPDATE_CHECK_URL'] != '' && current_user.can?(:view_devops) && SoftwareUpdate.urgent_pending? }, html: { class: 'warning' } + + n.item :profile, safe_join([fa_icon('user fw'), t('settings.profile')]), settings_profile_path, if: -> { current_user.functional? }, highlights_on: %r{/settings/profile|/settings/featured_tags|/settings/verification|/settings/privacy} n.item :preferences, safe_join([fa_icon('cog fw'), t('settings.preferences')]), settings_preferences_path, if: -> { current_user.functional? } do |s| s.item :appearance, safe_join([fa_icon('desktop fw'), t('settings.appearance')]), settings_preferences_appearance_path @@ -15,6 +14,12 @@ SimpleNavigation::Configuration.run do |navigation| s.item :other, safe_join([fa_icon('cog fw'), t('preferences.other')]), settings_preferences_other_path end + n.item :flavours, safe_join([fa_icon('paint-brush fw'), t('settings.flavours')]), settings_flavours_path do |flavours| + Themes.instance.flavours.each do |flavour| + flavours.item flavour.to_sym, safe_join([fa_icon('star fw'), t("flavours.#{flavour}.name", default: flavour)]), settings_flavour_path(flavour) + end + end + n.item :relationships, safe_join([fa_icon('users fw'), t('settings.relationships')]), relationships_path, if: -> { current_user.functional? } n.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}, if: -> { current_user.functional? } n.item :statuses_cleanup, safe_join([fa_icon('history fw'), t('settings.statuses_cleanup')]), statuses_cleanup_path, if: -> { current_user.functional_or_moved? } @@ -26,7 +31,7 @@ SimpleNavigation::Configuration.run do |navigation| end n.item :data, safe_join([fa_icon('cloud-download fw'), t('settings.import_and_export')]), settings_export_path do |s| - s.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_import_path, if: -> { current_user.functional? } + s.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_imports_path, if: -> { current_user.functional? } s.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_path end @@ -44,7 +49,7 @@ SimpleNavigation::Configuration.run do |navigation| s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_path(origin: 'local'), highlights_on: %r{/admin/accounts|/admin/pending_accounts|/admin/disputes|/admin/users}, if: -> { current_user.can?(:manage_users) } s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) } s.item :follow_recommendations, safe_join([fa_icon('user-plus fw'), t('admin.follow_recommendations.title')]), admin_follow_recommendations_path, highlights_on: %r{/admin/follow_recommendations}, if: -> { current_user.can?(:manage_taxonomies) } - s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: whitelist_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) } + s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: limited_federation_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) } s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_path, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.can?(:manage_blocks) } s.item :ip_blocks, safe_join([fa_icon('ban fw'), t('admin.ip_blocks.title')]), admin_ip_blocks_path, highlights_on: %r{/admin/ip_blocks}, if: -> { current_user.can?(:manage_blocks) } s.item :action_logs, safe_join([fa_icon('bars fw'), t('admin.action_logs.title')]), admin_action_logs_path, if: -> { current_user.can?(:view_audit_log) } @@ -58,7 +63,7 @@ SimpleNavigation::Configuration.run do |navigation| s.item :announcements, safe_join([fa_icon('bullhorn fw'), t('admin.announcements.title')]), admin_announcements_path, highlights_on: %r{/admin/announcements}, if: -> { current_user.can?(:manage_announcements) } s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_path, highlights_on: %r{/admin/custom_emojis}, if: -> { current_user.can?(:manage_custom_emojis) } s.item :webhooks, safe_join([fa_icon('inbox fw'), t('admin.webhooks.title')]), admin_webhooks_path, highlights_on: %r{/admin/webhooks}, if: -> { current_user.can?(:manage_webhooks) } - s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_path, highlights_on: %r{/admin/relays}, if: -> { !whitelist_mode? && current_user.can?(:manage_federation) } + s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_path, highlights_on: %r{/admin/relays}, if: -> { !limited_federation_mode? && current_user.can?(:manage_federation) } end n.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_path, link_html: { target: 'sidekiq' }, if: -> { current_user.can?(:view_devops) } diff --git a/config/puma.rb b/config/puma.rb index c4e2b0b85c..b7a5a62e4f 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + persistent_timeout ENV.fetch('PERSISTENT_TIMEOUT') { 20 }.to_i max_threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i @@ -7,7 +9,7 @@ threads min_threads_count, max_threads_count if ENV['SOCKET'] bind "unix://#{ENV['SOCKET']}" else - bind "tcp://#{ENV.fetch('BIND', '127.0.0.1')}:#{ENV.fetch('PORT', 3000)}" + bind "tcp://#{ENV.fetch('BIND', '0.0.0.0')}:#{ENV.fetch('PORT', 3000)}" end environment ENV.fetch('RAILS_ENV') { 'development' } diff --git a/config/routes.rb b/config/routes.rb index 7958c6db8a..8c16d3c720 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,10 +8,12 @@ Rails.application.routes.draw do # have alternative format representations requiring separate controllers web_app_paths = %w( /getting-started + /getting-started-misc /keyboard-shortcuts /home /public /public/local + /public/remote /conversations /lists/(*any) /notifications @@ -29,6 +31,7 @@ Rails.application.routes.draw do /mutes /followed_tags /statuses/(*any) + /deck/(*any) ).freeze root 'home#index' @@ -52,6 +55,7 @@ Rails.application.routes.draw do get '.well-known/nodeinfo', to: 'well_known/nodeinfo#index', as: :nodeinfo, defaults: { format: 'json' } get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger get '.well-known/change-password', to: redirect('/auth/edit') + get '.well-known/proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" } get '/nodeinfo/2.0', to: 'well_known/nodeinfo#show', as: :nodeinfo_schema @@ -59,6 +63,8 @@ Rails.application.routes.draw do get 'intent', to: 'intents#show' get 'custom.css', to: 'custom_css#show', as: :custom_css + get 'remote_interaction_helper', to: 'remote_interaction_helper#index' + resource :instance_actor, path: 'actor', only: [:show] do resource :inbox, only: [:create], module: :activitypub resource :outbox, only: [:show], module: :activitypub @@ -67,22 +73,27 @@ Rails.application.routes.draw do devise_scope :user do get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite + resource :unsubscribe, only: [:show, :create], controller: :mail_subscriptions + namespace :auth do resource :setup, only: [:show, :update], controller: :setup resource :challenge, only: [:create], controller: :challenges get 'sessions/security_key_options', to: 'sessions#webauthn_options' + post 'captcha_confirmation', to: 'confirmations#confirm_captcha', as: :captcha_confirmation end end devise_for :users, path: 'auth', format: false, controllers: { omniauth_callbacks: 'auth/omniauth_callbacks', - sessions: 'auth/sessions', - registrations: 'auth/registrations', - passwords: 'auth/passwords', - confirmations: 'auth/confirmations', + sessions: 'auth/sessions', + registrations: 'auth/registrations', + passwords: 'auth/passwords', + confirmations: 'auth/confirmations', } get '/users/:username', to: redirect('/@%{username}'), constraints: lambda { |req| req.format.nil? || req.format.html? } + get '/users/:username/following', to: redirect('/@%{username}/following'), constraints: lambda { |req| req.format.nil? || req.format.html? } + get '/users/:username/followers', to: redirect('/@%{username}/followers'), constraints: lambda { |req| req.format.nil? || req.format.html? } get '/users/:username/statuses/:id', to: redirect('/@%{username}/%{id}'), constraints: lambda { |req| req.format.nil? || req.format.html? } get '/authorize_follow', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" } @@ -98,8 +109,6 @@ Rails.application.routes.draw do resources :followers, only: [:index], controller: :follower_accounts resources :following, only: [:index], controller: :following_accounts - resource :follow, only: [:create], controller: :account_follow - resource :unfollow, only: [:create], controller: :account_unfollow resource :outbox, only: [:show], module: :activitypub resource :inbox, only: [:create], module: :activitypub @@ -112,88 +121,24 @@ Rails.application.routes.draw do get '/:encoded_at(*path)', to: redirect("/@%{path}"), constraints: { encoded_at: /%40/ } - constraints(username: /[^@\/.]+/) do + constraints(username: %r{[^@/.]+}) do get '/@:username', to: 'accounts#show', as: :short_account get '/@:username/with_replies', to: 'accounts#show', as: :short_account_with_replies get '/@:username/media', to: 'accounts#show', as: :short_account_media get '/@:username/tagged/:tag', to: 'accounts#show', as: :short_account_tag end - constraints(account_username: /[^@\/.]+/) do + constraints(account_username: %r{[^@/.]+}) do get '/@:account_username/following', to: 'following_accounts#index' get '/@:account_username/followers', to: 'follower_accounts#index' get '/@:account_username/:id', to: 'statuses#show', as: :short_account_status get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status end - get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: /([^\/])+?/ }, format: false + get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: %r{([^/])+?} }, format: false get '/settings', to: redirect('/settings/profile') - namespace :settings do - resource :profile, only: [:show, :update] do - resources :pictures, only: :destroy - end - - get :preferences, to: redirect('/settings/preferences/appearance') - - namespace :preferences do - resource :appearance, only: [:show, :update], controller: :appearance - resource :notifications, only: [:show, :update] - resource :other, only: [:show, :update], controller: :other - end - - resource :import, only: [:show, :create] - resource :export, only: [:show, :create] - - namespace :exports, constraints: { format: :csv } do - resources :follows, only: :index, controller: :following_accounts - resources :blocks, only: :index, controller: :blocked_accounts - resources :mutes, only: :index, controller: :muted_accounts - resources :lists, only: :index, controller: :lists - resources :domain_blocks, only: :index, controller: :blocked_domains - resources :bookmarks, only: :index, controller: :bookmarks - end - - resources :two_factor_authentication_methods, only: [:index] do - collection do - post :disable - end - end - - resource :otp_authentication, only: [:show, :create], controller: 'two_factor_authentication/otp_authentication' - - resources :webauthn_credentials, only: [:index, :new, :create, :destroy], - path: 'security_keys', - controller: 'two_factor_authentication/webauthn_credentials' do - - collection do - get :options - end - end - - namespace :two_factor_authentication do - resources :recovery_codes, only: [:create] - resource :confirmation, only: [:new, :create] - end - - resources :applications, except: [:edit] do - member do - post :regenerate - end - end - - resource :delete, only: [:show, :destroy] - resource :migration, only: [:show, :create] - - namespace :migration do - resource :redirect, only: [:new, :create, :destroy] - end - - resources :aliases, only: [:index, :create, :destroy] - resources :sessions, only: [:destroy] - resources :featured_tags, only: [:index, :create, :destroy] - resources :login_activities, only: [:index] - end + draw(:settings) namespace :disputes do resources :strikes, only: [:show, :index] do @@ -222,491 +167,14 @@ Rails.application.routes.draw do get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy, format: false get '/backups/:id/download', to: 'backups#download', as: :download_backup, format: false - resource :authorize_interaction, only: [:show, :create] - resource :share, only: [:show, :create] + resource :authorize_interaction, only: [:show] + resource :share, only: [:show] - namespace :admin do - get '/dashboard', to: 'dashboard#index' - - resources :domain_allows, only: [:new, :create, :show, :destroy] - resources :domain_blocks, only: [:new, :create, :show, :destroy, :update, :edit] do - collection do - post :batch - end - end - - resources :export_domain_allows, only: [:new] do - collection do - get :export, constraints: { format: :csv } - post :import - end - end - - resources :export_domain_blocks, only: [:new] do - collection do - get :export, constraints: { format: :csv } - post :import - end - end - - resources :email_domain_blocks, only: [:index, :new, :create] do - collection do - post :batch - end - end - - resources :action_logs, only: [:index] - resources :warning_presets, except: [:new] - - resources :announcements, except: [:show] do - member do - post :publish - post :unpublish - end - end - - get '/settings', to: redirect('/admin/settings/branding') - get '/settings/edit', to: redirect('/admin/settings/branding') - - namespace :settings do - resource :branding, only: [:show, :update], controller: 'branding' - resource :registrations, only: [:show, :update], controller: 'registrations' - resource :content_retention, only: [:show, :update], controller: 'content_retention' - resource :about, only: [:show, :update], controller: 'about' - resource :appearance, only: [:show, :update], controller: 'appearance' - resource :discovery, only: [:show, :update], controller: 'discovery' - end - - resources :site_uploads, only: [:destroy] - - resources :invites, only: [:index, :create, :destroy] do - collection do - post :deactivate_all - end - end - - resources :relays, only: [:index, :new, :create, :destroy] do - member do - post :enable - post :disable - end - end - - resources :instances, only: [:index, :show, :destroy], constraints: { id: /[^\/]+/ } do - member do - post :clear_delivery_errors - post :restart_delivery - post :stop_delivery - end - end - - resources :rules - - resources :webhooks do - member do - post :enable - post :disable - end - - resource :secret, only: [], controller: 'webhooks/secrets' do - post :rotate - end - end - - resources :reports, only: [:index, :show] do - resources :actions, only: [:create], controller: 'reports/actions' do - collection do - post :preview - end - end - - member do - post :assign_to_self - post :unassign - post :reopen - post :resolve - end - end - - resources :report_notes, only: [:create, :destroy] - - resources :accounts, only: [:index, :show, :destroy] do - member do - post :enable - post :unsensitive - post :unsilence - post :unsuspend - post :redownload - post :remove_avatar - post :remove_header - post :memorialize - post :approve - post :reject - post :unblock_email - end - - collection do - post :batch - end - - resource :change_email, only: [:show, :update] - resource :reset, only: [:create] - resource :action, only: [:new, :create], controller: 'account_actions' - - resources :statuses, only: [:index, :show] do - collection do - post :batch - end - end - - resources :relationships, only: [:index] - - resource :confirmation, only: [:create] do - collection do - post :resend - end - end - end - - resources :users, only: [] do - resource :two_factor_authentication, only: [:destroy], controller: 'users/two_factor_authentications' - resource :role, only: [:show, :update], controller: 'users/roles' - end - - resources :custom_emojis, only: [:index, :new, :create] do - collection do - post :batch - end - end - - resources :ip_blocks, only: [:index, :new, :create] do - collection do - post :batch - end - end - - resources :roles, except: [:show] - resources :account_moderation_notes, only: [:create, :destroy] - resource :follow_recommendations, only: [:show, :update] - resources :tags, only: [:show, :update] - - namespace :trends do - resources :links, only: [:index] do - collection do - post :batch - end - end - - resources :tags, only: [:index] do - collection do - post :batch - end - end - - resources :statuses, only: [:index] do - collection do - post :batch - end - end - - namespace :links do - resources :preview_card_providers, only: [:index], path: :publishers do - collection do - post :batch - end - end - end - end - - namespace :disputes do - resources :appeals, only: [:index] do - member do - post :approve - post :reject - end - end - end - end + draw(:admin) get '/admin', to: redirect('/admin/dashboard', status: 302) - namespace :api, format: false do - # OEmbed - get '/oembed', to: 'oembed#show', as: :oembed - - # JSON / REST API - namespace :v1 do - resources :statuses, only: [:create, :show, :update, :destroy] do - scope module: :statuses do - resources :reblogged_by, controller: :reblogged_by_accounts, only: :index - resources :favourited_by, controller: :favourited_by_accounts, only: :index - resource :reblog, only: :create - post :unreblog, to: 'reblogs#destroy' - - resource :favourite, only: :create - post :unfavourite, to: 'favourites#destroy' - - resource :bookmark, only: :create - post :unbookmark, to: 'bookmarks#destroy' - - resource :mute, only: :create - post :unmute, to: 'mutes#destroy' - - resource :pin, only: :create - post :unpin, to: 'pins#destroy' - - resource :history, only: :show - resource :source, only: :show - - post :translate, to: 'translations#create' - end - - member do - get :context - end - end - - namespace :timelines do - resource :home, only: :show, controller: :home - resource :public, only: :show, controller: :public - resources :tag, only: :show - resources :list, only: :show - end - - get '/streaming', to: 'streaming#index' - get '/streaming/(*any)', to: 'streaming#index' - - resources :custom_emojis, only: [:index] - resources :suggestions, only: [:index, :destroy] - resources :scheduled_statuses, only: [:index, :show, :update, :destroy] - resources :preferences, only: [:index] - - resources :announcements, only: [:index] do - scope module: :announcements do - resources :reactions, only: [:update, :destroy] - end - - member do - post :dismiss - end - end - - # namespace :crypto do - # resources :deliveries, only: :create - - # namespace :keys do - # resource :upload, only: [:create] - # resource :query, only: [:create] - # resource :claim, only: [:create] - # resource :count, only: [:show] - # end - - # resources :encrypted_messages, only: [:index] do - # collection do - # post :clear - # end - # end - # end - - resources :conversations, only: [:index, :destroy] do - member do - post :read - end - end - - resources :media, only: [:create, :update, :show] - resources :blocks, only: [:index] - resources :mutes, only: [:index] - resources :favourites, only: [:index] - resources :bookmarks, only: [:index] - resources :reports, only: [:create] - resources :trends, only: [:index], controller: 'trends/tags' - resources :filters, only: [:index, :create, :show, :update, :destroy] - resources :endorsements, only: [:index] - resources :markers, only: [:index, :create] - - namespace :apps do - get :verify_credentials, to: 'credentials#show' - end - - resources :apps, only: [:create] - - namespace :trends do - resources :links, only: [:index] - resources :tags, only: [:index] - resources :statuses, only: [:index] - end - - namespace :emails do - resources :confirmations, only: [:create] - end - - resource :instance, only: [:show] do - resources :peers, only: [:index], controller: 'instances/peers' - resources :rules, only: [:index], controller: 'instances/rules' - resources :domain_blocks, only: [:index], controller: 'instances/domain_blocks' - resource :privacy_policy, only: [:show], controller: 'instances/privacy_policies' - resource :extended_description, only: [:show], controller: 'instances/extended_descriptions' - resource :activity, only: [:show], controller: 'instances/activity' - end - - resource :domain_blocks, only: [:show, :create, :destroy] - - resource :directory, only: [:show] - - resources :follow_requests, only: [:index] do - member do - post :authorize - post :reject - end - end - - resources :notifications, only: [:index, :show] do - collection do - post :clear - end - - member do - post :dismiss - end - end - - namespace :accounts do - get :verify_credentials, to: 'credentials#show' - patch :update_credentials, to: 'credentials#update' - resource :search, only: :show, controller: :search - resource :lookup, only: :show, controller: :lookup - resources :relationships, only: :index - resources :familiar_followers, only: :index - end - - resources :accounts, only: [:create, :show] do - resources :statuses, only: :index, controller: 'accounts/statuses' - resources :followers, only: :index, controller: 'accounts/follower_accounts' - resources :following, only: :index, controller: 'accounts/following_accounts' - resources :lists, only: :index, controller: 'accounts/lists' - resources :identity_proofs, only: :index, controller: 'accounts/identity_proofs' - resources :featured_tags, only: :index, controller: 'accounts/featured_tags' - - member do - post :follow - post :unfollow - post :remove_from_followers - post :block - post :unblock - post :mute - post :unmute - end - - resource :pin, only: :create, controller: 'accounts/pins' - post :unpin, to: 'accounts/pins#destroy' - resource :note, only: :create, controller: 'accounts/notes' - end - - resources :tags, only: [:show] do - member do - post :follow - post :unfollow - end - end - - resources :followed_tags, only: [:index] - - resources :lists, only: [:index, :create, :show, :update, :destroy] do - resource :accounts, only: [:show, :create, :destroy], controller: 'lists/accounts' - end - - namespace :featured_tags do - get :suggestions, to: 'suggestions#index' - end - - resources :featured_tags, only: [:index, :create, :destroy] - - resources :polls, only: [:create, :show] do - resources :votes, only: :create, controller: 'polls/votes' - end - - namespace :push do - resource :subscription, only: [:create, :show, :update, :destroy] - end - - namespace :admin do - resources :accounts, only: [:index, :show, :destroy] do - member do - post :enable - post :unsensitive - post :unsilence - post :unsuspend - post :approve - post :reject - end - - resource :action, only: [:create], controller: 'account_actions' - end - - resources :reports, only: [:index, :update, :show] do - member do - post :assign_to_self - post :unassign - post :reopen - post :resolve - end - end - - resources :domain_allows, only: [:index, :show, :create, :destroy] - resources :domain_blocks, only: [:index, :show, :update, :create, :destroy] - resources :email_domain_blocks, only: [:index, :show, :create, :destroy] - resources :ip_blocks, only: [:index, :show, :update, :create, :destroy] - - namespace :trends do - resources :tags, only: [:index] - resources :links, only: [:index] - resources :statuses, only: [:index] - end - - post :measures, to: 'measures#create' - post :dimensions, to: 'dimensions#create' - post :retention, to: 'retention#create' - - resources :canonical_email_blocks, only: [:index, :create, :show, :destroy] do - collection do - post :test - end - end - end - end - - namespace :v2 do - get '/search', to: 'search#index', as: :search - - resources :media, only: [:create] - resources :suggestions, only: [:index] - resource :instance, only: [:show] - resources :filters, only: [:index, :create, :show, :update, :destroy] do - resources :keywords, only: [:index, :create], controller: 'filters/keywords' - resources :statuses, only: [:index, :create], controller: 'filters/statuses' - end - - namespace :filters do - resources :keywords, only: [:show, :update, :destroy] - resources :statuses, only: [:show, :destroy] - end - - namespace :admin do - resources :accounts, only: [:index] - end - end - - namespace :web do - resource :settings, only: [:update] - resource :embed, only: [:create] - resources :push_subscriptions, only: [:create] do - member do - put :update - end - end - end - end + draw(:api) web_app_paths.each do |path| get path, to: 'home#index' diff --git a/config/routes/admin.rb b/config/routes/admin.rb new file mode 100644 index 0000000000..14695c36c5 --- /dev/null +++ b/config/routes/admin.rb @@ -0,0 +1,207 @@ +# frozen_string_literal: true + +namespace :admin do + get '/dashboard', to: 'dashboard#index' + + resources :domain_allows, only: [:new, :create, :destroy] + resources :domain_blocks, only: [:new, :create, :destroy, :update, :edit] do + collection do + post :batch + end + end + + resources :export_domain_allows, only: [:new] do + collection do + get :export, constraints: { format: :csv } + post :import + end + end + + resources :export_domain_blocks, only: [:new] do + collection do + get :export, constraints: { format: :csv } + post :import + end + end + + resources :email_domain_blocks, only: [:index, :new, :create] do + collection do + post :batch + end + end + + resources :action_logs, only: [:index] + resources :warning_presets, except: [:new, :show] + + resources :announcements, except: [:show] do + member do + post :publish + post :unpublish + end + end + + get '/settings', to: redirect('/admin/settings/branding') + get '/settings/edit', to: redirect('/admin/settings/branding') + + namespace :settings do + resource :branding, only: [:show, :update], controller: 'branding' + resource :registrations, only: [:show, :update], controller: 'registrations' + resource :content_retention, only: [:show, :update], controller: 'content_retention' + resource :about, only: [:show, :update], controller: 'about' + resource :appearance, only: [:show, :update], controller: 'appearance' + resource :discovery, only: [:show, :update], controller: 'discovery' + resource :other, only: [:show, :update], controller: 'other' + end + + resources :site_uploads, only: [:destroy] + + resources :invites, only: [:index, :create, :destroy] do + collection do + post :deactivate_all + end + end + + resources :relays, only: [:index, :new, :create, :destroy] do + member do + post :enable + post :disable + end + end + + resources :instances, only: [:index, :show, :destroy], constraints: { id: %r{[^/]+} }, format: 'html' do + member do + post :clear_delivery_errors + post :restart_delivery + post :stop_delivery + end + end + + resources :rules, only: [:index, :create, :edit, :update, :destroy] + + resources :webhooks do + member do + post :enable + post :disable + end + + resource :secret, only: [], controller: 'webhooks/secrets' do + post :rotate + end + end + + resources :reports, only: [:index, :show] do + resources :actions, only: [:create], controller: 'reports/actions' do + collection do + post :preview + end + end + + member do + post :assign_to_self + post :unassign + post :reopen + post :resolve + end + end + + resources :report_notes, only: [:create, :destroy] + + resources :accounts, only: [:index, :show, :destroy] do + member do + post :enable + post :unsensitive + post :unsilence + post :unsuspend + post :redownload + post :remove_avatar + post :remove_header + post :memorialize + post :approve + post :reject + post :unblock_email + end + + collection do + post :batch + end + + resource :change_email, only: [:show, :update] + resource :reset, only: [:create] + resource :action, only: [:new, :create], controller: 'account_actions' + + resources :statuses, only: [:index, :show] do + collection do + post :batch + end + end + + resources :relationships, only: [:index] + + resource :confirmation, only: [:create] do + collection do + post :resend + end + end + end + + resources :users, only: [] do + resource :two_factor_authentication, only: [:destroy], controller: 'users/two_factor_authentications' + resource :role, only: [:show, :update], controller: 'users/roles' + end + + resources :custom_emojis, only: [:index, :new, :create] do + collection do + post :batch + end + end + + resources :ip_blocks, only: [:index, :new, :create] do + collection do + post :batch + end + end + + resources :roles, except: [:show] + resources :account_moderation_notes, only: [:create, :destroy] + resource :follow_recommendations, only: [:show, :update] + resources :tags, only: [:show, :update] + + namespace :trends do + resources :links, only: [:index] do + collection do + post :batch + end + end + + resources :tags, only: [:index] do + collection do + post :batch + end + end + + resources :statuses, only: [:index] do + collection do + post :batch + end + end + + namespace :links do + resources :preview_card_providers, only: [:index], path: :publishers do + collection do + post :batch + end + end + end + end + + namespace :disputes do + resources :appeals, only: [:index] do + member do + post :approve + post :reject + end + end + end + + resources :software_updates, only: [:index] +end diff --git a/config/routes/api.rb b/config/routes/api.rb new file mode 100644 index 0000000000..f4e4b204ad --- /dev/null +++ b/config/routes/api.rb @@ -0,0 +1,320 @@ +# frozen_string_literal: true + +namespace :api, format: false do + # OEmbed + get '/oembed', to: 'oembed#show', as: :oembed + + # JSON / REST API + namespace :v1 do + resources :statuses, only: [:create, :show, :update, :destroy] do + scope module: :statuses do + resources :reblogged_by, controller: :reblogged_by_accounts, only: :index + resources :favourited_by, controller: :favourited_by_accounts, only: :index + resource :reblog, only: :create + post :unreblog, to: 'reblogs#destroy' + + resource :favourite, only: :create + post :unfavourite, to: 'favourites#destroy' + + resource :bookmark, only: :create + post :unbookmark, to: 'bookmarks#destroy' + + resource :mute, only: :create + post :unmute, to: 'mutes#destroy' + + resource :pin, only: :create + post :unpin, to: 'pins#destroy' + + resource :history, only: :show + resource :source, only: :show + + post :translate, to: 'translations#create' + end + + member do + get :context + end + end + + namespace :timelines do + resource :direct, only: :show, controller: :direct + resource :home, only: :show, controller: :home + resource :public, only: :show, controller: :public + resources :tag, only: :show + resources :list, only: :show + end + + get '/streaming', to: 'streaming#index' + get '/streaming/(*any)', to: 'streaming#index' + + resources :custom_emojis, only: [:index] + resources :suggestions, only: [:index, :destroy] + resources :scheduled_statuses, only: [:index, :show, :update, :destroy] + resources :preferences, only: [:index] + + resources :announcements, only: [:index] do + scope module: :announcements do + resources :reactions, only: [:update, :destroy] + end + + member do + post :dismiss + end + end + + # namespace :crypto do + # resources :deliveries, only: :create + + # namespace :keys do + # resource :upload, only: [:create] + # resource :query, only: [:create] + # resource :claim, only: [:create] + # resource :count, only: [:show] + # end + + # resources :encrypted_messages, only: [:index] do + # collection do + # post :clear + # end + # end + # end + + resources :conversations, only: [:index, :destroy] do + member do + post :read + post :unread + end + end + + resources :media, only: [:create, :update, :show] + resources :blocks, only: [:index] + resources :mutes, only: [:index] + resources :favourites, only: [:index] + resources :bookmarks, only: [:index] + resources :reports, only: [:create] + resources :trends, only: [:index], controller: 'trends/tags' + resources :filters, only: [:index, :create, :show, :update, :destroy] + resources :endorsements, only: [:index] + resources :markers, only: [:index, :create] + + namespace :profile do + resource :avatar, only: :destroy + resource :header, only: :destroy + end + + namespace :apps do + get :verify_credentials, to: 'credentials#show' + end + + resources :apps, only: [:create] + + namespace :trends do + resources :tags, only: [:index] + resources :links, only: [:index] + resources :statuses, only: [:index] + end + + namespace :emails do + resources :confirmations, only: [:create] + get :check_confirmation, to: 'confirmations#check' + end + + resource :instance, only: [:show] do + resources :peers, only: [:index], controller: 'instances/peers' + resources :rules, only: [:index], controller: 'instances/rules' + resources :domain_blocks, only: [:index], controller: 'instances/domain_blocks' + resource :privacy_policy, only: [:show], controller: 'instances/privacy_policies' + resource :extended_description, only: [:show], controller: 'instances/extended_descriptions' + resource :translation_languages, only: [:show], controller: 'instances/translation_languages' + resource :languages, only: [:show], controller: 'instances/languages' + resource :activity, only: [:show], controller: 'instances/activity' + end + + namespace :peers do + get :search, to: 'search#index' + end + + resource :domain_blocks, only: [:show, :create, :destroy] + + resource :directory, only: [:show] + + resources :follow_requests, only: [:index] do + member do + post :authorize + post :reject + end + end + + resources :notifications, only: [:index, :show, :destroy] do + collection do + post :clear + delete :destroy_multiple + end + + member do + post :dismiss + end + end + + namespace :accounts do + get :verify_credentials, to: 'credentials#show' + patch :update_credentials, to: 'credentials#update' + resource :search, only: :show, controller: :search + resource :lookup, only: :show, controller: :lookup + resources :relationships, only: :index + resources :familiar_followers, only: :index + end + + resources :accounts, only: [:create, :show] do + resources :statuses, only: :index, controller: 'accounts/statuses' + resources :followers, only: :index, controller: 'accounts/follower_accounts' + resources :following, only: :index, controller: 'accounts/following_accounts' + resources :lists, only: :index, controller: 'accounts/lists' + resources :identity_proofs, only: :index, controller: 'accounts/identity_proofs' + resources :featured_tags, only: :index, controller: 'accounts/featured_tags' + + member do + post :follow + post :unfollow + post :remove_from_followers + post :block + post :unblock + post :mute + post :unmute + end + + resource :pin, only: :create, controller: 'accounts/pins' + post :unpin, to: 'accounts/pins#destroy' + resource :note, only: :create, controller: 'accounts/notes' + end + + resources :tags, only: [:show] do + member do + post :follow + post :unfollow + end + end + + resources :followed_tags, only: [:index] + + resources :lists, only: [:index, :create, :show, :update, :destroy] do + resource :accounts, only: [:show, :create, :destroy], controller: 'lists/accounts' + end + + namespace :featured_tags do + get :suggestions, to: 'suggestions#index' + end + + resources :featured_tags, only: [:index, :create, :destroy] + + resources :polls, only: [:create, :show] do + resources :votes, only: :create, controller: 'polls/votes' + end + + namespace :push do + resource :subscription, only: [:create, :show, :update, :destroy] + end + + namespace :admin do + resources :accounts, only: [:index, :show, :destroy] do + member do + post :enable + post :unsensitive + post :unsilence + post :unsuspend + post :approve + post :reject + end + + resource :action, only: [:create], controller: 'account_actions' + end + + resources :reports, only: [:index, :update, :show] do + member do + post :assign_to_self + post :unassign + post :reopen + post :resolve + end + end + + resources :domain_allows, only: [:index, :show, :create, :destroy] + resources :domain_blocks, only: [:index, :show, :update, :create, :destroy] + resources :email_domain_blocks, only: [:index, :show, :create, :destroy] + resources :ip_blocks, only: [:index, :show, :update, :create, :destroy] + + namespace :trends do + resources :tags, only: [:index] do + member do + post :approve + post :reject + end + end + resources :links, only: [:index] do + member do + post :approve + post :reject + end + end + resources :statuses, only: [:index] do + member do + post :approve + post :reject + end + end + + namespace :links do + resources :preview_card_providers, only: [:index], path: :publishers do + member do + post :approve + post :reject + end + end + end + end + + post :measures, to: 'measures#create' + post :dimensions, to: 'dimensions#create' + post :retention, to: 'retention#create' + + resources :canonical_email_blocks, only: [:index, :create, :show, :destroy] do + collection do + post :test + end + end + + resources :tags, only: [:index, :show, :update] + end + end + + namespace :v2 do + get '/search', to: 'search#index', as: :search + + resources :media, only: [:create] + resources :suggestions, only: [:index] + resource :instance, only: [:show] + resources :filters, only: [:index, :create, :show, :update, :destroy] do + resources :keywords, only: [:index, :create], controller: 'filters/keywords' + resources :statuses, only: [:index, :create], controller: 'filters/statuses' + end + + namespace :filters do + resources :keywords, only: [:show, :update, :destroy] + resources :statuses, only: [:show, :destroy] + end + + namespace :admin do + resources :accounts, only: [:index] + end + end + + namespace :web do + resource :settings, only: [:update] + resources :embeds, only: [:show] + resources :push_subscriptions, only: [:create] do + member do + put :update + end + end + end +end diff --git a/config/routes/settings.rb b/config/routes/settings.rb new file mode 100644 index 0000000000..9aac8ef690 --- /dev/null +++ b/config/routes/settings.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +namespace :settings do + resource :profile, only: [:show, :update] do + resources :pictures, only: :destroy + end + + get :preferences, to: redirect('/settings/preferences/appearance') + + namespace :preferences do + resource :appearance, only: [:show, :update], controller: :appearance + resource :notifications, only: [:show, :update] + resource :other, only: [:show, :update], controller: :other + end + + resources :imports, only: [:index, :show, :destroy, :create] do + member do + post :confirm + get :failures + end + end + + resource :export, only: [:show, :create] + + namespace :exports, constraints: { format: :csv } do + resources :follows, only: :index, controller: :following_accounts + resources :blocks, only: :index, controller: :blocked_accounts + resources :mutes, only: :index, controller: :muted_accounts + resources :lists, only: :index, controller: :lists + resources :domain_blocks, only: :index, controller: :blocked_domains + resources :bookmarks, only: :index, controller: :bookmarks + end + + resources :two_factor_authentication_methods, only: [:index] do + collection do + post :disable + end + end + + resource :otp_authentication, only: [:show, :create], controller: 'two_factor_authentication/otp_authentication' + + resources :webauthn_credentials, only: [:index, :new, :create, :destroy], + path: 'security_keys', + controller: 'two_factor_authentication/webauthn_credentials' do + collection do + get :options + end + end + + namespace :two_factor_authentication do + resources :recovery_codes, only: [:create] + resource :confirmation, only: [:new, :create] + end + + resources :applications, except: [:edit] do + member do + post :regenerate + end + end + + resources :flavours, only: [:index, :show, :update], param: :flavour + + resource :delete, only: [:show, :destroy] + resource :migration, only: [:show, :create] + resource :verification, only: :show + resource :privacy, only: [:show, :update], controller: 'privacy' + + namespace :migration do + resource :redirect, only: [:new, :create, :destroy] + end + + resources :aliases, only: [:index, :create, :destroy] + resources :sessions, only: [:destroy] + resources :featured_tags, only: [:index, :create, :destroy] + resources :login_activities, only: [:index] +end diff --git a/config/settings.yml b/config/settings.yml index f0b09dd5c8..c9c37a6f71 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -2,7 +2,7 @@ # important settings can be changed from the admin interface. defaults: &defaults - site_title: Mastodon + site_title: 'Mastodon Glitch Edition' site_short_description: '' site_description: '' site_extended_description: '' @@ -12,48 +12,17 @@ defaults: &defaults registrations_mode: 'open' profile_directory: true closed_registrations_message: '' - open_deletion: true - min_invite_role: 'admin' - timeline_preview: true + timeline_preview: false show_staff_badge: true - default_sensitive: false - unfollow_modal: false - boost_modal: false - delete_modal: true - auto_play_gif: false - display_media: 'default' - expand_spoilers: false preview_sensitive_media: false - reduce_motion: false - disable_swiping: false - show_application: true - system_font_ui: false noindex: false - theme: 'default' - aggregate_reblogs: true - advanced_layout: false - use_blurhash: true - use_pending_items: false + flavour: 'glitch' + skin: 'default' trends: true trends_as_landing_page: true trendable_by_default: false - crop_images: true - notification_emails: - follow: true - reblog: false - favourite: false - mention: true - follow_request: true - digest: true - report: true - pending_account: true - trending_tag: true - appeal: true - always_send_emails: false - interactions: - must_be_follower: false - must_be_following: false - must_be_following_dm: false + trending_status_cw: true + hide_followers_count: false reserved_usernames: - admin - support @@ -67,10 +36,15 @@ defaults: &defaults bootstrap_timeline_accounts: '' activity_api_enabled: true peers_api_enabled: true + show_reblogs_in_public_timelines: false + show_replies_in_public_timelines: false + default_content_type: 'text/plain' show_domain_blocks: 'disabled' show_domain_blocks_rationale: 'disabled' + outgoing_spoilers: '' require_invite_text: false backups_retention_period: 7 + captcha_enabled: false development: <<: *defaults diff --git a/config/sidekiq.yml b/config/sidekiq.yml index b8739aab33..f1ba5651dd 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -9,52 +9,56 @@ - [scheduler] :scheduler: :listened_queues_only: true -:schedule: - scheduled_statuses_scheduler: - every: '5m' - class: Scheduler::ScheduledStatusesScheduler - queue: scheduler - trends_refresh_scheduler: - every: '5m' - class: Scheduler::Trends::RefreshScheduler - queue: scheduler - trends_review_notifications_scheduler: - every: '6h' - class: Scheduler::Trends::ReviewNotificationsScheduler - queue: scheduler - indexing_scheduler: - every: '5m' - class: Scheduler::IndexingScheduler - queue: scheduler - vacuum_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' - class: Scheduler::VacuumScheduler - queue: scheduler - follow_recommendations_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(6..9) %> * * *' - class: Scheduler::FollowRecommendationsScheduler - queue: scheduler - user_cleanup_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *' - class: Scheduler::UserCleanupScheduler - queue: scheduler - ip_cleanup_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' - class: Scheduler::IpCleanupScheduler - queue: scheduler - pghero_scheduler: - cron: '0 0 * * *' - class: Scheduler::PgheroScheduler - queue: scheduler - instance_refresh_scheduler: - cron: '0 * * * *' - class: Scheduler::InstanceRefreshScheduler - queue: scheduler - accounts_statuses_cleanup_scheduler: - interval: 1 minute - class: Scheduler::AccountsStatusesCleanupScheduler - queue: scheduler - suspended_user_cleanup_scheduler: - interval: 1 minute - class: Scheduler::SuspendedUserCleanupScheduler - queue: scheduler + :schedule: + scheduled_statuses_scheduler: + every: '5m' + class: Scheduler::ScheduledStatusesScheduler + queue: scheduler + trends_refresh_scheduler: + every: '5m' + class: Scheduler::Trends::RefreshScheduler + queue: scheduler + trends_review_notifications_scheduler: + every: '6h' + class: Scheduler::Trends::ReviewNotificationsScheduler + queue: scheduler + indexing_scheduler: + interval: 1 minute + class: Scheduler::IndexingScheduler + queue: scheduler + vacuum_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' + class: Scheduler::VacuumScheduler + queue: scheduler + follow_recommendations_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(6..9) %> * * *' + class: Scheduler::FollowRecommendationsScheduler + queue: scheduler + user_cleanup_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *' + class: Scheduler::UserCleanupScheduler + queue: scheduler + ip_cleanup_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' + class: Scheduler::IpCleanupScheduler + queue: scheduler + pghero_scheduler: + cron: '0 0 * * *' + class: Scheduler::PgheroScheduler + queue: scheduler + instance_refresh_scheduler: + cron: '0 * * * *' + class: Scheduler::InstanceRefreshScheduler + queue: scheduler + accounts_statuses_cleanup_scheduler: + interval: 1 minute + class: Scheduler::AccountsStatusesCleanupScheduler + queue: scheduler + suspended_user_cleanup_scheduler: + interval: 1 minute + class: Scheduler::SuspendedUserCleanupScheduler + queue: scheduler + software_update_check_scheduler: + interval: 30 minutes + class: Scheduler::SoftwareUpdateCheckScheduler + queue: scheduler diff --git a/config/themes.yml b/config/themes.yml deleted file mode 100644 index e0a902f0e9..0000000000 --- a/config/themes.yml +++ /dev/null @@ -1,9 +0,0 @@ -dark: styles/application.scss -contrast: styles/contrast.scss -mastodon-light: styles/mastodon-light.scss -wobbl: styles/wobbl.scss -wobbl-light: styles/wobbl-light.scss -modern-dark: styles/modern-dark.scss -modern-light: styles/modern-light.scss -modern-light-wobbl: styles/modern-light-wobbl.scss -default: styles/modern-dark-wobbl.scss diff --git a/config/webpack/configuration.js b/config/webpack/configuration.js index 25b6b7abd6..82d5b2e3da 100644 --- a/config/webpack/configuration.js +++ b/config/webpack/configuration.js @@ -1,15 +1,59 @@ // Common configuration for webpacker loaded from config/webpacker.yml -const { resolve } = require('path'); +const { lstatSync, readFileSync } = require('fs'); +const { basename, dirname, extname, join, resolve } = require('path'); const { env } = require('process'); + +const glob = require('glob'); const { load } = require('js-yaml'); -const { readFileSync } = require('fs'); const configPath = resolve('config', 'webpacker.yml'); const settings = load(readFileSync(configPath), 'utf8')[env.RAILS_ENV || env.NODE_ENV]; +const flavourFiles = glob.sync('app/javascript/flavours/*/theme.yml'); +const skinFiles = glob.sync('app/javascript/skins/*/*'); +const flavours = {}; -const themePath = resolve('config', 'themes.yml'); -const themes = load(readFileSync(themePath), 'utf8'); +const core = function () { + const coreFile = resolve('app', 'javascript', 'core', 'theme.yml'); + const data = load(readFileSync(coreFile), 'utf8'); + if (!data.pack_directory) { + data.pack_directory = dirname(coreFile); + } + return data.pack ? data : {}; +}(); + +flavourFiles.forEach((flavourFile) => { + const data = load(readFileSync(flavourFile), 'utf8'); + data.name = basename(dirname(flavourFile)); + data.skin = {}; + if (!data.pack_directory) { + data.pack_directory = dirname(flavourFile); + } + if (data.locales) { + data.locales = join(dirname(flavourFile), data.locales); + } + if (data.pack && typeof data.pack === 'object') { + flavours[data.name] = data; + } +}); + +skinFiles.forEach((skinFile) => { + let skin = basename(skinFile); + const name = basename(dirname(skinFile)); + if (!flavours[name]) { + return; + } + const data = flavours[name].skin; + if (lstatSync(skinFile).isDirectory()) { + data[skin] = {}; + const skinPacks = glob.sync(join(skinFile, '*.{css,scss}')); + skinPacks.forEach((pack) => { + data[skin][basename(pack, extname(pack))] = pack; + }); + } else if ((skin = skin.match(/^(.*)\.s?css$/i))) { + data[skin[1]] = { common: skinFile }; + } +}); const output = { path: resolve('public', settings.public_output_path), @@ -18,7 +62,8 @@ const output = { module.exports = { settings, - themes, + core, + flavours, env: { NODE_ENV: env.NODE_ENV, PUBLIC_OUTPUT_PATH: settings.public_output_path, diff --git a/config/webpack/development.js b/config/webpack/development.js index c3cf1b655c..d04ae84169 100644 --- a/config/webpack/development.js +++ b/config/webpack/development.js @@ -1,8 +1,9 @@ // Note: You must restart bin/webpack-dev-server for changes to take effect const { merge } = require('webpack-merge'); -const sharedConfig = require('./shared'); + const { settings, output } = require('./configuration'); +const sharedConfig = require('./shared'); const watchOptions = {}; @@ -17,6 +18,7 @@ module.exports = merge(sharedConfig, { mode: 'development', cache: true, devtool: 'cheap-module-eval-source-map', + parallelism: 1, stats: { errorDetails: true, diff --git a/config/webpack/environment.js b/config/webpack/environment.js new file mode 100644 index 0000000000..d16d9af743 --- /dev/null +++ b/config/webpack/environment.js @@ -0,0 +1,3 @@ +const { environment } = require('@rails/webpacker') + +module.exports = environment diff --git a/config/webpack/generateLocalePacks.js b/config/webpack/generateLocalePacks.js deleted file mode 100644 index b71cf2ade3..0000000000 --- a/config/webpack/generateLocalePacks.js +++ /dev/null @@ -1,52 +0,0 @@ -// To avoid adding a lot of boilerplate, locale packs are -// automatically generated here. These are written into the tmp/ -// directory and then used to generate locale_en.js, locale_fr.js, etc. - -const fs = require('fs'); -const path = require('path'); -const rimraf = require('rimraf'); -const mkdirp = require('mkdirp'); - -const localesJsonPath = path.join(__dirname, '../../app/javascript/mastodon/locales'); -const locales = fs.readdirSync(localesJsonPath).filter(filename => { - return /\.json$/.test(filename) && - !/defaultMessages/.test(filename) && - !/whitelist/.test(filename); -}).map(filename => filename.replace(/\.json$/, '')); - -const outPath = path.join(__dirname, '../../tmp/packs'); - -rimraf.sync(outPath); -mkdirp.sync(outPath); - -const outPaths = []; - -locales.forEach(locale => { - const localePath = path.join(outPath, `locale_${locale}.js`); - const baseLocale = locale.split('-')[0]; // e.g. 'zh-TW' -> 'zh' - const localeDataPath = [ - // first try react-intl - `../../node_modules/react-intl/locale-data/${baseLocale}.js`, - // then check locales/locale-data - `../../app/javascript/mastodon/locales/locale-data/${baseLocale}.js`, - // fall back to English (this is what react-intl does anyway) - '../../node_modules/react-intl/locale-data/en.js', - ].filter(filename => fs.existsSync(path.join(outPath, filename))) - .map(filename => filename.replace(/..\/..\/node_modules\//, ''))[0]; - - const localeContent = `// -// locale_${locale}.js -// automatically generated by generateLocalePacks.js -// -import messages from '../../app/javascript/mastodon/locales/${locale}.json'; -import localeData from ${JSON.stringify(localeDataPath)}; -import { setLocale } from '../../app/javascript/mastodon/locales'; -setLocale({messages, localeData}); -`; - fs.writeFileSync(localePath, localeContent, 'utf8'); - outPaths.push(localePath); -}); - -module.exports = outPaths; - - diff --git a/config/webpack/production.js b/config/webpack/production.js index 143a23b99e..cec810184d 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -3,11 +3,13 @@ const { createHash } = require('crypto'); const { readFileSync } = require('fs'); const { resolve } = require('path'); -const { merge } = require('webpack-merge'); -const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); + +const CompressionPlugin = require('@renchap/compression-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); -const CompressionPlugin = require('compression-webpack-plugin'); +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const { merge } = require('webpack-merge'); const { InjectManifest } = require('workbox-webpack-plugin'); + const sharedConfig = require('./shared'); const root = resolve(__dirname, '..', '..'); diff --git a/config/webpack/rules/babel.js b/config/webpack/rules/babel.js index 2fc245c432..d642e807f7 100644 --- a/config/webpack/rules/babel.js +++ b/config/webpack/rules/babel.js @@ -1,8 +1,9 @@ const { join, resolve } = require('path'); + const { env, settings } = require('../configuration'); module.exports = { - test: /\.(js|jsx|mjs)$/, + test: /\.(js|jsx|mjs|ts|tsx)$/, include: [ settings.source_path, ...settings.resolved_paths, @@ -12,6 +13,7 @@ module.exports = { { loader: 'babel-loader', options: { + sourceRoot: 'app/javascript', cacheDirectory: join(settings.cache_path, 'babel-loader'), cacheCompression: env.NODE_ENV === 'production', compact: env.NODE_ENV === 'production', diff --git a/config/webpack/rules/css.js b/config/webpack/rules/css.js index bc1f42c134..6ecfb31640 100644 --- a/config/webpack/rules/css.js +++ b/config/webpack/rules/css.js @@ -20,6 +20,9 @@ module.exports = { { loader: 'sass-loader', options: { + sassOptions: { + includePaths: ['app/javascript'], + }, implementation: require('sass'), sourceMap: true, }, diff --git a/config/webpack/rules/file.js b/config/webpack/rules/file.js index f2fb587801..25cda0eae5 100644 --- a/config/webpack/rules/file.js +++ b/config/webpack/rules/file.js @@ -1,4 +1,5 @@ const { join } = require('path'); + const { settings } = require('../configuration'); module.exports = { diff --git a/config/webpack/rules/index.js b/config/webpack/rules/index.js index 92a384e6d8..b026857887 100644 --- a/config/webpack/rules/index.js +++ b/config/webpack/rules/index.js @@ -1,13 +1,15 @@ const babel = require('./babel'); const css = require('./css'); const file = require('./file'); -const tesseract = require('./tesseract'); +const materialIcons = require('./material_icons'); const nodeModules = require('./node_modules'); +const tesseract = require('./tesseract'); // Webpack loaders are processed in reverse order // https://webpack.js.org/concepts/loaders/#loader-features // Lastly, process static files using file loader module.exports = { + materialIcons, file, tesseract, css, diff --git a/config/webpack/rules/material_icons.js b/config/webpack/rules/material_icons.js new file mode 100644 index 0000000000..f53445ef79 --- /dev/null +++ b/config/webpack/rules/material_icons.js @@ -0,0 +1,13 @@ +module.exports = { + test: /\.svg$/, + include: /node_modules\/@material-design-icons/, + issuer: /\.[jt]sx?$/, + use: [ + { + loader: '@svgr/webpack', + options: { + svgo: false, + }, + }, + ], +}; diff --git a/config/webpack/rules/node_modules.js b/config/webpack/rules/node_modules.js index c084d3a57e..89c9d422d3 100644 --- a/config/webpack/rules/node_modules.js +++ b/config/webpack/rules/node_modules.js @@ -1,4 +1,5 @@ const { join } = require('path'); + const { settings, env } = require('../configuration'); module.exports = { diff --git a/config/webpack/shared.js b/config/webpack/shared.js index 3447e711c1..bf1b006b0a 100644 --- a/config/webpack/shared.js +++ b/config/webpack/shared.js @@ -1,43 +1,67 @@ // Note: You must restart bin/webpack-dev-server for changes to take effect -const webpack = require('webpack'); -const { basename, dirname, join, relative, resolve } = require('path'); -const { sync } = require('glob'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const AssetsManifestPlugin = require('webpack-assets-manifest'); -const extname = require('path-complete-extname'); -const { env, settings, themes, output } = require('./configuration'); -const rules = require('./rules'); -const localePackPaths = require('./generateLocalePacks'); +const { resolve } = require('path'); + +const CircularDependencyPlugin = require('circular-dependency-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const webpack = require('webpack'); +const AssetsManifestPlugin = require('webpack-assets-manifest'); + +const { env, settings, core, flavours, output } = require('./configuration'); +const rules = require('./rules'); + +function reducePacks (data, into = {}) { + if (!data.pack) return into; + + for (const entry in data.pack) { + const pack = data.pack[entry]; + if (!pack) continue; + + let packFiles = []; + if (typeof pack === 'string') + packFiles = [pack]; + else if (Array.isArray(pack)) + packFiles = pack; + else + packFiles = [pack.filename]; + + if (packFiles) { + into[data.name ? `flavours/${data.name}/${entry}` : `core/${entry}`] = packFiles.map(packFile => resolve(data.pack_directory, packFile)); + } + } + + if (!data.name) return into; + + for (const skinName in data.skin) { + const skin = data.skin[skinName]; + if (!skin) continue; + + for (const entry in skin) { + const packFile = skin[entry]; + if (!packFile) continue; + + into[`skins/${data.name}/${skinName}/${entry}`] = resolve(packFile); + } + } + + return into; +} + +const entries = Object.assign( + reducePacks(core), + Object.values(flavours).reduce((map, data) => reducePacks(data, map), {}), +); -const extensionGlob = `**/*{${settings.extensions.join(',')}}*`; -const entryPath = join(settings.source_path, settings.source_entry_path); -const packPaths = sync(join(entryPath, extensionGlob)); module.exports = { - entry: Object.assign( - packPaths.reduce((map, entry) => { - const localMap = map; - const namespace = relative(join(entryPath), dirname(entry)); - localMap[join(namespace, basename(entry, extname(entry)))] = resolve(entry); - return localMap; - }, {}), - localePackPaths.reduce((map, entry) => { - const localMap = map; - localMap[basename(entry, extname(entry, extname(entry)))] = resolve(entry); - return localMap; - }, {}), - Object.keys(themes).reduce((themePaths, name) => { - themePaths[name] = resolve(join(settings.source_path, themes[name])); - return themePaths; - }, {}), - ), + entry: entries, output: { filename: 'js/[name]-[chunkhash].js', chunkFilename: 'js/[name]-[chunkhash].chunk.js', hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js', hashFunction: 'sha256', + crossOriginLoading: 'anonymous', path: output.path, publicPath: output.publicPath, }, @@ -52,10 +76,12 @@ module.exports = { vendors: false, common: { name: 'common', - chunks: 'all', + chunks (chunk) { + return !(chunk.name in entries); + }, minChunks: 2, minSize: 0, - test: /^(?!.*[\\\/]node_modules[\\\/]react-intl[\\\/]).+$/, + test: /^(?!.*[\\/]node_modules[\\/]react-intl[\\/]).+$/, }, }, }, @@ -64,6 +90,7 @@ module.exports = { module: { rules: Object.keys(rules).map(key => rules[key]), + strictExportPresence: true, }, plugins: [ @@ -86,6 +113,9 @@ module.exports = { writeToDisk: true, publicPath: true, }), + new CircularDependencyPlugin({ + failOnError: true, + }) ], resolve: { diff --git a/config/webpack/test.js b/config/webpack/test.js new file mode 100644 index 0000000000..c5edff94ad --- /dev/null +++ b/config/webpack/test.js @@ -0,0 +1,5 @@ +process.env.NODE_ENV = process.env.NODE_ENV || 'development' + +const environment = require('./environment') + +module.exports = environment.toWebpackConfig() diff --git a/config/webpack/tests.js b/config/webpack/tests.js index 84f008eac8..e6a8f1c2a9 100644 --- a/config/webpack/tests.js +++ b/config/webpack/tests.js @@ -1,8 +1,9 @@ // Note: You must restart bin/webpack-dev-server for changes to take effect const { merge } = require('webpack-merge'); + const sharedConfig = require('./shared'); module.exports = merge(sharedConfig, { - mode: 'development', + mode: 'production', }); diff --git a/config/webpack/translationRunner.js b/config/webpack/translationRunner.js deleted file mode 100644 index 38050baf8d..0000000000 --- a/config/webpack/translationRunner.js +++ /dev/null @@ -1,99 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const { default: manageTranslations } = require('react-intl-translations-manager'); - -const RFC5646_REGEXP = /^[a-z]{2,3}(?:-(?:x|[A-Za-z]{2,4}))*$/; - -const rootDirectory = path.resolve(__dirname, '..', '..'); -const translationsDirectory = path.resolve(rootDirectory, 'app', 'javascript', 'mastodon', 'locales'); -const messagesDirectory = path.resolve(rootDirectory, 'build', 'messages'); -const availableLanguages = fs.readdirSync(translationsDirectory).reduce((languages, filename) => { - const basename = path.basename(filename, '.json'); - if (RFC5646_REGEXP.test(basename)) { - languages.push(basename); - } - return languages; -}, []); - -const testRFC5646 = language => { - if (!RFC5646_REGEXP.test(language)) { - throw new Error('Not RFC5646 name'); - } -}; - -const testAvailability = language => { - if (!availableLanguages.includes(language)) { - throw new Error('Not an available language'); - } -}; - -const validateLanguages = (languages, validators) => { - const invalidLanguages = languages.reduce((acc, language) => { - try { - validators.forEach(validator => validator(language)); - } catch (error) { - acc.push({ language, error }); - } - return acc; - }, []); - - if (invalidLanguages.length > 0) { - console.error(` -Error: Specified invalid LANGUAGES: -${invalidLanguages.map(({ language, error }) => `* ${language}: ${error.message}`).join('\n')} - -Use yarn "manage:translations -- --help" for usage information -`); - process.exit(1); - } -}; - -const usage = `Usage: yarn manage:translations [OPTIONS] [LANGUAGES] - -Manage JavaScript translation files in Mastodon. Generates and update translations in translationsDirectory: ${translationsDirectory} - -LANGUAGES -The RFC5646 language tag for the language you want to test or fix. If you want to input multiple languages, separate them with space. - -Available languages: -${availableLanguages.join(', ')} -`; - -const { argv } = require('yargs') - .usage(usage) - .option('f', { - alias: 'force', - default: false, - describe: 'force using the provided languages. create files if not exists.', - type: 'boolean', - }); - -// check if message directory exists -if (!fs.existsSync(messagesDirectory)) { - console.error(` -Error: messagesDirectory not exists -(${messagesDirectory}) -Try to run "yarn build:development" first`); - process.exit(1); -} - -// determine the languages list -const languages = (argv._.length > 0) ? argv._ : availableLanguages; - -// validate languages -validateLanguages(languages, [ - testRFC5646, - !argv.force && testAvailability, -].filter(Boolean)); - -// manage translations -manageTranslations({ - messagesDirectory, - translationsDirectory, - detectDuplicateIds: false, - singleMessagesFile: true, - languages, - jsonOptions: { - trailingNewline: true, - }, -}); diff --git a/config/webpacker.yml b/config/webpacker.yml index 4ad78a190e..921c1306c1 100644 --- a/config/webpacker.yml +++ b/config/webpacker.yml @@ -26,6 +26,7 @@ default: &default - .tiff - .ico - .svg + - .gif - .eot - .otf - .ttf @@ -35,6 +36,9 @@ default: &default extensions: - .mjs - .js + - .jsx + - .ts + - .tsx - .sass - .scss - .css @@ -55,7 +59,7 @@ development: # Reference: https://webpack.js.org/configuration/dev-server/ dev_server: https: false - host: localhost + host: 0.0.0.0 port: 3035 public: localhost:3035 hmr: false @@ -74,7 +78,7 @@ development: test: <<: *default - # CircleCI precompiles packs prior to running the tests. + # CI precompiles packs prior to running the tests. # Also avoids race conditions in parallel_tests. compile: false diff --git a/crowdin-glitch.yml b/crowdin-glitch.yml new file mode 100644 index 0000000000..7b150fffb2 --- /dev/null +++ b/crowdin-glitch.yml @@ -0,0 +1,14 @@ +# This is needed for the Github Action +project_id_env: CROWDIN_PROJECT_ID +api_token_env: CROWDIN_PERSONAL_TOKEN + +skip_untranslated_strings: 1 +commit_message: '[ci skip]' +preserve_hierarchy: true +files: + - source: /app/javascript/flavours/glitch/locales/en.json + translation: /app/javascript/flavours/glitch/locales/%two_letters_code%.json + - source: /config/locales-glitch/en.yml + translation: /config/locales-glitch/%two_letters_code%.yml + - source: /config/locales-glitch/simple_form.en.yml + translation: /config/locales-glitch/simple_form.%two_letters_code%.yml diff --git a/crowdin.yml b/crowdin.yml index 6d84ab0a10..d05b0e69f5 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,4 +1,10 @@ +# This is needed for the Github Action +project_id_env: CROWDIN_PROJECT_ID +api_token_env: CROWDIN_PERSONAL_TOKEN + +skip_untranslated_strings: 1 commit_message: '[ci skip]' +preserve_hierarchy: true files: - source: /app/javascript/mastodon/locales/en.json translation: /app/javascript/mastodon/locales/%two_letters_code%.json diff --git a/db/migrate/20160220174730_create_accounts.rb b/db/migrate/20160220174730_create_accounts.rb index daf7c65526..d23ed1f38f 100644 --- a/db/migrate/20160220174730_create_accounts.rb +++ b/db/migrate/20160220174730_create_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccounts < ActiveRecord::Migration[4.2] def change create_table :accounts do |t| diff --git a/db/migrate/20160220211917_create_statuses.rb b/db/migrate/20160220211917_create_statuses.rb index b174685687..b8439eff8b 100644 --- a/db/migrate/20160220211917_create_statuses.rb +++ b/db/migrate/20160220211917_create_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStatuses < ActiveRecord::Migration[4.2] def change create_table :statuses do |t| diff --git a/db/migrate/20160221003140_create_users.rb b/db/migrate/20160221003140_create_users.rb index 267466a949..076ee5da38 100644 --- a/db/migrate/20160221003140_create_users.rb +++ b/db/migrate/20160221003140_create_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateUsers < ActiveRecord::Migration[4.2] def change create_table :users do |t| diff --git a/db/migrate/20160221003621_create_follows.rb b/db/migrate/20160221003621_create_follows.rb index 17287d09bc..65d745e70c 100644 --- a/db/migrate/20160221003621_create_follows.rb +++ b/db/migrate/20160221003621_create_follows.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateFollows < ActiveRecord::Migration[4.2] def change create_table :follows do |t| diff --git a/db/migrate/20160222122600_create_stream_entries.rb b/db/migrate/20160222122600_create_stream_entries.rb index 00782abc33..598cc469ec 100644 --- a/db/migrate/20160222122600_create_stream_entries.rb +++ b/db/migrate/20160222122600_create_stream_entries.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStreamEntries < ActiveRecord::Migration[4.2] def change create_table :stream_entries do |t| diff --git a/db/migrate/20160222143943_add_profile_fields_to_accounts.rb b/db/migrate/20160222143943_add_profile_fields_to_accounts.rb index cf279a535d..058eb702c3 100644 --- a/db/migrate/20160222143943_add_profile_fields_to_accounts.rb +++ b/db/migrate/20160222143943_add_profile_fields_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddProfileFieldsToAccounts < ActiveRecord::Migration[4.2] def change add_column :accounts, :note, :text, null: false, default: '' diff --git a/db/migrate/20160223162837_add_metadata_to_statuses.rb b/db/migrate/20160223162837_add_metadata_to_statuses.rb index d11d5f5cdf..c564d69422 100644 --- a/db/migrate/20160223162837_add_metadata_to_statuses.rb +++ b/db/migrate/20160223162837_add_metadata_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddMetadataToStatuses < ActiveRecord::Migration[4.2] def change add_column :statuses, :in_reply_to_id, :integer, null: true diff --git a/db/migrate/20160223164502_make_uris_nullable_in_statuses.rb b/db/migrate/20160223164502_make_uris_nullable_in_statuses.rb index 24b9b6e190..fff07093c8 100644 --- a/db/migrate/20160223164502_make_uris_nullable_in_statuses.rb +++ b/db/migrate/20160223164502_make_uris_nullable_in_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MakeUrisNullableInStatuses < ActiveRecord::Migration[4.2] def change change_column :statuses, :uri, :string, null: true, default: nil diff --git a/db/migrate/20160223165723_add_url_to_statuses.rb b/db/migrate/20160223165723_add_url_to_statuses.rb index fee7f9c59f..6e4884afa9 100644 --- a/db/migrate/20160223165723_add_url_to_statuses.rb +++ b/db/migrate/20160223165723_add_url_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddURLToStatuses < ActiveRecord::Migration[4.2] def change add_column :statuses, :url, :string, null: true, default: nil diff --git a/db/migrate/20160223165855_add_url_to_accounts.rb b/db/migrate/20160223165855_add_url_to_accounts.rb index a4db8814af..a6d0e50031 100644 --- a/db/migrate/20160223165855_add_url_to_accounts.rb +++ b/db/migrate/20160223165855_add_url_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddURLToAccounts < ActiveRecord::Migration[4.2] def change add_column :accounts, :url, :string, null: true, default: nil diff --git a/db/migrate/20160223171800_create_favourites.rb b/db/migrate/20160223171800_create_favourites.rb index 64f5cf1197..dda1c30801 100644 --- a/db/migrate/20160223171800_create_favourites.rb +++ b/db/migrate/20160223171800_create_favourites.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateFavourites < ActiveRecord::Migration[4.2] def change create_table :favourites do |t| diff --git a/db/migrate/20160224223247_create_mentions.rb b/db/migrate/20160224223247_create_mentions.rb index 6dd742d3b1..92df6d01d2 100644 --- a/db/migrate/20160224223247_create_mentions.rb +++ b/db/migrate/20160224223247_create_mentions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateMentions < ActiveRecord::Migration[4.2] def change create_table :mentions do |t| diff --git a/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb b/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb index c107c4c7fa..3666abf1cc 100644 --- a/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb +++ b/db/migrate/20160227230233_add_attachment_avatar_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAttachmentAvatarToAccounts < ActiveRecord::Migration[4.2] def self.up change_table :accounts do |t| diff --git a/db/migrate/20160305115639_add_devise_to_users.rb b/db/migrate/20160305115639_add_devise_to_users.rb index 0e12e60536..5b9a817c60 100644 --- a/db/migrate/20160305115639_add_devise_to_users.rb +++ b/db/migrate/20160305115639_add_devise_to_users.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class AddDeviseToUsers < ActiveRecord::Migration[4.2] def self.up change_table(:users) do |t| ## Database authenticatable - t.string :encrypted_password, null: false, default: "" + t.string :encrypted_password, null: false, default: '' ## Recoverable t.string :reset_password_token diff --git a/db/migrate/20160306172223_create_doorkeeper_tables.rb b/db/migrate/20160306172223_create_doorkeeper_tables.rb index 462343e888..0137520d27 100644 --- a/db/migrate/20160306172223_create_doorkeeper_tables.rb +++ b/db/migrate/20160306172223_create_doorkeeper_tables.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateDoorkeeperTables < ActiveRecord::Migration[4.2] def change create_table :oauth_applications do |t| diff --git a/db/migrate/20160312193225_add_attachment_header_to_accounts.rb b/db/migrate/20160312193225_add_attachment_header_to_accounts.rb index ac9562cbbe..37108fc189 100644 --- a/db/migrate/20160312193225_add_attachment_header_to_accounts.rb +++ b/db/migrate/20160312193225_add_attachment_header_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAttachmentHeaderToAccounts < ActiveRecord::Migration[4.2] def self.up change_table :accounts do |t| diff --git a/db/migrate/20160314164231_add_owner_to_application.rb b/db/migrate/20160314164231_add_owner_to_application.rb index 553c18b5eb..d4eda38df0 100644 --- a/db/migrate/20160314164231_add_owner_to_application.rb +++ b/db/migrate/20160314164231_add_owner_to_application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddOwnerToApplication < ActiveRecord::Migration[4.2] def change add_column :oauth_applications, :owner_id, :integer, null: true diff --git a/db/migrate/20160316103650_add_missing_indices.rb b/db/migrate/20160316103650_add_missing_indices.rb index 8b6bc5771b..76ac7e3904 100644 --- a/db/migrate/20160316103650_add_missing_indices.rb +++ b/db/migrate/20160316103650_add_missing_indices.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddMissingIndices < ActiveRecord::Migration[4.2] def change add_index :users, :account_id diff --git a/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb b/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb index 0792863a37..fbfd0fc2df 100644 --- a/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb +++ b/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAvatarRemoteURLToAccounts < ActiveRecord::Migration[4.2] def change add_column :accounts, :avatar_remote_url, :string, null: true, default: nil diff --git a/db/migrate/20160325130944_add_admin_to_users.rb b/db/migrate/20160325130944_add_admin_to_users.rb index b0cd35e008..6b701ebcc8 100644 --- a/db/migrate/20160325130944_add_admin_to_users.rb +++ b/db/migrate/20160325130944_add_admin_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAdminToUsers < ActiveRecord::Migration[4.2] def change add_column :users, :admin, :boolean, default: false diff --git a/db/migrate/20160826155805_add_superapp_to_oauth_applications.rb b/db/migrate/20160826155805_add_superapp_to_oauth_applications.rb index a1b92fada3..af8bd922fc 100644 --- a/db/migrate/20160826155805_add_superapp_to_oauth_applications.rb +++ b/db/migrate/20160826155805_add_superapp_to_oauth_applications.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSuperappToOauthApplications < ActiveRecord::Migration[5.0] def change add_column :oauth_applications, :superapp, :boolean, default: false, null: false diff --git a/db/migrate/20160905150353_create_media_attachments.rb b/db/migrate/20160905150353_create_media_attachments.rb index 32d0897d86..3903a7b9a1 100644 --- a/db/migrate/20160905150353_create_media_attachments.rb +++ b/db/migrate/20160905150353_create_media_attachments.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateMediaAttachments < ActiveRecord::Migration[5.0] def change create_table :media_attachments do |t| diff --git a/db/migrate/20160919221059_add_subscription_expires_at_to_accounts.rb b/db/migrate/20160919221059_add_subscription_expires_at_to_accounts.rb index 5fd7f39e6a..12aaffa97a 100644 --- a/db/migrate/20160919221059_add_subscription_expires_at_to_accounts.rb +++ b/db/migrate/20160919221059_add_subscription_expires_at_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSubscriptionExpiresAtToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :subscription_expires_at, :datetime, null: true, default: nil diff --git a/db/migrate/20160920003904_remove_verify_token_from_accounts.rb b/db/migrate/20160920003904_remove_verify_token_from_accounts.rb index ab6a6c84cb..132b4c9741 100644 --- a/db/migrate/20160920003904_remove_verify_token_from_accounts.rb +++ b/db/migrate/20160920003904_remove_verify_token_from_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveVerifyTokenFromAccounts < ActiveRecord::Migration[5.0] def change remove_column :accounts, :verify_token, :string, null: false, default: '' diff --git a/db/migrate/20160926213048_remove_owner_from_application.rb b/db/migrate/20160926213048_remove_owner_from_application.rb index a42f53a294..0be01dc4cb 100644 --- a/db/migrate/20160926213048_remove_owner_from_application.rb +++ b/db/migrate/20160926213048_remove_owner_from_application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveOwnerFromApplication < ActiveRecord::Migration[5.0] def change remove_index :oauth_applications, [:owner_id, :owner_type] diff --git a/db/migrate/20161003142332_add_confirmable_to_users.rb b/db/migrate/20161003142332_add_confirmable_to_users.rb index cbef4c4df2..b33c9eadad 100644 --- a/db/migrate/20161003142332_add_confirmable_to_users.rb +++ b/db/migrate/20161003142332_add_confirmable_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddConfirmableToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :confirmation_token, :string diff --git a/db/migrate/20161003145426_create_blocks.rb b/db/migrate/20161003145426_create_blocks.rb index 14bae1e7f2..fec513c657 100644 --- a/db/migrate/20161003145426_create_blocks.rb +++ b/db/migrate/20161003145426_create_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateBlocks < ActiveRecord::Migration[5.0] def change create_table :blocks do |t| diff --git a/db/migrate/20161006213403_rails_settings_migration.rb b/db/migrate/20161006213403_rails_settings_migration.rb index 9d565cb5c6..401b7a83b7 100644 --- a/db/migrate/20161006213403_rails_settings_migration.rb +++ b/db/migrate/20161006213403_rails_settings_migration.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + MIGRATION_BASE_CLASS = if ActiveRecord::VERSION::MAJOR >= 5 - ActiveRecord::Migration[5.0] -else - ActiveRecord::Migration[4.2] -end + ActiveRecord::Migration[5.0] + else + ActiveRecord::Migration[4.2] + end class RailsSettingsMigration < MIGRATION_BASE_CLASS def self.up @@ -12,7 +14,7 @@ class RailsSettingsMigration < MIGRATION_BASE_CLASS t.references :target, null: false, polymorphic: true, index: { name: 'index_settings_on_target_type_and_target_id' } t.timestamps null: true end - add_index :settings, [ :target_type, :target_id, :var ], unique: true + add_index :settings, [:target_type, :target_id, :var], unique: true end def self.down diff --git a/db/migrate/20161009120834_create_domain_blocks.rb b/db/migrate/20161009120834_create_domain_blocks.rb index dda1606d3f..9006f601ab 100644 --- a/db/migrate/20161009120834_create_domain_blocks.rb +++ b/db/migrate/20161009120834_create_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateDomainBlocks < ActiveRecord::Migration[5.0] def change create_table :domain_blocks do |t| diff --git a/db/migrate/20161027172456_add_silenced_to_accounts.rb b/db/migrate/20161027172456_add_silenced_to_accounts.rb index cd3b9f8d03..1b06d381f0 100644 --- a/db/migrate/20161027172456_add_silenced_to_accounts.rb +++ b/db/migrate/20161027172456_add_silenced_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSilencedToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :silenced, :boolean, null: false, default: false diff --git a/db/migrate/20161104173623_create_tags.rb b/db/migrate/20161104173623_create_tags.rb index d6831ff8f3..d8f120956a 100644 --- a/db/migrate/20161104173623_create_tags.rb +++ b/db/migrate/20161104173623_create_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateTags < ActiveRecord::Migration[5.0] def change create_table :tags do |t| diff --git a/db/migrate/20161105130633_create_statuses_tags_join_table.rb b/db/migrate/20161105130633_create_statuses_tags_join_table.rb index 8a436c6ea0..b140f84c4a 100644 --- a/db/migrate/20161105130633_create_statuses_tags_join_table.rb +++ b/db/migrate/20161105130633_create_statuses_tags_join_table.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStatusesTagsJoinTable < ActiveRecord::Migration[5.0] def change create_join_table :statuses, :tags do |t| diff --git a/db/migrate/20161116162355_add_locale_to_users.rb b/db/migrate/20161116162355_add_locale_to_users.rb index ec1a42ef1e..ce8e55119a 100644 --- a/db/migrate/20161116162355_add_locale_to_users.rb +++ b/db/migrate/20161116162355_add_locale_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLocaleToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :locale, :string diff --git a/db/migrate/20161119211120_create_notifications.rb b/db/migrate/20161119211120_create_notifications.rb index e6bf1d66ee..5f2e8e71bc 100644 --- a/db/migrate/20161119211120_create_notifications.rb +++ b/db/migrate/20161119211120_create_notifications.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateNotifications < ActiveRecord::Migration[5.0] def change create_table :notifications do |t| diff --git a/db/migrate/20161122163057_remove_unneeded_indexes.rb b/db/migrate/20161122163057_remove_unneeded_indexes.rb index 3832b878d4..7ed92127d7 100644 --- a/db/migrate/20161122163057_remove_unneeded_indexes.rb +++ b/db/migrate/20161122163057_remove_unneeded_indexes.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class RemoveUnneededIndexes < ActiveRecord::Migration[5.0] def change - remove_index :notifications, name: "index_notifications_on_account_id" - remove_index :settings, name: "index_settings_on_target_type_and_target_id" - remove_index :statuses_tags, name: "index_statuses_tags_on_tag_id" + remove_index :notifications, name: 'index_notifications_on_account_id' + remove_index :settings, name: 'index_settings_on_target_type_and_target_id' + remove_index :statuses_tags, name: 'index_statuses_tags_on_tag_id' end end diff --git a/db/migrate/20161123093447_add_sensitive_to_statuses.rb b/db/migrate/20161123093447_add_sensitive_to_statuses.rb index 109f761ed7..7487b2ee33 100644 --- a/db/migrate/20161123093447_add_sensitive_to_statuses.rb +++ b/db/migrate/20161123093447_add_sensitive_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSensitiveToStatuses < ActiveRecord::Migration[5.0] def change add_column :statuses, :sensitive, :boolean, default: false diff --git a/db/migrate/20161128103007_create_subscriptions.rb b/db/migrate/20161128103007_create_subscriptions.rb index 46443680ad..c6ddc5d3eb 100644 --- a/db/migrate/20161128103007_create_subscriptions.rb +++ b/db/migrate/20161128103007_create_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateSubscriptions < ActiveRecord::Migration[5.0] def change create_table :subscriptions do |t| diff --git a/db/migrate/20161130142058_add_last_successful_delivery_at_to_subscriptions.rb b/db/migrate/20161130142058_add_last_successful_delivery_at_to_subscriptions.rb index 614155b910..6f06794f6a 100644 --- a/db/migrate/20161130142058_add_last_successful_delivery_at_to_subscriptions.rb +++ b/db/migrate/20161130142058_add_last_successful_delivery_at_to_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLastSuccessfulDeliveryAtToSubscriptions < ActiveRecord::Migration[5.0] def change add_column :subscriptions, :last_successful_delivery_at, :datetime, null: true, default: nil diff --git a/db/migrate/20161130185319_add_visibility_to_statuses.rb b/db/migrate/20161130185319_add_visibility_to_statuses.rb index 3ad2abe011..e38755b563 100644 --- a/db/migrate/20161130185319_add_visibility_to_statuses.rb +++ b/db/migrate/20161130185319_add_visibility_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddVisibilityToStatuses < ActiveRecord::Migration[5.0] def change add_column :statuses, :visibility, :integer, null: false, default: 0 diff --git a/db/migrate/20161202132159_add_in_reply_to_account_id_to_statuses.rb b/db/migrate/20161202132159_add_in_reply_to_account_id_to_statuses.rb index 3a559ccd6d..111c48610d 100644 --- a/db/migrate/20161202132159_add_in_reply_to_account_id_to_statuses.rb +++ b/db/migrate/20161202132159_add_in_reply_to_account_id_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddInReplyToAccountIdToStatuses < ActiveRecord::Migration[5.0] def up add_column :statuses, :in_reply_to_account_id, :integer, null: true, default: nil diff --git a/db/migrate/20161203164520_add_from_account_id_to_notifications.rb b/db/migrate/20161203164520_add_from_account_id_to_notifications.rb index 142adbe9ca..e65642b386 100644 --- a/db/migrate/20161203164520_add_from_account_id_to_notifications.rb +++ b/db/migrate/20161203164520_add_from_account_id_to_notifications.rb @@ -1,11 +1,42 @@ +# frozen_string_literal: true + class AddFromAccountIdToNotifications < ActiveRecord::Migration[5.0] def up add_column :notifications, :from_account_id, :integer - Notification.where(from_account_id: nil).where(activity_type: 'Status').update_all('from_account_id = (SELECT statuses.account_id FROM notifications AS notifications1 INNER JOIN statuses ON notifications1.activity_id = statuses.id WHERE notifications1.activity_type = \'Status\' AND notifications1.id = notifications.id)') - Notification.where(from_account_id: nil).where(activity_type: 'Mention').update_all('from_account_id = (SELECT statuses.account_id FROM notifications AS notifications1 INNER JOIN mentions ON notifications1.activity_id = mentions.id INNER JOIN statuses ON mentions.status_id = statuses.id WHERE notifications1.activity_type = \'Mention\' AND notifications1.id = notifications.id)') - Notification.where(from_account_id: nil).where(activity_type: 'Favourite').update_all('from_account_id = (SELECT favourites.account_id FROM notifications AS notifications1 INNER JOIN favourites ON notifications1.activity_id = favourites.id WHERE notifications1.activity_type = \'Favourite\' AND notifications1.id = notifications.id)') - Notification.where(from_account_id: nil).where(activity_type: 'Follow').update_all('from_account_id = (SELECT follows.account_id FROM notifications AS notifications1 INNER JOIN follows ON notifications1.activity_id = follows.id WHERE notifications1.activity_type = \'Follow\' AND notifications1.id = notifications.id)') + Notification.where(from_account_id: nil).where(activity_type: 'Status').update_all(<<~SQL.squish) + from_account_id = ( + SELECT statuses.account_id + FROM notifications AS notifications1 + INNER JOIN statuses ON notifications1.activity_id = statuses.id + WHERE notifications1.activity_type = 'Status' AND notifications1.id = notifications.id + ) + SQL + Notification.where(from_account_id: nil).where(activity_type: 'Mention').update_all(<<~SQL.squish) + from_account_id = ( + SELECT statuses.account_id + FROM notifications AS notifications1 + INNER JOIN mentions ON notifications1.activity_id = mentions.id + INNER JOIN statuses ON mentions.status_id = statuses.id + WHERE notifications1.activity_type = 'Mention' AND notifications1.id = notifications.id + ) + SQL + Notification.where(from_account_id: nil).where(activity_type: 'Favourite').update_all(<<~SQL.squish) + from_account_id = ( + SELECT favourites.account_id + FROM notifications AS notifications1 + INNER JOIN favourites ON notifications1.activity_id = favourites.id + WHERE notifications1.activity_type = 'Favourite' AND notifications1.id = notifications.id + ) + SQL + Notification.where(from_account_id: nil).where(activity_type: 'Follow').update_all(<<~SQL.squish) + from_account_id = ( + SELECT follows.account_id + FROM notifications AS notifications1 + INNER JOIN follows ON notifications1.activity_id = follows.id + WHERE notifications1.activity_type = 'Follow' AND notifications1.id = notifications.id + ) + SQL end def down diff --git a/db/migrate/20161205214545_add_suspended_to_accounts.rb b/db/migrate/20161205214545_add_suspended_to_accounts.rb index 0d7e2beac7..d389cd0e32 100644 --- a/db/migrate/20161205214545_add_suspended_to_accounts.rb +++ b/db/migrate/20161205214545_add_suspended_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSuspendedToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :suspended, :boolean, null: false, default: false diff --git a/db/migrate/20161221152630_add_hidden_to_stream_entries.rb b/db/migrate/20161221152630_add_hidden_to_stream_entries.rb index 0d2def7f87..c3e0bb4546 100644 --- a/db/migrate/20161221152630_add_hidden_to_stream_entries.rb +++ b/db/migrate/20161221152630_add_hidden_to_stream_entries.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddHiddenToStreamEntries < ActiveRecord::Migration[5.0] def change add_column :stream_entries, :hidden, :boolean, null: false, default: false diff --git a/db/migrate/20161222201034_add_locked_to_accounts.rb b/db/migrate/20161222201034_add_locked_to_accounts.rb index c246a90cef..367dbb3952 100644 --- a/db/migrate/20161222201034_add_locked_to_accounts.rb +++ b/db/migrate/20161222201034_add_locked_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLockedToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :locked, :boolean, null: false, default: false diff --git a/db/migrate/20161222204147_create_follow_requests.rb b/db/migrate/20161222204147_create_follow_requests.rb index fbe5edf3de..572c2215fd 100644 --- a/db/migrate/20161222204147_create_follow_requests.rb +++ b/db/migrate/20161222204147_create_follow_requests.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateFollowRequests < ActiveRecord::Migration[5.0] def change create_table :follow_requests do |t| diff --git a/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb b/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb index fba46a4b63..fe877d1e16 100644 --- a/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb +++ b/db/migrate/20170105224407_add_shortcode_to_media_attachments.rb @@ -1,10 +1,19 @@ +# frozen_string_literal: true + class AddShortcodeToMediaAttachments < ActiveRecord::Migration[5.0] + class MigrationMediaAttachment < ApplicationRecord + self.table_name = :media_attachments + scope :local, -> { where(remote_url: '') } + end + def up add_column :media_attachments, :shortcode, :string, null: true, default: nil add_index :media_attachments, :shortcode, unique: true + MigrationMediaAttachment.reset_column_information + # Migrate old links - MediaAttachment.local.update_all('shortcode = id') + MigrationMediaAttachment.local.update_all('shortcode = id') end def down diff --git a/db/migrate/20170109120109_create_web_settings.rb b/db/migrate/20170109120109_create_web_settings.rb index 2aeae1f919..75ad5fa915 100644 --- a/db/migrate/20170109120109_create_web_settings.rb +++ b/db/migrate/20170109120109_create_web_settings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateWebSettings < ActiveRecord::Migration[5.0] def change create_table :web_settings do |t| diff --git a/db/migrate/20170112154826_migrate_settings.rb b/db/migrate/20170112154826_migrate_settings.rb index 0f5afe1d39..a1dc0fe4e4 100644 --- a/db/migrate/20170112154826_migrate_settings.rb +++ b/db/migrate/20170112154826_migrate_settings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MigrateSettings < ActiveRecord::Migration[4.2] def up remove_index :settings, [:target_type, :target_id, :var] diff --git a/db/migrate/20170114194937_add_application_to_statuses.rb b/db/migrate/20170114194937_add_application_to_statuses.rb index b699db2ac6..c8e8310c1e 100644 --- a/db/migrate/20170114194937_add_application_to_statuses.rb +++ b/db/migrate/20170114194937_add_application_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddApplicationToStatuses < ActiveRecord::Migration[5.0] def change add_column :statuses, :application_id, :int diff --git a/db/migrate/20170114203041_add_website_to_oauth_application.rb b/db/migrate/20170114203041_add_website_to_oauth_application.rb index ee674be722..5a0f2b7901 100644 --- a/db/migrate/20170114203041_add_website_to_oauth_application.rb +++ b/db/migrate/20170114203041_add_website_to_oauth_application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddWebsiteToOauthApplication < ActiveRecord::Migration[5.0] def change add_column :oauth_applications, :website, :string diff --git a/db/migrate/20170119214911_create_preview_cards.rb b/db/migrate/20170119214911_create_preview_cards.rb index 70ed91bbd5..41a4da6b3d 100644 --- a/db/migrate/20170119214911_create_preview_cards.rb +++ b/db/migrate/20170119214911_create_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreatePreviewCards < ActiveRecord::Migration[5.0] def change create_table :preview_cards do |t| diff --git a/db/migrate/20170123162658_add_severity_to_domain_blocks.rb b/db/migrate/20170123162658_add_severity_to_domain_blocks.rb index dcbc32a1af..3bdee44580 100644 --- a/db/migrate/20170123162658_add_severity_to_domain_blocks.rb +++ b/db/migrate/20170123162658_add_severity_to_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSeverityToDomainBlocks < ActiveRecord::Migration[5.0] def change add_column :domain_blocks, :severity, :integer, default: 0 diff --git a/db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb b/db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb index 999fccda05..5282602ce9 100644 --- a/db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb +++ b/db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddRejectMediaToDomainBlocks < ActiveRecord::Migration[5.0] def change add_column :domain_blocks, :reject_media, :boolean diff --git a/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb b/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb index 2c43210bab..7d46af3002 100644 --- a/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb +++ b/db/migrate/20170125145934_add_spoiler_text_to_statuses.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + class AddSpoilerTextToStatuses < ActiveRecord::Migration[5.0] def change - add_column :statuses, :spoiler_text, :text, default: "", null: false + add_column :statuses, :spoiler_text, :text, default: '', null: false end end diff --git a/db/migrate/20170127165745_add_devise_two_factor_to_users.rb b/db/migrate/20170127165745_add_devise_two_factor_to_users.rb index f4183e4a92..f4eb72a6b7 100644 --- a/db/migrate/20170127165745_add_devise_two_factor_to_users.rb +++ b/db/migrate/20170127165745_add_devise_two_factor_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDeviseTwoFactorToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :encrypted_otp_secret, :string diff --git a/db/migrate/20170205175257_remove_devices.rb b/db/migrate/20170205175257_remove_devices.rb index 9ef5c440ef..643e196bf3 100644 --- a/db/migrate/20170205175257_remove_devices.rb +++ b/db/migrate/20170205175257_remove_devices.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveDevices < ActiveRecord::Migration[5.0] def change drop_table :devices if table_exists?(:devices) diff --git a/db/migrate/20170209184350_add_reply_to_statuses.rb b/db/migrate/20170209184350_add_reply_to_statuses.rb index b8b5c13068..ffef97609d 100644 --- a/db/migrate/20170209184350_add_reply_to_statuses.rb +++ b/db/migrate/20170209184350_add_reply_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddReplyToStatuses < ActiveRecord::Migration[5.0] def up add_column :statuses, :reply, :boolean, nil: false, default: false diff --git a/db/migrate/20170214110202_create_reports.rb b/db/migrate/20170214110202_create_reports.rb index aa772803b8..547fbf203f 100644 --- a/db/migrate/20170214110202_create_reports.rb +++ b/db/migrate/20170214110202_create_reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateReports < ActiveRecord::Migration[5.0] def change create_table :reports do |t| diff --git a/db/migrate/20170217012631_add_reblog_of_id_foreign_key_to_statuses.rb b/db/migrate/20170217012631_add_reblog_of_id_foreign_key_to_statuses.rb index 175d4048fc..21007a9207 100644 --- a/db/migrate/20170217012631_add_reblog_of_id_foreign_key_to_statuses.rb +++ b/db/migrate/20170217012631_add_reblog_of_id_foreign_key_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddReblogOfIdForeignKeyToStatuses < ActiveRecord::Migration[5.0] def change add_foreign_key :statuses, :statuses, column: :reblog_of_id, on_delete: :cascade diff --git a/db/migrate/20170301222600_create_mutes.rb b/db/migrate/20170301222600_create_mutes.rb index 4c27eca1e3..56c0b52134 100644 --- a/db/migrate/20170301222600_create_mutes.rb +++ b/db/migrate/20170301222600_create_mutes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateMutes < ActiveRecord::Migration[5.0] def change create_table :mutes do |t| diff --git a/db/migrate/20170303212857_add_last_emailed_at_to_users.rb b/db/migrate/20170303212857_add_last_emailed_at_to_users.rb index 9ae3da4fbb..c288140cee 100644 --- a/db/migrate/20170303212857_add_last_emailed_at_to_users.rb +++ b/db/migrate/20170303212857_add_last_emailed_at_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLastEmailedAtToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :last_emailed_at, :datetime, null: true, default: nil diff --git a/db/migrate/20170304202101_add_type_to_media_attachments.rb b/db/migrate/20170304202101_add_type_to_media_attachments.rb index 5140799580..e49d87fc74 100644 --- a/db/migrate/20170304202101_add_type_to_media_attachments.rb +++ b/db/migrate/20170304202101_add_type_to_media_attachments.rb @@ -1,9 +1,24 @@ +# frozen_string_literal: true + class AddTypeToMediaAttachments < ActiveRecord::Migration[5.0] + class MigrationMediaAttachment < ApplicationRecord + self.table_name = :media_attachments + enum type: [:image, :gifv, :video] + IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze + VIDEO_MIME_TYPES = ['video/webm', 'video/mp4'].freeze + end + def up add_column :media_attachments, :type, :integer, default: 0, null: false - MediaAttachment.where(file_content_type: MediaAttachment::IMAGE_MIME_TYPES).update_all(type: MediaAttachment.types[:image]) - MediaAttachment.where(file_content_type: MediaAttachment::VIDEO_MIME_TYPES).update_all(type: MediaAttachment.types[:video]) + MigrationMediaAttachment.reset_column_information + + MigrationMediaAttachment + .where(file_content_type: MigrationMediaAttachment::IMAGE_MIME_TYPES) + .update_all(type: MigrationMediaAttachment.types[:image]) + MigrationMediaAttachment + .where(file_content_type: MigrationMediaAttachment::VIDEO_MIME_TYPES) + .update_all(type: MigrationMediaAttachment.types[:video]) end def down diff --git a/db/migrate/20170317193015_add_search_index_to_accounts.rb b/db/migrate/20170317193015_add_search_index_to_accounts.rb index 14e1741470..e29da61b15 100644 --- a/db/migrate/20170317193015_add_search_index_to_accounts.rb +++ b/db/migrate/20170317193015_add_search_index_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSearchIndexToAccounts < ActiveRecord::Migration[5.0] def up execute 'CREATE INDEX search_index ON accounts USING gin((setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\')));' diff --git a/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb b/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb index 20c9659880..e9c9863688 100644 --- a/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb +++ b/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddHeaderRemoteURLToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :header_remote_url, :string, null: false, default: '' diff --git a/db/migrate/20170322021028_add_lowercase_index_to_accounts.rb b/db/migrate/20170322021028_add_lowercase_index_to_accounts.rb index 43032747a8..16f9aab01f 100644 --- a/db/migrate/20170322021028_add_lowercase_index_to_accounts.rb +++ b/db/migrate/20170322021028_add_lowercase_index_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLowercaseIndexToAccounts < ActiveRecord::Migration[5.0] def up execute 'CREATE INDEX index_accounts_on_username_and_domain_lower ON accounts (lower(username), lower(domain))' diff --git a/db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb b/db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb index 16b5db7dda..09959100ac 100644 --- a/db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb +++ b/db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ChangePrimaryKeyToBigintOnStatuses < ActiveRecord::Migration[5.0] def change change_column :statuses, :id, :bigint diff --git a/db/migrate/20170322162804_add_search_index_to_tags.rb b/db/migrate/20170322162804_add_search_index_to_tags.rb index 415dff9a07..87ae87eadd 100644 --- a/db/migrate/20170322162804_add_search_index_to_tags.rb +++ b/db/migrate/20170322162804_add_search_index_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSearchIndexToTags < ActiveRecord::Migration[5.0] def up execute 'CREATE INDEX hashtag_search_index ON tags USING gin(to_tsvector(\'simple\', tags.name));' diff --git a/db/migrate/20170330021336_add_counter_caches.rb b/db/migrate/20170330021336_add_counter_caches.rb index cf064b9e1c..a9e496ad2f 100644 --- a/db/migrate/20170330021336_add_counter_caches.rb +++ b/db/migrate/20170330021336_add_counter_caches.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddCounterCaches < ActiveRecord::Migration[5.0] def change add_column :statuses, :favourites_count, :integer, null: false, default: 0 diff --git a/db/migrate/20170330163835_create_imports.rb b/db/migrate/20170330163835_create_imports.rb index d6f74823d7..6bd9e28b5b 100644 --- a/db/migrate/20170330163835_create_imports.rb +++ b/db/migrate/20170330163835_create_imports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateImports < ActiveRecord::Migration[5.0] def change create_table :imports do |t| diff --git a/db/migrate/20170330164118_add_attachment_data_to_imports.rb b/db/migrate/20170330164118_add_attachment_data_to_imports.rb index 2deda18861..908d4da96a 100644 --- a/db/migrate/20170330164118_add_attachment_data_to_imports.rb +++ b/db/migrate/20170330164118_add_attachment_data_to_imports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAttachmentDataToImports < ActiveRecord::Migration[4.2] def self.up change_table :imports do |t| diff --git a/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb b/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb index 2d4e121980..9afe7b9607 100644 --- a/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb +++ b/db/migrate/20170403172249_add_action_taken_by_account_id_to_reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddActionTakenByAccountIdToReports < ActiveRecord::Migration[5.0] def change add_column :reports, :action_taken_by_account_id, :integer diff --git a/db/migrate/20170405112956_add_index_on_mentions_status_id.rb b/db/migrate/20170405112956_add_index_on_mentions_status_id.rb index 3ed1a20cff..20f783517e 100644 --- a/db/migrate/20170405112956_add_index_on_mentions_status_id.rb +++ b/db/migrate/20170405112956_add_index_on_mentions_status_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexOnMentionsStatusId < ActiveRecord::Migration[5.0] def change add_index :mentions, :status_id diff --git a/db/migrate/20170406215816_add_notifications_and_favourites_indices.rb b/db/migrate/20170406215816_add_notifications_and_favourites_indices.rb index 00e41bf3ab..29df295d25 100644 --- a/db/migrate/20170406215816_add_notifications_and_favourites_indices.rb +++ b/db/migrate/20170406215816_add_notifications_and_favourites_indices.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddNotificationsAndFavouritesIndices < ActiveRecord::Migration[5.0] def change add_index :notifications, [:activity_id, :activity_type] diff --git a/db/migrate/20170409170753_add_last_webfingered_at_to_accounts.rb b/db/migrate/20170409170753_add_last_webfingered_at_to_accounts.rb index 08c916fe2a..6b66911e14 100644 --- a/db/migrate/20170409170753_add_last_webfingered_at_to_accounts.rb +++ b/db/migrate/20170409170753_add_last_webfingered_at_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLastWebfingeredAtToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :last_webfingered_at, :datetime diff --git a/db/migrate/20170414080609_add_devise_two_factor_backupable_to_users.rb b/db/migrate/20170414080609_add_devise_two_factor_backupable_to_users.rb index 65517d9f44..ee9db34342 100644 --- a/db/migrate/20170414080609_add_devise_two_factor_backupable_to_users.rb +++ b/db/migrate/20170414080609_add_devise_two_factor_backupable_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDeviseTwoFactorBackupableToUsers < ActiveRecord::Migration[5.0] def change add_column :users, :otp_backup_codes, :string, array: true diff --git a/db/migrate/20170414132105_add_language_to_statuses.rb b/db/migrate/20170414132105_add_language_to_statuses.rb index 59d51cb861..43bff1f0e2 100644 --- a/db/migrate/20170414132105_add_language_to_statuses.rb +++ b/db/migrate/20170414132105_add_language_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLanguageToStatuses < ActiveRecord::Migration[5.0] def change add_column :statuses, :language, :string, null: false, default: 'en' diff --git a/db/migrate/20170418160728_add_indexes_to_reports_for_accounts.rb b/db/migrate/20170418160728_add_indexes_to_reports_for_accounts.rb index cd69bb8b14..cf0817829b 100644 --- a/db/migrate/20170418160728_add_indexes_to_reports_for_accounts.rb +++ b/db/migrate/20170418160728_add_indexes_to_reports_for_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexesToReportsForAccounts < ActiveRecord::Migration[5.0] def change add_index :reports, :account_id diff --git a/db/migrate/20170423005413_add_allowed_languages_to_user.rb b/db/migrate/20170423005413_add_allowed_languages_to_user.rb index 044a13334c..134815f3ef 100644 --- a/db/migrate/20170423005413_add_allowed_languages_to_user.rb +++ b/db/migrate/20170423005413_add_allowed_languages_to_user.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAllowedLanguagesToUser < ActiveRecord::Migration[5.0] def change add_column :users, :allowed_languages, :string, array: true, default: [], null: false diff --git a/db/migrate/20170424003227_create_account_domain_blocks.rb b/db/migrate/20170424003227_create_account_domain_blocks.rb index b9448aca4e..ebdf0eeb28 100644 --- a/db/migrate/20170424003227_create_account_domain_blocks.rb +++ b/db/migrate/20170424003227_create_account_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountDomainBlocks < ActiveRecord::Migration[5.0] def change create_table :account_domain_blocks do |t| diff --git a/db/migrate/20170424112722_add_status_id_index_to_statuses_tags.rb b/db/migrate/20170424112722_add_status_id_index_to_statuses_tags.rb index d1db8cc629..83bb553730 100644 --- a/db/migrate/20170424112722_add_status_id_index_to_statuses_tags.rb +++ b/db/migrate/20170424112722_add_status_id_index_to_statuses_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddStatusIdIndexToStatusesTags < ActiveRecord::Migration[5.0] def change add_index :statuses_tags, :status_id diff --git a/db/migrate/20170425131920_add_media_attachment_meta.rb b/db/migrate/20170425131920_add_media_attachment_meta.rb index c4da656354..0cc6997ee6 100644 --- a/db/migrate/20170425131920_add_media_attachment_meta.rb +++ b/db/migrate/20170425131920_add_media_attachment_meta.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddMediaAttachmentMeta < ActiveRecord::Migration[5.0] def change add_column :media_attachments, :file_meta, :json diff --git a/db/migrate/20170425202925_add_oembed_to_preview_cards.rb b/db/migrate/20170425202925_add_oembed_to_preview_cards.rb index 6a932bbf2a..f71d2c27ec 100644 --- a/db/migrate/20170425202925_add_oembed_to_preview_cards.rb +++ b/db/migrate/20170425202925_add_oembed_to_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddOEmbedToPreviewCards < ActiveRecord::Migration[5.0] def change add_column :preview_cards, :type, :integer, default: 0, null: false diff --git a/db/migrate/20170427011934_re_add_owner_to_application.rb b/db/migrate/20170427011934_re_add_owner_to_application.rb index a41d71d2a1..182ce36d2a 100644 --- a/db/migrate/20170427011934_re_add_owner_to_application.rb +++ b/db/migrate/20170427011934_re_add_owner_to_application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ReAddOwnerToApplication < ActiveRecord::Migration[5.0] def change add_column :oauth_applications, :owner_id, :integer, null: true diff --git a/db/migrate/20170506235850_create_conversations.rb b/db/migrate/20170506235850_create_conversations.rb index eaf66ded7c..92fd3f3279 100644 --- a/db/migrate/20170506235850_create_conversations.rb +++ b/db/migrate/20170506235850_create_conversations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateConversations < ActiveRecord::Migration[5.0] def change create_table :conversations, id: :bigserial do |t| diff --git a/db/migrate/20170507000211_add_conversation_id_to_statuses.rb b/db/migrate/20170507000211_add_conversation_id_to_statuses.rb index d1ef7c2905..4cf7fb5e58 100644 --- a/db/migrate/20170507000211_add_conversation_id_to_statuses.rb +++ b/db/migrate/20170507000211_add_conversation_id_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddConversationIdToStatuses < ActiveRecord::Migration[5.0] def change add_column :statuses, :conversation_id, :bigint, null: true, default: nil diff --git a/db/migrate/20170507141759_optimize_index_subscriptions.rb b/db/migrate/20170507141759_optimize_index_subscriptions.rb index 26acd5c4d3..cf0305fc76 100644 --- a/db/migrate/20170507141759_optimize_index_subscriptions.rb +++ b/db/migrate/20170507141759_optimize_index_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class OptimizeIndexSubscriptions < ActiveRecord::Migration[5.0] def up add_index :subscriptions, [:account_id, :callback_url], unique: true diff --git a/db/migrate/20170508230434_create_conversation_mutes.rb b/db/migrate/20170508230434_create_conversation_mutes.rb index 81edf2733f..01122c4516 100644 --- a/db/migrate/20170508230434_create_conversation_mutes.rb +++ b/db/migrate/20170508230434_create_conversation_mutes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateConversationMutes < ActiveRecord::Migration[5.0] def change create_table :conversation_mutes do |t| diff --git a/db/migrate/20170516072309_add_index_accounts_on_uri.rb b/db/migrate/20170516072309_add_index_accounts_on_uri.rb index d98e9faa5a..19c4a1400f 100644 --- a/db/migrate/20170516072309_add_index_accounts_on_uri.rb +++ b/db/migrate/20170516072309_add_index_accounts_on_uri.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexAccountsOnUri < ActiveRecord::Migration[5.0] def change add_index :accounts, :uri diff --git a/db/migrate/20170520145338_change_language_filter_to_opt_out.rb b/db/migrate/20170520145338_change_language_filter_to_opt_out.rb index 8dac98ee87..12e045480a 100644 --- a/db/migrate/20170520145338_change_language_filter_to_opt_out.rb +++ b/db/migrate/20170520145338_change_language_filter_to_opt_out.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ChangeLanguageFilterToOptOut < ActiveRecord::Migration[5.0] def change remove_index :users, :allowed_languages diff --git a/db/migrate/20170601210557_add_index_on_media_attachments_account_id.rb b/db/migrate/20170601210557_add_index_on_media_attachments_account_id.rb index c51ab28e52..a0ce062eaa 100644 --- a/db/migrate/20170601210557_add_index_on_media_attachments_account_id.rb +++ b/db/migrate/20170601210557_add_index_on_media_attachments_account_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexOnMediaAttachmentsAccountId < ActiveRecord::Migration[5.1] def change add_index :media_attachments, :account_id diff --git a/db/migrate/20170604144747_add_foreign_keys_for_accounts.rb b/db/migrate/20170604144747_add_foreign_keys_for_accounts.rb index 76a836ca08..039679ec5a 100644 --- a/db/migrate/20170604144747_add_foreign_keys_for_accounts.rb +++ b/db/migrate/20170604144747_add_foreign_keys_for_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddForeignKeysForAccounts < ActiveRecord::Migration[5.1] def change add_foreign_key :statuses, :accounts, on_delete: :cascade diff --git a/db/migrate/20170606113804_change_tag_search_index_to_btree.rb b/db/migrate/20170606113804_change_tag_search_index_to_btree.rb index 979df2e744..12ebbde60c 100644 --- a/db/migrate/20170606113804_change_tag_search_index_to_btree.rb +++ b/db/migrate/20170606113804_change_tag_search_index_to_btree.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ChangeTagSearchIndexToBtree < ActiveRecord::Migration[5.1] def up remove_index :tags, name: :hashtag_search_index diff --git a/db/migrate/20170609145826_remove_default_language_from_statuses.rb b/db/migrate/20170609145826_remove_default_language_from_statuses.rb index 46b90ae892..28b4172a8c 100644 --- a/db/migrate/20170609145826_remove_default_language_from_statuses.rb +++ b/db/migrate/20170609145826_remove_default_language_from_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveDefaultLanguageFromStatuses < ActiveRecord::Migration[5.1] def change change_column :statuses, :language, :string, default: nil, null: true diff --git a/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb b/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb index 3e74346a8d..fce70663b3 100644 --- a/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb +++ b/db/migrate/20170610000000_add_statuses_index_on_account_id_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddStatusesIndexOnAccountIdId < ActiveRecord::Migration[5.1] disable_ddl_transaction! @@ -6,7 +8,7 @@ class AddStatusesIndexOnAccountIdId < ActiveRecord::Migration[5.1] # of an account to show them in his status page is one of the most # significant examples. # Add this index to improve the performance in such cases. - add_index 'statuses', ['account_id', 'id'], algorithm: :concurrently, name: 'index_statuses_on_account_id_id' + add_index 'statuses', %w(account_id id), algorithm: :concurrently, name: 'index_statuses_on_account_id_id' remove_index 'statuses', algorithm: :concurrently, column: 'account_id', name: 'index_statuses_on_account_id' end diff --git a/db/migrate/20170623152212_create_session_activations.rb b/db/migrate/20170623152212_create_session_activations.rb index 81c776135e..0535320bdb 100644 --- a/db/migrate/20170623152212_create_session_activations.rb +++ b/db/migrate/20170623152212_create_session_activations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateSessionActivations < ActiveRecord::Migration[5.1] def change create_table :session_activations do |t| diff --git a/db/migrate/20170624134742_add_description_to_session_activations.rb b/db/migrate/20170624134742_add_description_to_session_activations.rb index 9dbb155641..78f9e7a8d9 100644 --- a/db/migrate/20170624134742_add_description_to_session_activations.rb +++ b/db/migrate/20170624134742_add_description_to_session_activations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDescriptionToSessionActivations < ActiveRecord::Migration[5.1] def change add_column :session_activations, :user_agent, :string, null: false, default: '' diff --git a/db/migrate/20170625140443_add_access_token_id_to_session_activations.rb b/db/migrate/20170625140443_add_access_token_id_to_session_activations.rb index 213a77a83d..591dd88333 100644 --- a/db/migrate/20170625140443_add_access_token_id_to_session_activations.rb +++ b/db/migrate/20170625140443_add_access_token_id_to_session_activations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAccessTokenIdToSessionActivations < ActiveRecord::Migration[5.1] def change add_column :session_activations, :access_token_id, :integer diff --git a/db/migrate/20170711225116_fix_null_booleans.rb b/db/migrate/20170711225116_fix_null_booleans.rb index aabb81f217..12cc9b8b86 100644 --- a/db/migrate/20170711225116_fix_null_booleans.rb +++ b/db/migrate/20170711225116_fix_null_booleans.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class FixNullBooleans < ActiveRecord::Migration[5.1] def change safety_assured do diff --git a/db/migrate/20170713112503_make_tag_search_case_insensitive.rb b/db/migrate/20170713112503_make_tag_search_case_insensitive.rb index 33ed6c0050..e99b795b49 100644 --- a/db/migrate/20170713112503_make_tag_search_case_insensitive.rb +++ b/db/migrate/20170713112503_make_tag_search_case_insensitive.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MakeTagSearchCaseInsensitive < ActiveRecord::Migration[5.1] def up remove_index :tags, name: :hashtag_search_index diff --git a/db/migrate/20170713175513_create_web_push_subscriptions.rb b/db/migrate/20170713175513_create_web_push_subscriptions.rb index 4e5c2ba001..405050f465 100644 --- a/db/migrate/20170713175513_create_web_push_subscriptions.rb +++ b/db/migrate/20170713175513_create_web_push_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateWebPushSubscriptions < ActiveRecord::Migration[5.1] def change create_table :web_push_subscriptions do |t| diff --git a/db/migrate/20170713190709_add_web_push_subscription_to_session_activations.rb b/db/migrate/20170713190709_add_web_push_subscription_to_session_activations.rb index d69cdfa508..0113c52ce7 100644 --- a/db/migrate/20170713190709_add_web_push_subscription_to_session_activations.rb +++ b/db/migrate/20170713190709_add_web_push_subscription_to_session_activations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddWebPushSubscriptionToSessionActivations < ActiveRecord::Migration[5.1] def change add_column :session_activations, :web_push_subscription_id, :integer diff --git a/db/migrate/20170714184731_add_domain_to_subscriptions.rb b/db/migrate/20170714184731_add_domain_to_subscriptions.rb index 7c01a64f57..313758c44a 100644 --- a/db/migrate/20170714184731_add_domain_to_subscriptions.rb +++ b/db/migrate/20170714184731_add_domain_to_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDomainToSubscriptions < ActiveRecord::Migration[5.1] def change add_column :subscriptions, :domain, :string diff --git a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb index a498396b75..b817d512de 100644 --- a/db/migrate/20170716191202_add_hide_notifications_to_mute.rb +++ b/db/migrate/20170716191202_add_hide_notifications_to_mute.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddHideNotificationsToMute < ActiveRecord::Migration[5.1] diff --git a/db/migrate/20170718211102_add_activitypub_to_accounts.rb b/db/migrate/20170718211102_add_activitypub_to_accounts.rb index c08e38bb90..83a45f13a9 100644 --- a/db/migrate/20170718211102_add_activitypub_to_accounts.rb +++ b/db/migrate/20170718211102_add_activitypub_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddActivityPubToAccounts < ActiveRecord::Migration[5.1] def change add_column :accounts, :inbox_url, :string, null: false, default: '' diff --git a/db/migrate/20170720000000_add_index_favourites_on_account_id_and_id.rb b/db/migrate/20170720000000_add_index_favourites_on_account_id_and_id.rb index 99903584c9..f50f91f2e1 100644 --- a/db/migrate/20170720000000_add_index_favourites_on_account_id_and_id.rb +++ b/db/migrate/20170720000000_add_index_favourites_on_account_id_and_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexFavouritesOnAccountIdAndId < ActiveRecord::Migration[5.1] def change # Used to query favourites of an account ordered by id. diff --git a/db/migrate/20170823162448_create_status_pins.rb b/db/migrate/20170823162448_create_status_pins.rb index 9a6d4a7b9b..c8d3fab3a5 100644 --- a/db/migrate/20170823162448_create_status_pins.rb +++ b/db/migrate/20170823162448_create_status_pins.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStatusPins < ActiveRecord::Migration[5.1] def change create_table :status_pins do |t| diff --git a/db/migrate/20170824103029_add_timestamps_to_status_pins.rb b/db/migrate/20170824103029_add_timestamps_to_status_pins.rb index 09f0fbeaf2..837b1e10cb 100644 --- a/db/migrate/20170824103029_add_timestamps_to_status_pins.rb +++ b/db/migrate/20170824103029_add_timestamps_to_status_pins.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTimestampsToStatusPins < ActiveRecord::Migration[5.1] def change add_timestamps :status_pins, null: false, default: -> { 'CURRENT_TIMESTAMP' } diff --git a/db/migrate/20170829215220_remove_status_pins_account_index.rb b/db/migrate/20170829215220_remove_status_pins_account_index.rb index e0144242eb..5c8643915c 100644 --- a/db/migrate/20170829215220_remove_status_pins_account_index.rb +++ b/db/migrate/20170829215220_remove_status_pins_account_index.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveStatusPinsAccountIndex < ActiveRecord::Migration[5.1] def change remove_index :status_pins, :account_id diff --git a/db/migrate/20170901141119_truncate_preview_cards.rb b/db/migrate/20170901141119_truncate_preview_cards.rb index 4d9802f3bd..22a7731099 100644 --- a/db/migrate/20170901141119_truncate_preview_cards.rb +++ b/db/migrate/20170901141119_truncate_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class TruncatePreviewCards < ActiveRecord::Migration[5.1] def up rename_table :preview_cards, :deprecated_preview_cards diff --git a/db/migrate/20170901142658_create_join_table_preview_cards_statuses.rb b/db/migrate/20170901142658_create_join_table_preview_cards_statuses.rb index be7f533b50..34808877eb 100644 --- a/db/migrate/20170901142658_create_join_table_preview_cards_statuses.rb +++ b/db/migrate/20170901142658_create_join_table_preview_cards_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateJoinTablePreviewCardsStatuses < ActiveRecord::Migration[5.1] def change create_join_table :preview_cards, :statuses do |t| diff --git a/db/migrate/20170905044538_add_index_id_account_id_activity_type_on_notifications.rb b/db/migrate/20170905044538_add_index_id_account_id_activity_type_on_notifications.rb index c47cea9e26..cb86555cf1 100644 --- a/db/migrate/20170905044538_add_index_id_account_id_activity_type_on_notifications.rb +++ b/db/migrate/20170905044538_add_index_id_account_id_activity_type_on_notifications.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexIdAccountIdActivityTypeOnNotifications < ActiveRecord::Migration[5.1] def change add_index :notifications, [:id, :account_id, :activity_type], order: { id: :desc } diff --git a/db/migrate/20170905165803_add_local_to_statuses.rb b/db/migrate/20170905165803_add_local_to_statuses.rb index fb4e7019df..cb6307c265 100644 --- a/db/migrate/20170905165803_add_local_to_statuses.rb +++ b/db/migrate/20170905165803_add_local_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLocalToStatuses < ActiveRecord::Migration[5.1] def change add_column :statuses, :local, :boolean, null: true, default: nil diff --git a/db/migrate/20170913000752_create_site_uploads.rb b/db/migrate/20170913000752_create_site_uploads.rb index 2246e48cdd..43a793806f 100644 --- a/db/migrate/20170913000752_create_site_uploads.rb +++ b/db/migrate/20170913000752_create_site_uploads.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateSiteUploads < ActiveRecord::Migration[5.1] def change create_table :site_uploads do |t| diff --git a/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb b/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb new file mode 100644 index 0000000000..d9866dfdee --- /dev/null +++ b/db/migrate/20170914032032_default_existing_mutes_to_hiding_notifications.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# This migration is glitch-soc-only because mutes were originally developed in +# glitch-soc and the default value changed when submitting the code upstream. + +# This migration originally changed existing values to `true`, but this has +# been dropped as to not cause issues when migrating from upstream. + +class DefaultExistingMutesToHidingNotifications < ActiveRecord::Migration[5.1] + def up + change_column_default :mutes, :hide_notifications, from: false, to: true + end +end diff --git a/db/migrate/20170917153509_create_custom_emojis.rb b/db/migrate/20170917153509_create_custom_emojis.rb index 4040c83125..984fcd2181 100644 --- a/db/migrate/20170917153509_create_custom_emojis.rb +++ b/db/migrate/20170917153509_create_custom_emojis.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateCustomEmojis < ActiveRecord::Migration[5.1] def change create_table :custom_emojis do |t| diff --git a/db/migrate/20170918125918_ids_to_bigints.rb b/db/migrate/20170918125918_ids_to_bigints.rb index bf875e4e59..83c5ab971b 100644 --- a/db/migrate/20170918125918_ids_to_bigints.rb +++ b/db/migrate/20170918125918_ids_to_bigints.rb @@ -1,7 +1,11 @@ -require Rails.root.join('lib', 'mastodon', 'migration_helpers') +# frozen_string_literal: true + +require_relative '../../lib/mastodon/migration_helpers' +require_relative '../../lib/mastodon/migration_warning' class IdsToBigints < ActiveRecord::Migration[5.1] include Mastodon::MigrationHelpers + include Mastodon::MigrationWarning disable_ddl_transaction! @@ -69,24 +73,12 @@ class IdsToBigints < ActiveRecord::Migration[5.1] ] included_columns << [:deprecated_preview_cards, :id] if table_exists?(:deprecated_preview_cards) - # Print out a warning that this will probably take a while. - if $stdout.isatty - say '' - say 'WARNING: This migration may take a *long* time for large instances' - say 'It will *not* lock tables for any significant time, but it may run' - say 'for a very long time. We will pause for 10 seconds to allow you to' - say 'interrupt this migration if you are not ready.' - say '' - say 'This migration has some sections that can be safely interrupted' - say 'and restarted later, and will tell you when those are occurring.' - say '' - say 'For more information, see https://github.com/mastodon/mastodon/pull/5088' + migration_duration_warning(<<~EXPLANATION) + This migration has some sections that can be safely interrupted + and restarted later, and will tell you when those are occurring. - 10.downto(1) do |i| - say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true - sleep 1 - end - end + For more information, see https://github.com/mastodon/mastodon/pull/5088 + EXPLANATION tables = included_columns.map(&:first).uniq table_sizes = {} diff --git a/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb b/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb index 8679f8ece8..b923373361 100644 --- a/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb +++ b/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + class StatusIdsToTimestampIds < ActiveRecord::Migration[5.1] def up # Prepare the function we will use to generate IDs. Mastodon::Snowflake.define_timestamp_id # Set up the statuses.id column to use our timestamp-based IDs. - ActiveRecord::Base.connection.execute(<<~SQL) + ActiveRecord::Base.connection.execute(<<~SQL.squish) ALTER TABLE statuses ALTER COLUMN id SET DEFAULT timestamp_id('statuses') @@ -21,7 +23,7 @@ class StatusIdsToTimestampIds < ActiveRecord::Migration[5.1] # We lock the table during this so that the ID won't get clobbered, # but ID is indexed, so this should be a fast operation. - ActiveRecord::Base.connection.execute(<<~SQL) + ActiveRecord::Base.connection.execute(<<~SQL.squish) LOCK statuses; SELECT setval('statuses_id_seq', (SELECT MAX(id) FROM statuses)); ALTER TABLE statuses diff --git a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb index 4ab68e8f32..fd6ad39f08 100644 --- a/db/migrate/20170920032311_fix_reblogs_in_feeds.rb +++ b/db/migrate/20170920032311_fix_reblogs_in_feeds.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + class FixReblogsInFeeds < ActiveRecord::Migration[5.1] def up - redis = Redis.current + redis = RedisConfiguration.pool.checkout fm = FeedManager.instance # Old scheme: diff --git a/db/migrate/20170924022025_ids_to_bigints2.rb b/db/migrate/20170924022025_ids_to_bigints2.rb index db8ccd919a..f194d0e494 100644 --- a/db/migrate/20170924022025_ids_to_bigints2.rb +++ b/db/migrate/20170924022025_ids_to_bigints2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class IdsToBigints2 < ActiveRecord::Migration[5.1] def up change_column :statuses_tags, :tag_id, :bigint diff --git a/db/migrate/20170927215609_add_description_to_media_attachments.rb b/db/migrate/20170927215609_add_description_to_media_attachments.rb index db8d765664..8d27d4756c 100644 --- a/db/migrate/20170927215609_add_description_to_media_attachments.rb +++ b/db/migrate/20170927215609_add_description_to_media_attachments.rb @@ -1,4 +1,6 @@ -class AddDescriptionToMediaAttachments < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddDescriptionToMediaAttachments < ActiveRecord::Migration[5.2] def change add_column :media_attachments, :description, :text end diff --git a/db/migrate/20170928082043_create_email_domain_blocks.rb b/db/migrate/20170928082043_create_email_domain_blocks.rb index 1f0fb75875..0af561680b 100644 --- a/db/migrate/20170928082043_create_email_domain_blocks.rb +++ b/db/migrate/20170928082043_create_email_domain_blocks.rb @@ -1,4 +1,6 @@ -class CreateEmailDomainBlocks < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateEmailDomainBlocks < ActiveRecord::Migration[5.2] def change create_table :email_domain_blocks do |t| t.string :domain, null: false diff --git a/db/migrate/20171005102658_create_account_moderation_notes.rb b/db/migrate/20171005102658_create_account_moderation_notes.rb index 010b94586e..254da20ef3 100644 --- a/db/migrate/20171005102658_create_account_moderation_notes.rb +++ b/db/migrate/20171005102658_create_account_moderation_notes.rb @@ -1,4 +1,6 @@ -class CreateAccountModerationNotes < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateAccountModerationNotes < ActiveRecord::Migration[5.2] def change create_table :account_moderation_notes do |t| t.text :content, null: false diff --git a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb index 067a7bee0c..d6fd228f95 100644 --- a/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb +++ b/db/migrate/20171005171936_add_disabled_to_custom_emojis.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddDisabledToCustomEmojis < ActiveRecord::Migration[5.1] +class AddDisabledToCustomEmojis < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20171006142024_add_uri_to_custom_emojis.rb b/db/migrate/20171006142024_add_uri_to_custom_emojis.rb index 04dfcf397c..a9d760d04b 100644 --- a/db/migrate/20171006142024_add_uri_to_custom_emojis.rb +++ b/db/migrate/20171006142024_add_uri_to_custom_emojis.rb @@ -1,4 +1,6 @@ -class AddUriToCustomEmojis < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddUriToCustomEmojis < ActiveRecord::Migration[5.2] def change add_column :custom_emojis, :uri, :string add_column :custom_emojis, :image_remote_url, :string diff --git a/db/migrate/20171009222537_create_keyword_mutes.rb b/db/migrate/20171009222537_create_keyword_mutes.rb new file mode 100644 index 0000000000..77c88b0a53 --- /dev/null +++ b/db/migrate/20171009222537_create_keyword_mutes.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CreateKeywordMutes < ActiveRecord::Migration[5.1] + def change + create_table :keyword_mutes do |t| + t.references :account, null: false + t.string :keyword, null: false + t.boolean :whole_word, null: false, default: true + t.timestamps + end + + safety_assured { add_foreign_key :keyword_mutes, :accounts, on_delete: :cascade } + end +end diff --git a/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb b/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb index cdcd159349..c66a61ffee 100644 --- a/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb +++ b/db/migrate/20171010023049_add_foreign_key_to_account_moderation_notes.rb @@ -1,4 +1,6 @@ -class AddForeignKeyToAccountModerationNotes < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddForeignKeyToAccountModerationNotes < ActiveRecord::Migration[5.2] def change safety_assured { add_foreign_key :account_moderation_notes, :accounts } end diff --git a/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb b/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb index 1d7a0086c2..02ccf5b452 100644 --- a/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb +++ b/db/migrate/20171010025614_change_accounts_nonnullable_in_account_moderation_notes.rb @@ -1,4 +1,6 @@ -class ChangeAccountsNonnullableInAccountModerationNotes < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class ChangeAccountsNonnullableInAccountModerationNotes < ActiveRecord::Migration[5.2] def change safety_assured do change_column_null :account_moderation_notes, :account_id, false diff --git a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb index 60a2871015..2874066d0d 100644 --- a/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb +++ b/db/migrate/20171020084748_add_visible_in_picker_to_custom_emoji.rb @@ -1,7 +1,9 @@ -class AddVisibleInPickerToCustomEmoji < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddVisibleInPickerToCustomEmoji < ActiveRecord::Migration[5.2] def change - safety_assured { + safety_assured do add_column :custom_emojis, :visible_in_picker, :boolean, default: true, null: false - } + end end end diff --git a/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb b/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb new file mode 100644 index 0000000000..b6ea537c2c --- /dev/null +++ b/db/migrate/20171021191900_move_keyword_mutes_into_glitch_namespace.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class MoveKeywordMutesIntoGlitchNamespace < ActiveRecord::Migration[5.1] + def change + safety_assured do + rename_table :keyword_mutes, :glitch_keyword_mutes + end + end +end diff --git a/db/migrate/20171028221157_add_reblogs_to_follows.rb b/db/migrate/20171028221157_add_reblogs_to_follows.rb index 3b2e46ed8a..0dab84c799 100644 --- a/db/migrate/20171028221157_add_reblogs_to_follows.rb +++ b/db/migrate/20171028221157_add_reblogs_to_follows.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddReblogsToFollows < ActiveRecord::Migration[5.1] +class AddReblogsToFollows < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20171107143332_add_memorial_to_accounts.rb b/db/migrate/20171107143332_add_memorial_to_accounts.rb index f3e012ce8b..3cf782b81f 100644 --- a/db/migrate/20171107143332_add_memorial_to_accounts.rb +++ b/db/migrate/20171107143332_add_memorial_to_accounts.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddMemorialToAccounts < ActiveRecord::Migration[5.1] +class AddMemorialToAccounts < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20171107143624_add_disabled_to_users.rb b/db/migrate/20171107143624_add_disabled_to_users.rb index a71cac1c61..4ab4df7372 100644 --- a/db/migrate/20171107143624_add_disabled_to_users.rb +++ b/db/migrate/20171107143624_add_disabled_to_users.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddDisabledToUsers < ActiveRecord::Migration[5.1] +class AddDisabledToUsers < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20171109012327_add_moderator_to_accounts.rb b/db/migrate/20171109012327_add_moderator_to_accounts.rb index ddd87583a7..e8fc313c8c 100644 --- a/db/migrate/20171109012327_add_moderator_to_accounts.rb +++ b/db/migrate/20171109012327_add_moderator_to_accounts.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddModeratorToAccounts < ActiveRecord::Migration[5.1] +class AddModeratorToAccounts < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb b/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb index 84a341510a..3fc966a9e3 100644 --- a/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb +++ b/db/migrate/20171114080328_add_index_domain_to_email_domain_blocks.rb @@ -1,4 +1,6 @@ -class AddIndexDomainToEmailDomainBlocks < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddIndexDomainToEmailDomainBlocks < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change diff --git a/db/migrate/20171114231651_create_lists.rb b/db/migrate/20171114231651_create_lists.rb index 21285e9016..4103d38e4f 100644 --- a/db/migrate/20171114231651_create_lists.rb +++ b/db/migrate/20171114231651_create_lists.rb @@ -1,4 +1,6 @@ -class CreateLists < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateLists < ActiveRecord::Migration[5.2] def change create_table :lists do |t| t.references :account, foreign_key: { on_delete: :cascade } diff --git a/db/migrate/20171116161857_create_list_accounts.rb b/db/migrate/20171116161857_create_list_accounts.rb index b76c906511..ff9ab3faad 100644 --- a/db/migrate/20171116161857_create_list_accounts.rb +++ b/db/migrate/20171116161857_create_list_accounts.rb @@ -1,4 +1,6 @@ -class CreateListAccounts < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateListAccounts < ActiveRecord::Migration[5.2] def change create_table :list_accounts do |t| t.belongs_to :list, foreign_key: { on_delete: :cascade }, null: false diff --git a/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb b/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb index 586ef6f02d..21915426f4 100644 --- a/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb +++ b/db/migrate/20171118012443_add_moved_to_account_id_to_accounts.rb @@ -1,4 +1,6 @@ -class AddMovedToAccountIdToAccounts < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddMovedToAccountIdToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :moved_to_account_id, :bigint, null: true, default: nil safety_assured { add_foreign_key :accounts, :accounts, column: :moved_to_account_id, on_delete: :nullify } diff --git a/db/migrate/20171119172437_create_admin_action_logs.rb b/db/migrate/20171119172437_create_admin_action_logs.rb index b690735d26..a1758bdfcf 100644 --- a/db/migrate/20171119172437_create_admin_action_logs.rb +++ b/db/migrate/20171119172437_create_admin_action_logs.rb @@ -1,4 +1,6 @@ -class CreateAdminActionLogs < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateAdminActionLogs < ActiveRecord::Migration[5.2] def change create_table :admin_action_logs do |t| t.belongs_to :account, foreign_key: { on_delete: :cascade } diff --git a/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb b/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb index 131e54b72e..556427d126 100644 --- a/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb +++ b/db/migrate/20171122120436_add_index_account_and_reblog_of_id_to_statuses.rb @@ -1,4 +1,6 @@ -class AddIndexAccountAndReblogOfIdToStatuses < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddIndexAccountAndReblogOfIdToStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up diff --git a/db/migrate/20171125024930_create_invites.rb b/db/migrate/20171125024930_create_invites.rb index bcf03bd723..4219b26f47 100644 --- a/db/migrate/20171125024930_create_invites.rb +++ b/db/migrate/20171125024930_create_invites.rb @@ -1,4 +1,6 @@ -class CreateInvites < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateInvites < ActiveRecord::Migration[5.2] def change create_table :invites do |t| t.belongs_to :user, foreign_key: { on_delete: :cascade } diff --git a/db/migrate/20171125031751_add_invite_id_to_users.rb b/db/migrate/20171125031751_add_invite_id_to_users.rb index 9cfb0c542c..45eadef157 100644 --- a/db/migrate/20171125031751_add_invite_id_to_users.rb +++ b/db/migrate/20171125031751_add_invite_id_to_users.rb @@ -1,4 +1,6 @@ -class AddInviteIdToUsers < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddInviteIdToUsers < ActiveRecord::Migration[5.2] def change safety_assured { add_reference :users, :invite, null: true, default: nil, foreign_key: { on_delete: :nullify }, index: false } end diff --git a/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb b/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb index 37662eaa5d..80556438bc 100644 --- a/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb +++ b/db/migrate/20171125185353_add_index_reblog_of_id_and_account_to_statuses.rb @@ -1,4 +1,6 @@ -class AddIndexReblogOfIdAndAccountToStatuses < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddIndexReblogOfIdAndAccountToStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change diff --git a/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb b/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb index 68146c5ce0..14a6888a72 100644 --- a/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb +++ b/db/migrate/20171125190735_remove_old_reblog_index_on_statuses.rb @@ -1,4 +1,6 @@ -class RemoveOldReblogIndexOnStatuses < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class RemoveOldReblogIndexOnStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up diff --git a/db/migrate/20171129172043_add_index_on_stream_entries.rb b/db/migrate/20171129172043_add_index_on_stream_entries.rb index 181c4f2882..c959135c22 100644 --- a/db/migrate/20171129172043_add_index_on_stream_entries.rb +++ b/db/migrate/20171129172043_add_index_on_stream_entries.rb @@ -1,4 +1,6 @@ -class AddIndexOnStreamEntries < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddIndexOnStreamEntries < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change diff --git a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb index 8fcabef9fd..e78373b24c 100644 --- a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb +++ b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.1] +class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb b/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb index ac86c9e777..4aa9027c05 100644 --- a/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb +++ b/db/migrate/20171201000000_change_account_id_nonnullable_in_lists.rb @@ -1,4 +1,6 @@ -class ChangeAccountIdNonnullableInLists < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class ChangeAccountIdNonnullableInLists < ActiveRecord::Migration[5.2] def change safety_assured do change_column_null :lists, :account_id, false diff --git a/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb b/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb new file mode 100644 index 0000000000..010503b10f --- /dev/null +++ b/db/migrate/20171210213213_add_local_only_flag_to_statuses.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddLocalOnlyFlagToStatuses < ActiveRecord::Migration[5.1] + def change + add_column :statuses, :local_only, :boolean + end +end diff --git a/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb b/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb index 03f2591a88..362b1367df 100644 --- a/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb +++ b/db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb @@ -1,6 +1,8 @@ -class RemoveDuplicateIndexesInLists < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class RemoveDuplicateIndexesInLists < ActiveRecord::Migration[5.2] def change - remove_index :list_accounts, name: "index_list_accounts_on_account_id" - remove_index :list_accounts, name: "index_list_accounts_on_list_id" + remove_index :list_accounts, name: 'index_list_accounts_on_account_id' + remove_index :list_accounts, name: 'index_list_accounts_on_list_id' end end diff --git a/db/migrate/20171226094803_more_faster_index_on_notifications.rb b/db/migrate/20171226094803_more_faster_index_on_notifications.rb index 0273a4e7c1..429eab96a1 100644 --- a/db/migrate/20171226094803_more_faster_index_on_notifications.rb +++ b/db/migrate/20171226094803_more_faster_index_on_notifications.rb @@ -1,4 +1,6 @@ -class MoreFasterIndexOnNotifications < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class MoreFasterIndexOnNotifications < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change diff --git a/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb index 401fc5e62e..1531c4dd29 100644 --- a/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb +++ b/db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb @@ -1,4 +1,6 @@ -class AddIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change diff --git a/db/migrate/20180109143959_add_remember_token_to_users.rb b/db/migrate/20180109143959_add_remember_token_to_users.rb index 662905bcbb..0d2185e9e5 100644 --- a/db/migrate/20180109143959_add_remember_token_to_users.rb +++ b/db/migrate/20180109143959_add_remember_token_to_users.rb @@ -1,4 +1,6 @@ -class AddRememberTokenToUsers < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddRememberTokenToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :remember_token, :string, null: true end diff --git a/db/migrate/20180204034416_create_identities.rb b/db/migrate/20180204034416_create_identities.rb index f6f5da910b..c9efe91525 100644 --- a/db/migrate/20180204034416_create_identities.rb +++ b/db/migrate/20180204034416_create_identities.rb @@ -1,7 +1,9 @@ -class CreateIdentities < ActiveRecord::Migration[5.0] +# frozen_string_literal: true + +class CreateIdentities < ActiveRecord::Migration[5.2] def change - create_table :identities do |t| - t.references :user, foreign_key: { on_delete: :cascade } + create_table :identities, id: :integer do |t| + t.references :user, type: :integer, foreign_key: { on_delete: :cascade } t.string :provider, null: false, default: '' t.string :uid, null: false, default: '' diff --git a/db/migrate/20180206000000_change_user_id_nonnullable.rb b/db/migrate/20180206000000_change_user_id_nonnullable.rb index 2d2cf20d38..16e18fce9b 100644 --- a/db/migrate/20180206000000_change_user_id_nonnullable.rb +++ b/db/migrate/20180206000000_change_user_id_nonnullable.rb @@ -1,4 +1,6 @@ -class ChangeUserIdNonnullable < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class ChangeUserIdNonnullable < ActiveRecord::Migration[5.2] def change safety_assured do change_column_null :invites, :user_id, false diff --git a/db/migrate/20180211015820_create_backups.rb b/db/migrate/20180211015820_create_backups.rb index 9725a3e9f3..67ad0f893e 100644 --- a/db/migrate/20180211015820_create_backups.rb +++ b/db/migrate/20180211015820_create_backups.rb @@ -1,4 +1,6 @@ -class CreateBackups < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateBackups < ActiveRecord::Migration[5.2] def change create_table :backups do |t| t.references :user, foreign_key: { on_delete: :nullify } diff --git a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb index 1964b51216..3a427cc30e 100644 --- a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb +++ b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb @@ -1,4 +1,6 @@ -class AddFeaturedCollectionURLToAccounts < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddFeaturedCollectionURLToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :featured_collection_url, :string end diff --git a/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb b/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb index dba789207d..778b900b09 100644 --- a/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb +++ b/db/migrate/20180310000000_change_columns_in_notifications_nonnullable.rb @@ -1,4 +1,6 @@ -class ChangeColumnsInNotificationsNonnullable < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class ChangeColumnsInNotificationsNonnullable < ActiveRecord::Migration[5.2] def change safety_assured do change_column_null :notifications, :activity_id, false diff --git a/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb b/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb index e2d1371d2d..be5ab47677 100644 --- a/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb +++ b/db/migrate/20180402031200_add_assigned_account_id_to_reports.rb @@ -1,4 +1,6 @@ -class AddAssignedAccountIdToReports < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddAssignedAccountIdToReports < ActiveRecord::Migration[5.2] def change safety_assured { add_reference :reports, :assigned_account, null: true, default: nil, foreign_key: { on_delete: :nullify, to_table: :accounts }, index: false } end diff --git a/db/migrate/20180402040909_create_report_notes.rb b/db/migrate/20180402040909_create_report_notes.rb index 429cb45349..40b42abd20 100644 --- a/db/migrate/20180402040909_create_report_notes.rb +++ b/db/migrate/20180402040909_create_report_notes.rb @@ -1,4 +1,6 @@ -class CreateReportNotes < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class CreateReportNotes < ActiveRecord::Migration[5.2] def change create_table :report_notes do |t| t.text :content, null: false diff --git a/db/migrate/20180410204633_add_fields_to_accounts.rb b/db/migrate/20180410204633_add_fields_to_accounts.rb index 5b8c17480f..8e39e6db77 100644 --- a/db/migrate/20180410204633_add_fields_to_accounts.rb +++ b/db/migrate/20180410204633_add_fields_to_accounts.rb @@ -1,4 +1,6 @@ -class AddFieldsToAccounts < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AddFieldsToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :fields, :jsonb end diff --git a/db/migrate/20180410220657_create_bookmarks.rb b/db/migrate/20180410220657_create_bookmarks.rb new file mode 100644 index 0000000000..aba21f5eaa --- /dev/null +++ b/db/migrate/20180410220657_create_bookmarks.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# This migration is a duplicate of 20180831171112 and may get ignored, see +# config/initializers/0_duplicate_migrations.rb + +class CreateBookmarks < ActiveRecord::Migration[5.1] + def change + create_table :bookmarks do |t| + t.references :account, null: false + t.references :status, null: false + + t.timestamps + end + + safety_assured do + add_foreign_key :bookmarks, :accounts, column: :account_id, on_delete: :cascade + add_foreign_key :bookmarks, :statuses, column: :status_id, on_delete: :cascade + end + + add_index :bookmarks, [:account_id, :status_id], unique: true + end +end diff --git a/db/migrate/20180416210259_add_uri_to_relationships.rb b/db/migrate/20180416210259_add_uri_to_relationships.rb index d8eaca450b..4bafffeffb 100644 --- a/db/migrate/20180416210259_add_uri_to_relationships.rb +++ b/db/migrate/20180416210259_add_uri_to_relationships.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddUriToRelationships < ActiveRecord::Migration[5.2] def change add_column :follows, :uri, :string diff --git a/db/migrate/20180506221944_add_actor_type_to_accounts.rb b/db/migrate/20180506221944_add_actor_type_to_accounts.rb index 7cfed640f7..38b2c3b63c 100644 --- a/db/migrate/20180506221944_add_actor_type_to_accounts.rb +++ b/db/migrate/20180506221944_add_actor_type_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddActorTypeToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :actor_type, :string diff --git a/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb b/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb index f607165328..5426d3bbbb 100644 --- a/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb +++ b/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAccessTokenIdToWebPushSubscriptions < ActiveRecord::Migration[5.2] def change safety_assured do diff --git a/db/migrate/20180510230049_migrate_web_push_subscriptions.rb b/db/migrate/20180510230049_migrate_web_push_subscriptions.rb index 6de1bed795..a9c0be49a3 100644 --- a/db/migrate/20180510230049_migrate_web_push_subscriptions.rb +++ b/db/migrate/20180510230049_migrate_web_push_subscriptions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MigrateWebPushSubscriptions < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb index b29e62803c..48d156bef4 100644 --- a/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb +++ b/db/migrate/20180514130000_improve_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -class ImproveIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.1] +class ImproveIndexOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change - # These changes ware reverted by migration 20180514140000. - # add_index :statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently - # add_index :statuses, [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently - # remove_index :statuses, column: [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 + # These changes were reverted by migration 20180514140000. + # add_index :statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently + # add_index :statuses, [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently + # remove_index :statuses, column: [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 end end diff --git a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb index ccd2ec7eac..242ae74107 100644 --- a/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb +++ b/db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true -class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.1] +class RevertIndexChangeOnStatusesForApiV1AccountsAccountIdStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! def change safety_assured do - add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, "index_statuses_20180106") + add_index :statuses, [:account_id, :id, :visibility, :updated_at], order: { id: :desc }, algorithm: :concurrently, name: :index_statuses_20180106 unless index_name_exists?(:statuses, 'index_statuses_20180106') end # These index may not exists (see migration 20180514130000) remove_index :statuses, column: [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)', algorithm: :concurrently if index_exists?(:statuses, [:account_id, :id, :visibility], where: 'visibility IN (0, 1, 2)') - remove_index :statuses, column: [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently if index_exists?(:statuses, ["account_id", "id"], where: "(visibility = 3)") + remove_index :statuses, column: [:account_id, :id], where: 'visibility = 3', algorithm: :concurrently if index_exists?(:statuses, %w(account_id id), where: '(visibility = 3)') end end diff --git a/db/migrate/20180528141303_fix_accounts_unique_index.rb b/db/migrate/20180528141303_fix_accounts_unique_index.rb index 3e33e2cac4..d21422b05d 100644 --- a/db/migrate/20180528141303_fix_accounts_unique_index.rb +++ b/db/migrate/20180528141303_fix_accounts_unique_index.rb @@ -1,4 +1,10 @@ +# frozen_string_literal: true + +require_relative '../../lib/mastodon/migration_warning' + class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2] + include Mastodon::MigrationWarning + class Account < ApplicationRecord # Dummy class, to make migration possible across version changes has_one :user, inverse_of: :account @@ -35,22 +41,11 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up - if $stdout.isatty - say '' - say 'WARNING: This migration may take a *long* time for large instances' - say 'It will *not* lock tables for any significant time, but it may run' - say 'for a very long time. We will pause for 10 seconds to allow you to' - say 'interrupt this migration if you are not ready.' - say '' - say 'This migration will irreversibly delete user accounts with duplicate' - say 'usernames. You may use the `rake mastodon:maintenance:find_duplicate_usernames`' - say 'task to manually deal with such accounts before running this migration.' - - 10.downto(1) do |i| - say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true - sleep 1 - end - end + migration_duration_warning(<<~EXPLANATION) + This migration will irreversibly delete user accounts with duplicate + usernames. You may use the `rake mastodon:maintenance:find_duplicate_usernames` + task to manually deal with such accounts before running this migration. + EXPLANATION duplicates = Account.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM accounts GROUP BY lower(username), lower(domain) HAVING count(*) > 1').to_ary @@ -106,21 +101,17 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2] # to check for (and skip past) uniqueness errors [Favourite, Follow, FollowRequest, Block, Mute].each do |klass| klass.where(account_id: duplicate_account.id).find_each do |record| - begin - record.update_attribute(:account_id, main_account.id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:account_id, main_account.id) + rescue ActiveRecord::RecordNotUnique + next end end [Follow, FollowRequest, Block, Mute].each do |klass| klass.where(target_account_id: duplicate_account.id).find_each do |record| - begin - record.update_attribute(:target_account_id, main_account.id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:target_account_id, main_account.id) + rescue ActiveRecord::RecordNotUnique + next end end end diff --git a/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb b/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb new file mode 100644 index 0000000000..8078a07bfc --- /dev/null +++ b/db/migrate/20180604000556_add_apply_to_mentions_flag_to_keyword_mutes.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'mastodon/migration_helpers' + +class AddApplyToMentionsFlagToKeywordMutes < ActiveRecord::Migration[5.2] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured do + add_column_with_default :glitch_keyword_mutes, :apply_to_mentions, :boolean, allow_null: false, default: true + end + end + + def down + remove_column :glitch_keyword_mutes, :apply_to_mentions + end +end diff --git a/db/migrate/20180608213548_reject_following_blocked_users.rb b/db/migrate/20180608213548_reject_following_blocked_users.rb index 78f8df5383..4cb6395469 100644 --- a/db/migrate/20180608213548_reject_following_blocked_users.rb +++ b/db/migrate/20180608213548_reject_following_blocked_users.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + class RejectFollowingBlockedUsers < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up - blocked_follows = Follow.find_by_sql(<<-SQL) + blocked_follows = Follow.find_by_sql(<<-SQL.squish) select f.* from follows f inner join blocks b on f.account_id = b.target_account_id and f.target_account_id = b.account_id SQL - domain_blocked_follows = Follow.find_by_sql(<<-SQL) + domain_blocked_follows = Follow.find_by_sql(<<-SQL.squish) select f.* from follows f inner join accounts following on f.account_id = following.id inner join account_domain_blocks b on diff --git a/db/migrate/20180609104432_migrate_web_push_subscriptions2.rb b/db/migrate/20180609104432_migrate_web_push_subscriptions2.rb index 510db64d23..aed1329df8 100644 --- a/db/migrate/20180609104432_migrate_web_push_subscriptions2.rb +++ b/db/migrate/20180609104432_migrate_web_push_subscriptions2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MigrateWebPushSubscriptions2 < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20180615122121_add_autofollow_to_invites.rb b/db/migrate/20180615122121_add_autofollow_to_invites.rb index 8c5fb74105..ef129003a1 100644 --- a/db/migrate/20180615122121_add_autofollow_to_invites.rb +++ b/db/migrate/20180615122121_add_autofollow_to_invites.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddAutofollowToInvites < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20180616192031_add_chosen_languages_to_users.rb b/db/migrate/20180616192031_add_chosen_languages_to_users.rb index 48b53019d6..eae8d6b4e1 100644 --- a/db/migrate/20180616192031_add_chosen_languages_to_users.rb +++ b/db/migrate/20180616192031_add_chosen_languages_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddChosenLanguagesToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :chosen_languages, :string, array: true, null: true, default: nil diff --git a/db/migrate/20180617162849_remove_unused_indexes.rb b/db/migrate/20180617162849_remove_unused_indexes.rb index 61add63855..14766589fd 100644 --- a/db/migrate/20180617162849_remove_unused_indexes.rb +++ b/db/migrate/20180617162849_remove_unused_indexes.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class RemoveUnusedIndexes < ActiveRecord::Migration[5.2] def change - remove_index :statuses, name: "index_statuses_on_conversation_id" - remove_index :users, name: "index_users_on_filtered_languages" - remove_index :backups, name: "index_backups_on_user_id" + remove_index :statuses, name: 'index_statuses_on_conversation_id' + remove_index :users, name: 'index_users_on_filtered_languages' + remove_index :backups, name: 'index_backups_on_user_id' end end diff --git a/db/migrate/20180628181026_create_custom_filters.rb b/db/migrate/20180628181026_create_custom_filters.rb index d19cf2e9d6..1e7f4463f3 100644 --- a/db/migrate/20180628181026_create_custom_filters.rb +++ b/db/migrate/20180628181026_create_custom_filters.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateCustomFilters < ActiveRecord::Migration[5.2] def change create_table :custom_filters do |t| diff --git a/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb b/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb index 63ecb87415..793c3e6cfb 100644 --- a/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb +++ b/db/migrate/20180707154237_add_whole_word_to_custom_filter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddWholeWordToCustomFilter < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20180707193142_migrate_filters.rb b/db/migrate/20180707193142_migrate_filters.rb new file mode 100644 index 0000000000..8f6b3e1bb0 --- /dev/null +++ b/db/migrate/20180707193142_migrate_filters.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +class MigrateFilters < ActiveRecord::Migration[5.2] + class GlitchKeywordMute < ApplicationRecord + # Dummy class, as we removed Glitch::KeywordMute + belongs_to :account, optional: false + validates_presence_of :keyword + end + + class CustomFilter < ApplicationRecord + # Dummy class, in case CustomFilter gets altered in the future + belongs_to :account + validates :phrase, :context, presence: true + + before_validation :clean_up_contexts + + private + + def clean_up_contexts + self.context = Array(context).map(&:strip).filter_map(&:presence) + end + end + + disable_ddl_transaction! + + def up + GlitchKeywordMute.find_each do |filter| + filter.account.custom_filters.create!( + phrase: filter.keyword, + context: filter.apply_to_mentions ? %w(home public notifications) : %w(home public), + whole_word: filter.whole_word, + irreversible: true + ) + end + end + + def down + unless table_exists? :glitch_keyword_mutes + create_table :glitch_keyword_mutes do |t| + t.references :account, null: false + t.string :keyword, null: false + t.boolean :whole_word, default: true, null: false + t.boolean :apply_to_mentions, default: true, null: false + t.timestamps + end + + safety_assured { add_foreign_key :glitch_keyword_mutes, :accounts, on_delete: :cascade } + end + + CustomFilter.where(irreversible: true).find_each do |filter| + GlitchKeywordMute.where(account: filter.account).create!( + keyword: filter.phrase, + whole_word: filter.whole_word, + apply_to_mentions: filter.context.include?('notifications') + ) + end + end +end diff --git a/db/migrate/20180711152640_create_relays.rb b/db/migrate/20180711152640_create_relays.rb index 8762f473a2..2d2f546d16 100644 --- a/db/migrate/20180711152640_create_relays.rb +++ b/db/migrate/20180711152640_create_relays.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateRelays < ActiveRecord::Migration[5.2] def change create_table :relays do |t| diff --git a/db/migrate/20180808175627_create_account_pins.rb b/db/migrate/20180808175627_create_account_pins.rb index 43d8185be9..551496c342 100644 --- a/db/migrate/20180808175627_create_account_pins.rb +++ b/db/migrate/20180808175627_create_account_pins.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountPins < ActiveRecord::Migration[5.2] def change create_table :account_pins do |t| diff --git a/db/migrate/20180812123222_change_relays_enabled.rb b/db/migrate/20180812123222_change_relays_enabled.rb index c4fd8179be..7424b91c7e 100644 --- a/db/migrate/20180812123222_change_relays_enabled.rb +++ b/db/migrate/20180812123222_change_relays_enabled.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ChangeRelaysEnabled < ActiveRecord::Migration[5.2] def up # The relays table is supposed to be very small, diff --git a/db/migrate/20180812162710_create_status_stats.rb b/db/migrate/20180812162710_create_status_stats.rb index d4da36fe78..882efce833 100644 --- a/db/migrate/20180812162710_create_status_stats.rb +++ b/db/migrate/20180812162710_create_status_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStatusStats < ActiveRecord::Migration[5.2] def change create_table :status_stats do |t| diff --git a/db/migrate/20180812173710_copy_status_stats.rb b/db/migrate/20180812173710_copy_status_stats.rb index ff10c18d9d..52ab43b762 100644 --- a/db/migrate/20180812173710_copy_status_stats.rb +++ b/db/migrate/20180812173710_copy_status_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CopyStatusStats < ActiveRecord::Migration[5.2] disable_ddl_transaction! @@ -19,7 +21,7 @@ class CopyStatusStats < ActiveRecord::Migration[5.2] def supports_upsert? version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i - version >= 90500 + version >= 90_500 end def up_fast @@ -43,12 +45,10 @@ class CopyStatusStats < ActiveRecord::Migration[5.2] # We cannot use bulk INSERT or overarching transactions here because of possible # uniqueness violations that we need to skip over Status.unscoped.select('id, reblogs_count, favourites_count, created_at, updated_at').find_each do |status| - begin - params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]] - exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params) - rescue ActiveRecord::RecordNotUnique - next - end + params = [status.id, status.reblogs_count, status.favourites_count, status.created_at, status.updated_at] + exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params) + rescue ActiveRecord::RecordNotUnique + next end end end diff --git a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb index 7077a4e659..7360c71ac9 100644 --- a/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb +++ b/db/migrate/20180814171349_add_confidential_to_doorkeeper_application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddConfidentialToDoorkeeperApplication < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20180831171112_create_bookmarks.rb b/db/migrate/20180831171112_create_bookmarks.rb index 27c7339c9a..4fa4c323d6 100644 --- a/db/migrate/20180831171112_create_bookmarks.rb +++ b/db/migrate/20180831171112_create_bookmarks.rb @@ -1,4 +1,9 @@ -class CreateBookmarks < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +# This migration is a duplicate of 20180410220657 and may get ignored, see +# config/initializers/0_duplicate_migrations.rb + +class CreateBookmarks < ActiveRecord::Migration[5.2] def change create_table :bookmarks do |t| t.references :account, null: false diff --git a/db/migrate/20180929222014_create_account_conversations.rb b/db/migrate/20180929222014_create_account_conversations.rb index 53fa137e15..9386b86e7c 100644 --- a/db/migrate/20180929222014_create_account_conversations.rb +++ b/db/migrate/20180929222014_create_account_conversations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountConversations < ActiveRecord::Migration[5.2] def change create_table :account_conversations do |t| diff --git a/db/migrate/20181007025445_create_pghero_space_stats.rb b/db/migrate/20181007025445_create_pghero_space_stats.rb index 6198a6f846..ddaf4aef31 100644 --- a/db/migrate/20181007025445_create_pghero_space_stats.rb +++ b/db/migrate/20181007025445_create_pghero_space_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreatePgheroSpaceStats < ActiveRecord::Migration[5.2] def change create_table :pghero_space_stats do |t| diff --git a/db/migrate/20181010141500_add_silent_to_mentions.rb b/db/migrate/20181010141500_add_silent_to_mentions.rb index dbb4fba263..f9bfc51694 100644 --- a/db/migrate/20181010141500_add_silent_to_mentions.rb +++ b/db/migrate/20181010141500_add_silent_to_mentions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddSilentToMentions < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb index f05d50fcd9..b6cfd31d25 100644 --- a/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb +++ b/db/migrate/20181017170937_add_reject_reports_to_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddRejectReportsToDomainBlocks < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20181018205649_add_unread_to_account_conversations.rb b/db/migrate/20181018205649_add_unread_to_account_conversations.rb index 3c28b9a641..fec9476398 100644 --- a/db/migrate/20181018205649_add_unread_to_account_conversations.rb +++ b/db/migrate/20181018205649_add_unread_to_account_conversations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddUnreadToAccountConversations < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20181024224956_migrate_account_conversations.rb b/db/migrate/20181024224956_migrate_account_conversations.rb index 9e6497d81f..93ef5da615 100644 --- a/db/migrate/20181024224956_migrate_account_conversations.rb +++ b/db/migrate/20181024224956_migrate_account_conversations.rb @@ -1,9 +1,35 @@ +# frozen_string_literal: true + +require_relative '../../lib/mastodon/migration_warning' + class MigrateAccountConversations < ActiveRecord::Migration[5.2] + include Mastodon::MigrationWarning + disable_ddl_transaction! - class Mention < ApplicationRecord - belongs_to :account, inverse_of: :mentions - belongs_to :status, -> { unscope(where: :deleted_at) } + class MigrationAccount < ApplicationRecord + self.table_name = :accounts + has_many :mentions, inverse_of: :account, dependent: :destroy, class_name: 'MigrationMention', foreign_key: :account_id + end + + class MigrationConversation < ApplicationRecord + self.table_name = :conversations + end + + class MigrationStatus < ApplicationRecord + self.table_name = :statuses + belongs_to :account, class_name: 'MigrationAccount' + has_many :mentions, dependent: :destroy, inverse_of: :status, class_name: 'MigrationMention', foreign_key: :status_id + scope :local, -> { where(local: true).or(where(uri: nil)) } + enum visibility: { public: 0, unlisted: 1, private: 2, direct: 3, limited: 4 }, _suffix: :visibility + has_many :active_mentions, -> { active }, class_name: 'MigrationMention', inverse_of: :status, foreign_key: :status_id + end + + class MigrationMention < ApplicationRecord + self.table_name = :mentions + belongs_to :account, inverse_of: :mentions, class_name: 'MigrationAccount' + belongs_to :status, -> { unscope(where: :deleted_at) }, class_name: 'MigrationStatus' + scope :active, -> { where(silent: false) } delegate( :username, @@ -13,22 +39,24 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] ) end - class Notification < ApplicationRecord - belongs_to :account, optional: true + class MigrationNotification < ApplicationRecord + self.table_name = :notifications + belongs_to :account, optional: true, class_name: 'MigrationAccount' belongs_to :activity, polymorphic: true, optional: true - belongs_to :status, foreign_key: 'activity_id', optional: true - belongs_to :mention, foreign_key: 'activity_id', optional: true + belongs_to :status, foreign_key: 'activity_id', optional: true, class_name: 'MigrationStatus' + belongs_to :mention, foreign_key: 'activity_id', optional: true, class_name: 'MigrationMention' def target_status mention&.status end end - class AccountConversation < ApplicationRecord - belongs_to :account - belongs_to :conversation - belongs_to :last_status, -> { unscope(where: :deleted_at) }, class_name: 'Status' + class MigrationAccountConversation < ApplicationRecord + self.table_name = :account_conversations + belongs_to :account, class_name: 'MigrationAccount' + belongs_to :conversation, class_name: 'MigrationConversation' + belongs_to :last_status, -> { unscope(where: :deleted_at) }, class_name: 'MigrationStatus' before_validation :set_last_status @@ -62,25 +90,13 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] end def up - if $stdout.isatty - say '' - say 'WARNING: This migration may take a *long* time for large instances' - say 'It will *not* lock tables for any significant time, but it may run' - say 'for a very long time. We will pause for 10 seconds to allow you to' - say 'interrupt this migration if you are not ready.' - say '' - - 10.downto(1) do |i| - say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true - sleep 1 - end - end + migration_duration_warning migrated = 0 last_time = Time.zone.now local_direct_statuses.includes(:account, mentions: :account).find_each do |status| - AccountConversation.add_status(status.account, status) + MigrationAccountConversation.add_status(status.account, status) migrated += 1 if Time.zone.now - last_time > 1 @@ -90,7 +106,7 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] end notifications_about_direct_statuses.includes(:account, mention: { status: [:account, mentions: :account] }).find_each do |notification| - AccountConversation.add_status(notification.account, notification.target_status) + MigrationAccountConversation.add_status(notification.account, notification.target_status) migrated += 1 if Time.zone.now - last_time > 1 @@ -100,8 +116,7 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] end end - def down - end + def down; end private @@ -110,10 +125,10 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] end def local_direct_statuses - Status.unscoped.local.where(visibility: :direct) + MigrationStatus.unscoped.local.where(visibility: :direct) end def notifications_about_direct_statuses - Notification.joins('INNER JOIN mentions ON mentions.id = notifications.activity_id INNER JOIN statuses ON statuses.id = mentions.status_id').where(activity_type: 'Mention', statuses: { visibility: :direct }) + MigrationNotification.joins('INNER JOIN mentions ON mentions.id = notifications.activity_id INNER JOIN statuses ON statuses.id = mentions.status_id').where(activity_type: 'Mention', statuses: { visibility: :direct }) end end diff --git a/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb b/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb index 40537e9c9e..12998f0af8 100644 --- a/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb +++ b/db/migrate/20181026034033_remove_faux_remote_account_duplicates.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveFauxRemoteAccountDuplicates < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20181116165755_create_account_stats.rb b/db/migrate/20181116165755_create_account_stats.rb index a798e8166e..e21c499486 100644 --- a/db/migrate/20181116165755_create_account_stats.rb +++ b/db/migrate/20181116165755_create_account_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountStats < ActiveRecord::Migration[5.2] def change create_table :account_stats do |t| diff --git a/db/migrate/20181116173541_copy_account_stats.rb b/db/migrate/20181116173541_copy_account_stats.rb index 8e27eb11b5..30d07764ef 100644 --- a/db/migrate/20181116173541_copy_account_stats.rb +++ b/db/migrate/20181116173541_copy_account_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CopyAccountStats < ActiveRecord::Migration[5.2] disable_ddl_transaction! @@ -19,7 +21,7 @@ class CopyAccountStats < ActiveRecord::Migration[5.2] def supports_upsert? version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i - version >= 90500 + version >= 90_500 end def up_fast @@ -43,12 +45,10 @@ class CopyAccountStats < ActiveRecord::Migration[5.2] # We cannot use bulk INSERT or overarching transactions here because of possible # uniqueness violations that we need to skip over Account.unscoped.select('id, statuses_count, following_count, followers_count, created_at, updated_at').find_each do |account| - begin - params = [[nil, account.id], [nil, account[:statuses_count]], [nil, account[:following_count]], [nil, account[:followers_count]], [nil, account.created_at], [nil, account.updated_at]] - exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params) - rescue ActiveRecord::RecordNotUnique - next - end + params = [account.id, account[:statuses_count], account[:following_count], account[:followers_count], account.created_at, account.updated_at] + exec_insert('INSERT INTO account_stats (account_id, statuses_count, following_count, followers_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6)', nil, params) + rescue ActiveRecord::RecordNotUnique + next end end end diff --git a/db/migrate/20181127130500_identity_id_to_bigint.rb b/db/migrate/20181127130500_identity_id_to_bigint.rb index 5f388aca7c..51420c79d6 100644 --- a/db/migrate/20181127130500_identity_id_to_bigint.rb +++ b/db/migrate/20181127130500_identity_id_to_bigint.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class IdentityIdToBigint < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20181127165847_add_show_replies_to_lists.rb b/db/migrate/20181127165847_add_show_replies_to_lists.rb index f68c98dafc..45d457b748 100644 --- a/db/migrate/20181127165847_add_show_replies_to_lists.rb +++ b/db/migrate/20181127165847_add_show_replies_to_lists.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddShowRepliesToLists < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20181203003808_create_accounts_tags_join_table.rb b/db/migrate/20181203003808_create_accounts_tags_join_table.rb index 3c275c2b78..4344176472 100644 --- a/db/migrate/20181203003808_create_accounts_tags_join_table.rb +++ b/db/migrate/20181203003808_create_accounts_tags_join_table.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountsTagsJoinTable < ActiveRecord::Migration[5.2] def change create_join_table :accounts, :tags do |t| diff --git a/db/migrate/20181203021853_add_discoverable_to_accounts.rb b/db/migrate/20181203021853_add_discoverable_to_accounts.rb index 5bbae2203e..16576aa043 100644 --- a/db/migrate/20181203021853_add_discoverable_to_accounts.rb +++ b/db/migrate/20181203021853_add_discoverable_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDiscoverableToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :discoverable, :boolean diff --git a/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb b/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb index 9466627071..dc1c6084b1 100644 --- a/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb +++ b/db/migrate/20181204193439_add_last_status_at_to_account_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLastStatusAtToAccountStats < ActiveRecord::Migration[5.2] def change add_column :account_stats, :last_status_at, :datetime diff --git a/db/migrate/20181204215309_create_account_tag_stats.rb b/db/migrate/20181204215309_create_account_tag_stats.rb index 15ed8587e3..1d4477c9c5 100644 --- a/db/migrate/20181204215309_create_account_tag_stats.rb +++ b/db/migrate/20181204215309_create_account_tag_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountTagStats < ActiveRecord::Migration[5.2] def change create_table :account_tag_stats do |t| diff --git a/db/migrate/20181207011115_downcase_custom_emoji_domains.rb b/db/migrate/20181207011115_downcase_custom_emoji_domains.rb index e27e0249d9..3f3da937a5 100644 --- a/db/migrate/20181207011115_downcase_custom_emoji_domains.rb +++ b/db/migrate/20181207011115_downcase_custom_emoji_domains.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class DowncaseCustomEmojiDomains < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20181213184704_create_account_warnings.rb b/db/migrate/20181213184704_create_account_warnings.rb index e768be2778..35989c986f 100644 --- a/db/migrate/20181213184704_create_account_warnings.rb +++ b/db/migrate/20181213184704_create_account_warnings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountWarnings < ActiveRecord::Migration[5.2] def change create_table :account_warnings do |t| diff --git a/db/migrate/20181213185533_create_account_warning_presets.rb b/db/migrate/20181213185533_create_account_warning_presets.rb index 9c81f1b5e6..f8a1017136 100644 --- a/db/migrate/20181213185533_create_account_warning_presets.rb +++ b/db/migrate/20181213185533_create_account_warning_presets.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountWarningPresets < ActiveRecord::Migration[5.2] def change create_table :account_warning_presets do |t| diff --git a/db/migrate/20181219235220_add_created_by_application_id_to_users.rb b/db/migrate/20181219235220_add_created_by_application_id_to_users.rb index 81c9237e83..0663d9c109 100644 --- a/db/migrate/20181219235220_add_created_by_application_id_to_users.rb +++ b/db/migrate/20181219235220_add_created_by_application_id_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddCreatedByApplicationIdToUsers < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20181226021420_add_also_known_as_to_accounts.rb b/db/migrate/20181226021420_add_also_known_as_to_accounts.rb index 1fd9566803..b0310fc324 100644 --- a/db/migrate/20181226021420_add_also_known_as_to_accounts.rb +++ b/db/migrate/20181226021420_add_also_known_as_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddAlsoKnownAsToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :also_known_as, :string, array: true diff --git a/db/migrate/20190103124649_create_scheduled_statuses.rb b/db/migrate/20190103124649_create_scheduled_statuses.rb index 2b78073b85..a66546187e 100644 --- a/db/migrate/20190103124649_create_scheduled_statuses.rb +++ b/db/migrate/20190103124649_create_scheduled_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateScheduledStatuses < ActiveRecord::Migration[5.2] def change create_table :scheduled_statuses do |t| diff --git a/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb b/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb index 7d904af60f..d575bdcaf2 100644 --- a/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb +++ b/db/migrate/20190103124754_add_scheduled_status_id_to_media_attachments.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddScheduledStatusIdToMediaAttachments < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20190117114553_create_tombstones.rb b/db/migrate/20190117114553_create_tombstones.rb index 06d6d8c5ad..b25d7964ee 100644 --- a/db/migrate/20190117114553_create_tombstones.rb +++ b/db/migrate/20190117114553_create_tombstones.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateTombstones < ActiveRecord::Migration[5.2] def change create_table :tombstones do |t| diff --git a/db/migrate/20190201012802_add_overwrite_to_imports.rb b/db/migrate/20190201012802_add_overwrite_to_imports.rb index 89b262cc72..fe9423ed04 100644 --- a/db/migrate/20190201012802_add_overwrite_to_imports.rb +++ b/db/migrate/20190201012802_add_overwrite_to_imports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddOverwriteToImports < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20190203180359_create_featured_tags.rb b/db/migrate/20190203180359_create_featured_tags.rb index b08410a3a7..fe525aef83 100644 --- a/db/migrate/20190203180359_create_featured_tags.rb +++ b/db/migrate/20190203180359_create_featured_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateFeaturedTags < ActiveRecord::Migration[5.2] def change create_table :featured_tags do |t| diff --git a/db/migrate/20190225031541_create_polls.rb b/db/migrate/20190225031541_create_polls.rb index ea9ad0425f..33497c5cb6 100644 --- a/db/migrate/20190225031541_create_polls.rb +++ b/db/migrate/20190225031541_create_polls.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreatePolls < ActiveRecord::Migration[5.2] def change create_table :polls do |t| diff --git a/db/migrate/20190225031625_create_poll_votes.rb b/db/migrate/20190225031625_create_poll_votes.rb index a0849d3a55..4b0504e82e 100644 --- a/db/migrate/20190225031625_create_poll_votes.rb +++ b/db/migrate/20190225031625_create_poll_votes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreatePollVotes < ActiveRecord::Migration[5.2] def change create_table :poll_votes do |t| diff --git a/db/migrate/20190226003449_add_poll_id_to_statuses.rb b/db/migrate/20190226003449_add_poll_id_to_statuses.rb index 692e8f814f..8d0af7ba0d 100644 --- a/db/migrate/20190226003449_add_poll_id_to_statuses.rb +++ b/db/migrate/20190226003449_add_poll_id_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddPollIdToStatuses < ActiveRecord::Migration[5.2] def change add_column :statuses, :poll_id, :bigint diff --git a/db/migrate/20190304152020_add_uri_to_poll_votes.rb b/db/migrate/20190304152020_add_uri_to_poll_votes.rb index f6b81f1ba3..37a7f0aa89 100644 --- a/db/migrate/20190304152020_add_uri_to_poll_votes.rb +++ b/db/migrate/20190304152020_add_uri_to_poll_votes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddUriToPollVotes < ActiveRecord::Migration[5.2] def change add_column :poll_votes, :uri, :string diff --git a/db/migrate/20190306145741_add_lock_version_to_polls.rb b/db/migrate/20190306145741_add_lock_version_to_polls.rb index 5bb8cd3b48..760818d97b 100644 --- a/db/migrate/20190306145741_add_lock_version_to_polls.rb +++ b/db/migrate/20190306145741_add_lock_version_to_polls.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddLockVersionToPolls < ActiveRecord::Migration[5.2] @@ -21,4 +23,3 @@ class AddLockVersionToPolls < ActiveRecord::Migration[5.2] remove_column :polls, :lock_version end end - diff --git a/db/migrate/20190307234537_add_approved_to_users.rb b/db/migrate/20190307234537_add_approved_to_users.rb index c57a66dbc3..9abab29c93 100644 --- a/db/migrate/20190307234537_add_approved_to_users.rb +++ b/db/migrate/20190307234537_add_approved_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddApprovedToUsers < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20190314181829_migrate_open_registrations_setting.rb b/db/migrate/20190314181829_migrate_open_registrations_setting.rb index e5fe95009e..3b1a963423 100644 --- a/db/migrate/20190314181829_migrate_open_registrations_setting.rb +++ b/db/migrate/20190314181829_migrate_open_registrations_setting.rb @@ -1,7 +1,10 @@ +# frozen_string_literal: true + class MigrateOpenRegistrationsSetting < ActiveRecord::Migration[5.2] def up open_registrations = Setting.find_by(var: 'open_registrations') return if open_registrations.nil? || open_registrations.value + setting = Setting.where(var: 'registrations_mode').first_or_initialize(var: 'registrations_mode') setting.update(value: 'none') end @@ -9,6 +12,7 @@ class MigrateOpenRegistrationsSetting < ActiveRecord::Migration[5.2] def down registrations_mode = Setting.find_by(var: 'registrations_mode') return if registrations_mode.nil? + setting = Setting.where(var: 'open_registrations').first_or_initialize(var: 'open_registrations') setting.update(value: registrations_mode.value == 'open') end diff --git a/db/migrate/20190316190352_create_account_identity_proofs.rb b/db/migrate/20190316190352_create_account_identity_proofs.rb index ddcbce3f36..7055dc37b9 100644 --- a/db/migrate/20190316190352_create_account_identity_proofs.rb +++ b/db/migrate/20190316190352_create_account_identity_proofs.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountIdentityProofs < ActiveRecord::Migration[5.2] def change create_table :account_identity_proofs do |t| diff --git a/db/migrate/20190317135723_add_uri_to_reports.rb b/db/migrate/20190317135723_add_uri_to_reports.rb index 47c0f2a21d..722e6af8ed 100644 --- a/db/migrate/20190317135723_add_uri_to_reports.rb +++ b/db/migrate/20190317135723_add_uri_to_reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddUriToReports < ActiveRecord::Migration[5.2] def change add_column :reports, :uri, :string diff --git a/db/migrate/20190403141604_add_comment_to_invites.rb b/db/migrate/20190403141604_add_comment_to_invites.rb index f0d7b1dcdd..5f87a0fe43 100644 --- a/db/migrate/20190403141604_add_comment_to_invites.rb +++ b/db/migrate/20190403141604_add_comment_to_invites.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddCommentToInvites < ActiveRecord::Migration[5.2] def change add_column :invites, :comment, :text diff --git a/db/migrate/20190409054914_create_user_invite_requests.rb b/db/migrate/20190409054914_create_user_invite_requests.rb index 974e0f69fe..233b5a5584 100644 --- a/db/migrate/20190409054914_create_user_invite_requests.rb +++ b/db/migrate/20190409054914_create_user_invite_requests.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateUserInviteRequests < ActiveRecord::Migration[5.2] def change create_table :user_invite_requests do |t| diff --git a/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb b/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb index f2bbe0a856..0f2f684894 100644 --- a/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb +++ b/db/migrate/20190420025523_add_blurhash_to_media_attachments.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddBlurhashToMediaAttachments < ActiveRecord::Migration[5.2] def change add_column :media_attachments, :blurhash, :string diff --git a/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb b/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb index 80c2448428..656cd0af58 100644 --- a/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb +++ b/db/migrate/20190509164208_add_by_moderator_to_tombstone.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddByModeratorToTombstone < ActiveRecord::Migration[5.2] def change add_column :tombstones, :by_moderator, :boolean diff --git a/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb b/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb index 1e5cd669c3..7301e960d5 100644 --- a/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb +++ b/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSilencedAtSuspendedAtToAccounts < ActiveRecord::Migration[5.2] class Account < ApplicationRecord # Dummy class, to make migration possible across version changes diff --git a/db/migrate/20190512200918_add_content_type_to_statuses.rb b/db/migrate/20190512200918_add_content_type_to_statuses.rb new file mode 100644 index 0000000000..31c1a4f174 --- /dev/null +++ b/db/migrate/20190512200918_add_content_type_to_statuses.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddContentTypeToStatuses < ActiveRecord::Migration[5.2] + def change + add_column :statuses, :content_type, :string + end +end diff --git a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb index 72b7c609d1..88dcea4360 100644 --- a/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb +++ b/db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class PreserveOldLayoutForExistingUsers < ActiveRecord::Migration[5.2] disable_ddl_transaction! @@ -8,10 +10,10 @@ class PreserveOldLayoutForExistingUsers < ActiveRecord::Migration[5.2] User.where(User.arel_table[:current_sign_in_at].gteq(1.month.ago)).find_each do |user| next if Setting.unscoped.where(thing_type: 'User', thing_id: user.id, var: 'advanced_layout').exists? + user.settings.advanced_layout = true end end - def down - end + def down; end end diff --git a/db/migrate/20190627222225_create_custom_emoji_categories.rb b/db/migrate/20190627222225_create_custom_emoji_categories.rb index 4713793e66..5d8a8b49ba 100644 --- a/db/migrate/20190627222225_create_custom_emoji_categories.rb +++ b/db/migrate/20190627222225_create_custom_emoji_categories.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateCustomEmojiCategories < ActiveRecord::Migration[5.2] def change create_table :custom_emoji_categories do |t| diff --git a/db/migrate/20190627222826_add_category_id_to_custom_emojis.rb b/db/migrate/20190627222826_add_category_id_to_custom_emojis.rb index 873b4d05fe..b8d102de57 100644 --- a/db/migrate/20190627222826_add_category_id_to_custom_emojis.rb +++ b/db/migrate/20190627222826_add_category_id_to_custom_emojis.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddCategoryIdToCustomEmojis < ActiveRecord::Migration[5.2] def change add_column :custom_emojis, :category_id, :bigint diff --git a/db/migrate/20190701022101_add_trust_level_to_accounts.rb b/db/migrate/20190701022101_add_trust_level_to_accounts.rb index 917486d2ed..2a906e15f2 100644 --- a/db/migrate/20190701022101_add_trust_level_to_accounts.rb +++ b/db/migrate/20190701022101_add_trust_level_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTrustLevelToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :trust_level, :integer diff --git a/db/migrate/20190705002136_create_domain_allows.rb b/db/migrate/20190705002136_create_domain_allows.rb index 83b0728d9d..cdd8c65d65 100644 --- a/db/migrate/20190705002136_create_domain_allows.rb +++ b/db/migrate/20190705002136_create_domain_allows.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateDomainAllows < ActiveRecord::Migration[5.2] def change create_table :domain_allows do |t| diff --git a/db/migrate/20190715164535_add_instance_actor.rb b/db/migrate/20190715164535_add_instance_actor.rb index 0ae53199ac..3785dc2553 100644 --- a/db/migrate/20190715164535_add_instance_actor.rb +++ b/db/migrate/20190715164535_add_instance_actor.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddInstanceActor < ActiveRecord::Migration[5.2] class Account < ApplicationRecord # Dummy class, to make migration possible across version changes diff --git a/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb b/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb index 3a6527f652..f2d3aa8ee8 100644 --- a/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb +++ b/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + class AddCaseInsensitiveIndexToTags < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up Tag.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM tags GROUP BY lower(name) HAVING count(*) > 1').to_ary.each do |row| canonical_tag_id = row['ids'].split(',').first - redundant_tag_ids = row['ids'].split(',')[1..-1] + redundant_tag_ids = row['ids'].split(',')[1..] safety_assured do execute "UPDATE accounts_tags AS t0 SET tag_id = #{canonical_tag_id} WHERE tag_id IN (#{redundant_tag_ids.join(', ')}) AND NOT EXISTS (SELECT t1.tag_id FROM accounts_tags AS t1 WHERE t1.tag_id = #{canonical_tag_id} AND t1.account_id = t0.account_id)" diff --git a/db/migrate/20190729185330_add_score_to_tags.rb b/db/migrate/20190729185330_add_score_to_tags.rb index 75fee4b570..b990209c67 100644 --- a/db/migrate/20190729185330_add_score_to_tags.rb +++ b/db/migrate/20190729185330_add_score_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddScoreToTags < ActiveRecord::Migration[5.2] def change add_column :tags, :score, :int diff --git a/db/migrate/20190805123746_add_capabilities_to_tags.rb b/db/migrate/20190805123746_add_capabilities_to_tags.rb index 43c7763b1b..623b56a831 100644 --- a/db/migrate/20190805123746_add_capabilities_to_tags.rb +++ b/db/migrate/20190805123746_add_capabilities_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddCapabilitiesToTags < ActiveRecord::Migration[5.2] def change add_column :tags, :usable, :boolean diff --git a/db/migrate/20190807135426_add_comments_to_domain_blocks.rb b/db/migrate/20190807135426_add_comments_to_domain_blocks.rb index b660a71adb..7cca3229c9 100644 --- a/db/migrate/20190807135426_add_comments_to_domain_blocks.rb +++ b/db/migrate/20190807135426_add_comments_to_domain_blocks.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + class AddCommentsToDomainBlocks < ActiveRecord::Migration[5.2] def change add_column :domain_blocks, :private_comment, :text add_column :domain_blocks, :public_comment, :text end end - diff --git a/db/migrate/20190815225426_add_last_status_at_to_tags.rb b/db/migrate/20190815225426_add_last_status_at_to_tags.rb index d83537c47f..03181988c6 100644 --- a/db/migrate/20190815225426_add_last_status_at_to_tags.rb +++ b/db/migrate/20190815225426_add_last_status_at_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLastStatusAtToTags < ActiveRecord::Migration[5.2] def change add_column :tags, :last_status_at, :datetime diff --git a/db/migrate/20190819134503_add_deleted_at_to_statuses.rb b/db/migrate/20190819134503_add_deleted_at_to_statuses.rb index 5af109097e..43a3333754 100644 --- a/db/migrate/20190819134503_add_deleted_at_to_statuses.rb +++ b/db/migrate/20190819134503_add_deleted_at_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDeletedAtToStatuses < ActiveRecord::Migration[5.2] def change add_column :statuses, :deleted_at, :datetime diff --git a/db/migrate/20190820003045_update_statuses_index.rb b/db/migrate/20190820003045_update_statuses_index.rb index 5c2ea1f6a2..df9ce0638f 100644 --- a/db/migrate/20190820003045_update_statuses_index.rb +++ b/db/migrate/20190820003045_update_statuses_index.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UpdateStatusesIndex < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20190823221802_add_local_index_to_statuses.rb b/db/migrate/20190823221802_add_local_index_to_statuses.rb index deca25c351..b5baa30287 100644 --- a/db/migrate/20190823221802_add_local_index_to_statuses.rb +++ b/db/migrate/20190823221802_add_local_index_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLocalIndexToStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20190901035623_add_max_score_to_tags.rb b/db/migrate/20190901035623_add_max_score_to_tags.rb index f936e98718..42a5796949 100644 --- a/db/migrate/20190901035623_add_max_score_to_tags.rb +++ b/db/migrate/20190901035623_add_max_score_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddMaxScoreToTags < ActiveRecord::Migration[5.2] def change add_column :tags, :max_score, :float diff --git a/db/migrate/20190904222339_create_markers.rb b/db/migrate/20190904222339_create_markers.rb index 71ca70ac3d..5d469ddef6 100644 --- a/db/migrate/20190904222339_create_markers.rb +++ b/db/migrate/20190904222339_create_markers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateMarkers < ActiveRecord::Migration[5.2] def change create_table :markers do |t| diff --git a/db/migrate/20190914202517_create_account_migrations.rb b/db/migrate/20190914202517_create_account_migrations.rb index cb9d71c096..44353e08c7 100644 --- a/db/migrate/20190914202517_create_account_migrations.rb +++ b/db/migrate/20190914202517_create_account_migrations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountMigrations < ActiveRecord::Migration[5.2] def change create_table :account_migrations do |t| diff --git a/db/migrate/20190915194355_create_account_aliases.rb b/db/migrate/20190915194355_create_account_aliases.rb index 32ce031d91..f5d648e6d1 100644 --- a/db/migrate/20190915194355_create_account_aliases.rb +++ b/db/migrate/20190915194355_create_account_aliases.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountAliases < ActiveRecord::Migration[5.2] def change create_table :account_aliases do |t| diff --git a/db/migrate/20190927232842_add_voters_count_to_polls.rb b/db/migrate/20190927232842_add_voters_count_to_polls.rb index 8463857009..02d6e4bda5 100644 --- a/db/migrate/20190927232842_add_voters_count_to_polls.rb +++ b/db/migrate/20190927232842_add_voters_count_to_polls.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddVotersCountToPolls < ActiveRecord::Migration[5.2] def change add_column :polls, :voters_count, :bigint diff --git a/db/migrate/20191001213028_add_lock_version_to_account_stats.rb b/db/migrate/20191001213028_add_lock_version_to_account_stats.rb index 47f37cca29..0dc1655596 100644 --- a/db/migrate/20191001213028_add_lock_version_to_account_stats.rb +++ b/db/migrate/20191001213028_add_lock_version_to_account_stats.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddLockVersionToAccountStats < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20191007013357_update_pt_locales.rb b/db/migrate/20191007013357_update_pt_locales.rb index 9e8f8b4241..a3a4e6b60e 100644 --- a/db/migrate/20191007013357_update_pt_locales.rb +++ b/db/migrate/20191007013357_update_pt_locales.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UpdatePtLocales < ActiveRecord::Migration[5.2] class User < ApplicationRecord # Dummy class, to make migration possible across version changes diff --git a/db/migrate/20191031163205_change_list_account_follow_nullable.rb b/db/migrate/20191031163205_change_list_account_follow_nullable.rb index 65ff933658..2416d4e916 100644 --- a/db/migrate/20191031163205_change_list_account_follow_nullable.rb +++ b/db/migrate/20191031163205_change_list_account_follow_nullable.rb @@ -1,4 +1,6 @@ -class ChangeListAccountFollowNullable < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class ChangeListAccountFollowNullable < ActiveRecord::Migration[5.2] def change safety_assured do change_column_null :list_accounts, :follow_id, true diff --git a/db/migrate/20191212003415_increase_backup_size.rb b/db/migrate/20191212003415_increase_backup_size.rb index a5192263cf..c531a198b4 100644 --- a/db/migrate/20191212003415_increase_backup_size.rb +++ b/db/migrate/20191212003415_increase_backup_size.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class IncreaseBackupSize < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20191212163405_add_hide_collections_to_accounts.rb b/db/migrate/20191212163405_add_hide_collections_to_accounts.rb index fa99b32e5c..d6740f19b8 100644 --- a/db/migrate/20191212163405_add_hide_collections_to_accounts.rb +++ b/db/migrate/20191212163405_add_hide_collections_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddHideCollectionsToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :hide_collections, :boolean diff --git a/db/migrate/20191218153258_create_announcements.rb b/db/migrate/20191218153258_create_announcements.rb index 58e143c920..632a912b1e 100644 --- a/db/migrate/20191218153258_create_announcements.rb +++ b/db/migrate/20191218153258_create_announcements.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAnnouncements < ActiveRecord::Migration[5.2] def change create_table :announcements do |t| diff --git a/db/migrate/20200113125135_create_announcement_mutes.rb b/db/migrate/20200113125135_create_announcement_mutes.rb index c588e7fcd3..42c45d7738 100644 --- a/db/migrate/20200113125135_create_announcement_mutes.rb +++ b/db/migrate/20200113125135_create_announcement_mutes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAnnouncementMutes < ActiveRecord::Migration[5.2] def change create_table :announcement_mutes do |t| diff --git a/db/migrate/20200114113335_create_announcement_reactions.rb b/db/migrate/20200114113335_create_announcement_reactions.rb index 226c81a18e..f74d05fc02 100644 --- a/db/migrate/20200114113335_create_announcement_reactions.rb +++ b/db/migrate/20200114113335_create_announcement_reactions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAnnouncementReactions < ActiveRecord::Migration[5.2] def change create_table :announcement_reactions do |t| diff --git a/db/migrate/20200119112504_add_public_index_to_statuses.rb b/db/migrate/20200119112504_add_public_index_to_statuses.rb index db007848e0..6451b9254e 100644 --- a/db/migrate/20200119112504_add_public_index_to_statuses.rb +++ b/db/migrate/20200119112504_add_public_index_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddPublicIndexToStatuses < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20200126203551_add_published_at_to_announcements.rb b/db/migrate/20200126203551_add_published_at_to_announcements.rb index d99f956942..98a3a95920 100644 --- a/db/migrate/20200126203551_add_published_at_to_announcements.rb +++ b/db/migrate/20200126203551_add_published_at_to_announcements.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddPublishedAtToAnnouncements < ActiveRecord::Migration[5.2] def change add_column :announcements, :published_at, :datetime diff --git a/db/migrate/20200306035625_add_processing_to_media_attachments.rb b/db/migrate/20200306035625_add_processing_to_media_attachments.rb index 131ffa52ae..4506c03665 100644 --- a/db/migrate/20200306035625_add_processing_to_media_attachments.rb +++ b/db/migrate/20200306035625_add_processing_to_media_attachments.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddProcessingToMediaAttachments < ActiveRecord::Migration[5.2] def change add_column :media_attachments, :processing, :integer diff --git a/db/migrate/20200309150742_add_forwarded_to_reports.rb b/db/migrate/20200309150742_add_forwarded_to_reports.rb index df278240ba..60db0167e3 100644 --- a/db/migrate/20200309150742_add_forwarded_to_reports.rb +++ b/db/migrate/20200309150742_add_forwarded_to_reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddForwardedToReports < ActiveRecord::Migration[5.2] def change add_column :reports, :forwarded, :boolean diff --git a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb index 46a5350e7c..78b854f82c 100644 --- a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb +++ b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddTitleToAccountWarningPresets < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20200312162302_add_status_ids_to_announcements.rb b/db/migrate/20200312162302_add_status_ids_to_announcements.rb index 42aa6513de..a892b7396f 100644 --- a/db/migrate/20200312162302_add_status_ids_to_announcements.rb +++ b/db/migrate/20200312162302_add_status_ids_to_announcements.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + class AddStatusIdsToAnnouncements < ActiveRecord::Migration[5.2] def change add_column :announcements, :status_ids, :bigint, array: true end end - diff --git a/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb b/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb index 54ca3b87c8..585a097bda 100644 --- a/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb +++ b/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddParentIdToEmailDomainBlocks < ActiveRecord::Migration[5.2] def change safety_assured { add_reference :email_domain_blocks, :parent, null: true, default: nil, foreign_key: { on_delete: :cascade, to_table: :email_domain_blocks }, index: false } diff --git a/db/migrate/20200317021758_add_expires_at_to_mutes.rb b/db/migrate/20200317021758_add_expires_at_to_mutes.rb index eaae8319d7..75bf3ed85c 100644 --- a/db/migrate/20200317021758_add_expires_at_to_mutes.rb +++ b/db/migrate/20200317021758_add_expires_at_to_mutes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddExpiresAtToMutes < ActiveRecord::Migration[5.2] def change add_column :mutes, :expires_at, :datetime diff --git a/db/migrate/20200407201300_create_unavailable_domains.rb b/db/migrate/20200407201300_create_unavailable_domains.rb index 56b477da5d..cbddcab80f 100644 --- a/db/migrate/20200407201300_create_unavailable_domains.rb +++ b/db/migrate/20200407201300_create_unavailable_domains.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateUnavailableDomains < ActiveRecord::Migration[5.2] def change create_table :unavailable_domains do |t| diff --git a/db/migrate/20200407202420_migrate_unavailable_inboxes.rb b/db/migrate/20200407202420_migrate_unavailable_inboxes.rb index 92a3acb5d1..a79045839b 100644 --- a/db/migrate/20200407202420_migrate_unavailable_inboxes.rb +++ b/db/migrate/20200407202420_migrate_unavailable_inboxes.rb @@ -1,12 +1,15 @@ +# frozen_string_literal: true + class MigrateUnavailableInboxes < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up - urls = Redis.current.smembers('unavailable_inboxes') + redis = RedisConfiguration.pool.checkout + urls = redis.smembers('unavailable_inboxes') - hosts = urls.map do |url| + hosts = urls.filter_map do |url| Addressable::URI.parse(url).normalized_host - end.compact.uniq + end.uniq UnavailableDomain.delete_all @@ -14,7 +17,7 @@ class MigrateUnavailableInboxes < ActiveRecord::Migration[5.2] UnavailableDomain.create(domain: host) end - Redis.current.del(*(['unavailable_inboxes'] + Redis.current.keys('exhausted_deliveries:*'))) + redis.del(*(['unavailable_inboxes'] + redis.keys('exhausted_deliveries:*'))) end def down; end diff --git a/db/migrate/20200417125749_add_storage_schema_version.rb b/db/migrate/20200417125749_add_storage_schema_version.rb index 7438f97bae..b504537311 100644 --- a/db/migrate/20200417125749_add_storage_schema_version.rb +++ b/db/migrate/20200417125749_add_storage_schema_version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddStorageSchemaVersion < ActiveRecord::Migration[5.2] def change add_column :preview_cards, :image_storage_schema_version, :integer diff --git a/db/migrate/20200508212852_reset_unique_jobs_locks.rb b/db/migrate/20200508212852_reset_unique_jobs_locks.rb index d717ffc547..16e5c060b9 100644 --- a/db/migrate/20200508212852_reset_unique_jobs_locks.rb +++ b/db/migrate/20200508212852_reset_unique_jobs_locks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ResetUniqueJobsLocks < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20200510110808_reset_web_app_secret.rb b/db/migrate/20200510110808_reset_web_app_secret.rb index b274844c58..9f5a77a195 100644 --- a/db/migrate/20200510110808_reset_web_app_secret.rb +++ b/db/migrate/20200510110808_reset_web_app_secret.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ResetWebAppSecret < ActiveRecord::Migration[5.2] disable_ddl_transaction! @@ -10,6 +12,5 @@ class ResetWebAppSecret < ActiveRecord::Migration[5.2] web_app.save! end - def down - end + def down; end end diff --git a/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb b/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb index 1d6ba1fe98..ce575d6284 100644 --- a/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb +++ b/db/migrate/20200510181721_remove_duplicated_indexes_pghero.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveDuplicatedIndexesPghero < ActiveRecord::Migration[5.2] def up remove_index :account_conversations, name: :index_account_conversations_on_account_id if index_exists?(:account_conversations, :account_id, name: :index_account_conversations_on_account_id) @@ -19,4 +21,3 @@ class RemoveDuplicatedIndexesPghero < ActiveRecord::Migration[5.2] add_index :markers, :user_id, name: :index_markers_on_user_id unless index_exists?(:markers, :user_id, name: :index_markers_on_user_id) end end - diff --git a/db/migrate/20200516180352_create_devices.rb b/db/migrate/20200516180352_create_devices.rb index 04a628a897..a3e22c1457 100644 --- a/db/migrate/20200516180352_create_devices.rb +++ b/db/migrate/20200516180352_create_devices.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateDevices < ActiveRecord::Migration[5.2] def change create_table :devices do |t| diff --git a/db/migrate/20200516183822_create_one_time_keys.rb b/db/migrate/20200516183822_create_one_time_keys.rb index 642b9e6323..4245ceef16 100644 --- a/db/migrate/20200516183822_create_one_time_keys.rb +++ b/db/migrate/20200516183822_create_one_time_keys.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateOneTimeKeys < ActiveRecord::Migration[5.2] def change create_table :one_time_keys do |t| diff --git a/db/migrate/20200518083523_create_encrypted_messages.rb b/db/migrate/20200518083523_create_encrypted_messages.rb index 486726303c..a8b2976e61 100644 --- a/db/migrate/20200518083523_create_encrypted_messages.rb +++ b/db/migrate/20200518083523_create_encrypted_messages.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateEncryptedMessages < ActiveRecord::Migration[5.2] def change create_table :encrypted_messages do |t| diff --git a/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb b/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb index 24d43a0bfd..422e4f43fa 100644 --- a/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb +++ b/db/migrate/20200521180606_encrypted_message_ids_to_timestamp_ids.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class EncryptedMessageIdsToTimestampIds < ActiveRecord::Migration[5.2] def up safety_assured do @@ -6,7 +8,7 @@ class EncryptedMessageIdsToTimestampIds < ActiveRecord::Migration[5.2] end def down - execute("LOCK encrypted_messages") + execute('LOCK encrypted_messages') execute("SELECT setval('encrypted_messages_id_seq', (SELECT MAX(id) FROM encrypted_messages))") execute("ALTER TABLE encrypted_messages ALTER COLUMN id SET DEFAULT nextval('encrypted_messages_id_seq')") end diff --git a/db/migrate/20200529214050_add_devices_url_to_accounts.rb b/db/migrate/20200529214050_add_devices_url_to_accounts.rb index 1323f8df7e..6f868579fe 100644 --- a/db/migrate/20200529214050_add_devices_url_to_accounts.rb +++ b/db/migrate/20200529214050_add_devices_url_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDevicesURLToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :devices_url, :string diff --git a/db/migrate/20200601222558_create_system_keys.rb b/db/migrate/20200601222558_create_system_keys.rb index fd9d221aa2..38ec147d4d 100644 --- a/db/migrate/20200601222558_create_system_keys.rb +++ b/db/migrate/20200601222558_create_system_keys.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateSystemKeys < ActiveRecord::Migration[5.2] def change create_table :system_keys do |t| diff --git a/db/migrate/20200605155027_add_blurhash_to_preview_cards.rb b/db/migrate/20200605155027_add_blurhash_to_preview_cards.rb index dc4b7a9849..f89dc7b2b1 100644 --- a/db/migrate/20200605155027_add_blurhash_to_preview_cards.rb +++ b/db/migrate/20200605155027_add_blurhash_to_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddBlurhashToPreviewCards < ActiveRecord::Migration[5.2] def change add_column :preview_cards, :blurhash, :string diff --git a/db/migrate/20200608113046_add_sign_in_token_to_users.rb b/db/migrate/20200608113046_add_sign_in_token_to_users.rb index baa63c10f2..5b71276a24 100644 --- a/db/migrate/20200608113046_add_sign_in_token_to_users.rb +++ b/db/migrate/20200608113046_add_sign_in_token_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSignInTokenToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :sign_in_token, :string diff --git a/db/migrate/20200614002136_add_sensitized_to_accounts.rb b/db/migrate/20200614002136_add_sensitized_to_accounts.rb index bc2dfcb636..bf5d363c81 100644 --- a/db/migrate/20200614002136_add_sensitized_to_accounts.rb +++ b/db/migrate/20200614002136_add_sensitized_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSensitizedToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :sensitized_at, :datetime diff --git a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb index 652ce97522..fa81ac1649 100644 --- a/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb +++ b/db/migrate/20200620164023_add_fixed_lowercase_index_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddFixedLowercaseIndexToAccounts < ActiveRecord::Migration[5.2] @@ -16,7 +18,7 @@ class AddFixedLowercaseIndexToAccounts < ActiveRecord::Migration[5.2] add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true, algorithm: :concurrently rescue ActiveRecord::RecordNotUnique remove_index :accounts, name: 'index_accounts_on_username_and_domain_lower' - raise CorruptionError.new('index_accounts_on_username_and_domain_lower') + raise CorruptionError, 'index_accounts_on_username_and_domain_lower' end remove_index :accounts, name: 'old_index_accounts_on_username_and_domain_lower' if index_name_exists?(:accounts, 'old_index_accounts_on_username_and_domain_lower') diff --git a/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb b/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb index 5c6865b927..4b1caeddb5 100644 --- a/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb +++ b/db/migrate/20200622213645_media_attachment_ids_to_timestamp_ids.rb @@ -1,4 +1,6 @@ -class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.2] def up # Set up the media_attachments.id column to use our timestamp-based IDs. safety_assured do @@ -10,7 +12,7 @@ class MediaAttachmentIdsToTimestampIds < ActiveRecord::Migration[5.1] end def down - execute("LOCK media_attachments") + execute('LOCK media_attachments') execute("SELECT setval('media_attachments_id_seq', (SELECT MAX(id) FROM media_attachments))") execute("ALTER TABLE media_attachments ALTER COLUMN id SET DEFAULT nextval('media_attachments_id_seq')") end diff --git a/db/migrate/20200627125810_add_thumbnail_columns_to_media_attachments.rb b/db/migrate/20200627125810_add_thumbnail_columns_to_media_attachments.rb index f9c87a53cc..a3c6b55fd2 100644 --- a/db/migrate/20200627125810_add_thumbnail_columns_to_media_attachments.rb +++ b/db/migrate/20200627125810_add_thumbnail_columns_to_media_attachments.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddThumbnailColumnsToMediaAttachments < ActiveRecord::Migration[5.2] def up add_attachment :media_attachments, :thumbnail diff --git a/db/migrate/20200628133322_create_account_notes.rb b/db/migrate/20200628133322_create_account_notes.rb index 664727e60b..dd2366198d 100644 --- a/db/migrate/20200628133322_create_account_notes.rb +++ b/db/migrate/20200628133322_create_account_notes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountNotes < ActiveRecord::Migration[5.2] def change create_table :account_notes do |t| @@ -10,4 +12,3 @@ class CreateAccountNotes < ActiveRecord::Migration[5.2] end end end - diff --git a/db/migrate/20200630190240_create_webauthn_credentials.rb b/db/migrate/20200630190240_create_webauthn_credentials.rb index ea924238d4..21c60ce008 100644 --- a/db/migrate/20200630190240_create_webauthn_credentials.rb +++ b/db/migrate/20200630190240_create_webauthn_credentials.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateWebauthnCredentials < ActiveRecord::Migration[5.2] def change create_table :webauthn_credentials do |t| diff --git a/db/migrate/20200630190544_add_webauthn_id_to_users.rb b/db/migrate/20200630190544_add_webauthn_id_to_users.rb index 95d3c92a86..e2628b65bf 100644 --- a/db/migrate/20200630190544_add_webauthn_id_to_users.rb +++ b/db/migrate/20200630190544_add_webauthn_id_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddWebauthnIdToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :webauthn_id, :string diff --git a/db/migrate/20200908193330_create_account_deletion_requests.rb b/db/migrate/20200908193330_create_account_deletion_requests.rb index e03183ae45..1f543ca332 100644 --- a/db/migrate/20200908193330_create_account_deletion_requests.rb +++ b/db/migrate/20200908193330_create_account_deletion_requests.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountDeletionRequests < ActiveRecord::Migration[5.2] def change create_table :account_deletion_requests do |t| diff --git a/db/migrate/20200917192924_add_notify_to_follows.rb b/db/migrate/20200917192924_add_notify_to_follows.rb index d27471c447..a57bb36dc2 100644 --- a/db/migrate/20200917192924_add_notify_to_follows.rb +++ b/db/migrate/20200917192924_add_notify_to_follows.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddNotifyToFollows < ActiveRecord::Migration[5.1] +class AddNotifyToFollows < ActiveRecord::Migration[5.2] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20200917193034_add_type_to_notifications.rb b/db/migrate/20200917193034_add_type_to_notifications.rb index 002be3aa00..b0fb3bfe3a 100644 --- a/db/migrate/20200917193034_add_type_to_notifications.rb +++ b/db/migrate/20200917193034_add_type_to_notifications.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTypeToNotifications < ActiveRecord::Migration[5.2] def change add_column :notifications, :type, :string diff --git a/db/migrate/20200917222316_add_index_notifications_on_type.rb b/db/migrate/20200917222316_add_index_notifications_on_type.rb index 9bd23c1d3d..a819f23ee2 100644 --- a/db/migrate/20200917222316_add_index_notifications_on_type.rb +++ b/db/migrate/20200917222316_add_index_notifications_on_type.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexNotificationsOnType < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20201008202037_create_ip_blocks.rb b/db/migrate/20201008202037_create_ip_blocks.rb index 32acd6ede1..76b86d648b 100644 --- a/db/migrate/20201008202037_create_ip_blocks.rb +++ b/db/migrate/20201008202037_create_ip_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateIpBlocks < ActiveRecord::Migration[5.2] def change create_table :ip_blocks do |t| diff --git a/db/migrate/20201008220312_add_sign_up_ip_to_users.rb b/db/migrate/20201008220312_add_sign_up_ip_to_users.rb index 66cd624bbb..58d1a7aedc 100644 --- a/db/migrate/20201008220312_add_sign_up_ip_to_users.rb +++ b/db/migrate/20201008220312_add_sign_up_ip_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSignUpIpToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :sign_up_ip, :inet diff --git a/db/migrate/20201017233919_add_suspension_origin_to_accounts.rb b/db/migrate/20201017233919_add_suspension_origin_to_accounts.rb index f0db02143a..1150f10941 100644 --- a/db/migrate/20201017233919_add_suspension_origin_to_accounts.rb +++ b/db/migrate/20201017233919_add_suspension_origin_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSuspensionOriginToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :suspension_origin, :integer diff --git a/db/migrate/20201206004238_create_instances.rb b/db/migrate/20201206004238_create_instances.rb index a4b866894a..965ab26e27 100644 --- a/db/migrate/20201206004238_create_instances.rb +++ b/db/migrate/20201206004238_create_instances.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateInstances < ActiveRecord::Migration[5.2] def change create_view :instances, materialized: true diff --git a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb index 26f4ddb851..91bba38c58 100644 --- a/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb +++ b/db/migrate/20201218054746_add_obfuscate_to_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddObfuscateToDomainBlocks < ActiveRecord::Migration[5.2] diff --git a/db/migrate/20210221045109_create_rules.rb b/db/migrate/20210221045109_create_rules.rb index abe2fd42a0..293a1a6c43 100644 --- a/db/migrate/20210221045109_create_rules.rb +++ b/db/migrate/20210221045109_create_rules.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateRules < ActiveRecord::Migration[5.2] def change create_table :rules do |t| diff --git a/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb b/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb index 39cd4cdea4..0b3f1f638a 100644 --- a/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb +++ b/db/migrate/20210306164523_account_ids_to_timestamp_ids.rb @@ -1,4 +1,6 @@ -class AccountIdsToTimestampIds < ActiveRecord::Migration[5.1] +# frozen_string_literal: true + +class AccountIdsToTimestampIds < ActiveRecord::Migration[5.2] def up # Set up the accounts.id column to use our timestamp-based IDs. safety_assured do @@ -10,7 +12,7 @@ class AccountIdsToTimestampIds < ActiveRecord::Migration[5.1] end def down - execute("LOCK accounts") + execute('LOCK accounts') execute("SELECT setval('accounts_id_seq', (SELECT MAX(id) FROM accounts))") execute("ALTER TABLE accounts ALTER COLUMN id SET DEFAULT nextval('accounts_id_seq')") end diff --git a/db/migrate/20210322164601_create_account_summaries.rb b/db/migrate/20210322164601_create_account_summaries.rb index bc9011113f..8d18e9eeb4 100644 --- a/db/migrate/20210322164601_create_account_summaries.rb +++ b/db/migrate/20210322164601_create_account_summaries.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountSummaries < ActiveRecord::Migration[5.2] def change create_view :account_summaries, materialized: { no_data: true } diff --git a/db/migrate/20210323114347_create_follow_recommendations.rb b/db/migrate/20210323114347_create_follow_recommendations.rb index 77e7290320..b63564a030 100644 --- a/db/migrate/20210323114347_create_follow_recommendations.rb +++ b/db/migrate/20210323114347_create_follow_recommendations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateFollowRecommendations < ActiveRecord::Migration[5.2] def change create_view :follow_recommendations diff --git a/db/migrate/20210324171613_create_follow_recommendation_suppressions.rb b/db/migrate/20210324171613_create_follow_recommendation_suppressions.rb index c17a0be635..a2040ca983 100644 --- a/db/migrate/20210324171613_create_follow_recommendation_suppressions.rb +++ b/db/migrate/20210324171613_create_follow_recommendation_suppressions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateFollowRecommendationSuppressions < ActiveRecord::Migration[6.1] def change create_table :follow_recommendation_suppressions do |t| diff --git a/db/migrate/20210416200740_create_canonical_email_blocks.rb b/db/migrate/20210416200740_create_canonical_email_blocks.rb index 32c44646c3..a18539fa1c 100644 --- a/db/migrate/20210416200740_create_canonical_email_blocks.rb +++ b/db/migrate/20210416200740_create_canonical_email_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateCanonicalEmailBlocks < ActiveRecord::Migration[6.1] def change create_table :canonical_email_blocks do |t| diff --git a/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb b/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb index b3ee11d09e..43b4e5a6f6 100644 --- a/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb +++ b/db/migrate/20210421121431_add_case_insensitive_btree_index_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddCaseInsensitiveBtreeIndexToTags < ActiveRecord::Migration[5.2] @@ -10,7 +12,8 @@ class AddCaseInsensitiveBtreeIndexToTags < ActiveRecord::Migration[5.2] safety_assured { execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' } rescue ActiveRecord::StatementInvalid => e remove_index :tags, name: 'index_tags_on_name_lower_btree' - raise CorruptionError.new('index_tags_on_name_lower_btree') if e.is_a?(ActiveRecord::RecordNotUnique) + raise CorruptionError, 'index_tags_on_name_lower_btree' if e.is_a?(ActiveRecord::RecordNotUnique) + raise e end diff --git a/db/migrate/20210425135952_add_index_on_media_attachments_account_id_status_id.rb b/db/migrate/20210425135952_add_index_on_media_attachments_account_id_status_id.rb index 5ef2d3c398..68fdcd51e9 100644 --- a/db/migrate/20210425135952_add_index_on_media_attachments_account_id_status_id.rb +++ b/db/migrate/20210425135952_add_index_on_media_attachments_account_id_status_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexOnMediaAttachmentsAccountIdStatusId < ActiveRecord::Migration[5.2] disable_ddl_transaction! diff --git a/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb b/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb index 56c0b4cb0a..22c27a0e7a 100644 --- a/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb +++ b/db/migrate/20210505174616_update_follow_recommendations_to_version_2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UpdateFollowRecommendationsToVersion2 < ActiveRecord::Migration[6.1] # We're switching from a normal to a materialized view so we need # custom `up` and `down` paths. diff --git a/db/migrate/20210609202149_create_login_activities.rb b/db/migrate/20210609202149_create_login_activities.rb index 38e147c327..f2da335997 100644 --- a/db/migrate/20210609202149_create_login_activities.rb +++ b/db/migrate/20210609202149_create_login_activities.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateLoginActivities < ActiveRecord::Migration[6.1] def change create_table :login_activities do |t| diff --git a/db/migrate/20210616214526_create_user_ips.rb b/db/migrate/20210616214526_create_user_ips.rb index 68e81a9d81..4aaf9a4746 100644 --- a/db/migrate/20210616214526_create_user_ips.rb +++ b/db/migrate/20210616214526_create_user_ips.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateUserIps < ActiveRecord::Migration[6.1] def change create_view :user_ips diff --git a/db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb b/db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb index 43ad9b9545..8c5d9c368a 100644 --- a/db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb +++ b/db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddSkipSignInTokenToUsers < ActiveRecord::Migration[6.1] def change add_column :users, :skip_sign_in_token, :boolean diff --git a/db/migrate/20210630000137_fix_canonical_email_blocks_foreign_key.rb b/db/migrate/20210630000137_fix_canonical_email_blocks_foreign_key.rb index 64cf84448b..9b475966bb 100644 --- a/db/migrate/20210630000137_fix_canonical_email_blocks_foreign_key.rb +++ b/db/migrate/20210630000137_fix_canonical_email_blocks_foreign_key.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class FixCanonicalEmailBlocksForeignKey < ActiveRecord::Migration[6.1] def up safety_assured do diff --git a/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb b/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb index 28cfb6ef52..334c375a4e 100644 --- a/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb +++ b/db/migrate/20210722120340_create_account_statuses_cleanup_policies.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAccountStatusesCleanupPolicies < ActiveRecord::Migration[6.1] def change create_table :account_statuses_cleanup_policies do |t| @@ -17,4 +19,3 @@ class CreateAccountStatusesCleanupPolicies < ActiveRecord::Migration[6.1] end end end - diff --git a/db/migrate/20210904215403_add_edited_at_to_statuses.rb b/db/migrate/20210904215403_add_edited_at_to_statuses.rb index 216ad8e138..545c6f79c4 100644 --- a/db/migrate/20210904215403_add_edited_at_to_statuses.rb +++ b/db/migrate/20210904215403_add_edited_at_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddEditedAtToStatuses < ActiveRecord::Migration[6.1] def change add_column :statuses, :edited_at, :datetime diff --git a/db/migrate/20210908220918_create_status_edits.rb b/db/migrate/20210908220918_create_status_edits.rb index 6c90149d00..dfc2c51743 100644 --- a/db/migrate/20210908220918_create_status_edits.rb +++ b/db/migrate/20210908220918_create_status_edits.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStatusEdits < ActiveRecord::Migration[6.1] def change create_table :status_edits do |t| diff --git a/db/migrate/20211031031021_create_preview_card_providers.rb b/db/migrate/20211031031021_create_preview_card_providers.rb index 0bd46198e2..83255614b6 100644 --- a/db/migrate/20211031031021_create_preview_card_providers.rb +++ b/db/migrate/20211031031021_create_preview_card_providers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreatePreviewCardProviders < ActiveRecord::Migration[6.1] def change create_table :preview_card_providers do |t| diff --git a/db/migrate/20211112011713_add_language_to_preview_cards.rb b/db/migrate/20211112011713_add_language_to_preview_cards.rb index 995934de4c..b9049e9795 100644 --- a/db/migrate/20211112011713_add_language_to_preview_cards.rb +++ b/db/migrate/20211112011713_add_language_to_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLanguageToPreviewCards < ActiveRecord::Migration[6.1] def change add_column :preview_cards, :language, :string diff --git a/db/migrate/20211115032527_add_trendable_to_preview_cards.rb b/db/migrate/20211115032527_add_trendable_to_preview_cards.rb index 87bf3d7a23..21fc4ecf46 100644 --- a/db/migrate/20211115032527_add_trendable_to_preview_cards.rb +++ b/db/migrate/20211115032527_add_trendable_to_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTrendableToPreviewCards < ActiveRecord::Migration[6.1] def change add_column :preview_cards, :trendable, :boolean diff --git a/db/migrate/20211123212714_add_link_type_to_preview_cards.rb b/db/migrate/20211123212714_add_link_type_to_preview_cards.rb index 9f57e02194..68a2a92cbf 100644 --- a/db/migrate/20211123212714_add_link_type_to_preview_cards.rb +++ b/db/migrate/20211123212714_add_link_type_to_preview_cards.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLinkTypeToPreviewCards < ActiveRecord::Migration[6.1] def change add_column :preview_cards, :link_type, :int diff --git a/db/migrate/20211213040746_update_account_summaries_to_version_2.rb b/db/migrate/20211213040746_update_account_summaries_to_version_2.rb index 0d1f092ec6..e347a874ff 100644 --- a/db/migrate/20211213040746_update_account_summaries_to_version_2.rb +++ b/db/migrate/20211213040746_update_account_summaries_to_version_2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UpdateAccountSummariesToVersion2 < ActiveRecord::Migration[6.1] def up reapplication_follow_recommendations_v2 do diff --git a/db/migrate/20211231080958_add_category_to_reports.rb b/db/migrate/20211231080958_add_category_to_reports.rb index c2b495c635..97a59f8c23 100644 --- a/db/migrate/20211231080958_add_category_to_reports.rb +++ b/db/migrate/20211231080958_add_category_to_reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddCategoryToReports < ActiveRecord::Migration[6.1] diff --git a/db/migrate/20220105163928_remove_mentions_status_id_index.rb b/db/migrate/20220105163928_remove_mentions_status_id_index.rb index 56e9037192..58d665f85c 100644 --- a/db/migrate/20220105163928_remove_mentions_status_id_index.rb +++ b/db/migrate/20220105163928_remove_mentions_status_id_index.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveMentionsStatusIdIndex < ActiveRecord::Migration[6.1] def up remove_index :mentions, name: :mentions_status_id_index if index_exists?(:mentions, :status_id, name: :mentions_status_id_index) diff --git a/db/migrate/20220115125126_add_report_id_to_account_warnings.rb b/db/migrate/20220115125126_add_report_id_to_account_warnings.rb index a1c20c99ef..43e5adcfee 100644 --- a/db/migrate/20220115125126_add_report_id_to_account_warnings.rb +++ b/db/migrate/20220115125126_add_report_id_to_account_warnings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddReportIdToAccountWarnings < ActiveRecord::Migration[6.1] def change safety_assured { add_reference :account_warnings, :report, foreign_key: { on_delete: :cascade }, index: false } diff --git a/db/migrate/20220115125341_fix_account_warning_actions.rb b/db/migrate/20220115125341_fix_account_warning_actions.rb index 25cc17fd39..5a580e92ce 100644 --- a/db/migrate/20220115125341_fix_account_warning_actions.rb +++ b/db/migrate/20220115125341_fix_account_warning_actions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class FixAccountWarningActions < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220116202951_add_deleted_at_index_on_statuses.rb b/db/migrate/20220116202951_add_deleted_at_index_on_statuses.rb index dc33625528..7615111824 100644 --- a/db/migrate/20220116202951_add_deleted_at_index_on_statuses.rb +++ b/db/migrate/20220116202951_add_deleted_at_index_on_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDeletedAtIndexOnStatuses < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220124141035_create_appeals.rb b/db/migrate/20220124141035_create_appeals.rb index afb3efbd53..03911172a3 100644 --- a/db/migrate/20220124141035_create_appeals.rb +++ b/db/migrate/20220124141035_create_appeals.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateAppeals < ActiveRecord::Migration[6.1] def change create_table :appeals do |t| diff --git a/db/migrate/20220202200743_add_trendable_to_accounts.rb b/db/migrate/20220202200743_add_trendable_to_accounts.rb index 414df5108d..20de235c2d 100644 --- a/db/migrate/20220202200743_add_trendable_to_accounts.rb +++ b/db/migrate/20220202200743_add_trendable_to_accounts.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTrendableToAccounts < ActiveRecord::Migration[6.1] def change add_column :accounts, :trendable, :boolean diff --git a/db/migrate/20220202200926_add_trendable_to_statuses.rb b/db/migrate/20220202200926_add_trendable_to_statuses.rb index 7f38c8ca71..5d101132b8 100644 --- a/db/migrate/20220202200926_add_trendable_to_statuses.rb +++ b/db/migrate/20220202200926_add_trendable_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddTrendableToStatuses < ActiveRecord::Migration[6.1] def change add_column :statuses, :trendable, :boolean diff --git a/db/migrate/20220209175231_add_content_type_to_status_edits.rb b/db/migrate/20220209175231_add_content_type_to_status_edits.rb new file mode 100644 index 0000000000..bb414535dc --- /dev/null +++ b/db/migrate/20220209175231_add_content_type_to_status_edits.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddContentTypeToStatusEdits < ActiveRecord::Migration[6.1] + def change + add_column :status_edits, :content_type, :string + end +end diff --git a/db/migrate/20220210153119_add_overruled_at_to_account_warnings.rb b/db/migrate/20220210153119_add_overruled_at_to_account_warnings.rb index a082da774c..68ca277e39 100644 --- a/db/migrate/20220210153119_add_overruled_at_to_account_warnings.rb +++ b/db/migrate/20220210153119_add_overruled_at_to_account_warnings.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddOverruledAtToAccountWarnings < ActiveRecord::Migration[6.1] def change add_column :account_warnings, :overruled_at, :datetime diff --git a/db/migrate/20220224010024_add_ips_to_email_domain_blocks.rb b/db/migrate/20220224010024_add_ips_to_email_domain_blocks.rb index 1b19a2aa1f..f70dbe5e32 100644 --- a/db/migrate/20220224010024_add_ips_to_email_domain_blocks.rb +++ b/db/migrate/20220224010024_add_ips_to_email_domain_blocks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIpsToEmailDomainBlocks < ActiveRecord::Migration[6.1] def change add_column :email_domain_blocks, :ips, :inet, array: true diff --git a/db/migrate/20220227041951_add_last_used_at_to_oauth_access_tokens.rb b/db/migrate/20220227041951_add_last_used_at_to_oauth_access_tokens.rb index 6b46e60a8b..a733fa1c4b 100644 --- a/db/migrate/20220227041951_add_last_used_at_to_oauth_access_tokens.rb +++ b/db/migrate/20220227041951_add_last_used_at_to_oauth_access_tokens.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLastUsedAtToOauthAccessTokens < ActiveRecord::Migration[6.1] def change add_column :oauth_access_tokens, :last_used_at, :datetime diff --git a/db/migrate/20220302232632_add_ordered_media_attachment_ids_to_statuses.rb b/db/migrate/20220302232632_add_ordered_media_attachment_ids_to_statuses.rb index 5443f32a2e..3a08963a78 100644 --- a/db/migrate/20220302232632_add_ordered_media_attachment_ids_to_statuses.rb +++ b/db/migrate/20220302232632_add_ordered_media_attachment_ids_to_statuses.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddOrderedMediaAttachmentIdsToStatuses < ActiveRecord::Migration[6.1] def change add_column :statuses, :ordered_media_attachment_ids, :bigint, array: true diff --git a/db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb b/db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb index b1071f3593..b8ebee6f07 100644 --- a/db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb +++ b/db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddOrderedMediaAttachmentIdsToStatusEdits < ActiveRecord::Migration[6.1] def change add_column :status_edits, :ordered_media_attachment_ids, :bigint, array: true diff --git a/db/migrate/20220304195405_migrate_hide_network_preference.rb b/db/migrate/20220304195405_migrate_hide_network_preference.rb index 102ee46d6f..0083e0422a 100644 --- a/db/migrate/20220304195405_migrate_hide_network_preference.rb +++ b/db/migrate/20220304195405_migrate_hide_network_preference.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MigrateHideNetworkPreference < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220307094650_fix_featured_tags_constraints.rb b/db/migrate/20220307094650_fix_featured_tags_constraints.rb index bad1c90d41..db2e9f4f7b 100644 --- a/db/migrate/20220307094650_fix_featured_tags_constraints.rb +++ b/db/migrate/20220307094650_fix_featured_tags_constraints.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class FixFeaturedTagsConstraints < ActiveRecord::Migration[6.1] def up safety_assured do diff --git a/db/migrate/20220309213005_fix_reblog_deleted_at.rb b/db/migrate/20220309213005_fix_reblog_deleted_at.rb index 8ec1813d95..e3474beeb1 100644 --- a/db/migrate/20220309213005_fix_reblog_deleted_at.rb +++ b/db/migrate/20220309213005_fix_reblog_deleted_at.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class FixReblogDeletedAt < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220316233212_update_kurdish_locales.rb b/db/migrate/20220316233212_update_kurdish_locales.rb index 36586622fb..fa8ced0fdb 100644 --- a/db/migrate/20220316233212_update_kurdish_locales.rb +++ b/db/migrate/20220316233212_update_kurdish_locales.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UpdateKurdishLocales < ActiveRecord::Migration[6.1] class User < ApplicationRecord # Dummy class, to make migration possible across version changes diff --git a/db/migrate/20220428112511_add_index_statuses_on_account_id.rb b/db/migrate/20220428112511_add_index_statuses_on_account_id.rb index 87a601b728..b1ace18df8 100644 --- a/db/migrate/20220428112511_add_index_statuses_on_account_id.rb +++ b/db/migrate/20220428112511_add_index_statuses_on_account_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexStatusesOnAccountId < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220428112727_add_index_statuses_pins_on_status_id.rb b/db/migrate/20220428112727_add_index_statuses_pins_on_status_id.rb index 26a5430876..0358da9b5a 100644 --- a/db/migrate/20220428112727_add_index_statuses_pins_on_status_id.rb +++ b/db/migrate/20220428112727_add_index_statuses_pins_on_status_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexStatusesPinsOnStatusId < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220428114454_add_index_reports_on_assigned_account_id.rb b/db/migrate/20220428114454_add_index_reports_on_assigned_account_id.rb index c260c9732a..6b3888c422 100644 --- a/db/migrate/20220428114454_add_index_reports_on_assigned_account_id.rb +++ b/db/migrate/20220428114454_add_index_reports_on_assigned_account_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexReportsOnAssignedAccountId < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220428114902_add_index_reports_on_action_taken_by_account_id.rb b/db/migrate/20220428114902_add_index_reports_on_action_taken_by_account_id.rb index aed88cd80a..3c2d9dac90 100644 --- a/db/migrate/20220428114902_add_index_reports_on_action_taken_by_account_id.rb +++ b/db/migrate/20220428114902_add_index_reports_on_action_taken_by_account_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexReportsOnActionTakenByAccountId < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220606044941_create_webhooks.rb b/db/migrate/20220606044941_create_webhooks.rb index cca48fce65..0e70fbeadc 100644 --- a/db/migrate/20220606044941_create_webhooks.rb +++ b/db/migrate/20220606044941_create_webhooks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateWebhooks < ActiveRecord::Migration[6.1] def change create_table :webhooks do |t| diff --git a/db/migrate/20220611210335_create_user_roles.rb b/db/migrate/20220611210335_create_user_roles.rb index 6b7f2b6371..c778b70591 100644 --- a/db/migrate/20220611210335_create_user_roles.rb +++ b/db/migrate/20220611210335_create_user_roles.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateUserRoles < ActiveRecord::Migration[6.1] def change create_table :user_roles do |t| diff --git a/db/migrate/20220611212541_add_role_id_to_users.rb b/db/migrate/20220611212541_add_role_id_to_users.rb index 2fda647d4c..9c1cb2fad8 100644 --- a/db/migrate/20220611212541_add_role_id_to_users.rb +++ b/db/migrate/20220611212541_add_role_id_to_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddRoleIdToUsers < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20220613110834_add_action_to_custom_filters.rb b/db/migrate/20220613110834_add_action_to_custom_filters.rb index 9427a66fc4..c1daf3c948 100644 --- a/db/migrate/20220613110834_add_action_to_custom_filters.rb +++ b/db/migrate/20220613110834_add_action_to_custom_filters.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class AddActionToCustomFilters < ActiveRecord::Migration[6.1] diff --git a/db/migrate/20220710102457_add_display_name_to_tags.rb b/db/migrate/20220710102457_add_display_name_to_tags.rb index aa78676459..b74de5085d 100644 --- a/db/migrate/20220710102457_add_display_name_to_tags.rb +++ b/db/migrate/20220710102457_add_display_name_to_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddDisplayNameToTags < ActiveRecord::Migration[6.1] def change add_column :tags, :display_name, :string diff --git a/db/migrate/20220714171049_create_tag_follows.rb b/db/migrate/20220714171049_create_tag_follows.rb index a393e90f50..9a3f3e0930 100644 --- a/db/migrate/20220714171049_create_tag_follows.rb +++ b/db/migrate/20220714171049_create_tag_follows.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateTagFollows < ActiveRecord::Migration[6.1] def change create_table :tag_follows do |t| diff --git a/db/migrate/20220824164433_add_human_identifier_to_admin_action_logs.rb b/db/migrate/20220824164433_add_human_identifier_to_admin_action_logs.rb index 2cb8cddf19..90bc767288 100644 --- a/db/migrate/20220824164433_add_human_identifier_to_admin_action_logs.rb +++ b/db/migrate/20220824164433_add_human_identifier_to_admin_action_logs.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddHumanIdentifierToAdminActionLogs < ActiveRecord::Migration[6.1] def change add_column :admin_action_logs, :human_identifier, :string diff --git a/db/migrate/20220824233535_create_status_trends.rb b/db/migrate/20220824233535_create_status_trends.rb index cea0abf355..52dcbf8f38 100644 --- a/db/migrate/20220824233535_create_status_trends.rb +++ b/db/migrate/20220824233535_create_status_trends.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreateStatusTrends < ActiveRecord::Migration[6.1] def change create_table :status_trends do |t| diff --git a/db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb b/db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb index 5b3ec47275..e794824afc 100644 --- a/db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb +++ b/db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ChangeCanonicalEmailBlocksNullable < ActiveRecord::Migration[6.1] def change safety_assured { change_column :canonical_email_blocks, :reference_account_id, :bigint, null: true, default: nil } diff --git a/db/migrate/20220829192633_add_languages_to_follows.rb b/db/migrate/20220829192633_add_languages_to_follows.rb index f6cf48880a..ad88396bdc 100644 --- a/db/migrate/20220829192633_add_languages_to_follows.rb +++ b/db/migrate/20220829192633_add_languages_to_follows.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLanguagesToFollows < ActiveRecord::Migration[6.1] def change add_column :follows, :languages, :string, array: true diff --git a/db/migrate/20220829192658_add_languages_to_follow_requests.rb b/db/migrate/20220829192658_add_languages_to_follow_requests.rb index f98fabb220..94031fd873 100644 --- a/db/migrate/20220829192658_add_languages_to_follow_requests.rb +++ b/db/migrate/20220829192658_add_languages_to_follow_requests.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddLanguagesToFollowRequests < ActiveRecord::Migration[6.1] def change add_column :follow_requests, :languages, :string, array: true diff --git a/db/migrate/20221006061337_create_preview_card_trends.rb b/db/migrate/20221006061337_create_preview_card_trends.rb index baad9c31c3..934a06e24d 100644 --- a/db/migrate/20221006061337_create_preview_card_trends.rb +++ b/db/migrate/20221006061337_create_preview_card_trends.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CreatePreviewCardTrends < ActiveRecord::Migration[6.1] def change create_table :preview_card_trends do |t| diff --git a/db/migrate/20221012181003_add_blurhash_to_site_uploads.rb b/db/migrate/20221012181003_add_blurhash_to_site_uploads.rb index e1c87712b1..3ed2eb9682 100644 --- a/db/migrate/20221012181003_add_blurhash_to_site_uploads.rb +++ b/db/migrate/20221012181003_add_blurhash_to_site_uploads.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddBlurhashToSiteUploads < ActiveRecord::Migration[6.1] def change add_column :site_uploads, :blurhash, :string diff --git a/db/migrate/20221021055441_add_index_featured_tags_on_account_id_and_tag_id.rb b/db/migrate/20221021055441_add_index_featured_tags_on_account_id_and_tag_id.rb index 74d7673f7d..7925aae939 100644 --- a/db/migrate/20221021055441_add_index_featured_tags_on_account_id_and_tag_id.rb +++ b/db/migrate/20221021055441_add_index_featured_tags_on_account_id_and_tag_id.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexFeaturedTagsOnAccountIdAndTagId < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20221025171544_add_index_ip_blocks_on_ip.rb b/db/migrate/20221025171544_add_index_ip_blocks_on_ip.rb index 0221369b7e..a1d824c4e4 100644 --- a/db/migrate/20221025171544_add_index_ip_blocks_on_ip.rb +++ b/db/migrate/20221025171544_add_index_ip_blocks_on_ip.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddIndexIpBlocksOnIp < ActiveRecord::Migration[6.1] disable_ddl_transaction! diff --git a/db/migrate/20221104133904_add_name_to_featured_tags.rb b/db/migrate/20221104133904_add_name_to_featured_tags.rb index 7c8c8ebfbc..44b9e64486 100644 --- a/db/migrate/20221104133904_add_name_to_featured_tags.rb +++ b/db/migrate/20221104133904_add_name_to_featured_tags.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddNameToFeaturedTags < ActiveRecord::Migration[6.1] def change add_column :featured_tags, :name, :string diff --git a/db/migrate/20230129023109_add_template_to_webhooks.rb b/db/migrate/20230129023109_add_template_to_webhooks.rb new file mode 100644 index 0000000000..73bdd73ff9 --- /dev/null +++ b/db/migrate/20230129023109_add_template_to_webhooks.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddTemplateToWebhooks < ActiveRecord::Migration[6.1] + def change + add_column :webhooks, :template, :text + end +end diff --git a/db/migrate/20230215074327_add_settings_to_users.rb b/db/migrate/20230215074327_add_settings_to_users.rb new file mode 100644 index 0000000000..ff5308f423 --- /dev/null +++ b/db/migrate/20230215074327_add_settings_to_users.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddSettingsToUsers < ActiveRecord::Migration[6.1] + def change + add_column :users, :settings, :text + end +end diff --git a/db/migrate/20230215074423_move_user_settings.rb b/db/migrate/20230215074423_move_user_settings.rb new file mode 100644 index 0000000000..27caac1011 --- /dev/null +++ b/db/migrate/20230215074423_move_user_settings.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +class MoveUserSettings < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + class User < ApplicationRecord; end + + MAPPING = { + default_privacy: 'default_privacy', + default_sensitive: 'web.default_sensitive', + default_language: 'default_language', + noindex: 'noindex', + theme: 'theme', + trends: 'web.trends', + unfollow_modal: 'web.unfollow_modal', + boost_modal: 'web.reblog_modal', + delete_modal: 'web.delete_modal', + auto_play_gif: 'web.auto_play', + display_media: 'web.display_media', + expand_spoilers: 'web.expand_content_warnings', + reduce_motion: 'web.reduce_motion', + disable_swiping: 'web.disable_swiping', + show_application: 'show_application', + system_font_ui: 'web.use_system_font', + aggregate_reblogs: 'aggregate_reblogs', + advanced_layout: 'web.advanced_layout', + use_blurhash: 'web.use_blurhash', + use_pending_items: 'web.use_pending_items', + crop_images: 'web.crop_images', + notification_emails: { + follow: 'notification_emails.follow', + reblog: 'notification_emails.reblog', + favourite: 'notification_emails.favourite', + mention: 'notification_emails.mention', + follow_request: 'notification_emails.follow_request', + report: 'notification_emails.report', + pending_account: 'notification_emails.pending_account', + trending_tag: 'notification_emails.trends', + appeal: 'notification_emails.appeal', + }.freeze, + always_send_emails: 'always_send_emails', + interactions: { + must_be_follower: 'interactions.must_be_follower', + must_be_following: 'interactions.must_be_following', + must_be_following_dm: 'interactions.must_be_following_dm', + }.freeze, + }.freeze + + class LegacySetting < ApplicationRecord + self.table_name = 'settings' + + def var + self[:var]&.to_sym + end + + def value + YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present? + end + end + + def up + User.find_in_batches do |users| + previous_settings_for_batch = LegacySetting.where(thing_type: 'User', thing_id: users.map(&:id)).group_by(&:thing_id) + + users.each do |user| + previous_settings = previous_settings_for_batch[user.id]&.index_by(&:var) || {} + user_settings = {} + + MAPPING.each do |legacy_key, new_key| + value = previous_settings[legacy_key]&.value + + next if value.nil? + + if value.is_a?(Hash) + value.each do |nested_key, nested_value| + user_settings[MAPPING[legacy_key][nested_key.to_sym]] = nested_value + end + else + user_settings[new_key] = value + end + end + + user.update_column('settings', Oj.dump(user_settings)) # rubocop:disable Rails/SkipsModelValidations + end + end + end + + def down; end +end diff --git a/db/migrate/20230215074424_move_glitch_user_settings.rb b/db/migrate/20230215074424_move_glitch_user_settings.rb new file mode 100644 index 0000000000..48bb6f97e0 --- /dev/null +++ b/db/migrate/20230215074424_move_glitch_user_settings.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +class MoveGlitchUserSettings < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + class User < ApplicationRecord; end + + MAPPING = { + favourite_modal: 'web.favourite_modal', + system_emoji_font: 'web.use_system_emoji_font', + hide_followers_count: 'hide_followers_count', + default_content_type: 'default_content_type', + flavour: 'flavour', + skin: 'skin', + notification_emails: { + trending_link: 'notification_emails.link_trends', + trending_status: 'notification_emails.status_trends', + }.freeze, + }.freeze + + class LegacySetting < ApplicationRecord + self.table_name = 'settings' + + def var + self[:var]&.to_sym + end + + def value + YAML.safe_load(self[:value], permitted_classes: [ActiveSupport::HashWithIndifferentAccess, Symbol]) if self[:value].present? + end + end + + def up + User.find_in_batches do |users| + previous_settings_for_batch = LegacySetting.where(thing_type: 'User', thing_id: users.map(&:id)).group_by(&:thing_id) + + users.each do |user| + previous_settings = previous_settings_for_batch[user.id]&.index_by(&:var) || {} + user_settings = Oj.load(user.settings || '{}') + user_settings.delete('theme') + + MAPPING.each do |legacy_key, new_key| + value = previous_settings[legacy_key]&.value + + next if value.nil? + + if value.is_a?(Hash) + value.each do |nested_key, nested_value| + user_settings[MAPPING[legacy_key][nested_key.to_sym]] = nested_value + end + else + user_settings[new_key] = value + end + end + + user.update_column('settings', Oj.dump(user_settings)) # rubocop:disable Rails/SkipsModelValidations + end + end + end + + def down; end +end diff --git a/db/migrate/20230330135507_create_bulk_imports.rb b/db/migrate/20230330135507_create_bulk_imports.rb new file mode 100644 index 0000000000..117a135086 --- /dev/null +++ b/db/migrate/20230330135507_create_bulk_imports.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class CreateBulkImports < ActiveRecord::Migration[6.1] + def change + create_table :bulk_imports do |t| + t.integer :type, null: false + t.integer :state, null: false + t.integer :total_items, null: false, default: 0 + t.integer :imported_items, null: false, default: 0 + t.integer :processed_items, null: false, default: 0 + t.datetime :finished_at + t.boolean :overwrite, null: false, default: false + t.boolean :likely_mismatched, null: false, default: false + t.string :original_filename, null: false, default: '' + t.references :account, null: false, foreign_key: { on_delete: :cascade } + + t.timestamps + end + + add_index :bulk_imports, [:id], name: :index_bulk_imports_unconfirmed, where: 'state = 0' + end +end diff --git a/db/migrate/20230330140036_create_bulk_import_rows.rb b/db/migrate/20230330140036_create_bulk_import_rows.rb new file mode 100644 index 0000000000..ef6ad7069b --- /dev/null +++ b/db/migrate/20230330140036_create_bulk_import_rows.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class CreateBulkImportRows < ActiveRecord::Migration[6.1] + def change + create_table :bulk_import_rows do |t| + t.references :bulk_import, null: false, foreign_key: { on_delete: :cascade } + t.jsonb :data + + t.timestamps + end + end +end diff --git a/db/migrate/20230330155710_add_follow_request_id_to_list_accounts.rb b/db/migrate/20230330155710_add_follow_request_id_to_list_accounts.rb new file mode 100644 index 0000000000..5f4ac374ca --- /dev/null +++ b/db/migrate/20230330155710_add_follow_request_id_to_list_accounts.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddFollowRequestIdToListAccounts < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + safety_assured { add_reference :list_accounts, :follow_request, foreign_key: { on_delete: :cascade }, index: false } + add_index :list_accounts, :follow_request_id, algorithm: :concurrently, where: 'follow_request_id IS NOT NULL' + end +end diff --git a/db/migrate/20230524190515_add_index_accounts_on_domain_and_id.rb b/db/migrate/20230524190515_add_index_accounts_on_domain_and_id.rb new file mode 100644 index 0000000000..4ee52b0ca8 --- /dev/null +++ b/db/migrate/20230524190515_add_index_accounts_on_domain_and_id.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIndexAccountsOnDomainAndId < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + add_index :accounts, [:domain, :id], name: :index_accounts_on_domain_and_id, algorithm: :concurrently + end +end diff --git a/db/migrate/20230524192812_fix_account_domain_casing.rb b/db/migrate/20230524192812_fix_account_domain_casing.rb new file mode 100644 index 0000000000..e1edf23749 --- /dev/null +++ b/db/migrate/20230524192812_fix_account_domain_casing.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class FixAccountDomainCasing < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def up + safety_assured do + execute 'UPDATE accounts SET domain = lower(domain) WHERE domain IS NOT NULL AND domain != lower(domain)' + end + end + + def down; end +end diff --git a/db/migrate/20230524194155_add_index_instances_on_reverse_domain.rb b/db/migrate/20230524194155_add_index_instances_on_reverse_domain.rb new file mode 100644 index 0000000000..c3e774936c --- /dev/null +++ b/db/migrate/20230524194155_add_index_instances_on_reverse_domain.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIndexInstancesOnReverseDomain < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + add_index :instances, "reverse('.' || domain), domain", name: :index_instances_on_reverse_domain, algorithm: :concurrently + end +end diff --git a/db/migrate/20230531153942_add_primary_key_to_accounts_tags_join_table.rb b/db/migrate/20230531153942_add_primary_key_to_accounts_tags_join_table.rb new file mode 100644 index 0000000000..0c3c17a366 --- /dev/null +++ b/db/migrate/20230531153942_add_primary_key_to_accounts_tags_join_table.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class AddPrimaryKeyToAccountsTagsJoinTable < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def up + ActiveRecord::Base.transaction do + safety_assured do + execute 'ALTER TABLE accounts_tags ADD PRIMARY KEY USING INDEX index_accounts_tags_on_tag_id_and_account_id' + + # Rename for consistency as the primary key's name is not represented in db/schema.rb + execute 'ALTER INDEX index_accounts_tags_on_tag_id_and_account_id RENAME TO accounts_tags_pkey' + end + end + end + + def down + safety_assured do + # I have found no way to demote the primary key to an index, instead, re-create the index + execute 'CREATE UNIQUE INDEX CONCURRENTLY index_accounts_tags_on_tag_id_and_account_id ON accounts_tags (tag_id, account_id)' + execute 'ALTER TABLE accounts_tags DROP CONSTRAINT accounts_tags_pkey' + end + end +end diff --git a/db/migrate/20230531154811_add_primary_key_to_statuses_tags_join_table.rb b/db/migrate/20230531154811_add_primary_key_to_statuses_tags_join_table.rb new file mode 100644 index 0000000000..6581943da2 --- /dev/null +++ b/db/migrate/20230531154811_add_primary_key_to_statuses_tags_join_table.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class AddPrimaryKeyToStatusesTagsJoinTable < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def up + ActiveRecord::Base.transaction do + safety_assured do + execute 'ALTER TABLE statuses_tags ADD PRIMARY KEY USING INDEX index_statuses_tags_on_tag_id_and_status_id' + + # Rename for consistency as the primary key's name is not represented in db/schema.rb + execute 'ALTER INDEX index_statuses_tags_on_tag_id_and_status_id RENAME TO statuses_tags_pkey' + end + end + end + + def down + safety_assured do + # I have found no way to demote the primary key to an index, instead, re-create the index + execute 'CREATE UNIQUE INDEX CONCURRENTLY index_statuses_tags_on_tag_id_and_status_id ON statuses_tags (tag_id, status_id)' + execute 'ALTER TABLE statuses_tags DROP CONSTRAINT statuses_tags_pkey' + end + end +end diff --git a/db/migrate/20230605085710_add_exclusive_to_lists.rb b/db/migrate/20230605085710_add_exclusive_to_lists.rb new file mode 100644 index 0000000000..315c9d4872 --- /dev/null +++ b/db/migrate/20230605085710_add_exclusive_to_lists.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddExclusiveToLists < ActiveRecord::Migration[6.1] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured { add_column_with_default :lists, :exclusive, :boolean, default: false, allow_null: false } + end + + def down + remove_column :lists, :exclusive + end +end diff --git a/db/migrate/20230605085711_add_time_zone_to_users.rb b/db/migrate/20230605085711_add_time_zone_to_users.rb new file mode 100644 index 0000000000..fc6c0b091c --- /dev/null +++ b/db/migrate/20230605085711_add_time_zone_to_users.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddTimeZoneToUsers < ActiveRecord::Migration[6.1] + def change + add_column :users, :time_zone, :string + end +end diff --git a/db/migrate/20230630145300_add_index_backups_on_user_id.rb b/db/migrate/20230630145300_add_index_backups_on_user_id.rb new file mode 100644 index 0000000000..c3d2f17707 --- /dev/null +++ b/db/migrate/20230630145300_add_index_backups_on_user_id.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIndexBackupsOnUserId < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + add_index :backups, :user_id, algorithm: :concurrently + end +end diff --git a/db/migrate/20230702131023_add_superapp_index_to_applications.rb b/db/migrate/20230702131023_add_superapp_index_to_applications.rb new file mode 100644 index 0000000000..f301127a3e --- /dev/null +++ b/db/migrate/20230702131023_add_superapp_index_to_applications.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddSuperappIndexToApplications < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + add_index :oauth_applications, :superapp, where: 'superapp = true', algorithm: :concurrently + end +end diff --git a/db/migrate/20230702151753_add_index_user_on_unconfirmed_email.rb b/db/migrate/20230702151753_add_index_user_on_unconfirmed_email.rb new file mode 100644 index 0000000000..a935463eaa --- /dev/null +++ b/db/migrate/20230702151753_add_index_user_on_unconfirmed_email.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIndexUserOnUnconfirmedEmail < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def change + add_index :users, :unconfirmed_email, where: 'unconfirmed_email IS NOT NULL', algorithm: :concurrently + end +end diff --git a/db/migrate/20230724160715_add_published_at_to_preview_cards.rb b/db/migrate/20230724160715_add_published_at_to_preview_cards.rb new file mode 100644 index 0000000000..a1571b3b2a --- /dev/null +++ b/db/migrate/20230724160715_add_published_at_to_preview_cards.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddPublishedAtToPreviewCards < ActiveRecord::Migration[7.0] + def change + add_column :preview_cards, :published_at, :datetime + end +end diff --git a/db/migrate/20230725213448_add_image_description_to_preview_cards.rb b/db/migrate/20230725213448_add_image_description_to_preview_cards.rb new file mode 100644 index 0000000000..03020db655 --- /dev/null +++ b/db/migrate/20230725213448_add_image_description_to_preview_cards.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddImageDescriptionToPreviewCards < ActiveRecord::Migration[7.0] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured { add_column_with_default :preview_cards, :image_description, :string, default: '', allow_null: false } + end + + def down + remove_column :preview_cards, :image_description + end +end diff --git a/db/migrate/20230814223300_add_indexable_to_accounts.rb b/db/migrate/20230814223300_add_indexable_to_accounts.rb new file mode 100644 index 0000000000..6729c05ef2 --- /dev/null +++ b/db/migrate/20230814223300_add_indexable_to_accounts.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddIndexableToAccounts < ActiveRecord::Migration[7.0] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured { add_column_with_default :accounts, :indexable, :boolean, default: false, allow_null: false } + end + + def down + remove_column :accounts, :indexable + end +end diff --git a/db/migrate/20230818141056_create_global_follow_recommendations.rb b/db/migrate/20230818141056_create_global_follow_recommendations.rb new file mode 100644 index 0000000000..b88c71b9d7 --- /dev/null +++ b/db/migrate/20230818141056_create_global_follow_recommendations.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class CreateGlobalFollowRecommendations < ActiveRecord::Migration[7.0] + def change + create_view :global_follow_recommendations, materialized: { no_data: true } + safety_assured { add_index :global_follow_recommendations, :account_id, unique: true } + end +end diff --git a/db/migrate/20230822081029_create_software_updates.rb b/db/migrate/20230822081029_create_software_updates.rb new file mode 100644 index 0000000000..146d5d3037 --- /dev/null +++ b/db/migrate/20230822081029_create_software_updates.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class CreateSoftwareUpdates < ActiveRecord::Migration[7.0] + def change + create_table :software_updates do |t| + t.string :version, null: false + t.boolean :urgent, default: false, null: false + t.integer :type, default: 0, null: false + t.string :release_notes, default: '', null: false + + t.timestamps + end + + add_index :software_updates, :version, unique: true + end +end diff --git a/db/migrate/20230907150100_add_index_account_stats_on_last_status_at_and_account_id.rb b/db/migrate/20230907150100_add_index_account_stats_on_last_status_at_and_account_id.rb new file mode 100644 index 0000000000..17ac65547c --- /dev/null +++ b/db/migrate/20230907150100_add_index_account_stats_on_last_status_at_and_account_id.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddIndexAccountStatsOnLastStatusAtAndAccountId < ActiveRecord::Migration[7.0] + disable_ddl_transaction! + + def change + add_index :account_stats, [:last_status_at, :account_id], order: { last_status_at: 'DESC NULLS LAST' }, algorithm: :concurrently + end +end diff --git a/db/post_migrate/20180813160548_post_migrate_filters.rb b/db/post_migrate/20180813160548_post_migrate_filters.rb new file mode 100644 index 0000000000..82acf13d51 --- /dev/null +++ b/db/post_migrate/20180813160548_post_migrate_filters.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class PostMigrateFilters < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def up + drop_table :glitch_keyword_mutes if table_exists? :glitch_keyword_mutes + end + + def down; end +end diff --git a/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb b/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb index a46349cb73..615f35cd0d 100644 --- a/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb +++ b/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb @@ -34,6 +34,7 @@ class RemoveSuspendedSilencedAccountFields < ActiveRecord::Migration[5.2] remove_column :accounts, :suspended, :boolean, null: false, default: false remove_column :accounts, :silenced, :boolean, null: false, default: false end + Account.reset_column_information end def down diff --git a/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb b/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb index d2d9242392..89a95041ee 100644 --- a/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb +++ b/db/post_migrate/20190519130537_remove_boosts_widening_audience.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class RemoveBoostsWideningAudience < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up - public_boosts = Status.find_by_sql(<<-SQL) + public_boosts = Status.find_by_sql(<<-SQL.squish) SELECT boost.id FROM statuses AS boost LEFT JOIN statuses AS boosted ON boost.reblog_of_id = boosted.id diff --git a/db/post_migrate/20200917193528_migrate_notifications_type.rb b/db/post_migrate/20200917193528_migrate_notifications_type.rb index 88e4230842..9dc9ecd48e 100644 --- a/db/post_migrate/20200917193528_migrate_notifications_type.rb +++ b/db/post_migrate/20200917193528_migrate_notifications_type.rb @@ -4,12 +4,12 @@ class MigrateNotificationsType < ActiveRecord::Migration[5.2] disable_ddl_transaction! TYPES_TO_MIGRATE = { - 'Mention' => :mention, - 'Status' => :reblog, - 'Follow' => :follow, + 'Mention' => :mention, + 'Status' => :reblog, + 'Follow' => :follow, 'FollowRequest' => :follow_request, - 'Favourite' => :favourite, - 'Poll' => :poll, + 'Favourite' => :favourite, + 'Poll' => :poll, }.freeze def up diff --git a/db/post_migrate/20201017234926_fill_account_suspension_origin.rb b/db/post_migrate/20201017234926_fill_account_suspension_origin.rb index ab7407d79e..b00f9df533 100644 --- a/db/post_migrate/20201017234926_fill_account_suspension_origin.rb +++ b/db/post_migrate/20201017234926_fill_account_suspension_origin.rb @@ -3,8 +3,15 @@ class FillAccountSuspensionOrigin < ActiveRecord::Migration[5.2] disable_ddl_transaction! + class MigrationAccount < ApplicationRecord + self.table_name = :accounts + scope :suspended, -> { where.not(suspended_at: nil) } + enum suspension_origin: { local: 0, remote: 1 }, _prefix: true + end + def up - Account.suspended.where(suspension_origin: nil).in_batches.update_all(suspension_origin: :local) + MigrationAccount.reset_column_information + MigrationAccount.suspended.where(suspension_origin: nil).in_batches.update_all(suspension_origin: :local) end def down; end diff --git a/db/post_migrate/20210308133107_remove_subscription_expires_at_from_accounts.rb b/db/post_migrate/20210308133107_remove_subscription_expires_at_from_accounts.rb index 53e24ef261..f95e96297e 100644 --- a/db/post_migrate/20210308133107_remove_subscription_expires_at_from_accounts.rb +++ b/db/post_migrate/20210308133107_remove_subscription_expires_at_from_accounts.rb @@ -1,7 +1,9 @@ -class RemoveSubscriptionExpiresAtFromAccounts < ActiveRecord::Migration[5.0] +# frozen_string_literal: true + +class RemoveSubscriptionExpiresAtFromAccounts < ActiveRecord::Migration[5.2] def change safety_assured do - remove_column :accounts, :subscription_expires_at, :datetime, null: true, default: nil + remove_column :accounts, :subscription_expires_at, :datetime, null: true, default: nil, precision: nil end end end diff --git a/db/post_migrate/20220118183123_remove_rememberable_from_users.rb b/db/post_migrate/20220118183123_remove_rememberable_from_users.rb index 1e274c6e0b..0acd686145 100644 --- a/db/post_migrate/20220118183123_remove_rememberable_from_users.rb +++ b/db/post_migrate/20220118183123_remove_rememberable_from_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class RemoveRememberableFromUsers < ActiveRecord::Migration[6.1] def change safety_assured do diff --git a/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb b/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb index 7ef0749e54..99c3366a20 100644 --- a/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb +++ b/db/post_migrate/20220613110802_remove_whole_word_from_custom_filters.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class RemoveWholeWordFromCustomFilters < ActiveRecord::Migration[6.1] diff --git a/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb b/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb index 6ed8bcfeee..1c366ee53c 100644 --- a/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb +++ b/db/post_migrate/20220613110903_remove_irreversible_from_custom_filters.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require Rails.root.join('lib', 'mastodon', 'migration_helpers') class RemoveIrreversibleFromCustomFilters < ActiveRecord::Migration[6.1] diff --git a/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb b/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb index 7ed34a3efc..eb437c86c5 100644 --- a/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb +++ b/db/post_migrate/20220729171123_fix_custom_filter_keywords_id_seq.rb @@ -5,7 +5,7 @@ class FixCustomFilterKeywordsIdSeq < ActiveRecord::Migration[6.1] def up # 20220613110711 manually inserts items with set `id` in the database, but - # we also need to bump the sequence number, otherwise + # we also need to bump the sequence number, otherwise safety_assured do execute <<-SQL.squish BEGIN; diff --git a/db/post_migrate/20221101190723_backfill_admin_action_logs.rb b/db/post_migrate/20221101190723_backfill_admin_action_logs.rb index 48ef1e6e31..6476f4b13a 100644 --- a/db/post_migrate/20221101190723_backfill_admin_action_logs.rb +++ b/db/post_migrate/20221101190723_backfill_admin_action_logs.rb @@ -62,7 +62,7 @@ class BackfillAdminActionLogs < ActiveRecord::Migration[6.1] # Cannot use usual polymorphic support because of namespacing issues belongs_to :status, foreign_key: :target_id belongs_to :account, foreign_key: :target_id - belongs_to :user, foreign_key: :user_id + belongs_to :user belongs_to :domain_block, foreign_key: :target_id belongs_to :domain_allow, foreign_key: :target_id belongs_to :email_domain_block, foreign_key: :target_id @@ -79,70 +79,83 @@ class BackfillAdminActionLogs < ActiveRecord::Migration[6.1] safety_assured do AdminActionLog.includes(:account).where(target_type: 'Account', human_identifier: nil).find_each do |log| next if log.account.nil? + log.update_attribute('human_identifier', log.account.acct) end AdminActionLog.includes(user: :account).where(target_type: 'User', human_identifier: nil).find_each do |log| next if log.user.nil? + log.update_attribute('human_identifier', log.user.account.acct) log.update_attribute('route_param', log.user.account_id) end - Admin::ActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') + AdminActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') AdminActionLog.includes(:domain_block).where(target_type: 'DomainBlock').find_each do |log| next if log.domain_block.nil? + log.update_attribute('human_identifier', log.domain_block.domain) end AdminActionLog.includes(:domain_allow).where(target_type: 'DomainAllow').find_each do |log| next if log.domain_allow.nil? + log.update_attribute('human_identifier', log.domain_allow.domain) end AdminActionLog.includes(:email_domain_block).where(target_type: 'EmailDomainBlock').find_each do |log| next if log.email_domain_block.nil? + log.update_attribute('human_identifier', log.email_domain_block.domain) end AdminActionLog.includes(:unavailable_domain).where(target_type: 'UnavailableDomain').find_each do |log| next if log.unavailable_domain.nil? + log.update_attribute('human_identifier', log.unavailable_domain.domain) end AdminActionLog.includes(status: :account).where(target_type: 'Status', human_identifier: nil).find_each do |log| next if log.status.nil? + log.update_attribute('human_identifier', log.status.account.acct) log.update_attribute('permalink', log.status.uri) end AdminActionLog.includes(account_warning: :account).where(target_type: 'AccountWarning', human_identifier: nil).find_each do |log| next if log.account_warning.nil? + log.update_attribute('human_identifier', log.account_warning.account.acct) end AdminActionLog.includes(:announcement).where(target_type: 'Announcement', human_identifier: nil).find_each do |log| next if log.announcement.nil? + log.update_attribute('human_identifier', log.announcement.text) end AdminActionLog.includes(:ip_block).where(target_type: 'IpBlock', human_identifier: nil).find_each do |log| next if log.ip_block.nil? + log.update_attribute('human_identifier', "#{log.ip_block.ip}/#{log.ip_block.ip.prefix}") end AdminActionLog.includes(:custom_emoji).where(target_type: 'CustomEmoji', human_identifier: nil).find_each do |log| next if log.custom_emoji.nil? + log.update_attribute('human_identifier', log.custom_emoji.shortcode) end AdminActionLog.includes(:canonical_email_block).where(target_type: 'CanonicalEmailBlock', human_identifier: nil).find_each do |log| next if log.canonical_email_block.nil? + log.update_attribute('human_identifier', log.canonical_email_block.canonical_email_hash) end AdminActionLog.includes(appeal: :account).where(target_type: 'Appeal', human_identifier: nil).find_each do |log| next if log.appeal.nil? + log.update_attribute('human_identifier', log.appeal.account.acct) log.update_attribute('route_param', log.appeal.account_warning_id) end diff --git a/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb b/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb index 279053ab94..3c68470a7f 100644 --- a/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb +++ b/db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb @@ -62,7 +62,7 @@ class BackfillAdminActionLogsAgain < ActiveRecord::Migration[6.1] # Cannot use usual polymorphic support because of namespacing issues belongs_to :status, foreign_key: :target_id belongs_to :account, foreign_key: :target_id - belongs_to :user, foreign_key: :user_id + belongs_to :user belongs_to :domain_block, foreign_key: :target_id belongs_to :domain_allow, foreign_key: :target_id belongs_to :email_domain_block, foreign_key: :target_id @@ -79,70 +79,83 @@ class BackfillAdminActionLogsAgain < ActiveRecord::Migration[6.1] safety_assured do AdminActionLog.includes(:account).where(target_type: 'Account', human_identifier: nil).find_each do |log| next if log.account.nil? + log.update_attribute('human_identifier', log.account.acct) end AdminActionLog.includes(user: :account).where(target_type: 'User', human_identifier: nil).find_each do |log| next if log.user.nil? + log.update_attribute('human_identifier', log.user.account.acct) log.update_attribute('route_param', log.user.account_id) end - Admin::ActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') + AdminActionLog.where(target_type: 'Report', human_identifier: nil).in_batches.update_all('human_identifier = target_id::text') AdminActionLog.includes(:domain_block).where(target_type: 'DomainBlock').find_each do |log| next if log.domain_block.nil? + log.update_attribute('human_identifier', log.domain_block.domain) end AdminActionLog.includes(:domain_allow).where(target_type: 'DomainAllow').find_each do |log| next if log.domain_allow.nil? + log.update_attribute('human_identifier', log.domain_allow.domain) end AdminActionLog.includes(:email_domain_block).where(target_type: 'EmailDomainBlock').find_each do |log| next if log.email_domain_block.nil? + log.update_attribute('human_identifier', log.email_domain_block.domain) end AdminActionLog.includes(:unavailable_domain).where(target_type: 'UnavailableDomain').find_each do |log| next if log.unavailable_domain.nil? + log.update_attribute('human_identifier', log.unavailable_domain.domain) end AdminActionLog.includes(status: :account).where(target_type: 'Status', human_identifier: nil).find_each do |log| next if log.status.nil? + log.update_attribute('human_identifier', log.status.account.acct) log.update_attribute('permalink', log.status.uri) end AdminActionLog.includes(account_warning: :account).where(target_type: 'AccountWarning', human_identifier: nil).find_each do |log| next if log.account_warning.nil? + log.update_attribute('human_identifier', log.account_warning.account.acct) end AdminActionLog.includes(:announcement).where(target_type: 'Announcement', human_identifier: nil).find_each do |log| next if log.announcement.nil? + log.update_attribute('human_identifier', log.announcement.text) end AdminActionLog.includes(:ip_block).where(target_type: 'IpBlock', human_identifier: nil).find_each do |log| next if log.ip_block.nil? + log.update_attribute('human_identifier', "#{log.ip_block.ip}/#{log.ip_block.ip.prefix}") end AdminActionLog.includes(:custom_emoji).where(target_type: 'CustomEmoji', human_identifier: nil).find_each do |log| next if log.custom_emoji.nil? + log.update_attribute('human_identifier', log.custom_emoji.shortcode) end AdminActionLog.includes(:canonical_email_block).where(target_type: 'CanonicalEmailBlock', human_identifier: nil).find_each do |log| next if log.canonical_email_block.nil? + log.update_attribute('human_identifier', log.canonical_email_block.canonical_email_hash) end AdminActionLog.includes(appeal: :account).where(target_type: 'Appeal', human_identifier: nil).find_each do |log| next if log.appeal.nil? + log.update_attribute('human_identifier', log.appeal.account.acct) log.update_attribute('route_param', log.appeal.account_warning_id) end diff --git a/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb b/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb new file mode 100644 index 0000000000..d29d7847c5 --- /dev/null +++ b/db/post_migrate/20230803082451_add_unique_index_on_preview_cards_statuses.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +class AddUniqueIndexOnPreviewCardsStatuses < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def up + add_index :preview_cards_statuses, [:status_id, :preview_card_id], name: :preview_cards_statuses_pkey, algorithm: :concurrently, unique: true + rescue ActiveRecord::RecordNotUnique + deduplicate_and_reindex! + end + + def down + remove_index :preview_cards_statuses, name: :preview_cards_statuses_pkey + end + + private + + def supports_concurrent_reindex? + @supports_concurrent_reindex ||= begin + version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i + version >= 120_000 + end + end + + def deduplicate_and_reindex! + deduplicate_preview_cards! + + if supports_concurrent_reindex? + safety_assured { execute 'REINDEX INDEX CONCURRENTLY preview_cards_statuses_pkey' } + else + remove_index :preview_cards_statuses, name: :preview_cards_statuses_pkey + add_index :preview_cards_statuses, [:status_id, :preview_card_id], name: :preview_cards_statuses_pkey, algorithm: :concurrently, unique: true + end + rescue ActiveRecord::RecordNotUnique + retry + end + + def deduplicate_preview_cards! + # Statuses should have only one preview card at most, even if that's not the database + # constraint we will end up with + duplicate_ids = select_all('SELECT status_id FROM preview_cards_statuses GROUP BY status_id HAVING count(*) > 1;').rows + + duplicate_ids.each_slice(1000) do |ids| + # This one is tricky: since we don't have primary keys to keep only one record, + # use the physical `ctid` + safety_assured do + execute "DELETE FROM preview_cards_statuses p WHERE p.status_id IN (#{ids.join(', ')}) AND p.ctid NOT IN (SELECT q.ctid FROM preview_cards_statuses q WHERE q.status_id = p.status_id LIMIT 1)" + end + end + end +end diff --git a/db/post_migrate/20230803112520_add_primary_key_to_preview_cards_statuses_join_table.rb b/db/post_migrate/20230803112520_add_primary_key_to_preview_cards_statuses_join_table.rb new file mode 100644 index 0000000000..34877ac672 --- /dev/null +++ b/db/post_migrate/20230803112520_add_primary_key_to_preview_cards_statuses_join_table.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class AddPrimaryKeyToPreviewCardsStatusesJoinTable < ActiveRecord::Migration[6.1] + disable_ddl_transaction! + + def up + safety_assured do + execute 'ALTER TABLE preview_cards_statuses ADD PRIMARY KEY USING INDEX preview_cards_statuses_pkey' + end + end + + def down + safety_assured do + # I have found no way to demote the primary key to an index, instead, re-create the index + execute 'CREATE UNIQUE INDEX CONCURRENTLY preview_cards_statuses_pkey_tmp ON preview_cards_statuses (status_id, preview_card_id)' + execute 'ALTER TABLE preview_cards_statuses DROP CONSTRAINT preview_cards_statuses_pkey' + execute 'ALTER INDEX preview_cards_statuses_pkey_tmp RENAME TO preview_cards_statuses_pkey' + end + end +end diff --git a/db/post_migrate/20230811103651_remove_index_preview_cards_statuses_on_status_id_and_preview_card_id.rb b/db/post_migrate/20230811103651_remove_index_preview_cards_statuses_on_status_id_and_preview_card_id.rb new file mode 100644 index 0000000000..11e0bf6f1b --- /dev/null +++ b/db/post_migrate/20230811103651_remove_index_preview_cards_statuses_on_status_id_and_preview_card_id.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class RemoveIndexPreviewCardsStatusesOnStatusIdAndPreviewCardId < ActiveRecord::Migration[7.0] + disable_ddl_transaction! + + def change + remove_index :preview_cards_statuses, column: [:status_id, :preview_card_id], name: :index_preview_cards_statuses_on_status_id_and_preview_card_id + end +end diff --git a/db/post_migrate/20230818142253_drop_follow_recommendations.rb b/db/post_migrate/20230818142253_drop_follow_recommendations.rb new file mode 100644 index 0000000000..95913d6caa --- /dev/null +++ b/db/post_migrate/20230818142253_drop_follow_recommendations.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class DropFollowRecommendations < ActiveRecord::Migration[7.0] + def up + drop_view :follow_recommendations, materialized: true + end + + def down + create_view :follow_recommendations, version: 2, materialized: { no_data: true } + safety_assured { add_index :follow_recommendations, :account_id, unique: true } + end +end diff --git a/db/post_migrate/20230904134623_fix_kmr_locale_settings.rb b/db/post_migrate/20230904134623_fix_kmr_locale_settings.rb new file mode 100644 index 0000000000..10e3f1da99 --- /dev/null +++ b/db/post_migrate/20230904134623_fix_kmr_locale_settings.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class FixKmrLocaleSettings < ActiveRecord::Migration[7.0] + disable_ddl_transaction! + + class MigrationUser < ApplicationRecord + self.table_name = :users + end + + def up + MigrationUser.reset_column_information + + MigrationUser.where.not(settings: [nil, '{}']).find_each do |user| + user_settings = Oj.load(user.settings) + next unless user_settings['default_language'] == 'kmr' + + user_settings['default_language'] = 'ku' + user.update!(settings: Oj.dump(user_settings)) + end + + MigrationUser.where.not(chosen_languages: nil).where('chosen_languages && ?', '{kmr}').find_each do |user| + user.update!(chosen_languages: user.chosen_languages.map { |lang| lang == 'kmr' ? 'ku' : lang }.uniq) + end + end + + def down; end +end diff --git a/db/schema.rb b/db/schema.rb index 704cef1228..9c7c490bb1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,8 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_12_06_114142) do - +ActiveRecord::Schema[7.0].define(version: 2023_09_07_150100) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -19,8 +18,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "account_id" t.string "acct", default: "", null: false t.string "uri", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id"], name: "index_account_aliases_on_account_id" end @@ -38,15 +37,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "account_deletion_requests", force: :cascade do |t| t.bigint "account_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id"], name: "index_account_deletion_requests_on_account_id" end create_table "account_domain_blocks", force: :cascade do |t| t.string "domain" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id" t.index ["account_id", "domain"], name: "index_account_domain_blocks_on_account_id_and_domain", unique: true end @@ -56,8 +55,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "acct", default: "", null: false t.bigint "followers_count", default: 0, null: false t.bigint "target_account_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id"], name: "index_account_migrations_on_account_id" t.index ["target_account_id"], name: "index_account_migrations_on_target_account_id", where: "(target_account_id IS NOT NULL)" end @@ -66,8 +65,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.text "content", null: false t.bigint "account_id", null: false t.bigint "target_account_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id"], name: "index_account_moderation_notes_on_account_id" t.index ["target_account_id"], name: "index_account_moderation_notes_on_target_account_id" end @@ -76,8 +75,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "account_id" t.bigint "target_account_id" t.text "comment", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id", "target_account_id"], name: "index_account_notes_on_account_id_and_target_account_id", unique: true t.index ["target_account_id"], name: "index_account_notes_on_target_account_id" end @@ -85,8 +84,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "account_pins", force: :cascade do |t| t.bigint "account_id" t.bigint "target_account_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id", "target_account_id"], name: "index_account_pins_on_account_id_and_target_account_id", unique: true t.index ["target_account_id"], name: "index_account_pins_on_target_account_id" end @@ -96,10 +95,11 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "statuses_count", default: 0, null: false t.bigint "following_count", default: 0, null: false t.bigint "followers_count", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.datetime "last_status_at" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.datetime "last_status_at", precision: nil t.index ["account_id"], name: "index_account_stats_on_account_id", unique: true + t.index ["last_status_at", "account_id"], name: "index_account_stats_on_last_status_at_and_account_id", order: { last_status_at: "DESC NULLS LAST" } end create_table "account_statuses_cleanup_policies", force: :cascade do |t| @@ -114,15 +114,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.boolean "keep_self_bookmark", default: true, null: false t.integer "min_favs" t.integer "min_reblogs" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["account_id"], name: "index_account_statuses_cleanup_policies_on_account_id" end create_table "account_warning_presets", force: :cascade do |t| t.text "text", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "title", default: "", null: false end @@ -131,11 +131,11 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "target_account_id" t.integer "action", default: 0, null: false t.text "text", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "report_id" t.string "status_ids", array: true - t.datetime "overruled_at" + t.datetime "overruled_at", precision: nil t.index ["account_id"], name: "index_account_warnings_on_account_id" t.index ["target_account_id"], name: "index_account_warnings_on_target_account_id" end @@ -145,8 +145,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "domain" t.text "private_key" t.text "public_key", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.text "note", default: "", null: false t.string "display_name", default: "", null: false t.string "uri", default: "", null: false @@ -154,15 +154,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "avatar_file_name" t.string "avatar_content_type" t.integer "avatar_file_size" - t.datetime "avatar_updated_at" + t.datetime "avatar_updated_at", precision: nil t.string "header_file_name" t.string "header_content_type" t.integer "header_file_size" - t.datetime "header_updated_at" + t.datetime "header_updated_at", precision: nil t.string "avatar_remote_url" t.boolean "locked", default: false, null: false t.string "header_remote_url", default: "", null: false - t.datetime "last_webfingered_at" + t.datetime "last_webfingered_at", precision: nil t.string "inbox_url", default: "", null: false t.string "outbox_url", default: "", null: false t.string "shared_inbox_url", default: "", null: false @@ -175,29 +175,30 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "actor_type" t.boolean "discoverable" t.string "also_known_as", array: true - t.datetime "silenced_at" - t.datetime "suspended_at" + t.datetime "silenced_at", precision: nil + t.datetime "suspended_at", precision: nil t.boolean "hide_collections" t.integer "avatar_storage_schema_version" t.integer "header_storage_schema_version" t.string "devices_url" t.integer "suspension_origin" - t.datetime "sensitized_at" + t.datetime "sensitized_at", precision: nil t.boolean "trendable" - t.datetime "reviewed_at" - t.datetime "requested_review_at" + t.datetime "reviewed_at", precision: nil + t.datetime "requested_review_at", precision: nil + t.boolean "indexable", default: false, null: false t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), COALESCE(lower((domain)::text), ''::text)", name: "index_accounts_on_username_and_domain_lower", unique: true + t.index ["domain", "id"], name: "index_accounts_on_domain_and_id" t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id", where: "(moved_to_account_id IS NOT NULL)" t.index ["uri"], name: "index_accounts_on_uri" t.index ["url"], name: "index_accounts_on_url", opclass: :text_pattern_ops, where: "(url IS NOT NULL)" end - create_table "accounts_tags", id: false, force: :cascade do |t| + create_table "accounts_tags", primary_key: ["tag_id", "account_id"], force: :cascade do |t| t.bigint "account_id", null: false t.bigint "tag_id", null: false t.index ["account_id", "tag_id"], name: "index_accounts_tags_on_account_id_and_tag_id" - t.index ["tag_id", "account_id"], name: "index_accounts_tags_on_tag_id_and_account_id", unique: true end create_table "admin_action_logs", force: :cascade do |t| @@ -205,8 +206,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "action", default: "", null: false t.string "target_type" t.bigint "target_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "human_identifier" t.string "route_param" t.string "permalink" @@ -217,8 +218,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "announcement_mutes", force: :cascade do |t| t.bigint "account_id" t.bigint "announcement_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id", "announcement_id"], name: "index_announcement_mutes_on_account_id_and_announcement_id", unique: true t.index ["announcement_id"], name: "index_announcement_mutes_on_announcement_id" end @@ -228,8 +229,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "announcement_id" t.string "name", default: "", null: false t.bigint "custom_emoji_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id", "announcement_id", "name"], name: "index_announcement_reactions_on_account_id_and_announcement_id", unique: true t.index ["announcement_id"], name: "index_announcement_reactions_on_announcement_id" t.index ["custom_emoji_id"], name: "index_announcement_reactions_on_custom_emoji_id", where: "(custom_emoji_id IS NOT NULL)" @@ -239,12 +240,12 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.text "text", default: "", null: false t.boolean "published", default: false, null: false t.boolean "all_day", default: false, null: false - t.datetime "scheduled_at" - t.datetime "starts_at" - t.datetime "ends_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.datetime "published_at" + t.datetime "scheduled_at", precision: nil + t.datetime "starts_at", precision: nil + t.datetime "ends_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.datetime "published_at", precision: nil t.bigint "status_ids", array: true end @@ -252,12 +253,12 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "account_id", null: false t.bigint "account_warning_id", null: false t.text "text", default: "", null: false - t.datetime "approved_at" + t.datetime "approved_at", precision: nil t.bigint "approved_by_account_id" - t.datetime "rejected_at" + t.datetime "rejected_at", precision: nil t.bigint "rejected_by_account_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["account_id"], name: "index_appeals_on_account_id" t.index ["account_warning_id"], name: "index_appeals_on_account_warning_id", unique: true t.index ["approved_by_account_id"], name: "index_appeals_on_approved_by_account_id", where: "(approved_by_account_id IS NOT NULL)" @@ -268,16 +269,17 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "user_id" t.string "dump_file_name" t.string "dump_content_type" - t.datetime "dump_updated_at" + t.datetime "dump_updated_at", precision: nil t.boolean "processed", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "dump_file_size" + t.index ["user_id"], name: "index_backups_on_user_id" end create_table "blocks", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id", null: false t.bigint "target_account_id", null: false t.string "uri" @@ -288,17 +290,42 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "bookmarks", force: :cascade do |t| t.bigint "account_id", null: false t.bigint "status_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id", "status_id"], name: "index_bookmarks_on_account_id_and_status_id", unique: true t.index ["status_id"], name: "index_bookmarks_on_status_id" end + create_table "bulk_import_rows", force: :cascade do |t| + t.bigint "bulk_import_id", null: false + t.jsonb "data" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["bulk_import_id"], name: "index_bulk_import_rows_on_bulk_import_id" + end + + create_table "bulk_imports", force: :cascade do |t| + t.integer "type", null: false + t.integer "state", null: false + t.integer "total_items", default: 0, null: false + t.integer "imported_items", default: 0, null: false + t.integer "processed_items", default: 0, null: false + t.datetime "finished_at", precision: nil + t.boolean "overwrite", default: false, null: false + t.boolean "likely_mismatched", default: false, null: false + t.string "original_filename", default: "", null: false + t.bigint "account_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["account_id"], name: "index_bulk_imports_on_account_id" + t.index ["id"], name: "index_bulk_imports_unconfirmed", where: "(state = 0)" + end + create_table "canonical_email_blocks", force: :cascade do |t| t.string "canonical_email_hash", default: "", null: false t.bigint "reference_account_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["canonical_email_hash"], name: "index_canonical_email_blocks_on_canonical_email_hash", unique: true t.index ["reference_account_id"], name: "index_canonical_email_blocks_on_reference_account_id" end @@ -311,15 +338,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "conversations", force: :cascade do |t| t.string "uri" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["uri"], name: "index_conversations_on_uri", unique: true, opclass: :text_pattern_ops, where: "(uri IS NOT NULL)" end create_table "custom_emoji_categories", force: :cascade do |t| t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["name"], name: "index_custom_emoji_categories_on_name", unique: true end @@ -329,9 +356,9 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "image_file_name" t.string "image_content_type" t.integer "image_file_size" - t.datetime "image_updated_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "image_updated_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "disabled", default: false, null: false t.string "uri" t.string "image_remote_url" @@ -345,27 +372,27 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "custom_filter_id", null: false t.text "keyword", default: "", null: false t.boolean "whole_word", default: true, null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["custom_filter_id"], name: "index_custom_filter_keywords_on_custom_filter_id" end create_table "custom_filter_statuses", force: :cascade do |t| t.bigint "custom_filter_id", null: false t.bigint "status_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["custom_filter_id"], name: "index_custom_filter_statuses_on_custom_filter_id" t.index ["status_id"], name: "index_custom_filter_statuses_on_status_id" end create_table "custom_filters", force: :cascade do |t| t.bigint "account_id" - t.datetime "expires_at" + t.datetime "expires_at", precision: nil t.text "phrase", default: "", null: false t.string "context", default: [], null: false, array: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "action", default: 0, null: false t.index ["account_id"], name: "index_custom_filters_on_account_id" end @@ -377,23 +404,23 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "name", default: "", null: false t.text "fingerprint_key", default: "", null: false t.text "identity_key", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["access_token_id"], name: "index_devices_on_access_token_id" t.index ["account_id"], name: "index_devices_on_account_id" end create_table "domain_allows", force: :cascade do |t| t.string "domain", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["domain"], name: "index_domain_allows_on_domain", unique: true end create_table "domain_blocks", force: :cascade do |t| t.string "domain", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "severity", default: 0 t.boolean "reject_media", default: false, null: false t.boolean "reject_reports", default: false, null: false @@ -405,8 +432,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "email_domain_blocks", force: :cascade do |t| t.string "domain", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "parent_id" t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true end @@ -419,15 +446,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.text "body", default: "", null: false t.text "digest", default: "", null: false t.text "message_franking", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["device_id"], name: "index_encrypted_messages_on_device_id" t.index ["from_account_id"], name: "index_encrypted_messages_on_from_account_id" end create_table "favourites", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id", null: false t.bigint "status_id", null: false t.index ["account_id", "id"], name: "index_favourites_on_account_id_and_id" @@ -439,9 +466,9 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "account_id", null: false t.bigint "tag_id", null: false t.bigint "statuses_count", default: 0, null: false - t.datetime "last_status_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "last_status_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "name" t.index ["account_id", "tag_id"], name: "index_featured_tags_on_account_id_and_tag_id", unique: true t.index ["tag_id"], name: "index_featured_tags_on_tag_id" @@ -449,14 +476,14 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "follow_recommendation_suppressions", force: :cascade do |t| t.bigint "account_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["account_id"], name: "index_follow_recommendation_suppressions_on_account_id", unique: true end create_table "follow_requests", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id", null: false t.bigint "target_account_id", null: false t.boolean "show_reblogs", default: true, null: false @@ -467,8 +494,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do end create_table "follows", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id", null: false t.bigint "target_account_id", null: false t.boolean "show_reblogs", default: true, null: false @@ -482,8 +509,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "identities", force: :cascade do |t| t.string "provider", default: "", null: false t.string "uid", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "user_id" t.index ["user_id"], name: "index_identities_on_user_id" end @@ -491,12 +518,12 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "imports", force: :cascade do |t| t.integer "type", null: false t.boolean "approved", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "data_file_name" t.string "data_content_type" t.integer "data_file_size" - t.datetime "data_updated_at" + t.datetime "data_updated_at", precision: nil t.bigint "account_id", null: false t.boolean "overwrite", default: false, null: false end @@ -504,11 +531,11 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "invites", force: :cascade do |t| t.bigint "user_id", null: false t.string "code", default: "", null: false - t.datetime "expires_at" + t.datetime "expires_at", precision: nil t.integer "max_uses" t.integer "uses", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "autofollow", default: false, null: false t.text "comment" t.index ["code"], name: "index_invites_on_code", unique: true @@ -516,9 +543,9 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do end create_table "ip_blocks", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.datetime "expires_at" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false + t.datetime "expires_at", precision: nil t.inet "ip", default: "0.0.0.0", null: false t.integer "severity", default: 0, null: false t.text "comment", default: "", null: false @@ -529,17 +556,20 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "list_id", null: false t.bigint "account_id", null: false t.bigint "follow_id" + t.bigint "follow_request_id" t.index ["account_id", "list_id"], name: "index_list_accounts_on_account_id_and_list_id", unique: true t.index ["follow_id"], name: "index_list_accounts_on_follow_id", where: "(follow_id IS NOT NULL)" + t.index ["follow_request_id"], name: "index_list_accounts_on_follow_request_id", where: "(follow_request_id IS NOT NULL)" t.index ["list_id", "account_id"], name: "index_list_accounts_on_list_id_and_account_id" end create_table "lists", force: :cascade do |t| t.bigint "account_id", null: false t.string "title", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "replies_policy", default: 0, null: false + t.boolean "exclusive", default: false, null: false t.index ["account_id"], name: "index_lists_on_account_id" end @@ -551,7 +581,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "failure_reason" t.inet "ip" t.string "user_agent" - t.datetime "created_at" + t.datetime "created_at", precision: nil t.index ["user_id"], name: "index_login_activities_on_user_id" end @@ -560,8 +590,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "timeline", default: "", null: false t.bigint "last_read_id", default: 0, null: false t.integer "lock_version", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["user_id", "timeline"], name: "index_markers_on_user_id_and_timeline", unique: true end @@ -570,10 +600,10 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "file_file_name" t.string "file_content_type" t.integer "file_file_size" - t.datetime "file_updated_at" + t.datetime "file_updated_at", precision: nil t.string "remote_url", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "shortcode" t.integer "type", default: 0, null: false t.json "file_meta" @@ -586,7 +616,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "thumbnail_file_name" t.string "thumbnail_content_type" t.integer "thumbnail_file_size" - t.datetime "thumbnail_updated_at" + t.datetime "thumbnail_updated_at", precision: nil t.string "thumbnail_remote_url" t.index ["account_id", "status_id"], name: "index_media_attachments_on_account_id_and_status_id", order: { status_id: :desc } t.index ["scheduled_status_id"], name: "index_media_attachments_on_scheduled_status_id", where: "(scheduled_status_id IS NOT NULL)" @@ -596,8 +626,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "mentions", force: :cascade do |t| t.bigint "status_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id" t.boolean "silent", default: false, null: false t.index ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true @@ -605,12 +635,12 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do end create_table "mutes", force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "hide_notifications", default: true, null: false t.bigint "account_id", null: false t.bigint "target_account_id", null: false - t.datetime "expires_at" + t.datetime "expires_at", precision: nil t.index ["account_id", "target_account_id"], name: "index_mutes_on_account_id_and_target_account_id", unique: true t.index ["target_account_id"], name: "index_mutes_on_target_account_id" end @@ -618,8 +648,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "notifications", force: :cascade do |t| t.bigint "activity_id", null: false t.string "activity_type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id", null: false t.bigint "from_account_id", null: false t.string "type" @@ -632,8 +662,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "token", null: false t.integer "expires_in", null: false t.text "redirect_uri", null: false - t.datetime "created_at", null: false - t.datetime "revoked_at" + t.datetime "created_at", precision: nil, null: false + t.datetime "revoked_at", precision: nil t.string "scopes" t.bigint "application_id", null: false t.bigint "resource_owner_id", null: false @@ -645,12 +675,12 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "token", null: false t.string "refresh_token" t.integer "expires_in" - t.datetime "revoked_at" - t.datetime "created_at", null: false + t.datetime "revoked_at", precision: nil + t.datetime "created_at", precision: nil, null: false t.string "scopes" t.bigint "application_id" t.bigint "resource_owner_id" - t.datetime "last_used_at" + t.datetime "last_used_at", precision: nil t.inet "last_used_ip" t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, opclass: :text_pattern_ops, where: "(refresh_token IS NOT NULL)" t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", where: "(resource_owner_id IS NOT NULL)" @@ -663,14 +693,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "secret", null: false t.text "redirect_uri", null: false t.string "scopes", default: "", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.boolean "superapp", default: false, null: false t.string "website" t.string "owner_type" t.bigint "owner_id" t.boolean "confidential", default: true, null: false t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type" + t.index ["superapp"], name: "index_oauth_applications_on_superapp", where: "(superapp = true)" t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true end @@ -679,8 +710,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "key_id", default: "", null: false t.text "key", default: "", null: false t.text "signature", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["device_id"], name: "index_one_time_keys_on_device_id" t.index ["key_id"], name: "index_one_time_keys_on_key_id" end @@ -690,7 +721,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.text "schema" t.text "relation" t.bigint "size" - t.datetime "captured_at" + t.datetime "captured_at", precision: nil t.index ["database", "captured_at"], name: "index_pghero_space_stats_on_database_and_captured_at" end @@ -698,8 +729,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "account_id" t.bigint "poll_id" t.integer "choice", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "uri" t.index ["account_id"], name: "index_poll_votes_on_account_id" t.index ["poll_id"], name: "index_poll_votes_on_poll_id" @@ -708,15 +739,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "polls", force: :cascade do |t| t.bigint "account_id" t.bigint "status_id" - t.datetime "expires_at" + t.datetime "expires_at", precision: nil t.string "options", default: [], null: false, array: true t.bigint "cached_tallies", default: [], null: false, array: true t.boolean "multiple", default: false, null: false t.boolean "hide_totals", default: false, null: false t.bigint "votes_count", default: 0, null: false - t.datetime "last_fetched_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "last_fetched_at", precision: nil + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "lock_version", default: 0, null: false t.bigint "voters_count" t.index ["account_id"], name: "index_polls_on_account_id" @@ -728,12 +759,12 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "icon_file_name" t.string "icon_content_type" t.bigint "icon_file_size" - t.datetime "icon_updated_at" + t.datetime "icon_updated_at", precision: nil t.boolean "trendable" - t.datetime "reviewed_at" - t.datetime "requested_review_at" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "reviewed_at", precision: nil + t.datetime "requested_review_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["domain"], name: "index_preview_card_providers_on_domain", unique: true end @@ -753,7 +784,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "image_file_name" t.string "image_content_type" t.integer "image_file_size" - t.datetime "image_updated_at" + t.datetime "image_updated_at", precision: nil t.integer "type", default: 0, null: false t.text "html", default: "", null: false t.string "author_name", default: "", null: false @@ -762,30 +793,31 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "provider_url", default: "", null: false t.integer "width", default: 0, null: false t.integer "height", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "embed_url", default: "", null: false t.integer "image_storage_schema_version" t.string "blurhash" t.string "language" t.float "max_score" - t.datetime "max_score_at" + t.datetime "max_score_at", precision: nil t.boolean "trendable" t.integer "link_type" + t.datetime "published_at" + t.string "image_description", default: "", null: false t.index ["url"], name: "index_preview_cards_on_url", unique: true end - create_table "preview_cards_statuses", id: false, force: :cascade do |t| + create_table "preview_cards_statuses", primary_key: ["status_id", "preview_card_id"], force: :cascade do |t| t.bigint "preview_card_id", null: false t.bigint "status_id", null: false - t.index ["status_id", "preview_card_id"], name: "index_preview_cards_statuses_on_status_id_and_preview_card_id" end create_table "relays", force: :cascade do |t| t.string "inbox_url", default: "", null: false t.string "follow_activity_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "state", default: 0, null: false end @@ -793,8 +825,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.text "content", null: false t.bigint "report_id", null: false t.bigint "account_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["account_id"], name: "index_report_notes_on_account_id" t.index ["report_id"], name: "index_report_notes_on_report_id" end @@ -802,8 +834,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "reports", force: :cascade do |t| t.bigint "status_ids", default: [], null: false, array: true t.text "comment", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "account_id", null: false t.bigint "action_taken_by_account_id" t.bigint "target_account_id", null: false @@ -811,7 +843,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "uri" t.boolean "forwarded" t.integer "category", default: 0, null: false - t.datetime "action_taken_at" + t.datetime "action_taken_at", precision: nil t.bigint "rule_ids", array: true t.index ["account_id"], name: "index_reports_on_account_id" t.index ["action_taken_by_account_id"], name: "index_reports_on_action_taken_by_account_id", where: "(action_taken_by_account_id IS NOT NULL)" @@ -821,15 +853,15 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "rules", force: :cascade do |t| t.integer "priority", default: 0, null: false - t.datetime "deleted_at" + t.datetime "deleted_at", precision: nil t.text "text", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false end create_table "scheduled_statuses", force: :cascade do |t| t.bigint "account_id" - t.datetime "scheduled_at" + t.datetime "scheduled_at", precision: nil t.jsonb "params" t.index ["account_id"], name: "index_scheduled_statuses_on_account_id" t.index ["scheduled_at"], name: "index_scheduled_statuses_on_scheduled_at" @@ -837,8 +869,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "session_activations", force: :cascade do |t| t.string "session_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "user_agent", default: "", null: false t.inet "ip" t.bigint "access_token_id" @@ -853,8 +885,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "var", null: false t.text "value" t.string "thing_type" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.bigint "thing_id" t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true end @@ -864,21 +896,32 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "file_file_name" t.string "file_content_type" t.integer "file_file_size" - t.datetime "file_updated_at" + t.datetime "file_updated_at", precision: nil t.json "meta" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "blurhash" t.index ["var"], name: "index_site_uploads_on_var", unique: true end + create_table "software_updates", force: :cascade do |t| + t.string "version", null: false + t.boolean "urgent", default: false, null: false + t.integer "type", default: 0, null: false + t.string "release_notes", default: "", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["version"], name: "index_software_updates_on_version", unique: true + end + create_table "status_edits", force: :cascade do |t| t.bigint "status_id", null: false t.bigint "account_id" t.text "text", default: "", null: false t.text "spoiler_text", default: "", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "content_type" t.bigint "ordered_media_attachment_ids", array: true t.text "media_descriptions", array: true t.string "poll_options", array: true @@ -890,8 +933,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "status_pins", force: :cascade do |t| t.bigint "account_id", null: false t.bigint "status_id", null: false - t.datetime "created_at", default: -> { "now()" }, null: false - t.datetime "updated_at", default: -> { "now()" }, null: false + t.datetime "created_at", precision: nil, default: -> { "now()" }, null: false + t.datetime "updated_at", precision: nil, default: -> { "now()" }, null: false t.index ["account_id", "status_id"], name: "index_status_pins_on_account_id_and_status_id", unique: true t.index ["status_id"], name: "index_status_pins_on_status_id" end @@ -901,8 +944,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "replies_count", default: 0, null: false t.bigint "reblogs_count", default: 0, null: false t.bigint "favourites_count", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true end @@ -920,8 +963,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "statuses", id: :bigint, default: -> { "timestamp_id('statuses'::text)" }, force: :cascade do |t| t.string "uri" t.text "text", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "in_reply_to_id" t.bigint "reblog_of_id" t.string "url" @@ -935,9 +978,11 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "account_id", null: false t.bigint "application_id" t.bigint "in_reply_to_account_id" + t.boolean "local_only" t.bigint "poll_id" - t.datetime "deleted_at" - t.datetime "edited_at" + t.string "content_type" + t.datetime "deleted_at", precision: nil + t.datetime "edited_at", precision: nil t.boolean "trendable" t.bigint "ordered_media_attachment_ids", array: true t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20190820", order: { id: :desc }, where: "(deleted_at IS NULL)" @@ -951,40 +996,39 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.index ["uri"], name: "index_statuses_on_uri", unique: true, opclass: :text_pattern_ops, where: "(uri IS NOT NULL)" end - create_table "statuses_tags", id: false, force: :cascade do |t| + create_table "statuses_tags", primary_key: ["tag_id", "status_id"], force: :cascade do |t| t.bigint "status_id", null: false t.bigint "tag_id", null: false t.index ["status_id"], name: "index_statuses_tags_on_status_id" - t.index ["tag_id", "status_id"], name: "index_statuses_tags_on_tag_id_and_status_id", unique: true end create_table "system_keys", force: :cascade do |t| t.binary "key" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false end create_table "tag_follows", force: :cascade do |t| t.bigint "tag_id", null: false t.bigint "account_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["account_id", "tag_id"], name: "index_tag_follows_on_account_id_and_tag_id", unique: true t.index ["tag_id"], name: "index_tag_follows_on_tag_id" end create_table "tags", force: :cascade do |t| t.string "name", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "usable" t.boolean "trendable" t.boolean "listable" - t.datetime "reviewed_at" - t.datetime "requested_review_at" - t.datetime "last_status_at" + t.datetime "reviewed_at", precision: nil + t.datetime "requested_review_at", precision: nil + t.datetime "last_status_at", precision: nil t.float "max_score" - t.datetime "max_score_at" + t.datetime "max_score_at", precision: nil t.string "display_name" t.index "lower((name)::text) text_pattern_ops", name: "index_tags_on_name_lower_btree", unique: true end @@ -992,8 +1036,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "tombstones", force: :cascade do |t| t.bigint "account_id" t.string "uri", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "by_moderator" t.index ["account_id"], name: "index_tombstones_on_account_id" t.index ["uri"], name: "index_tombstones_on_uri" @@ -1001,16 +1045,16 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "unavailable_domains", force: :cascade do |t| t.string "domain", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["domain"], name: "index_unavailable_domains_on_domain", unique: true end create_table "user_invite_requests", force: :cascade do |t| t.bigint "user_id" t.text "text" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["user_id"], name: "index_user_invite_requests_on_user_id" end @@ -1020,24 +1064,24 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.integer "position", default: 0, null: false t.bigint "permissions", default: 0, null: false t.boolean "highlighted", default: false, null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "users", force: :cascade do |t| t.string "email", default: "", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" - t.datetime "reset_password_sent_at" + t.datetime "reset_password_sent_at", precision: nil t.integer "sign_in_count", default: 0, null: false - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil t.boolean "admin", default: false, null: false t.string "confirmation_token" - t.datetime "confirmed_at" - t.datetime "confirmation_sent_at" + t.datetime "confirmed_at", precision: nil + t.datetime "confirmation_sent_at", precision: nil t.string "unconfirmed_email" t.string "locale" t.string "encrypted_otp_secret" @@ -1045,7 +1089,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "encrypted_otp_secret_salt" t.integer "consumed_timestep" t.boolean "otp_required_for_login", default: false, null: false - t.datetime "last_emailed_at" + t.datetime "last_emailed_at", precision: nil t.string "otp_backup_codes", array: true t.bigint "account_id", null: false t.boolean "disabled", default: false, null: false @@ -1055,17 +1099,20 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.bigint "created_by_application_id" t.boolean "approved", default: true, null: false t.string "sign_in_token" - t.datetime "sign_in_token_sent_at" + t.datetime "sign_in_token_sent_at", precision: nil t.string "webauthn_id" t.inet "sign_up_ip" t.boolean "skip_sign_in_token" t.bigint "role_id" + t.text "settings" + t.string "time_zone" t.index ["account_id"], name: "index_users_on_account_id" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["created_by_application_id"], name: "index_users_on_created_by_application_id", where: "(created_by_application_id IS NOT NULL)" t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, opclass: :text_pattern_ops, where: "(reset_password_token IS NOT NULL)" t.index ["role_id"], name: "index_users_on_role_id", where: "(role_id IS NOT NULL)" + t.index ["unconfirmed_email"], name: "index_users_on_unconfirmed_email", where: "(unconfirmed_email IS NOT NULL)" end create_table "web_push_subscriptions", force: :cascade do |t| @@ -1073,8 +1120,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "key_p256dh", null: false t.string "key_auth", null: false t.json "data" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "access_token_id" t.bigint "user_id" t.index ["access_token_id"], name: "index_web_push_subscriptions_on_access_token_id", where: "(access_token_id IS NOT NULL)" @@ -1083,8 +1130,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do create_table "web_settings", force: :cascade do |t| t.json "data" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "user_id", null: false t.index ["user_id"], name: "index_web_settings_on_user_id", unique: true end @@ -1095,8 +1142,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "nickname", null: false t.bigint "sign_count", default: 0, null: false t.bigint "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["external_id"], name: "index_webauthn_credentials_on_external_id", unique: true t.index ["user_id"], name: "index_webauthn_credentials_on_user_id" end @@ -1106,8 +1153,9 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do t.string "events", default: [], null: false, array: true t.string "secret", default: "", null: false t.boolean "enabled", default: true, null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "template" t.index ["url"], name: "index_webhooks_on_url", unique: true end @@ -1145,6 +1193,8 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do add_foreign_key "blocks", "accounts", name: "fk_4269e03e65", on_delete: :cascade add_foreign_key "bookmarks", "accounts", on_delete: :cascade add_foreign_key "bookmarks", "statuses", on_delete: :cascade + add_foreign_key "bulk_import_rows", "bulk_imports", on_delete: :cascade + add_foreign_key "bulk_imports", "accounts", on_delete: :cascade add_foreign_key "canonical_email_blocks", "accounts", column: "reference_account_id", on_delete: :cascade add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade add_foreign_key "conversation_mutes", "conversations", on_delete: :cascade @@ -1170,6 +1220,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do add_foreign_key "imports", "accounts", name: "fk_6db1b6e408", on_delete: :cascade add_foreign_key "invites", "users", on_delete: :cascade add_foreign_key "list_accounts", "accounts", on_delete: :cascade + add_foreign_key "list_accounts", "follow_requests", on_delete: :cascade add_foreign_key "list_accounts", "follows", on_delete: :cascade add_foreign_key "list_accounts", "lists", on_delete: :cascade add_foreign_key "lists", "accounts", on_delete: :cascade @@ -1252,6 +1303,7 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do FROM (domain_allows LEFT JOIN domain_counts ON (((domain_counts.domain)::text = (domain_allows.domain)::text))); SQL + add_index "instances", "reverse(('.'::text || (domain)::text)), domain", name: "index_instances_on_reverse_domain" add_index "instances", ["domain"], name: "index_instances_on_domain", unique: true create_view "user_ips", sql_definition: <<-SQL @@ -1293,34 +1345,36 @@ ActiveRecord::Schema.define(version: 2022_12_06_114142) do SQL add_index "account_summaries", ["account_id"], name: "index_account_summaries_on_account_id", unique: true - create_view "follow_recommendations", materialized: true, sql_definition: <<-SQL + create_view "global_follow_recommendations", materialized: true, sql_definition: <<-SQL SELECT t0.account_id, sum(t0.rank) AS rank, array_agg(t0.reason) AS reason FROM ( SELECT account_summaries.account_id, ((count(follows.id))::numeric / (1.0 + (count(follows.id))::numeric)) AS rank, 'most_followed'::text AS reason - FROM (((follows + FROM ((follows JOIN account_summaries ON ((account_summaries.account_id = follows.target_account_id))) JOIN users ON ((users.account_id = follows.account_id))) - LEFT JOIN follow_recommendation_suppressions ON ((follow_recommendation_suppressions.account_id = follows.target_account_id))) - WHERE ((users.current_sign_in_at >= (now() - 'P30D'::interval)) AND (account_summaries.sensitive = false) AND (follow_recommendation_suppressions.id IS NULL)) + WHERE ((users.current_sign_in_at >= (now() - 'P30D'::interval)) AND (account_summaries.sensitive = false) AND (NOT (EXISTS ( SELECT 1 + FROM follow_recommendation_suppressions + WHERE (follow_recommendation_suppressions.account_id = follows.target_account_id))))) GROUP BY account_summaries.account_id HAVING (count(follows.id) >= 5) UNION ALL SELECT account_summaries.account_id, (sum((status_stats.reblogs_count + status_stats.favourites_count)) / (1.0 + sum((status_stats.reblogs_count + status_stats.favourites_count)))) AS rank, 'most_interactions'::text AS reason - FROM (((status_stats + FROM ((status_stats JOIN statuses ON ((statuses.id = status_stats.status_id))) JOIN account_summaries ON ((account_summaries.account_id = statuses.account_id))) - LEFT JOIN follow_recommendation_suppressions ON ((follow_recommendation_suppressions.account_id = statuses.account_id))) - WHERE ((statuses.id >= (((date_part('epoch'::text, (now() - 'P30D'::interval)) * (1000)::double precision))::bigint << 16)) AND (account_summaries.sensitive = false) AND (follow_recommendation_suppressions.id IS NULL)) + WHERE ((statuses.id >= (((date_part('epoch'::text, (now() - 'P30D'::interval)) * (1000)::double precision))::bigint << 16)) AND (account_summaries.sensitive = false) AND (NOT (EXISTS ( SELECT 1 + FROM follow_recommendation_suppressions + WHERE (follow_recommendation_suppressions.account_id = statuses.account_id))))) GROUP BY account_summaries.account_id HAVING (sum((status_stats.reblogs_count + status_stats.favourites_count)) >= (5)::numeric)) t0 GROUP BY t0.account_id ORDER BY (sum(t0.rank)) DESC; SQL - add_index "follow_recommendations", ["account_id"], name: "index_follow_recommendations_on_account_id", unique: true + add_index "global_follow_recommendations", ["account_id"], name: "index_global_follow_recommendations_on_account_id", unique: true end diff --git a/db/seeds.rb b/db/seeds.rb index c01e83f1d3..370790e513 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true Chewy.strategy(:mastodon) do - Dir[Rails.root.join('db', 'seeds', '*.rb')].sort.each do |seed| + Dir[Rails.root.join('db', 'seeds', '*.rb')].each do |seed| load seed end end diff --git a/db/seeds/01_web_app.rb b/db/seeds/01_web_app.rb index a457a883b3..a9d8fd3bae 100644 --- a/db/seeds/01_web_app.rb +++ b/db/seeds/01_web_app.rb @@ -1 +1,3 @@ +# frozen_string_literal: true + Doorkeeper::Application.create_with(name: 'Web', redirect_uri: Doorkeeper.configuration.native_redirect_uri, scopes: 'read write follow push').find_or_create_by(superapp: true) diff --git a/db/seeds/02_instance_actor.rb b/db/seeds/02_instance_actor.rb index f9aa372f1c..55e83e8a08 100644 --- a/db/seeds/02_instance_actor.rb +++ b/db/seeds/02_instance_actor.rb @@ -1 +1,3 @@ +# frozen_string_literal: true + Account.create_with(actor_type: 'Application', locked: true, username: 'mastodon.internal').find_or_create_by(id: -99) diff --git a/db/seeds/03_roles.rb b/db/seeds/03_roles.rb index 7fedf0f711..8b359582b5 100644 --- a/db/seeds/03_roles.rb +++ b/db/seeds/03_roles.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Pre-create base role UserRole.everyone diff --git a/db/seeds/04_admin.rb b/db/seeds/04_admin.rb index a67040e4ec..c9b0369c9f 100644 --- a/db/seeds/04_admin.rb +++ b/db/seeds/04_admin.rb @@ -1,5 +1,8 @@ +# frozen_string_literal: true + if Rails.env.development? domain = ENV['LOCAL_DOMAIN'] || Rails.configuration.x.local_domain + domain = domain.gsub(/:\d+$/, '') admin = Account.where(username: 'admin').first_or_initialize(username: 'admin') admin.save(validate: false) diff --git a/db/views/global_follow_recommendations_v01.sql b/db/views/global_follow_recommendations_v01.sql new file mode 100644 index 0000000000..de693c9fcd --- /dev/null +++ b/db/views/global_follow_recommendations_v01.sql @@ -0,0 +1,32 @@ +SELECT + account_id, + sum(rank) AS rank, + array_agg(reason) AS reason +FROM ( + SELECT + account_summaries.account_id AS account_id, + count(follows.id) / (1.0 + count(follows.id)) AS rank, + 'most_followed' AS reason + FROM follows + INNER JOIN account_summaries ON account_summaries.account_id = follows.target_account_id + INNER JOIN users ON users.account_id = follows.account_id + WHERE users.current_sign_in_at >= (now() - interval '30 days') + AND account_summaries.sensitive = 'f' + AND NOT EXISTS (SELECT 1 FROM follow_recommendation_suppressions WHERE follow_recommendation_suppressions.account_id = follows.target_account_id) + GROUP BY account_summaries.account_id + HAVING count(follows.id) >= 5 + UNION ALL + SELECT account_summaries.account_id AS account_id, + sum(status_stats.reblogs_count + status_stats.favourites_count) / (1.0 + sum(status_stats.reblogs_count + status_stats.favourites_count)) AS rank, + 'most_interactions' AS reason + FROM status_stats + INNER JOIN statuses ON statuses.id = status_stats.status_id + INNER JOIN account_summaries ON account_summaries.account_id = statuses.account_id + WHERE statuses.id >= ((date_part('epoch', now() - interval '30 days') * 1000)::bigint << 16) + AND account_summaries.sensitive = 'f' + AND NOT EXISTS (SELECT 1 FROM follow_recommendation_suppressions WHERE follow_recommendation_suppressions.account_id = statuses.account_id) + GROUP BY account_summaries.account_id + HAVING sum(status_stats.reblogs_count + status_stats.favourites_count) >= 5 +) t0 +GROUP BY account_id +ORDER BY rank DESC diff --git a/dist/mastodon-streaming.service b/dist/mastodon-streaming.service index cf1f2d8bc6..66cc3474ef 100644 --- a/dist/mastodon-streaming.service +++ b/dist/mastodon-streaming.service @@ -1,51 +1,12 @@ [Unit] Description=mastodon-streaming After=network.target +Wants=mastodon-streaming@4000.service [Service] -Type=simple -User=mastodon -WorkingDirectory=/home/mastodon/live -Environment="NODE_ENV=production" -Environment="PORT=4000" -Environment="STREAMING_CLUSTER_NUM=1" -ExecStart=/usr/bin/node ./streaming -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 @memlock @mount @obsolete @privileged @resources @setuid -SystemCallFilter=pipe -SystemCallFilter=pipe2 -ReadWritePaths=/home/mastodon/live +Type=oneshot +ExecStart=/bin/echo "mastodon-streaming exists only to collectively start and stop mastodon-streaming@ instances, shimming over the migration to templated mastodon-streaming systemd unit" +RemainAfterExit=yes [Install] WantedBy=multi-user.target diff --git a/dist/mastodon-streaming@.service b/dist/mastodon-streaming@.service new file mode 100644 index 0000000000..f43c4ea4a6 --- /dev/null +++ b/dist/mastodon-streaming@.service @@ -0,0 +1,54 @@ +[Unit] +Description=mastodon-streaming on port %I +After=network.target +# handles using `systemctl restart mastodon-streaming` +PartOf=mastodon-streaming.service +ReloadPropagatedFrom=mastodon-streaming.service + +[Service] +Type=simple +User=mastodon +WorkingDirectory=/home/mastodon/live +Environment="NODE_ENV=production" +Environment="PORT=%i" +ExecStart=/usr/bin/node ./streaming +TimeoutSec=15 +Restart=always +LimitNOFILE=65536 +# 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 @memlock @mount @obsolete @privileged @resources @setuid +SystemCallFilter=pipe +SystemCallFilter=pipe2 +ReadWritePaths=/home/mastodon/live + +[Install] +WantedBy=multi-user.target mastodon-streaming.service diff --git a/dist/nginx.conf b/dist/nginx.conf index b59446403b..5bb9903864 100644 --- a/dist/nginx.conf +++ b/dist/nginx.conf @@ -8,7 +8,15 @@ upstream backend { } upstream streaming { + # Instruct nginx to send connections to the server with the least number of connections + # to ensure load is distributed evenly. + least_conn; + server 127.0.0.1:4000 fail_timeout=0; + # Uncomment these lines for load-balancing multiple instances of streaming for scaling, + # this assumes your running the streaming server on ports 4000, 4001, and 4002: + # server 127.0.0.1:4001 fail_timeout=0; + # server 127.0.0.1:4002 fail_timeout=0; } proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g; @@ -28,7 +36,11 @@ server { server_name example.com; ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; + + # You can use https://ssl-config.mozilla.org/ to generate your cipher set. + # We recommend their "Intermediate" level. + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; + ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; @@ -39,7 +51,7 @@ server { keepalive_timeout 70; sendfile on; - client_max_body_size 80m; + client_max_body_size 99m; root /home/mastodon/live/public; diff --git a/docker-compose.yml b/docker-compose.yml index f603c2f7e2..d19f278f75 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -56,7 +56,7 @@ services: web: build: . - image: ghcr.io/mastodon/mastodon + image: ghcr.io/mastodon/mastodon:v4.2.0 restart: always env_file: .env.production command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" @@ -77,7 +77,7 @@ services: streaming: build: . - image: ghcr.io/mastodon/mastodon + image: ghcr.io/mastodon/mastodon:v4.2.0 restart: always env_file: .env.production command: node ./streaming @@ -95,7 +95,7 @@ services: sidekiq: build: . - image: ghcr.io/mastodon/mastodon + image: ghcr.io/mastodon/mastodon:v4.2.0 restart: always env_file: .env.production command: bundle exec sidekiq diff --git a/jest.config.js b/jest.config.js index d7b5610b81..0b928b63a9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,32 +1,24 @@ -module.exports = { - 'testEnvironment': 'jsdom', - 'projects': [ - '/app/javascript/mastodon', - ], - 'testPathIgnorePatterns': [ +/** @type {import('jest').Config} */ +const config = { + testEnvironment: 'jsdom', + testPathIgnorePatterns: [ '/node_modules/', '/vendor/', '/config/', '/log/', '/public/', '/tmp/', + '/app/javascript/themes/', ], - 'setupFiles': [ - 'raf/polyfill', - ], - 'setupFilesAfterEnv': [ - '/app/javascript/mastodon/test_setup.js', - ], - 'collectCoverageFrom': [ - 'app/javascript/mastodon/**/*.js', + setupFilesAfterEnv: ['/app/javascript/mastodon/test_setup.js'], + collectCoverageFrom: [ + 'app/javascript/mastodon/**/*.{js,jsx,ts,tsx}', '!app/javascript/mastodon/features/emoji/emoji_compressed.js', - '!app/javascript/mastodon/locales/locale-data/*.js', '!app/javascript/mastodon/service_worker/entry.js', '!app/javascript/mastodon/test_setup.js', ], - 'coverageDirectory': '/coverage', - 'moduleDirectories': [ - '/node_modules', - '/app/javascript', - ], + coverageDirectory: '/coverage', + moduleDirectories: ['/node_modules', '/app/javascript'], }; + +module.exports = config; diff --git a/lib/active_record/batches.rb b/lib/active_record/batches.rb index 55d29e52ef..91e50cc43d 100644 --- a/lib/active_record/batches.rb +++ b/lib/active_record/batches.rb @@ -29,7 +29,7 @@ module ActiveRecord if flatten yield record[1] else - yield record[1..-1] + yield record[1..] end end diff --git a/lib/assets/wordmark.light.css b/lib/assets/wordmark.light.css index 9a601f9725..b8c9993fd8 100644 --- a/lib/assets/wordmark.light.css +++ b/lib/assets/wordmark.light.css @@ -1 +1,3 @@ -use { color: #000 !important; } +use { + color: #000 !important; +} diff --git a/lib/chewy/index_extensions.rb b/lib/chewy/index_extensions.rb new file mode 100644 index 0000000000..064fd56b3e --- /dev/null +++ b/lib/chewy/index_extensions.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Chewy + module IndexExtensions + def index_preset(base_options = {}) + case ENV['ES_PRESET'].presence + when 'single_node_cluster', nil + base_options.merge(number_of_replicas: 0) + when 'small_cluster' + base_options.merge(number_of_replicas: 1) + when 'large_cluster' + base_options.merge(number_of_replicas: 1, number_of_shards: (base_options[:number_of_shards] || 1) * 2) + end + end + end +end + +Chewy::Index.extend(Chewy::IndexExtensions) diff --git a/lib/chewy/settings_extensions.rb b/lib/chewy/settings_extensions.rb new file mode 100644 index 0000000000..0eb8b336f3 --- /dev/null +++ b/lib/chewy/settings_extensions.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Chewy + module SettingsExtensions + def enabled? + settings[:enabled] + end + end +end + +Chewy.extend(Chewy::SettingsExtensions) diff --git a/lib/generators/post_deployment_migration/USAGE b/lib/generators/post_deployment_migration/USAGE new file mode 100644 index 0000000000..57f3c6aa1c --- /dev/null +++ b/lib/generators/post_deployment_migration/USAGE @@ -0,0 +1,10 @@ +Description: + Generate a Rails migration in the db/post_migrate/ dir. + + Interacts with the post_deployment_migrations initializer. + +Example: + bin/rails generate post_deployment_migration IsolateChanges + + Creates a migration in db/post_migrate/_isolate_changes.rb + which will have `disable_ddl_transaction!` and a `change` method included. diff --git a/lib/generators/post_deployment_migration/post_deployment_migration_generator.rb b/lib/generators/post_deployment_migration/post_deployment_migration_generator.rb new file mode 100644 index 0000000000..adb34a2896 --- /dev/null +++ b/lib/generators/post_deployment_migration/post_deployment_migration_generator.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails/generators/active_record' + +class PostDeploymentMigrationGenerator < Rails::Generators::NamedBase + source_root File.expand_path('templates', __dir__) + + include Rails::Generators::Migration + + def create_post_deployment_migration + migration_template 'migration.erb', "db/post_migrate/#{file_name}.rb" + end + + def self.next_migration_number(path) + ActiveRecord::Generators::Base.next_migration_number(path) + end +end diff --git a/lib/generators/post_deployment_migration/templates/migration.erb b/lib/generators/post_deployment_migration/templates/migration.erb new file mode 100644 index 0000000000..fd6a02a0f7 --- /dev/null +++ b/lib/generators/post_deployment_migration/templates/migration.erb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class <%= migration_class_name %> < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>] + disable_ddl_transaction! + + def change + end +end diff --git a/lib/generators/post_deployment_migration_generator.rb b/lib/generators/post_deployment_migration_generator.rb deleted file mode 100644 index 798c01b883..0000000000 --- a/lib/generators/post_deployment_migration_generator.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require 'rails/generators' - -module Rails - class PostDeploymentMigrationGenerator < Rails::Generators::NamedBase - def create_migration_file - timestamp = Time.zone.now.strftime('%Y%m%d%H%M%S') - - template 'migration.rb', "db/post_migrate/#{timestamp}_#{file_name}.rb" - end - - def migration_class_name - file_name.camelize - end - end -end diff --git a/lib/http_extensions.rb b/lib/http_extensions.rb new file mode 100644 index 0000000000..048f85f87b --- /dev/null +++ b/lib/http_extensions.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Monkey patching until https://github.com/httprb/http/pull/757 is merged +unless HTTP::Request::METHODS.include?(:purge) + methods = HTTP::Request::METHODS.dup + HTTP::Request.send(:remove_const, :METHODS) + HTTP::Request.const_set(:METHODS, methods.push(:purge).freeze) +end diff --git a/lib/linter/haml_middle_dot.rb b/lib/linter/haml_middle_dot.rb new file mode 100644 index 0000000000..3b27711521 --- /dev/null +++ b/lib/linter/haml_middle_dot.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module HamlLint + # Bans the usage of “•” (bullet) in HTML/HAML in favor of “·” (middle dot) in anything that will end up as a text node. (including string literals in Ruby code) + class Linter::MiddleDot < Linter + include LinterRegistry + + # rubocop:disable Style/MiddleDot + BULLET = '•' + # rubocop:enable Style/MiddleDot + MIDDLE_DOT = '·' + MESSAGE = "Use '#{MIDDLE_DOT}' (middle dot) instead of '#{BULLET}' (bullet)".freeze + + def visit_plain(node) + return unless node.text.include?(BULLET) + + record_lint(node, MESSAGE) + end + + def visit_script(node) + return unless node.script.include?(BULLET) + + record_lint(node, MESSAGE) + end + end +end diff --git a/lib/linter/rubocop_middle_dot.rb b/lib/linter/rubocop_middle_dot.rb new file mode 100644 index 0000000000..3a1d97c0c9 --- /dev/null +++ b/lib/linter/rubocop_middle_dot.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Style + # Bans the usage of “•” (bullet) in HTML/HAML in favor of “·” (middle dot) in string literals + class MiddleDot < Base + extend AutoCorrector + extend Util + + # rubocop:disable Style/MiddleDot + BULLET = '•' + # rubocop:enable Style/MiddleDot + MIDDLE_DOT = '·' + MESSAGE = "Use '#{MIDDLE_DOT}' (middle dot) instead of '#{BULLET}' (bullet)".freeze + + def on_str(node) + # Constants like __FILE__ are handled as strings, + # but don't respond to begin. + return unless node.loc.respond_to?(:begin) && node.loc.begin + + return unless node.value.include?(BULLET) + + add_offense(node, message: MESSAGE) do |corrector| + corrector.replace(node, node.source.gsub(BULLET, MIDDLE_DOT)) + end + end + end + end + end +end diff --git a/lib/mastodon/cache_cli.rb b/lib/mastodon/cache_cli.rb deleted file mode 100644 index 803404c34f..0000000000 --- a/lib/mastodon/cache_cli.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class CacheCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end - - desc 'clear', 'Clear out the cache storage' - def clear - Rails.cache.clear - say('OK', :green) - end - - option :concurrency, type: :numeric, default: 5, aliases: [:c] - option :verbose, type: :boolean, aliases: [:v] - desc 'recount TYPE', 'Update hard-cached counters' - long_desc <<~LONG_DESC - Update hard-cached counters of TYPE by counting referenced - records from scratch. TYPE can be "accounts" or "statuses". - - It may take a very long time to finish, depending on the - size of the database. - LONG_DESC - def recount(type) - case type - when 'accounts' - processed, = parallelize_with_progress(Account.local.includes(:account_stat)) do |account| - account_stat = account.account_stat - account_stat.following_count = account.active_relationships.count - account_stat.followers_count = account.passive_relationships.count - account_stat.statuses_count = account.statuses.where.not(visibility: :direct).count - - account_stat.save if account_stat.changed? - end - when 'statuses' - processed, = parallelize_with_progress(Status.includes(:status_stat)) do |status| - status_stat = status.status_stat - status_stat.replies_count = status.replies.where.not(visibility: :direct).count - status_stat.reblogs_count = status.reblogs.count - status_stat.favourites_count = status.favourites.count - - status_stat.save if status_stat.changed? - end - else - say("Unknown type: #{type}", :red) - exit(1) - end - - say - say("OK, recounted #{processed} records", :green) - end - end -end diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/cli/accounts.rb similarity index 91% rename from lib/mastodon/accounts_cli.rb rename to lib/mastodon/cli/accounts.rb index d4a6bbc127..33520df25d 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/cli/accounts.rb @@ -1,18 +1,10 @@ # frozen_string_literal: true require 'set' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class AccountsCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class Accounts < Base option :all, type: :boolean desc 'rotate [USERNAME]', 'Generate and broadcast new keys' long_desc <<-LONG_DESC @@ -57,6 +49,7 @@ module Mastodon option :role option :reattach, type: :boolean option :force, type: :boolean + option :approve, type: :boolean desc 'create USERNAME', 'Create a new user account' long_desc <<-LONG_DESC Create a new user account with a given USERNAME and an @@ -72,6 +65,8 @@ module Mastodon account is still in use by someone else, you can supply the --force option to delete the old record and reattach the username to the new account anyway. + + With the --approve option, the account will be approved. LONG_DESC def create(username) role_id = nil @@ -89,7 +84,7 @@ module Mastodon account = Account.new(username: username) password = SecureRandom.hex - user = User.new(email: options[:email], password: password, agreement: true, approved: true, role_id: role_id, confirmed_at: options[:confirmed] ? Time.now.utc : nil, bypass_invite_request_check: true) + user = User.new(email: options[:email], password: password, agreement: true, role_id: role_id, confirmed_at: options[:confirmed] ? Time.now.utc : nil, bypass_invite_request_check: true) if options[:reattach] account = Account.find_local(username) || Account.new(username: username) @@ -99,7 +94,8 @@ module Mastodon say('Use --force to reattach it anyway and delete the other user') return elsif account.user.present? - DeleteAccountService.new.call(account, reserve_email: false) + DeleteAccountService.new.call(account, reserve_email: false, reserve_username: false) + account = Account.new(username: username) end end @@ -112,15 +108,12 @@ module Mastodon user.confirm! end + user.approve! if options[:approve] + say('OK', :green) say("New password: #{password}") else - user.errors.to_h.each do |key, error| - say('Failure/Error: ', :red) - say(key) - say(" #{error}", :red) - end - + report_errors(user.errors) exit(1) end end @@ -184,18 +177,14 @@ module Mastodon user.disabled = true if options[:disable] user.approved = true if options[:approve] user.otp_required_for_login = false if options[:disable_2fa] - user.confirm if options[:confirm] if user.save + user.confirm if options[:confirm] + say('OK', :green) say("New password: #{password}") if options[:reset_password] else - user.errors.to_h.each do |key, error| - say('Failure/Error: ', :red) - say(key) - say(" #{error}", :red) - end - + report_errors(user.errors) exit(1) end end @@ -218,7 +207,6 @@ module Mastodon exit(1) end - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' account = nil if username.present? @@ -235,9 +223,9 @@ module Mastodon end end - say("Deleting user with #{account.statuses_count} statuses, this might take a while...#{dry_run}") - DeleteAccountService.new.call(account, reserve_email: false) unless options[:dry_run] - say("OK#{dry_run}", :green) + say("Deleting user with #{account.statuses_count} statuses, this might take a while...#{dry_run_mode_suffix}") + DeleteAccountService.new.call(account, reserve_email: false) unless dry_run? + say("OK#{dry_run_mode_suffix}", :green) end option :force, type: :boolean, aliases: [:f], description: 'Override public key check' @@ -292,7 +280,7 @@ module Mastodon Account.remote.select(:uri, 'count(*)').group(:uri).having('count(*) > 1').pluck(:uri).each do |uri| say("Duplicates found for #{uri}") begin - ActivityPub::FetchRemoteAccountService.new.call(uri) unless options[:dry_run] + ActivityPub::FetchRemoteAccountService.new.call(uri) unless dry_run? rescue => e say("Error processing #{uri}: #{e}", :red) end @@ -333,7 +321,6 @@ module Mastodon LONG_DESC def cull(*domains) skip_threshold = 7.days.ago - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' skip_domains = Concurrent::Set.new query = Account.remote.where(protocol: :activitypub) @@ -346,12 +333,12 @@ module Mastodon begin code = Request.new(:head, account.uri).perform(&:code) - rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Mastodon::PrivateNetworkAddressError skip_domains << account.domain end if [404, 410].include?(code) - DeleteAccountService.new.call(account, reserve_username: false) unless options[:dry_run] + DeleteAccountService.new.call(account, reserve_username: false) unless dry_run? 1 else # Touch account even during dry run to avoid getting the account into the window again @@ -359,7 +346,7 @@ module Mastodon end end - say("Visited #{processed} accounts, removed #{culled}#{dry_run}", :green) + say("Visited #{processed} accounts, removed #{culled}#{dry_run_mode_suffix}", :green) unless skip_domains.empty? say('The following domains were not available during the check:', :yellow) @@ -382,21 +369,19 @@ module Mastodon specified with space-separated USERNAMES. LONG_DESC def refresh(*usernames) - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' - if options[:domain] || options[:all] scope = Account.remote scope = scope.where(domain: options[:domain]) if options[:domain] processed, = parallelize_with_progress(scope) do |account| - next if options[:dry_run] + next if dry_run? account.reset_avatar! account.reset_header! account.save end - say("Refreshed #{processed} accounts#{dry_run}", :green, true) + say("Refreshed #{processed} accounts#{dry_run_mode_suffix}", :green, true) elsif !usernames.empty? usernames.each do |user| user, domain = user.split('@') @@ -407,7 +392,7 @@ module Mastodon exit(1) end - next if options[:dry_run] + next if dry_run? begin account.reset_avatar! @@ -418,7 +403,7 @@ module Mastodon end end - say("OK#{dry_run}", :green) + say("OK#{dry_run_mode_suffix}", :green) else say('No account(s) given', :red) exit(1) @@ -496,14 +481,12 @@ module Mastodon scope = Account.where(id: ::Follow.where(account: account).select(:target_account_id)) scope.find_each do |target_account| - begin - UnfollowService.new.call(account, target_account) - rescue => e - progress.log pastel.red("Error processing #{target_account.id}: #{e}") - ensure - progress.increment - processed += 1 - end + UnfollowService.new.call(account, target_account) + rescue => e + progress.log pastel.red("Error processing #{target_account.id}: #{e}") + ensure + progress.increment + processed += 1 end BootstrapTimelineWorker.perform_async(account.id) @@ -513,14 +496,12 @@ module Mastodon scope = Account.where(id: ::Follow.where(target_account: account).select(:account_id)) scope.find_each do |target_account| - begin - UnfollowService.new.call(target_account, account) - rescue => e - progress.log pastel.red("Error processing #{target_account.id}: #{e}") - ensure - progress.increment - processed += 1 - end + UnfollowService.new.call(target_account, account) + rescue => e + progress.log pastel.red("Error processing #{target_account.id}: #{e}") + ensure + progress.increment + processed += 1 end end @@ -541,7 +522,7 @@ module Mastodon if options[:all] User.pending.find_each(&:approve!) say('OK', :green) - elsif options[:number] + elsif options[:number]&.positive? User.pending.order(created_at: :asc).limit(options[:number]).each(&:approve!) say('OK', :green) elsif username.present? @@ -555,6 +536,7 @@ module Mastodon account.user&.approve! say('OK', :green) else + say('Number must be positive', :red) if options[:number] exit(1) end end @@ -572,8 +554,6 @@ module Mastodon - not muted/blocked by us LONG_DESC def prune - dry_run = options[:dry_run] ? ' (dry run)' : '' - query = Account.remote.where.not(actor_type: %i(Application Service)) query = query.where('NOT EXISTS (SELECT 1 FROM mentions WHERE account_id = accounts.id)') query = query.where('NOT EXISTS (SELECT 1 FROM favourites WHERE account_id = accounts.id)') @@ -589,11 +569,11 @@ module Mastodon next if account.suspended? next if account.silenced? - account.destroy unless options[:dry_run] + account.destroy unless dry_run? 1 end - say("OK, pruned #{deleted} accounts#{dry_run}", :green) + say("OK, pruned #{deleted} accounts#{dry_run_mode_suffix}", :green) end option :force, type: :boolean @@ -671,6 +651,14 @@ module Mastodon private + def report_errors(errors) + errors.each do |error| + say('Failure/Error: ', :red) + say(error.attribute) + say(" #{error.type}", :red) + end + end + def rotate_keys_for_account(account, delay = 0) if account.nil? say('No such account', :red) diff --git a/lib/mastodon/cli/base.rb b/lib/mastodon/cli/base.rb new file mode 100644 index 0000000000..32aff2fcc5 --- /dev/null +++ b/lib/mastodon/cli/base.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require_relative '../../../config/boot' +require_relative '../../../config/environment' + +require 'thor' +require_relative 'progress_helper' + +module Mastodon + module CLI + class Base < Thor + include ProgressHelper + + def self.exit_on_failure? + true + end + + private + + def pastel + @pastel ||= Pastel.new + end + + def dry_run? + options[:dry_run] + end + + def dry_run_mode_suffix + dry_run? ? ' (DRY RUN)' : '' + end + + def reset_connection_pools! + ActiveRecord::Base.establish_connection( + ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first.configuration_hash + .dup + .tap { |config| config['pool'] = options[:concurrency] + 1 } + ) + RedisConfiguration.establish_pool(options[:concurrency]) + end + end + end +end diff --git a/lib/mastodon/cli/cache.rb b/lib/mastodon/cli/cache.rb new file mode 100644 index 0000000000..e8a2ac1610 --- /dev/null +++ b/lib/mastodon/cli/cache.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require_relative 'base' + +module Mastodon::CLI + class Cache < Base + desc 'clear', 'Clear out the cache storage' + def clear + Rails.cache.clear + say('OK', :green) + end + + option :concurrency, type: :numeric, default: 5, aliases: [:c] + option :verbose, type: :boolean, aliases: [:v] + desc 'recount TYPE', 'Update hard-cached counters' + long_desc <<~LONG_DESC + Update hard-cached counters of TYPE by counting referenced + records from scratch. TYPE can be "accounts" or "statuses". + + It may take a very long time to finish, depending on the + size of the database. + LONG_DESC + def recount(type) + case type + when 'accounts' + processed, = parallelize_with_progress(accounts_with_stats) do |account| + recount_account_stats(account) + end + when 'statuses' + processed, = parallelize_with_progress(statuses_with_stats) do |status| + recount_status_stats(status) + end + else + say("Unknown type: #{type}", :red) + exit(1) + end + + say + say("OK, recounted #{processed} records", :green) + end + + private + + def accounts_with_stats + Account.local.includes(:account_stat) + end + + def statuses_with_stats + Status.includes(:status_stat) + end + + def recount_account_stats(account) + account.account_stat.tap do |account_stat| + account_stat.following_count = account.active_relationships.count + account_stat.followers_count = account.passive_relationships.count + account_stat.statuses_count = account.statuses.where.not(visibility: :direct).count + + account_stat.save if account_stat.changed? + end + end + + def recount_status_stats(status) + status.status_stat.tap do |status_stat| + status_stat.replies_count = status.replies.where.not(visibility: :direct).count + status_stat.reblogs_count = status.reblogs.count + status_stat.favourites_count = status.favourites.count + + status_stat.save if status_stat.changed? + end + end + end +end diff --git a/lib/mastodon/canonical_email_blocks_cli.rb b/lib/mastodon/cli/canonical_email_blocks.rb similarity index 83% rename from lib/mastodon/canonical_email_blocks_cli.rb rename to lib/mastodon/cli/canonical_email_blocks.rb index ec228d466a..dd5e6596dd 100644 --- a/lib/mastodon/canonical_email_blocks_cli.rb +++ b/lib/mastodon/cli/canonical_email_blocks.rb @@ -1,18 +1,10 @@ # frozen_string_literal: true require 'concurrent' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class CanonicalEmailBlocksCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class CanonicalEmailBlocks < Base desc 'find EMAIL', 'Find a given e-mail address in the canonical e-mail blocks' long_desc <<-LONG_DESC When suspending a local user, a hash of a "canonical" version of their e-mail diff --git a/lib/mastodon/domains_cli.rb b/lib/mastodon/cli/domains.rb similarity index 93% rename from lib/mastodon/domains_cli.rb rename to lib/mastodon/cli/domains.rb index 81ee53c18e..d17b253681 100644 --- a/lib/mastodon/domains_cli.rb +++ b/lib/mastodon/cli/domains.rb @@ -1,18 +1,10 @@ # frozen_string_literal: true require 'concurrent' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class DomainsCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class Domains < Base option :concurrency, type: :numeric, default: 5, aliases: [:c] option :verbose, type: :boolean, aliases: [:v] option :dry_run, type: :boolean @@ -42,7 +34,6 @@ module Mastodon When the --purge-domain-blocks option is given, also purge matching domain blocks. LONG_DESC def purge(*domains) - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' domains = domains.map { |domain| TagManager.instance.normalize_domain(domain) } account_scope = Account.none domain_block_scope = DomainBlock.none @@ -87,23 +78,23 @@ module Mastodon # Actually perform the deletions processed, = parallelize_with_progress(account_scope) do |account| - DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true) unless options[:dry_run] + DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true) unless dry_run? end - say("Removed #{processed} accounts#{dry_run}", :green) + say("Removed #{processed} accounts#{dry_run_mode_suffix}", :green) if options[:purge_domain_blocks] domain_block_count = domain_block_scope.count - domain_block_scope.in_batches.destroy_all unless options[:dry_run] - say("Removed #{domain_block_count} domain blocks#{dry_run}", :green) + domain_block_scope.in_batches.destroy_all unless dry_run? + say("Removed #{domain_block_count} domain blocks#{dry_run_mode_suffix}", :green) end custom_emojis_count = emoji_scope.count - emoji_scope.in_batches.destroy_all unless options[:dry_run] + emoji_scope.in_batches.destroy_all unless dry_run? - Instance.refresh unless options[:dry_run] + Instance.refresh unless dry_run? - say("Removed #{custom_emojis_count} custom emojis#{dry_run}", :green) + say("Removed #{custom_emojis_count} custom emojis#{dry_run_mode_suffix}", :green) end option :concurrency, type: :numeric, default: 50, aliases: [:c] @@ -139,7 +130,7 @@ module Mastodon pool = Concurrent::ThreadPoolExecutor.new(min_threads: 0, max_threads: options[:concurrency], idletime: 10, auto_terminate: true, max_queue: 0) - work_unit = ->(domain) do + work_unit = lambda do |domain| next if stats.key?(domain) next if options[:exclude_suspended] && domain.match?(blocked_domains) @@ -148,6 +139,7 @@ module Mastodon begin Request.new(:get, "https://#{domain}/api/v1/instance").perform do |res| next unless res.code == 200 + stats[domain] = Oj.load(res.to_s) end @@ -161,9 +153,10 @@ module Mastodon Request.new(:get, "https://#{domain}/api/v1/instance/activity").perform do |res| next unless res.code == 200 + stats[domain]['activity'] = Oj.load(res.to_s) end - rescue StandardError + rescue failed.increment ensure processed.increment diff --git a/lib/mastodon/email_domain_blocks_cli.rb b/lib/mastodon/cli/email_domain_blocks.rb similarity index 90% rename from lib/mastodon/email_domain_blocks_cli.rb rename to lib/mastodon/cli/email_domain_blocks.rb index f39f470691..88a84ecb42 100644 --- a/lib/mastodon/email_domain_blocks_cli.rb +++ b/lib/mastodon/cli/email_domain_blocks.rb @@ -1,18 +1,10 @@ # frozen_string_literal: true require 'concurrent' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class EmailDomainBlocksCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class EmailDomainBlocks < Base desc 'list', 'List blocked e-mail domains' def list EmailDomainBlock.where(parent_id: nil).order(id: 'DESC').find_each do |entry| @@ -47,7 +39,7 @@ module Mastodon processed = 0 domains.each do |domain| - if EmailDomainBlock.where(domain: domain).exists? + if EmailDomainBlock.exists?(domain: domain) say("#{domain} is already blocked.", :yellow) skipped += 1 next @@ -68,7 +60,7 @@ module Mastodon (email_domain_block.other_domains || []).uniq.each do |hostname| another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: email_domain_block) - if EmailDomainBlock.where(domain: hostname).exists? + if EmailDomainBlock.exists?(domain: hostname) say("#{hostname} is already blocked.", :yellow) skipped += 1 next diff --git a/lib/mastodon/emoji_cli.rb b/lib/mastodon/cli/emoji.rb similarity index 92% rename from lib/mastodon/emoji_cli.rb rename to lib/mastodon/cli/emoji.rb index a3e9479098..912c099124 100644 --- a/lib/mastodon/emoji_cli.rb +++ b/lib/mastodon/cli/emoji.rb @@ -1,16 +1,10 @@ # frozen_string_literal: true require 'rubygems/package' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class EmojiCLI < Thor - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class Emoji < Base option :prefix option :suffix option :overwrite, type: :boolean @@ -49,7 +43,7 @@ module Mastodon next if filename.start_with?('._') shortcode = [options[:prefix], filename, options[:suffix]].compact.join - custom_emoji = CustomEmoji.local.find_by("LOWER(shortcode) = ?", shortcode.downcase) + custom_emoji = CustomEmoji.local.find_by('LOWER(shortcode) = ?', shortcode.downcase) if custom_emoji && !options[:overwrite] skipped += 1 @@ -68,12 +62,11 @@ module Mastodon failed += 1 say('Failure/Error: ', :red) say(entry.full_name) - say(' ' + custom_emoji.errors[:image].join(', '), :red) + say(" #{custom_emoji.errors[:image].join(', ')}", :red) end end end - puts say("Imported #{imported}, skipped #{skipped}, failed to import #{failed}", color(imported, skipped, failed)) end diff --git a/lib/mastodon/feeds_cli.rb b/lib/mastodon/cli/feeds.rb similarity index 63% rename from lib/mastodon/feeds_cli.rb rename to lib/mastodon/cli/feeds.rb index 428d63a446..3467dd427c 100644 --- a/lib/mastodon/feeds_cli.rb +++ b/lib/mastodon/cli/feeds.rb @@ -1,18 +1,11 @@ # frozen_string_literal: true -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' +require_relative 'base' -module Mastodon - class FeedsCLI < Thor - include CLIHelper +module Mastodon::CLI + class Feeds < Base include Redisable - def self.exit_on_failure? - true - end - option :all, type: :boolean, default: false option :concurrency, type: :numeric, default: 5, aliases: [:c] option :verbose, type: :boolean, aliases: [:v] @@ -25,14 +18,12 @@ module Mastodon Otherwise, a single user specified by USERNAME. LONG_DESC def build(username = nil) - dry_run = options[:dry_run] ? '(DRY RUN)' : '' - if options[:all] || username.nil? - processed, = parallelize_with_progress(Account.joins(:user).merge(User.active)) do |account| - PrecomputeFeedService.new.call(account) unless options[:dry_run] + processed, = parallelize_with_progress(active_user_accounts) do |account| + PrecomputeFeedService.new.call(account) unless dry_run? end - say("Regenerated feeds for #{processed} accounts #{dry_run}", :green, true) + say("Regenerated feeds for #{processed} accounts #{dry_run_mode_suffix}", :green, true) elsif username.present? account = Account.find_local(username) @@ -41,9 +32,9 @@ module Mastodon exit(1) end - PrecomputeFeedService.new.call(account) unless options[:dry_run] + PrecomputeFeedService.new.call(account) unless dry_run? - say("OK #{dry_run}", :green, true) + say("OK #{dry_run_mode_suffix}", :green, true) else say('No account(s) given', :red) exit(1) @@ -53,12 +44,14 @@ module Mastodon desc 'clear', 'Remove all home and list feeds from Redis' def clear keys = redis.keys('feed:*') - - redis.pipelined do - keys.each { |key| redis.del(key) } - end - + redis.del(keys) say('OK', :green) end + + private + + def active_user_accounts + Account.joins(:user).merge(User.active) + end end end diff --git a/lib/mastodon/ip_blocks_cli.rb b/lib/mastodon/cli/ip_blocks.rb similarity index 80% rename from lib/mastodon/ip_blocks_cli.rb rename to lib/mastodon/cli/ip_blocks.rb index 5c38c1aca0..d12919c360 100644 --- a/lib/mastodon/ip_blocks_cli.rb +++ b/lib/mastodon/cli/ip_blocks.rb @@ -1,17 +1,11 @@ # frozen_string_literal: true require 'rubygems/package' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' +require_relative 'base' -module Mastodon - class IpBlocksCLI < Thor - def self.exit_on_failure? - true - end - - option :severity, required: true, enum: %w(no_access sign_up_requires_approval), desc: 'Severity of the block' +module Mastodon::CLI + class IpBlocks < Base + option :severity, required: true, enum: %w(no_access sign_up_requires_approval sign_up_block), desc: 'Severity of the block' option :comment, aliases: [:c], desc: 'Optional comment' option :duration, aliases: [:d], type: :numeric, desc: 'Duration of the block in seconds' option :force, type: :boolean, aliases: [:f], desc: 'Overwrite existing blocks' @@ -36,6 +30,12 @@ module Mastodon failed = 0 addresses.each do |address| + unless valid_ip_address?(address) + say("#{address} is invalid", :red) + failed += 1 + next + end + ip_block = IpBlock.find_by(ip: address) if ip_block.present? && !options[:force] @@ -79,14 +79,18 @@ module Mastodon skipped = 0 addresses.each do |address| - ip_blocks = begin - if options[:force] - IpBlock.where('ip >>= ?', address) - else - IpBlock.where('ip <<= ?', address) - end + unless valid_ip_address?(address) + say("#{address} is invalid", :yellow) + skipped += 1 + next end + ip_blocks = if options[:force] + IpBlock.where('ip >>= ?', address) + else + IpBlock.where('ip <<= ?', address) + end + if ip_blocks.empty? say("#{address} is not yet blocked", :yellow) skipped += 1 @@ -110,9 +114,9 @@ module Mastodon IpBlock.where(severity: :no_access).find_each do |ip_block| case options[:format] when 'nginx' - puts "deny #{ip_block.ip}/#{ip_block.ip.prefix};" + say "deny #{ip_block.ip}/#{ip_block.ip.prefix};" else - puts "#{ip_block.ip}/#{ip_block.ip.prefix}" + say "#{ip_block.ip}/#{ip_block.ip.prefix}" end end end @@ -128,5 +132,12 @@ module Mastodon :red end end + + def valid_ip_address?(ip_address) + IPAddr.new(ip_address) + true + rescue IPAddr::InvalidAddressError + false + end end end diff --git a/lib/cli.rb b/lib/mastodon/cli/main.rb similarity index 67% rename from lib/cli.rb rename to lib/mastodon/cli/main.rb index 35c00e736f..1594eadce8 100644 --- a/lib/cli.rb +++ b/lib/mastodon/cli/main.rb @@ -1,73 +1,69 @@ # frozen_string_literal: true -require 'thor' -require_relative 'mastodon/media_cli' -require_relative 'mastodon/emoji_cli' -require_relative 'mastodon/accounts_cli' -require_relative 'mastodon/feeds_cli' -require_relative 'mastodon/search_cli' -require_relative 'mastodon/settings_cli' -require_relative 'mastodon/statuses_cli' -require_relative 'mastodon/domains_cli' -require_relative 'mastodon/preview_cards_cli' -require_relative 'mastodon/cache_cli' -require_relative 'mastodon/upgrade_cli' -require_relative 'mastodon/email_domain_blocks_cli' -require_relative 'mastodon/canonical_email_blocks_cli' -require_relative 'mastodon/ip_blocks_cli' -require_relative 'mastodon/maintenance_cli' -require_relative 'mastodon/version' +require_relative 'base' -module Mastodon - class CLI < Thor - def self.exit_on_failure? - true - end +require_relative 'accounts' +require_relative 'cache' +require_relative 'canonical_email_blocks' +require_relative 'domains' +require_relative 'email_domain_blocks' +require_relative 'emoji' +require_relative 'feeds' +require_relative 'ip_blocks' +require_relative 'maintenance' +require_relative 'media' +require_relative 'preview_cards' +require_relative 'search' +require_relative 'settings' +require_relative 'statuses' +require_relative 'upgrade' +module Mastodon::CLI + class Main < Base desc 'media SUBCOMMAND ...ARGS', 'Manage media files' - subcommand 'media', Mastodon::MediaCLI + subcommand 'media', Media desc 'emoji SUBCOMMAND ...ARGS', 'Manage custom emoji' - subcommand 'emoji', Mastodon::EmojiCLI + subcommand 'emoji', Emoji desc 'accounts SUBCOMMAND ...ARGS', 'Manage accounts' - subcommand 'accounts', Mastodon::AccountsCLI + subcommand 'accounts', Accounts desc 'feeds SUBCOMMAND ...ARGS', 'Manage feeds' - subcommand 'feeds', Mastodon::FeedsCLI + subcommand 'feeds', Feeds desc 'search SUBCOMMAND ...ARGS', 'Manage the search engine' - subcommand 'search', Mastodon::SearchCLI + subcommand 'search', Search desc 'settings SUBCOMMAND ...ARGS', 'Manage dynamic settings' - subcommand 'settings', Mastodon::SettingsCLI + subcommand 'settings', Settings desc 'statuses SUBCOMMAND ...ARGS', 'Manage statuses' - subcommand 'statuses', Mastodon::StatusesCLI + subcommand 'statuses', Statuses desc 'domains SUBCOMMAND ...ARGS', 'Manage account domains' - subcommand 'domains', Mastodon::DomainsCLI + subcommand 'domains', Domains desc 'preview_cards SUBCOMMAND ...ARGS', 'Manage preview cards' - subcommand 'preview_cards', Mastodon::PreviewCardsCLI + subcommand 'preview_cards', PreviewCards desc 'cache SUBCOMMAND ...ARGS', 'Manage cache' - subcommand 'cache', Mastodon::CacheCLI + subcommand 'cache', Cache desc 'upgrade SUBCOMMAND ...ARGS', 'Various version upgrade utilities' - subcommand 'upgrade', Mastodon::UpgradeCLI + subcommand 'upgrade', Upgrade desc 'email_domain_blocks SUBCOMMAND ...ARGS', 'Manage e-mail domain blocks' - subcommand 'email_domain_blocks', Mastodon::EmailDomainBlocksCLI + subcommand 'email_domain_blocks', EmailDomainBlocks desc 'ip_blocks SUBCOMMAND ...ARGS', 'Manage IP blocks' - subcommand 'ip_blocks', Mastodon::IpBlocksCLI + subcommand 'ip_blocks', IpBlocks desc 'canonical_email_blocks SUBCOMMAND ...ARGS', 'Manage canonical e-mail blocks' - subcommand 'canonical_email_blocks', Mastodon::CanonicalEmailBlocksCLI + subcommand 'canonical_email_blocks', CanonicalEmailBlocks desc 'maintenance SUBCOMMAND ...ARGS', 'Various maintenance utilities' - subcommand 'maintenance', Mastodon::MaintenanceCLI + subcommand 'maintenance', Maintenance option :dry_run, type: :boolean desc 'self-destruct', 'Erase the server from the federation' @@ -98,7 +94,7 @@ module Mastodon exit(1) unless prompt.ask('Type in the domain of the server to confirm:', required: true) == Rails.configuration.x.local_domain - unless options[:dry_run] + unless dry_run? prompt.warn('This operation WILL NOT be reversible. It can also take a long time.') prompt.warn('While the data won\'t be erased locally, the server will be in a BROKEN STATE afterwards.') prompt.warn('A running Sidekiq process is required. Do not shut it down until queues clear.') @@ -108,12 +104,11 @@ module Mastodon inboxes = Account.inboxes processed = 0 - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' - Setting.registrations_mode = 'none' unless options[:dry_run] + Setting.registrations_mode = 'none' unless dry_run? if inboxes.empty? - Account.local.without_suspended.in_batches.update_all(suspended_at: Time.now.utc, suspension_origin: :local) unless options[:dry_run] + Account.local.without_suspended.in_batches.update_all(suspended_at: Time.now.utc, suspension_origin: :local) unless dry_run? prompt.ok('It seems like your server has not federated with anything') prompt.ok('You can shut it down and delete it any time') return @@ -121,7 +116,7 @@ module Mastodon prompt.warn('Do NOT interrupt this process...') - delete_account = ->(account) do + delete_account = lambda do |account| payload = ActiveModelSerializers::SerializableResource.new( account, serializer: ActivityPub::DeleteActorSerializer, @@ -130,8 +125,8 @@ module Mastodon json = Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(account)) - unless options[:dry_run] - ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url| + unless dry_run? + ActivityPub::DeliveryWorker.push_bulk(inboxes, limit: 1_000) do |inbox_url| [json, account.id, inbox_url] end @@ -144,7 +139,7 @@ module Mastodon Account.local.without_suspended.find_each { |account| delete_account.call(account) } Account.local.suspended.joins(:deletion_request).find_each { |account| delete_account.call(account) } - prompt.ok("Queued #{inboxes.size * processed} items into Sidekiq for #{processed} accounts#{dry_run}") + prompt.ok("Queued #{inboxes.size * processed} items into Sidekiq for #{processed} accounts#{dry_run_mode_suffix}") prompt.ok('Wait until Sidekiq processes all items, then you can shut everything down and delete the data') rescue TTY::Reader::InputInterrupt exit(1) diff --git a/lib/mastodon/maintenance_cli.rb b/lib/mastodon/cli/maintenance.rb similarity index 77% rename from lib/mastodon/maintenance_cli.rb rename to lib/mastodon/cli/maintenance.rb index 85937da812..e73bcbf86a 100644 --- a/lib/mastodon/maintenance_cli.rb +++ b/lib/mastodon/cli/maintenance.rb @@ -1,20 +1,11 @@ # frozen_string_literal: true -require 'tty-prompt' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' +require_relative 'base' -module Mastodon - class MaintenanceCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end - - MIN_SUPPORTED_VERSION = 2019_10_01_213028 # rubocop:disable Style/NumericLiterals - MAX_SUPPORTED_VERSION = 2022_11_04_133904 # rubocop:disable Style/NumericLiterals +module Mastodon::CLI + class Maintenance < Base + MIN_SUPPORTED_VERSION = 2019_10_01_213028 + MAX_SUPPORTED_VERSION = 2023_09_07_150100 # Stubs to enjoy ActiveRecord queries while not depending on a particular # version of the code/database @@ -46,6 +37,8 @@ module Mastodon class CanonicalEmailBlock < ApplicationRecord; end class Appeal < ApplicationRecord; end class Webhook < ApplicationRecord; end + class BulkImport < ApplicationRecord; end + class SoftwareUpdate < ApplicationRecord; end class PreviewCard < ApplicationRecord self.inheritance_column = false @@ -95,14 +88,13 @@ module Mastodon owned_classes << FollowRecommendationSuppression if ActiveRecord::Base.connection.table_exists?(:follow_recommendation_suppressions) owned_classes << AccountIdentityProof if ActiveRecord::Base.connection.table_exists?(:account_identity_proofs) owned_classes << Appeal if ActiveRecord::Base.connection.table_exists?(:appeals) + owned_classes << BulkImport if ActiveRecord::Base.connection.table_exists?(:bulk_imports) owned_classes.each do |klass| klass.where(account_id: other_account.id).find_each do |record| - begin - record.update_attribute(:account_id, id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:account_id, id) + rescue ActiveRecord::RecordNotUnique + next end end @@ -111,11 +103,9 @@ module Mastodon target_classes.each do |klass| klass.where(target_account_id: other_account.id).find_each do |record| - begin - record.update_attribute(:target_account_id, id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:target_account_id, id) + rescue ActiveRecord::RecordNotUnique + next end end @@ -146,25 +136,23 @@ module Mastodon Mastodon has to be stopped to run this task, which will take a long time and may be destructive. LONG_DESC def fix_duplicates - @prompt = TTY::Prompt.new - if ActiveRecord::Migrator.current_version < MIN_SUPPORTED_VERSION - @prompt.error 'Your version of the database schema is too old and is not supported by this script.' - @prompt.error 'Please update to at least Mastodon 3.0.0 before running this script.' + say 'Your version of the database schema is too old and is not supported by this script.', :red + say 'Please update to at least Mastodon 3.0.0 before running this script.', :red exit(1) elsif ActiveRecord::Migrator.current_version > MAX_SUPPORTED_VERSION - @prompt.warn 'Your version of the database schema is more recent than this script, this may cause unexpected errors.' - exit(1) unless @prompt.yes?('Continue anyway? (Yes/No)') + say 'Your version of the database schema is more recent than this script, this may cause unexpected errors.', :yellow + exit(1) unless yes?('Continue anyway? (Yes/No)') end if Sidekiq::ProcessSet.new.any? - @prompt.error 'It seems Sidekiq is running. All Mastodon processes need to be stopped when using this script.' + say 'It seems Sidekiq is running. All Mastodon processes need to be stopped when using this script.', :red exit(1) end - @prompt.warn 'This task will take a long time to run and is potentially destructive.' - @prompt.warn 'Please make sure to stop Mastodon and have a backup.' - exit(1) unless @prompt.yes?('Continue? (Yes/No)') + say 'This task will take a long time to run and is potentially destructive.', :yellow + say 'Please make sure to stop Mastodon and have a backup.', :yellow + exit(1) unless yes?('Continue? (Yes/No)') deduplicate_users! deduplicate_account_domain_blocks! @@ -184,11 +172,12 @@ module Mastodon deduplicate_tags! deduplicate_webauthn_credentials! deduplicate_webhooks! + deduplicate_software_updates! Scenic.database.refresh_materialized_view('instances', concurrently: true, cascade: false) if ActiveRecord::Migrator.current_version >= 2020_12_06_004238 Rails.cache.clear - @prompt.say 'Finished!' + say 'Finished!' end private @@ -196,7 +185,7 @@ module Mastodon def deduplicate_accounts! remove_index_if_exists!(:accounts, 'index_accounts_on_username_and_domain_lower') - @prompt.say 'Deduplicating accounts… for local accounts, you will be asked to chose which account to keep unchanged.' + say 'Deduplicating accounts… for local accounts, you will be asked to chose which account to keep unchanged.' find_duplicate_accounts.each do |row| accounts = Account.where(id: row['ids'].split(',')).to_a @@ -208,17 +197,18 @@ module Mastodon end end - @prompt.say 'Restoring index_accounts_on_username_and_domain_lower…' - if ActiveRecord::Migrator.current_version < 20200620164023 # rubocop:disable Style/NumericLiterals + say 'Restoring index_accounts_on_username_and_domain_lower…' + if ActiveRecord::Migrator.current_version < 2020_06_20_164023 ActiveRecord::Base.connection.add_index :accounts, 'lower (username), lower(domain)', name: 'index_accounts_on_username_and_domain_lower', unique: true else ActiveRecord::Base.connection.add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true end - @prompt.say 'Reindexing textual indexes on accounts…' + say 'Reindexing textual indexes on accounts…' ActiveRecord::Base.connection.execute('REINDEX INDEX search_index;') ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_uri;') ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_url;') + ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_domain_and_id;') if ActiveRecord::Migrator.current_version >= 2023_05_24_190515 end def deduplicate_users! @@ -227,73 +217,84 @@ module Mastodon remove_index_if_exists!(:users, 'index_users_on_remember_token') remove_index_if_exists!(:users, 'index_users_on_reset_password_token') - @prompt.say 'Deduplicating user records…' + say 'Deduplicating user records…' # Deduplicating email ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users GROUP BY email HAVING count(*) > 1").each do |row| users = User.where(id: row['ids'].split(',')).sort_by(&:updated_at).reverse ref_user = users.shift - @prompt.warn "Multiple users registered with e-mail address #{ref_user.email}." - @prompt.warn "e-mail will be disabled for the following accounts: #{user.map(&:account).map(&:acct).join(', ')}" - @prompt.warn 'Please reach out to them and set another address with `tootctl account modify` or delete them.' + say "Multiple users registered with e-mail address #{ref_user.email}.", :yellow + say "e-mail will be disabled for the following accounts: #{user.map(&:account).map(&:acct).join(', ')}", :yellow + say 'Please reach out to them and set another address with `tootctl account modify` or delete them.', :yellow - i = 0 - users.each do |user| - user.update!(email: "#{i} " + user.email) + users.each_with_index do |user, index| + user.update!(email: "#{index} " + user.email) end end + deduplicate_users_process_confirmation_token + deduplicate_users_process_remember_token + deduplicate_users_process_password_token + + say 'Restoring users indexes…' + ActiveRecord::Base.connection.add_index :users, ['confirmation_token'], name: 'index_users_on_confirmation_token', unique: true + ActiveRecord::Base.connection.add_index :users, ['email'], name: 'index_users_on_email', unique: true + ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 2022_01_18_183010 + + if ActiveRecord::Migrator.current_version < 2022_03_10_060641 + ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true + else + ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, where: 'reset_password_token IS NOT NULL', opclass: :text_pattern_ops + end + + ActiveRecord::Base.connection.execute('REINDEX INDEX index_users_on_unconfirmed_email;') if ActiveRecord::Migrator.current_version >= 2023_07_02_151753 + end + + def deduplicate_users_process_confirmation_token ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users WHERE confirmation_token IS NOT NULL GROUP BY confirmation_token HAVING count(*) > 1").each do |row| users = User.where(id: row['ids'].split(',')).sort_by(&:created_at).reverse.drop(1) - @prompt.warn "Unsetting confirmation token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}" + say "Unsetting confirmation token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}", :yellow users.each do |user| user.update!(confirmation_token: nil) end end + end - if ActiveRecord::Migrator.current_version < 20220118183010 # rubocop:disable Style/NumericLiterals + def deduplicate_users_process_remember_token + if ActiveRecord::Migrator.current_version < 2022_01_18_183010 ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users WHERE remember_token IS NOT NULL GROUP BY remember_token HAVING count(*) > 1").each do |row| users = User.where(id: row['ids'].split(',')).sort_by(&:updated_at).reverse.drop(1) - @prompt.warn "Unsetting remember token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}" + say "Unsetting remember token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}", :yellow users.each do |user| user.update!(remember_token: nil) end end end + end + def deduplicate_users_process_password_token ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users WHERE reset_password_token IS NOT NULL GROUP BY reset_password_token HAVING count(*) > 1").each do |row| users = User.where(id: row['ids'].split(',')).sort_by(&:updated_at).reverse.drop(1) - @prompt.warn "Unsetting password reset token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}" + say "Unsetting password reset token for those accounts: #{users.map(&:account).map(&:acct).join(', ')}", :yellow users.each do |user| user.update!(reset_password_token: nil) end end - - @prompt.say 'Restoring users indexes…' - ActiveRecord::Base.connection.add_index :users, ['confirmation_token'], name: 'index_users_on_confirmation_token', unique: true - ActiveRecord::Base.connection.add_index :users, ['email'], name: 'index_users_on_email', unique: true - ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 20220118183010 - - if ActiveRecord::Migrator.current_version < 20220310060641 # rubocop:disable Style/NumericLiterals - ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true - else - ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, where: 'reset_password_token IS NOT NULL', opclass: :text_pattern_ops - end end def deduplicate_account_domain_blocks! remove_index_if_exists!(:account_domain_blocks, 'index_account_domain_blocks_on_account_id_and_domain') - @prompt.say 'Removing duplicate account domain blocks…' + say 'Removing duplicate account domain blocks…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM account_domain_blocks GROUP BY account_id, domain HAVING count(*) > 1").each do |row| AccountDomainBlock.where(id: row['ids'].split(',').drop(1)).delete_all end - @prompt.say 'Restoring account domain blocks indexes…' - ActiveRecord::Base.connection.add_index :account_domain_blocks, ['account_id', 'domain'], name: 'index_account_domain_blocks_on_account_id_and_domain', unique: true + say 'Restoring account domain blocks indexes…' + ActiveRecord::Base.connection.add_index :account_domain_blocks, %w(account_id domain), name: 'index_account_domain_blocks_on_account_id_and_domain', unique: true end def deduplicate_account_identity_proofs! @@ -301,13 +302,13 @@ module Mastodon remove_index_if_exists!(:account_identity_proofs, 'index_account_proofs_on_account_and_provider_and_username') - @prompt.say 'Removing duplicate account identity proofs…' + say 'Removing duplicate account identity proofs…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM account_identity_proofs GROUP BY account_id, provider, provider_username HAVING count(*) > 1").each do |row| AccountIdentityProof.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring account identity proofs indexes…' - ActiveRecord::Base.connection.add_index :account_identity_proofs, ['account_id', 'provider', 'provider_username'], name: 'index_account_proofs_on_account_and_provider_and_username', unique: true + say 'Restoring account identity proofs indexes…' + ActiveRecord::Base.connection.add_index :account_identity_proofs, %w(account_id provider provider_username), name: 'index_account_proofs_on_account_and_provider_and_username', unique: true end def deduplicate_announcement_reactions! @@ -315,19 +316,19 @@ module Mastodon remove_index_if_exists!(:announcement_reactions, 'index_announcement_reactions_on_account_id_and_announcement_id') - @prompt.say 'Removing duplicate account identity proofs…' + say 'Removing duplicate account identity proofs…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM announcement_reactions GROUP BY account_id, announcement_id, name HAVING count(*) > 1").each do |row| AnnouncementReaction.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring announcement_reactions indexes…' - ActiveRecord::Base.connection.add_index :announcement_reactions, ['account_id', 'announcement_id', 'name'], name: 'index_announcement_reactions_on_account_id_and_announcement_id', unique: true + say 'Restoring announcement_reactions indexes…' + ActiveRecord::Base.connection.add_index :announcement_reactions, %w(account_id announcement_id name), name: 'index_announcement_reactions_on_account_id_and_announcement_id', unique: true end def deduplicate_conversations! remove_index_if_exists!(:conversations, 'index_conversations_on_uri') - @prompt.say 'Deduplicating conversations…' + say 'Deduplicating conversations…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM conversations WHERE uri IS NOT NULL GROUP BY uri HAVING count(*) > 1").each do |row| conversations = Conversation.where(id: row['ids'].split(',')).sort_by(&:id).reverse @@ -339,8 +340,8 @@ module Mastodon end end - @prompt.say 'Restoring conversations indexes…' - if ActiveRecord::Migrator.current_version < 20220307083603 # rubocop:disable Style/NumericLiterals + say 'Restoring conversations indexes…' + if ActiveRecord::Migrator.current_version < 2022_03_07_083603 ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true else ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops @@ -350,7 +351,7 @@ module Mastodon def deduplicate_custom_emojis! remove_index_if_exists!(:custom_emojis, 'index_custom_emojis_on_shortcode_and_domain') - @prompt.say 'Deduplicating custom_emojis…' + say 'Deduplicating custom_emojis…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM custom_emojis GROUP BY shortcode, domain HAVING count(*) > 1").each do |row| emojis = CustomEmoji.where(id: row['ids'].split(',')).sort_by(&:id).reverse @@ -362,14 +363,14 @@ module Mastodon end end - @prompt.say 'Restoring custom_emojis indexes…' - ActiveRecord::Base.connection.add_index :custom_emojis, ['shortcode', 'domain'], name: 'index_custom_emojis_on_shortcode_and_domain', unique: true + say 'Restoring custom_emojis indexes…' + ActiveRecord::Base.connection.add_index :custom_emojis, %w(shortcode domain), name: 'index_custom_emojis_on_shortcode_and_domain', unique: true end def deduplicate_custom_emoji_categories! remove_index_if_exists!(:custom_emoji_categories, 'index_custom_emoji_categories_on_name') - @prompt.say 'Deduplicating custom_emoji_categories…' + say 'Deduplicating custom_emoji_categories…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM custom_emoji_categories GROUP BY name HAVING count(*) > 1").each do |row| categories = CustomEmojiCategory.where(id: row['ids'].split(',')).sort_by(&:id).reverse @@ -381,26 +382,26 @@ module Mastodon end end - @prompt.say 'Restoring custom_emoji_categories indexes…' + say 'Restoring custom_emoji_categories indexes…' ActiveRecord::Base.connection.add_index :custom_emoji_categories, ['name'], name: 'index_custom_emoji_categories_on_name', unique: true end def deduplicate_domain_allows! remove_index_if_exists!(:domain_allows, 'index_domain_allows_on_domain') - @prompt.say 'Deduplicating domain_allows…' + say 'Deduplicating domain_allows…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM domain_allows GROUP BY domain HAVING count(*) > 1").each do |row| DomainAllow.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring domain_allows indexes…' + say 'Restoring domain_allows indexes…' ActiveRecord::Base.connection.add_index :domain_allows, ['domain'], name: 'index_domain_allows_on_domain', unique: true end def deduplicate_domain_blocks! remove_index_if_exists!(:domain_blocks, 'index_domain_blocks_on_domain') - @prompt.say 'Deduplicating domain_allows…' + say 'Deduplicating domain_allows…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM domain_blocks GROUP BY domain HAVING count(*) > 1").each do |row| domain_blocks = DomainBlock.where(id: row['ids'].split(',')).by_severity.reverse.to_a @@ -417,7 +418,7 @@ module Mastodon domain_blocks.each(&:destroy) end - @prompt.say 'Restoring domain_blocks indexes…' + say 'Restoring domain_blocks indexes…' ActiveRecord::Base.connection.add_index :domain_blocks, ['domain'], name: 'index_domain_blocks_on_domain', unique: true end @@ -426,38 +427,38 @@ module Mastodon remove_index_if_exists!(:unavailable_domains, 'index_unavailable_domains_on_domain') - @prompt.say 'Deduplicating unavailable_domains…' + say 'Deduplicating unavailable_domains…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM unavailable_domains GROUP BY domain HAVING count(*) > 1").each do |row| UnavailableDomain.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring domain_allows indexes…' + say 'Restoring domain_allows indexes…' ActiveRecord::Base.connection.add_index :unavailable_domains, ['domain'], name: 'index_unavailable_domains_on_domain', unique: true end def deduplicate_email_domain_blocks! remove_index_if_exists!(:email_domain_blocks, 'index_email_domain_blocks_on_domain') - @prompt.say 'Deduplicating email_domain_blocks…' + say 'Deduplicating email_domain_blocks…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM email_domain_blocks GROUP BY domain HAVING count(*) > 1").each do |row| domain_blocks = EmailDomainBlock.where(id: row['ids'].split(',')).sort_by { |b| b.parent.nil? ? 1 : 0 }.to_a domain_blocks.drop(1).each(&:destroy) end - @prompt.say 'Restoring email_domain_blocks indexes…' + say 'Restoring email_domain_blocks indexes…' ActiveRecord::Base.connection.add_index :email_domain_blocks, ['domain'], name: 'index_email_domain_blocks_on_domain', unique: true end def deduplicate_media_attachments! remove_index_if_exists!(:media_attachments, 'index_media_attachments_on_shortcode') - @prompt.say 'Deduplicating media_attachments…' + say 'Deduplicating media_attachments…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM media_attachments WHERE shortcode IS NOT NULL GROUP BY shortcode HAVING count(*) > 1").each do |row| MediaAttachment.where(id: row['ids'].split(',').drop(1)).update_all(shortcode: nil) end - @prompt.say 'Restoring media_attachments indexes…' - if ActiveRecord::Migrator.current_version < 20220310060626 # rubocop:disable Style/NumericLiterals + say 'Restoring media_attachments indexes…' + if ActiveRecord::Migrator.current_version < 2022_03_10_060626 ActiveRecord::Base.connection.add_index :media_attachments, ['shortcode'], name: 'index_media_attachments_on_shortcode', unique: true else ActiveRecord::Base.connection.add_index :media_attachments, ['shortcode'], name: 'index_media_attachments_on_shortcode', unique: true, where: 'shortcode IS NOT NULL', opclass: :text_pattern_ops @@ -467,19 +468,19 @@ module Mastodon def deduplicate_preview_cards! remove_index_if_exists!(:preview_cards, 'index_preview_cards_on_url') - @prompt.say 'Deduplicating preview_cards…' + say 'Deduplicating preview_cards…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM preview_cards GROUP BY url HAVING count(*) > 1").each do |row| PreviewCard.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring preview_cards indexes…' + say 'Restoring preview_cards indexes…' ActiveRecord::Base.connection.add_index :preview_cards, ['url'], name: 'index_preview_cards_on_url', unique: true end def deduplicate_statuses! remove_index_if_exists!(:statuses, 'index_statuses_on_uri') - @prompt.say 'Deduplicating statuses…' + say 'Deduplicating statuses…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM statuses WHERE uri IS NOT NULL GROUP BY uri HAVING count(*) > 1").each do |row| statuses = Status.where(id: row['ids'].split(',')).sort_by(&:id) ref_status = statuses.shift @@ -489,8 +490,8 @@ module Mastodon end end - @prompt.say 'Restoring statuses indexes…' - if ActiveRecord::Migrator.current_version < 20220310060706 # rubocop:disable Style/NumericLiterals + say 'Restoring statuses indexes…' + if ActiveRecord::Migrator.current_version < 2022_03_10_060706 ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true else ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops @@ -501,7 +502,7 @@ module Mastodon remove_index_if_exists!(:tags, 'index_tags_on_name_lower') remove_index_if_exists!(:tags, 'index_tags_on_name_lower_btree') - @prompt.say 'Deduplicating tags…' + say 'Deduplicating tags…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM tags GROUP BY lower((name)::text) HAVING count(*) > 1").each do |row| tags = Tag.where(id: row['ids'].split(',')).sort_by { |t| [t.usable?, t.trendable?, t.listable?].count(false) } ref_tag = tags.shift @@ -511,8 +512,8 @@ module Mastodon end end - @prompt.say 'Restoring tags indexes…' - if ActiveRecord::Migrator.current_version < 20210421121431 + say 'Restoring tags indexes…' + if ActiveRecord::Migrator.current_version < 2021_04_21_121431 ActiveRecord::Base.connection.add_index :tags, 'lower((name)::text)', name: 'index_tags_on_name_lower', unique: true else ActiveRecord::Base.connection.execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' @@ -524,12 +525,12 @@ module Mastodon remove_index_if_exists!(:webauthn_credentials, 'index_webauthn_credentials_on_external_id') - @prompt.say 'Deduplicating webauthn_credentials…' + say 'Deduplicating webauthn_credentials…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM webauthn_credentials GROUP BY external_id HAVING count(*) > 1").each do |row| WebauthnCredential.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring webauthn_credentials indexes…' + say 'Restoring webauthn_credentials indexes…' ActiveRecord::Base.connection.add_index :webauthn_credentials, ['external_id'], name: 'index_webauthn_credentials_on_external_id', unique: true end @@ -538,28 +539,42 @@ module Mastodon remove_index_if_exists!(:webhooks, 'index_webhooks_on_url') - @prompt.say 'Deduplicating webhooks…' + say 'Deduplicating webhooks…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM webhooks GROUP BY url HAVING count(*) > 1").each do |row| Webhooks.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) end - @prompt.say 'Restoring webhooks indexes…' + say 'Restoring webhooks indexes…' ActiveRecord::Base.connection.add_index :webhooks, ['url'], name: 'index_webhooks_on_url', unique: true end + def deduplicate_software_updates! + # Not bothering with this, it's data that will be recovered with the scheduler + SoftwareUpdate.delete_all + end + def deduplicate_local_accounts!(accounts) accounts = accounts.sort_by(&:id).reverse - @prompt.warn "Multiple local accounts were found for username '#{accounts.first.username}'." - @prompt.warn 'All those accounts are distinct accounts but only the most recently-created one is fully-functional.' + say "Multiple local accounts were found for username '#{accounts.first.username}'.", :yellow + say 'All those accounts are distinct accounts but only the most recently-created one is fully-functional.', :yellow accounts.each_with_index do |account, idx| - @prompt.say '%2d. %s: created at: %s; updated at: %s; last logged in at: %s; statuses: %5d; last status at: %s' % [idx, account.username, account.created_at, account.updated_at, account.user&.last_sign_in_at&.to_s || 'N/A', account.account_stat&.statuses_count || 0, account.account_stat&.last_status_at || 'N/A'] + say format( + '%2d. %s: created at: %s; updated at: %s; last logged in at: %s; statuses: %5d; last status at: %s', + index: idx, + username: account.username, + created_at: account.created_at, + updated_at: account.updated_at, + last_log_in_at: account.user&.last_sign_in_at&.to_s || 'N/A', + status_count: account.account_stat&.statuses_count || 0, + last_status_at: account.account_stat&.last_status_at || 'N/A' + ) end - @prompt.say 'Please chose the one to keep unchanged, other ones will be automatically renamed.' + say 'Please chose the one to keep unchanged, other ones will be automatically renamed.' - ref_id = @prompt.ask('Account to keep unchanged:') do |q| + ref_id = ask('Account to keep unchanged:') do |q| q.required true q.default 0 q.convert :int @@ -601,11 +616,9 @@ module Mastodon owned_classes = [ConversationMute, AccountConversation] owned_classes.each do |klass| klass.where(conversation_id: duplicate_conv.id).find_each do |record| - begin - record.update_attribute(:account_id, main_conv.id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:account_id, main_conv.id) + rescue ActiveRecord::RecordNotUnique + next end end end @@ -629,47 +642,37 @@ module Mastodon owned_classes << Bookmark if ActiveRecord::Base.connection.table_exists?(:bookmarks) owned_classes.each do |klass| klass.where(status_id: duplicate_status.id).find_each do |record| - begin - record.update_attribute(:status_id, main_status.id) - rescue ActiveRecord::RecordNotUnique - next - end - end - end - - StatusPin.where(account_id: main_status.account_id, status_id: duplicate_status.id).find_each do |record| - begin record.update_attribute(:status_id, main_status.id) rescue ActiveRecord::RecordNotUnique next end end + StatusPin.where(account_id: main_status.account_id, status_id: duplicate_status.id).find_each do |record| + record.update_attribute(:status_id, main_status.id) + rescue ActiveRecord::RecordNotUnique + next + end + Status.where(in_reply_to_id: duplicate_status.id).find_each do |record| - begin - record.update_attribute(:in_reply_to_id, main_status.id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:in_reply_to_id, main_status.id) + rescue ActiveRecord::RecordNotUnique + next end Status.where(reblog_of_id: duplicate_status.id).find_each do |record| - begin - record.update_attribute(:reblog_of_id, main_status.id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:reblog_of_id, main_status.id) + rescue ActiveRecord::RecordNotUnique + next end end def merge_tags!(main_tag, duplicate_tag) [FeaturedTag].each do |klass| klass.where(tag_id: duplicate_tag.id).find_each do |record| - begin - record.update_attribute(:tag_id, main_tag.id) - rescue ActiveRecord::RecordNotUnique - next - end + record.update_attribute(:tag_id, main_tag.id) + rescue ActiveRecord::RecordNotUnique + next end end end @@ -680,9 +683,7 @@ module Mastodon def remove_index_if_exists!(table, name) ActiveRecord::Base.connection.remove_index(table, name: name) - rescue ArgumentError - nil - rescue ActiveRecord::StatementInvalid + rescue ArgumentError, ActiveRecord::StatementInvalid nil end end diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/cli/media.rb similarity index 87% rename from lib/mastodon/media_cli.rb rename to lib/mastodon/cli/media.rb index 24cc989646..c906161770 100644 --- a/lib/mastodon/media_cli.rb +++ b/lib/mastodon/cli/media.rb @@ -1,17 +1,12 @@ # frozen_string_literal: true -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' +require_relative 'base' -module Mastodon - class MediaCLI < Thor +module Mastodon::CLI + class Media < Base include ActionView::Helpers::NumberHelper - include CLIHelper - def self.exit_on_failure? - true - end + VALID_PATH_SEGMENTS_SIZE = [7, 10].freeze option :days, type: :numeric, default: 7, aliases: [:d] option :prune_profiles, type: :boolean, default: false @@ -22,7 +17,7 @@ module Mastodon desc 'remove', 'Remove remote media files, headers or avatars' long_desc <<-DESC Removes locally cached copies of media attachments (and optionally profile - headers and avatars) from other servers. By default, only media attachements + headers and avatars) from other servers. By default, only media attachments are removed. The --days option specifies how old media attachments have to be before they are removed. In case of avatars and headers, it specifies how old @@ -35,18 +30,17 @@ module Mastodon follow status. By default, only accounts that are not followed by or following anyone locally are pruned. DESC - # rubocop:disable Metrics/PerceivedComplexity def remove if options[:prune_profiles] && options[:remove_headers] say('--prune-profiles and --remove-headers should not be specified simultaneously', :red, true) exit(1) end + if options[:include_follows] && !(options[:prune_profiles] || options[:remove_headers]) say('--include-follows can only be used with --prune-profiles or --remove-headers', :red, true) exit(1) end - time_ago = options[:days].days.ago - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' + time_ago = options[:days].days.ago if options[:prune_profiles] || options[:remove_headers] processed, aggregate = parallelize_with_progress(Account.remote.where({ last_webfingered_at: ..time_ago, updated_at: ..time_ago })) do |account| @@ -57,7 +51,7 @@ module Mastodon size = (account.header_file_size || 0) size += (account.avatar_file_size || 0) if options[:prune_profiles] - unless options[:dry_run] + unless dry_run? account.header.destroy account.avatar.destroy if options[:prune_profiles] account.save! @@ -66,7 +60,7 @@ module Mastodon size end - say("Visited #{processed} accounts and removed profile media totaling #{number_to_human_size(aggregate)}#{dry_run}", :green, true) + say("Visited #{processed} accounts and removed profile media totaling #{number_to_human_size(aggregate)}#{dry_run_mode_suffix}", :green, true) end unless options[:prune_profiles] || options[:remove_headers] @@ -75,7 +69,7 @@ module Mastodon size = (media_attachment.file_file_size || 0) + (media_attachment.thumbnail_file_size || 0) - unless options[:dry_run] + unless dry_run? media_attachment.file.destroy media_attachment.thumbnail.destroy media_attachment.save @@ -84,7 +78,7 @@ module Mastodon size end - say("Removed #{processed} media attachments (approx. #{number_to_human_size(aggregate)})#{dry_run}", :green, true) + say("Removed #{processed} media attachments (approx. #{number_to_human_size(aggregate)})#{dry_run_mode_suffix}", :green, true) end end @@ -103,7 +97,6 @@ module Mastodon progress = create_progress_bar(nil) reclaimed_bytes = 0 removed = 0 - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' prefix = options[:prefix] case Paperclip::Attachment.default_options[:storage] @@ -116,13 +109,11 @@ module Mastodon loop do objects = begin - begin - bucket.objects(start_after: last_key, prefix: prefix).limit(1000).map { |x| x } - rescue => e - progress.log(pastel.red("Error fetching list of files: #{e}")) - progress.log("If you want to continue from this point, add --start-after=#{last_key} to your command") if last_key - break - end + bucket.objects(start_after: last_key, prefix: prefix).limit(1000).map { |x| x } + rescue => e + progress.log(pastel.red("Error fetching list of files: #{e}")) + progress.log("If you want to continue from this point, add --start-after=#{last_key} to your command") if last_key + break end break if objects.empty? @@ -131,12 +122,12 @@ module Mastodon record_map = preload_records_from_mixed_objects(objects) objects.each do |object| - object.acl.put(acl: s3_permissions) if options[:fix_permissions] && !options[:dry_run] + object.acl.put(acl: s3_permissions) if options[:fix_permissions] && !dry_run? path_segments = object.key.split('/') path_segments.delete('cache') - unless [7, 10].include?(path_segments.size) + unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size) progress.log(pastel.yellow("Unrecognized file found: #{object.key}")) next end @@ -153,7 +144,7 @@ module Mastodon next unless attachment.blank? || !attachment.variant?(file_name) begin - object.delete unless options[:dry_run] + object.delete unless dry_run? reclaimed_bytes += object.size removed += 1 @@ -167,6 +158,9 @@ module Mastodon when :fog say('The fog storage driver is not supported for this operation at this time', :red) exit(1) + when :azure + say('The azure storage driver is not supported for this operation at this time', :red) + exit(1) when :filesystem require 'find' @@ -180,7 +174,7 @@ module Mastodon path_segments = key.split(File::SEPARATOR) path_segments.delete('cache') - unless [7, 10].include?(path_segments.size) + unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size) progress.log(pastel.yellow("Unrecognized file found: #{key}")) next end @@ -202,7 +196,7 @@ module Mastodon begin size = File.size(path) - unless options[:dry_run] + unless dry_run? File.delete(path) begin FileUtils.rmdir(File.dirname(path), parents: true) @@ -224,9 +218,8 @@ module Mastodon progress.total = progress.progress progress.finish - say("Removed #{removed} orphans (approx. #{number_to_human_size(reclaimed_bytes)})#{dry_run}", :green, true) + say("Removed #{removed} orphans (approx. #{number_to_human_size(reclaimed_bytes)})#{dry_run_mode_suffix}", :green, true) end - # rubocop:enable Metrics/PerceivedComplexity option :account, type: :string option :domain, type: :string @@ -255,8 +248,6 @@ module Mastodon not be re-downloaded. To force re-download of every URL, use --force. DESC def refresh - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' - if options[:status] scope = MediaAttachment.where(status_id: options[:status]) elsif options[:account] @@ -277,15 +268,13 @@ module Mastodon exit(1) end - if options[:days].present? - scope = scope.where('media_attachments.id > ?', Mastodon::Snowflake.id_at(options[:days].days.ago, with_random: false)) - end + scope = scope.where('media_attachments.id > ?', Mastodon::Snowflake.id_at(options[:days].days.ago, with_random: false)) if options[:days].present? processed, aggregate = parallelize_with_progress(scope) do |media_attachment| next if media_attachment.remote_url.blank? || (!options[:force] && media_attachment.file_file_name.present?) next if DomainBlock.reject_media?(media_attachment.account.domain) - unless options[:dry_run] + unless dry_run? media_attachment.reset_file! media_attachment.reset_thumbnail! media_attachment.save @@ -294,7 +283,7 @@ module Mastodon media_attachment.file_file_size + (media_attachment.thumbnail_file_size || 0) end - say("Downloaded #{processed} media attachments (approx. #{number_to_human_size(aggregate)})#{dry_run}", :green, true) + say("Downloaded #{processed} media attachments (approx. #{number_to_human_size(aggregate)})#{dry_run_mode_suffix}", :green, true) end desc 'usage', 'Calculate disk space consumed by Mastodon' @@ -316,7 +305,7 @@ module Mastodon path_segments = path.split('/')[2..] path_segments.delete('cache') - unless [7, 10].include?(path_segments.size) + unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size) say('Not a media URL', :red) exit(1) end @@ -369,7 +358,7 @@ module Mastodon segments = object.key.split('/') segments.delete('cache') - next unless [7, 10].include?(segments.size) + next unless VALID_PATH_SEGMENTS_SIZE.include?(segments.size) model_name = segments.first.classify record_id = segments[2..-2].join.to_i diff --git a/lib/mastodon/preview_cards_cli.rb b/lib/mastodon/cli/preview_cards.rb similarity index 80% rename from lib/mastodon/preview_cards_cli.rb rename to lib/mastodon/cli/preview_cards.rb index cf4407250c..2df3d095da 100644 --- a/lib/mastodon/preview_cards_cli.rb +++ b/lib/mastodon/cli/preview_cards.rb @@ -1,18 +1,11 @@ # frozen_string_literal: true require 'tty-prompt' -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' +require_relative 'base' -module Mastodon - class PreviewCardsCLI < Thor +module Mastodon::CLI + class PreviewCards < Base include ActionView::Helpers::NumberHelper - include CLIHelper - - def self.exit_on_failure? - true - end option :days, type: :numeric, default: 180 option :concurrency, type: :numeric, default: 5, aliases: [:c] @@ -34,7 +27,6 @@ module Mastodon DESC def remove time_ago = options[:days].days.ago - dry_run = options[:dry_run] ? ' (DRY RUN)' : '' link = options[:link] ? 'link-type ' : '' scope = PreviewCard.cached scope = scope.where(type: :link) if options[:link] @@ -45,7 +37,7 @@ module Mastodon size = preview_card.image_file_size - unless options[:dry_run] + unless dry_run? preview_card.image.destroy preview_card.save end @@ -53,7 +45,7 @@ module Mastodon size end - say("Removed #{processed} #{link}preview cards (approx. #{number_to_human_size(aggregate)})#{dry_run}", :green, true) + say("Removed #{processed} #{link}preview cards (approx. #{number_to_human_size(aggregate)})#{dry_run_mode_suffix}", :green, true) end end end diff --git a/lib/mastodon/cli/progress_helper.rb b/lib/mastodon/cli/progress_helper.rb new file mode 100644 index 0000000000..1fa2745c18 --- /dev/null +++ b/lib/mastodon/cli/progress_helper.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +dev_null = Logger.new('/dev/null') + +Rails.logger = dev_null +ActiveRecord::Base.logger = dev_null +ActiveJob::Base.logger = dev_null +HttpLog.configuration.logger = dev_null +Paperclip.options[:log] = false +Chewy.logger = dev_null + +require 'ruby-progressbar/outputs/null' + +module Mastodon::CLI + module ProgressHelper + PROGRESS_FORMAT = '%c/%u |%b%i| %e' + + def create_progress_bar(total = nil) + ProgressBar.create( + { + total: total, + format: PROGRESS_FORMAT, + }.merge(progress_output_options) + ) + end + + def parallelize_with_progress(scope) + if options[:concurrency] < 1 + say('Cannot run with this concurrency setting, must be at least 1', :red) + exit(1) + end + + reset_connection_pools! + + progress = create_progress_bar(scope.count) + pool = Concurrent::FixedThreadPool.new(options[:concurrency]) + total = Concurrent::AtomicFixnum.new(0) + aggregate = Concurrent::AtomicFixnum.new(0) + + scope.reorder(nil).find_in_batches do |items| + futures = [] + + items.each do |item| + futures << Concurrent::Future.execute(executor: pool) do + if !progress.total.nil? && progress.progress + 1 > progress.total + # The number of items has changed between start and now, + # since there is no good way to predict the final count from + # here, just change the progress bar to an indeterminate one + + progress.total = nil + end + + progress.log("Processing #{item.id}") if options[:verbose] + + Chewy.strategy(:mastodon) do + result = ActiveRecord::Base.connection_pool.with_connection do + yield(item) + ensure + RedisConfiguration.pool.checkin if Thread.current[:redis] + Thread.current[:redis] = nil + end + + aggregate.increment(result) if result.is_a?(Integer) + end + rescue => e + progress.log pastel.red("Error processing #{item.id}: #{e}") + ensure + progress.increment + end + end + + total.increment(items.size) + futures.map(&:value) + end + + progress.stop + + [total.value, aggregate.value] + end + + private + + def progress_output_options + Rails.env.test? ? { output: ProgressBar::Outputs::Null } : {} + end + end +end diff --git a/lib/mastodon/search_cli.rb b/lib/mastodon/cli/search.rb similarity index 73% rename from lib/mastodon/search_cli.rb rename to lib/mastodon/cli/search.rb index b206854ab3..25a595aadd 100644 --- a/lib/mastodon/search_cli.rb +++ b/lib/mastodon/cli/search.rb @@ -1,26 +1,25 @@ # frozen_string_literal: true -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class SearchCLI < Thor - include CLIHelper +require_relative 'base' +module Mastodon::CLI + class Search < Base # Indices are sorted by amount of data to be expected in each, so that # smaller indices can go online sooner INDICES = [ + InstancesIndex, AccountsIndex, TagsIndex, + PublicStatusesIndex, StatusesIndex, ].freeze option :concurrency, type: :numeric, default: 5, aliases: [:c], desc: 'Workload will be split between this number of threads' option :batch_size, type: :numeric, default: 100, aliases: [:b], desc: 'Number of records in each batch' - option :only, type: :array, enum: %w(accounts tags statuses), desc: 'Only process these indices' + option :only, type: :array, enum: %w(instances accounts tags statuses public_statuses), desc: 'Only process these indices' option :import, type: :boolean, default: true, desc: 'Import data from the database to the index' option :clean, type: :boolean, default: true, desc: 'Remove outdated documents from the index' + option :reset_chewy, type: :boolean, default: false, desc: "Reset Chewy's internal index" desc 'deploy', 'Create or upgrade Elasticsearch indices and populate them' long_desc <<~LONG_DESC If Elasticsearch is empty, this command will create the necessary indices @@ -33,28 +32,20 @@ module Mastodon database will be imported into the indices, unless overridden with --no-import. LONG_DESC def deploy - if options[:concurrency] < 1 - say('Cannot run with this concurrency setting, must be at least 1', :red) - exit(1) - end + verify_deploy_options! - if options[:batch_size] < 1 - say('Cannot run with this batch_size setting, must be at least 1', :red) - exit(1) - end - - indices = begin - if options[:only] - options[:only].map { |str| "#{str.camelize}Index".constantize } - else - INDICES - end - end + indices = if options[:only] + options[:only].map { |str| "#{str.camelize}Index".constantize } + else + INDICES + end pool = Concurrent::FixedThreadPool.new(options[:concurrency], max_queue: options[:concurrency] * 10) importers = indices.index_with { |index| "Importer::#{index.name}Importer".constantize.new(batch_size: options[:batch_size], executor: pool) } progress = ProgressBar.create(total: nil, format: '%t%c/%u |%b%i| %e (%r docs/s)', autofinish: false) + Chewy::Stash::Specification.reset! if options[:reset_chewy] + # First, ensure all indices are created and have the correct # structure, so that live data can already be written indices.select { |index| index.specification.changed? }.each do |index| @@ -104,5 +95,26 @@ module Mastodon say("Indexed #{added} records, de-indexed #{removed}", :green, true) end + + private + + def verify_deploy_options! + verify_deploy_concurrency! + verify_deploy_batch_size! + end + + def verify_deploy_concurrency! + return unless options[:concurrency] < 1 + + say('Cannot run with this concurrency setting, must be at least 1', :red) + exit(1) + end + + def verify_deploy_batch_size! + return unless options[:batch_size] < 1 + + say('Cannot run with this batch_size setting, must be at least 1', :red) + exit(1) + end end end diff --git a/lib/mastodon/settings_cli.rb b/lib/mastodon/cli/settings.rb similarity index 76% rename from lib/mastodon/settings_cli.rb rename to lib/mastodon/cli/settings.rb index 488c655dee..7d4c13b78e 100644 --- a/lib/mastodon/settings_cli.rb +++ b/lib/mastodon/cli/settings.rb @@ -1,15 +1,9 @@ # frozen_string_literal: true -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class RegistrationsCLI < Thor - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class Registrations < Base desc 'open', 'Open registrations' def open Setting.registrations_mode = 'open' @@ -37,8 +31,8 @@ module Mastodon end end - class SettingsCLI < Thor + class Settings < Base desc 'registrations SUBCOMMAND ...ARGS', 'Manage state of registrations' - subcommand 'registrations', RegistrationsCLI + subcommand 'registrations', Registrations end end diff --git a/lib/mastodon/statuses_cli.rb b/lib/mastodon/cli/statuses.rb similarity index 97% rename from lib/mastodon/statuses_cli.rb rename to lib/mastodon/cli/statuses.rb index baab83e297..0d6018a2b9 100644 --- a/lib/mastodon/statuses_cli.rb +++ b/lib/mastodon/cli/statuses.rb @@ -1,18 +1,11 @@ # frozen_string_literal: true -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' +require_relative 'base' -module Mastodon - class StatusesCLI < Thor - include CLIHelper +module Mastodon::CLI + class Statuses < Base include ActionView::Helpers::NumberHelper - def self.exit_on_failure? - true - end - option :days, type: :numeric, default: 90 option :batch_size, type: :numeric, default: 1_000, aliases: [:b], desc: 'Number of records in each batch' option :continue, type: :boolean, default: false, desc: 'If remove is not completed, execute from the previous continuation' @@ -68,7 +61,7 @@ module Mastodon # Skip accounts followed by local accounts clean_followed_sql = 'AND NOT EXISTS (SELECT 1 FROM follows WHERE statuses.account_id = follows.target_account_id)' unless options[:clean_followed] - ActiveRecord::Base.connection.exec_insert(<<-SQL.squish, 'SQL', [[nil, max_id]]) + ActiveRecord::Base.connection.exec_insert(<<-SQL.squish, 'SQL', [max_id]) INSERT INTO statuses_to_be_deleted (id) SELECT statuses.id FROM statuses WHERE deleted_at IS NULL AND NOT local AND uri IS NOT NULL AND (id < $1) AND NOT EXISTS (SELECT 1 FROM statuses AS statuses1 WHERE statuses.id = statuses1.in_reply_to_id) diff --git a/lib/mastodon/upgrade_cli.rb b/lib/mastodon/cli/upgrade.rb similarity index 74% rename from lib/mastodon/upgrade_cli.rb rename to lib/mastodon/cli/upgrade.rb index 570b7e6fa8..cf83986844 100644 --- a/lib/mastodon/upgrade_cli.rb +++ b/lib/mastodon/cli/upgrade.rb @@ -1,17 +1,9 @@ # frozen_string_literal: true -require_relative '../../config/boot' -require_relative '../../config/environment' -require_relative 'cli_helper' - -module Mastodon - class UpgradeCLI < Thor - include CLIHelper - - def self.exit_on_failure? - true - end +require_relative 'base' +module Mastodon::CLI + class Upgrade < Base CURRENT_STORAGE_SCHEMA_VERSION = 1 option :dry_run, type: :boolean, default: false @@ -25,7 +17,6 @@ module Mastodon LONG_DESC def storage_schema progress = create_progress_bar(nil) - dry_run = dry_run? ? ' (DRY RUN)' : '' records = 0 klasses = [ @@ -50,16 +41,16 @@ module Mastodon styles << :original unless styles.include?(:original) styles.each do |style| - success = begin - case Paperclip::Attachment.default_options[:storage] - when :s3 - upgrade_storage_s3(progress, attachment, style) - when :fog - upgrade_storage_fog(progress, attachment, style) - when :filesystem - upgrade_storage_filesystem(progress, attachment, style) - end - end + success = case Paperclip::Attachment.default_options[:storage] + when :s3 + upgrade_storage_s3(progress, attachment, style) + when :fog + upgrade_storage_fog(progress, attachment, style) + when :azure + upgrade_storage_azure(progress, attachment, style) + when :filesystem + upgrade_storage_filesystem(progress, attachment, style) + end upgraded = true if style == :original && success @@ -79,7 +70,7 @@ module Mastodon progress.total = progress.progress progress.finish - say("Upgraded storage schema of #{records} records#{dry_run}", :green, true) + say("Upgraded storage schema of #{records} records#{dry_run_mode_suffix}", :green, true) end private @@ -116,6 +107,11 @@ module Mastodon exit(1) end + def upgrade_storage_azure(_progress, _attachment, _style) + say('The azure storage driver is not supported for this operation at this time', :red) + exit(1) + end + def upgrade_storage_filesystem(progress, attachment, style) previous_storage_schema_version = attachment.storage_schema_version previous_path = attachment.path(style) @@ -129,27 +125,12 @@ module Mastodon progress.log("Moving #{previous_path} to #{upgraded_path}") if options[:verbose] begin - unless dry_run? - FileUtils.mkdir_p(File.dirname(upgraded_path)) - FileUtils.mv(previous_path, upgraded_path) - - begin - FileUtils.rmdir(File.dirname(previous_path), parents: true) - rescue Errno::ENOTEMPTY - # OK - end - end + move_previous_to_upgraded rescue => e progress.log(pastel.red("Error processing #{previous_path}: #{e}")) success = false - unless dry_run? - begin - FileUtils.rmdir(File.dirname(upgraded_path), parents: true) - rescue Errno::ENOTEMPTY - # OK - end - end + remove_directory end end @@ -159,5 +140,28 @@ module Mastodon attachment.instance_write(:storage_schema_version, previous_storage_schema_version) success end + + def move_previous_to_upgraded(previous_path, upgraded_path) + return if dry_run? + + FileUtils.mkdir_p(File.dirname(upgraded_path)) + FileUtils.mv(previous_path, upgraded_path) + + begin + FileUtils.rmdir(File.dirname(previous_path), parents: true) + rescue Errno::ENOTEMPTY + # OK + end + end + + def remove_directory(path) + return if dry_run? + + begin + FileUtils.rmdir(File.dirname(path), parents: true) + rescue Errno::ENOTEMPTY + # OK + end + end end end diff --git a/lib/mastodon/cli_helper.rb b/lib/mastodon/cli_helper.rb deleted file mode 100644 index 4e304c9035..0000000000 --- a/lib/mastodon/cli_helper.rb +++ /dev/null @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -dev_null = Logger.new('/dev/null') - -Rails.logger = dev_null -ActiveRecord::Base.logger = dev_null -ActiveJob::Base.logger = dev_null -HttpLog.configuration.logger = dev_null -Paperclip.options[:log] = false -Chewy.logger = dev_null - -module Mastodon - module CLIHelper - def dry_run? - options[:dry_run] - end - - def create_progress_bar(total = nil) - ProgressBar.create(total: total, format: '%c/%u |%b%i| %e') - end - - def reset_connection_pools! - ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[Rails.env].dup.tap { |config| config['pool'] = options[:concurrency] + 1 }) - RedisConfiguration.establish_pool(options[:concurrency]) - end - - def parallelize_with_progress(scope) - if options[:concurrency] < 1 - say('Cannot run with this concurrency setting, must be at least 1', :red) - exit(1) - end - - reset_connection_pools! - - progress = create_progress_bar(scope.count) - pool = Concurrent::FixedThreadPool.new(options[:concurrency]) - total = Concurrent::AtomicFixnum.new(0) - aggregate = Concurrent::AtomicFixnum.new(0) - - scope.reorder(nil).find_in_batches do |items| - futures = [] - - items.each do |item| - futures << Concurrent::Future.execute(executor: pool) do - begin - if !progress.total.nil? && progress.progress + 1 > progress.total - # The number of items has changed between start and now, - # since there is no good way to predict the final count from - # here, just change the progress bar to an indeterminate one - - progress.total = nil - end - - progress.log("Processing #{item.id}") if options[:verbose] - - Chewy.strategy(:mastodon) do - result = ActiveRecord::Base.connection_pool.with_connection do - yield(item) - ensure - RedisConfiguration.pool.checkin if Thread.current[:redis] - Thread.current[:redis] = nil - end - - aggregate.increment(result) if result.is_a?(Integer) - end - rescue => e - progress.log pastel.red("Error processing #{item.id}: #{e}") - ensure - progress.increment - end - end - end - - total.increment(items.size) - futures.map(&:value) - end - - progress.stop - - [total.value, aggregate.value] - end - - def pastel - @pastel ||= Pastel.new - end - end -end diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index 2ab8150ec9..a92a8767ce 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -37,7 +37,6 @@ # This is bad form, but there are enough differences that it's impractical to do # otherwise: -# rubocop:disable all module Mastodon module MigrationHelpers @@ -195,7 +194,14 @@ module Mastodon def supports_drop_index_concurrently? version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i - version >= 90200 + version >= 90_200 + end + + # Only available on Postgresql >= 11 + def supports_add_column_with_default? + version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i + + version >= 110_000 end # Adds a foreign key with only minimal locking on the tables involved. @@ -289,8 +295,6 @@ module Mastodon # determines this method to be too complex while there's no way to make it # less "complex" without introducing extra methods (which actually will # make things _more_ complex). - # - # rubocop: disable Metrics/AbcSize def update_column_in_batches(table_name, column, value) if transaction_open? raise 'update_column_in_batches can not be run inside a transaction, ' \ @@ -416,6 +420,11 @@ module Mastodon # This method can also take a block which is passed directly to the # `update_column_in_batches` method. def add_column_with_default(table, column, type, default:, limit: nil, allow_null: false, &block) + if supports_add_column_with_default? + add_column(table, column, type, default: default, limit: limit, null: allow_null) + return + end + if transaction_open? raise 'add_column_with_default can not be run inside a transaction, ' \ 'you can disable transactions by calling disable_ddl_transaction! ' \ @@ -573,7 +582,7 @@ module Mastodon o.conname as name, o.confdeltype as on_delete from pg_constraint o - left join pg_class f on f.oid = o.confrelid + left join pg_class f on f.oid = o.confrelid left join pg_class c on c.oid = o.conrelid left join pg_class m on m.oid = o.conrelid where o.contype = 'f' @@ -979,5 +988,3 @@ into similar problems in the future (e.g. when new tables are created). end end end - -# rubocop:enable all diff --git a/lib/mastodon/migration_warning.rb b/lib/mastodon/migration_warning.rb new file mode 100644 index 0000000000..227f6705d3 --- /dev/null +++ b/lib/mastodon/migration_warning.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Mastodon + module MigrationWarning + WARNING_SECONDS = 10 + + DEFAULT_WARNING = <<~WARNING_MESSAGE + WARNING: This migration may take a *long* time for large instances. + It will *not* lock tables for any significant time, but it may run + for a very long time. We will pause for #{WARNING_SECONDS} seconds to allow you to + interrupt this migration if you are not ready. + WARNING_MESSAGE + + def migration_duration_warning(explanation = nil) + return unless valid_environment? + + announce_warning(explanation) + + announce_countdown + end + + private + + def announce_countdown + WARNING_SECONDS.downto(1) do |i| + say "Continuing in #{i} second#{i == 1 ? '' : 's'}...", true + sleep 1 + end + end + + def valid_environment? + $stdout.isatty && Rails.env.production? + end + + def announce_warning(explanation) + announce_message prepare_message(explanation) + end + + def announce_message(text) + say '' + text.each_line do |line| + say(line) + end + say '' + end + + def prepare_message(explanation) + if explanation.blank? + DEFAULT_WARNING + else + DEFAULT_WARNING + "\n#{explanation}" + end + end + end +end diff --git a/lib/mastodon/premailer_webpack_strategy.rb b/lib/mastodon/premailer_webpack_strategy.rb index 4356b7285a..6816d04745 100644 --- a/lib/mastodon/premailer_webpack_strategy.rb +++ b/lib/mastodon/premailer_webpack_strategy.rb @@ -12,11 +12,11 @@ module PremailerWebpackStrategy css = if url.start_with?('http') HTTP.get(url).to_s else - url = url[1..-1] if url.start_with?('/') - File.read(Rails.public_path.join(url)) + url = url[1..] if url.start_with?('/') + Rails.public_path.join(url).read end - css.gsub(/url\(\//, "url(#{asset_host}/") + css.gsub(%r{url\(/}, "url(#{asset_host}/") end module_function :load diff --git a/lib/mastodon/redis_config.rb b/lib/mastodon/redis_config.rb index 3522fa11e3..2dbe76f83c 100644 --- a/lib/mastodon/redis_config.rb +++ b/lib/mastodon/redis_config.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true def setup_redis_env_url(prefix = nil, defaults = true) - prefix = prefix.to_s.upcase + '_' unless prefix.nil? + prefix = "#{prefix.to_s.upcase}_" unless prefix.nil? prefix = '' if prefix.nil? - return if ENV[prefix + 'REDIS_URL'].present? + return if ENV["#{prefix}REDIS_URL"].present? - password = ENV.fetch(prefix + 'REDIS_PASSWORD') { '' if defaults } - host = ENV.fetch(prefix + 'REDIS_HOST') { 'localhost' if defaults } - port = ENV.fetch(prefix + 'REDIS_PORT') { 6379 if defaults } - db = ENV.fetch(prefix + 'REDIS_DB') { 0 if defaults } + password = ENV.fetch("#{prefix}REDIS_PASSWORD") { '' if defaults } + host = ENV.fetch("#{prefix}REDIS_HOST") { 'localhost' if defaults } + port = ENV.fetch("#{prefix}REDIS_PORT") { 6379 if defaults } + db = ENV.fetch("#{prefix}REDIS_DB") { 0 if defaults } - ENV[prefix + 'REDIS_URL'] = begin + ENV["#{prefix}REDIS_URL"] = begin if [password, host, port, db].all?(&:nil?) ENV['REDIS_URL'] else @@ -27,7 +27,7 @@ setup_redis_env_url(:cache, false) setup_redis_env_url(:sidekiq, false) namespace = ENV.fetch('REDIS_NAMESPACE', nil) -cache_namespace = namespace ? namespace + '_cache' : 'cache' +cache_namespace = namespace ? "#{namespace}_cache" : 'cache' sidekiq_namespace = namespace REDIS_CACHE_PARAMS = { @@ -35,7 +35,7 @@ REDIS_CACHE_PARAMS = { url: ENV['CACHE_REDIS_URL'], expires_in: 10.minutes, namespace: cache_namespace, - pool_size: Sidekiq.server? ? Sidekiq.options[:concurrency] : Integer(ENV['MAX_THREADS'] || 5), + pool_size: Sidekiq.server? ? Sidekiq[:concurrency] : Integer(ENV['MAX_THREADS'] || 5), pool_timeout: 5, connect_timeout: 5, }.freeze @@ -46,6 +46,4 @@ REDIS_SIDEKIQ_PARAMS = { namespace: sidekiq_namespace, }.freeze -if Rails.env.test? - ENV['REDIS_NAMESPACE'] = "mastodon_test#{ENV['TEST_ENV_NUMBER']}" -end +ENV['REDIS_NAMESPACE'] = "mastodon_test#{ENV['TEST_ENV_NUMBER']}" if Rails.env.test? diff --git a/lib/mastodon/sidekiq_middleware.rb b/lib/mastodon/sidekiq_middleware.rb index 9832e1a27c..3a747afb63 100644 --- a/lib/mastodon/sidekiq_middleware.rb +++ b/lib/mastodon/sidekiq_middleware.rb @@ -16,7 +16,7 @@ class Mastodon::SidekiqMiddleware private def limit_backtrace_and_raise(exception) - exception.set_backtrace(exception.backtrace.first(BACKTRACE_LIMIT)) + exception.set_backtrace(exception.backtrace.first(BACKTRACE_LIMIT)) unless ENV['BACKTRACE'] raise exception end diff --git a/lib/mastodon/snowflake.rb b/lib/mastodon/snowflake.rb index fe0dc1722e..0a596b2940 100644 --- a/lib/mastodon/snowflake.rb +++ b/lib/mastodon/snowflake.rb @@ -64,46 +64,7 @@ module Mastodon::Snowflake def define_timestamp_id return if already_defined? - connection.execute(<<~SQL) - CREATE OR REPLACE FUNCTION timestamp_id(table_name text) - RETURNS bigint AS - $$ - DECLARE - time_part bigint; - sequence_base bigint; - tail bigint; - BEGIN - time_part := ( - -- Get the time in milliseconds - ((date_part('epoch', now()) * 1000))::bigint - -- And shift it over two bytes - << 16); - - sequence_base := ( - 'x' || - -- Take the first two bytes (four hex characters) - substr( - -- Of the MD5 hash of the data we documented - md5(table_name || '#{SecureRandom.hex(16)}' || time_part::text), - 1, 4 - ) - -- And turn it into a bigint - )::bit(16)::bigint; - - -- Finally, add our sequence number to our base, and chop - -- it to the last two bytes - tail := ( - (sequence_base + nextval(table_name || '_id_seq')) - & 65535); - - -- Return the time part and the sequence part. OR appears - -- faster here than addition, but they're equivalent: - -- time_part has no trailing two bytes, and tail is only - -- the last two bytes. - RETURN time_part | tail; - END - $$ LANGUAGE plpgsql VOLATILE; - SQL + connection.execute(sanitized_timestamp_id_sql) end def ensure_id_sequences_exist @@ -115,7 +76,7 @@ module Mastodon::Snowflake # And only those that are using timestamp_id. next unless (data = DEFAULT_REGEX.match(id_col.default_function)) - seq_name = data[:seq_prefix] + '_id_seq' + seq_name = "#{data[:seq_prefix]}_id_seq" # If we were on Postgres 9.5+, we could do CREATE SEQUENCE IF # NOT EXISTS, but we can't depend on that. Instead, catch the @@ -143,16 +104,71 @@ module Mastodon::Snowflake id end + def to_time(id) + Time.at((id >> 16) / 1000).utc + end + private def already_defined? - connection.execute(<<~SQL).values.first.first + connection.execute(<<~SQL.squish).values.first.first SELECT EXISTS( SELECT * FROM pg_proc WHERE proname = 'timestamp_id' ); SQL end + def sanitized_timestamp_id_sql + ActiveRecord::Base.sanitize_sql_array(timestamp_id_sql_array) + end + + def timestamp_id_sql_array + [timestamp_id_sql_string, { random_string: SecureRandom.hex(16) }] + end + + def timestamp_id_sql_string + <<~SQL + CREATE OR REPLACE FUNCTION timestamp_id(table_name text) + RETURNS bigint AS + $$ + DECLARE + time_part bigint; + sequence_base bigint; + tail bigint; + BEGIN + time_part := ( + -- Get the time in milliseconds + ((date_part('epoch', now()) * 1000))::bigint + -- And shift it over two bytes + << 16); + + sequence_base := ( + 'x' || + -- Take the first two bytes (four hex characters) + substr( + -- Of the MD5 hash of the data we documented + md5(table_name || :random_string || time_part::text), + 1, 4 + ) + -- And turn it into a bigint + )::bit(16)::bigint; + + -- Finally, add our sequence number to our base, and chop + -- it to the last two bytes + tail := ( + (sequence_base + nextval(table_name || '_id_seq')) + & 65535); + + -- Return the time part and the sequence part. OR appears + -- faster here than addition, but they're equivalent: + -- time_part has no trailing two bytes, and tail is only + -- the last two bytes. + RETURN time_part | tail; + END + $$ LANGUAGE plpgsql VOLATILE; + SQL + end + def connection ActiveRecord::Base.connection end diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 9a8d5ec881..3761679109 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,19 +9,23 @@ module Mastodon end def minor - 1 + 3 end def patch 3 end - def flags - '' + def default_prerelease + 'alpha.0' end - def suffix - '' + def prerelease + ENV['MASTODON_VERSION_PRERELEASE'].presence || default_prerelease + end + + def build_metadata + ['glitch', ENV.fetch('MASTODON_VERSION_METADATA', nil)].compact_blank.join('.') end def to_a @@ -29,11 +33,18 @@ module Mastodon end def to_s - [to_a.join('.'), flags, suffix].join + components = [to_a.join('.')] + components << "-#{prerelease}" if prerelease.present? + components << "+#{build_metadata}" if build_metadata.present? + components.join + end + + def gem_version + @gem_version ||= Gem::Version.new(to_s.split('+')[0]) end def repository - ENV.fetch('GITHUB_REPOSITORY', 'mastodon/mastodon') + ENV.fetch('GITHUB_REPOSITORY', 'glitch-soc/mastodon') end def source_base_url diff --git a/lib/paperclip/attachment_extensions.rb b/lib/paperclip/attachment_extensions.rb index d66a176235..7f82138aa8 100644 --- a/lib/paperclip/attachment_extensions.rb +++ b/lib/paperclip/attachment_extensions.rb @@ -8,7 +8,7 @@ module Paperclip # monkey-patch to avoid unlinking too avoid unlinking source file too early # see https://github.com/kreeti/kt-paperclip/issues/64 - def post_process_style(name, style) #:nodoc: + def post_process_style(name, style) # :nodoc: raise "Style #{name} has no processors defined." if style.processors.blank? intermediate_files = [] @@ -16,16 +16,16 @@ module Paperclip # if we're processing the original, close + unlink the source tempfile intermediate_files << original if name == :original - @queued_for_write[name] = style.processors. - inject(original) do |file, processor| + @queued_for_write[name] = style.processors + .inject(original) do |file, processor| file = Paperclip.processor(processor).make(file, style.processor_options, self) intermediate_files << file unless file == original file end unadapted_file = @queued_for_write[name] - @queued_for_write[name] = Paperclip.io_adapters. - for(@queued_for_write[name], @options[:adapter_options]) + @queued_for_write[name] = Paperclip.io_adapters + .for(@queued_for_write[name], @options[:adapter_options]) unadapted_file.close if unadapted_file.respond_to?(:close) @queued_for_write[name] rescue Paperclip::Errors::NotIdentifiedByImageMagickError => e diff --git a/lib/paperclip/color_extractor.rb b/lib/paperclip/color_extractor.rb index d3b8e10229..d2f7e7c602 100644 --- a/lib/paperclip/color_extractor.rb +++ b/lib/paperclip/color_extractor.rb @@ -79,8 +79,8 @@ module Paperclip private def w3c_contrast(color1, color2) - luminance1 = color1.to_xyz.y * 0.01 + 0.05 - luminance2 = color2.to_xyz.y * 0.01 + 0.05 + luminance1 = (color1.to_xyz.y * 0.01) + 0.05 + luminance2 = (color2.to_xyz.y * 0.01) + 0.05 if luminance1 > luminance2 luminance1 / luminance2 @@ -109,11 +109,11 @@ module Paperclip case max when r - h = (g - b) / d + (g < b ? 6.0 : 0) + h = ((g - b) / d) + (g < b ? 6.0 : 0) when g - h = (b - r) / d + 2.0 + h = ((b - r) / d) + 2.0 when b - h = (r - g) / d + 4.0 + h = ((r - g) / d) + 4.0 end h /= 6.0 @@ -126,9 +126,9 @@ module Paperclip t += 1 if t.negative? t -= 1 if t > 1 - return (p + (q - p) * 6 * t) if t < 1 / 6.0 + return (p + ((q - p) * 6 * t)) if t < 1 / 6.0 return q if t < 1 / 2.0 - return (p + (q - p) * (2 / 3.0 - t) * 6) if t < 2 / 3.0 + return (p + ((q - p) * ((2 / 3.0) - t) * 6)) if t < 2 / 3.0 p end @@ -147,11 +147,11 @@ module Paperclip g = l.to_f b = l.to_f # achromatic else - q = l < 0.5 ? l * (s + 1) : l + s - l * s - p = 2 * l - q - r = hue_to_rgb(p, q, h + 1 / 3.0) + q = l < 0.5 ? l * (s + 1) : l + s - (l * s) + p = (2 * l) - q + r = hue_to_rgb(p, q, h + (1 / 3.0)) g = hue_to_rgb(p, q, h) - b = hue_to_rgb(p, q, h - 1 / 3.0) + b = hue_to_rgb(p, q, h - (1 / 3.0)) end [(r * 255).round, (g * 255).round, (b * 255).round] @@ -161,21 +161,19 @@ module Paperclip def lighten_or_darken(color, by) hue, saturation, light = rgb_to_hsl(color.r, color.g, color.b) - light = begin - if light < 50 - [100, light + by].min - else - [0, light - by].max - end - end + light = if light < 50 + [100, light + by].min + else + [0, light - by].max + end ColorDiff::Color::RGB.new(*hsl_to_rgb(hue, saturation, light)) end def palette_from_histogram(result, quantity) - frequencies = result.scan(/([0-9]+)\:/).flatten.map(&:to_f) + frequencies = result.scan(/([0-9]+):/).flatten.map(&:to_f) hex_values = result.scan(/\#([0-9A-Fa-f]{6,8})/).flatten - total_frequencies = frequencies.reduce(&:+).to_f + total_frequencies = frequencies.sum.to_f frequencies.map.with_index { |f, i| [f / total_frequencies, hex_values[i]] } .sort_by { |r| -r[0] } @@ -185,7 +183,7 @@ module Paperclip end def rgb_to_hex(rgb) - '#%02x%02x%02x' % [rgb.r, rgb.g, rgb.b] + format('#%02x%02x%02x', rgb.r, rgb.g, rgb.b) end end end diff --git a/lib/paperclip/gif_transcoder.rb b/lib/paperclip/gif_transcoder.rb index d14465c018..32bdb8a863 100644 --- a/lib/paperclip/gif_transcoder.rb +++ b/lib/paperclip/gif_transcoder.rb @@ -57,7 +57,7 @@ class GifReader end # Skip lzw min code size - raise InvalidValue unless s.read(1).unpack('C')[0] >= 2 + raise InvalidValue unless s.read(1).unpack1('C') >= 2 # Skip image data sub-blocks skip_sub_blocks!(s) @@ -77,7 +77,7 @@ class GifReader private def skip_extension_block!(file) - if EXTENSION_LABELS.include?(file.read(1).unpack('C')[0]) + if EXTENSION_LABELS.include?(file.read(1).unpack1('C')) block_size, = file.read(1).unpack('C') file.seek(block_size, IO::SEEK_CUR) end @@ -109,7 +109,7 @@ module Paperclip final_file = Paperclip::Transcoder.make(file, options, attachment) if options[:style] == :original - attachment.instance.file_file_name = File.basename(attachment.instance.file_file_name, '.*') + '.mp4' + attachment.instance.file_file_name = "#{File.basename(attachment.instance.file_file_name, '.*')}.mp4" attachment.instance.file_content_type = 'video/mp4' attachment.instance.type = MediaAttachment.types[:gifv] end diff --git a/lib/paperclip/media_type_spoof_detector_extensions.rb b/lib/paperclip/media_type_spoof_detector_extensions.rb index a406ef312f..c8868d5e95 100644 --- a/lib/paperclip/media_type_spoof_detector_extensions.rb +++ b/lib/paperclip/media_type_spoof_detector_extensions.rb @@ -2,13 +2,15 @@ module Paperclip module MediaTypeSpoofDetectorExtensions + MARCEL_MIME_TYPES = %w(audio/mpeg image/avif).freeze + def calculated_content_type return @calculated_content_type if defined?(@calculated_content_type) @calculated_content_type = type_from_file_command.chomp # The `file` command fails to recognize some MP3 files as such - @calculated_content_type = type_from_marcel if @calculated_content_type == 'application/octet-stream' && type_from_marcel == 'audio/mpeg' + @calculated_content_type = type_from_marcel if @calculated_content_type == 'application/octet-stream' && type_from_marcel.in?(MARCEL_MIME_TYPES) @calculated_content_type end diff --git a/lib/paperclip/transcoder.rb b/lib/paperclip/transcoder.rb index be40b49241..d2d946d3ad 100644 --- a/lib/paperclip/transcoder.rb +++ b/lib/paperclip/transcoder.rb @@ -4,6 +4,9 @@ module Paperclip # This transcoder is only to be used for the MediaAttachment model # to check when uploaded videos are actually gifv's class Transcoder < Paperclip::Processor + # This is the H.264 "High" value taken from https://www.dr-lex.be/info-stuff/videocalc.html + BITS_PER_PIXEL = 0.11 + def initialize(file, options = {}, attachment = nil) super @@ -37,12 +40,21 @@ module Paperclip @output_options['f'] = 'image2' @output_options['vframes'] = 1 when 'mp4' - @output_options['acodec'] = 'aac' - @output_options['strict'] = 'experimental' + unless eligible_to_passthrough?(metadata) + size_limit_in_bits = MediaAttachment::VIDEO_LIMIT * 8 + desired_bitrate = (metadata.width * metadata.height * 30 * BITS_PER_PIXEL).floor + duration = [metadata.duration, 1].max + maximum_bitrate = (size_limit_in_bits / duration).floor - 192_000 # Leave some space for the audio stream + bitrate = [desired_bitrate, maximum_bitrate].min - if high_vfr?(metadata) && !eligible_to_passthrough?(metadata) - @output_options['vsync'] = 'vfr' - @output_options['r'] = @vfr_threshold + @output_options['b:v'] = bitrate + @output_options['maxrate'] = bitrate + 192_000 + @output_options['bufsize'] = bitrate * 5 + + if high_vfr?(metadata) + @output_options['vsync'] = 'vfr' + @output_options['r'] = @vfr_threshold + end end end diff --git a/lib/paperclip/type_corrector.rb b/lib/paperclip/type_corrector.rb index 17e2fc5daa..030b98b122 100644 --- a/lib/paperclip/type_corrector.rb +++ b/lib/paperclip/type_corrector.rb @@ -7,7 +7,7 @@ module Paperclip def make return @file unless options[:format] - target_extension = '.' + options[:format] + target_extension = ".#{options[:format]}" extension = File.extname(attachment.instance_read(:file_name)) return @file unless options[:style] == :original && target_extension && extension != target_extension diff --git a/lib/rails/engine_extensions.rb b/lib/rails/engine_extensions.rb index 4e3767db9e..68535570d4 100644 --- a/lib/rails/engine_extensions.rb +++ b/lib/rails/engine_extensions.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + module Rails module EngineExtensions # Rewrite task loading code to filter digitalocean.rake task def run_tasks_blocks(app) Railtie.instance_method(:run_tasks_blocks).bind_call(self, app) - paths["lib/tasks"].existent.reject { |ext| ext.end_with?('digitalocean.rake') }.sort.each { |ext| load(ext) } + paths['lib/tasks'].existent.reject { |ext| ext.end_with?('digitalocean.rake') }.sort.each { |ext| load(ext) } end end end diff --git a/lib/redis/namespace_extensions.rb b/lib/redis/namespace_extensions.rb index 310a4f465b..9af59c296e 100644 --- a/lib/redis/namespace_extensions.rb +++ b/lib/redis/namespace_extensions.rb @@ -2,8 +2,8 @@ class Redis module NamespaceExtensions - def exists?(*args, &block) - call_with_namespace('exists?', *args, &block) + def exists?(...) + call_with_namespace('exists?', ...) end end end diff --git a/lib/sanitize_ext/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb index 703ba8b059..53508d3e45 100644 --- a/lib/sanitize_ext/sanitize_config.rb +++ b/lib/sanitize_ext/sanitize_config.rb @@ -36,46 +36,54 @@ class Sanitize node['class'] = class_list.join(' ') end + IMG_TAG_TRANSFORMER = lambda do |env| + node = env[:node] + + return unless env[:node_name] == 'img' + + node.name = 'a' + + node['href'] = node['src'] + if node['alt'].present? + node.content = "[🖼 #{node['alt']}]" + else + url = node['href'] + prefix = url.match(%r{\Ahttps?://(www\.)?}).to_s + text = url[prefix.length, 30] + text += '…' if url.length - prefix.length > 30 + node.content = "[🖼 #{text}]" + end + end + + TRANSLATE_TRANSFORMER = lambda do |env| + node = env[:node] + node.remove_attribute('translate') unless node['translate'] == 'no' + end + UNSUPPORTED_HREF_TRANSFORMER = lambda do |env| return unless env[:node_name] == 'a' current_node = env[:node] - scheme = begin - if current_node['href'] =~ Sanitize::REGEX_PROTOCOL - Regexp.last_match(1).downcase - else - :relative - end - end + scheme = if current_node['href'] =~ Sanitize::REGEX_PROTOCOL + Regexp.last_match(1).downcase + else + :relative + end current_node.replace(Nokogiri::XML::Text.new(current_node.text, current_node.document)) unless LINK_PROTOCOLS.include?(scheme) end - UNSUPPORTED_ELEMENTS_TRANSFORMER = lambda do |env| - return unless %w(h1 h2 h3 h4 h5 h6 blockquote pre ul ol li).include?(env[:node_name]) - - current_node = env[:node] - - case env[:node_name] - when 'li' - current_node.traverse do |node| - next unless %w(p ul ol li).include?(node.name) - - node.add_next_sibling('
') if node.next_sibling - node.replace(node.children) unless node.text? - end - else - current_node.name = 'p' - end - end - MASTODON_STRICT ||= freeze_config( - elements: %w(p br span a), + elements: %w(p br span a abbr del pre blockquote code b strong u sub sup i em h1 h2 h3 h4 h5 ul ol li), attributes: { - 'a' => %w(href rel class), - 'span' => %w(class), + 'a' => %w(href rel class title translate), + 'abbr' => %w(title), + 'span' => %w(class translate), + 'blockquote' => %w(cite), + 'ol' => %w(start reversed), + 'li' => %w(value), }, add_attributes: { @@ -85,11 +93,15 @@ class Sanitize }, }, - protocols: {}, + protocols: { + 'a' => { 'href' => LINK_PROTOCOLS }, + 'blockquote' => { 'cite' => LINK_PROTOCOLS }, + }, transformers: [ CLASS_WHITELIST_TRANSFORMER, - UNSUPPORTED_ELEMENTS_TRANSFORMER, + IMG_TAG_TRANSFORMER, + TRANSLATE_TRANSFORMER, UNSUPPORTED_HREF_TRANSFORMER, ] ) @@ -98,15 +110,15 @@ class Sanitize elements: %w(audio embed iframe source video), attributes: { - 'audio' => %w(controls), - 'embed' => %w(height src type width), + 'audio' => %w(controls), + 'embed' => %w(height src type width), 'iframe' => %w(allowfullscreen frameborder height scrolling src width), 'source' => %w(src type), - 'video' => %w(controls height loop width), + 'video' => %w(controls height loop width), }, protocols: { - 'embed' => { 'src' => HTTP_PROTOCOLS }, + 'embed' => { 'src' => HTTP_PROTOCOLS }, 'iframe' => { 'src' => HTTP_PROTOCOLS }, 'source' => { 'src' => HTTP_PROTOCOLS }, }, @@ -115,5 +127,49 @@ class Sanitize 'iframe' => { 'sandbox' => 'allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-forms' }, } ) + + LINK_REL_TRANSFORMER = lambda do |env| + return unless env[:node_name] == 'a' && env[:node]['href'] + + node = env[:node] + + rel = (node['rel'] || '').split & ['tag'] + rel += %w(nofollow noopener noreferrer) unless TagManager.instance.local_url?(node['href']) + + if rel.empty? + node.remove_attribute('rel') + else + node['rel'] = rel.join(' ') + end + end + + LINK_TARGET_TRANSFORMER = lambda do |env| + return unless env[:node_name] == 'a' && env[:node]['href'] + + node = env[:node] + if node['target'] != '_blank' && TagManager.instance.local_url?(node['href']) + node.remove_attribute('target') + else + node['target'] = '_blank' + end + end + + MASTODON_OUTGOING ||= freeze_config MASTODON_STRICT.merge( + attributes: merge( + MASTODON_STRICT[:attributes], + 'a' => %w(href rel class title target translate) + ), + + add_attributes: {}, + + transformers: [ + CLASS_WHITELIST_TRANSFORMER, + IMG_TAG_TRANSFORMER, + TRANSLATE_TRANSFORMER, + UNSUPPORTED_HREF_TRANSFORMER, + LINK_REL_TRANSFORMER, + LINK_TARGET_TRANSFORMER, + ] + ) end end diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 1d2270572e..76e190f70a 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -1,13 +1,19 @@ # frozen_string_literal: true -def render_static_page(action, dest:, **opts) - html = ApplicationController.render(action, opts) - File.write(dest, html) -end - namespace :assets do desc 'Generate static pages' task generate_static_pages: :environment do + def render_static_page(action, dest:, **opts) + renderer = Class.new(ApplicationController) do + def current_user + nil + end + end + + html = renderer.render(action, opts) + File.write(dest, html) + end + render_static_page 'errors/500', layout: 'error', dest: Rails.public_path.join('assets', '500.html') end end diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake index a374e33ad2..4b5997920a 100644 --- a/lib/tasks/auto_annotate_models.rake +++ b/lib/tasks/auto_annotate_models.rake @@ -3,42 +3,42 @@ if Rails.env.development? task :set_annotation_options do Annotate.set_defaults( - 'routes' => 'false', - 'models' => 'true', - 'position_in_routes' => 'before', - 'position_in_class' => 'before', - 'position_in_test' => 'before', - 'position_in_fixture' => 'before', - 'position_in_factory' => 'before', - 'position_in_serializer' => 'before', - 'show_foreign_keys' => 'false', - 'show_indexes' => 'false', - 'simple_indexes' => 'false', - 'model_dir' => 'app/models', - 'root_dir' => '', - 'include_version' => 'false', - 'require' => '', - 'exclude_tests' => 'true', - 'exclude_fixtures' => 'true', - 'exclude_factories' => 'true', - 'exclude_serializers' => 'true', - 'exclude_scaffolds' => 'true', - 'exclude_controllers' => 'true', - 'exclude_helpers' => 'true', - 'ignore_model_sub_dir' => 'false', - 'ignore_columns' => nil, - 'ignore_routes' => nil, - 'ignore_unknown_models' => 'false', + 'routes' => 'false', + 'models' => 'true', + 'position_in_routes' => 'before', + 'position_in_class' => 'before', + 'position_in_test' => 'before', + 'position_in_fixture' => 'before', + 'position_in_factory' => 'before', + 'position_in_serializer' => 'before', + 'show_foreign_keys' => 'false', + 'show_indexes' => 'false', + 'simple_indexes' => 'false', + 'model_dir' => 'app/models', + 'root_dir' => '', + 'include_version' => 'false', + 'require' => '', + 'exclude_tests' => 'true', + 'exclude_fixtures' => 'true', + 'exclude_factories' => 'true', + 'exclude_serializers' => 'true', + 'exclude_scaffolds' => 'true', + 'exclude_controllers' => 'true', + 'exclude_helpers' => 'true', + 'ignore_model_sub_dir' => 'false', + 'ignore_columns' => nil, + 'ignore_routes' => nil, + 'ignore_unknown_models' => 'false', 'hide_limit_column_types' => 'integer,boolean', - 'skip_on_db_migrate' => 'false', - 'format_bare' => 'true', - 'format_rdoc' => 'false', - 'format_markdown' => 'false', - 'sort' => 'false', - 'force' => 'false', - 'trace' => 'false', - 'wrapper_open' => nil, - 'wrapper_close' => nil + 'skip_on_db_migrate' => 'false', + 'format_bare' => 'true', + 'format_rdoc' => 'false', + 'format_markdown' => 'false', + 'sort' => 'false', + 'force' => 'false', + 'trace' => 'false', + 'wrapper_open' => nil, + 'wrapper_close' => nil ) end diff --git a/lib/tasks/branding.rake b/lib/tasks/branding.rake index d1c1c9dede..608fb3af9c 100644 --- a/lib/tasks/branding.rake +++ b/lib/tasks/branding.rake @@ -1,3 +1,5 @@ +# frozen_string_literal: true + namespace :branding do desc 'Generate necessary graphic assets for branding from source SVG files' task generate: :environment do @@ -40,7 +42,7 @@ namespace :branding do output_dest = Rails.root.join('app', 'javascript', 'icons') rsvg_convert = Terrapin::CommandLine.new('rsvg-convert', '-w :size -h :size --keep-aspect-ratio :input -o :output') - convert = Terrapin::CommandLine.new('convert', ':input :output') + convert = Terrapin::CommandLine.new('convert', ':input :output', environment: { 'MAGICK_CONFIGURE_PATH' => nil }) favicon_sizes = [16, 32, 48] apple_icon_sizes = [57, 60, 72, 76, 114, 120, 144, 152, 167, 180, 1024] diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index ca939fd1f0..e8a64b8fb2 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -4,16 +4,14 @@ namespace :db do namespace :migrate do desc 'Setup the db or migrate depending on state of db' task setup: :environment do - begin - if ActiveRecord::Migrator.current_version.zero? - Rake::Task['db:migrate'].invoke - Rake::Task['db:seed'].invoke - end - rescue ActiveRecord::NoDatabaseError - Rake::Task['db:setup'].invoke - else + if ActiveRecord::Migrator.current_version.zero? Rake::Task['db:migrate'].invoke + Rake::Task['db:seed'].invoke end + rescue ActiveRecord::NoDatabaseError + Rake::Task['db:setup'].invoke + else + Rake::Task['db:migrate'].invoke end end diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake index 02d772b488..c24ea42e7d 100644 --- a/lib/tasks/emojis.rake +++ b/lib/tasks/emojis.rake @@ -6,7 +6,7 @@ def gen_border(codepoint, color) doc = File.open(input) { |f| Nokogiri::XML(f) } svg = doc.at_css('svg') if svg.key?('viewBox') - view_box = svg['viewBox'].split(' ').map(&:to_i) + view_box = svg['viewBox'].split.map(&:to_i) view_box[0] -= 2 view_box[1] -= 2 view_box[2] += 4 @@ -31,12 +31,12 @@ def gen_border(codepoint, color) end def codepoints_to_filename(codepoints) - codepoints.downcase.gsub(/\A[0]+/, '').tr(' ', '-') + codepoints.downcase.gsub(/\A0+/, '').tr(' ', '-') end def codepoints_to_unicode(codepoints) if codepoints.include?(' ') - codepoints.split(' ').map(&:hex).pack('U*') + codepoints.split.map(&:hex).pack('U*') else [codepoints.hex].pack('U') end @@ -69,7 +69,7 @@ namespace :emojis do end end - existence_maps = grouped_codes.map { |c| c.index_with { |cc| File.exist?(Rails.public_path.join('emoji', "#{codepoints_to_filename(cc)}.svg")) } } + existence_maps = grouped_codes.map { |c| c.index_with { |cc| Rails.public_path.join('emoji', "#{codepoints_to_filename(cc)}.svg").exist? } } map = {} existence_maps.each do |group| diff --git a/lib/tasks/glitchsoc.rake b/lib/tasks/glitchsoc.rake new file mode 100644 index 0000000000..72558fa190 --- /dev/null +++ b/lib/tasks/glitchsoc.rake @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +namespace :glitchsoc do + desc 'Backfill local-only flag on statuses table' + task backfill_local_only: :environment do + Status.local.where(local_only: nil).find_each do |status| + ActiveRecord::Base.logger.silence do + status.update_attribute(:local_only, status.marked_local_only?) # rubocop:disable Rails/SkipsModelValidations + end + end + end +end diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 1184e52739..f68d1cf1f8 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -21,7 +21,7 @@ namespace :mastodon do env['LOCAL_DOMAIN'] = prompt.ask('Domain name:') do |q| q.required true q.modify :strip - q.validate(/\A[a-z0-9\.\-]+\z/i) + q.validate(/\A[a-z0-9.-]+\z/i) q.messages[:valid?] = 'Invalid domain. If you intend to use unicode characters, enter punycode here' end @@ -92,7 +92,7 @@ namespace :mastodon do prompt.ok 'Database configuration works! 🎆' db_connection_works = true break - rescue StandardError => e + rescue => e prompt.error 'Database connection could not be established with this configuration, try again.' prompt.error e.message break unless prompt.yes?('Try again?') @@ -132,7 +132,7 @@ namespace :mastodon do redis.ping prompt.ok 'Redis configuration works! 🎆' break - rescue StandardError => e + rescue => e prompt.error 'Redis connection could not be established with this configuration, try again.' prompt.error e.message break unless prompt.yes?('Try again?') @@ -240,7 +240,7 @@ namespace :mastodon do end env['S3_PROTOCOL'] = env['S3_ENDPOINT'].start_with?('https') ? 'https' : 'http' - env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(/\Ahttps?:\/\//, '') + env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(%r{\Ahttps?://}, '') env['S3_BUCKET'] = prompt.ask('Minio bucket name:') do |q| q.required true @@ -264,12 +264,12 @@ namespace :mastodon do env['S3_ENDPOINT'] = prompt.ask('Storj DCS endpoint URL:') do |q| q.required true - q.default "https://gateway.storjshare.io" + q.default 'https://gateway.storjshare.io' q.modify :strip end env['S3_PROTOCOL'] = env['S3_ENDPOINT'].start_with?('https') ? 'https' : 'http' - env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(/\Ahttps?:\/\//, '') + env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(%r{\Ahttps?://}, '') env['S3_BUCKET'] = prompt.ask('Storj DCS bucket name:') do |q| q.required true @@ -286,13 +286,13 @@ namespace :mastodon do q.required true q.modify :strip end - + linksharing_access_key = prompt.ask('Storj Linksharing access key (uplink share --register --public --readonly=true --disallow-lists --not-after=none sj://bucket):') do |q| q.required true q.modify :strip end env['S3_ALIAS_HOST'] = "link.storjshare.io/raw/#{linksharing_access_key}/#{env['S3_BUCKET']}" - + when 'Google Cloud Storage' env['S3_ENABLED'] = 'true' env['S3_PROTOCOL'] = 'https' @@ -399,14 +399,14 @@ namespace :mastodon do end ActionMailer::Base.smtp_settings = { - port: env['SMTP_PORT'], - address: env['SMTP_SERVER'], - user_name: env['SMTP_LOGIN'].presence, - password: env['SMTP_PASSWORD'].presence, - domain: env['LOCAL_DOMAIN'], - authentication: env['SMTP_AUTH_METHOD'] == 'none' ? nil : env['SMTP_AUTH_METHOD'] || :plain, - openssl_verify_mode: env['SMTP_OPENSSL_VERIFY_MODE'], - enable_starttls: enable_starttls, + port: env['SMTP_PORT'], + address: env['SMTP_SERVER'], + user_name: env['SMTP_LOGIN'].presence, + password: env['SMTP_PASSWORD'].presence, + domain: env['LOCAL_DOMAIN'], + authentication: env['SMTP_AUTH_METHOD'] == 'none' ? nil : env['SMTP_AUTH_METHOD'] || :plain, + openssl_verify_mode: env['SMTP_OPENSSL_VERIFY_MODE'], + enable_starttls: enable_starttls, enable_starttls_auto: enable_starttls_auto, } @@ -417,13 +417,17 @@ namespace :mastodon do mail = ActionMailer::Base.new.mail to: send_to, subject: 'Test', body: 'Mastodon SMTP configuration works!' mail.deliver break - rescue StandardError => e + rescue => e prompt.error 'E-mail could not be sent with this configuration, try again.' prompt.error e.message break unless prompt.yes?('Try again?') end end + prompt.say "\n" + + env['UPDATE_CHECK_URL'] = '' unless prompt.yes?('Do you want Mastodon to periodically check for important updates and notify you? (Recommended)', default: true) + prompt.say "\n" prompt.say 'This configuration will be written to .env.production' @@ -438,14 +442,9 @@ namespace :mastodon do "#{key}=#{escaped}" end.join("\n") - generated_header = "# Generated with mastodon:setup on #{Time.now.utc}\n\n".dup + generated_header = generate_header(incompatible_syntax) - if incompatible_syntax - generated_header << "# Some variables in this file will be interpreted differently whether you are\n" - generated_header << "# using docker-compose or not.\n\n" - end - - File.write(Rails.root.join('.env.production'), "#{generated_header}#{env_contents}\n") + Rails.root.join('.env.production').write("#{generated_header}#{env_contents}\n") if using_docker prompt.ok 'Below is your configuration, save it to an .env.production file outside Docker:' @@ -538,6 +537,19 @@ namespace :mastodon do puts "VAPID_PUBLIC_KEY=#{vapid_key.public_key}" end end + + private + + def generate_header(include_warning) + default_message = "# Generated with mastodon:setup on #{Time.now.utc}\n\n" + + default_message.tap do |string| + if include_warning + string << "# Some variables in this file will be interpreted differently whether you are\n" + string << "# using docker-compose or not.\n\n" + end + end + end end def disable_log_stdout! @@ -573,7 +585,7 @@ def dotenv_escape(value) # As long as the value doesn't include single quotes, we can safely # rely on single quotes - return "'#{value}'" unless /[']/.match?(value) + return "'#{value}'" unless value.include?("'") # If the value contains the string '\n' or '\r' we simply can't use # a double-quoted string, because Dotenv will expand \n or \r no diff --git a/lib/tasks/repo.rake b/lib/tasks/repo.rake index 795b54c59c..1ed1ee5c32 100644 --- a/lib/tasks/repo.rake +++ b/lib/tasks/repo.rake @@ -5,7 +5,7 @@ REPOSITORY_NAME = 'mastodon/mastodon' namespace :repo do desc 'Generate the AUTHORS.md file' task :authors do - file = File.open(Rails.root.join('AUTHORS.md'), 'w') + file = Rails.root.join('AUTHORS.md').open('w') file << <<~HEADER Authors @@ -49,8 +49,8 @@ namespace :repo do File.open(path, 'r') do |file| file.each_line do |line| if line.start_with?('-') - new_line = line.gsub(/#([[:digit:]]+)*/) do |pull_request_reference| - pull_request_number = pull_request_reference[1..-1] + new_line = line.gsub(/[(]#([[:digit:]]+)[)]\Z/) do |pull_request_reference| + pull_request_number = pull_request_reference[2..-2] response = nil loop do @@ -66,7 +66,7 @@ namespace :repo do end pull_request = Oj.load(response.to_s) - "[#{pull_request['user']['login']}](#{pull_request['html_url']})" + "([#{pull_request['user']['login']}](#{pull_request['html_url']}))" end tmp.puts new_line @@ -87,12 +87,12 @@ namespace :repo do task check_locales_files: :environment do pastel = Pastel.new - missing_yaml_files = I18n.available_locales.reject { |locale| File.exist?(Rails.root.join('config', 'locales', "#{locale}.yml")) } - missing_json_files = I18n.available_locales.reject { |locale| File.exist?(Rails.root.join('app', 'javascript', 'mastodon', 'locales', "#{locale}.json")) } + missing_yaml_files = I18n.available_locales.reject { |locale| Rails.root.join('config', 'locales', "#{locale}.yml").exist? } + missing_json_files = I18n.available_locales.reject { |locale| Rails.root.join('app', 'javascript', 'mastodon', 'locales', "#{locale}.json").exist? } locales_in_files = Dir[Rails.root.join('config', 'locales', '*.yml')].map do |path| - file_name = File.basename(path) - file_name.gsub(/\A(doorkeeper|devise|activerecord|simple_form)\./, '').gsub(/\.yml\z/, '').to_sym + file_name = File.basename(path, '.yml') + file_name.gsub(/\A(doorkeeper|devise|activerecord|simple_form)\./, '').to_sym end.uniq.compact missing_available_locales = locales_in_files - I18n.available_locales diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake new file mode 100644 index 0000000000..ec4cd39bf4 --- /dev/null +++ b/lib/tasks/spec.rake @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +if Rake::Task.task_defined?('spec:system') + namespace :spec do + task :enable_system_specs do # rubocop:disable Rails/RakeEnvironment + ENV['RUN_SYSTEM_SPECS'] = 'true' + end + end + + Rake::Task['spec:system'].enhance ['spec:enable_system_specs'] +end + +if Rake::Task.task_defined?('spec:search') + namespace :spec do + task :enable_search_specs do # rubocop:disable Rails/RakeEnvironment + ENV['RUN_SEARCH_SPECS'] = 'true' + end + end + + Rake::Task['spec:search'].enhance ['spec:enable_search_specs'] +end diff --git a/lib/tasks/statistics.rake b/lib/tasks/statistics.rake index 82f2b54162..dde7890f6b 100644 --- a/lib/tasks/statistics.rake +++ b/lib/tasks/statistics.rake @@ -7,13 +7,13 @@ namespace :mastodon do task :stats do require 'rails/code_statistics' [ - %w(App\ Libraries app/lib), + ['App Libraries', 'app/lib'], %w(Presenters app/presenters), %w(Services app/services), %w(Validators app/validators), %w(Workers app/workers), ].each do |name, dir| - ::STATS_DIRECTORIES << [name, Rails.root.join(dir)] + STATS_DIRECTORIES << [name, Rails.root.join(dir)] end end end diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index 1dd25abb9b..7f8e72dd8f 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -25,7 +25,7 @@ namespace :tests do end if Account.where(domain: Rails.configuration.x.local_domain).exists? - puts 'Faux remote accounts not properly claned up' + puts 'Faux remote accounts not properly cleaned up' exit(1) end @@ -53,10 +53,44 @@ namespace :tests do puts 'Admin::ActionLog email domain block records not updated as expected' exit(1) end + + unless User.find(1).settings['notification_emails.favourite'] == true && User.find(1).settings['notification_emails.mention'] == false + puts 'User settings not kept as expected' + exit(1) + end + + unless User.find(1).settings['web.trends'] == false + puts 'User settings not kept as expected' + exit(1) + end + + unless Account.find_remote('bob', 'ActivityPub.com').domain == 'activitypub.com' + puts 'Account domains not properly normalized' + exit(1) + end + + unless Status.find(12).preview_cards.pluck(:url) == ['https://joinmastodon.org/'] + puts 'Preview cards not deduplicated as expected' + exit(1) + end + + unless Account.find_local('kmruser').user.chosen_languages == %w(en ku ckb) + puts 'Chosen languages not migrated as expected for kmr users' + exit(1) + end + + unless Account.find_local('kmruser').user.settings['default_language'] == 'ku' + puts 'Default posting language not migrated as expected for kmr users' + exit(1) + end end desc 'Populate the database with test data for 2.4.3' task populate_v2_4_3: :environment do # rubocop:disable Naming/VariableNumber + user_key = OpenSSL::PKey::RSA.new(2048) + user_private_key = ActiveRecord::Base.connection.quote(user_key.to_pem) + user_public_key = ActiveRecord::Base.connection.quote(user_key.public_key.to_pem) + ActiveRecord::Base.connection.execute(<<~SQL) INSERT INTO "custom_filters" (id, account_id, phrase, context, whole_word, irreversible, created_at, updated_at) @@ -98,12 +132,33 @@ namespace :tests do (1, 'destroy', 'EmailDomainBlock', 1, now(), now()), (1, 'destroy', 'Status', 1, now(), now()), (1, 'destroy', 'CustomEmoji', 3, now(), now()); + + INSERT INTO "settings" + (id, thing_type, thing_id, var, value, created_at, updated_at) + VALUES + (3, 'User', 1, 'notification_emails', E'--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\nfollow: false\nreblog: true\nfavourite: true\nmention: false\nfollow_request: true\ndigest: true\nreport: true\npending_account: false\ntrending_tag: true\nappeal: true\n', now(), now()), + (4, 'User', 1, 'trends', E'--- false\n', now(), now()); + + INSERT INTO "accounts" + (id, username, domain, private_key, public_key, created_at, updated_at) + VALUES + (10, 'kmruser', NULL, #{user_private_key}, #{user_public_key}, now(), now()); + + INSERT INTO "users" + (id, account_id, email, created_at, updated_at, admin, locale, chosen_languages) + VALUES + (4, 10, 'kmruser@localhost', now(), now(), false, 'ku', '{en,kmr,ku,ckb}'); + + INSERT INTO "settings" + (id, thing_type, thing_id, var, value, created_at, updated_at) + VALUES + (5, 'User', 4, 'default_language', E'--- kmr\n', now(), now()); SQL end desc 'Populate the database with test data for 2.4.0' task populate_v2_4: :environment do # rubocop:disable Naming/VariableNumber - ActiveRecord::Base.connection.execute(<<~SQL) + ActiveRecord::Base.connection.execute(<<~SQL.squish) INSERT INTO "settings" (id, thing_type, thing_id, var, value, created_at, updated_at) VALUES @@ -150,7 +205,7 @@ namespace :tests do INSERT INTO "accounts" (id, username, domain, private_key, public_key, created_at, updated_at, protocol, inbox_url, outbox_url, followers_url) VALUES - (6, 'bob', 'activitypub.com', NULL, #{remote_public_key_ap}, now(), now(), + (6, 'bob', 'ActivityPub.com', NULL, #{remote_public_key_ap}, now(), now(), 1, 'https://activitypub.com/users/bob/inbox', 'https://activitypub.com/users/bob/outbox', 'https://activitypub.com/users/bob/followers'); INSERT INTO "accounts" @@ -177,7 +232,7 @@ namespace :tests do INSERT INTO "users" (id, account_id, email, created_at, updated_at, admin, locale) VALUES - (3, 7, 'ptuser@localhost', now(), now(), false, 'pt'); + (3, 8, 'ptuser@localhost', now(), now(), false, 'pt'); -- conversations INSERT INTO "conversations" (id, created_at, updated_at) VALUES (1, now(), now()); @@ -223,6 +278,11 @@ namespace :tests do (10, 2, '@admin hey!', NULL, 1, 3, now(), now()), (11, 1, '@user hey!', 10, 1, 3, now(), now()); + INSERT INTO "statuses" + (id, account_id, text, created_at, updated_at) + VALUES + (12, 1, 'check out https://joinmastodon.org/', now(), now()); + -- mentions (from previous statuses) INSERT INTO "mentions" @@ -311,6 +371,21 @@ namespace :tests do (1, 6, 2, 'Follow', 2, now(), now()), (2, 2, 1, 'Mention', 4, now(), now()), (3, 1, 2, 'Mention', 5, now(), now()); + + -- preview cards + + INSERT INTO "preview_cards" + (id, url, title, created_at, updated_at) + VALUES + (1, 'https://joinmastodon.org/', 'Mastodon - Decentralized social media', now(), now()); + + -- many-to-many association between preview cards and statuses + + INSERT INTO "preview_cards_statuses" + (status_id, preview_card_id) + VALUES + (12, 1), + (12, 1); SQL end end diff --git a/lib/templates/rails/post_deployment_migration/migration.rb b/lib/templates/rails/post_deployment_migration/migration.rb deleted file mode 100644 index 503205b841..0000000000 --- a/lib/templates/rails/post_deployment_migration/migration.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -class <%= migration_class_name %> < ActiveRecord::Migration[5.2] - disable_ddl_transaction! - - def change - end -end diff --git a/lib/terrapin/multi_pipe_extensions.rb b/lib/terrapin/multi_pipe_extensions.rb index 209f4ad6ce..bddba4a2b1 100644 --- a/lib/terrapin/multi_pipe_extensions.rb +++ b/lib/terrapin/multi_pipe_extensions.rb @@ -13,7 +13,7 @@ module Terrapin def pipe_options # Add some flags to explicitly close the other end of the pipes - { out: @stdout_out, err: @stderr_out, @stdout_in => :close, @stderr_in => :close } + { :out => @stdout_out, :err => @stderr_out, @stdout_in => :close, @stderr_in => :close } end def read diff --git a/lib/webpacker/helper_extensions.rb b/lib/webpacker/helper_extensions.rb index 8f46d76313..3872e3d86d 100644 --- a/lib/webpacker/helper_extensions.rb +++ b/lib/webpacker/helper_extensions.rb @@ -13,7 +13,14 @@ module Webpacker::HelperExtensions def preload_pack_asset(name, **options) src, integrity = current_webpacker_instance.manifest.lookup!(name, with_integrity: true) - preload_link_tag(src, options.merge(integrity: integrity)) + + # This attribute will only work if the assets are on a different domain. + # And Webpack will (correctly) only add it in this case, so we need to conditionally set it here + # otherwise the preloaded request and the real request will have different crossorigin values + # and the preloaded file wont be loaded + crossorigin = 'anonymous' if Rails.configuration.action_controller.asset_host.present? + + preload_link_tag(src, options.merge(integrity: integrity, crossorigin: crossorigin)) end end diff --git a/package.json b/package.json index 96f1e7b0e6..ef2bfb3767 100644 --- a/package.json +++ b/package.json @@ -2,21 +2,30 @@ "name": "@mastodon/mastodon", "license": "AGPL-3.0-or-later", "engines": { - "node": ">=14" + "node": ">=16" }, "scripts": { - "postversion": "git push --tags", "build:development": "cross-env RAILS_ENV=development NODE_ENV=development ./bin/webpack", "build:production": "cross-env RAILS_ENV=production NODE_ENV=production ./bin/webpack", - "manage:translations": "node ./config/webpack/translationRunner.js", + "fix:js": "yarn lint:js --fix", + "fix:json": "prettier --write \"**/*.{json,json5}\"", + "fix:md": "prettier --write \"**/*.md\"", + "fix:sass": "stylelint --fix \"**/*.{css,scss}\" && prettier --write \"**/*.{css,scss}\"", + "fix:yml": "prettier --write \"**/*.{yaml,yml}\"", + "fix": "yarn fix:js && yarn fix:json && yarn fix:sass && yarn fix:yml", + "i18n:extract": "formatjs extract 'app/javascript/**/*.{js,jsx,ts,tsx}' '--ignore=**/*.d.ts' --out-file app/javascript/flavours/glitch/locales/en.json --format config/formatjs-formatter.js", + "jest": "cross-env NODE_ENV=test jest", + "lint:js": "eslint . --ext=.js,.jsx,.ts,.tsx --cache --report-unused-disable-directives", + "lint:json": "prettier --check \"**/*.{json,json5}\"", + "lint:md": "prettier --check \"**/*.md\"", + "lint:sass": "stylelint \"**/*.{css,scss}\" && prettier --check \"**/*.{css,scss}\"", + "lint:yml": "prettier --check \"**/*.{yaml,yml}\"", + "lint": "yarn lint:js && yarn lint:json && yarn lint:sass && yarn lint:yml", + "postversion": "git push --tags", + "prepare": "husky install", "start": "node ./streaming/index.js", - "test": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:jest", - "test:lint": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:lint:sass", - "test:lint:js": "eslint --ext=js . --cache --report-unused-disable-directives", - "test:lint:sass": "stylelint \"**/*.{css,scss}\"", - "test:jest": "cross-env NODE_ENV=test jest", - "format": "prettier --write \"**/*.{json,yml}\"", - "format-check": "prettier --check \"**/*.{json,yml}\"" + "test": "yarn lint && yarn run typecheck && yarn jest", + "typecheck": "tsc --noEmit" }, "repository": { "type": "git", @@ -24,149 +33,202 @@ }, "private": true, "dependencies": { - "@babel/core": "^7.20.12", - "@babel/plugin-proposal-decorators": "^7.20.13", - "@babel/plugin-transform-react-inline-elements": "^7.18.6", - "@babel/plugin-transform-runtime": "^7.19.6", - "@babel/preset-env": "^7.20.2", - "@babel/preset-react": "^7.18.6", - "@babel/runtime": "^7.20.13", + "@babel/core": "^7.22.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.3", + "@babel/plugin-transform-react-inline-elements": "^7.21.0", + "@babel/plugin-transform-runtime": "^7.22.4", + "@babel/preset-env": "^7.22.4", + "@babel/preset-react": "^7.22.3", + "@babel/preset-typescript": "^7.21.5", + "@babel/runtime": "^7.22.3", + "@formatjs/intl-pluralrules": "^5.2.2", "@gamestdio/websocket": "^0.3.2", - "@github/webauthn-json": "^0.5.7", - "@rails/ujs": "^6.1.7", + "@github/webauthn-json": "^2.1.1", + "@material-design-icons/svg": "^0.14.10", + "@rails/ujs": "^7.0.6", + "@rails/webpacker": "5.4.4", + "@reduxjs/toolkit": "^1.9.5", + "@renchap/compression-webpack-plugin": "^6.1.4", + "@svgr/webpack": "^5.5.0", "abortcontroller-polyfill": "^1.7.5", - "array-includes": "^3.1.6", "arrow-key-navigation": "^1.2.0", - "autoprefixer": "^9.8.8", - "axios": "^1.3.2", + "async-mutex": "^0.4.0", + "atrament": "0.2.4", + "autoprefixer": "^10.4.14", + "axios": "^1.4.0", "babel-loader": "^8.3.0", + "babel-plugin-formatjs": "^10.5.1", "babel-plugin-lodash": "^3.3.4", "babel-plugin-preval": "^5.1.0", - "babel-plugin-react-intl": "^6.2.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", - "blurhash": "^2.0.4", + "blurhash": "^2.0.5", + "circular-dependency-plugin": "^5.2.2", "classnames": "^2.3.2", "cocoon-js-vanilla": "^1.3.0", - "color-blend": "^3.0.1", - "compression-webpack-plugin": "^6.1.1", + "color-blend": "^4.0.0", + "core-js": "^3.30.2", "cross-env": "^7.0.3", "css-loader": "^5.2.7", - "cssnano": "^4.1.11", + "cssnano": "^6.0.1", "detect-passive-events": "^2.0.3", "dotenv": "^16.0.3", "emoji-mart": "npm:emoji-mart-lazyload@latest", - "es6-symbol": "^3.1.3", "escape-html": "^1.0.3", "exif-js": "^2.3.0", "express": "^4.18.2", + "favico.js": "^0.3.10", "file-loader": "^6.2.0", "font-awesome": "^4.7.0", - "fuzzysort": "^1.9.0", - "glob": "^8.1.0", + "fuzzysort": "^2.0.4", + "glob": "^10.2.6", "history": "^4.10.1", - "http-link-header": "^1.1.0", - "immutable": "^4.2.4", + "http-link-header": "^1.1.1", + "immutable": "^4.3.0", "imports-loader": "^1.2.0", - "intl": "^1.2.5", - "intl-messageformat": "^2.2.0", - "intl-relativeformat": "^6.4.3", - "is-nan": "^1.3.2", + "intl-messageformat": "^10.3.5", + "ioredis": "^5.3.2", "js-yaml": "^4.1.0", - "jsdom": "^21.1.0", + "jsdom": "^22.1.0", "lodash": "^4.17.21", "mark-loader": "^0.1.6", "marky": "^1.2.5", "mini-css-extract-plugin": "^1.6.2", - "mkdirp": "^2.1.3", + "mkdirp": "^3.0.1", "npmlog": "^7.0.1", - "object-assign": "^4.1.1", - "object.values": "^1.1.6", "path-complete-extname": "^1.0.0", "pg": "^8.5.0", - "postcss": "^8.4.21", - "postcss-loader": "^3.0.0", - "promise.prototype.finally": "^3.1.4", + "pg-connection-string": "^2.6.0", + "postcss": "^8.4.24", + "postcss-loader": "^4.3.0", + "prom-client": "^14.2.0", "prop-types": "^15.8.1", "punycode": "^2.3.0", - "react": "^16.14.0", - "react-dom": "^16.14.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "react-helmet": "^6.1.0", "react-hotkeys": "^1.1.4", "react-immutable-proptypes": "^2.2.0", "react-immutable-pure-component": "^2.2.2", - "react-intl": "^2.9.0", + "react-intl": "^6.4.2", "react-motion": "^0.5.2", "react-notification": "^6.8.5", "react-overlays": "^5.2.1", - "react-redux": "^7.2.9", + "react-redux": "^8.0.4", "react-redux-loading-bar": "^5.0.4", + "react-router": "^4.3.1", "react-router-dom": "^4.1.1", "react-router-scroll-4": "^1.0.0-beta.1", - "react-select": "^5.7.0", + "react-select": "^5.7.3", "react-sparklines": "^1.7.0", "react-swipeable-views": "^0.14.0", - "react-textarea-autosize": "^8.4.0", + "react-textarea-autosize": "^8.4.1", "react-toggle": "^4.1.3", - "redis": "^4.0.6 <4.1.0", "redux": "^4.2.1", "redux-immutable": "^4.0.0", "redux-thunk": "^2.4.2", - "regenerator-runtime": "^0.13.11", + "regenerator-runtime": "^0.14.0", "requestidlecallback": "^0.3.0", - "reselect": "^4.1.7", - "rimraf": "^4.1.2", - "sass": "^1.58.0", + "reselect": "^4.1.8", + "rimraf": "^5.0.1", + "sass": "^1.62.1", "sass-loader": "^10.2.0", "stacktrace-js": "^2.0.2", "stringz": "^2.1.0", "substring-trie": "^1.0.2", "terser-webpack-plugin": "^4.2.3", - "tesseract.js": "^2.1.1", - "throng": "^4.0.0", + "tesseract.js": "^2.1.5", "tiny-queue": "^0.2.1", "twitter-text": "3.1.0", - "uuid": "^8.3.1", - "webpack": "^4.46.0", + "uuid": "^9.0.0", + "webpack": "^4.47.0", "webpack-assets-manifest": "^4.0.6", - "webpack-bundle-analyzer": "^4.7.0", + "webpack-bundle-analyzer": "^4.8.0", "webpack-cli": "^3.3.12", - "webpack-merge": "^5.8.0", + "webpack-merge": "^5.9.0", "wicg-inert": "^3.1.2", - "workbox-expiration": "^6.5.4", - "workbox-precaching": "^6.5.4", - "workbox-routing": "^6.5.4", - "workbox-strategies": "^6.5.4", - "workbox-webpack-plugin": "^6.5.4", - "workbox-window": "^6.5.4", - "ws": "^8.12.0" + "workbox-expiration": "^7.0.0", + "workbox-precaching": "^7.0.0", + "workbox-routing": "^7.0.0", + "workbox-strategies": "^7.0.0", + "workbox-webpack-plugin": "^7.0.0", + "workbox-window": "^7.0.0", + "ws": "^8.12.1" }, "devDependencies": { - "@babel/eslint-parser": "^7.19.1", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^12.1.5", - "babel-jest": "^29.4.1", - "eslint": "^8.33.0", - "eslint-plugin-import": "~2.27.5", + "@formatjs/cli": "^6.1.1", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^14.0.0", + "@types/babel__core": "^7.20.1", + "@types/emoji-mart": "^3.0.9", + "@types/escape-html": "^1.0.2", + "@types/express": "^4.17.17", + "@types/http-link-header": "^1.0.3", + "@types/intl": "^1.2.0", + "@types/jest": "^29.5.2", + "@types/js-yaml": "^4.0.5", + "@types/lodash": "^4.14.195", + "@types/npmlog": "^4.1.4", + "@types/object-assign": "^4.0.30", + "@types/pg": "^8.6.6", + "@types/prop-types": "^15.7.5", + "@types/punycode": "^2.1.0", + "@types/react": "^18.2.7", + "@types/react-dom": "^18.2.4", + "@types/react-helmet": "^6.1.6", + "@types/react-immutable-proptypes": "^2.1.0", + "@types/react-motion": "^0.0.35", + "@types/react-overlays": "^3.1.0", + "@types/react-router-dom": "^5.3.3", + "@types/react-select": "^5.0.1", + "@types/react-sparklines": "^1.7.2", + "@types/react-swipeable-views": "^0.13.1", + "@types/react-test-renderer": "^18.0.0", + "@types/react-textarea-autosize": "^8.0.0", + "@types/react-toggle": "^4.0.3", + "@types/redux-immutable": "^4.0.3", + "@types/requestidlecallback": "^0.3.5", + "@types/uuid": "^9.0.0", + "@types/webpack": "^4.41.33", + "@types/yargs": "^17.0.24", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "babel-jest": "^29.5.0", + "eslint": "^8.41.0", + "eslint-config-prettier": "^9.0.0", + "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-formatjs": "^4.10.1", + "eslint-plugin-import": "~2.28.0", + "eslint-plugin-jsdoc": "^46.1.0", "eslint-plugin-jsx-a11y": "~6.7.1", + "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-promise": "~6.1.1", - "eslint-plugin-react": "~7.32.2", - "jest": "^29.4.1", - "jest-environment-jsdom": "^29.4.1", - "postcss-scss": "^4.0.6", - "prettier": "^2.8.3", - "raf": "^3.4.1", - "react-intl-translations-manager": "^5.0.3", - "react-test-renderer": "^16.14.0", - "stylelint": "^14.16.1", - "stylelint-config-standard-scss": "^6.1.0", - "webpack-dev-server": "^3.11.3", - "yargs": "^17.6.2" + "eslint-plugin-react": "~7.33.0", + "eslint-plugin-react-hooks": "^4.6.0", + "husky": "^8.0.3", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "lint-staged": "^13.2.2", + "prettier": "^3.0.0", + "react-test-renderer": "^18.2.0", + "stylelint": "^15.10.1", + "stylelint-config-standard-scss": "^11.0.0", + "typescript": "^5.0.4", + "webpack-dev-server": "^3", + "yargs": "^17.7.2" }, "resolutions": { - "kind-of": "^6.0.3" + "@types/react": "^18.0.26", + "kind-of": "^6.0.3", + "webpack/terser-webpack-plugin": "^4.2.3" }, "optionalDependencies": { "bufferutil": "^4.0.7", - "utf-8-validate": "^6.0.2" + "utf-8-validate": "^6.0.3" + }, + "lint-staged": { + "*": "prettier --ignore-unknown --write", + "Capfile|Gemfile|*.{rb,ruby,ru,rake}": "bundle exec rubocop --force-exclusion -a", + "*.{js,jsx,ts,tsx}": "eslint --fix", + "*.{css,scss}": "stylelint --fix" } } diff --git a/postcss.config.js b/postcss.config.js index e7749a219d..5d58d74e34 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ module.exports = ({ env }) => ({ - plugins: { - autoprefixer: {}, - cssnano: env === 'production' ? {} : false, - }, + plugins: [ + 'autoprefixer', + env === 'production' ? 'cssnano' : '', + ], }); diff --git a/public/background-cybre.png b/public/background-cybre.png new file mode 100644 index 0000000000..151fd55849 Binary files /dev/null and b/public/background-cybre.png differ diff --git a/public/clock.js b/public/clock.js new file mode 100644 index 0000000000..ffb9beae80 --- /dev/null +++ b/public/clock.js @@ -0,0 +1,54 @@ +document.addEventListener("DOMContentLoaded", function(event) { + updateClock(); + setInterval(updateClock, 1000); +}); + +function getNextOpen(now) { + var days = [[0, 14], [4, 18], [8, 22], [12], [2, 16], [6, 20], [10]] + var nowday = now.getUTCDay(); + var nour = now.getUTCHours(); + + var open_hour = -1; + var d = 0; + + while (open_hour == -1) { + var times = days[(nowday + d) % 7]; + for (var i = 0; i < times.length; ++i) { + var time = times[i]; + if (time == nour) { + return "refresh"; + } else if (time > nour || d > 0) { + open_hour = time; + break; + } + } + if (open_hour == -1) { + d += 1; + nour = -1; + } + } + + var open = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + d)); + var ts = open.setUTCHours(open_hour); + return open; +} + +function updateClock() { + var clock = document.querySelector(".closed-registrations-message .clock"); + var now = new Date(); + var open = getNextOpen(now); + + if (open == "refresh") { + location.reload(); + return; + } + + var until = open - now; + var ms = until % 1000; + var s = Math.floor((until / 1000)) % 60; + var m = Math.floor((until / 1000 / 60)) % 60; + var h = Math.floor((until / 1000 / 60 / 60)); + if (m < 10) m = "0" + m; + if (s < 10) s = "0" + s; + clock.innerHTML = h + ":" + m + ":" + s; +} diff --git a/public/logo-cybre-glitch.gif b/public/logo-cybre-glitch.gif new file mode 100644 index 0000000000..abe9b2a9a2 Binary files /dev/null and b/public/logo-cybre-glitch.gif differ diff --git a/public/riot-glitch.png b/public/riot-glitch.png new file mode 100644 index 0000000000..1c97ce5f13 Binary files /dev/null and b/public/riot-glitch.png differ diff --git a/public/robots.txt b/public/robots.txt index 771bf2160b..0f9b65cea9 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,5 +1,11 @@ # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +User-agent: GPTBot +Disallow: / + User-agent: * Disallow: /media_proxy/ Disallow: /interact/ + +User-agent: GPTBot +Disallow:/ diff --git a/scalingo.json b/scalingo.json index 8c89929774..58c943b63c 100644 --- a/scalingo.json +++ b/scalingo.json @@ -31,7 +31,7 @@ "required": false }, "S3_REGION": { - "description": "Amazon S3 region that the bucket is located in", + "description": "Amazon S3 region that the bucket is located in; see regions list here: http://docs.aws.amazon.com/general/latest/gr/rande.html", "required": false }, "AWS_ACCESS_KEY_ID": { diff --git a/spec/chewy/accounts_index_spec.rb b/spec/chewy/accounts_index_spec.rb new file mode 100644 index 0000000000..f9c5922c76 --- /dev/null +++ b/spec/chewy/accounts_index_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountsIndex do + describe 'Searching the index' do + before do + mock_elasticsearch_response(described_class, raw_response) + end + + it 'returns results from a query' do + results = described_class.query(match: { name: 'account' }) + + expect(results).to eq [] + end + end + + def raw_response + { + took: 3, + hits: { + hits: [ + { + _id: '0', + _score: 1.6375021, + }, + ], + }, + } + end +end diff --git a/spec/chewy/public_statuses_index_spec.rb b/spec/chewy/public_statuses_index_spec.rb new file mode 100644 index 0000000000..2f93d0ff02 --- /dev/null +++ b/spec/chewy/public_statuses_index_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PublicStatusesIndex do + describe 'Searching the index' do + before do + mock_elasticsearch_response(described_class, raw_response) + end + + it 'returns results from a query' do + results = described_class.query(match: { name: 'status' }) + + expect(results).to eq [] + end + end + + def raw_response + { + took: 3, + hits: { + hits: [ + { + _id: '0', + _score: 1.6375021, + }, + ], + }, + } + end +end diff --git a/spec/chewy/statuses_index_spec.rb b/spec/chewy/statuses_index_spec.rb new file mode 100644 index 0000000000..768e9415fc --- /dev/null +++ b/spec/chewy/statuses_index_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe StatusesIndex do + describe 'Searching the index' do + before do + mock_elasticsearch_response(described_class, raw_response) + end + + it 'returns results from a query' do + results = described_class.query(match: { name: 'status' }) + + expect(results).to eq [] + end + end + + def raw_response + { + took: 3, + hits: { + hits: [ + { + _id: '0', + _score: 1.6375021, + }, + ], + }, + } + end +end diff --git a/spec/chewy/tags_index_spec.rb b/spec/chewy/tags_index_spec.rb new file mode 100644 index 0000000000..054589bdfb --- /dev/null +++ b/spec/chewy/tags_index_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe TagsIndex do + describe 'Searching the index' do + before do + mock_elasticsearch_response(described_class, raw_response) + end + + it 'returns results from a query' do + results = described_class.query(match: { name: 'tag' }) + + expect(results).to eq [] + end + end + + def raw_response + { + took: 3, + hits: { + hits: [ + { + _id: '0', + _score: 1.6375021, + }, + ], + }, + } + end +end diff --git a/spec/config/initializers/rack_attack_spec.rb b/spec/config/initializers/rack_attack_spec.rb index 581021cb90..7cd4ac76bb 100644 --- a/spec/config/initializers/rack_attack_spec.rb +++ b/spec/config/initializers/rack_attack_spec.rb @@ -1,28 +1,44 @@ +# frozen_string_literal: true + require 'rails_helper' -describe Rack::Attack do - include Rack::Test::Methods - +describe Rack::Attack, type: :request do def app Rails.application end shared_examples 'throttled endpoint' do + before do + # Rack::Attack periods are not rolling, so avoid flaky tests by setting the time in a way + # to avoid crossing period boundaries. + + # The code Rack::Attack uses to set periods is the following: + # https://github.com/rack/rack-attack/blob/v6.6.1/lib/rack/attack/cache.rb#L64-L66 + # So we want to minimize `Time.now.to_i % period` + + travel_to Time.zone.at((Time.now.to_i / period.seconds).to_i * period.seconds) + end + context 'when the number of requests is lower than the limit' do it 'does not change the request status' do limit.times do request.call - expect(last_response.status).to_not eq(429) + expect(response).to_not have_http_status(429) end end end context 'when the number of requests is higher than the limit' do - it 'returns http too many requests' do + it 'returns http too many requests after limit and returns to normal status after period' do (limit * 2).times do |i| request.call - expect(last_response.status).to eq(429) if i > limit + expect(response).to have_http_status(429) if i > limit end + + travel period + + request.call + expect(response).to_not have_http_status(429) end end end @@ -30,52 +46,60 @@ describe Rack::Attack do let(:remote_ip) { '1.2.3.5' } describe 'throttle excessive sign-up requests by IP address' do - context 'through the website' do - let(:limit) { 25 } - let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } } + context 'when accessed through the website' do + let(:limit) { 25 } + let(:period) { 5.minutes } + let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } } + + context 'with exact path' do + let(:path) { '/auth' } - context 'for exact path' do - let(:path) { '/auth' } it_behaves_like 'throttled endpoint' end - context 'for path with format' do - let(:path) { '/auth.html' } + context 'with path with format' do + let(:path) { '/auth.html' } + it_behaves_like 'throttled endpoint' end end - context 'through the API' do - let(:limit) { 5 } - let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } } + context 'when accessed through the API' do + let(:limit) { 5 } + let(:period) { 30.minutes } + let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } } + + context 'with exact path' do + let(:path) { '/api/v1/accounts' } - context 'for exact path' do - let(:path) { '/api/v1/accounts' } it_behaves_like 'throttled endpoint' end - context 'for path with format' do + context 'with path with format' do let(:path) { '/api/v1/accounts.json' } it 'returns http not found' do request.call - expect(last_response.status).to eq(404) + expect(response).to have_http_status(404) end end end end describe 'throttle excessive sign-in requests by IP address' do - let(:limit) { 25 } - let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } } + let(:limit) { 25 } + let(:period) { 5.minutes } + let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } } + + context 'with exact path' do + let(:path) { '/auth/sign_in' } - context 'for exact path' do - let(:path) { '/auth/sign_in' } it_behaves_like 'throttled endpoint' end - context 'for path with format' do - let(:path) { '/auth/sign_in.html' } + context 'with path with format' do + let(:path) { '/auth/sign_in.html' } + it_behaves_like 'throttled endpoint' end end diff --git a/spec/controllers/.rubocop.yml b/spec/controllers/.rubocop.yml new file mode 100644 index 0000000000..525479be81 --- /dev/null +++ b/spec/controllers/.rubocop.yml @@ -0,0 +1,6 @@ +inherit_from: ../../.rubocop.yml + +# Anonymous controllers in specs cannot access described_class +# https://github.com/rubocop/rubocop-rspec/blob/master/lib/rubocop/cop/rspec/described_class.rb#L36-L39 +RSpec/DescribedClass: + SkipBlocks: true diff --git a/spec/controllers/about_controller_spec.rb b/spec/controllers/about_controller_spec.rb index 97143ec437..8db6d80b0b 100644 --- a/spec/controllers/about_controller_spec.rb +++ b/spec/controllers/about_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AboutController, type: :controller do +RSpec.describe AboutController do render_views describe 'GET #show' do diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index defa8b2d38..5a8585b069 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AccountsController, type: :controller do +RSpec.describe AccountsController do render_views let(:account) { Fabricate(:account) } @@ -8,13 +10,17 @@ RSpec.describe AccountsController, type: :controller do shared_examples 'cacheable response' do it 'does not set cookies' do expect(response.cookies).to be_empty - expect(response.headers['Set-Cookies']).to be nil + expect(response.headers['Set-Cookies']).to be_nil end it 'does not set sessions' do expect(session).to be_empty end + it 'returns Vary header' do + expect(response.headers['Vary']).to include 'Accept' + end + it 'returns public Cache-Control header' do expect(response.headers['Cache-Control']).to include 'public' end @@ -51,7 +57,7 @@ RSpec.describe AccountsController, type: :controller do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it_behaves_like 'preliminary checks' @@ -93,7 +99,7 @@ RSpec.describe AccountsController, type: :controller do end end - context do + context 'with a normal account in an HTML request' do before do get :show, params: { username: account.username, format: format } end @@ -134,7 +140,7 @@ RSpec.describe AccountsController, type: :controller do end end - context 'as JSON' do + context 'with JSON' do let(:authorized_fetch_mode) { false } let(:format) { 'json' } @@ -167,7 +173,7 @@ RSpec.describe AccountsController, type: :controller do end end - context do + context 'with a normal account in a JSON request' do before do get :show, params: { username: account.username, format: format } end @@ -187,7 +193,7 @@ RSpec.describe AccountsController, type: :controller do expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) end - context 'in authorized fetch mode' do + context 'with authorized fetch mode' do let(:authorized_fetch_mode) { true } it 'returns http unauthorized' do @@ -212,8 +218,8 @@ RSpec.describe AccountsController, type: :controller do expect(response.media_type).to eq 'application/activity+json' end - it 'returns public Cache-Control header' do - expect(response.headers['Cache-Control']).to include 'public' + it 'returns private Cache-Control header' do + expect(response.headers['Cache-Control']).to include 'private' end it 'renders account' do @@ -245,7 +251,7 @@ RSpec.describe AccountsController, type: :controller do expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :name, :summary) end - context 'in authorized fetch mode' do + context 'with authorized fetch mode' do let(:authorized_fetch_mode) { true } it 'returns http success' do @@ -272,7 +278,7 @@ RSpec.describe AccountsController, type: :controller do end end - context 'as RSS' do + context 'with RSS' do let(:format) { 'rss' } it_behaves_like 'preliminary checks' @@ -308,7 +314,7 @@ RSpec.describe AccountsController, type: :controller do it_behaves_like 'cacheable response' end - context do + context 'with a normal account in an RSS request' do before do get :show, params: { username: account.username, format: format } end diff --git a/spec/controllers/activitypub/claims_controller_spec.rb b/spec/controllers/activitypub/claims_controller_spec.rb new file mode 100644 index 0000000000..f00eeb732a --- /dev/null +++ b/spec/controllers/activitypub/claims_controller_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::ClaimsController do + let(:account) { Fabricate(:account) } + + describe 'POST #create' do + context 'without signature' do + before do + post :create, params: { account_username: account.username }, body: '{}' + end + + it 'returns http not authorized' do + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/controllers/activitypub/collections_controller_spec.rb b/spec/controllers/activitypub/collections_controller_spec.rb index f78d9abbf0..e2802cf565 100644 --- a/spec/controllers/activitypub/collections_controller_spec.rb +++ b/spec/controllers/activitypub/collections_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ActivityPub::CollectionsController, type: :controller do +RSpec.describe ActivityPub::CollectionsController do let!(:account) { Fabricate(:account) } let!(:private_pinned) { Fabricate(:status, account: account, text: 'secret private stuff', visibility: :private) } let(:remote_account) { nil } @@ -10,7 +10,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do shared_examples 'cacheable response' do it 'does not set cookies' do expect(response.cookies).to be_empty - expect(response.headers['Set-Cookies']).to be nil + expect(response.headers['Set-Cookies']).to be_nil end it 'does not set sessions' do @@ -35,10 +35,10 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do describe 'GET #show' do context 'when id is "featured"' do context 'without signature' do - let(:remote_account) { nil } - subject(:response) { get :show, params: { id: 'featured', account_username: account.username } } - subject(:body) { body_as_json } + + let(:body) { body_as_json } + let(:remote_account) { nil } it 'returns http success' do expect(response).to have_http_status(200) @@ -60,7 +60,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do end it 'does not include contents of private pinned status' do - expect(response.body).not_to include(private_pinned.text) + expect(response.body).to_not include(private_pinned.text) end context 'when account is permanently suspended' do @@ -88,7 +88,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do context 'with signature' do let(:remote_account) { Fabricate(:account, domain: 'example.com') } - context do + context 'when getting a featured resource' do before do get :show, params: { id: 'featured', account_username: account.username } end @@ -115,11 +115,11 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do end it 'does not include contents of private pinned status' do - expect(response.body).not_to include(private_pinned.text) + expect(response.body).to_not include(private_pinned.text) end end - context 'in authorized fetch mode' do + context 'with authorized fetch mode' do before do allow(controller).to receive(:authorized_fetch_mode?).and_return(true) end diff --git a/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb b/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb index c19bb8cae7..b50c7b9cdc 100644 --- a/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb +++ b/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb @@ -1,20 +1,20 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe ActivityPub::FollowersSynchronizationsController, type: :controller do - let!(:account) { Fabricate(:account) } - let!(:follower_1) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/users/a') } - let!(:follower_2) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/users/b') } - let!(:follower_3) { Fabricate(:account, domain: 'foo.com', uri: 'https://foo.com/users/a') } - let!(:follower_4) { Fabricate(:account, username: 'instance-actor', domain: 'example.com', uri: 'https://example.com') } +RSpec.describe ActivityPub::FollowersSynchronizationsController do + let!(:account) { Fabricate(:account) } + let!(:follower_example_com_user_a) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/users/a') } + let!(:follower_example_com_user_b) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/users/b') } + let!(:follower_foo_com_user_a) { Fabricate(:account, domain: 'foo.com', uri: 'https://foo.com/users/a') } + let!(:follower_example_com_instance_actor) { Fabricate(:account, username: 'instance-actor', domain: 'example.com', uri: 'https://example.com') } before do - follower_1.follow!(account) - follower_2.follow!(account) - follower_3.follow!(account) - follower_4.follow!(account) - end + follower_example_com_user_a.follow!(account) + follower_example_com_user_b.follow!(account) + follower_foo_com_user_a.follow!(account) + follower_example_com_instance_actor.follow!(account) - before do allow(controller).to receive(:signed_request_actor).and_return(remote_account) end @@ -32,10 +32,10 @@ RSpec.describe ActivityPub::FollowersSynchronizationsController, type: :controll end context 'with signature from example.com' do - let(:remote_account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/instance') } - subject(:response) { get :show, params: { account_username: account.username } } - subject(:body) { body_as_json } + + let(:body) { body_as_json } + let(:remote_account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/instance') } it 'returns http success' do expect(response).to have_http_status(200) @@ -47,7 +47,11 @@ RSpec.describe ActivityPub::FollowersSynchronizationsController, type: :controll it 'returns orderedItems with followers from example.com' do expect(body[:orderedItems]).to be_an Array - expect(body[:orderedItems]).to match_array([follower_4.uri, follower_1.uri, follower_2.uri]) + expect(body[:orderedItems]).to contain_exactly( + follower_example_com_instance_actor.uri, + follower_example_com_user_a.uri, + follower_example_com_user_b.uri + ) end it 'returns private Cache-Control header' do diff --git a/spec/controllers/activitypub/inboxes_controller_spec.rb b/spec/controllers/activitypub/inboxes_controller_spec.rb index 2f023197be..030a303266 100644 --- a/spec/controllers/activitypub/inboxes_controller_spec.rb +++ b/spec/controllers/activitypub/inboxes_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ActivityPub::InboxesController, type: :controller do +RSpec.describe ActivityPub::InboxesController do let(:remote_account) { nil } before do @@ -21,11 +21,11 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do expect(response).to have_http_status(202) end - context 'for a specific account' do - let(:account) { Fabricate(:account) } - + context 'with a specific account' do subject(:response) { post :create, params: { account_username: account.username }, body: '{}' } + let(:account) { Fabricate(:account) } + context 'when account is permanently suspended' do before do account.suspend! @@ -68,7 +68,7 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do let(:synchronization_collection) { 'https://example.com/followers2' } it 'does not start a synchronization job' do - expect(ActivityPub::FollowersSynchronizationWorker).not_to have_received(:perform_async) + expect(ActivityPub::FollowersSynchronizationWorker).to_not have_received(:perform_async) end end @@ -76,13 +76,13 @@ RSpec.describe ActivityPub::InboxesController, type: :controller do let(:synchronization_url) { 'https://example.org/followers' } it 'does not start a synchronization job' do - expect(ActivityPub::FollowersSynchronizationWorker).not_to have_received(:perform_async) + expect(ActivityPub::FollowersSynchronizationWorker).to_not have_received(:perform_async) end end context 'with matching digest' do it 'does not start a synchronization job' do - expect(ActivityPub::FollowersSynchronizationWorker).not_to have_received(:perform_async) + expect(ActivityPub::FollowersSynchronizationWorker).to_not have_received(:perform_async) end end diff --git a/spec/controllers/activitypub/outboxes_controller_spec.rb b/spec/controllers/activitypub/outboxes_controller_spec.rb index 74bf46a5eb..6946fdfcff 100644 --- a/spec/controllers/activitypub/outboxes_controller_spec.rb +++ b/spec/controllers/activitypub/outboxes_controller_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe ActivityPub::OutboxesController, type: :controller do +RSpec.describe ActivityPub::OutboxesController do let!(:account) { Fabricate(:account) } shared_examples 'cacheable response' do it 'does not set cookies' do expect(response.cookies).to be_empty - expect(response.headers['Set-Cookies']).to be nil + expect(response.headers['Set-Cookies']).to be_nil end it 'does not set sessions' do @@ -25,18 +27,16 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do Fabricate(:status, account: account, visibility: :private) Fabricate(:status, account: account, visibility: :direct) Fabricate(:status, account: account, visibility: :limited) - end - before do allow(controller).to receive(:signed_request_actor).and_return(remote_account) end describe 'GET #show' do context 'without signature' do - let(:remote_account) { nil } - subject(:response) { get :show, params: { account_username: account.username, page: page } } - subject(:body) { body_as_json } + + let(:body) { body_as_json } + let(:remote_account) { nil } context 'with page not requested' do let(:page) { nil } diff --git a/spec/controllers/activitypub/replies_controller_spec.rb b/spec/controllers/activitypub/replies_controller_spec.rb index aee1a8b1ad..c7b65f004d 100644 --- a/spec/controllers/activitypub/replies_controller_spec.rb +++ b/spec/controllers/activitypub/replies_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ActivityPub::RepliesController, type: :controller do +RSpec.describe ActivityPub::RepliesController do let(:status) { Fabricate(:status, visibility: parent_visibility) } let(:remote_account) { Fabricate(:account, domain: 'foobar.com') } let(:remote_reply_id) { 'https://foobar.com/statuses/1234' } @@ -11,7 +11,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do shared_examples 'cacheable response' do it 'does not set cookies' do expect(response.cookies).to be_empty - expect(response.headers['Set-Cookies']).to be nil + expect(response.headers['Set-Cookies']).to be_nil end it 'does not set sessions' do @@ -181,6 +181,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do describe 'GET #index' do subject(:response) { get :index, params: { account_username: status.account.username, status_id: status.id, only_other_accounts: only_other_accounts } } + let(:only_other_accounts) { nil } context 'with no signature' do diff --git a/spec/controllers/admin/account_actions_controller_spec.rb b/spec/controllers/admin/account_actions_controller_spec.rb new file mode 100644 index 0000000000..b8dae79939 --- /dev/null +++ b/spec/controllers/admin/account_actions_controller_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::AccountActionsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #new' do + let(:account) { Fabricate(:account) } + + it 'returns http success' do + get :new, params: { account_id: account.id } + + expect(response).to have_http_status(:success) + end + end + + describe 'POST #create' do + let(:account) { Fabricate(:account) } + + it 'records the account action' do + expect do + post :create, params: { account_id: account.id, admin_account_action: { type: 'silence' } } + end.to change { account.strikes.count }.by(1) + + expect(response).to redirect_to(admin_account_path(account.id)) + end + end +end diff --git a/spec/controllers/admin/account_moderation_notes_controller_spec.rb b/spec/controllers/admin/account_moderation_notes_controller_spec.rb index d3f3263f88..3e1b4b280f 100644 --- a/spec/controllers/admin/account_moderation_notes_controller_spec.rb +++ b/spec/controllers/admin/account_moderation_notes_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::AccountModerationNotesController, type: :controller do +RSpec.describe Admin::AccountModerationNotesController do render_views let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } @@ -17,7 +19,7 @@ RSpec.describe Admin::AccountModerationNotesController, type: :controller do let(:params) { { account_moderation_note: { target_account_id: target_account.id, content: 'test content' } } } it 'successfully creates a note' do - expect { subject }.to change { AccountModerationNote.count }.by(1) + expect { subject }.to change(AccountModerationNote, :count).by(1) expect(subject).to redirect_to admin_account_path(target_account.id) end end @@ -26,7 +28,7 @@ RSpec.describe Admin::AccountModerationNotesController, type: :controller do let(:params) { { account_moderation_note: { target_account_id: target_account.id, content: '' } } } it 'falls to create a note' do - expect { subject }.not_to change { AccountModerationNote.count } + expect { subject }.to_not change(AccountModerationNote, :count) expect(subject).to render_template 'admin/accounts/show' end end @@ -39,7 +41,7 @@ RSpec.describe Admin::AccountModerationNotesController, type: :controller do let(:account) { Fabricate(:account) } it 'destroys note' do - expect { subject }.to change { AccountModerationNote.count }.by(-1) + expect { subject }.to change(AccountModerationNote, :count).by(-1) expect(subject).to redirect_to admin_account_path(target_account.id) end end diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb index 81d592dddd..782e460a42 100644 --- a/spec/controllers/admin/accounts_controller_spec.rb +++ b/spec/controllers/admin/accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::AccountsController, type: :controller do +RSpec.describe Admin::AccountsController do render_views before { sign_in current_user, scope: :user } @@ -39,7 +41,7 @@ RSpec.describe Admin::AccountsController, type: :controller do username: 'username', display_name: 'display name', email: 'local-part@domain', - ip: '0.0.0.42' + ip: '0.0.0.42', } end @@ -83,8 +85,8 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:target_role) { UserRole.find_by(name: 'Admin') } it 'fails to memorialize account' do - is_expected.to have_http_status :forbidden - expect(account.reload).not_to be_memorial + expect(subject).to have_http_status 403 + expect(account.reload).to_not be_memorial end end @@ -92,7 +94,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:target_role) { UserRole.find_by(name: 'Moderator') } it 'succeeds in memorializing account' do - is_expected.to redirect_to admin_account_path(account.id) + expect(subject).to redirect_to admin_account_path(account.id) expect(account.reload).to be_memorial end end @@ -105,8 +107,8 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:target_role) { UserRole.find_by(name: 'Admin') } it 'fails to memorialize account' do - is_expected.to have_http_status :forbidden - expect(account.reload).not_to be_memorial + expect(subject).to have_http_status 403 + expect(account.reload).to_not be_memorial end end @@ -114,8 +116,8 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:target_role) { UserRole.find_by(name: 'Moderator') } it 'fails to memorialize account' do - is_expected.to have_http_status :forbidden - expect(account.reload).not_to be_memorial + expect(subject).to have_http_status 403 + expect(account.reload).to_not be_memorial end end end @@ -132,8 +134,8 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in enabling account' do - is_expected.to redirect_to admin_account_path(account.id) - expect(user.reload).not_to be_disabled + expect(subject).to redirect_to admin_account_path(account.id) + expect(user.reload).to_not be_disabled end end @@ -141,7 +143,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.everyone } it 'fails to enable account' do - is_expected.to have_http_status :forbidden + expect(subject).to have_http_status 403 expect(user.reload).to be_disabled end end @@ -162,12 +164,12 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in approving account' do - is_expected.to redirect_to admin_accounts_path(status: 'pending') + expect(subject).to redirect_to admin_accounts_path(status: 'pending') expect(user.reload).to be_approved end it 'logs action' do - is_expected.to have_http_status :found + expect(subject).to have_http_status 302 log_item = Admin::ActionLog.last @@ -182,8 +184,8 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.everyone } it 'fails to approve account' do - is_expected.to have_http_status :forbidden - expect(user.reload).not_to be_approved + expect(subject).to have_http_status 403 + expect(user.reload).to_not be_approved end end end @@ -203,11 +205,11 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in rejecting account' do - is_expected.to redirect_to admin_accounts_path(status: 'pending') + expect(subject).to redirect_to admin_accounts_path(status: 'pending') end it 'logs action' do - is_expected.to have_http_status :found + expect(subject).to have_http_status 302 log_item = Admin::ActionLog.last @@ -222,8 +224,8 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.everyone } it 'fails to reject account' do - is_expected.to have_http_status :forbidden - expect(user.reload).not_to be_approved + expect(subject).to have_http_status 403 + expect(user.reload).to_not be_approved end end end @@ -242,7 +244,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in redownloading' do - is_expected.to redirect_to admin_account_path(account.id) + expect(subject).to redirect_to admin_account_path(account.id) end end @@ -250,7 +252,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.everyone } it 'fails to redownload' do - is_expected.to have_http_status :forbidden + expect(subject).to have_http_status 403 end end end @@ -265,7 +267,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in removing avatar' do - is_expected.to redirect_to admin_account_path(account.id) + expect(subject).to redirect_to admin_account_path(account.id) end end @@ -273,7 +275,7 @@ RSpec.describe Admin::AccountsController, type: :controller do let(:role) { UserRole.everyone } it 'fails to remove avatar' do - is_expected.to have_http_status :forbidden + expect(subject).to have_http_status 403 end end end @@ -303,7 +305,131 @@ RSpec.describe Admin::AccountsController, type: :controller do it 'fails to remove avatar' do subject - expect(response).to have_http_status :forbidden + expect(response).to have_http_status 403 + end + end + end + + describe 'POST #unsensitive' do + subject { post :unsensitive, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, role: role) } + let(:account) { Fabricate(:account, sensitized_at: 1.year.ago) } + + context 'when user is admin' do + let(:role) { UserRole.find_by(name: 'Admin') } + + it 'marks accounts not sensitized' do + subject + + expect(account.reload).to_not be_sensitized + expect(response).to redirect_to admin_account_path(account.id) + end + end + + context 'when user is not admin' do + let(:role) { UserRole.everyone } + + it 'fails to change account' do + subject + + expect(response).to have_http_status 403 + end + end + end + + describe 'POST #unsilence' do + subject { post :unsilence, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, role: role) } + let(:account) { Fabricate(:account, silenced_at: 1.year.ago) } + + context 'when user is admin' do + let(:role) { UserRole.find_by(name: 'Admin') } + + it 'marks accounts not silenced' do + subject + + expect(account.reload).to_not be_silenced + expect(response).to redirect_to admin_account_path(account.id) + end + end + + context 'when user is not admin' do + let(:role) { UserRole.everyone } + + it 'fails to change account' do + subject + + expect(response).to have_http_status 403 + end + end + end + + describe 'POST #unsuspend' do + subject { post :unsuspend, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, role: role) } + let(:account) { Fabricate(:account) } + + before do + account.suspend! + end + + context 'when user is admin' do + let(:role) { UserRole.find_by(name: 'Admin') } + + it 'marks accounts not suspended' do + subject + + expect(account.reload).to_not be_suspended + expect(response).to redirect_to admin_account_path(account.id) + end + end + + context 'when user is not admin' do + let(:role) { UserRole.everyone } + + it 'fails to change account' do + subject + + expect(response).to have_http_status 403 + end + end + end + + describe 'POST #destroy' do + subject { post :destroy, params: { id: account.id } } + + let(:current_user) { Fabricate(:user, role: role) } + let(:account) { Fabricate(:account) } + + before do + account.suspend! + end + + context 'when user is admin' do + let(:role) { UserRole.find_by(name: 'Admin') } + + before do + allow(Admin::AccountDeletionWorker).to receive(:perform_async).with(account.id) + end + + it 'destroys the account' do + subject + + expect(Admin::AccountDeletionWorker).to have_received(:perform_async).with(account.id) + expect(response).to redirect_to admin_account_path(account.id) + end + end + + context 'when user is not admin' do + let(:role) { UserRole.everyone } + + it 'fails to change account' do + subject + + expect(response).to have_http_status 403 end end end diff --git a/spec/controllers/admin/action_logs_controller_spec.rb b/spec/controllers/admin/action_logs_controller_spec.rb index 7cd8cdf462..044ddf2c42 100644 --- a/spec/controllers/admin/action_logs_controller_spec.rb +++ b/spec/controllers/admin/action_logs_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Admin::ActionLogsController, type: :controller do +describe Admin::ActionLogsController do render_views # Action logs typically cause issues when their targets are not in the database diff --git a/spec/controllers/admin/announcements_controller_spec.rb b/spec/controllers/admin/announcements_controller_spec.rb new file mode 100644 index 0000000000..c2d3135d92 --- /dev/null +++ b/spec/controllers/admin/announcements_controller_spec.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::AnnouncementsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end + + describe 'GET #new' do + it 'returns http success and renders new' do + get :new + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + + describe 'GET #edit' do + let(:announcement) { Fabricate(:announcement) } + + it 'returns http success and renders edit' do + get :edit, params: { id: announcement.id } + + expect(response).to have_http_status(:success) + expect(response).to render_template(:edit) + end + end + + describe 'POST #create' do + it 'creates a new announcement and redirects' do + expect do + post :create, params: { announcement: { text: 'The announcement message.' } } + end.to change(Announcement, :count).by(1) + + expect(response).to redirect_to(admin_announcements_path) + expect(flash.notice).to match(I18n.t('admin.announcements.published_msg')) + end + end + + describe 'PUT #update' do + let(:announcement) { Fabricate(:announcement, text: 'Original text') } + + it 'updates an announcement and redirects' do + put :update, params: { id: announcement.id, announcement: { text: 'Updated text.' } } + + expect(response).to redirect_to(admin_announcements_path) + expect(flash.notice).to match(I18n.t('admin.announcements.updated_msg')) + end + end + + describe 'DELETE #destroy' do + let!(:announcement) { Fabricate(:announcement, text: 'Original text') } + + it 'destroys an announcement and redirects' do + expect do + delete :destroy, params: { id: announcement.id } + end.to change(Announcement, :count).by(-1) + + expect(response).to redirect_to(admin_announcements_path) + expect(flash.notice).to match(I18n.t('admin.announcements.destroyed_msg')) + end + end + + describe 'POST #publish' do + subject { post :publish, params: { id: announcement.id } } + + let(:announcement) { Fabricate(:announcement, published_at: nil) } + + it 'marks announcement published' do + subject + + expect(announcement.reload).to be_published + expect(response).to redirect_to admin_announcements_path + end + end + + describe 'POST #unpublish' do + subject { post :unpublish, params: { id: announcement.id } } + + let(:announcement) { Fabricate(:announcement, published_at: 4.days.ago) } + + it 'marks announcement as not published' do + subject + + expect(announcement.reload).to_not be_published + expect(response).to redirect_to admin_announcements_path + end + end +end diff --git a/spec/controllers/admin/base_controller_spec.rb b/spec/controllers/admin/base_controller_spec.rb index 44be91951b..1f1fa8441a 100644 --- a/spec/controllers/admin/base_controller_spec.rb +++ b/spec/controllers/admin/base_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Admin::BaseController, type: :controller do +describe Admin::BaseController do controller do def success authorize :dashboard, :index? @@ -15,7 +15,15 @@ describe Admin::BaseController, type: :controller do sign_in(Fabricate(:user)) get :success - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) + end + + it 'returns private cache control headers' do + routes.draw { get 'success' => 'admin/base#success' } + sign_in(Fabricate(:user, role: UserRole.find_by(name: 'Moderator'))) + get :success + + expect(response.headers['Cache-Control']).to include('private, no-store') end it 'renders admin layout as a moderator' do diff --git a/spec/controllers/admin/change_email_controller_spec.rb b/spec/controllers/admin/change_emails_controller_spec.rb similarity index 68% rename from spec/controllers/admin/change_email_controller_spec.rb rename to spec/controllers/admin/change_emails_controller_spec.rb index cf8a27d394..dd8a764b64 100644 --- a/spec/controllers/admin/change_email_controller_spec.rb +++ b/spec/controllers/admin/change_emails_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::ChangeEmailsController, type: :controller do +RSpec.describe Admin::ChangeEmailsController do render_views let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } @@ -9,8 +11,8 @@ RSpec.describe Admin::ChangeEmailsController, type: :controller do sign_in admin end - describe "GET #show" do - it "returns http success" do + describe 'GET #show' do + it 'returns http success' do user = Fabricate(:user) get :show, params: { account_id: user.account.id } @@ -19,12 +21,13 @@ RSpec.describe Admin::ChangeEmailsController, type: :controller do end end - describe "GET #update" do + describe 'GET #update' do before do - allow(UserMailer).to receive(:confirmation_instructions).and_return(double('email', deliver_later: nil)) + allow(UserMailer).to receive(:confirmation_instructions) + .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later: nil)) end - it "returns http success" do + it 'returns http success' do user = Fabricate(:user) previous_email = user.email @@ -35,7 +38,7 @@ RSpec.describe Admin::ChangeEmailsController, type: :controller do expect(user.email).to eq previous_email expect(user.unconfirmed_email).to eq 'test@example.com' - expect(user.confirmation_token).not_to be_nil + expect(user.confirmation_token).to_not be_nil expect(UserMailer).to have_received(:confirmation_instructions).with(user, user.confirmation_token, { to: 'test@example.com' }) diff --git a/spec/controllers/admin/confirmations_controller_spec.rb b/spec/controllers/admin/confirmations_controller_spec.rb index 6268903c4e..9559160786 100644 --- a/spec/controllers/admin/confirmations_controller_spec.rb +++ b/spec/controllers/admin/confirmations_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::ConfirmationsController, type: :controller do +RSpec.describe Admin::ConfirmationsController do render_views before do @@ -30,13 +32,13 @@ RSpec.describe Admin::ConfirmationsController, type: :controller do end end - describe 'POST #resernd' do + describe 'POST #resend' do subject { post :resend, params: { account_id: user.account.id } } let!(:user) { Fabricate(:user, confirmed_at: confirmed_at) } before do - allow(UserMailer).to receive(:confirmation_instructions) { double(:email, deliver_later: nil) } + allow(UserMailer).to receive(:confirmation_instructions) { instance_double(ActionMailer::MessageDelivery, deliver_later: nil) } end context 'when email is not confirmed' do @@ -55,7 +57,7 @@ RSpec.describe Admin::ConfirmationsController, type: :controller do it 'does not resend confirmation mail' do expect(subject).to redirect_to admin_accounts_path expect(flash[:error]).to eq I18n.t('admin.accounts.resend_confirmation.already_confirmed') - expect(UserMailer).not_to have_received(:confirmation_instructions) + expect(UserMailer).to_not have_received(:confirmation_instructions) end end end diff --git a/spec/controllers/admin/custom_emojis_controller_spec.rb b/spec/controllers/admin/custom_emojis_controller_spec.rb index 06cd0c22df..6c32a3a579 100644 --- a/spec/controllers/admin/custom_emojis_controller_spec.rb +++ b/spec/controllers/admin/custom_emojis_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::CustomEmojisController do @@ -40,7 +42,7 @@ describe Admin::CustomEmojisController do let(:params) { { shortcode: 'test', image: image } } it 'creates custom emoji' do - expect { subject }.to change { CustomEmoji.count }.by(1) + expect { subject }.to change(CustomEmoji, :count).by(1) end end diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb index 6231a09a24..25300fdd90 100644 --- a/spec/controllers/admin/dashboard_controller_spec.rb +++ b/spec/controllers/admin/dashboard_controller_spec.rb @@ -2,16 +2,16 @@ require 'rails_helper' -describe Admin::DashboardController, type: :controller do +describe Admin::DashboardController do render_views describe 'GET #index' do before do allow(Admin::SystemCheck).to receive(:perform).and_return([ - Admin::SystemCheck::Message.new(:database_schema_check), - Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path), - Admin::SystemCheck::Message.new(:sidekiq_process_check, 'foo, bar'), - ]) + Admin::SystemCheck::Message.new(:database_schema_check), + Admin::SystemCheck::Message.new(:rules_check, nil, admin_rules_path), + Admin::SystemCheck::Message.new(:sidekiq_process_check, 'foo, bar'), + ]) sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')) end diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index 7126577915..3c3f23f529 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -1,23 +1,26 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::Disputes::AppealsController, type: :controller do +RSpec.describe Admin::Disputes::AppealsController do render_views - before { sign_in current_user, scope: :user } + before do + sign_in current_user, scope: :user + + target_account.suspend! + end let(:target_account) { Fabricate(:account) } let(:strike) { Fabricate(:account_warning, target_account: target_account, action: :suspend) } let(:appeal) { Fabricate(:appeal, strike: strike, account: target_account) } - before do - target_account.suspend! - end - describe 'POST #approve' do let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do - allow(UserMailer).to receive(:appeal_approved).and_return(double('email', deliver_later: nil)) + allow(UserMailer).to receive(:appeal_approved) + .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later: nil)) post :approve, params: { id: appeal.id } end @@ -38,7 +41,8 @@ RSpec.describe Admin::Disputes::AppealsController, type: :controller do let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do - allow(UserMailer).to receive(:appeal_rejected).and_return(double('email', deliver_later: nil)) + allow(UserMailer).to receive(:appeal_rejected) + .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later: nil)) post :reject, params: { id: appeal.id } end diff --git a/spec/controllers/admin/domain_allows_controller_spec.rb b/spec/controllers/admin/domain_allows_controller_spec.rb index 6c4e677876..6f82f322b5 100644 --- a/spec/controllers/admin/domain_allows_controller_spec.rb +++ b/spec/controllers/admin/domain_allows_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::DomainAllowsController, type: :controller do +RSpec.describe Admin::DomainAllowsController do render_views before do @@ -35,7 +37,7 @@ RSpec.describe Admin::DomainAllowsController, type: :controller do describe 'DELETE #destroy' do it 'disallows the domain' do - service = double(call: true) + service = instance_double(UnallowDomainService, call: true) allow(UnallowDomainService).to receive(:new).and_return(service) domain_allow = Fabricate(:domain_allow) delete :destroy, params: { id: domain_allow.id } diff --git a/spec/controllers/admin/domain_blocks_controller_spec.rb b/spec/controllers/admin/domain_blocks_controller_spec.rb index f432060d98..9be55906ed 100644 --- a/spec/controllers/admin/domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/domain_blocks_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::DomainBlocksController, type: :controller do +RSpec.describe Admin::DomainBlocksController do render_views before do @@ -26,9 +28,9 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do domain_blocks_attributes: { '0' => { enabled: '1', domain: 'example.com', severity: 'silence' }, '1' => { enabled: '0', domain: 'mastodon.social', severity: 'suspend' }, - '2' => { enabled: '1', domain: 'mastodon.online', severity: 'suspend' } - } - } + '2' => { enabled: '1', domain: 'mastodon.online', severity: 'suspend' }, + }, + }, } expect(DomainBlockWorker).to have_received(:perform_async).exactly(2).times @@ -38,51 +40,144 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do end describe 'POST #create' do - it 'blocks the domain when succeeded to save' do + before do allow(DomainBlockWorker).to receive(:perform_async).and_return(true) - - post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } } - - expect(DomainBlockWorker).to have_received(:perform_async) - expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg') - expect(response).to redirect_to(admin_instances_path(limited: '1')) end - it 'renders new when failed to save' do - Fabricate(:domain_block, domain: 'example.com', severity: 'suspend') - allow(DomainBlockWorker).to receive(:perform_async).and_return(true) + context 'with "silence" severity and no conflict' do + before do + post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } } + end - post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } } + it 'records a block' do + expect(DomainBlock.exists?(domain: 'example.com', severity: 'silence')).to be true + end - expect(DomainBlockWorker).not_to have_received(:perform_async) - expect(response).to render_template :new + it 'calls DomainBlockWorker' do + expect(DomainBlockWorker).to have_received(:perform_async) + end + + it 'redirects with a success message' do + expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg') + expect(response).to redirect_to(admin_instances_path(limited: '1')) + end end - it 'allows upgrading a block' do - Fabricate(:domain_block, domain: 'example.com', severity: 'silence') - allow(DomainBlockWorker).to receive(:perform_async).and_return(true) + context 'when the new domain block conflicts with an existing one' do + before do + Fabricate(:domain_block, domain: 'example.com', severity: 'suspend') + post :create, params: { domain_block: { domain: 'example.com', severity: 'silence' } } + end - post :create, params: { domain_block: { domain: 'example.com', severity: 'silence', reject_media: true, reject_reports: true } } + it 'does not record a block' do + expect(DomainBlock.exists?(domain: 'example.com', severity: 'silence')).to be false + end - expect(DomainBlockWorker).to have_received(:perform_async) - expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg') - expect(response).to redirect_to(admin_instances_path(limited: '1')) + it 'does not call DomainBlockWorker' do + expect(DomainBlockWorker).to_not have_received(:perform_async) + end + + it 'renders new' do + expect(response).to render_template :new + end + end + + context 'with "suspend" severity and no conflict' do + context 'without a confirmation' do + before do + post :create, params: { domain_block: { domain: 'example.com', severity: 'suspend', reject_media: true, reject_reports: true } } + end + + it 'does not record a block' do + expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be false + end + + it 'does not call DomainBlockWorker' do + expect(DomainBlockWorker).to_not have_received(:perform_async) + end + + it 'renders confirm_suspension' do + expect(response).to render_template :confirm_suspension + end + end + + context 'with a confirmation' do + before do + post :create, params: { :domain_block => { domain: 'example.com', severity: 'suspend', reject_media: true, reject_reports: true }, 'confirm' => '' } + end + + it 'records a block' do + expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be true + end + + it 'calls DomainBlockWorker' do + expect(DomainBlockWorker).to have_received(:perform_async) + end + + it 'redirects with a success message' do + expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg') + expect(response).to redirect_to(admin_instances_path(limited: '1')) + end + end + end + + context 'when upgrading an existing block' do + before do + Fabricate(:domain_block, domain: 'example.com', severity: 'silence') + end + + context 'without a confirmation' do + before do + post :create, params: { domain_block: { domain: 'example.com', severity: 'suspend', reject_media: true, reject_reports: true } } + end + + it 'does not record a block' do + expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be false + end + + it 'does not call DomainBlockWorker' do + expect(DomainBlockWorker).to_not have_received(:perform_async) + end + + it 'renders confirm_suspension' do + expect(response).to render_template :confirm_suspension + end + end + + context 'with a confirmation' do + before do + post :create, params: { :domain_block => { domain: 'example.com', severity: 'suspend', reject_media: true, reject_reports: true }, 'confirm' => '' } + end + + it 'updates the record' do + expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be true + end + + it 'calls DomainBlockWorker' do + expect(DomainBlockWorker).to have_received(:perform_async) + end + + it 'redirects with a success message' do + expect(flash[:notice]).to eq I18n.t('admin.domain_blocks.created_msg') + expect(response).to redirect_to(admin_instances_path(limited: '1')) + end + end end end describe 'PUT #update' do + subject do + post :update, params: { :id => domain_block.id, :domain_block => { domain: 'example.com', severity: new_severity }, 'confirm' => '' } + end + let!(:remote_account) { Fabricate(:account, domain: 'example.com') } - let(:domain_block) { Fabricate(:domain_block, domain: 'example.com', severity: original_severity) } + let(:domain_block) { Fabricate(:domain_block, domain: 'example.com', severity: original_severity) } before do BlockDomainService.new.call(domain_block) end - let(:subject) do - post :update, params: { id: domain_block.id, domain_block: { domain: 'example.com', severity: new_severity } } - end - - context 'downgrading a domain suspension to silence' do + context 'when downgrading a domain suspension to silence' do let(:original_severity) { 'suspend' } let(:new_severity) { 'silence' } @@ -99,7 +194,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do end end - context 'upgrading a domain silence to suspend' do + context 'when upgrading a domain silence to suspend' do let(:original_severity) { 'silence' } let(:new_severity) { 'suspend' } @@ -119,7 +214,7 @@ RSpec.describe Admin::DomainBlocksController, type: :controller do describe 'DELETE #destroy' do it 'unblocks the domain' do - service = double(call: true) + service = instance_double(UnblockDomainService, call: true) allow(UnblockDomainService).to receive(:new).and_return(service) domain_block = Fabricate(:domain_block) delete :destroy, params: { id: domain_block.id } diff --git a/spec/controllers/admin/email_domain_blocks_controller_spec.rb b/spec/controllers/admin/email_domain_blocks_controller_spec.rb index e9cef4a94c..4286600144 100644 --- a/spec/controllers/admin/email_domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/email_domain_blocks_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Admin::EmailDomainBlocksController, type: :controller do +RSpec.describe Admin::EmailDomainBlocksController do render_views before do diff --git a/spec/controllers/admin/export_domain_allows_controller_spec.rb b/spec/controllers/admin/export_domain_allows_controller_spec.rb index 1e1a5ae7d4..9d50c04aad 100644 --- a/spec/controllers/admin/export_domain_allows_controller_spec.rb +++ b/spec/controllers/admin/export_domain_allows_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::ExportDomainAllowsController, type: :controller do +RSpec.describe Admin::ExportDomainAllowsController do render_views before do @@ -14,7 +16,7 @@ RSpec.describe Admin::ExportDomainAllowsController, type: :controller do get :export, params: { format: :csv } expect(response).to have_http_status(200) - expect(response.body).to eq(IO.read(File.join(file_fixture_path, 'domain_allows.csv'))) + expect(response.body).to eq(File.read(File.join(file_fixture_path, 'domain_allows.csv'))) end end @@ -25,12 +27,12 @@ RSpec.describe Admin::ExportDomainAllowsController, type: :controller do expect(response).to redirect_to(admin_instances_path) # Header should not be imported - expect(DomainAllow.where(domain: '#domain').present?).to eq(false) + expect(DomainAllow.where(domain: '#domain').present?).to be(false) # Domains should now be added get :export, params: { format: :csv } expect(response).to have_http_status(200) - expect(response.body).to eq(IO.read(File.join(file_fixture_path, 'domain_allows.csv'))) + expect(response.body).to eq(File.read(File.join(file_fixture_path, 'domain_allows.csv'))) end it 'displays error on no file selected' do diff --git a/spec/controllers/admin/export_domain_blocks_controller_spec.rb b/spec/controllers/admin/export_domain_blocks_controller_spec.rb index 2766102c89..1a63077736 100644 --- a/spec/controllers/admin/export_domain_blocks_controller_spec.rb +++ b/spec/controllers/admin/export_domain_blocks_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::ExportDomainBlocksController, type: :controller do +RSpec.describe Admin::ExportDomainBlocksController do render_views before do @@ -16,7 +18,7 @@ RSpec.describe Admin::ExportDomainBlocksController, type: :controller do get :export, params: { format: :csv } expect(response).to have_http_status(200) - expect(response.body).to eq(IO.read(File.join(file_fixture_path, 'domain_blocks.csv'))) + expect(response.body).to eq(File.read(File.join(file_fixture_path, 'domain_blocks.csv'))) end end @@ -27,7 +29,7 @@ RSpec.describe Admin::ExportDomainBlocksController, type: :controller do end it 'renders page with expected domain blocks' do - expect(assigns(:domain_blocks).map { |block| [block.domain, block.severity.to_sym] }).to match_array [['bad.domain', :silence], ['worse.domain', :suspend], ['reject.media', :noop]] + expect(assigns(:domain_blocks).map { |block| [block.domain, block.severity.to_sym] }).to contain_exactly(['bad.domain', :silence], ['worse.domain', :suspend], ['reject.media', :noop]) end it 'returns http success' do @@ -41,7 +43,7 @@ RSpec.describe Admin::ExportDomainBlocksController, type: :controller do end it 'renders page with expected domain blocks' do - expect(assigns(:domain_blocks).map { |block| [block.domain, block.severity.to_sym] }).to match_array [['bad.domain', :suspend], ['worse.domain', :suspend], ['reject.media', :suspend]] + expect(assigns(:domain_blocks).map { |block| [block.domain, block.severity.to_sym] }).to contain_exactly(['bad.domain', :suspend], ['worse.domain', :suspend], ['reject.media', :suspend]) end it 'returns http success' do diff --git a/spec/controllers/admin/follow_recommendations_controller_spec.rb b/spec/controllers/admin/follow_recommendations_controller_spec.rb new file mode 100644 index 0000000000..f62aa6e4b2 --- /dev/null +++ b/spec/controllers/admin/follow_recommendations_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::FollowRecommendationsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb index 337f7a80c7..dd772d1036 100644 --- a/spec/controllers/admin/instances_controller_spec.rb +++ b/spec/controllers/admin/instances_controller_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::InstancesController, type: :controller do +RSpec.describe Admin::InstancesController do render_views let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } - let!(:account) { Fabricate(:account, domain: 'popular') } - let!(:account2) { Fabricate(:account, domain: 'popular') } - let!(:account3) { Fabricate(:account, domain: 'less.popular') } + let!(:account_popular_main) { Fabricate(:account, domain: 'popular') } + let!(:account_popular_other) { Fabricate(:account, domain: 'popular') } + let!(:account_less_popular) { Fabricate(:account, domain: 'less.popular') } before do sign_in current_user, scope: :user @@ -42,7 +44,7 @@ RSpec.describe Admin::InstancesController, type: :controller do let(:role) { UserRole.find_by(name: 'Admin') } it 'succeeds in purging instance' do - is_expected.to redirect_to admin_instances_path + expect(subject).to redirect_to admin_instances_path end end @@ -50,7 +52,7 @@ RSpec.describe Admin::InstancesController, type: :controller do let(:role) { nil } it 'fails to purge instance' do - is_expected.to have_http_status :forbidden + expect(subject).to have_http_status 403 end end end diff --git a/spec/controllers/admin/invites_controller_spec.rb b/spec/controllers/admin/invites_controller_spec.rb index 1fb4887423..ca87417305 100644 --- a/spec/controllers/admin/invites_controller_spec.rb +++ b/spec/controllers/admin/invites_controller_spec.rb @@ -26,17 +26,17 @@ describe Admin::InvitesController do subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } } it 'succeeds to create a invite' do - expect { subject }.to change { Invite.count }.by(1) + expect { subject }.to change(Invite, :count).by(1) expect(subject).to redirect_to admin_invites_path expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10) end end describe 'DELETE #destroy' do - let!(:invite) { Fabricate(:invite, expires_at: nil) } - subject { delete :destroy, params: { id: invite.id } } + let!(:invite) { Fabricate(:invite, expires_at: nil) } + it 'expires invite' do expect(subject).to redirect_to admin_invites_path expect(invite.reload).to be_expired diff --git a/spec/controllers/admin/ip_blocks_controller_spec.rb b/spec/controllers/admin/ip_blocks_controller_spec.rb new file mode 100644 index 0000000000..05190f1340 --- /dev/null +++ b/spec/controllers/admin/ip_blocks_controller_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::IpBlocksController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end + + describe 'GET #new' do + it 'returns http success and renders view' do + get :new + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + + describe 'POST #create' do + context 'with valid data' do + it 'creates a new ip block and redirects' do + expect do + post :create, params: { ip_block: { ip: '1.1.1.1', severity: 'no_access', expires_in: 1.day.to_i.to_s } } + end.to change(IpBlock, :count).by(1) + + expect(response).to redirect_to(admin_ip_blocks_path) + expect(flash.notice).to match(I18n.t('admin.ip_blocks.created_msg')) + end + end + + context 'with invalid data' do + it 'does not create new a ip block and renders new' do + expect do + post :create, params: { ip_block: { ip: '1.1.1.1' } } + end.to_not change(IpBlock, :count) + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + end +end diff --git a/spec/controllers/admin/relationships_controller_spec.rb b/spec/controllers/admin/relationships_controller_spec.rb new file mode 100644 index 0000000000..1099a37a3b --- /dev/null +++ b/spec/controllers/admin/relationships_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::RelationshipsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + let(:account) { Fabricate(:account) } + + it 'returns http success' do + get :index, params: { account_id: account.id } + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/relays_controller_spec.rb b/spec/controllers/admin/relays_controller_spec.rb new file mode 100644 index 0000000000..ca351c39b2 --- /dev/null +++ b/spec/controllers/admin/relays_controller_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::RelaysController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end + + describe 'GET #new' do + it 'returns http success and renders view' do + get :new + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + + describe 'POST #create' do + context 'with valid data' do + let(:inbox_url) { 'https://example.com/inbox' } + + before do + stub_request(:post, inbox_url).to_return(status: 200) + end + + it 'creates a new relay and redirects' do + expect do + post :create, params: { relay: { inbox_url: inbox_url } } + end.to change(Relay, :count).by(1) + + expect(response).to redirect_to(admin_relays_path) + end + end + + context 'with invalid data' do + it 'does not create new a relay and renders new' do + expect do + post :create, params: { relay: { inbox_url: 'invalid' } } + end.to_not change(Relay, :count) + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + end + + describe 'DELETE #destroy' do + let(:relay) { Fabricate(:relay) } + + it 'deletes an existing relay' do + delete :destroy, params: { id: relay.id } + + expect { relay.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect(response).to redirect_to(admin_relays_path) + end + end + + describe 'POST #enable' do + let(:relay) { Fabricate(:relay, state: :idle) } + + before do + stub_request(:post, /example.com/).to_return(status: 200) + end + + it 'updates a relay from idle to pending' do + post :enable, params: { id: relay.id } + + expect(relay.reload).to be_pending + expect(response).to redirect_to(admin_relays_path) + end + end + + describe 'POST #disable' do + let(:relay) { Fabricate(:relay, state: :pending) } + + before do + stub_request(:post, /example.com/).to_return(status: 200) + end + + it 'updates a relay from pending to idle' do + post :disable, params: { id: relay.id } + + expect(relay.reload).to be_idle + expect(response).to redirect_to(admin_relays_path) + end + end +end diff --git a/spec/controllers/admin/report_notes_controller_spec.rb b/spec/controllers/admin/report_notes_controller_spec.rb index fa7572d186..b5ba4a84dc 100644 --- a/spec/controllers/admin/report_notes_controller_spec.rb +++ b/spec/controllers/admin/report_notes_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::ReportNotesController do @@ -23,7 +25,7 @@ describe Admin::ReportNotesController do let(:params) { { report_note: { content: 'test content', report_id: report.id }, create_and_resolve: nil } } it 'creates a report note and resolves report' do - expect { subject }.to change { ReportNote.count }.by(1) + expect { subject }.to change(ReportNote, :count).by(1) expect(report.reload).to be_action_taken expect(subject).to redirect_to admin_reports_path end @@ -33,8 +35,8 @@ describe Admin::ReportNotesController do let(:params) { { report_note: { content: 'test content', report_id: report.id } } } it 'creates a report note and does not resolve report' do - expect { subject }.to change { ReportNote.count }.by(1) - expect(report.reload).not_to be_action_taken + expect { subject }.to change(ReportNote, :count).by(1) + expect(report.reload).to_not be_action_taken expect(subject).to redirect_to admin_report_path(report) end end @@ -48,8 +50,8 @@ describe Admin::ReportNotesController do let(:params) { { report_note: { content: 'test content', report_id: report.id }, create_and_unresolve: nil } } it 'creates a report note and unresolves report' do - expect { subject }.to change { ReportNote.count }.by(1) - expect(report.reload).not_to be_action_taken + expect { subject }.to change(ReportNote, :count).by(1) + expect(report.reload).to_not be_action_taken expect(subject).to redirect_to admin_report_path(report) end end @@ -58,7 +60,7 @@ describe Admin::ReportNotesController do let(:params) { { report_note: { content: 'test content', report_id: report.id } } } it 'creates a report note and does not unresolve report' do - expect { subject }.to change { ReportNote.count }.by(1) + expect { subject }.to change(ReportNote, :count).by(1) expect(report.reload).to be_action_taken expect(subject).to redirect_to admin_report_path(report) end @@ -83,7 +85,7 @@ describe Admin::ReportNotesController do let!(:report_note) { Fabricate(:report_note) } it 'deletes note' do - expect { subject }.to change { ReportNote.count }.by(-1) + expect { subject }.to change(ReportNote, :count).by(-1) expect(subject).to redirect_to admin_report_path(report_note.report) end end diff --git a/spec/controllers/admin/reports/actions_controller_spec.rb b/spec/controllers/admin/reports/actions_controller_spec.rb index 9890ac9ce8..1f3951516d 100644 --- a/spec/controllers/admin/reports/actions_controller_spec.rb +++ b/spec/controllers/admin/reports/actions_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::Reports::ActionsController do @@ -13,7 +15,7 @@ describe Admin::Reports::ActionsController do let(:report) { Fabricate(:report) } before do - post :preview, params: { report_id: report.id, action => '' } + post :preview, params: { :report_id => report.id, action => '' } end context 'when the action is "suspend"' do @@ -55,20 +57,37 @@ describe Admin::Reports::ActionsController do let!(:media) { Fabricate(:media_attachment, account: target_account, status: statuses[0]) } let(:report) { Fabricate(:report, target_account: target_account, status_ids: statuses.map(&:id)) } let(:text) { 'hello' } + let(:common_params) do + { report_id: report.id, text: text } + end shared_examples 'common behavior' do - it 'closes the report' do - expect { subject }.to change { report.reload.action_taken? }.from(false).to(true) - end + it 'closes the report and redirects' do + expect { subject }.to mark_report_action_taken.and create_target_account_strike - it 'creates a strike with the expected text' do - expect { subject }.to change { report.target_account.strikes.count }.by(1) expect(report.target_account.strikes.last.text).to eq text + expect(response).to redirect_to(admin_reports_path) end - it 'redirects' do - subject - expect(response).to redirect_to(admin_reports_path) + context 'when text is unset' do + let(:common_params) do + { report_id: report.id } + end + + it 'closes the report and redirects' do + expect { subject }.to mark_report_action_taken.and create_target_account_strike + + expect(report.target_account.strikes.last.text).to eq '' + expect(response).to redirect_to(admin_reports_path) + end + end + + def mark_report_action_taken + change { report.reload.action_taken? }.from(false).to(true) + end + + def create_target_account_strike + change { report.target_account.strikes.count }.by(1) end end @@ -116,18 +135,20 @@ describe Admin::Reports::ActionsController do it 'marks the non-deleted as sensitive' do subject - expect(media_attached_status.reload.sensitive).to eq true + expect(media_attached_status.reload.sensitive).to be true end end end - context 'action as submit button' do - subject { post :create, params: { report_id: report.id, text: text, action => '' } } + context 'with action as submit button' do + subject { post :create, params: common_params.merge({ action => '' }) } + it_behaves_like 'all action types' end - context 'action as submit button' do - subject { post :create, params: { report_id: report.id, text: text, moderation_action: action } } + context 'with moderation action as an extra field' do + subject { post :create, params: common_params.merge({ moderation_action: action }) } + it_behaves_like 'all action types' end end diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index 4cd1524bf7..97daaf8da9 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -1,9 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::ReportsController do render_views let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + before do sign_in user, scope: :user end @@ -54,7 +57,7 @@ describe Admin::ReportsController do expect(response).to redirect_to(admin_reports_path) report.reload expect(report.action_taken_by_account).to eq user.account - expect(report.action_taken?).to eq true + expect(report.action_taken?).to be true end end @@ -65,8 +68,8 @@ describe Admin::ReportsController do put :reopen, params: { id: report } expect(response).to redirect_to(admin_report_path(report)) report.reload - expect(report.action_taken_by_account).to eq nil - expect(report.action_taken?).to eq false + expect(report.action_taken_by_account).to be_nil + expect(report.action_taken?).to be false end end @@ -88,7 +91,7 @@ describe Admin::ReportsController do put :unassign, params: { id: report } expect(response).to redirect_to(admin_report_path(report)) report.reload - expect(report.assigned_account).to eq nil + expect(report.assigned_account).to be_nil end end end diff --git a/spec/controllers/admin/resets_controller_spec.rb b/spec/controllers/admin/resets_controller_spec.rb index aeb172318b..16adb8a128 100644 --- a/spec/controllers/admin/resets_controller_spec.rb +++ b/spec/controllers/admin/resets_controller_spec.rb @@ -1,9 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::ResetsController do render_views let(:account) { Fabricate(:account) } + before do sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb index 8ff8912054..223d0a472a 100644 --- a/spec/controllers/admin/roles_controller_spec.rb +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::RolesController do @@ -18,7 +20,7 @@ describe Admin::RolesController do context 'when user does not have permission to manage roles' do it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end @@ -38,7 +40,7 @@ describe Admin::RolesController do context 'when user does not have permission to manage roles' do it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end @@ -128,7 +130,7 @@ describe Admin::RolesController do context 'when user does not have permission to manage roles' do it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end @@ -145,7 +147,7 @@ describe Admin::RolesController do let(:role_position) { current_role.position + 1 } it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end end @@ -165,7 +167,7 @@ describe Admin::RolesController do context 'when user does not have permission to manage roles' do it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end it 'does not update the role' do @@ -203,7 +205,7 @@ describe Admin::RolesController do let(:role_position) { current_role.position + 1 } it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end it 'does not update the role' do @@ -224,7 +226,7 @@ describe Admin::RolesController do context 'when user does not have permission to manage roles' do it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end @@ -241,7 +243,7 @@ describe Admin::RolesController do let(:role_position) { current_role.position + 1 } it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end end diff --git a/spec/controllers/admin/rules_controller_spec.rb b/spec/controllers/admin/rules_controller_spec.rb new file mode 100644 index 0000000000..92ffb41567 --- /dev/null +++ b/spec/controllers/admin/rules_controller_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::RulesController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end + + describe 'GET #edit' do + let(:rule) { Fabricate(:rule) } + + it 'returns http success and renders edit' do + get :edit, params: { id: rule.id } + + expect(response).to have_http_status(:success) + expect(response).to render_template(:edit) + end + end + + describe 'POST #create' do + context 'with valid data' do + it 'creates a new rule and redirects' do + expect do + post :create, params: { rule: { text: 'The rule text.' } } + end.to change(Rule, :count).by(1) + + expect(response).to redirect_to(admin_rules_path) + end + end + + context 'with invalid data' do + it 'does creates a new rule and renders index' do + expect do + post :create, params: { rule: { text: '' } } + end.to_not change(Rule, :count) + + expect(response).to render_template(:index) + end + end + end + + describe 'PUT #update' do + let(:rule) { Fabricate(:rule, text: 'Original text') } + + context 'with valid data' do + it 'updates the rule and redirects' do + put :update, params: { id: rule.id, rule: { text: 'Updated text.' } } + + expect(response).to redirect_to(admin_rules_path) + end + end + + context 'with invalid data' do + it 'does not update the rule and renders index' do + put :update, params: { id: rule.id, rule: { text: '' } } + + expect(response).to render_template(:edit) + end + end + end + + describe 'DELETE #destroy' do + let!(:rule) { Fabricate(:rule) } + + it 'destroys the rule and redirects' do + delete :destroy, params: { id: rule.id } + + expect(rule.reload).to be_discarded + expect(response).to redirect_to(admin_rules_path) + end + end +end diff --git a/spec/controllers/admin/settings/about_controller_spec.rb b/spec/controllers/admin/settings/about_controller_spec.rb new file mode 100644 index 0000000000..2ae26090b6 --- /dev/null +++ b/spec/controllers/admin/settings/about_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Settings::AboutController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/settings/appearance_controller_spec.rb b/spec/controllers/admin/settings/appearance_controller_spec.rb new file mode 100644 index 0000000000..65b29acc3e --- /dev/null +++ b/spec/controllers/admin/settings/appearance_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Settings::AppearanceController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/settings/branding_controller_spec.rb b/spec/controllers/admin/settings/branding_controller_spec.rb index ee1c441bc5..4b0f1e21e0 100644 --- a/spec/controllers/admin/settings/branding_controller_spec.rb +++ b/spec/controllers/admin/settings/branding_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Admin::Settings::BrandingController, type: :controller do +RSpec.describe Admin::Settings::BrandingController do render_views describe 'When signed in as an admin' do diff --git a/spec/controllers/admin/settings/content_retention_controller_spec.rb b/spec/controllers/admin/settings/content_retention_controller_spec.rb new file mode 100644 index 0000000000..53ce84d189 --- /dev/null +++ b/spec/controllers/admin/settings/content_retention_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Settings::ContentRetentionController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/settings/discovery_controller_spec.rb b/spec/controllers/admin/settings/discovery_controller_spec.rb new file mode 100644 index 0000000000..c7307ffc88 --- /dev/null +++ b/spec/controllers/admin/settings/discovery_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Settings::DiscoveryController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/settings/registrations_controller_spec.rb b/spec/controllers/admin/settings/registrations_controller_spec.rb new file mode 100644 index 0000000000..3fc1f9d132 --- /dev/null +++ b/spec/controllers/admin/settings/registrations_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Settings::RegistrationsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/site_uploads_controller_spec.rb b/spec/controllers/admin/site_uploads_controller_spec.rb new file mode 100644 index 0000000000..4ea37f396a --- /dev/null +++ b/spec/controllers/admin/site_uploads_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SiteUploadsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'DELETE #destroy' do + let(:site_upload) { Fabricate(:site_upload, var: 'thumbnail') } + + it 'returns http success' do + delete :destroy, params: { id: site_upload.id } + + expect(response).to redirect_to(admin_settings_path) + end + end +end diff --git a/spec/controllers/admin/statuses_controller_spec.rb b/spec/controllers/admin/statuses_controller_spec.rb index 7f912c1c07..9befdf978f 100644 --- a/spec/controllers/admin/statuses_controller_spec.rb +++ b/spec/controllers/admin/statuses_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::StatusesController do @@ -18,7 +20,7 @@ describe Admin::StatusesController do end describe 'GET #index' do - context do + context 'with a valid account' do before do get :index, params: { account_id: account.id } end @@ -28,7 +30,7 @@ describe Admin::StatusesController do end end - context 'filtering by media' do + context 'when filtering by media' do before do get :index, params: { account_id: account.id, media: '1' } end @@ -39,25 +41,47 @@ describe Admin::StatusesController do end end - describe 'POST #batch' do + describe 'GET #show' do before do - post :batch, params: { account_id: account.id, action => '', admin_status_batch_action: { status_ids: status_ids } } + get :show, params: { account_id: account.id, id: status.id } end + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + + describe 'POST #batch' do + subject { post :batch, params: { :account_id => account.id, action => '', :admin_status_batch_action => { status_ids: status_ids } } } + let(:status_ids) { [media_attached_status.id] } - context 'when action is report' do + shared_examples 'when action is report' do let(:action) { 'report' } it 'creates a report' do + subject + report = Report.last expect(report.target_account_id).to eq account.id expect(report.status_ids).to eq status_ids end it 'redirects to report page' do + subject + expect(response).to redirect_to(admin_report_path(Report.last.id)) end end + + it_behaves_like 'when action is report' + + context 'when the moderator is blocked by the author' do + before do + account.block!(user.account) + end + + it_behaves_like 'when action is report' + end end end diff --git a/spec/controllers/admin/tags_controller_spec.rb b/spec/controllers/admin/tags_controller_spec.rb index 52fd09eb10..313298f14a 100644 --- a/spec/controllers/admin/tags_controller_spec.rb +++ b/spec/controllers/admin/tags_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Admin::TagsController, type: :controller do +RSpec.describe Admin::TagsController do render_views before do diff --git a/spec/controllers/admin/trends/links/preview_card_providers_controller_spec.rb b/spec/controllers/admin/trends/links/preview_card_providers_controller_spec.rb new file mode 100644 index 0000000000..95ed38d6b1 --- /dev/null +++ b/spec/controllers/admin/trends/links/preview_card_providers_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Trends::Links::PreviewCardProvidersController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/trends/links_controller_spec.rb b/spec/controllers/admin/trends/links_controller_spec.rb new file mode 100644 index 0000000000..7c67f5e5aa --- /dev/null +++ b/spec/controllers/admin/trends/links_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Trends::LinksController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/trends/statuses_controller_spec.rb b/spec/controllers/admin/trends/statuses_controller_spec.rb new file mode 100644 index 0000000000..b752234d3c --- /dev/null +++ b/spec/controllers/admin/trends/statuses_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Trends::StatusesController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/trends/tags_controller_spec.rb b/spec/controllers/admin/trends/tags_controller_spec.rb new file mode 100644 index 0000000000..4f74a55455 --- /dev/null +++ b/spec/controllers/admin/trends/tags_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Trends::TagsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end +end diff --git a/spec/controllers/admin/users/roles_controller.rb b/spec/controllers/admin/users/roles_controller_spec.rb similarity index 92% rename from spec/controllers/admin/users/roles_controller.rb rename to spec/controllers/admin/users/roles_controller_spec.rb index bd6a3fa673..97f69a0b0a 100644 --- a/spec/controllers/admin/users/roles_controller.rb +++ b/spec/controllers/admin/users/roles_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::Users::RolesController do @@ -26,7 +28,7 @@ describe Admin::Users::RolesController do let(:previous_role) { UserRole.create(name: 'Baz', permissions: UserRole::FLAGS[:administrator], position: 100) } it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end end @@ -38,7 +40,7 @@ describe Admin::Users::RolesController do put :update, params: { user_id: user.id, user: { role_id: selected_role.id } } end - context do + context 'with manage roles permissions' do let(:permissions) { UserRole::FLAGS[:manage_roles] } let(:position) { 1 } @@ -74,7 +76,7 @@ describe Admin::Users::RolesController do end it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end end diff --git a/spec/controllers/admin/users/two_factor_authentications_controller_spec.rb b/spec/controllers/admin/users/two_factor_authentications_controller_spec.rb index e56264ef62..eb10d47963 100644 --- a/spec/controllers/admin/users/two_factor_authentications_controller_spec.rb +++ b/spec/controllers/admin/users/two_factor_authentications_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' require 'webauthn/fake_client' @@ -20,7 +22,7 @@ describe Admin::Users::TwoFactorAuthenticationsController do delete :destroy, params: { user_id: user.id } user.reload - expect(user.otp_enabled?).to eq false + expect(user.otp_enabled?).to be false expect(response).to redirect_to(admin_account_path(user.account_id)) end end @@ -43,8 +45,8 @@ describe Admin::Users::TwoFactorAuthenticationsController do delete :destroy, params: { user_id: user.id } user.reload - expect(user.otp_enabled?).to eq false - expect(user.webauthn_enabled?).to eq false + expect(user.otp_enabled?).to be false + expect(user.webauthn_enabled?).to be false expect(response).to redirect_to(admin_account_path(user.account_id)) end end diff --git a/spec/controllers/admin/warning_presets_controller_spec.rb b/spec/controllers/admin/warning_presets_controller_spec.rb new file mode 100644 index 0000000000..b32a58e990 --- /dev/null +++ b/spec/controllers/admin/warning_presets_controller_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::WarningPresetsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end + + describe 'GET #edit' do + let(:account_warning_preset) { Fabricate(:account_warning_preset) } + + it 'returns http success and renders edit' do + get :edit, params: { id: account_warning_preset.id } + + expect(response).to have_http_status(:success) + expect(response).to render_template(:edit) + end + end + + describe 'POST #create' do + context 'with valid data' do + it 'creates a new account_warning_preset and redirects' do + expect do + post :create, params: { account_warning_preset: { text: 'The account_warning_preset text.' } } + end.to change(AccountWarningPreset, :count).by(1) + + expect(response).to redirect_to(admin_warning_presets_path) + end + end + + context 'with invalid data' do + it 'does creates a new account_warning_preset and renders index' do + expect do + post :create, params: { account_warning_preset: { text: '' } } + end.to_not change(AccountWarningPreset, :count) + + expect(response).to render_template(:index) + end + end + end + + describe 'PUT #update' do + let(:account_warning_preset) { Fabricate(:account_warning_preset, text: 'Original text') } + + context 'with valid data' do + it 'updates the account_warning_preset and redirects' do + put :update, params: { id: account_warning_preset.id, account_warning_preset: { text: 'Updated text.' } } + + expect(response).to redirect_to(admin_warning_presets_path) + end + end + + context 'with invalid data' do + it 'does not update the account_warning_preset and renders index' do + put :update, params: { id: account_warning_preset.id, account_warning_preset: { text: '' } } + + expect(response).to render_template(:edit) + end + end + end + + describe 'DELETE #destroy' do + let!(:account_warning_preset) { Fabricate(:account_warning_preset) } + + it 'destroys the account_warning_preset and redirects' do + delete :destroy, params: { id: account_warning_preset.id } + + expect { account_warning_preset.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect(response).to redirect_to(admin_warning_presets_path) + end + end +end diff --git a/spec/controllers/admin/webhooks/secrets_controller_spec.rb b/spec/controllers/admin/webhooks/secrets_controller_spec.rb new file mode 100644 index 0000000000..291a10fba5 --- /dev/null +++ b/spec/controllers/admin/webhooks/secrets_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Webhooks::SecretsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'POST #rotate' do + let(:webhook) { Fabricate(:webhook) } + + it 'returns http success' do + post :rotate, params: { webhook_id: webhook.id } + + expect(response).to redirect_to(admin_webhook_path(webhook)) + end + end +end diff --git a/spec/controllers/admin/webhooks_controller_spec.rb b/spec/controllers/admin/webhooks_controller_spec.rb new file mode 100644 index 0000000000..0ccfbbcc6e --- /dev/null +++ b/spec/controllers/admin/webhooks_controller_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::WebhooksController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(:success) + end + end + + describe 'GET #new' do + it 'returns http success and renders view' do + get :new + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + + describe 'POST #create' do + it 'creates a new webhook record with valid data' do + expect do + post :create, params: { webhook: { url: 'https://example.com/hook', events: ['account.approved'] } } + end.to change(Webhook, :count).by(1) + + expect(response).to be_redirect + end + + it 'does not create a new webhook record with invalid data' do + expect do + post :create, params: { webhook: { url: 'https://example.com/hook', events: [] } } + end.to_not change(Webhook, :count) + + expect(response).to have_http_status(:success) + expect(response).to render_template(:new) + end + end + + context 'with an existing record' do + let!(:webhook) { Fabricate(:webhook, events: ['account.created', 'report.created']) } + + describe 'GET #show' do + it 'returns http success and renders view' do + get :show, params: { id: webhook.id } + + expect(response).to have_http_status(:success) + expect(response).to render_template(:show) + end + end + + describe 'GET #edit' do + it 'returns http success and renders view' do + get :edit, params: { id: webhook.id } + + expect(response).to have_http_status(:success) + expect(response).to render_template(:edit) + end + end + + describe 'PUT #update' do + it 'updates the record with valid data' do + put :update, params: { id: webhook.id, webhook: { url: 'https://example.com/new/location' } } + + expect(webhook.reload.url).to match(%r{new/location}) + expect(response).to redirect_to(admin_webhook_path(webhook)) + end + + it 'does not update the record with invalid data' do + expect do + put :update, params: { id: webhook.id, webhook: { url: '' } } + end.to_not change(webhook, :url) + + expect(response).to have_http_status(:success) + expect(response).to render_template(:edit) + end + end + + describe 'DELETE #destroy' do + it 'destroys the record' do + expect do + delete :destroy, params: { id: webhook.id } + end.to change(Webhook, :count).by(-1) + + expect(response).to redirect_to(admin_webhooks_path) + end + end + end +end diff --git a/spec/controllers/api/base_controller_spec.rb b/spec/controllers/api/base_controller_spec.rb index c286b8cbfc..db1e8777f7 100644 --- a/spec/controllers/api/base_controller_spec.rb +++ b/spec/controllers/api/base_controller_spec.rb @@ -2,9 +2,11 @@ require 'rails_helper' -class FakeService; end - describe Api::BaseController do + before do + stub_const('FakeService', Class.new) + end + controller do def success head 200 @@ -15,6 +17,12 @@ describe Api::BaseController do end end + it 'returns private cache control headers by default' do + routes.draw { get 'success' => 'api/base#success' } + get :success + expect(response.headers['Cache-Control']).to include('private, no-store') + end + describe 'forgery protection' do before do routes.draw { post 'success' => 'api/base#success' } @@ -66,7 +74,11 @@ describe Api::BaseController do end describe 'error handling' do - ERRORS_WITH_CODES = { + before do + routes.draw { get 'error' => 'api/base#error' } + end + + { ActiveRecord::RecordInvalid => 422, Mastodon::ValidationError => 422, ActiveRecord::RecordNotFound => 404, @@ -74,18 +86,13 @@ describe Api::BaseController do HTTP::Error => 503, OpenSSL::SSL::SSLError => 503, Mastodon::NotPermittedError => 403, - } - - before do - routes.draw { get 'error' => 'api/base#error' } - end - - ERRORS_WITH_CODES.each do |error, code| + }.each do |error, code| it "Handles error class of #{error}" do - expect(FakeService).to receive(:new).and_raise(error) + allow(FakeService).to receive(:new).and_raise(error) get 'error' expect(response).to have_http_status(code) + expect(FakeService).to have_received(:new) end end end diff --git a/spec/controllers/api/oembed_controller_spec.rb b/spec/controllers/api/oembed_controller_spec.rb index b9082bde1e..70248c3982 100644 --- a/spec/controllers/api/oembed_controller_spec.rb +++ b/spec/controllers/api/oembed_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::OEmbedController, type: :controller do +RSpec.describe Api::OEmbedController do render_views let(:alice) { Fabricate(:account, username: 'alice') } @@ -15,5 +17,9 @@ RSpec.describe Api::OEmbedController, type: :controller do it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end end diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb index b2557d9575..a677aaad0e 100644 --- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::CredentialsController do @@ -35,7 +37,7 @@ describe Api::V1::Accounts::CredentialsController do source: { privacy: 'unlisted', sensitive: true, - } + }, } end @@ -44,6 +46,7 @@ describe Api::V1::Accounts::CredentialsController do end it 'updates account info' do + user.reload user.account.reload expect(user.account.display_name).to eq("Alice Isn't Dead") @@ -51,7 +54,7 @@ describe Api::V1::Accounts::CredentialsController do expect(user.account.avatar).to exist expect(user.account.header).to exist expect(user.setting_default_privacy).to eq('unlisted') - expect(user.setting_default_sensitive).to eq(true) + expect(user.setting_default_sensitive).to be(true) end it 'queues up an account update distribution' do @@ -70,15 +73,17 @@ describe Api::V1::Accounts::CredentialsController do it 'returns http success' do expect(response).to have_http_status(200) end - end + end - describe 'with invalid data' do + describe 'with a too long profile bio' do before do - patch :update, params: { note: 'This is too long. ' * 30 } + note = 'This is too long. ' + note += 'a' * (Account::MAX_NOTE_LENGTH - note.length + 1) + patch :update, params: { note: note } end it 'returns http unprocessable entity' do - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(422) end end end @@ -86,20 +91,20 @@ describe Api::V1::Accounts::CredentialsController do context 'without an oauth token' do before do - allow(controller).to receive(:doorkeeper_token) { nil } + allow(controller).to receive(:doorkeeper_token).and_return(nil) end describe 'GET #show' do it 'returns http unauthorized' do get :show - expect(response).to have_http_status(:unauthorized) + expect(response).to have_http_status(401) end end describe 'PATCH #update' do it 'returns http unauthorized' do patch :update, params: { note: 'Foo' } - expect(response).to have_http_status(:unauthorized) + expect(response).to have_http_status(401) end end end diff --git a/spec/controllers/api/v1/accounts/familiar_followers_controller_spec.rb b/spec/controllers/api/v1/accounts/familiar_followers_controller_spec.rb new file mode 100644 index 0000000000..bb075261f3 --- /dev/null +++ b/spec/controllers/api/v1/accounts/familiar_followers_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Accounts::FamiliarFollowersController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:follows') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb b/spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb new file mode 100644 index 0000000000..53ac1e2a7a --- /dev/null +++ b/spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Accounts::FeaturedTagsController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/accounts/follower_accounts_controller_spec.rb b/spec/controllers/api/v1/accounts/follower_accounts_controller_spec.rb index 1e6e1d8e0a..7a387f326f 100644 --- a/spec/controllers/api/v1/accounts/follower_accounts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/follower_accounts_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::FollowerAccountsController do @@ -26,7 +28,7 @@ describe Api::V1::Accounts::FollowerAccountsController do get :index, params: { account_id: account.id, limit: 2 } expect(body_as_json.size).to eq 2 - expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s]) + expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) end it 'does not return blocked users' do @@ -56,7 +58,7 @@ describe Api::V1::Accounts::FollowerAccountsController do get :index, params: { account_id: account.id, limit: 2 } expect(body_as_json.size).to eq 2 - expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s]) + expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) end end end diff --git a/spec/controllers/api/v1/accounts/following_accounts_controller_spec.rb b/spec/controllers/api/v1/accounts/following_accounts_controller_spec.rb index cc962c6ee3..b69b0bd395 100644 --- a/spec/controllers/api/v1/accounts/following_accounts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/following_accounts_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::FollowingAccountsController do @@ -26,7 +28,7 @@ describe Api::V1::Accounts::FollowingAccountsController do get :index, params: { account_id: account.id, limit: 2 } expect(body_as_json.size).to eq 2 - expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s]) + expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) end it 'does not return blocked users' do @@ -56,7 +58,7 @@ describe Api::V1::Accounts::FollowingAccountsController do get :index, params: { account_id: account.id, limit: 2 } expect(body_as_json.size).to eq 2 - expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s]) + expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) end end end diff --git a/spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb b/spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb new file mode 100644 index 0000000000..6351de7616 --- /dev/null +++ b/spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Accounts::IdentityProofsController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/accounts/lists_controller_spec.rb b/spec/controllers/api/v1/accounts/lists_controller_spec.rb index d714856335..418839cfa5 100644 --- a/spec/controllers/api/v1/accounts/lists_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/lists_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::ListsController do diff --git a/spec/controllers/api/v1/accounts/lookup_controller_spec.rb b/spec/controllers/api/v1/accounts/lookup_controller_spec.rb new file mode 100644 index 0000000000..37407766f2 --- /dev/null +++ b/spec/controllers/api/v1/accounts/lookup_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Accounts::LookupController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #show' do + it 'returns http success' do + get :show, params: { account_id: account.id, acct: account.acct } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/accounts/notes_controller_spec.rb b/spec/controllers/api/v1/accounts/notes_controller_spec.rb index 42c2d8a86f..4107105afd 100644 --- a/spec/controllers/api/v1/accounts/notes_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/notes_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::NotesController do @@ -41,7 +43,7 @@ describe Api::V1::Accounts::NotesController do it 'does not create account note' do subject - expect(AccountNote.where(account_id: user.account.id, target_account_id: account.id).exists?).to be_falsey + expect(AccountNote.where(account_id: user.account.id, target_account_id: account.id)).to_not exist end end end diff --git a/spec/controllers/api/v1/accounts/pins_controller_spec.rb b/spec/controllers/api/v1/accounts/pins_controller_spec.rb index 19bba093e4..b4aa9b7116 100644 --- a/spec/controllers/api/v1/accounts/pins_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/pins_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::Accounts::PinsController, type: :controller do +RSpec.describe Api::V1::Accounts::PinsController do let(:john) { Fabricate(:user) } let(:kevin) { Fabricate(:user) } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: john.id, scopes: 'write:accounts') } diff --git a/spec/controllers/api/v1/accounts/relationships_controller_spec.rb b/spec/controllers/api/v1/accounts/relationships_controller_spec.rb index 69ad0d061a..993ead636a 100644 --- a/spec/controllers/api/v1/accounts/relationships_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/relationships_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::RelationshipsController do @@ -19,7 +21,7 @@ describe Api::V1::Accounts::RelationshipsController do lewis.follow!(user.account) end - context 'provided only one ID' do + context 'when provided only one ID' do before do get :index, params: { id: simon.id } end @@ -37,7 +39,7 @@ describe Api::V1::Accounts::RelationshipsController do end end - context 'provided multiple IDs' do + context 'when provided multiple IDs' do before do get :index, params: { id: [simon.id, lewis.id] } end @@ -46,25 +48,32 @@ describe Api::V1::Accounts::RelationshipsController do expect(response).to have_http_status(200) end - it 'returns JSON with correct data' do - json = body_as_json + context 'when there is returned JSON data' do + let(:json) { body_as_json } - expect(json).to be_a Enumerable - expect(json.first[:id]).to eq simon.id.to_s - expect(json.first[:following]).to be true - expect(json.first[:showing_reblogs]).to be true - expect(json.first[:followed_by]).to be false - expect(json.first[:muting]).to be false - expect(json.first[:requested]).to be false - expect(json.first[:domain_blocking]).to be false + it 'returns an enumerable json' do + expect(json).to be_a Enumerable + end - expect(json.second[:id]).to eq lewis.id.to_s - expect(json.second[:following]).to be false - expect(json.second[:showing_reblogs]).to be false - expect(json.second[:followed_by]).to be true - expect(json.second[:muting]).to be false - expect(json.second[:requested]).to be false - expect(json.second[:domain_blocking]).to be false + it 'returns a correct first element' do + expect(json.first[:id]).to eq simon.id.to_s + expect(json.first[:following]).to be true + expect(json.first[:showing_reblogs]).to be true + expect(json.first[:followed_by]).to be false + expect(json.first[:muting]).to be false + expect(json.first[:requested]).to be false + expect(json.first[:domain_blocking]).to be false + end + + it 'returns a correct second element' do + expect(json.second[:id]).to eq lewis.id.to_s + expect(json.second[:following]).to be false + expect(json.second[:showing_reblogs]).to be false + expect(json.second[:followed_by]).to be true + expect(json.second[:muting]).to be false + expect(json.second[:requested]).to be false + expect(json.second[:domain_blocking]).to be false + end end it 'returns JSON with correct data on cached requests too' do diff --git a/spec/controllers/api/v1/accounts/search_controller_spec.rb b/spec/controllers/api/v1/accounts/search_controller_spec.rb index 5b23bff681..aa9455a4a3 100644 --- a/spec/controllers/api/v1/accounts/search_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/search_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::Accounts::SearchController, type: :controller do +RSpec.describe Api::V1::Accounts::SearchController do render_views let(:user) { Fabricate(:user) } diff --git a/spec/controllers/api/v1/accounts/statuses_controller_spec.rb b/spec/controllers/api/v1/accounts/statuses_controller_spec.rb index b962b3398f..cb62afcf93 100644 --- a/spec/controllers/api/v1/accounts/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/statuses_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Accounts::StatusesController do @@ -16,6 +18,11 @@ describe Api::V1::Accounts::StatusesController do get :index, params: { account_id: user.account.id, limit: 1 } expect(response).to have_http_status(200) + end + + it 'returns expected headers' do + get :index, params: { account_id: user.account.id, limit: 1 } + expect(response.headers['Link'].links.size).to eq(2) end @@ -28,15 +35,25 @@ describe Api::V1::Accounts::StatusesController do end context 'with exclude replies' do + let!(:older_statuses) { user.account.statuses.destroy_all } + let!(:status) { Fabricate(:status, account: user.account) } + let!(:status_self_reply) { Fabricate(:status, account: user.account, thread: status) } + before do - Fabricate(:status, account: user.account, thread: Fabricate(:status)) + Fabricate(:status, account: user.account, thread: Fabricate(:status)) # Reply to another user + get :index, params: { account_id: user.account.id, exclude_replies: true } end it 'returns http success' do - get :index, params: { account_id: user.account.id, exclude_replies: true } - expect(response).to have_http_status(200) end + + it 'returns posts along with self replies' do + json = body_as_json + post_ids = json.map { |item| item[:id].to_i }.sort + + expect(post_ids).to eq [status.id, status_self_reply.id] + end end context 'with only own pinned' do @@ -55,8 +72,11 @@ describe Api::V1::Accounts::StatusesController do let(:account) { Fabricate(:account, username: 'bob', domain: 'example.com') } let(:status) { Fabricate(:status, account: account) } let(:private_status) { Fabricate(:status, account: account, visibility: :private) } - let!(:pin) { Fabricate(:status_pin, account: account, status: status) } - let!(:private_pin) { Fabricate(:status_pin, account: account, status: private_status) } + + before do + Fabricate(:status_pin, account: account, status: status) + Fabricate(:status_pin, account: account, status: private_status) + end it 'returns http success' do get :index, params: { account_id: account.id, pinned: true } @@ -79,7 +99,7 @@ describe Api::V1::Accounts::StatusesController do it 'lists both the public and the private statuses' do get :index, params: { account_id: account.id, pinned: true } json = body_as_json - expect(json.map { |item| item[:id].to_i }).to match_array([status.id, private_status.id]) + expect(json.map { |item| item[:id].to_i }).to contain_exactly(status.id, private_status.id) end end end diff --git a/spec/controllers/api/v1/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts_controller_spec.rb index d6bbcefd77..0daec691a5 100644 --- a/spec/controllers/api/v1/accounts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::AccountsController, type: :controller do +RSpec.describe Api::V1::AccountsController do render_views let(:user) { Fabricate(:user) } @@ -11,14 +13,6 @@ RSpec.describe Api::V1::AccountsController, type: :controller do allow(controller).to receive(:doorkeeper_token) { token } end - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - describe 'POST #create' do let(:app) { Fabricate(:application) } let(:token) { Doorkeeper::AccessToken.find_or_create_for(application: app, resource_owner: nil, scopes: 'read write', use_refresh_token: false) } @@ -28,7 +22,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do post :create, params: { username: 'test', password: '12345678', email: 'hello@world.tld', agreement: agreement } end - context 'given truthy agreement' do + context 'when given truthy agreement' do let(:agreement) { 'true' } it 'returns http success' do @@ -46,32 +40,18 @@ RSpec.describe Api::V1::AccountsController, type: :controller do end end - context 'given no agreement' do + context 'when given no agreement' do it 'returns http unprocessable entity' do expect(response).to have_http_status(422) end end end - describe 'GET #show' do - let(:scopes) { 'read:accounts' } - - before do - get :show, params: { id: user.account.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - end - describe 'POST #follow' do let(:scopes) { 'write:follows' } let(:other_account) { Fabricate(:account, username: 'bob', locked: locked) } - context do + context 'when posting to an other account' do before do post :follow, params: { id: other_account.id } end @@ -119,7 +99,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do end end - context 'modifying follow options' do + context 'when modifying follow options' do let(:locked) { false } before do diff --git a/spec/controllers/api/v1/admin/account_actions_controller_spec.rb b/spec/controllers/api/v1/admin/account_actions_controller_spec.rb deleted file mode 100644 index 462c2cfa99..0000000000 --- a/spec/controllers/api/v1/admin/account_actions_controller_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::Admin::AccountActionsController, type: :controller do - render_views - - let(:role) { UserRole.find_by(name: 'Moderator') } - let(:user) { Fabricate(:user, role: role) } - let(:scopes) { 'admin:read admin:write' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - let(:account) { Fabricate(:account) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { UserRole.find_by(name: wrong_role) } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - describe 'POST #create' do - context do - before do - post :create, params: { account_id: account.id, type: 'disable' } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'performs action against account' do - expect(account.reload.user_disabled?).to be true - end - - it 'logs action' do - log_item = Admin::ActionLog.last - - expect(log_item).to_not be_nil - expect(log_item.action).to eq :disable - expect(log_item.account_id).to eq user.account_id - expect(log_item.target_id).to eq account.user.id - end - end - - context 'with no type' do - before do - post :create, params: { account_id: account.id } - end - - it 'returns http unprocessable entity' do - expect(response).to have_http_status(422) - end - end - end -end diff --git a/spec/controllers/api/v1/admin/accounts_controller_spec.rb b/spec/controllers/api/v1/admin/accounts_controller_spec.rb index 8d35b86cb2..36f6e398cb 100644 --- a/spec/controllers/api/v1/admin/accounts_controller_spec.rb +++ b/spec/controllers/api/v1/admin/accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::Admin::AccountsController, type: :controller do +RSpec.describe Api::V1::Admin::AccountsController do render_views let(:role) { UserRole.find_by(name: 'Moderator') } @@ -13,22 +15,6 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do allow(controller).to receive(:doorkeeper_token) { token } end - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { UserRole.find_by(name: wrong_role) } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - describe 'GET #index' do let!(:remote_account) { Fabricate(:account, domain: 'example.org') } let!(:other_remote_account) { Fabricate(:account, domain: 'foo.bar') } @@ -65,7 +51,7 @@ RSpec.describe Api::V1::Admin::AccountsController, type: :controller do it "returns the correct accounts (#{expected_results.inspect})" do json = body_as_json - expect(json.map { |a| a[:id].to_i }).to eq (expected_results.map { |symbol| send(symbol).id }) + expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id }) end end end diff --git a/spec/controllers/api/v1/admin/dimensions_controller_spec.rb b/spec/controllers/api/v1/admin/dimensions_controller_spec.rb new file mode 100644 index 0000000000..ea18efe383 --- /dev/null +++ b/spec/controllers/api/v1/admin/dimensions_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::DimensionsController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'POST #create' do + it 'returns http success' do + post :create, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb b/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb deleted file mode 100644 index 8100363f6b..0000000000 --- a/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb +++ /dev/null @@ -1,130 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::Admin::DomainAllowsController, type: :controller do - render_views - - let(:role) { UserRole.find_by(name: 'Admin') } - let(:user) { Fabricate(:user, role: role) } - let(:scopes) { 'admin:read admin:write' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { UserRole.find_by(name: wrong_role) } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - describe 'GET #index' do - let!(:domain_allow) { Fabricate(:domain_allow) } - - before do - get :index - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns the expected domain allows' do - json = body_as_json - expect(json.length).to eq 1 - expect(json[0][:id].to_i).to eq domain_allow.id - end - end - - describe 'GET #show' do - let!(:domain_allow) { Fabricate(:domain_allow) } - - before do - get :show, params: { id: domain_allow.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns expected domain name' do - json = body_as_json - expect(json[:domain]).to eq domain_allow.domain - end - end - - describe 'DELETE #destroy' do - let!(:domain_allow) { Fabricate(:domain_allow) } - - before do - delete :destroy, params: { id: domain_allow.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'deletes the block' do - expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil - end - end - - describe 'POST #create' do - let!(:domain_allow) { Fabricate(:domain_allow, domain: 'example.com') } - - context do - before do - post :create, params: { domain: 'foo.bar.com' } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns expected domain name' do - json = body_as_json - expect(json[:domain]).to eq 'foo.bar.com' - end - - it 'creates a domain block' do - expect(DomainAllow.find_by(domain: 'foo.bar.com')).to_not be_nil - end - end - - context 'with invalid domain name' do - before do - post :create, params: { domain: 'foo bar' } - end - - it 'returns http unprocessable entity' do - expect(response).to have_http_status(422) - end - end - end -end diff --git a/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb b/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb deleted file mode 100644 index 606def602f..0000000000 --- a/spec/controllers/api/v1/admin/domain_blocks_controller_spec.rb +++ /dev/null @@ -1,179 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::Admin::DomainBlocksController, type: :controller do - render_views - - let(:role) { UserRole.find_by(name: 'Admin') } - let(:user) { Fabricate(:user, role: role) } - let(:scopes) { 'admin:read admin:write' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { UserRole.find_by(name: wrong_role) } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - describe 'GET #index' do - let!(:block) { Fabricate(:domain_block) } - - before do - get :index - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns the expected domain blocks' do - json = body_as_json - expect(json.length).to eq 1 - expect(json[0][:id].to_i).to eq block.id - end - end - - describe 'GET #show' do - let!(:block) { Fabricate(:domain_block) } - - before do - get :show, params: { id: block.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns expected domain name' do - json = body_as_json - expect(json[:domain]).to eq block.domain - end - end - - describe 'PUT #update' do - let!(:remote_account) { Fabricate(:account, domain: 'example.com') } - let(:domain_block) { Fabricate(:domain_block, domain: 'example.com', severity: original_severity) } - - before do - BlockDomainService.new.call(domain_block) - end - - let(:subject) do - post :update, params: { id: domain_block.id, domain: 'example.com', severity: new_severity } - end - - context 'downgrading a domain suspension to silence' do - let(:original_severity) { 'suspend' } - let(:new_severity) { 'silence' } - - it 'changes the block severity' do - expect { subject }.to change { domain_block.reload.severity }.from('suspend').to('silence') - end - - it 'undoes individual suspensions' do - expect { subject }.to change { remote_account.reload.suspended? }.from(true).to(false) - end - - it 'performs individual silences' do - expect { subject }.to change { remote_account.reload.silenced? }.from(false).to(true) - end - end - - context 'upgrading a domain silence to suspend' do - let(:original_severity) { 'silence' } - let(:new_severity) { 'suspend' } - - it 'changes the block severity' do - expect { subject }.to change { domain_block.reload.severity }.from('silence').to('suspend') - end - - it 'undoes individual silences' do - expect { subject }.to change { remote_account.reload.silenced? }.from(true).to(false) - end - - it 'performs individual suspends' do - expect { subject }.to change { remote_account.reload.suspended? }.from(false).to(true) - end - end - end - - describe 'DELETE #destroy' do - let!(:block) { Fabricate(:domain_block) } - - before do - delete :destroy, params: { id: block.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'deletes the block' do - expect(DomainBlock.find_by(id: block.id)).to be_nil - end - end - - describe 'POST #create' do - let(:existing_block_domain) { 'example.com' } - let!(:block) { Fabricate(:domain_block, domain: existing_block_domain, severity: :suspend) } - - before do - post :create, params: { domain: 'foo.bar.com', severity: :silence } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns expected domain name' do - json = body_as_json - expect(json[:domain]).to eq 'foo.bar.com' - end - - it 'creates a domain block' do - expect(DomainBlock.find_by(domain: 'foo.bar.com')).to_not be_nil - end - - context 'when a stricter domain block already exists' do - let(:existing_block_domain) { 'bar.com' } - - it 'returns http unprocessable entity' do - expect(response).to have_http_status(422) - end - - it 'renders existing domain block in error' do - json = body_as_json - expect(json[:existing_domain_block][:domain]).to eq existing_block_domain - end - end - end -end diff --git a/spec/controllers/api/v1/admin/measures_controller_spec.rb b/spec/controllers/api/v1/admin/measures_controller_spec.rb new file mode 100644 index 0000000000..03727a6329 --- /dev/null +++ b/spec/controllers/api/v1/admin/measures_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::MeasuresController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'POST #create' do + it 'returns http success' do + post :create, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/admin/reports_controller_spec.rb b/spec/controllers/api/v1/admin/reports_controller_spec.rb deleted file mode 100644 index 880e72030a..0000000000 --- a/spec/controllers/api/v1/admin/reports_controller_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::Admin::ReportsController, type: :controller do - render_views - - let(:role) { UserRole.find_by(name: 'Moderator') } - let(:user) { Fabricate(:user, role: role) } - let(:scopes) { 'admin:read admin:write' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - let(:report) { Fabricate(:report) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { UserRole.find_by(name: wrong_role) } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - describe 'GET #index' do - before do - get :index - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - describe 'GET #show' do - before do - get :show, params: { id: report.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - describe 'POST #resolve' do - before do - post :resolve, params: { id: report.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - describe 'POST #reopen' do - before do - post :reopen, params: { id: report.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - describe 'POST #assign_to_self' do - before do - post :assign_to_self, params: { id: report.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - describe 'POST #unassign' do - before do - post :unassign, params: { id: report.id } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/controllers/api/v1/admin/retention_controller_spec.rb b/spec/controllers/api/v1/admin/retention_controller_spec.rb new file mode 100644 index 0000000000..2381dbcb48 --- /dev/null +++ b/spec/controllers/api/v1/admin/retention_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::RetentionController do + render_views + + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'POST #create' do + it 'returns http success' do + post :create, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/admin/trends/links/preview_card_providers_controller_spec.rb b/spec/controllers/api/v1/admin/trends/links/preview_card_providers_controller_spec.rb new file mode 100644 index 0000000000..76e215440d --- /dev/null +++ b/spec/controllers/api/v1/admin/trends/links/preview_card_providers_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::Trends::Links::PreviewCardProvidersController do + render_views + + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:account) { Fabricate(:account) } + let(:preview_card_provider) { Fabricate(:preview_card_provider) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end + + describe 'POST #approve' do + before do + post :approve, params: { id: preview_card_provider.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + + describe 'POST #reject' do + before do + post :reject, params: { id: preview_card_provider.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/admin/trends/links_controller_spec.rb b/spec/controllers/api/v1/admin/trends/links_controller_spec.rb new file mode 100644 index 0000000000..d9aa06824d --- /dev/null +++ b/spec/controllers/api/v1/admin/trends/links_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::Trends::LinksController do + render_views + + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:account) { Fabricate(:account) } + let(:preview_card) { Fabricate(:preview_card) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end + + describe 'POST #approve' do + before do + post :approve, params: { id: preview_card.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + + describe 'POST #reject' do + before do + post :reject, params: { id: preview_card.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/admin/trends/statuses_controller_spec.rb b/spec/controllers/api/v1/admin/trends/statuses_controller_spec.rb new file mode 100644 index 0000000000..4d80055ac0 --- /dev/null +++ b/spec/controllers/api/v1/admin/trends/statuses_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::Trends::StatusesController do + render_views + + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:account) { Fabricate(:account) } + let(:status) { Fabricate(:status) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end + + describe 'POST #approve' do + before do + post :approve, params: { id: status.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + + describe 'POST #reject' do + before do + post :reject, params: { id: status.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/admin/trends/tags_controller_spec.rb b/spec/controllers/api/v1/admin/trends/tags_controller_spec.rb new file mode 100644 index 0000000000..0b8eb8c3b8 --- /dev/null +++ b/spec/controllers/api/v1/admin/trends/tags_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Admin::Trends::TagsController do + render_views + + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:account) { Fabricate(:account) } + let(:tag) { Fabricate(:tag) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end + + describe 'POST #approve' do + before do + post :approve, params: { id: tag.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + + describe 'POST #reject' do + before do + post :reject, params: { id: tag.id } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/announcements/reactions_controller_spec.rb b/spec/controllers/api/v1/announcements/reactions_controller_spec.rb index 72620e2421..10aaa553f5 100644 --- a/spec/controllers/api/v1/announcements/reactions_controller_spec.rb +++ b/spec/controllers/api/v1/announcements/reactions_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::Announcements::ReactionsController, type: :controller do +RSpec.describe Api::V1::Announcements::ReactionsController do render_views let(:user) { Fabricate(:user) } @@ -15,7 +15,7 @@ RSpec.describe Api::V1::Announcements::ReactionsController, type: :controller do context 'without token' do it 'returns http unauthorized' do put :update, params: { announcement_id: announcement.id, id: '😂' } - expect(response).to have_http_status :unauthorized + expect(response).to have_http_status 401 end end @@ -43,7 +43,7 @@ RSpec.describe Api::V1::Announcements::ReactionsController, type: :controller do context 'without token' do it 'returns http unauthorized' do delete :destroy, params: { announcement_id: announcement.id, id: '😂' } - expect(response).to have_http_status :unauthorized + expect(response).to have_http_status 401 end end diff --git a/spec/controllers/api/v1/announcements_controller_spec.rb b/spec/controllers/api/v1/announcements_controller_spec.rb index 6ee46b60eb..15d94b4512 100644 --- a/spec/controllers/api/v1/announcements_controller_spec.rb +++ b/spec/controllers/api/v1/announcements_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::AnnouncementsController, type: :controller do +RSpec.describe Api::V1::AnnouncementsController do render_views let(:user) { Fabricate(:user) } @@ -15,7 +15,7 @@ RSpec.describe Api::V1::AnnouncementsController, type: :controller do context 'without token' do it 'returns http unprocessable entity' do get :index - expect(response).to have_http_status :unprocessable_entity + expect(response).to have_http_status 422 end end @@ -35,7 +35,7 @@ RSpec.describe Api::V1::AnnouncementsController, type: :controller do context 'without token' do it 'returns http unauthorized' do post :dismiss, params: { id: announcement.id } - expect(response).to have_http_status :unauthorized + expect(response).to have_http_status 401 end end diff --git a/spec/controllers/api/v1/apps/credentials_controller_spec.rb b/spec/controllers/api/v1/apps/credentials_controller_spec.rb deleted file mode 100644 index 0f811d5f37..0000000000 --- a/spec/controllers/api/v1/apps/credentials_controller_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'rails_helper' - -describe Api::V1::Apps::CredentialsController do - render_views - - let(:token) { Fabricate(:accessible_access_token, scopes: 'read', application: Fabricate(:application)) } - - context 'with an oauth token' do - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #show' do - before do - get :show - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'does not contain client credentials' do - json = body_as_json - - expect(json).to_not have_key(:client_secret) - expect(json).to_not have_key(:client_id) - end - end - end - - context 'without an oauth token' do - before do - allow(controller).to receive(:doorkeeper_token) { nil } - end - - describe 'GET #show' do - it 'returns http unauthorized' do - get :show - expect(response).to have_http_status(:unauthorized) - end - end - end -end diff --git a/spec/controllers/api/v1/blocks_controller_spec.rb b/spec/controllers/api/v1/blocks_controller_spec.rb index 0e5c8296d8..eaafc1b4fa 100644 --- a/spec/controllers/api/v1/blocks_controller_spec.rb +++ b/spec/controllers/api/v1/blocks_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::BlocksController, type: :controller do +RSpec.describe Api::V1::BlocksController do render_views let(:user) { Fabricate(:user) } @@ -11,13 +13,13 @@ RSpec.describe Api::V1::BlocksController, type: :controller do describe 'GET #index' do it 'limits according to limit parameter' do - 2.times.map { Fabricate(:block, account: user.account) } + Array.new(2) { Fabricate(:block, account: user.account) } get :index, params: { limit: 1 } expect(body_as_json.size).to eq 1 end it 'queries blocks in range according to max_id' do - blocks = 2.times.map { Fabricate(:block, account: user.account) } + blocks = Array.new(2) { Fabricate(:block, account: user.account) } get :index, params: { max_id: blocks[1] } @@ -26,7 +28,7 @@ RSpec.describe Api::V1::BlocksController, type: :controller do end it 'queries blocks in range according to since_id' do - blocks = 2.times.map { Fabricate(:block, account: user.account) } + blocks = Array.new(2) { Fabricate(:block, account: user.account) } get :index, params: { since_id: blocks[0] } @@ -35,15 +37,15 @@ RSpec.describe Api::V1::BlocksController, type: :controller do end it 'sets pagination header for next path' do - blocks = 2.times.map { Fabricate(:block, account: user.account) } + blocks = Array.new(2) { Fabricate(:block, account: user.account) } get :index, params: { limit: 1, since_id: blocks[0] } - expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq api_v1_blocks_url(limit: 1, max_id: blocks[1]) + expect(response.headers['Link'].find_link(%w(rel next)).href).to eq api_v1_blocks_url(limit: 1, max_id: blocks[1]) end it 'sets pagination header for previous path' do block = Fabricate(:block, account: user.account) get :index - expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq api_v1_blocks_url(since_id: block) + expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq api_v1_blocks_url(since_id: block) end it 'returns http success' do diff --git a/spec/controllers/api/v1/bookmarks_controller_spec.rb b/spec/controllers/api/v1/bookmarks_controller_spec.rb deleted file mode 100644 index d7c5847b0c..0000000000 --- a/spec/controllers/api/v1/bookmarks_controller_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::BookmarksController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:bookmarks') } - - describe 'GET #index' do - context 'without token' do - it 'returns http unauthorized' do - get :index - expect(response).to have_http_status :unauthorized - end - end - - context 'with token' do - context 'without read scope' do - before do - allow(controller).to receive(:doorkeeper_token) do - Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: '') - end - end - - it 'returns http forbidden' do - get :index - expect(response).to have_http_status :forbidden - end - end - - context 'without valid resource owner' do - before do - token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') - user.destroy! - - allow(controller).to receive(:doorkeeper_token) { token } - end - - it 'returns http unprocessable entity' do - get :index - expect(response).to have_http_status :unprocessable_entity - end - end - - context 'with read scope and valid resource owner' do - before do - allow(controller).to receive(:doorkeeper_token) do - Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') - end - end - - it 'shows bookmarks owned by the user' do - bookmarked_by_user = Fabricate(:bookmark, account: user.account) - bookmarked_by_others = Fabricate(:bookmark) - - get :index - - expect(assigns(:statuses)).to match_array [bookmarked_by_user.status] - end - - it 'adds pagination headers if necessary' do - bookmark = Fabricate(:bookmark, account: user.account) - - get :index, params: { limit: 1 } - - expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq "http://test.host/api/v1/bookmarks?limit=1&max_id=#{bookmark.id}" - expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq "http://test.host/api/v1/bookmarks?limit=1&min_id=#{bookmark.id}" - end - - it 'does not add pagination headers if not necessary' do - get :index - - expect(response.headers['Link']).to eq nil - end - end - end - end -end diff --git a/spec/controllers/api/v1/conversations_controller_spec.rb b/spec/controllers/api/v1/conversations_controller_spec.rb index 1ec26d5203..28d7c7f3ae 100644 --- a/spec/controllers/api/v1/conversations_controller_spec.rb +++ b/spec/controllers/api/v1/conversations_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::ConversationsController, type: :controller do +RSpec.describe Api::V1::ConversationsController do render_views let!(:user) { Fabricate(:user, account_attributes: { username: 'alice' }) } diff --git a/spec/controllers/api/v1/custom_emojis_controller_spec.rb b/spec/controllers/api/v1/custom_emojis_controller_spec.rb index fe8daa7c5a..08af57f405 100644 --- a/spec/controllers/api/v1/custom_emojis_controller_spec.rb +++ b/spec/controllers/api/v1/custom_emojis_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::CustomEmojisController, type: :controller do +RSpec.describe Api::V1::CustomEmojisController do render_views describe 'GET #index' do diff --git a/spec/controllers/api/v1/directories_controller_spec.rb b/spec/controllers/api/v1/directories_controller_spec.rb new file mode 100644 index 0000000000..308a8874c8 --- /dev/null +++ b/spec/controllers/api/v1/directories_controller_spec.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::DirectoriesController do + render_views + + let(:user) { Fabricate(:user, confirmed_at: nil) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:follows') } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #show' do + context 'with no params' do + before do + local_unconfirmed_account = Fabricate( + :account, + domain: nil, + user: Fabricate(:user, confirmed_at: nil, approved: true), + username: 'local_unconfirmed' + ) + local_unconfirmed_account.create_account_stat! + + local_unapproved_account = Fabricate( + :account, + domain: nil, + user: Fabricate(:user, confirmed_at: 10.days.ago), + username: 'local_unapproved' + ) + local_unapproved_account.create_account_stat! + local_unapproved_account.user.update(approved: false) + + local_undiscoverable_account = Fabricate( + :account, + domain: nil, + user: Fabricate(:user, confirmed_at: 10.days.ago, approved: true), + discoverable: false, + username: 'local_undiscoverable' + ) + local_undiscoverable_account.create_account_stat! + + excluded_from_timeline_account = Fabricate( + :account, + domain: 'host.example', + discoverable: true, + username: 'remote_excluded_from_timeline' + ) + excluded_from_timeline_account.create_account_stat! + Fabricate(:block, account: user.account, target_account: excluded_from_timeline_account) + + domain_blocked_account = Fabricate( + :account, + domain: 'test.example', + discoverable: true, + username: 'remote_domain_blocked' + ) + domain_blocked_account.create_account_stat! + Fabricate(:account_domain_block, account: user.account, domain: 'test.example') + end + + it 'returns the local discoverable account and the remote discoverable account' do + local_discoverable_account = Fabricate( + :account, + domain: nil, + user: Fabricate(:user, confirmed_at: 10.days.ago, approved: true), + discoverable: true, + username: 'local_discoverable' + ) + local_discoverable_account.create_account_stat! + + eligible_remote_account = Fabricate( + :account, + domain: 'host.example', + discoverable: true, + username: 'eligible_remote' + ) + eligible_remote_account.create_account_stat! + + get :show + + expect(response).to have_http_status(200) + expect(body_as_json.size).to eq(2) + expect(body_as_json.pluck(:id)).to contain_exactly(eligible_remote_account.id.to_s, local_discoverable_account.id.to_s) + end + end + + context 'when asking for local accounts only' do + it 'returns only the local accounts' do + user = Fabricate(:user, confirmed_at: 10.days.ago, approved: true) + local_account = Fabricate(:account, domain: nil, user: user) + remote_account = Fabricate(:account, domain: 'host.example') + local_account.create_account_stat! + remote_account.create_account_stat! + + get :show, params: { local: '1' } + + expect(response).to have_http_status(200) + expect(body_as_json.size).to eq(1) + expect(body_as_json.first[:id]).to include(local_account.id.to_s) + expect(response.body).to_not include(remote_account.id.to_s) + end + end + + context 'when ordered by active' do + it 'returns accounts in order of most recent status activity' do + old_stat = Fabricate(:account_stat, last_status_at: 1.day.ago) + new_stat = Fabricate(:account_stat, last_status_at: 1.minute.ago) + + get :show, params: { order: 'active' } + + expect(response).to have_http_status(200) + expect(body_as_json.size).to eq(2) + expect(body_as_json.first[:id]).to include(new_stat.account_id.to_s) + expect(body_as_json.second[:id]).to include(old_stat.account_id.to_s) + end + end + + context 'when ordered by new' do + it 'returns accounts in order of creation' do + account_old = Fabricate(:account_stat).account + travel_to 10.seconds.from_now + account_new = Fabricate(:account_stat).account + + get :show, params: { order: 'new' } + + expect(response).to have_http_status(200) + expect(body_as_json.size).to eq(2) + expect(body_as_json.first[:id]).to include(account_new.id.to_s) + expect(body_as_json.second[:id]).to include(account_old.id.to_s) + end + end + end +end diff --git a/spec/controllers/api/v1/domain_blocks_controller_spec.rb b/spec/controllers/api/v1/domain_blocks_controller_spec.rb deleted file mode 100644 index d9dc1bdbfe..0000000000 --- a/spec/controllers/api/v1/domain_blocks_controller_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::DomainBlocksController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before do - user.account.block_domain!('example.com') - allow(controller).to receive(:doorkeeper_token) { token } - end - - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - describe 'GET #show' do - let(:scopes) { 'read:blocks' } - - before do - get :show, params: { limit: 1 } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns blocked domains' do - expect(body_as_json.first).to eq 'example.com' - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - end - - describe 'POST #create' do - let(:scopes) { 'write:blocks' } - - before do - post :create, params: { domain: 'example.org' } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'creates a domain block' do - expect(user.account.domain_blocking?('example.org')).to be true - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - end - - describe 'DELETE #destroy' do - let(:scopes) { 'write:blocks' } - - before do - delete :destroy, params: { domain: 'example.com' } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'deletes a domain block' do - expect(user.account.domain_blocking?('example.com')).to be false - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - end -end diff --git a/spec/controllers/api/v1/emails/confirmations_controller_spec.rb b/spec/controllers/api/v1/emails/confirmations_controller_spec.rb deleted file mode 100644 index 15ac31cbc5..0000000000 --- a/spec/controllers/api/v1/emails/confirmations_controller_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::Emails::ConfirmationsController, type: :controller do - let(:confirmed_at) { nil } - let(:user) { Fabricate(:user, confirmed_at: confirmed_at) } - let(:app) { Fabricate(:application) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes, application: app) } - let(:scopes) { 'write' } - - describe '#create' do - context 'with an oauth token' do - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - context 'from a random app' do - it 'returns http forbidden' do - post :create - expect(response).to have_http_status(:forbidden) - end - end - - context 'from an app that created the account' do - before do - user.update(created_by_application: token.application) - end - - context 'when the account is already confirmed' do - let(:confirmed_at) { Time.now.utc } - - it 'returns http forbidden' do - post :create - expect(response).to have_http_status(:forbidden) - end - - context 'but user changed e-mail and has not confirmed it' do - before do - user.update(email: 'foo@bar.com') - end - - it 'returns http success' do - post :create - expect(response).to have_http_status(:success) - end - end - end - - context 'when the account is unconfirmed' do - it 'returns http success' do - post :create - expect(response).to have_http_status(:success) - end - end - end - end - - context 'without an oauth token' do - it 'returns http unauthorized' do - post :create - expect(response).to have_http_status(:unauthorized) - end - end - end -end diff --git a/spec/controllers/api/v1/endorsements_controller_spec.rb b/spec/controllers/api/v1/endorsements_controller_spec.rb index ad5ff400f5..738804bb7b 100644 --- a/spec/controllers/api/v1/endorsements_controller_spec.rb +++ b/spec/controllers/api/v1/endorsements_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::EndorsementsController, type: :controller do +RSpec.describe Api::V1::EndorsementsController do let(:user) { Fabricate(:user) } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } diff --git a/spec/controllers/api/v1/favourites_controller_spec.rb b/spec/controllers/api/v1/favourites_controller_spec.rb index 231f765008..c9ca046be0 100644 --- a/spec/controllers/api/v1/favourites_controller_spec.rb +++ b/spec/controllers/api/v1/favourites_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::FavouritesController, type: :controller do +RSpec.describe Api::V1::FavouritesController do render_views let(:user) { Fabricate(:user) } @@ -10,7 +12,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do context 'without token' do it 'returns http unauthorized' do get :index - expect(response).to have_http_status :unauthorized + expect(response).to have_http_status 401 end end @@ -24,7 +26,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do it 'returns http forbidden' do get :index - expect(response).to have_http_status :forbidden + expect(response).to have_http_status 403 end end @@ -38,7 +40,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do it 'returns http unprocessable entity' do get :index - expect(response).to have_http_status :unprocessable_entity + expect(response).to have_http_status 422 end end @@ -55,7 +57,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do get :index - expect(assigns(:statuses)).to match_array [favourite_by_user.status] + expect(assigns(:statuses)).to contain_exactly(favourite_by_user.status) end it 'adds pagination headers if necessary' do @@ -63,14 +65,14 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do get :index, params: { limit: 1 } - expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq "http://test.host/api/v1/favourites?limit=1&max_id=#{favourite.id}" - expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq "http://test.host/api/v1/favourites?limit=1&min_id=#{favourite.id}" + expect(response.headers['Link'].find_link(%w(rel next)).href).to eq "http://test.host/api/v1/favourites?limit=1&max_id=#{favourite.id}" + expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq "http://test.host/api/v1/favourites?limit=1&min_id=#{favourite.id}" end it 'does not add pagination headers if not necessary' do get :index - expect(response.headers['Link']).to eq nil + expect(response.headers['Link']).to be_nil end end end diff --git a/spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb b/spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb new file mode 100644 index 0000000000..54c63dcc6f --- /dev/null +++ b/spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::FeaturedTags::SuggestionsController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index, params: { account_id: account.id, limit: 2 } + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/filters_controller_spec.rb b/spec/controllers/api/v1/filters_controller_spec.rb index 8acb46a007..8ccd2f4d66 100644 --- a/spec/controllers/api/v1/filters_controller_spec.rb +++ b/spec/controllers/api/v1/filters_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::FiltersController, type: :controller do +RSpec.describe Api::V1::FiltersController do render_views let(:user) { Fabricate(:user) } diff --git a/spec/controllers/api/v1/follow_requests_controller_spec.rb b/spec/controllers/api/v1/follow_requests_controller_spec.rb deleted file mode 100644 index 856ba2a1c0..0000000000 --- a/spec/controllers/api/v1/follow_requests_controller_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::FollowRequestsController, type: :controller do - render_views - - let(:user) { Fabricate(:user, account_attributes: { locked: true }) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - let(:follower) { Fabricate(:account) } - - before do - FollowService.new.call(follower, user.account) - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - let(:scopes) { 'read:follows' } - - before do - get :index, params: { limit: 1 } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - describe 'POST #authorize' do - let(:scopes) { 'write:follows' } - - before do - post :authorize, params: { id: follower.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'allows follower to follow' do - expect(follower.following?(user.account)).to be true - end - - it 'returns JSON with followed_by=true' do - json = body_as_json - - expect(json[:followed_by]).to be true - end - end - - describe 'POST #reject' do - let(:scopes) { 'write:follows' } - - before do - post :reject, params: { id: follower.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'removes follow request' do - expect(FollowRequest.where(target_account: user.account, account: follower).count).to eq 0 - end - - it 'returns JSON with followed_by=false' do - json = body_as_json - - expect(json[:followed_by]).to be false - end - end -end diff --git a/spec/controllers/api/v1/followed_tags_controller_spec.rb b/spec/controllers/api/v1/followed_tags_controller_spec.rb index 2191350ef6..c1a366d4e3 100644 --- a/spec/controllers/api/v1/followed_tags_controller_spec.rb +++ b/spec/controllers/api/v1/followed_tags_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::FollowedTagsController, type: :controller do +RSpec.describe Api::V1::FollowedTagsController do render_views let(:user) { Fabricate(:user) } diff --git a/spec/controllers/api/v1/instances/activity_controller_spec.rb b/spec/controllers/api/v1/instances/activity_controller_spec.rb index 159792ee01..b446a521f8 100644 --- a/spec/controllers/api/v1/instances/activity_controller_spec.rb +++ b/spec/controllers/api/v1/instances/activity_controller_spec.rb @@ -2,14 +2,14 @@ require 'rails_helper' -RSpec.describe Api::V1::Instances::ActivityController, type: :controller do +RSpec.describe Api::V1::Instances::ActivityController do describe 'GET #show' do it 'returns 200' do get :show expect(response).to have_http_status(200) end - context '!Setting.activity_api_enabled' do + context 'with !Setting.activity_api_enabled' do it 'returns 404' do Setting.activity_api_enabled = false diff --git a/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb b/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb new file mode 100644 index 0000000000..08f505c3d4 --- /dev/null +++ b/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Instances::DomainBlocksController do + render_views + + describe 'GET #index' do + it 'returns http success' do + Setting.show_domain_blocks = 'all' + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb b/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb new file mode 100644 index 0000000000..58c0d4b8f1 --- /dev/null +++ b/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Instances::ExtendedDescriptionsController do + render_views + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/instances/peers_controller_spec.rb b/spec/controllers/api/v1/instances/peers_controller_spec.rb index 12a214a83a..92b1019154 100644 --- a/spec/controllers/api/v1/instances/peers_controller_spec.rb +++ b/spec/controllers/api/v1/instances/peers_controller_spec.rb @@ -2,14 +2,14 @@ require 'rails_helper' -RSpec.describe Api::V1::Instances::PeersController, type: :controller do +RSpec.describe Api::V1::Instances::PeersController do describe 'GET #index' do it 'returns 200' do get :index expect(response).to have_http_status(200) end - context '!Setting.peers_api_enabled' do + context 'with !Setting.peers_api_enabled' do it 'returns 404' do Setting.peers_api_enabled = false diff --git a/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb b/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb new file mode 100644 index 0000000000..ac0bed9dc6 --- /dev/null +++ b/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Instances::PrivacyPoliciesController do + render_views + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/instances/rules_controller_spec.rb b/spec/controllers/api/v1/instances/rules_controller_spec.rb new file mode 100644 index 0000000000..5af50239b0 --- /dev/null +++ b/spec/controllers/api/v1/instances/rules_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Instances::RulesController do + render_views + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb b/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb new file mode 100644 index 0000000000..88bcc40341 --- /dev/null +++ b/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Instances::TranslationLanguagesController do + describe 'GET #show' do + context 'when no translation service is configured' do + it 'returns empty language matrix' do + get :show + + expect(response).to have_http_status(200) + expect(body_as_json).to eq({}) + end + end + + context 'when a translation service is configured' do + before do + service = instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] }) + allow(TranslationService).to receive_messages(configured?: true, configured: service) + end + + it 'returns language matrix' do + get :show + + expect(response).to have_http_status(200) + expect(body_as_json).to eq({ und: %w(en de), en: ['de'] }) + end + end + end +end diff --git a/spec/controllers/api/v1/instances_controller_spec.rb b/spec/controllers/api/v1/instances_controller_spec.rb index 842669d965..fcc2c9288c 100644 --- a/spec/controllers/api/v1/instances_controller_spec.rb +++ b/spec/controllers/api/v1/instances_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::InstancesController, type: :controller do +RSpec.describe Api::V1::InstancesController do render_views let(:user) { Fabricate(:user) } diff --git a/spec/controllers/api/v1/lists/accounts_controller_spec.rb b/spec/controllers/api/v1/lists/accounts_controller_spec.rb index 526d8b5616..d4550dd769 100644 --- a/spec/controllers/api/v1/lists/accounts_controller_spec.rb +++ b/spec/controllers/api/v1/lists/accounts_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Api::V1::Lists::AccountsController do @@ -27,17 +29,48 @@ describe Api::V1::Lists::AccountsController do let(:scopes) { 'write:lists' } let(:bob) { Fabricate(:account, username: 'bob') } - before do - user.account.follow!(bob) - post :create, params: { list_id: list.id, account_ids: [bob.id] } + context 'when the added account is followed' do + before do + user.account.follow!(bob) + post :create, params: { list_id: list.id, account_ids: [bob.id] } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'adds account to the list' do + expect(list.accounts.include?(bob)).to be true + end end - it 'returns http success' do - expect(response).to have_http_status(200) + context 'when the added account has been sent a follow request' do + before do + user.account.follow_requests.create!(target_account: bob) + post :create, params: { list_id: list.id, account_ids: [bob.id] } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'adds account to the list' do + expect(list.accounts.include?(bob)).to be true + end end - it 'adds account to the list' do - expect(list.accounts.include?(bob)).to be true + context 'when the added account is not followed' do + before do + post :create, params: { list_id: list.id, account_ids: [bob.id] } + end + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + + it 'does not add the account to the list' do + expect(list.accounts.include?(bob)).to be false + end end end diff --git a/spec/controllers/api/v1/lists_controller_spec.rb b/spec/controllers/api/v1/lists_controller_spec.rb deleted file mode 100644 index 71a8094e68..0000000000 --- a/spec/controllers/api/v1/lists_controller_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::ListsController, type: :controller do - render_views - - let!(:user) { Fabricate(:user) } - let!(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - let!(:list) { Fabricate(:list, account: user.account) } - - before { allow(controller).to receive(:doorkeeper_token) { token } } - - describe 'GET #index' do - let(:scopes) { 'read:lists' } - - it 'returns http success' do - get :index - expect(response).to have_http_status(200) - end - end - - describe 'GET #show' do - let(:scopes) { 'read:lists' } - - it 'returns http success' do - get :show, params: { id: list.id } - expect(response).to have_http_status(200) - end - end - - describe 'POST #create' do - let(:scopes) { 'write:lists' } - - before do - post :create, params: { title: 'Foo bar' } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'creates list' do - expect(List.where(account: user.account).count).to eq 2 - expect(List.last.title).to eq 'Foo bar' - end - end - - describe 'PUT #update' do - let(:scopes) { 'write:lists' } - - before do - put :update, params: { id: list.id, title: 'Updated title' } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the list' do - expect(list.reload.title).to eq 'Updated title' - end - end - - describe 'DELETE #destroy' do - let(:scopes) { 'write:lists' } - - before do - delete :destroy, params: { id: list.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'deletes the list' do - expect(List.find_by(id: list.id)).to be_nil - end - end -end diff --git a/spec/controllers/api/v1/markers_controller_spec.rb b/spec/controllers/api/v1/markers_controller_spec.rb index ba0f3c3221..64e9dcafb6 100644 --- a/spec/controllers/api/v1/markers_controller_spec.rb +++ b/spec/controllers/api/v1/markers_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::MarkersController, type: :controller do +RSpec.describe Api::V1::MarkersController do render_views let!(:user) { Fabricate(:user) } @@ -42,7 +44,7 @@ RSpec.describe Api::V1::MarkersController, type: :controller do it 'creates a marker' do expect(user.markers.first.timeline).to eq 'home' - expect(user.markers.first.last_read_id).to eq 69420 + expect(user.markers.first.last_read_id).to eq 69_420 end end @@ -58,7 +60,7 @@ RSpec.describe Api::V1::MarkersController, type: :controller do it 'updates a marker' do expect(user.markers.first.timeline).to eq 'home' - expect(user.markers.first.last_read_id).to eq 70120 + expect(user.markers.first.last_read_id).to eq 70_120 end end end diff --git a/spec/controllers/api/v1/media_controller_spec.rb b/spec/controllers/api/v1/media_controller_spec.rb index a1f6ddb244..94b2a0a98f 100644 --- a/spec/controllers/api/v1/media_controller_spec.rb +++ b/spec/controllers/api/v1/media_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::MediaController, type: :controller do +RSpec.describe Api::V1::MediaController do render_views let(:user) { Fabricate(:user) } @@ -13,29 +15,25 @@ RSpec.describe Api::V1::MediaController, type: :controller do describe 'POST #create' do describe 'with paperclip errors' do context 'when imagemagick cant identify the file type' do - before do - expect_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Errors::NotIdentifiedByImageMagickError) - post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } - end - it 'returns http 422' do - expect(response).to have_http_status(:unprocessable_entity) + allow_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Errors::NotIdentifiedByImageMagickError) + post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } + + expect(response).to have_http_status(422) end end context 'when there is a generic error' do - before do - expect_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Error) - post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } - end - it 'returns http 422' do + allow_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Error) + post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } + expect(response).to have_http_status(500) end end end - context 'image/jpeg' do + context 'with image/jpeg' do before do post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } end @@ -57,7 +55,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do end end - context 'image/gif' do + context 'with image/gif' do before do post :create, params: { file: fixture_file_upload('attachment.gif', 'image/gif') } end @@ -79,7 +77,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do end end - context 'video/webm' do + context 'with video/webm' do before do post :create, params: { file: fixture_file_upload('attachment.webm', 'video/webm') } end @@ -106,7 +104,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do it 'returns http not found' do put :update, params: { id: media.id, description: 'Lorem ipsum!!!' } - expect(response).to have_http_status(:not_found) + expect(response).to have_http_status(404) end end @@ -126,7 +124,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do let(:status) { Fabricate(:status, account: user.account) } it 'returns http not found' do - expect(response).to have_http_status(:not_found) + expect(response).to have_http_status(404) end end end diff --git a/spec/controllers/api/v1/mutes_controller_spec.rb b/spec/controllers/api/v1/mutes_controller_spec.rb deleted file mode 100644 index 8176815d4e..0000000000 --- a/spec/controllers/api/v1/mutes_controller_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::MutesController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:scopes) { 'read:mutes' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before { allow(controller).to receive(:doorkeeper_token) { token } } - - describe 'GET #index' do - it 'limits according to limit parameter' do - 2.times.map { Fabricate(:mute, account: user.account) } - get :index, params: { limit: 1 } - expect(body_as_json.size).to eq 1 - end - - it 'queries mutes in range according to max_id' do - mutes = 2.times.map { Fabricate(:mute, account: user.account) } - - get :index, params: { max_id: mutes[1] } - - expect(body_as_json.size).to eq 1 - expect(body_as_json[0][:id]).to eq mutes[0].target_account_id.to_s - end - - it 'queries mutes in range according to since_id' do - mutes = 2.times.map { Fabricate(:mute, account: user.account) } - - get :index, params: { since_id: mutes[0] } - - expect(body_as_json.size).to eq 1 - expect(body_as_json[0][:id]).to eq mutes[1].target_account_id.to_s - end - - it 'sets pagination header for next path' do - mutes = 2.times.map { Fabricate(:mute, account: user.account) } - get :index, params: { limit: 1, since_id: mutes[0] } - expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq api_v1_mutes_url(limit: 1, max_id: mutes[1]) - end - - it 'sets pagination header for previous path' do - mute = Fabricate(:mute, account: user.account) - get :index - expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq api_v1_mutes_url(since_id: mute) - end - - it 'returns http success' do - get :index - expect(response).to have_http_status(200) - end - - context 'with wrong scopes' do - let(:scopes) { 'write:mutes' } - - it 'returns http forbidden' do - get :index - expect(response).to have_http_status(403) - end - end - end -end diff --git a/spec/controllers/api/v1/notifications_controller_spec.rb b/spec/controllers/api/v1/notifications_controller_spec.rb index 46e177c0ec..6615848b83 100644 --- a/spec/controllers/api/v1/notifications_controller_spec.rb +++ b/spec/controllers/api/v1/notifications_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::NotificationsController, type: :controller do +RSpec.describe Api::V1::NotificationsController do render_views let(:user) { Fabricate(:user, account_attributes: { username: 'alice' }) } @@ -65,24 +67,13 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do get :index end - it 'returns http success' do + it 'returns expected notification types', :aggregate_failures do expect(response).to have_http_status(200) - end - it 'includes reblog' do - expect(body_as_json.map { |x| x[:type] }).to include 'reblog' - end - - it 'includes mention' do - expect(body_as_json.map { |x| x[:type] }).to include 'mention' - end - - it 'includes favourite' do - expect(body_as_json.map { |x| x[:type] }).to include 'favourite' - end - - it 'includes follow' do - expect(body_as_json.map { |x| x[:type] }).to include 'follow' + expect(body_json_types).to include 'reblog' + expect(body_json_types).to include 'mention' + expect(body_json_types).to include 'favourite' + expect(body_json_types).to include 'follow' end end @@ -91,12 +82,14 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do get :index, params: { account_id: third.account.id } end - it 'returns http success' do + it 'returns only notifications from specified user', :aggregate_failures do expect(response).to have_http_status(200) + + expect(body_json_account_ids.uniq).to eq [third.account.id.to_s] end - it 'returns only notifications from specified user' do - expect(body_as_json.map { |x| x[:account][:id] }.uniq).to eq [third.account.id.to_s] + def body_json_account_ids + body_as_json.map { |x| x[:account][:id] } end end @@ -105,27 +98,23 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do get :index, params: { account_id: 'foo' } end - it 'returns http success' do + it 'returns nothing', :aggregate_failures do expect(response).to have_http_status(200) - end - it 'returns nothing' do expect(body_as_json.size).to eq 0 end end - describe 'with excluded_types param' do + describe 'with exclude_types param' do before do get :index, params: { exclude_types: %w(mention) } end - it 'returns http success' do + it 'returns everything but excluded type', :aggregate_failures do expect(response).to have_http_status(200) - end - it 'returns everything but excluded type' do expect(body_as_json.size).to_not eq 0 - expect(body_as_json.map { |x| x[:type] }.uniq).to_not include 'mention' + expect(body_json_types.uniq).to_not include 'mention' end end @@ -134,13 +123,15 @@ RSpec.describe Api::V1::NotificationsController, type: :controller do get :index, params: { types: %w(mention) } end - it 'returns http success' do + it 'returns only requested type', :aggregate_failures do expect(response).to have_http_status(200) - end - it 'returns only requested type' do - expect(body_as_json.map { |x| x[:type] }.uniq).to eq ['mention'] + expect(body_json_types.uniq).to eq ['mention'] end end + + def body_json_types + body_as_json.pluck(:type) + end end end diff --git a/spec/controllers/api/v1/polls/votes_controller_spec.rb b/spec/controllers/api/v1/polls/votes_controller_spec.rb index d7a9c19704..7abd2a1b17 100644 --- a/spec/controllers/api/v1/polls/votes_controller_spec.rb +++ b/spec/controllers/api/v1/polls/votes_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::Polls::VotesController, type: :controller do +RSpec.describe Api::V1::Polls::VotesController do render_views let(:user) { Fabricate(:user) } diff --git a/spec/controllers/api/v1/polls_controller_spec.rb b/spec/controllers/api/v1/polls_controller_spec.rb deleted file mode 100644 index f0d9eaf92d..0000000000 --- a/spec/controllers/api/v1/polls_controller_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::PollsController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:scopes) { 'read:statuses' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before { allow(controller).to receive(:doorkeeper_token) { token } } - - describe 'GET #show' do - let(:poll) { Fabricate(:poll, status: Fabricate(:status, visibility: visibility)) } - - before do - get :show, params: { id: poll.id } - end - - context 'when parent status is public' do - let(:visibility) { 'public' } - - it 'returns http success' do - expect(response).to have_http_status(200) - end - end - - context 'when parent status is private' do - let(:visibility) { 'private' } - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - end -end diff --git a/spec/controllers/api/v1/preferences_controller_spec.rb b/spec/controllers/api/v1/preferences_controller_spec.rb new file mode 100644 index 0000000000..79cc3066e1 --- /dev/null +++ b/spec/controllers/api/v1/preferences_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::PreferencesController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/push/subscriptions_controller_spec.rb b/spec/controllers/api/v1/push/subscriptions_controller_spec.rb index 9487251e16..1681914680 100644 --- a/spec/controllers/api/v1/push/subscriptions_controller_spec.rb +++ b/spec/controllers/api/v1/push/subscriptions_controller_spec.rb @@ -5,13 +5,7 @@ require 'rails_helper' describe Api::V1::Push::SubscriptionsController do render_views - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'push') } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - + let(:user) { Fabricate(:user) } let(:create_payload) do { subscription: { @@ -20,10 +14,9 @@ describe Api::V1::Push::SubscriptionsController do p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=', auth: 'eH_C8rq2raXqlcBVDa1gLg==', }, - } + }, }.with_indifferent_access end - let(:alerts_payload) do { data: { @@ -37,10 +30,15 @@ describe Api::V1::Push::SubscriptionsController do mention: false, poll: true, status: false, - } - } + }, + }, }.with_indifferent_access end + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'push') } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end describe 'POST #create' do before do diff --git a/spec/controllers/api/v1/reports_controller_spec.rb b/spec/controllers/api/v1/reports_controller_spec.rb index dbc64e7047..f923ff0794 100644 --- a/spec/controllers/api/v1/reports_controller_spec.rb +++ b/spec/controllers/api/v1/reports_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::ReportsController, type: :controller do +RSpec.describe Api::V1::ReportsController do render_views let(:user) { Fabricate(:user) } @@ -20,10 +20,9 @@ RSpec.describe Api::V1::ReportsController, type: :controller do let(:target_account) { status.account } let(:category) { nil } let(:forward) { nil } - let(:rule_ids){ nil } + let(:rule_ids) { nil } before do - allow(AdminMailer).to receive(:new_report).and_return(double('email', deliver_later: nil)) post :create, params: { status_ids: [status.id], account_id: target_account.id, comment: 'reasons', category: category, rule_ids: rule_ids, forward: forward } end @@ -40,7 +39,7 @@ RSpec.describe Api::V1::ReportsController, type: :controller do end it 'sends e-mails to admins' do - expect(AdminMailer).to have_received(:new_report).with(admin.account, Report) + expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) end context 'when a status does not belong to the reported account' do @@ -69,7 +68,7 @@ RSpec.describe Api::V1::ReportsController, type: :controller do end it 'saves rule_ids' do - expect(target_account.targeted_reports.first.rule_ids).to match_array([rule.id]) + expect(target_account.targeted_reports.first.rule_ids).to contain_exactly(rule.id) end end end diff --git a/spec/controllers/api/v1/scheduled_statuses_controller_spec.rb b/spec/controllers/api/v1/scheduled_statuses_controller_spec.rb new file mode 100644 index 0000000000..256c4b272a --- /dev/null +++ b/spec/controllers/api/v1/scheduled_statuses_controller_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::ScheduledStatusesController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } + let(:account) { Fabricate(:account) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb b/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb deleted file mode 100644 index 46d7b6c0a5..0000000000 --- a/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Statuses::BookmarksController do - render_views - - let(:user) { Fabricate(:user) } - let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:bookmarks', application: app) } - - context 'with an oauth token' do - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'POST #create' do - let(:status) { Fabricate(:status, account: user.account) } - - before do - post :create, params: { status_id: status.id } - end - - context 'with public status' do - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'updates the bookmarked attribute' do - expect(user.account.bookmarked?(status)).to be true - end - - it 'returns json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:bookmarked]).to be true - end - end - - context 'with private status of not-followed account' do - let(:status) { Fabricate(:status, visibility: :private) } - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - end - - describe 'POST #destroy' do - context 'with public status' do - let(:status) { Fabricate(:status, account: user.account) } - - before do - Bookmark.find_or_create_by!(account: user.account, status: status) - post :destroy, params: { status_id: status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'updates the bookmarked attribute' do - expect(user.account.bookmarked?(status)).to be false - end - - it 'returns json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:bookmarked]).to be false - end - end - - context 'with public status when blocked by its author' do - let(:status) { Fabricate(:status) } - - before do - Bookmark.find_or_create_by!(account: user.account, status: status) - status.account.block!(user.account) - post :destroy, params: { status_id: status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the bookmarked attribute' do - expect(user.account.bookmarked?(status)).to be false - end - - it 'returns json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:bookmarked]).to be false - end - end - - context 'with private status that was not bookmarked' do - let(:status) { Fabricate(:status, visibility: :private) } - - before do - post :destroy, params: { status_id: status.id } - end - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - end - end -end diff --git a/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb b/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb index 7cc77f4308..01816743e5 100644 --- a/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/favourited_by_accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :controller do +RSpec.describe Api::V1::Statuses::FavouritedByAccountsController do render_views let(:user) { Fabricate(:user) } @@ -31,7 +33,7 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control it 'returns accounts who favorited the status' do get :index, params: { status_id: status.id, limit: 2 } expect(body_as_json.size).to eq 2 - expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s]) + expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) end it 'does not return blocked users' do @@ -45,7 +47,7 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control context 'without an oauth token' do before do - allow(controller).to receive(:doorkeeper_token) { nil } + allow(controller).to receive(:doorkeeper_token).and_return(nil) end context 'with a private status' do diff --git a/spec/controllers/api/v1/statuses/favourites_controller_spec.rb b/spec/controllers/api/v1/statuses/favourites_controller_spec.rb deleted file mode 100644 index 609957e3ef..0000000000 --- a/spec/controllers/api/v1/statuses/favourites_controller_spec.rb +++ /dev/null @@ -1,123 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Statuses::FavouritesController do - render_views - - let(:user) { Fabricate(:user) } - let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:favourites', application: app) } - - context 'with an oauth token' do - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'POST #create' do - let(:status) { Fabricate(:status, account: user.account) } - - before do - post :create, params: { status_id: status.id } - end - - context 'with public status' do - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the favourites count' do - expect(status.favourites.count).to eq 1 - end - - it 'updates the favourited attribute' do - expect(user.account.favourited?(status)).to be true - end - - it 'returns json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:favourites_count]).to eq 1 - expect(hash_body[:favourited]).to be true - end - end - - context 'with private status of not-followed account' do - let(:status) { Fabricate(:status, visibility: :private) } - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - end - - describe 'POST #destroy' do - context 'with public status' do - let(:status) { Fabricate(:status, account: user.account) } - - before do - FavouriteService.new.call(user.account, status) - post :destroy, params: { status_id: status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the favourites count' do - expect(status.favourites.count).to eq 0 - end - - it 'updates the favourited attribute' do - expect(user.account.favourited?(status)).to be false - end - - it 'returns json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:favourites_count]).to eq 0 - expect(hash_body[:favourited]).to be false - end - end - - context 'with public status when blocked by its author' do - let(:status) { Fabricate(:status) } - - before do - FavouriteService.new.call(user.account, status) - status.account.block!(user.account) - post :destroy, params: { status_id: status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the favourite attribute' do - expect(user.account.favourited?(status)).to be false - end - - it 'returns json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:favourited]).to be false - end - end - - context 'with private status that was not favourited' do - let(:status) { Fabricate(:status, visibility: :private) } - - before do - post :destroy, params: { status_id: status.id } - end - - it 'returns http not found' do - expect(response).to have_http_status(404) - end - end - end - end -end diff --git a/spec/controllers/api/v1/statuses/pins_controller_spec.rb b/spec/controllers/api/v1/statuses/pins_controller_spec.rb deleted file mode 100644 index 8bdaf8b548..0000000000 --- a/spec/controllers/api/v1/statuses/pins_controller_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Statuses::PinsController do - render_views - - let(:user) { Fabricate(:user) } - let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:accounts', application: app) } - - context 'with an oauth token' do - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'POST #create' do - let(:status) { Fabricate(:status, account: user.account) } - - before do - post :create, params: { status_id: status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the pinned attribute' do - expect(user.account.pinned?(status)).to be true - end - - it 'return json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:pinned]).to be true - end - end - - describe 'POST #destroy' do - let(:status) { Fabricate(:status, account: user.account) } - - before do - Fabricate(:status_pin, status: status, account: user.account) - post :destroy, params: { status_id: status.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the pinned attribute' do - expect(user.account.pinned?(status)).to be false - end - end - end -end diff --git a/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb index 8d4a6f91ca..756010af87 100644 --- a/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogged_by_accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::Statuses::RebloggedByAccountsController, type: :controller do +RSpec.describe Api::V1::Statuses::RebloggedByAccountsController do render_views let(:user) { Fabricate(:user) } @@ -31,7 +33,7 @@ RSpec.describe Api::V1::Statuses::RebloggedByAccountsController, type: :controll it 'returns accounts who reblogged the status' do get :index, params: { status_id: status.id, limit: 2 } expect(body_as_json.size).to eq 2 - expect([body_as_json[0][:id], body_as_json[1][:id]]).to match_array([alice.id.to_s, bob.id.to_s]) + expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s) end it 'does not return blocked users' do @@ -45,7 +47,7 @@ RSpec.describe Api::V1::Statuses::RebloggedByAccountsController, type: :controll context 'without an oauth token' do before do - allow(controller).to receive(:doorkeeper_token) { nil } + allow(controller).to receive(:doorkeeper_token).and_return(nil) end context 'with a private status' do diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb index 6eac02b232..16ce95dc22 100644 --- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb @@ -10,6 +10,12 @@ describe Api::V1::Statuses::ReblogsController do let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses', application: app) } context 'with an oauth token' do + around do |example| + Sidekiq::Testing.fake! do + example.run + end + end + before do allow(controller).to receive(:doorkeeper_token) { token } end diff --git a/spec/controllers/api/v1/statuses/translations_controller_spec.rb b/spec/controllers/api/v1/statuses/translations_controller_spec.rb new file mode 100644 index 0000000000..6257494ae1 --- /dev/null +++ b/spec/controllers/api/v1/statuses/translations_controller_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Statuses::TranslationsController do + render_views + + let(:user) { Fabricate(:user) } + let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses', application: app) } + + context 'with an oauth token' do + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'POST #create' do + let(:status) { Fabricate(:status, account: user.account, text: 'Hola', language: 'es') } + + 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 :create, params: { status_id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + end +end diff --git a/spec/controllers/api/v1/statuses_controller_spec.rb b/spec/controllers/api/v1/statuses_controller_spec.rb index 24810a5d27..c2bdba9ace 100644 --- a/spec/controllers/api/v1/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/statuses_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::StatusesController, type: :controller do +RSpec.describe Api::V1::StatusesController do render_views let(:user) { Fabricate(:user) } @@ -118,7 +120,7 @@ RSpec.describe Api::V1::StatusesController, type: :controller do describe 'POST #create' do let(:scopes) { 'write:statuses' } - context do + context 'with a basic status body' do before do post :create, params: { status: 'Hello world' } end @@ -133,6 +135,23 @@ RSpec.describe Api::V1::StatusesController, type: :controller do end end + context 'with a safeguard' do + let!(:alice) { Fabricate(:account, username: 'alice') } + let!(:bob) { Fabricate(:account, username: 'bob') } + + before do + post :create, params: { status: '@alice hm, @bob is really annoying lately', allowed_mentions: [alice.id] } + end + + it 'returns http unprocessable entity' do + expect(response).to have_http_status(422) + end + + it 'returns serialized extra accounts in body' do + expect(body_as_json[:unexpected_accounts].map { |a| a.slice(:id, :acct) }).to eq [{ id: bob.id.to_s, acct: bob.acct }] + end + end + context 'with missing parameters' do before do post :create, params: {} @@ -178,7 +197,7 @@ RSpec.describe Api::V1::StatusesController, type: :controller do end it 'removes the status' do - expect(Status.find_by(id: status.id)).to be nil + expect(Status.find_by(id: status.id)).to be_nil end end @@ -202,7 +221,7 @@ RSpec.describe Api::V1::StatusesController, type: :controller do context 'without an oauth token' do before do - allow(controller).to receive(:doorkeeper_token) { nil } + allow(controller).to receive(:doorkeeper_token).and_return(nil) end context 'with a private status' do diff --git a/spec/controllers/api/v1/streaming_controller_spec.rb b/spec/controllers/api/v1/streaming_controller_spec.rb index 4ab409a541..7014ed9b2b 100644 --- a/spec/controllers/api/v1/streaming_controller_spec.rb +++ b/spec/controllers/api/v1/streaming_controller_spec.rb @@ -25,7 +25,7 @@ describe Api::V1::StreamingController do context 'with streaming api on different host' do before(:each) do - Rails.configuration.x.streaming_api_base_url = 'wss://streaming-' + Rails.configuration.x.web_domain + Rails.configuration.x.streaming_api_base_url = "wss://streaming-#{Rails.configuration.x.web_domain}" @streaming_host = URI.parse(Rails.configuration.x.streaming_api_base_url).host end @@ -38,7 +38,7 @@ describe Api::V1::StreamingController do [:scheme, :path, :query, :fragment].each do |part| expect(redirect_to_uri.send(part)).to eq(request_uri.send(part)), "redirect target #{part}" end - expect(redirect_to_uri.host).to eq(@streaming_host), "redirect target host" + expect(redirect_to_uri.host).to eq(@streaming_host), 'redirect target host' end end end diff --git a/spec/controllers/api/v1/suggestions_controller_spec.rb b/spec/controllers/api/v1/suggestions_controller_spec.rb deleted file mode 100644 index 17f10b04fe..0000000000 --- a/spec/controllers/api/v1/suggestions_controller_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::SuggestionsController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read write') } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - let(:bob) { Fabricate(:account) } - let(:jeff) { Fabricate(:account) } - - before do - PotentialFriendshipTracker.record(user.account_id, bob.id, :reblog) - PotentialFriendshipTracker.record(user.account_id, jeff.id, :favourite) - - get :index - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns accounts' do - json = body_as_json - - expect(json.size).to be >= 1 - expect(json.map { |i| i[:id] }).to include *[bob, jeff].map { |i| i.id.to_s } - end - end -end diff --git a/spec/controllers/api/v1/tags_controller_spec.rb b/spec/controllers/api/v1/tags_controller_spec.rb deleted file mode 100644 index 216faad872..0000000000 --- a/spec/controllers/api/v1/tags_controller_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V1::TagsController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:scopes) { 'write:follows' } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before { allow(controller).to receive(:doorkeeper_token) { token } } - - describe 'GET #show' do - before do - get :show, params: { id: name } - end - - context 'with existing tag' do - let!(:tag) { Fabricate(:tag) } - let(:name) { tag.name } - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - end - - context 'with non-existing tag' do - let(:name) { 'hoge' } - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - end - end - - describe 'POST #follow' do - let!(:unrelated_tag) { Fabricate(:tag) } - - before do - TagFollow.create!(account: user.account, tag: unrelated_tag) - - post :follow, params: { id: name } - end - - context 'with existing tag' do - let!(:tag) { Fabricate(:tag) } - let(:name) { tag.name } - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'creates follow' do - expect(TagFollow.where(tag: tag, account: user.account).exists?).to be true - end - end - - context 'with non-existing tag' do - let(:name) { 'hoge' } - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'creates follow' do - expect(TagFollow.where(tag: Tag.find_by!(name: name), account: user.account).exists?).to be true - end - end - end - - describe 'POST #unfollow' do - let!(:tag) { Fabricate(:tag, name: 'foo') } - let!(:tag_follow) { Fabricate(:tag_follow, account: user.account, tag: tag) } - - before do - post :unfollow, params: { id: tag.name } - end - - it 'returns http success' do - expect(response).to have_http_status(:success) - end - - it 'removes the follow' do - expect(TagFollow.where(tag: tag, account: user.account).exists?).to be false - end - end -end diff --git a/spec/controllers/api/v1/timelines/direct_controller_spec.rb b/spec/controllers/api/v1/timelines/direct_controller_spec.rb new file mode 100644 index 0000000000..def67a0fea --- /dev/null +++ b/spec/controllers/api/v1/timelines/direct_controller_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V1::Timelines::DirectController do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } + + describe 'GET #show' do + it 'returns 200' do + allow(controller).to receive(:doorkeeper_token) { token } + get :show + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/timelines/home_controller_spec.rb b/spec/controllers/api/v1/timelines/home_controller_spec.rb deleted file mode 100644 index 131c2d92fa..0000000000 --- a/spec/controllers/api/v1/timelines/home_controller_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Timelines::HomeController do - render_views - - let(:user) { Fabricate(:user, current_sign_in_at: 1.day.ago) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - context 'with a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } - - describe 'GET #show' do - before do - follow = Fabricate(:follow, account: user.account) - PostStatusService.new.call(follow.target_account, text: 'New status for user home timeline.') - end - - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - expect(response.headers['Link'].links.size).to eq(2) - end - end - end - - context 'without a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: 'read') } - - describe 'GET #show' do - it 'returns http unprocessable entity' do - get :show - - expect(response).to have_http_status(:unprocessable_entity) - expect(response.headers['Link']).to be_nil - end - end - end -end diff --git a/spec/controllers/api/v1/timelines/list_controller_spec.rb b/spec/controllers/api/v1/timelines/list_controller_spec.rb index 526c66a058..4ef5d41af8 100644 --- a/spec/controllers/api/v1/timelines/list_controller_spec.rb +++ b/spec/controllers/api/v1/timelines/list_controller_spec.rb @@ -36,7 +36,7 @@ describe Api::V1::Timelines::ListController do describe 'GET #show' do it 'returns http not found' do get :show, params: { id: list.id } - expect(response).to have_http_status(:not_found) + expect(response).to have_http_status(404) end end end @@ -48,7 +48,7 @@ describe Api::V1::Timelines::ListController do it 'returns http unprocessable entity' do get :show, params: { id: list.id } - expect(response).to have_http_status(:unprocessable_entity) + expect(response).to have_http_status(422) expect(response.headers['Link']).to be_nil end end diff --git a/spec/controllers/api/v1/timelines/public_controller_spec.rb b/spec/controllers/api/v1/timelines/public_controller_spec.rb deleted file mode 100644 index 31e594d22b..0000000000 --- a/spec/controllers/api/v1/timelines/public_controller_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Timelines::PublicController do - render_views - - let(:user) { Fabricate(:user) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - context 'with a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } - - describe 'GET #show' do - before do - PostStatusService.new.call(user.account, text: 'New status from user for federated public timeline.') - end - - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - expect(response.headers['Link'].links.size).to eq(2) - end - end - - describe 'GET #show with local only' do - before do - PostStatusService.new.call(user.account, text: 'New status from user for local public timeline.') - end - - it 'returns http success' do - get :show, params: { local: true } - - expect(response).to have_http_status(200) - expect(response.headers['Link'].links.size).to eq(2) - end - end - end - - context 'without a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil) } - - describe 'GET #show' do - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - expect(response.headers['Link']).to be_nil - end - end - end -end diff --git a/spec/controllers/api/v1/timelines/tag_controller_spec.rb b/spec/controllers/api/v1/timelines/tag_controller_spec.rb index 7189110833..8896f02a77 100644 --- a/spec/controllers/api/v1/timelines/tag_controller_spec.rb +++ b/spec/controllers/api/v1/timelines/tag_controller_spec.rb @@ -5,36 +5,70 @@ require 'rails_helper' describe Api::V1::Timelines::TagController do render_views - let(:user) { Fabricate(:user) } + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') } before do allow(controller).to receive(:doorkeeper_token) { token } end - context 'with a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } + describe 'GET #show' do + subject do + get :show, params: { id: 'test' } + end - describe 'GET #show' do + before do + PostStatusService.new.call(user.account, text: 'It is a #test') + end + + context 'when the instance allows public preview' do before do - PostStatusService.new.call(user.account, text: 'It is a #test') + Setting.timeline_preview = true end - it 'returns http success' do - get :show, params: { id: 'test' } - expect(response).to have_http_status(200) - expect(response.headers['Link'].links.size).to eq(2) + context 'when the user is not authenticated' do + let(:token) { nil } + + it 'returns http success', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.headers['Link'].links.size).to eq(2) + end + end + + context 'when the user is authenticated' do + it 'returns http success', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.headers['Link'].links.size).to eq(2) + end end end - end - context 'without a user context' do - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil) } + context 'when the instance does not allow public preview' do + before do + Form::AdminSettings.new(timeline_preview: false).save + end - describe 'GET #show' do - it 'returns http success' do - get :show, params: { id: 'test' } - expect(response).to have_http_status(200) - expect(response.headers['Link']).to be_nil + context 'when the user is not authenticated' do + let(:token) { nil } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + + context 'when the user is authenticated' do + it 'returns http success', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(response.headers['Link'].links.size).to eq(2) + end end end end diff --git a/spec/controllers/api/v1/trends/links_controller_spec.rb b/spec/controllers/api/v1/trends/links_controller_spec.rb new file mode 100644 index 0000000000..71a7e2e477 --- /dev/null +++ b/spec/controllers/api/v1/trends/links_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Trends::LinksController do + render_views + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/trends/statuses_controller_spec.rb b/spec/controllers/api/v1/trends/statuses_controller_spec.rb new file mode 100644 index 0000000000..e9892bb140 --- /dev/null +++ b/spec/controllers/api/v1/trends/statuses_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Trends::StatusesController do + render_views + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v1/trends/tags_controller_spec.rb b/spec/controllers/api/v1/trends/tags_controller_spec.rb index d29551c56c..84370d8412 100644 --- a/spec/controllers/api/v1/trends/tags_controller_spec.rb +++ b/spec/controllers/api/v1/trends/tags_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V1::Trends::TagsController, type: :controller do +RSpec.describe Api::V1::Trends::TagsController do render_views describe 'GET #index' do diff --git a/spec/controllers/api/v2/admin/accounts_controller_spec.rb b/spec/controllers/api/v2/admin/accounts_controller_spec.rb index ebec4a13e8..635f645915 100644 --- a/spec/controllers/api/v2/admin/accounts_controller_spec.rb +++ b/spec/controllers/api/v2/admin/accounts_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V2::Admin::AccountsController, type: :controller do +RSpec.describe Api::V2::Admin::AccountsController do render_views let(:role) { UserRole.find_by(name: 'Moderator') } @@ -13,22 +15,6 @@ RSpec.describe Api::V2::Admin::AccountsController, type: :controller do allow(controller).to receive(:doorkeeper_token) { token } end - shared_examples 'forbidden for wrong scope' do |wrong_scope| - let(:scopes) { wrong_scope } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - - shared_examples 'forbidden for wrong role' do |wrong_role| - let(:role) { UserRole.find_by(name: wrong_role) } - - it 'returns http forbidden' do - expect(response).to have_http_status(403) - end - end - describe 'GET #index' do let!(:remote_account) { Fabricate(:account, domain: 'example.org') } let!(:other_remote_account) { Fabricate(:account, domain: 'foo.bar') } @@ -65,7 +51,7 @@ RSpec.describe Api::V2::Admin::AccountsController, type: :controller do it "returns the correct accounts (#{expected_results.inspect})" do json = body_as_json - expect(json.map { |a| a[:id].to_i }).to eq (expected_results.map { |symbol| send(symbol).id }) + expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id }) end end end diff --git a/spec/controllers/api/v2/filters/keywords_controller_spec.rb b/spec/controllers/api/v2/filters/keywords_controller_spec.rb index 1201a4ca23..057a9c3d00 100644 --- a/spec/controllers/api/v2/filters/keywords_controller_spec.rb +++ b/spec/controllers/api/v2/filters/keywords_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V2::Filters::KeywordsController, type: :controller do +RSpec.describe Api::V2::Filters::KeywordsController do render_views let(:user) { Fabricate(:user) } @@ -45,7 +47,7 @@ RSpec.describe Api::V2::Filters::KeywordsController, type: :controller do it 'returns a keyword' do json = body_as_json expect(json[:keyword]).to eq 'magic' - expect(json[:whole_word]).to eq false + expect(json[:whole_word]).to be false end it 'creates a keyword' do @@ -78,7 +80,7 @@ RSpec.describe Api::V2::Filters::KeywordsController, type: :controller do it 'returns expected data' do json = body_as_json expect(json[:keyword]).to eq 'foo' - expect(json[:whole_word]).to eq false + expect(json[:whole_word]).to be false end context "when trying to access another user's filter keyword" do diff --git a/spec/controllers/api/v2/filters/statuses_controller_spec.rb b/spec/controllers/api/v2/filters/statuses_controller_spec.rb index 9740c1eb30..588532ffd2 100644 --- a/spec/controllers/api/v2/filters/statuses_controller_spec.rb +++ b/spec/controllers/api/v2/filters/statuses_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V2::Filters::StatusesController, type: :controller do +RSpec.describe Api::V2::Filters::StatusesController do render_views let(:user) { Fabricate(:user) } @@ -64,7 +66,7 @@ RSpec.describe Api::V2::Filters::StatusesController, type: :controller do end describe 'GET #show' do - let(:scopes) { 'read:filters' } + let(:scopes) { 'read:filters' } let!(:status_filter) { Fabricate(:custom_filter_status, custom_filter: filter) } before do @@ -90,7 +92,7 @@ RSpec.describe Api::V2::Filters::StatusesController, type: :controller do end describe 'DELETE #destroy' do - let(:scopes) { 'write:filters' } + let(:scopes) { 'write:filters' } let(:status_filter) { Fabricate(:custom_filter_status, custom_filter: filter) } before do diff --git a/spec/controllers/api/v2/filters_controller_spec.rb b/spec/controllers/api/v2/filters_controller_spec.rb deleted file mode 100644 index cc0070d577..0000000000 --- a/spec/controllers/api/v2/filters_controller_spec.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'rails_helper' - -RSpec.describe Api::V2::FiltersController, type: :controller do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - let(:scopes) { 'read:filters' } - let!(:filter) { Fabricate(:custom_filter, account: user.account) } - - it 'returns http success' do - get :index - expect(response).to have_http_status(200) - end - end - - describe 'POST #create' do - let(:scopes) { 'write:filters' } - - before do - post :create, params: { title: 'magic', context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns a filter with keywords' do - json = body_as_json - expect(json[:title]).to eq 'magic' - expect(json[:filter_action]).to eq 'hide' - expect(json[:context]).to eq ['home'] - expect(json[:keywords].map { |keyword| keyword.slice(:keyword, :whole_word) }).to eq [{ keyword: 'magic', whole_word: true }] - end - - it 'creates a filter' do - filter = user.account.custom_filters.first - expect(filter).to_not be_nil - expect(filter.keywords.pluck(:keyword)).to eq ['magic'] - expect(filter.context).to eq %w(home) - expect(filter.irreversible?).to be true - expect(filter.expires_at).to be_nil - end - end - - describe 'GET #show' do - let(:scopes) { 'read:filters' } - let(:filter) { Fabricate(:custom_filter, account: user.account) } - - it 'returns http success' do - get :show, params: { id: filter.id } - expect(response).to have_http_status(200) - end - end - - describe 'PUT #update' do - let(:scopes) { 'write:filters' } - let!(:filter) { Fabricate(:custom_filter, account: user.account) } - let!(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } - - context 'updating filter parameters' do - before do - put :update, params: { id: filter.id, title: 'updated', context: %w(home public) } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the filter title' do - expect(filter.reload.title).to eq 'updated' - end - - it 'updates the filter context' do - expect(filter.reload.context).to eq %w(home public) - end - end - - context 'updating keywords in bulk' do - before do - allow(redis).to receive_messages(publish: nil) - put :update, params: { id: filter.id, keywords_attributes: [{ id: keyword.id, keyword: 'updated' }] } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'updates the keyword' do - expect(keyword.reload.keyword).to eq 'updated' - end - - it 'sends exactly one filters_changed event' do - expect(redis).to have_received(:publish).with("timeline:#{user.account.id}", Oj.dump(event: :filters_changed)).once - end - end - end - - describe 'DELETE #destroy' do - let(:scopes) { 'write:filters' } - let(:filter) { Fabricate(:custom_filter, account: user.account) } - - before do - delete :destroy, params: { id: filter.id } - end - - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'removes the filter' do - expect { filter.reload }.to raise_error ActiveRecord::RecordNotFound - end - end -end diff --git a/spec/controllers/api/v2/instances_controller_spec.rb b/spec/controllers/api/v2/instances_controller_spec.rb new file mode 100644 index 0000000000..b7206da0a2 --- /dev/null +++ b/spec/controllers/api/v2/instances_controller_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V2::InstancesController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #show' do + it 'returns http success' do + get :show + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/v2/search_controller_spec.rb b/spec/controllers/api/v2/search_controller_spec.rb index d417ea58ca..a3b92fc37a 100644 --- a/spec/controllers/api/v2/search_controller_spec.rb +++ b/spec/controllers/api/v2/search_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Api::V2::SearchController, type: :controller do +RSpec.describe Api::V2::SearchController do render_views context 'with token' do @@ -14,13 +14,40 @@ RSpec.describe Api::V2::SearchController, type: :controller do end describe 'GET #index' do - before do - get :index, params: { q: 'test' } - end + let!(:bob) { Fabricate(:account, username: 'bob_test') } + let!(:ana) { Fabricate(:account, username: 'ana_test') } + let!(:tom) { Fabricate(:account, username: 'tom_test') } + let(:params) { { q: 'test' } } it 'returns http success' do + get :index, params: params + expect(response).to have_http_status(200) end + + context 'when searching accounts' do + let(:params) { { q: 'test', type: 'accounts' } } + + it 'returns all matching accounts' do + get :index, params: params + + expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(bob.id.to_s, ana.id.to_s, tom.id.to_s) + end + + context 'with following=true' do + let(:params) { { q: 'test', type: 'accounts', following: 'true' } } + + before do + user.account.follow!(ana) + end + + it 'returns only the followed accounts' do + get :index, params: params + + expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(ana.id.to_s) + end + end + end end end diff --git a/spec/controllers/api/v2/suggestions_controller_spec.rb b/spec/controllers/api/v2/suggestions_controller_spec.rb new file mode 100644 index 0000000000..5e6508bfda --- /dev/null +++ b/spec/controllers/api/v2/suggestions_controller_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V2::SuggestionsController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + describe 'GET #index' do + it 'returns http success' do + get :index + + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/api/web/embeds_controller_spec.rb b/spec/controllers/api/web/embeds_controller_spec.rb deleted file mode 100644 index a8fc1718f6..0000000000 --- a/spec/controllers/api/web/embeds_controller_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::Web::EmbedsController do - render_views - - let(:user) { Fabricate(:user) } - before { sign_in user } - - describe 'POST #create' do - subject(:response) { post :create, params: { url: url } } - subject(:body) { JSON.parse(response.body, symbolize_names: true) } - - context 'when successfully finds status' do - let(:status) { Fabricate(:status) } - let(:url) { "http://#{Rails.configuration.x.web_domain}/@#{status.account.username}/#{status.id}" } - - it 'returns a right response' do - expect(response).to have_http_status :ok - expect(body[:author_name]).to eq status.account.username - end - end - - context 'when fails to find status' do - let(:url) { 'https://host.test/oembed.html' } - let(:service_instance) { double('fetch_oembed_service') } - - before do - allow(FetchOEmbedService).to receive(:new) { service_instance } - allow(service_instance).to receive(:call) { call_result } - end - - context 'when successfully fetching oembed' do - let(:call_result) { { result: :ok } } - - it 'returns a right response' do - expect(response).to have_http_status :ok - expect(body[:result]).to eq 'ok' - end - end - - context 'when fails to fetch oembed' do - let(:call_result) { nil } - - it 'returns a right response' do - expect(response).to have_http_status :not_found - end - end - end - end -end diff --git a/spec/controllers/api/web/push_subscriptions_controller_spec.rb b/spec/controllers/api/web/push_subscriptions_controller_spec.rb index bda4a76614..9f027ede90 100644 --- a/spec/controllers/api/web/push_subscriptions_controller_spec.rb +++ b/spec/controllers/api/web/push_subscriptions_controller_spec.rb @@ -15,7 +15,7 @@ describe Api::Web::PushSubscriptionsController do p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=', auth: 'eH_C8rq2raXqlcBVDa1gLg==', }, - } + }, } end @@ -32,8 +32,8 @@ describe Api::Web::PushSubscriptionsController do mention: false, poll: true, status: false, - } - } + }, + }, } end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 1b002e01cb..bbe6856e27 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe ApplicationController, type: :controller do +describe ApplicationController do controller do def success head 200 @@ -27,12 +27,12 @@ describe ApplicationController, type: :controller do expect(response).to have_http_status(code) end - it "renders template for http" do - is_expected.to render_template("errors/#{code}", layout: 'error') + it 'renders template for http' do + expect(subject).to render_template("errors/#{code}", layout: 'error') end end - context 'forgery' do + context 'with a forgery' do subject do ActionController::Base.allow_forgery_protection = true routes.draw { post 'success' => 'anonymous#success' } @@ -57,57 +57,62 @@ describe ApplicationController, type: :controller do describe 'helper_method :single_user_mode?' do it 'returns false if it is in single_user_mode but there is no account' do allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true) - expect(controller.view_context.single_user_mode?).to eq false + expect(controller.view_context.single_user_mode?).to be false end it 'returns false if there is an account but it is not in single_user_mode' do allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false) Fabricate(:account) - expect(controller.view_context.single_user_mode?).to eq false + expect(controller.view_context.single_user_mode?).to be false end it 'returns true if it is in single_user_mode and there is an account' do allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true) Fabricate(:account) - expect(controller.view_context.single_user_mode?).to eq true + expect(controller.view_context.single_user_mode?).to be true end end - describe 'helper_method :current_theme' do - it 'returns "default" when theme wasn\'t changed in admin settings' do - allow(Setting).to receive(:default_settings).and_return({ 'theme' => 'default' }) + describe 'helper_method :current_flavour' do + it 'returns "glitch" when theme wasn\'t changed in admin settings' do + allow(Setting).to receive(:default_settings).and_return({ 'skin' => 'default' }) + allow(Setting).to receive(:default_settings).and_return({ 'flavour' => 'glitch' }) - expect(controller.view_context.current_theme).to eq 'default' + expect(controller.view_context.current_flavour).to eq 'glitch' end - it 'returns instances\'s theme when user is not signed in' do - allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + it 'returns instances\'s flavour when user is not signed in' do + allow(Setting).to receive(:[]).with('skin').and_return 'default' + allow(Setting).to receive(:[]).with('flavour').and_return 'vanilla' - expect(controller.view_context.current_theme).to eq 'contrast' + expect(controller.view_context.current_flavour).to eq 'vanilla' end - it 'returns instances\'s default theme when user didn\'t set theme' do + it 'returns instances\'s default flavour when user didn\'t set theme' do current_user = Fabricate(:user) sign_in current_user - allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + allow(Setting).to receive(:[]).with('skin').and_return 'default' + allow(Setting).to receive(:[]).with('flavour').and_return 'vanilla' allow(Setting).to receive(:[]).with('noindex').and_return false - expect(controller.view_context.current_theme).to eq 'contrast' + expect(controller.view_context.current_flavour).to eq 'vanilla' end - it 'returns user\'s theme when it is set' do + it 'returns user\'s flavour when it is set' do current_user = Fabricate(:user) - current_user.settings['theme'] = 'mastodon-light' + current_user.settings.update(flavour: 'glitch') + current_user.save sign_in current_user - allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + allow(Setting).to receive(:[]).with('skin').and_return 'default' + allow(Setting).to receive(:[]).with('flavour').and_return 'vanilla' - expect(controller.view_context.current_theme).to eq 'mastodon-light' + expect(controller.view_context.current_flavour).to eq 'glitch' end end - context 'ActionController::RoutingError' do + context 'with ActionController::RoutingError' do subject do routes.draw { get 'routing_error' => 'anonymous#routing_error' } get 'routing_error' @@ -116,7 +121,7 @@ describe ApplicationController, type: :controller do include_examples 'respond_with_error', 404 end - context 'ActiveRecord::RecordNotFound' do + context 'with ActiveRecord::RecordNotFound' do subject do routes.draw { get 'record_not_found' => 'anonymous#record_not_found' } get 'record_not_found' @@ -125,7 +130,7 @@ describe ApplicationController, type: :controller do include_examples 'respond_with_error', 404 end - context 'ActionController::InvalidAuthenticityToken' do + context 'with ActionController::InvalidAuthenticityToken' do subject do routes.draw { get 'invalid_authenticity_token' => 'anonymous#invalid_authenticity_token' } get 'invalid_authenticity_token' @@ -134,25 +139,6 @@ describe ApplicationController, type: :controller do include_examples 'respond_with_error', 422 end - describe 'before_action :store_current_location' do - it 'stores location for user if it is not devise controller' do - routes.draw { get 'success' => 'anonymous#success' } - get 'success' - expect(controller.stored_location_for(:user)).to eq '/success' - end - - context do - controller Devise::SessionsController do - end - - it 'does not store location for user if it is devise controller' do - @request.env["devise.mapping"] = Devise.mappings[:user] - get 'create' - expect(controller.stored_location_for(:user)).to be_nil - end - end - end - describe 'before_action :check_suspension' do before do routes.draw { get 'success' => 'anonymous#success' } @@ -244,14 +230,16 @@ describe ApplicationController, type: :controller do end describe 'cache_collection' do - class C < ApplicationController - public :cache_collection + subject do + Class.new(ApplicationController) do + public :cache_collection + end end shared_examples 'receives :with_includes' do |fabricator, klass| it 'uses raw if it is not an ActiveRecord::Relation' do record = Fabricate(fabricator) - expect(C.new.cache_collection([record], klass)).to eq [record] + expect(subject.new.cache_collection([record], klass)).to eq [record] end end @@ -262,16 +250,16 @@ describe ApplicationController, type: :controller do record = Fabricate(fabricator) relation = klass.none allow(relation).to receive(:cache_ids).and_return([record]) - expect(C.new.cache_collection(relation, klass)).to eq [record] + expect(subject.new.cache_collection(relation, klass)).to eq [record] end end it 'returns raw unless class responds to :with_includes' do raw = Object.new - expect(C.new.cache_collection(raw, Object)).to eq raw + expect(subject.new.cache_collection(raw, Object)).to eq raw end - context 'Status' do + context 'with a Status' do include_examples 'cacheable', :status, Status end end diff --git a/spec/controllers/auth/challenges_controller_spec.rb b/spec/controllers/auth/challenges_controller_spec.rb index 2a6ca301ef..32bbedde63 100644 --- a/spec/controllers/auth/challenges_controller_spec.rb +++ b/spec/controllers/auth/challenges_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Auth::ChallengesController, type: :controller do +describe Auth::ChallengesController do render_views let(:password) { 'foobar12345' } diff --git a/spec/controllers/auth/confirmations_controller_spec.rb b/spec/controllers/auth/confirmations_controller_spec.rb index 8469119d23..799d3857e4 100644 --- a/spec/controllers/auth/confirmations_controller_spec.rb +++ b/spec/controllers/auth/confirmations_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Auth::ConfirmationsController, type: :controller do +describe Auth::ConfirmationsController do render_views describe 'GET #new' do diff --git a/spec/controllers/auth/passwords_controller_spec.rb b/spec/controllers/auth/passwords_controller_spec.rb index 1c6874f08c..38fbed27a7 100644 --- a/spec/controllers/auth/passwords_controller_spec.rb +++ b/spec/controllers/auth/passwords_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe Auth::PasswordsController, type: :controller do +describe Auth::PasswordsController do include Devise::Test::ControllerHelpers describe 'GET #new' do diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index 0ebf6641fa..a9b24a1004 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Auth::RegistrationsController, type: :controller do +RSpec.describe Auth::RegistrationsController do render_views shared_examples 'checks for enabled registrations' do |path| @@ -13,45 +15,62 @@ RSpec.describe Auth::RegistrationsController, type: :controller do it 'redirects if it is in single user mode while it is open for registration' do Fabricate(:account) Setting.registrations_mode = 'open' - expect(Rails.configuration.x).to receive(:single_user_mode).and_return(true) + allow(Rails.configuration.x).to receive(:single_user_mode).and_return(true) get path expect(response).to redirect_to '/' + expect(Rails.configuration.x).to have_received(:single_user_mode) end it 'redirects if it is not open for registration while it is not in single user mode' do Setting.registrations_mode = 'none' - expect(Rails.configuration.x).to receive(:single_user_mode).and_return(false) + allow(Rails.configuration.x).to receive(:single_user_mode).and_return(false) get path expect(response).to redirect_to '/' + expect(Rails.configuration.x).to have_received(:single_user_mode) end end describe 'GET #edit' do - it 'returns http success' do - request.env["devise.mapping"] = Devise.mappings[:user] + before do + request.env['devise.mapping'] = Devise.mappings[:user] sign_in(Fabricate(:user)) get :edit + end + + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control header' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end describe 'GET #update' do - it 'returns http success' do - request.env["devise.mapping"] = Devise.mappings[:user] - sign_in(Fabricate(:user), scope: :user) + let(:user) { Fabricate(:user) } + + before do + request.env['devise.mapping'] = Devise.mappings[:user] + sign_in(user, scope: :user) post :update + end + + it 'returns http success' do expect(response).to have_http_status(200) end + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + context 'when suspended' do + let(:user) { Fabricate(:user, account_attributes: { username: 'test', suspended_at: Time.now.utc }) } + it 'returns http forbidden' do - request.env["devise.mapping"] = Devise.mappings[:user] - sign_in(Fabricate(:user, account_attributes: { username: 'test', suspended_at: Time.now.utc }), scope: :user) - post :update expect(response).to have_http_status(403) end end @@ -59,10 +78,10 @@ RSpec.describe Auth::RegistrationsController, type: :controller do describe 'GET #new' do before do - request.env["devise.mapping"] = Devise.mappings[:user] + request.env['devise.mapping'] = Devise.mappings[:user] end - context do + context 'with open registrations' do around do |example| registrations_mode = Setting.registrations_mode example.run @@ -80,33 +99,33 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end describe 'POST #create' do - let(:accept_language) { Rails.application.config.i18n.available_locales.sample.to_s } + let(:accept_language) { 'de' } before do session[:registration_form_time] = 5.seconds.ago + + request.env['devise.mapping'] = Devise.mappings[:user] end around do |example| - current_locale = I18n.locale - example.run - I18n.locale = current_locale + I18n.with_locale(I18n.locale) do + example.run + end end - before { request.env["devise.mapping"] = Devise.mappings[:user] } + context 'when an accept language is present in headers' do + subject do + Setting.registrations_mode = 'open' + request.headers['Accept-Language'] = accept_language + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } + end - context do around do |example| registrations_mode = Setting.registrations_mode example.run Setting.registrations_mode = registrations_mode end - subject do - Setting.registrations_mode = 'open' - request.headers["Accept-Language"] = accept_language - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } - end - it 'redirects to setup' do subject expect(response).to redirect_to auth_setup_path @@ -121,18 +140,18 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end context 'when user has not agreed to terms of service' do + subject do + Setting.registrations_mode = 'open' + request.headers['Accept-Language'] = accept_language + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'false' } } + end + around do |example| registrations_mode = Setting.registrations_mode example.run Setting.registrations_mode = registrations_mode end - subject do - Setting.registrations_mode = 'open' - request.headers["Accept-Language"] = accept_language - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'false' } } - end - it 'does not create user' do subject user = User.find_by(email: 'test@example.com') @@ -140,45 +159,45 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end end - context 'approval-based registrations without invite' do - around do |example| - registrations_mode = Setting.registrations_mode - example.run - Setting.registrations_mode = registrations_mode - end - + context 'with Approval-based registrations without invite' do subject do Setting.registrations_mode = 'approved' - request.headers["Accept-Language"] = accept_language + request.headers['Accept-Language'] = accept_language post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } end - it 'redirects to setup' do - subject - expect(response).to redirect_to auth_setup_path - end - - it 'creates user' do - subject - user = User.find_by(email: 'test@example.com') - expect(user).to_not be_nil - expect(user.locale).to eq(accept_language) - expect(user.approved).to eq(false) - end - end - - context 'approval-based registrations with expired invite' do around do |example| registrations_mode = Setting.registrations_mode example.run Setting.registrations_mode = registrations_mode end + it 'redirects to setup' do + subject + expect(response).to redirect_to auth_setup_path + end + + it 'creates user' do + subject + user = User.find_by(email: 'test@example.com') + expect(user).to_not be_nil + expect(user.locale).to eq(accept_language) + expect(user.approved).to be(false) + end + end + + context 'with Approval-based registrations with expired invite' do subject do Setting.registrations_mode = 'approved' - request.headers["Accept-Language"] = accept_language + request.headers['Accept-Language'] = accept_language invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago) - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code, agreement: 'true' } } + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } } + end + + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode end it 'redirects to setup' do @@ -191,11 +210,20 @@ RSpec.describe Auth::RegistrationsController, type: :controller do user = User.find_by(email: 'test@example.com') expect(user).to_not be_nil expect(user.locale).to eq(accept_language) - expect(user.approved).to eq(false) + expect(user.approved).to be(false) end end - context 'approval-based registrations with valid invite and required invite text' do + context 'with Approval-based registrations with valid invite and required invite text' do + subject do + inviter = Fabricate(:user, confirmed_at: 2.days.ago) + Setting.registrations_mode = 'approved' + Setting.require_invite_text = true + request.headers['Accept-Language'] = accept_language + invite = Fabricate(:invite, user: inviter, max_uses: nil, expires_at: 1.hour.from_now) + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', invite_code: invite.code, agreement: 'true' } } + end + around do |example| registrations_mode = Setting.registrations_mode require_invite_text = Setting.require_invite_text @@ -204,15 +232,6 @@ RSpec.describe Auth::RegistrationsController, type: :controller do Setting.registrations_mode = registrations_mode end - subject do - inviter = Fabricate(:user, confirmed_at: 2.days.ago) - Setting.registrations_mode = 'approved' - Setting.require_invite_text = true - request.headers["Accept-Language"] = accept_language - invite = Fabricate(:invite, user: inviter, max_uses: nil, expires_at: 1.hour.from_now) - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code, agreement: 'true' } } - end - it 'redirects to setup' do subject expect(response).to redirect_to auth_setup_path @@ -223,13 +242,30 @@ RSpec.describe Auth::RegistrationsController, type: :controller do user = User.find_by(email: 'test@example.com') expect(user).to_not be_nil expect(user.locale).to eq(accept_language) - expect(user.approved).to eq(true) + expect(user.approved).to be(true) end end - it 'does nothing if user already exists' do - Fabricate(:account, username: 'test') - subject + context 'with an already taken username' do + subject do + Setting.registrations_mode = 'open' + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } + end + + before do + Fabricate(:account, username: 'test') + end + + it 'responds with an error message about the username' do + subject + + expect(response).to have_http_status(:success) + expect(username_error_text).to eq(I18n.t('errors.messages.taken')) + end + + def username_error_text + Nokogiri::Slop(response.body).css('.user_account_username .error').text + end end include_examples 'checks for enabled registrations', :create @@ -245,7 +281,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end it 'returns http not found' do - expect(response).to have_http_status(:not_found) + expect(response).to have_http_status(404) end it 'does not delete user' do diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index d3db7aa1ab..c727a76333 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' require 'webauthn/fake_client' -RSpec.describe Auth::SessionsController, type: :controller do +RSpec.describe Auth::SessionsController do render_views before do @@ -51,10 +51,10 @@ RSpec.describe Auth::SessionsController, type: :controller do end describe 'POST #create' do - context 'using PAM authentication', if: ENV['PAM_ENABLED'] == 'true' do - context 'using a valid password' do + context 'when using PAM authentication', if: ENV['PAM_ENABLED'] == 'true' do + context 'when using a valid password' do before do - post :create, params: { user: { email: "pam_user1", password: '123456' } } + post :create, params: { user: { email: 'pam_user1', password: '123456' } } end it 'redirects to home' do @@ -66,9 +66,9 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using an invalid password' do + context 'when using an invalid password' do before do - post :create, params: { user: { email: "pam_user1", password: 'WRONGPW' } } + post :create, params: { user: { email: 'pam_user1', password: 'WRONGPW' } } end it 'shows a login error' do @@ -80,7 +80,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using a valid email and existing user' do + context 'when using a valid email and existing user' do let!(:user) do account = Fabricate.build(:account, username: 'pam_user1', user: nil) account.save!(validate: false) @@ -102,10 +102,10 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using password authentication' do + context 'when using password authentication' do let(:user) { Fabricate(:user, email: 'foo@bar.com', password: 'abcdefgh') } - context 'using a valid password' do + context 'when using a valid password' do before do post :create, params: { user: { email: user.email, password: user.password } } end @@ -119,7 +119,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using a valid password on a previously-used account with a new IP address' do + context 'when using a valid password on a previously-used account with a new IP address' do let(:previous_ip) { '1.2.3.4' } let(:current_ip) { '4.3.2.1' } @@ -127,7 +127,8 @@ RSpec.describe Auth::SessionsController, type: :controller do before do allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return(current_ip) - allow(UserMailer).to receive(:suspicious_sign_in).and_return(double('email', 'deliver_later!': nil)) + allow(UserMailer).to receive(:suspicious_sign_in) + .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later!: nil)) user.update(current_sign_in_at: 1.month.ago) post :create, params: { user: { email: user.email, password: user.password } } end @@ -145,7 +146,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using email with uppercase letters' do + context 'when using email with uppercase letters' do before do post :create, params: { user: { email: user.email.upcase, password: user.password } } end @@ -159,7 +160,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using an invalid password' do + context 'when using an invalid password' do before do post :create, params: { user: { email: user.email, password: 'wrongpw' } } end @@ -173,7 +174,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using an unconfirmed password' do + context 'when using an unconfirmed password' do before do request.headers['Accept-Language'] = accept_language post :create, params: { user: { email: unconfirmed_user.email, password: unconfirmed_user.password } } @@ -187,14 +188,14 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context "logging in from the user's page" do + context "when logging in from the user's page" do before do allow(controller).to receive(:single_user_mode?).and_return(single_user_mode) allow(controller).to receive(:stored_location_for).with(:user).and_return("/@#{user.account.username}") post :create, params: { user: { email: user.email, password: user.password } } end - context "in single user mode" do + context 'with single user mode' do let(:single_user_mode) { true } it 'redirects to home' do @@ -202,7 +203,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context "in non-single user mode" do + context 'with non-single user mode' do let(:single_user_mode) { false } it "redirects back to the user's page" do @@ -212,7 +213,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using two-factor authentication' do + context 'when using two-factor authentication' do context 'with OTP enabled as second factor' do let!(:user) do Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) @@ -224,18 +225,18 @@ RSpec.describe Auth::SessionsController, type: :controller do return codes end - context 'using email and password' do + context 'when using email and password' do before do post :create, params: { user: { email: user.email, password: user.password } } end it 'renders two factor authentication page' do - expect(controller).to render_template("two_factor") - expect(controller).to render_template(partial: "_otp_authentication_form") + expect(controller).to render_template('two_factor') + expect(controller).to render_template(partial: '_otp_authentication_form') end end - context 'using email and password after an unfinished log-in attempt to a 2FA-protected account' do + context 'when using email and password after an unfinished log-in attempt to a 2FA-protected account' do let!(:other_user) do Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) end @@ -246,23 +247,23 @@ RSpec.describe Auth::SessionsController, type: :controller do end it 'renders two factor authentication page' do - expect(controller).to render_template("two_factor") - expect(controller).to render_template(partial: "_otp_authentication_form") + expect(controller).to render_template('two_factor') + expect(controller).to render_template(partial: '_otp_authentication_form') end end - context 'using upcase email and password' do + context 'when using upcase email and password' do before do post :create, params: { user: { email: user.email.upcase, password: user.password } } end it 'renders two factor authentication page' do - expect(controller).to render_template("two_factor") - expect(controller).to render_template(partial: "_otp_authentication_form") + expect(controller).to render_template('two_factor') + expect(controller).to render_template(partial: '_otp_authentication_form') end end - context 'using a valid OTP' do + context 'when using a valid OTP' do before do post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s } end @@ -291,7 +292,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using a valid recovery code' do + context 'when using a valid recovery code' do before do post :create, params: { user: { otp_attempt: recovery_codes.first } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s } end @@ -305,7 +306,7 @@ RSpec.describe Auth::SessionsController, type: :controller do end end - context 'using an invalid OTP' do + context 'when using an invalid OTP' do before do post :create, params: { user: { otp_attempt: 'wrongotp' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s } end @@ -339,11 +340,11 @@ RSpec.describe Auth::SessionsController, type: :controller do external_id: public_key_credential.id, public_key: public_key_credential.public_key, sign_count: '1000' - ) + ) user.webauthn_credentials.take end - let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" } + let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" } let(:fake_client) { WebAuthn::FakeClient.new(domain) } @@ -353,29 +354,29 @@ RSpec.describe Auth::SessionsController, type: :controller do let(:fake_credential) { fake_client.get(challenge: challenge, sign_count: sign_count) } - context 'using email and password' do + context 'when using email and password' do before do post :create, params: { user: { email: user.email, password: user.password } } end it 'renders webauthn authentication page' do - expect(controller).to render_template("two_factor") - expect(controller).to render_template(partial: "_webauthn_form") + expect(controller).to render_template('two_factor') + expect(controller).to render_template(partial: '_webauthn_form') end end - context 'using upcase email and password' do + context 'when using upcase email and password' do before do post :create, params: { user: { email: user.email.upcase, password: user.password } } end it 'renders webauthn authentication page' do - expect(controller).to render_template("two_factor") - expect(controller).to render_template(partial: "_webauthn_form") + expect(controller).to render_template('two_factor') + expect(controller).to render_template(partial: '_webauthn_form') end end - context 'using a valid webauthn credential' do + context 'when using a valid webauthn credential' do before do @controller.session[:webauthn_challenge] = challenge @@ -400,7 +401,7 @@ RSpec.describe Auth::SessionsController, type: :controller do describe 'GET #webauthn_options' do context 'with WebAuthn and OTP enabled as second factor' do - let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" } + let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" } let(:fake_client) { WebAuthn::FakeClient.new(domain) } @@ -422,7 +423,7 @@ RSpec.describe Auth::SessionsController, type: :controller do it 'returns http success' do get :webauthn_options - expect(response).to have_http_status :ok + expect(response).to have_http_status 200 end end end diff --git a/spec/controllers/auth/setup_controller_spec.rb b/spec/controllers/auth/setup_controller_spec.rb new file mode 100644 index 0000000000..75e42aaf96 --- /dev/null +++ b/spec/controllers/auth/setup_controller_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Auth::SetupController do + render_views + + describe 'GET #show' do + context 'with a signed out request' do + it 'returns http redirect' do + get :show + expect(response).to be_redirect + end + end + + context 'with an unconfirmed signed in user' do + before { sign_in Fabricate(:user, confirmed_at: nil) } + + it 'returns http success' do + get :show + expect(response).to have_http_status(200) + end + end + end +end diff --git a/spec/controllers/authorize_interactions_controller_spec.rb b/spec/controllers/authorize_interactions_controller_spec.rb index 44f52df69f..5282a196a6 100644 --- a/spec/controllers/authorize_interactions_controller_spec.rb +++ b/spec/controllers/authorize_interactions_controller_spec.rb @@ -24,87 +24,43 @@ describe AuthorizeInteractionsController do it 'renders error without acct param' do get :show - expect(response).to render_template(:error) + expect(response).to have_http_status(404) end it 'renders error when account cant be found' do - service = double + service = instance_double(ResolveAccountService) allow(ResolveAccountService).to receive(:new).and_return(service) allow(service).to receive(:call).with('missing@hostname').and_return(nil) get :show, params: { acct: 'acct:missing@hostname' } - expect(response).to render_template(:error) + expect(response).to have_http_status(404) expect(service).to have_received(:call).with('missing@hostname') end it 'sets resource from url' do account = Fabricate(:account) - service = double + service = instance_double(ResolveURLService) allow(ResolveURLService).to receive(:new).and_return(service) allow(service).to receive(:call).with('http://example.com').and_return(account) get :show, params: { acct: 'http://example.com' } - expect(response).to have_http_status(200) + expect(response).to have_http_status(302) expect(assigns(:resource)).to eq account end it 'sets resource from acct uri' do account = Fabricate(:account) - service = double + service = instance_double(ResolveAccountService) allow(ResolveAccountService).to receive(:new).and_return(service) allow(service).to receive(:call).with('found@hostname').and_return(account) get :show, params: { acct: 'acct:found@hostname' } - expect(response).to have_http_status(200) + expect(response).to have_http_status(302) expect(assigns(:resource)).to eq account end end end - - describe 'POST #create' do - describe 'when signed out' do - it 'redirects to sign in page' do - post :create - - expect(response).to redirect_to(new_user_session_path) - end - end - - describe 'when signed in' do - let!(:user) { Fabricate(:user) } - let(:account) { user.account } - - before do - sign_in(user) - end - - it 'shows error when account not found' do - service = double - - allow(ResolveAccountService).to receive(:new).and_return(service) - allow(service).to receive(:call).with('user@hostname').and_return(nil) - - post :create, params: { acct: 'acct:user@hostname' } - - expect(response).to render_template(:error) - end - - it 'follows account when found' do - target_account = Fabricate(:account) - service = double - - allow(ResolveAccountService).to receive(:new).and_return(service) - allow(service).to receive(:call).with('user@hostname').and_return(target_account) - - - post :create, params: { acct: 'acct:user@hostname' } - - expect(account.following?(target_account)).to be true - expect(response).to render_template(:success) - end - end - end end diff --git a/spec/controllers/concerns/account_controller_concern_spec.rb b/spec/controllers/concerns/account_controller_concern_spec.rb index 99975f4c44..d080475c32 100644 --- a/spec/controllers/concerns/account_controller_concern_spec.rb +++ b/spec/controllers/concerns/account_controller_concern_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' -describe ApplicationController, type: :controller do - controller do +describe AccountControllerConcern do + controller(ApplicationController) do include AccountControllerConcern def success diff --git a/spec/controllers/concerns/accountable_concern_spec.rb b/spec/controllers/concerns/accountable_concern_spec.rb index 5c5180bc24..cd06d872bb 100644 --- a/spec/controllers/concerns/accountable_concern_spec.rb +++ b/spec/controllers/concerns/accountable_concern_spec.rb @@ -3,24 +3,26 @@ require 'rails_helper' RSpec.describe AccountableConcern do - class Hoge - include AccountableConcern - attr_reader :current_account + let(:hoge_class) do + Class.new do + include AccountableConcern + attr_reader :current_account - def initialize(current_account) - @current_account = current_account + def initialize(current_account) + @current_account = current_account + end end end let(:user) { Fabricate(:account) } let(:target) { Fabricate(:account) } - let(:hoge) { Hoge.new(user) } + let(:hoge) { hoge_class.new(user) } describe '#log_action' do it 'creates Admin::ActionLog' do expect do hoge.log_action(:create, target) - end.to change { Admin::ActionLog.count }.by(1) + end.to change(Admin::ActionLog, :count).by(1) end end end diff --git a/spec/controllers/concerns/cache_concern_spec.rb b/spec/controllers/concerns/cache_concern_spec.rb index a34d7d7267..fffd2b266e 100644 --- a/spec/controllers/concerns/cache_concern_spec.rb +++ b/spec/controllers/concerns/cache_concern_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe CacheConcern, type: :controller do +RSpec.describe CacheConcern do controller(ApplicationController) do include CacheConcern @@ -13,28 +13,48 @@ RSpec.describe CacheConcern, type: :controller do def empty_relation render plain: cache_collection(Status.none, Status).size end + + def account_statuses_favourites + render plain: cache_collection(Status.where(account_id: params[:id]), Status).map(&:favourites_count) + end end before do routes.draw do - get 'empty_array' => 'anonymous#empty_array' - post 'empty_relation' => 'anonymous#empty_relation' + get 'empty_array' => 'anonymous#empty_array' + get 'empty_relation' => 'anonymous#empty_relation' + get 'account_statuses_favourites' => 'anonymous#account_statuses_favourites' end end describe '#cache_collection' do - context 'given an empty array' do + context 'when given an empty array' do it 'returns an empty array' do get :empty_array expect(response.body).to eq '0' end end - context 'given an empty relation' do + context 'when given an empty relation' do it 'returns an empty array' do get :empty_relation expect(response.body).to eq '0' end end + + context 'when given a collection of statuses' do + let!(:account) { Fabricate(:account) } + let!(:status) { Fabricate(:status, account: account) } + + it 'correctly updates with new interactions' do + get :account_statuses_favourites, params: { id: account.id } + expect(response.body).to eq '[0]' + + FavouriteService.new.call(account, status) + + get :account_statuses_favourites, params: { id: account.id } + expect(response.body).to eq '[1]' + end + end end end diff --git a/spec/controllers/concerns/challengable_concern_spec.rb b/spec/controllers/concerns/challengable_concern_spec.rb index 4db3b740db..3324bdd24f 100644 --- a/spec/controllers/concerns/challengable_concern_spec.rb +++ b/spec/controllers/concerns/challengable_concern_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe ChallengableConcern, type: :controller do +RSpec.describe ChallengableConcern do controller(ApplicationController) do include ChallengableConcern @@ -31,7 +31,7 @@ RSpec.describe ChallengableConcern, type: :controller do sign_in user end - context 'for GET requests' do + context 'with GET requests' do before { get :foo } it 'does not ask for password' do @@ -39,7 +39,7 @@ RSpec.describe ChallengableConcern, type: :controller do end end - context 'for POST requests' do + context 'with POST requests' do before { post :bar } it 'does not ask for password' do @@ -56,7 +56,7 @@ RSpec.describe ChallengableConcern, type: :controller do sign_in user end - context 'for GET requests' do + context 'with GET requests' do before { get :foo, session: { challenge_passed_at: Time.now.utc } } it 'does not ask for password' do @@ -64,7 +64,7 @@ RSpec.describe ChallengableConcern, type: :controller do end end - context 'for POST requests' do + context 'with POST requests' do before { post :bar, session: { challenge_passed_at: Time.now.utc } } it 'does not ask for password' do @@ -81,7 +81,7 @@ RSpec.describe ChallengableConcern, type: :controller do sign_in user end - context 'for GET requests' do + context 'with GET requests' do before { get :foo } it 'renders challenge' do @@ -91,7 +91,7 @@ RSpec.describe ChallengableConcern, type: :controller do # See Auth::ChallengesControllerSpec end - context 'for POST requests' do + context 'with POST requests' do before { post :bar } it 'renders challenge' do diff --git a/spec/controllers/concerns/export_controller_concern_spec.rb b/spec/controllers/concerns/export_controller_concern_spec.rb index 1a5e46f8ef..e253aa5206 100644 --- a/spec/controllers/concerns/export_controller_concern_spec.rb +++ b/spec/controllers/concerns/export_controller_concern_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' -describe ApplicationController, type: :controller do - controller do +describe ExportControllerConcern do + controller(ApplicationController) do include ExportControllerConcern def index @@ -29,7 +29,7 @@ describe ApplicationController, type: :controller do it 'returns unauthorized when not signed in' do get :index, format: :csv - expect(response).to have_http_status(:unauthorized) + expect(response).to have_http_status(401) end end end diff --git a/spec/controllers/concerns/localized_spec.rb b/spec/controllers/concerns/localized_spec.rb index a89e24af04..ce31e786f0 100644 --- a/spec/controllers/concerns/localized_spec.rb +++ b/spec/controllers/concerns/localized_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' -describe ApplicationController, type: :controller do - controller do +describe Localized do + controller(ApplicationController) do include Localized def success @@ -41,7 +41,7 @@ describe ApplicationController, type: :controller do end end - context 'user with valid locale has signed in' do + context 'with a user with valid locale has signed in' do it "sets user's locale" do user = Fabricate(:user, locale: :ca) @@ -52,7 +52,7 @@ describe ApplicationController, type: :controller do end end - context 'user with invalid locale has signed in' do + context 'with a user with invalid locale has signed in' do before do user = Fabricate.build(:user, locale: :invalid) user.save!(validate: false) @@ -62,7 +62,7 @@ describe ApplicationController, type: :controller do include_examples 'default locale' end - context 'user has not signed in' do + context 'with a user who has not signed in' do include_examples 'default locale' end end diff --git a/spec/controllers/concerns/rate_limit_headers_spec.rb b/spec/controllers/concerns/rate_limit_headers_spec.rb index 00a9a2080d..1cdf741f4d 100644 --- a/spec/controllers/concerns/rate_limit_headers_spec.rb +++ b/spec/controllers/concerns/rate_limit_headers_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' -describe ApplicationController do - controller do +describe RateLimitHeaders do + controller(ApplicationController) do include RateLimitHeaders def show @@ -16,7 +16,7 @@ describe ApplicationController do end describe 'rate limiting' do - context 'throttling is off' do + context 'when throttling is off' do before do request.env['rack.attack.throttle_data'] = nil end @@ -30,7 +30,7 @@ describe ApplicationController do end end - context 'throttling is on' do + context 'when throttling is on' do let(:start_time) { DateTime.new(2017, 1, 1, 12, 0, 0).utc } before do diff --git a/spec/controllers/concerns/signature_verification_spec.rb b/spec/controllers/concerns/signature_verification_spec.rb index 13655f3133..650cd21eaf 100644 --- a/spec/controllers/concerns/signature_verification_spec.rb +++ b/spec/controllers/concerns/signature_verification_spec.rb @@ -2,18 +2,20 @@ require 'rails_helper' -describe ApplicationController, type: :controller do - class WrappedActor - attr_reader :wrapped_account +describe SignatureVerification do + let(:wrapped_actor_class) do + Class.new do + attr_reader :wrapped_account - def initialize(wrapped_account) - @wrapped_account = wrapped_account + def initialize(wrapped_account) + @wrapped_account = wrapped_account + end + + delegate :uri, :keypair, to: :wrapped_account end - - delegate :uri, :keypair, to: :wrapped_account end - controller do + controller(ApplicationController) do include SignatureVerification before_action :require_actor_signature!, only: [:signature_required] @@ -33,8 +35,8 @@ describe ApplicationController, type: :controller do before do routes.draw do - match via: [:get, :post], 'success' => 'anonymous#success' - match via: [:get, :post], 'signature_required' => 'anonymous#signature_required' + match :via => [:get, :post], 'success' => 'anonymous#success' + match :via => [:get, :post], 'signature_required' => 'anonymous#signature_required' end end @@ -93,7 +95,7 @@ describe ApplicationController, type: :controller do end context 'with a valid actor that is not an Account' do - let(:actor) { WrappedActor.new(author) } + let(:actor) { wrapped_actor_class.new(author) } before do get :success @@ -127,7 +129,7 @@ describe ApplicationController, type: :controller do end end - context 'with request with unparseable Date header' do + context 'with request with unparsable Date header' do before do get :success diff --git a/spec/controllers/concerns/user_tracking_concern_spec.rb b/spec/controllers/concerns/user_tracking_concern_spec.rb index b2548d5c00..dd0b3c042a 100644 --- a/spec/controllers/concerns/user_tracking_concern_spec.rb +++ b/spec/controllers/concerns/user_tracking_concern_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' -describe ApplicationController, type: :controller do - controller do +describe UserTrackingConcern do + controller(ApplicationController) do include UserTrackingConcern def show diff --git a/spec/controllers/custom_css_controller_spec.rb b/spec/controllers/custom_css_controller_spec.rb new file mode 100644 index 0000000000..99d36d21b9 --- /dev/null +++ b/spec/controllers/custom_css_controller_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe CustomCssController do + render_views + + describe 'GET #show' do + before do + get :show + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns public cache control header' do + expect(response.headers['Cache-Control']).to include('public') + end + + it 'does not set cookies' do + expect(response.cookies).to be_empty + expect(response.headers['Set-Cookies']).to be_nil + end + + it 'does not set sessions' do + expect(session).to be_empty + end + end +end diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb index 90f222f494..c8444a2a96 100644 --- a/spec/controllers/disputes/appeals_controller_spec.rb +++ b/spec/controllers/disputes/appeals_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Disputes::AppealsController, type: :controller do +RSpec.describe Disputes::AppealsController do render_views before { sign_in current_user, scope: :user } @@ -12,12 +14,11 @@ RSpec.describe Disputes::AppealsController, type: :controller do let(:strike) { Fabricate(:account_warning, target_account: current_user.account) } before do - allow(AdminMailer).to receive(:new_appeal).and_return(double('email', deliver_later: nil)) post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } } end it 'notifies staff about new appeal' do - expect(AdminMailer).to have_received(:new_appeal).with(admin.account, Appeal.last) + expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email]) end it 'redirects back to the strike page' do diff --git a/spec/controllers/disputes/strikes_controller_spec.rb b/spec/controllers/disputes/strikes_controller_spec.rb index 157f9ec3c7..f6d28fc09a 100644 --- a/spec/controllers/disputes/strikes_controller_spec.rb +++ b/spec/controllers/disputes/strikes_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Disputes::StrikesController, type: :controller do +RSpec.describe Disputes::StrikesController do render_views before { sign_in current_user, scope: :user } @@ -23,7 +25,7 @@ RSpec.describe Disputes::StrikesController, type: :controller do let(:strike) { Fabricate(:account_warning) } it 'returns http forbidden' do - expect(response).to have_http_status(:forbidden) + expect(response).to have_http_status(403) end end end diff --git a/spec/controllers/emojis_controller_spec.rb b/spec/controllers/emojis_controller_spec.rb index fbbd11f648..249dfd9d51 100644 --- a/spec/controllers/emojis_controller_spec.rb +++ b/spec/controllers/emojis_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe EmojisController do @@ -6,9 +8,10 @@ describe EmojisController do let(:emoji) { Fabricate(:custom_emoji) } describe 'GET #show' do - subject(:response) { get :show, params: { id: emoji.id, format: :json } } subject(:body) { JSON.parse(response.body, symbolize_names: true) } + let(:response) { get :show, params: { id: emoji.id, format: :json } } + it 'returns the right response' do expect(response).to have_http_status 200 expect(body[:name]).to eq ':coolcat:' diff --git a/spec/controllers/filters/statuses_controller_spec.rb b/spec/controllers/filters/statuses_controller_spec.rb new file mode 100644 index 0000000000..2c80613302 --- /dev/null +++ b/spec/controllers/filters/statuses_controller_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Filters::StatusesController do + render_views + + describe 'GET #index' do + let(:filter) { Fabricate(:custom_filter) } + + context 'with signed out user' do + it 'redirects' do + get :index, params: { filter_id: filter } + + expect(response).to be_redirect + end + end + + context 'with a signed in user' do + context 'with the filter user signed in' do + before do + sign_in(filter.account.user) + get :index, params: { filter_id: filter } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + + context 'with another user signed in' do + before do + sign_in(Fabricate(:user)) + get :index, params: { filter_id: filter } + end + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + end +end diff --git a/spec/controllers/filters_controller_spec.rb b/spec/controllers/filters_controller_spec.rb new file mode 100644 index 0000000000..091f714bb3 --- /dev/null +++ b/spec/controllers/filters_controller_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe FiltersController do + render_views + + describe 'GET #index' do + context 'with signed out user' do + before do + get :index + end + + it 'redirects' do + expect(response).to be_redirect + end + end + + context 'with a signed in user' do + before do + sign_in(Fabricate(:user)) + get :index + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + end +end diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index ab2e82e850..cb8c2a0e5b 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + require 'rails_helper' describe FollowerAccountsController do render_views - let(:alice) { Fabricate(:account) } - let(:follower0) { Fabricate(:account) } - let(:follower1) { Fabricate(:account) } + let(:alice) { Fabricate(:account, username: 'alice') } + let(:follower_bob) { Fabricate(:account, username: 'bob') } + let(:follower_chris) { Fabricate(:account, username: 'curt') } describe 'GET #index' do - let!(:follow0) { follower0.follow!(alice) } - let!(:follow1) { follower1.follow!(alice) } + let!(:follow_from_bob) { follower_bob.follow!(alice) } + let!(:follow_from_chris) { follower_chris.follow!(alice) } context 'when format is html' do subject(:response) { get :index, params: { account_username: alice.username, format: :html } } @@ -37,8 +39,9 @@ describe FollowerAccountsController do end context 'when format is json' do - subject(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } - subject(:body) { JSON.parse(response.body) } + subject(:body) { response.parsed_body } + + let(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } context 'with page' do let(:page) { 1 } diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index e43dbf882b..095528ed07 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + require 'rails_helper' describe FollowingAccountsController do render_views - let(:alice) { Fabricate(:account) } - let(:followee0) { Fabricate(:account) } - let(:followee1) { Fabricate(:account) } + let(:alice) { Fabricate(:account, username: 'alice') } + let(:followee_bob) { Fabricate(:account, username: 'bob') } + let(:followee_chris) { Fabricate(:account, username: 'chris') } describe 'GET #index' do - let!(:follow0) { alice.follow!(followee0) } - let!(:follow1) { alice.follow!(followee1) } + let!(:follow_of_bob) { alice.follow!(followee_bob) } + let!(:follow_of_chris) { alice.follow!(followee_chris) } context 'when format is html' do subject(:response) { get :index, params: { account_username: alice.username, format: :html } } @@ -37,8 +39,9 @@ describe FollowingAccountsController do end context 'when format is json' do - subject(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } - subject(:body) { JSON.parse(response.body) } + subject(:body) { response.parsed_body } + + let(:response) { get :index, params: { account_username: alice.username, page: page, format: :json } } context 'with page' do let(:page) { 1 } diff --git a/spec/controllers/health_controller_spec.rb b/spec/controllers/health_controller_spec.rb new file mode 100644 index 0000000000..282b664199 --- /dev/null +++ b/spec/controllers/health_controller_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe HealthController do + render_views + + describe 'GET #show' do + it 'returns http success' do + get :show + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index d845ae01d7..3ddc5691a9 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe HomeController, type: :controller do +RSpec.describe HomeController do render_views describe 'GET #index' do @@ -9,7 +11,7 @@ RSpec.describe HomeController, type: :controller do context 'when not signed in' do it 'returns http success' do @request.path = '/' - is_expected.to have_http_status(:success) + expect(subject).to have_http_status(:success) end end @@ -21,7 +23,7 @@ RSpec.describe HomeController, type: :controller do end it 'returns http success' do - is_expected.to have_http_status(:success) + expect(subject).to have_http_status(:success) end end end diff --git a/spec/controllers/instance_actors_controller_spec.rb b/spec/controllers/instance_actors_controller_spec.rb index f64a7d2ca3..8406094311 100644 --- a/spec/controllers/instance_actors_controller_spec.rb +++ b/spec/controllers/instance_actors_controller_spec.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe InstanceActorsController, type: :controller do +RSpec.describe InstanceActorsController do describe 'GET #show' do - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } shared_examples 'shared behavior' do @@ -20,7 +22,7 @@ RSpec.describe InstanceActorsController, type: :controller do it 'does not set cookies' do expect(response.cookies).to be_empty - expect(response.headers['Set-Cookies']).to be nil + expect(response.headers['Set-Cookies']).to be_nil end it 'does not set sessions' do @@ -43,11 +45,13 @@ RSpec.describe InstanceActorsController, type: :controller do context 'without authorized fetch mode' do let(:authorized_fetch_mode) { false } + it_behaves_like 'shared behavior' end context 'with authorized fetch mode' do let(:authorized_fetch_mode) { true } + it_behaves_like 'shared behavior' end end diff --git a/spec/controllers/intents_controller_spec.rb b/spec/controllers/intents_controller_spec.rb index ddfd5ea365..668d833ea7 100644 --- a/spec/controllers/intents_controller_spec.rb +++ b/spec/controllers/intents_controller_spec.rb @@ -1,9 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe IntentsController, type: :controller do +RSpec.describe IntentsController do render_views let(:user) { Fabricate(:user) } + before { sign_in user, scope: :user } describe 'GET #show' do diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb index 23b98fb129..3190c82884 100644 --- a/spec/controllers/invites_controller_spec.rb +++ b/spec/controllers/invites_controller_spec.rb @@ -1,37 +1,44 @@ +# frozen_string_literal: true + require 'rails_helper' describe InvitesController do render_views + let(:user) { Fabricate(:user) } + before do sign_in user end describe 'GET #index' do - subject { get :index } - - let(:user) { Fabricate(:user) } - let!(:invite) { Fabricate(:invite, user: user) } + before do + Fabricate(:invite, user: user) + end context 'when everyone can invite' do before do UserRole.everyone.update(permissions: UserRole.everyone.permissions | UserRole::FLAGS[:invite_users]) + get :index end - it 'renders index page' do - expect(subject).to render_template :index - expect(assigns(:invites)).to include invite - expect(assigns(:invites).count).to eq 1 + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') end end context 'when not everyone can invite' do before do UserRole.everyone.update(permissions: UserRole.everyone.permissions & ~UserRole::FLAGS[:invite_users]) + get :index end - it 'returns 403' do - expect(subject).to have_http_status 403 + it 'returns http forbidden' do + expect(response).to have_http_status(403) end end end @@ -40,40 +47,40 @@ describe InvitesController do subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } } context 'when everyone can invite' do - let(:user) { Fabricate(:user) } - before do UserRole.everyone.update(permissions: UserRole.everyone.permissions | UserRole::FLAGS[:invite_users]) end it 'succeeds to create a invite' do - expect { subject }.to change { Invite.count }.by(1) + expect { subject }.to change(Invite, :count).by(1) expect(subject).to redirect_to invites_path expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10) end end context 'when not everyone can invite' do - let(:user) { Fabricate(:user) } - before do UserRole.everyone.update(permissions: UserRole.everyone.permissions & ~UserRole::FLAGS[:invite_users]) end - it 'returns 403' do - expect(subject).to have_http_status 403 + it 'returns http forbidden' do + expect(subject).to have_http_status(403) end end end describe 'DELETE #create' do - subject { delete :destroy, params: { id: invite.id } } + let(:invite) { Fabricate(:invite, user: user, expires_at: nil) } - let(:user) { Fabricate(:user) } - let!(:invite) { Fabricate(:invite, user: user, expires_at: nil) } + before do + delete :destroy, params: { id: invite.id } + end + + it 'redirects' do + expect(response).to redirect_to invites_path + end it 'expires invite' do - expect(subject).to redirect_to invites_path expect(invite.reload).to be_expired end end diff --git a/spec/controllers/manifests_controller_spec.rb b/spec/controllers/manifests_controller_spec.rb index a549adef3f..d0699c438b 100644 --- a/spec/controllers/manifests_controller_spec.rb +++ b/spec/controllers/manifests_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe ManifestsController do @@ -5,11 +7,24 @@ describe ManifestsController do describe 'GET #show' do before do - get :show, format: :json + get :show end it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns public cache control header' do + expect(response.headers['Cache-Control']).to include('public') + end + + it 'does not set cookies' do + expect(response.cookies).to be_empty + expect(response.headers['Set-Cookies']).to be_nil + end + + it 'does not set sessions' do + expect(session).to be_empty + end end end diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb index c5eeea397e..9b3ae251e6 100644 --- a/spec/controllers/oauth/authorizations_controller_spec.rb +++ b/spec/controllers/oauth/authorizations_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Oauth::AuthorizationsController, type: :controller do +RSpec.describe Oauth::AuthorizationsController do render_views let(:app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/', scopes: 'read') } @@ -31,6 +31,11 @@ RSpec.describe Oauth::AuthorizationsController, type: :controller do expect(response).to have_http_status(200) end + it 'returns private cache control headers' do + subject + expect(response.headers['Cache-Control']).to include('private, no-store') + end + it 'gives options to authorize and deny' do subject expect(response.body).to match(/Authorize/) diff --git a/spec/controllers/oauth/authorized_applications_controller_spec.rb b/spec/controllers/oauth/authorized_applications_controller_spec.rb index 901e538e95..b54610604c 100644 --- a/spec/controllers/oauth/authorized_applications_controller_spec.rb +++ b/spec/controllers/oauth/authorized_applications_controller_spec.rb @@ -13,7 +13,7 @@ describe Oauth::AuthorizedApplicationsController do shared_examples 'stores location for user' do it 'stores location for user' do subject - expect(controller.stored_location_for(:user)).to eq "/oauth/authorized_applications" + expect(controller.stored_location_for(:user)).to eq '/oauth/authorized_applications' end end @@ -27,6 +27,11 @@ describe Oauth::AuthorizedApplicationsController do expect(response).to have_http_status(200) end + it 'returns private cache control headers' do + subject + expect(response.headers['Cache-Control']).to include('private, no-store') + end + include_examples 'stores location for user' end diff --git a/spec/controllers/oauth/tokens_controller_spec.rb b/spec/controllers/oauth/tokens_controller_spec.rb index 3804e035bb..973393bcf2 100644 --- a/spec/controllers/oauth/tokens_controller_spec.rb +++ b/spec/controllers/oauth/tokens_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Oauth::TokensController, type: :controller do +RSpec.describe Oauth::TokensController do describe 'POST #revoke' do let!(:user) { Fabricate(:user) } let!(:application) { Fabricate(:application, confidential: false) } diff --git a/spec/controllers/privacy_controller_spec.rb b/spec/controllers/privacy_controller_spec.rb new file mode 100644 index 0000000000..c92c71ea64 --- /dev/null +++ b/spec/controllers/privacy_controller_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PrivacyController do + render_views + + describe 'GET #show' do + it 'returns http success' do + get :show + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/controllers/relationships_controller_spec.rb b/spec/controllers/relationships_controller_spec.rb index bcdcfa9051..9495fc214f 100644 --- a/spec/controllers/relationships_controller_spec.rb +++ b/spec/controllers/relationships_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe RelationshipsController do @@ -5,42 +7,39 @@ describe RelationshipsController do let(:user) { Fabricate(:user) } - shared_examples 'authenticate user' do - it 'redirects when not signed in' do - is_expected.to redirect_to '/auth/sign_in' - end - end - describe 'GET #show' do - subject { get :show, params: { page: 2, relationship: 'followed_by' } } + context 'when signed in' do + before do + sign_in user, scope: :user + get :show, params: { page: 2, relationship: 'followed_by' } + end - it 'assigns @accounts' do - Fabricate(:account, domain: 'old').follow!(user.account) - Fabricate(:account, domain: 'recent').follow!(user.account) + it 'returns http success' do + expect(response).to have_http_status(200) + end - sign_in user, scope: :user - subject - - assigned = assigns(:accounts).per(1).to_a - expect(assigned.size).to eq 1 - expect(assigned[0].domain).to eq 'old' + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end - it 'returns http success' do - sign_in user, scope: :user - subject - expect(response).to have_http_status(200) - end + context 'when not signed in' do + before do + get :show, params: { page: 2, relationship: 'followed_by' } + end - include_examples 'authenticate user' + it 'redirects when not signed in' do + expect(response).to redirect_to '/auth/sign_in' + end + end end describe 'PATCH #update' do - let(:poopfeast) { Fabricate(:account, username: 'poopfeast', domain: 'example.com') } + let(:alice) { Fabricate(:account, username: 'alice', domain: 'example.com') } shared_examples 'redirects back to followers page' do it 'redirects back to followers page' do - poopfeast.follow!(user.account) + alice.follow!(user.account) sign_in user, scope: :user subject @@ -51,31 +50,41 @@ describe RelationshipsController do context 'when select parameter is not provided' do subject { patch :update } + include_examples 'redirects back to followers page' end context 'when select parameter is provided' do - subject { patch :update, params: { form_account_batch: { account_ids: [poopfeast.id] }, remove_domains_from_followers: '' } } + subject { patch :update, params: { form_account_batch: { account_ids: [alice.id] }, remove_domains_from_followers: '' } } it 'soft-blocks followers from selected domains' do - poopfeast.follow!(user.account) + alice.follow!(user.account) sign_in user, scope: :user subject - expect(poopfeast.following?(user.account)).to be false + expect(alice.following?(user.account)).to be false end it 'does not unfollow users from selected domains' do - user.account.follow!(poopfeast) + user.account.follow!(alice) sign_in user, scope: :user subject - expect(user.account.following?(poopfeast)).to be true + expect(user.account.following?(alice)).to be true + end + + context 'when not signed in' do + before do + subject + end + + it 'redirects when not signed in' do + expect(response).to redirect_to '/auth/sign_in' + end end - include_examples 'authenticate user' include_examples 'redirects back to followers page' end end diff --git a/spec/controllers/settings/aliases_controller_spec.rb b/spec/controllers/settings/aliases_controller_spec.rb new file mode 100644 index 0000000000..9636c1ac55 --- /dev/null +++ b/spec/controllers/settings/aliases_controller_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::AliasesController do + render_views + + let!(:user) { Fabricate(:user) } + let(:account) { user.account } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + before do + get :index + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + + describe 'POST #create' do + context 'with valid alias' do + before { stub_resolver } + + it 'creates an alias for the user' do + expect do + post :create, params: { account_alias: { acct: 'new@example.com' } } + end.to change(AccountAlias, :count).by(1) + + expect(response).to redirect_to(settings_aliases_path) + end + end + + context 'with invalid alias' do + it 'does not create an alias for the user' do + expect do + post :create, params: { account_alias: { acct: 'format-wrong' } } + end.to_not change(AccountAlias, :count) + + expect(response).to have_http_status(200) + end + end + end + + describe 'DELETE #destroy' do + let(:account_alias) do + AccountAlias.new(account: user.account, acct: 'new@example.com').tap do |account_alias| + account_alias.save(validate: false) + end + end + + it 'removes an alias' do + delete :destroy, params: { id: account_alias.id } + + expect(response).to redirect_to(settings_aliases_path) + expect { account_alias.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + + private + + def stub_resolver + resolver = instance_double(ResolveAccountService, call: Fabricate(:account)) + allow(ResolveAccountService).to receive(:new).and_return(resolver) + end +end diff --git a/spec/controllers/settings/applications_controller_spec.rb b/spec/controllers/settings/applications_controller_spec.rb index 1292e9ff83..169304b3ed 100644 --- a/spec/controllers/settings/applications_controller_spec.rb +++ b/spec/controllers/settings/applications_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::ApplicationsController do @@ -11,13 +13,17 @@ describe Settings::ApplicationsController do end describe 'GET #index' do - let!(:other_app) { Fabricate(:application) } - - it 'shows apps' do + before do + Fabricate(:application) get :index + end + + it 'returns http success' do expect(response).to have_http_status(200) - expect(assigns(:applications)).to include(app) - expect(assigns(:applications)).to_not include(other_app) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') end end @@ -32,27 +38,27 @@ describe Settings::ApplicationsController do app.update!(owner: nil) get :show, params: { id: app.id } - expect(response.status).to eq 404 + expect(response).to have_http_status 404 end end describe 'GET #new' do - it 'works' do + it 'returns http success' do get :new expect(response).to have_http_status(200) end end describe 'POST #create' do - context 'success (passed scopes as a String)' do + context 'when success (passed scopes as a String)' do def call_create post :create, params: { doorkeeper_application: { name: 'My New App', redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', website: 'http://google.com', - scopes: 'read write follow' - } + scopes: 'read write follow', + }, } response end @@ -66,15 +72,15 @@ describe Settings::ApplicationsController do end end - context 'success (passed scopes as an Array)' do + context 'when success (passed scopes as an Array)' do def call_create post :create, params: { doorkeeper_application: { name: 'My New App', redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', website: 'http://google.com', - scopes: [ 'read', 'write', 'follow' ] - } + scopes: %w(read write follow), + }, } response end @@ -88,15 +94,15 @@ describe Settings::ApplicationsController do end end - context 'failure' do + context 'with failure request' do before do post :create, params: { doorkeeper_application: { name: '', redirect_uri: '', website: '', - scopes: [] - } + scopes: [], + }, } end @@ -111,17 +117,17 @@ describe Settings::ApplicationsController do end describe 'PATCH #update' do - context 'success' do - let(:opts) { + context 'when success' do + let(:opts) do { - website: 'https://foo.bar/' + website: 'https://foo.bar/', } - } + end def call_update patch :update, params: { id: app.id, - doorkeeper_application: opts + doorkeeper_application: opts, } response end @@ -136,7 +142,7 @@ describe Settings::ApplicationsController do end end - context 'failure' do + context 'with failure request' do before do patch :update, params: { id: app.id, @@ -144,8 +150,8 @@ describe Settings::ApplicationsController do name: '', redirect_uri: '', website: '', - scopes: [] - } + scopes: [], + }, } end @@ -175,12 +181,11 @@ describe Settings::ApplicationsController do describe 'regenerate' do let(:token) { user.token_for_app(app) } - before do + + it 'creates new token' do expect(token).to_not be_nil post :regenerate, params: { id: app.id } - end - it 'should create new token' do expect(user.token_for_app(app)).to_not eql(token) end end diff --git a/spec/controllers/settings/deletes_controller_spec.rb b/spec/controllers/settings/deletes_controller_spec.rb index a94dc042a5..7ee18f9fb1 100644 --- a/spec/controllers/settings/deletes_controller_spec.rb +++ b/spec/controllers/settings/deletes_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::DeletesController do @@ -9,20 +11,27 @@ describe Settings::DeletesController do before do sign_in user, scope: :user + get :show end it 'renders confirmation page' do - get :show expect(response).to have_http_status(200) end + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + context 'when suspended' do let(:user) { Fabricate(:user, account_attributes: { suspended_at: Time.now.utc }) } it 'returns http forbidden' do - get :show expect(response).to have_http_status(403) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end end diff --git a/spec/controllers/settings/exports/blocked_accounts_controller_spec.rb b/spec/controllers/settings/exports/blocked_accounts_controller_spec.rb index 5ff41b7fcd..459b278d64 100644 --- a/spec/controllers/settings/exports/blocked_accounts_controller_spec.rb +++ b/spec/controllers/settings/exports/blocked_accounts_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::Exports::BlockedAccountsController do diff --git a/spec/controllers/settings/exports/blocked_domains_controller_spec.rb b/spec/controllers/settings/exports/blocked_domains_controller_spec.rb new file mode 100644 index 0000000000..ac72fd9dd7 --- /dev/null +++ b/spec/controllers/settings/exports/blocked_domains_controller_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::Exports::BlockedDomainsController do + render_views + + describe 'GET #index' do + it 'returns a csv of the domains' do + account = Fabricate(:account, domain: 'example.com') + user = Fabricate(:user, account: account) + Fabricate(:account_domain_block, domain: 'example.com', account: account) + + sign_in user, scope: :user + get :index, format: :csv + + expect(response.body).to eq "example.com\n" + end + end +end diff --git a/spec/controllers/settings/exports/bookmarks_controller_spec.rb b/spec/controllers/settings/exports/bookmarks_controller_spec.rb index a06c02e0c3..9982eff165 100644 --- a/spec/controllers/settings/exports/bookmarks_controller_spec.rb +++ b/spec/controllers/settings/exports/bookmarks_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::Exports::BookmarksController do diff --git a/spec/controllers/settings/exports/following_accounts_controller_spec.rb b/spec/controllers/settings/exports/following_accounts_controller_spec.rb index bfe0105556..72b0b94e13 100644 --- a/spec/controllers/settings/exports/following_accounts_controller_spec.rb +++ b/spec/controllers/settings/exports/following_accounts_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::Exports::FollowingAccountsController do diff --git a/spec/controllers/settings/exports/lists_controller_spec.rb b/spec/controllers/settings/exports/lists_controller_spec.rb new file mode 100644 index 0000000000..29623ba499 --- /dev/null +++ b/spec/controllers/settings/exports/lists_controller_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::Exports::ListsController do + render_views + + describe 'GET #index' do + it 'returns a csv of the domains' do + account = Fabricate(:account) + user = Fabricate(:user, account: account) + list = Fabricate(:list, account: account, title: 'The List') + Fabricate(:list_account, list: list, account: account) + + sign_in user, scope: :user + get :index, format: :csv + + expect(response.body).to match 'The List' + end + end +end diff --git a/spec/controllers/settings/exports/muted_accounts_controller_spec.rb b/spec/controllers/settings/exports/muted_accounts_controller_spec.rb index 642f0a9b8f..b4170cb160 100644 --- a/spec/controllers/settings/exports/muted_accounts_controller_spec.rb +++ b/spec/controllers/settings/exports/muted_accounts_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::Exports::MutedAccountsController do diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb index a46fe095d8..6a42021318 100644 --- a/spec/controllers/settings/exports_controller_spec.rb +++ b/spec/controllers/settings/exports_controller_spec.rb @@ -11,16 +11,16 @@ describe Settings::ExportsController do before do sign_in user, scope: :user + get :show end - it 'renders export' do - get :show - - export = assigns(:export) - expect(export).to be_instance_of Export - expect(export.account).to eq user.account + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end context 'when not signed in' do diff --git a/spec/controllers/settings/featured_tags_controller_spec.rb b/spec/controllers/settings/featured_tags_controller_spec.rb index 33b87f9f67..fc25e7aa88 100644 --- a/spec/controllers/settings/featured_tags_controller_spec.rb +++ b/spec/controllers/settings/featured_tags_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::FeaturedTagsController do @@ -5,24 +7,24 @@ describe Settings::FeaturedTagsController do shared_examples 'authenticate user' do it 'redirects to sign_in page' do - is_expected.to redirect_to new_user_session_path + expect(subject).to redirect_to new_user_session_path end end - describe 'POST #create' do - context 'when user is not sign in' do - subject { post :create } + context 'when user is not signed in' do + subject { post :create } - it_behaves_like 'authenticate user' - end + it_behaves_like 'authenticate user' + end - context 'when user is sign in' do + context 'when user is signed in' do + let(:user) { Fabricate(:user, password: '12345678') } + + before { sign_in user, scope: :user } + + describe 'POST #create' do subject { post :create, params: { featured_tag: params } } - let(:user) { Fabricate(:user, password: '12345678') } - - before { sign_in user, scope: :user } - context 'when parameter is valid' do let(:params) { { name: 'test' } } @@ -39,5 +41,24 @@ describe Settings::FeaturedTagsController do end end end + + describe 'GET to #index' do + it 'responds with success' do + get :index + + expect(response).to have_http_status(200) + end + end + + describe 'DELETE to #destroy' do + let(:featured_tag) { Fabricate(:featured_tag, account: user.account) } + + it 'removes the featured tag' do + delete :destroy, params: { id: featured_tag.id } + + expect(response).to redirect_to(settings_featured_tags_path) + expect { featured_tag.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end end end diff --git a/spec/controllers/settings/flavours_controller_spec.rb b/spec/controllers/settings/flavours_controller_spec.rb new file mode 100644 index 0000000000..8c7d4a7688 --- /dev/null +++ b/spec/controllers/settings/flavours_controller_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Settings::FlavoursController do + let(:user) { Fabricate(:user) } + + before do + sign_in user, scope: :user + end + + describe 'PUT #update' do + describe 'without a user[setting_skin] parameter' do + it 'sets the selected flavour' do + put :update, params: { flavour: 'schnozzberry' } + + user.reload + + expect(user.setting_flavour).to eq 'schnozzberry' + end + end + + describe 'with a user[setting_skin] parameter' do + before do + put :update, params: { flavour: 'schnozzberry', user: { setting_skin: 'wallpaper' } } + + user.reload + end + + it 'sets the selected flavour' do + expect(user.setting_flavour).to eq 'schnozzberry' + end + + it 'sets the selected skin' do + expect(user.setting_skin).to eq 'wallpaper' + end + end + end +end diff --git a/spec/controllers/settings/imports_controller_spec.rb b/spec/controllers/settings/imports_controller_spec.rb index b8caf59413..76e1e4ecb0 100644 --- a/spec/controllers/settings/imports_controller_spec.rb +++ b/spec/controllers/settings/imports_controller_spec.rb @@ -1,44 +1,319 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Settings::ImportsController, type: :controller do +RSpec.describe Settings::ImportsController do render_views + let(:user) { Fabricate(:user) } + before do - sign_in Fabricate(:user), scope: :user + sign_in user, scope: :user end - describe "GET #show" do - it "returns http success" do - get :show + describe 'GET #index' do + let!(:import) { Fabricate(:bulk_import, account: user.account) } + let!(:other_import) { Fabricate(:bulk_import) } + + before do + get :index + end + + it 'assigns the expected imports' do + expect(assigns(:recent_imports)).to eq [import] + end + + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + + describe 'GET #show' do + before do + get :show, params: { id: bulk_import.id } + end + + context 'with someone else\'s import' do + let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + + context 'with an already-confirmed import' do + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + + context 'with an unconfirmed import' do + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) } + + it 'returns http success' do + expect(response).to have_http_status(200) + end + end + end + + describe 'POST #confirm' do + subject { post :confirm, params: { id: bulk_import.id } } + + before do + allow(BulkImportWorker).to receive(:perform_async) + end + + context 'with someone else\'s import' do + let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) } + + it 'does not change the import\'s state' do + expect { subject }.to_not(change { bulk_import.reload.state }) + end + + it 'does not fire the import worker' do + subject + expect(BulkImportWorker).to_not have_received(:perform_async) + end + + it 'returns http not found' do + subject + expect(response).to have_http_status(404) + end + end + + context 'with an already-confirmed import' do + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) } + + it 'does not change the import\'s state' do + expect { subject }.to_not(change { bulk_import.reload.state }) + end + + it 'does not fire the import worker' do + subject + expect(BulkImportWorker).to_not have_received(:perform_async) + end + + it 'returns http not found' do + subject + expect(response).to have_http_status(404) + end + end + + context 'with an unconfirmed import' do + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) } + + it 'changes the import\'s state to scheduled' do + expect { subject }.to change { bulk_import.reload.state.to_sym }.from(:unconfirmed).to(:scheduled) + end + + it 'fires the import worker on the expected import' do + subject + expect(BulkImportWorker).to have_received(:perform_async).with(bulk_import.id) + end + + it 'redirects to imports path' do + subject + expect(response).to redirect_to(settings_imports_path) + end + end + end + + describe 'DELETE #destroy' do + subject { delete :destroy, params: { id: bulk_import.id } } + + context 'with someone else\'s import' do + let(:bulk_import) { Fabricate(:bulk_import, state: :unconfirmed) } + + it 'does not delete the import' do + expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) }) + end + + it 'returns http not found' do + subject + expect(response).to have_http_status(404) + end + end + + context 'with an already-confirmed import' do + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :in_progress) } + + it 'does not delete the import' do + expect { subject }.to_not(change { BulkImport.exists?(bulk_import.id) }) + end + + it 'returns http not found' do + subject + expect(response).to have_http_status(404) + end + end + + context 'with an unconfirmed import' do + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, state: :unconfirmed) } + + it 'deletes the import' do + expect { subject }.to change { BulkImport.exists?(bulk_import.id) }.from(true).to(false) + end + + it 'redirects to imports path' do + subject + expect(response).to redirect_to(settings_imports_path) + end + end + end + + describe 'GET #failures' do + subject { get :failures, params: { id: bulk_import.id }, format: :csv } + + shared_examples 'export failed rows' do |expected_contents| + let(:bulk_import) { Fabricate(:bulk_import, account: user.account, type: import_type, state: :finished) } + + before do + bulk_import.update(total_items: bulk_import.rows.count, processed_items: bulk_import.rows.count, imported_items: 0) + end + + it 'returns http success' do + subject + expect(response).to have_http_status(200) + end + + it 'returns expected contents' do + subject + expect(response.body).to eq expected_contents + end + end + + context 'with follows' do + let(:import_type) { 'following' } + + let!(:rows) do + [ + { 'acct' => 'foo@bar' }, + { 'acct' => 'user@bar', 'show_reblogs' => false, 'notify' => true, 'languages' => ['fr', 'de'] }, + ].map { |data| Fabricate(:bulk_import_row, bulk_import: bulk_import, data: data) } + end + + include_examples 'export failed rows', "Account address,Show boosts,Notify on new posts,Languages\nfoo@bar,true,false,\nuser@bar,false,true,\"fr, de\"\n" + end + + context 'with blocks' do + let(:import_type) { 'blocking' } + + let!(:rows) do + [ + { 'acct' => 'foo@bar' }, + { 'acct' => 'user@bar' }, + ].map { |data| Fabricate(:bulk_import_row, bulk_import: bulk_import, data: data) } + end + + include_examples 'export failed rows', "foo@bar\nuser@bar\n" + end + + context 'with mutes' do + let(:import_type) { 'muting' } + + let!(:rows) do + [ + { 'acct' => 'foo@bar' }, + { 'acct' => 'user@bar', 'hide_notifications' => false }, + ].map { |data| Fabricate(:bulk_import_row, bulk_import: bulk_import, data: data) } + end + + include_examples 'export failed rows', "Account address,Hide notifications\nfoo@bar,true\nuser@bar,false\n" + end + + context 'with domain blocks' do + let(:import_type) { 'domain_blocking' } + + let!(:rows) do + [ + { 'domain' => 'bad.domain' }, + { 'domain' => 'evil.domain' }, + ].map { |data| Fabricate(:bulk_import_row, bulk_import: bulk_import, data: data) } + end + + include_examples 'export failed rows', "bad.domain\nevil.domain\n" + end + + context 'with bookmarks' do + let(:import_type) { 'bookmarks' } + + let!(:rows) do + [ + { 'uri' => 'https://foo.com/1' }, + { 'uri' => 'https://foo.com/2' }, + ].map { |data| Fabricate(:bulk_import_row, bulk_import: bulk_import, data: data) } + end + + include_examples 'export failed rows', "https://foo.com/1\nhttps://foo.com/2\n" + end end describe 'POST #create' do - it 'redirects to settings path with successful following import' do - service = double(call: nil) - allow(ResolveAccountService).to receive(:new).and_return(service) + subject do post :create, params: { - import: { - type: 'following', - data: fixture_file_upload('imports.txt') - } + form_import: { + type: import_type, + mode: import_mode, + data: fixture_file_upload(import_file), + }, } - - expect(response).to redirect_to(settings_import_path) end - it 'redirects to settings path with successful blocking import' do - service = double(call: nil) - allow(ResolveAccountService).to receive(:new).and_return(service) - post :create, params: { - import: { - type: 'blocking', - data: fixture_file_upload('imports.txt') - } - } + shared_examples 'successful import' do |type, file, mode| + let(:import_type) { type } + let(:import_file) { file } + let(:import_mode) { mode } - expect(response).to redirect_to(settings_import_path) + it 'creates an unconfirmed bulk_import with expected type' do + expect { subject }.to change { user.account.bulk_imports.pluck(:state, :type) }.from([]).to([['unconfirmed', import_type]]) + end + + it 'redirects to confirmation page for the import' do + subject + expect(response).to redirect_to(settings_import_path(user.account.bulk_imports.first)) + end end + + shared_examples 'unsuccessful import' do |type, file, mode| + let(:import_type) { type } + let(:import_file) { file } + let(:import_mode) { mode } + + it 'does not creates an unconfirmed bulk_import' do + expect { subject }.to_not(change { user.account.bulk_imports.count }) + end + + it 'sets error to the import' do + subject + expect(assigns(:import).errors).to_not be_empty + end + end + + it_behaves_like 'successful import', 'following', 'imports.txt', 'merge' + it_behaves_like 'successful import', 'following', 'imports.txt', 'overwrite' + it_behaves_like 'successful import', 'blocking', 'imports.txt', 'merge' + it_behaves_like 'successful import', 'blocking', 'imports.txt', 'overwrite' + it_behaves_like 'successful import', 'muting', 'imports.txt', 'merge' + it_behaves_like 'successful import', 'muting', 'imports.txt', 'overwrite' + it_behaves_like 'successful import', 'domain_blocking', 'domain_blocks.csv', 'merge' + it_behaves_like 'successful import', 'domain_blocking', 'domain_blocks.csv', 'overwrite' + it_behaves_like 'successful import', 'bookmarks', 'bookmark-imports.txt', 'merge' + it_behaves_like 'successful import', 'bookmarks', 'bookmark-imports.txt', 'overwrite' + + it_behaves_like 'unsuccessful import', 'following', 'domain_blocks.csv', 'merge' + it_behaves_like 'unsuccessful import', 'following', 'domain_blocks.csv', 'overwrite' + it_behaves_like 'unsuccessful import', 'blocking', 'domain_blocks.csv', 'merge' + it_behaves_like 'unsuccessful import', 'blocking', 'domain_blocks.csv', 'overwrite' + it_behaves_like 'unsuccessful import', 'muting', 'domain_blocks.csv', 'merge' + it_behaves_like 'unsuccessful import', 'muting', 'domain_blocks.csv', 'overwrite' + + it_behaves_like 'unsuccessful import', 'following', 'empty.csv', 'merge' + it_behaves_like 'unsuccessful import', 'following', 'empty.csv', 'overwrite' end end diff --git a/spec/controllers/settings/login_activities_controller_spec.rb b/spec/controllers/settings/login_activities_controller_spec.rb new file mode 100644 index 0000000000..80c8f484cc --- /dev/null +++ b/spec/controllers/settings/login_activities_controller_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::LoginActivitiesController do + render_views + + let!(:user) { Fabricate(:user) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + before do + get :index + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end +end diff --git a/spec/controllers/settings/migration/redirects_controller_spec.rb b/spec/controllers/settings/migration/redirects_controller_spec.rb new file mode 100644 index 0000000000..aa6df64cff --- /dev/null +++ b/spec/controllers/settings/migration/redirects_controller_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::Migration::RedirectsController do + render_views + + let!(:user) { Fabricate(:user, password: 'testtest') } + + before do + sign_in user, scope: :user + end + + describe 'GET #new' do + before do + get :new + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + + describe 'POST #create' do + context 'with valid params' do + before { stub_resolver } + + it 'redirects to the settings migration path' do + post :create, params: { form_redirect: { acct: 'new@host.com', current_password: 'testtest' } } + + expect(response).to redirect_to(settings_migration_path) + end + end + + context 'with non valid params' do + it 'returns success and renders the new page' do + post :create, params: { form_redirect: { acct: '' } } + + expect(response).to have_http_status(200) + expect(response).to render_template(:new) + end + end + end + + describe 'DELETE #destroy' do + let(:account) { Fabricate(:account) } + + before do + user.account.update(moved_to_account_id: account.id) + end + + it 'resets the account and sends an update' do + delete :destroy + + expect(response).to redirect_to(settings_migration_path) + expect(user.account.reload.moved_to_account).to be_nil + end + end + + private + + def stub_resolver + resolver = instance_double(ResolveAccountService, call: Fabricate(:account)) + allow(ResolveAccountService).to receive(:new).and_return(resolver) + end +end diff --git a/spec/controllers/settings/migrations_controller_spec.rb b/spec/controllers/settings/migrations_controller_spec.rb index 35c5747a06..9b12bc40f1 100644 --- a/spec/controllers/settings/migrations_controller_spec.rb +++ b/spec/controllers/settings/migrations_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::MigrationsController do @@ -5,7 +7,7 @@ describe Settings::MigrationsController do shared_examples 'authenticate user' do it 'redirects to sign_in page' do - is_expected.to redirect_to new_user_session_path + expect(subject).to redirect_to new_user_session_path end end @@ -27,8 +29,8 @@ describe Settings::MigrationsController do let(:moved_to_account) { nil } it 'renders show page' do - is_expected.to have_http_status 200 - is_expected.to render_template :show + expect(subject).to have_http_status 200 + expect(subject).to render_template :show end end @@ -36,8 +38,8 @@ describe Settings::MigrationsController do let(:moved_to_account) { Fabricate(:account) } it 'renders show page' do - is_expected.to have_http_status 200 - is_expected.to render_template :show + expect(subject).to have_http_status 200 + expect(subject).to render_template :show end end end @@ -61,7 +63,7 @@ describe Settings::MigrationsController do let(:acct) { Fabricate(:account, also_known_as: [ActivityPub::TagManager.instance.uri_for(user.account)]) } it 'updates moved to account' do - is_expected.to redirect_to settings_migration_path + expect(subject).to redirect_to settings_migration_path expect(user.account.reload.moved_to_account_id).to eq acct.id end end @@ -70,7 +72,7 @@ describe Settings::MigrationsController do let(:acct) { user.account } it 'renders show' do - is_expected.to render_template :show + expect(subject).to render_template :show end it 'does not update the moved account' do @@ -82,7 +84,7 @@ describe Settings::MigrationsController do let(:acct) { Fabricate(:account, also_known_as: []) } it 'renders show' do - is_expected.to render_template :show + expect(subject).to render_template :show end it 'does not update the moved account' do @@ -90,7 +92,7 @@ describe Settings::MigrationsController do end end - context 'when a recent migration already exists ' do + context 'when a recent migration already exists' do let(:acct) { Fabricate(:account, also_known_as: [ActivityPub::TagManager.instance.uri_for(user.account)]) } before do @@ -99,7 +101,7 @@ describe Settings::MigrationsController do end it 'renders show' do - is_expected.to render_template :show + expect(subject).to render_template :show end it 'does not update the moved account' do diff --git a/spec/controllers/settings/pictures_controller_spec.rb b/spec/controllers/settings/pictures_controller_spec.rb new file mode 100644 index 0000000000..705878f03d --- /dev/null +++ b/spec/controllers/settings/pictures_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::PicturesController do + render_views + + let!(:user) { Fabricate(:user) } + + before do + sign_in user, scope: :user + end + + describe 'DELETE #destroy' do + context 'with invalid picture id' do + it 'returns http bad request' do + delete :destroy, params: { id: 'invalid' } + expect(response).to have_http_status(400) + end + end + + context 'with valid picture id' do + context 'when account updates correctly' do + let(:service) { instance_double(UpdateAccountService, call: true) } + + before do + allow(UpdateAccountService).to receive(:new).and_return(service) + end + + it 'updates the account' do + delete :destroy, params: { id: 'avatar' } + expect(response).to redirect_to(settings_profile_path) + expect(response).to have_http_status(303) + expect(service).to have_received(:call).with(user.account, { 'avatar' => nil, 'avatar_remote_url' => '' }) + end + end + + context 'when account cannot update' do + let(:service) { instance_double(UpdateAccountService, call: false) } + + before do + allow(UpdateAccountService).to receive(:new).and_return(service) + end + + it 'redirects to profile' do + delete :destroy, params: { id: 'avatar' } + expect(response).to redirect_to(settings_profile_path) + end + end + end + end +end diff --git a/spec/controllers/settings/preferences/appearance_controller_spec.rb b/spec/controllers/settings/preferences/appearance_controller_spec.rb new file mode 100644 index 0000000000..9a98a41886 --- /dev/null +++ b/spec/controllers/settings/preferences/appearance_controller_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::Preferences::AppearanceController do + render_views + + let!(:user) { Fabricate(:user) } + + before do + sign_in user, scope: :user + end + + describe 'GET #show' do + before do + get :show + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + + describe 'PUT #update' do + it 'redirects correctly' do + put :update, params: { user: { setting_theme: 'contrast' } } + + expect(response).to redirect_to(settings_preferences_appearance_path) + end + + it 'renders show on failure' do + put :update, params: { user: { locale: 'fake option' } } + + expect(response).to render_template('preferences/appearance/show') + end + end +end diff --git a/spec/controllers/settings/preferences/base_controller_spec.rb b/spec/controllers/settings/preferences/base_controller_spec.rb new file mode 100644 index 0000000000..53b3a461ed --- /dev/null +++ b/spec/controllers/settings/preferences/base_controller_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Settings::Preferences::BaseController do + describe 'after_update_redirect_path' do + it 'raises error when called' do + expect { described_class.new.send(:after_update_redirect_path) }.to raise_error(/Override/) + end + end +end diff --git a/spec/controllers/settings/preferences/notifications_controller_spec.rb b/spec/controllers/settings/preferences/notifications_controller_spec.rb index 02180b3832..6a04df9edb 100644 --- a/spec/controllers/settings/preferences/notifications_controller_spec.rb +++ b/spec/controllers/settings/preferences/notifications_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::Preferences::NotificationsController do @@ -10,28 +12,37 @@ describe Settings::Preferences::NotificationsController do end describe 'GET #show' do - it 'returns http success' do + before do get :show + end + + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end describe 'PUT #update' do it 'updates notifications settings' do - user.settings['notification_emails'] = user.settings['notification_emails'].merge('follow' => false) - user.settings['interactions'] = user.settings['interactions'].merge('must_be_follower' => true) + user.settings.update('notification_emails.follow': false, 'interactions.must_be_follower': true) + user.save put :update, params: { user: { - notification_emails: { follow: '1' }, - interactions: { must_be_follower: '0' }, - } + settings_attributes: { + 'notification_emails.follow': '1', + 'interactions.must_be_follower': '0', + }, + }, } expect(response).to redirect_to(settings_preferences_notifications_path) user.reload - expect(user.settings['notification_emails']['follow']).to be true - expect(user.settings['interactions']['must_be_follower']).to be false + expect(user.settings['notification_emails.follow']).to be true + expect(user.settings['interactions.must_be_follower']).to be false end end end diff --git a/spec/controllers/settings/preferences/other_controller_spec.rb b/spec/controllers/settings/preferences/other_controller_spec.rb index 960378a018..750510b04b 100644 --- a/spec/controllers/settings/preferences/other_controller_spec.rb +++ b/spec/controllers/settings/preferences/other_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::Preferences::OtherController do @@ -10,10 +12,17 @@ describe Settings::Preferences::OtherController do end describe 'GET #show' do - it 'returns http success' do + before do get :show + end + + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end describe 'PUT #update' do @@ -23,24 +32,26 @@ describe Settings::Preferences::OtherController do expect(response).to redirect_to(settings_preferences_other_path) user.reload expect(user.locale).to eq 'en' - expect(user.chosen_languages).to eq ['es', 'fr'] + expect(user.chosen_languages).to eq %w(es fr) end it 'updates user settings' do - user.settings['boost_modal'] = false - user.settings['delete_modal'] = true + user.settings.update('web.reblog_modal': false, 'web.delete_modal': true) + user.save put :update, params: { user: { - setting_boost_modal: '1', - setting_delete_modal: '0', - } + settings_attributes: { + 'web.reblog_modal': '1', + 'web.delete_modal': '0', + }, + }, } expect(response).to redirect_to(settings_preferences_other_path) user.reload - expect(user.settings['boost_modal']).to be true - expect(user.settings['delete_modal']).to be false + expect(user.settings['web.reblog_modal']).to be true + expect(user.settings['web.delete_modal']).to be false end end end diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb index ee3aec8156..806fad19a8 100644 --- a/spec/controllers/settings/profiles_controller_spec.rb +++ b/spec/controllers/settings/profiles_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Settings::ProfilesController, type: :controller do +RSpec.describe Settings::ProfilesController do render_views let!(:user) { Fabricate(:user) } @@ -10,11 +12,18 @@ RSpec.describe Settings::ProfilesController, type: :controller do sign_in user, scope: :user end - describe "GET #show" do - it "returns http success" do + describe 'GET #show' do + before do get :show + end + + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end describe 'PUT #update' do @@ -38,16 +47,8 @@ RSpec.describe Settings::ProfilesController, type: :controller do put :update, params: { account: { avatar: fixture_file_upload('avatar.gif', 'image/gif') } } expect(response).to redirect_to(settings_profile_path) - expect(account.reload.avatar.instance.avatar_file_name).not_to be_nil + expect(account.reload.avatar.instance.avatar_file_name).to_not be_nil expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id) end end - - describe 'PUT #update with oversized image' do - it 'gives the user an error message' do - allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) - put :update, params: { account: { avatar: fixture_file_upload('4096x4097.png', 'image/png') } } - expect(response.body).to include('images are not supported') - end - end end diff --git a/spec/controllers/settings/sessions_controller_spec.rb b/spec/controllers/settings/sessions_controller_spec.rb index 52b204a6a3..a4248e1bde 100644 --- a/spec/controllers/settings/sessions_controller_spec.rb +++ b/spec/controllers/settings/sessions_controller_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Settings::SessionsController do @@ -5,6 +7,7 @@ describe Settings::SessionsController do let(:user) { Fabricate(:user) } let(:session_activation) { Fabricate(:session_activation, user: user) } + before { sign_in user, scope: :user } describe 'DELETE #destroy' do @@ -14,7 +17,7 @@ describe Settings::SessionsController do let(:id) { session_activation.id } it 'destroys session activation' do - is_expected.to redirect_to edit_user_registration_path + expect(subject).to redirect_to edit_user_registration_path expect(SessionActivation.find_by(id: id)).to be_nil end end @@ -23,7 +26,7 @@ describe Settings::SessionsController do let(:id) { session_activation.id + 1000 } it 'destroys session activation' do - is_expected.to have_http_status :not_found + expect(subject).to have_http_status 404 end end end diff --git a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb index 569c8322bd..37381fe1f7 100644 --- a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb @@ -5,7 +5,6 @@ require 'rails_helper' describe Settings::TwoFactorAuthentication::ConfirmationsController do render_views - shared_examples 'renders :new' do it 'renders the new view' do subject @@ -57,18 +56,11 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do end describe 'when creation succeeds' do + let!(:otp_backup_codes) { user.generate_otp_backup_codes! } + it 'renders page with success' do - otp_backup_codes = user.generate_otp_backup_codes! - expect_any_instance_of(User).to receive(:generate_otp_backup_codes!) do |value| - expect(value).to eq user - otp_backup_codes - end - expect_any_instance_of(User).to receive(:validate_and_consume_otp!) do |value, code, options| - expect(value).to eq user - expect(code).to eq '123456' - expect(options).to eq({ otp_secret: 'thisisasecretforthespecofnewview' }) - true - end + prepare_user_otp_generation + prepare_user_otp_consumption expect do post :create, @@ -81,6 +73,22 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do expect(response).to have_http_status(200) expect(response).to render_template('settings/two_factor_authentication/recovery_codes/index') end + + def prepare_user_otp_generation + expect_any_instance_of(User).to receive(:generate_otp_backup_codes!) do |value| + expect(value).to eq user + otp_backup_codes + end + end + + def prepare_user_otp_consumption + expect_any_instance_of(User).to receive(:validate_and_consume_otp!) do |value, code, options| + expect(value).to eq user + expect(code).to eq '123456' + expect(options).to eq({ otp_secret: 'thisisasecretforthespecofnewview' }) + true + end + end end describe 'when creation fails' do @@ -96,7 +104,7 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do post :create, params: { form_two_factor_confirmation: { otp_attempt: '123456' } }, session: { challenge_passed_at: Time.now.utc, new_otp_secret: 'thisisasecretforthespecofnewview' } - end.to not_change { user.reload.otp_secret } + end.to(not_change { user.reload.otp_secret }) end it 'renders the new view' do diff --git a/spec/controllers/settings/two_factor_authentication/otp_authentication_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/otp_authentication_controller_spec.rb index c8ba6f9a88..007df87d95 100644 --- a/spec/controllers/settings/two_factor_authentication/otp_authentication_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/otp_authentication_controller_spec.rb @@ -63,7 +63,7 @@ describe Settings::TwoFactorAuthentication::OtpAuthenticationController do expect do post :create, session: { challenge_passed_at: Time.now.utc } end.to not_change { user.reload.otp_secret } - .and change { session[:new_otp_secret] } + .and(change { session[:new_otp_secret] }) expect(response).to redirect_to(new_settings_two_factor_authentication_confirmation_path) end @@ -80,7 +80,7 @@ describe Settings::TwoFactorAuthentication::OtpAuthenticationController do expect do post :create, session: { challenge_passed_at: Time.now.utc } end.to not_change { user.reload.otp_secret } - .and change { session[:new_otp_secret] } + .and(change { session[:new_otp_secret] }) expect(response).to redirect_to(new_settings_two_factor_authentication_confirmation_path) end diff --git a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb index 269c4d685a..fe4868956c 100644 --- a/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb @@ -7,7 +7,7 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do render_views let(:user) { Fabricate(:user) } - let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" } + let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" } let(:fake_client) { WebAuthn::FakeClient.new(domain) } def add_webauthn_credential(user) @@ -134,13 +134,13 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do end it 'does not change webauthn_id' do - expect { get :options }.to_not change { user.webauthn_id } + expect { get :options }.to_not change(user, :webauthn_id) end - it "includes existing credentials in list of excluded credentials" do + it 'includes existing credentials in list of excluded credentials' do get :options - excluded_credentials_ids = JSON.parse(response.body)['excludeCredentials'].map { |credential| credential['id'] } + excluded_credentials_ids = response.parsed_body['excludeCredentials'].pluck('id') expect(excluded_credentials_ids).to match_array(user.webauthn_credentials.pluck(:external_id)) end end @@ -238,7 +238,7 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do expect do post :create, params: { credential: new_webauthn_credential, nickname: nickname } - end.to_not change { user.webauthn_id } + end.to_not change(user, :webauthn_id) end end @@ -275,7 +275,7 @@ describe Settings::TwoFactorAuthentication::WebauthnCredentialsController do end context 'when user have not enabled webauthn' do - context 'creation succeeds' do + context 'when creation succeeds' do it 'creates a webauthn credential' do @controller.session[:webauthn_challenge] = challenge diff --git a/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb b/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb index 66ffe89f3d..3e61912ad4 100644 --- a/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication_methods_controller_spec.rb @@ -5,40 +5,8 @@ require 'rails_helper' describe Settings::TwoFactorAuthenticationMethodsController do render_views - let(:user) { Fabricate(:user) } - - describe 'GET #index' do - context 'when signed in' do - before do - sign_in user, scope: :user - end - - describe 'when user has enabled otp' do - before do - user.update(otp_required_for_login: true) - end - - it 'returns http success' do - get :index - - expect(response).to have_http_status(200) - end - end - - describe 'when user has not enabled otp' do - before do - user.update(otp_required_for_login: false) - end - - it 'redirects to enable otp' do - get :index - - expect(response).to redirect_to(settings_otp_authentication_path) - end - end - end - - context 'when not signed in' do + context 'when not signed in' do + describe 'GET to #index' do it 'redirects' do get :index @@ -46,4 +14,69 @@ describe Settings::TwoFactorAuthenticationMethodsController do end end end + + context 'when signed in' do + let(:user) { Fabricate(:user) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + describe 'when user has enabled otp' do + before do + user.update(otp_required_for_login: true) + get :index + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end + end + + describe 'when user has not enabled otp' do + before do + user.update(otp_required_for_login: false) + get :index + end + + it 'redirects to enable otp' do + expect(response).to redirect_to(settings_otp_authentication_path) + end + end + end + + describe 'POST to #disable' do + before do + user.update(otp_required_for_login: true) + end + + context 'when user has not passed challenge' do + it 'renders challenge page' do + post :disable + + expect(response).to have_http_status(200) + expect(response).to render_template('auth/challenges/new') + end + end + + context 'when user has passed challenge' do + before do + mailer = instance_double(ApplicationMailer::MessageDelivery, deliver_later!: true) + allow(UserMailer).to receive(:two_factor_disabled).with(user).and_return(mailer) + end + + it 'redirects to settings page' do + post :disable, session: { challenge_passed_at: 10.minutes.ago } + + expect(UserMailer).to have_received(:two_factor_disabled).with(user) + expect(response).to redirect_to(settings_otp_authentication_path) + end + end + end + end end diff --git a/spec/controllers/shares_controller_spec.rb b/spec/controllers/shares_controller_spec.rb index d6de3016ae..5dcc46e47a 100644 --- a/spec/controllers/shares_controller_spec.rb +++ b/spec/controllers/shares_controller_spec.rb @@ -1,18 +1,21 @@ +# frozen_string_literal: true + require 'rails_helper' describe SharesController do render_views let(:user) { Fabricate(:user) } + before { sign_in user } - describe 'GTE #show' do + describe 'GET #show' do subject(:body_classes) { assigns(:body_classes) } before { get :show, params: { title: 'test title', text: 'test text', url: 'url1 url2' } } it 'returns http success' do - expect(response).to have_http_status :ok + expect(response).to have_http_status 200 expect(body_classes).to eq 'modal-layout compose-standalone' end end diff --git a/spec/controllers/statuses_cleanup_controller_spec.rb b/spec/controllers/statuses_cleanup_controller_spec.rb index 9247092603..e082b69c51 100644 --- a/spec/controllers/statuses_cleanup_controller_spec.rb +++ b/spec/controllers/statuses_cleanup_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe StatusesCleanupController, type: :controller do +RSpec.describe StatusesCleanupController do render_views before do @@ -8,20 +10,33 @@ RSpec.describe StatusesCleanupController, type: :controller do sign_in @user, scope: :user end - describe "GET #show" do - it "returns http success" do + describe 'GET #show' do + before do get :show + end + + it 'returns http success' do expect(response).to have_http_status(200) end + + it 'returns private cache control headers' do + expect(response.headers['Cache-Control']).to include('private, no-store') + end end describe 'PUT #update' do - it 'updates the account status cleanup policy' do + before do put :update, params: { account_statuses_cleanup_policy: { enabled: true, min_status_age: 2.weeks.seconds, keep_direct: false, keep_polls: true } } + end + + it 'updates the account status cleanup policy' do + expect(@user.account.statuses_cleanup_policy.enabled).to be true + expect(@user.account.statuses_cleanup_policy.keep_direct).to be false + expect(@user.account.statuses_cleanup_policy.keep_polls).to be true + end + + it 'redirects' do expect(response).to redirect_to(statuses_cleanup_path) - expect(@user.account.statuses_cleanup_policy.enabled).to eq true - expect(@user.account.statuses_cleanup_policy.keep_direct).to eq false - expect(@user.account.statuses_cleanup_policy.keep_polls).to eq true end end end diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb index 6ed5d4bbb6..bd98929c02 100644 --- a/spec/controllers/statuses_controller_spec.rb +++ b/spec/controllers/statuses_controller_spec.rb @@ -8,13 +8,17 @@ describe StatusesController do shared_examples 'cacheable response' do it 'does not set cookies' do expect(response.cookies).to be_empty - expect(response.headers['Set-Cookies']).to be nil + expect(response.headers['Set-Cookies']).to be_nil end it 'does not set sessions' do expect(session).to be_empty end + it 'returns Vary header' do + expect(response.headers['Vary']).to include 'Accept, Accept-Language, Cookie' + end + it 'returns public Cache-Control header' do expect(response.headers['Cache-Control']).to include 'public' end @@ -68,53 +72,29 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns public Cache-Control header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Cache-Control']).to include 'public' - end - - it 'renders status' do expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns Link header' do - expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - it_behaves_like 'cacheable response' - it 'returns Content-Type header' do + it 'renders ActivityPub Note object successfully', :aggregate_failures do + expect(response).to have_http_status(200) + expect(response.headers['Link'].to_s).to include 'activity+json' + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -128,7 +108,7 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } it 'returns http not found' do @@ -136,7 +116,7 @@ describe StatusesController do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it 'returns http not found' do @@ -152,7 +132,7 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } it 'returns http not found' do @@ -160,7 +140,7 @@ describe StatusesController do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it 'returns http not found' do @@ -192,55 +172,28 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns no Cache-Control header' do - expect(response.headers).to_not include 'Cache-Control' - end - - it 'renders status' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do + it 'renders ActivityPub Note object successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns public Cache-Control header' do - expect(response.headers['Cache-Control']).to include 'public' - end - - it 'returns Content-Type header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -256,55 +209,28 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns no Cache-Control header' do - expect(response.headers).to_not include 'Cache-Control' - end - - it 'renders status' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do + it 'renders ActivityPub Note object successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns private Cache-Control header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Cache-Control']).to include 'private' - end - - it 'returns Content-Type header' do expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -316,7 +242,7 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } it 'returns http not found' do @@ -324,7 +250,7 @@ describe StatusesController do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it 'returns http not found' do @@ -343,55 +269,28 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns no Cache-Control header' do - expect(response.headers).to_not include 'Cache-Control' - end - - it 'renders status' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do + it 'renders ActivityPub Note object successfully' do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns private Cache-Control header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Cache-Control']).to include 'private' - end - - it 'returns Content-Type header' do expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -403,7 +302,7 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } it 'returns http not found' do @@ -411,7 +310,7 @@ describe StatusesController do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it 'returns http not found' do @@ -456,53 +355,29 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns no Cache-Control header' do - expect(response.headers).to_not include 'Cache-Control' - end - - it 'renders status' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do - expect(response).to have_http_status(200) - end - - it 'returns Link header' do - expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - it_behaves_like 'cacheable response' - it 'returns Content-Type header' do + it 'renders ActivityPub Note object successfully', :aggregate_failures do + expect(response).to have_http_status(200) + expect(response.headers['Link'].to_s).to include 'activity+json' + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -518,55 +393,28 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns no Cache-Control header' do - expect(response.headers).to_not include 'Cache-Control' - end - - it 'renders status' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do + it 'renders ActivityPub Note object successfully' do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns private Cache-Control header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Cache-Control']).to include 'private' - end - - it 'returns Content-Type header' do expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -578,7 +426,7 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } it 'returns http not found' do @@ -586,7 +434,7 @@ describe StatusesController do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it 'returns http not found' do @@ -605,55 +453,28 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns no Cache-Control header' do - expect(response.headers).to_not include 'Cache-Control' - end - - it 'renders status' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + expect(response.headers['Cache-Control']).to include 'private' expect(response).to render_template(:show) expect(response.body).to include status.text end end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } - it 'returns http success' do + it 'renders ActivityPub Note object', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns private Cache-Control header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Cache-Control']).to include 'private' - end - - it 'returns Content-Type header' do expect(response.headers['Content-Type']).to include 'application/activity+json' - end - - it 'renders ActivityPub Note object' do json = body_as_json expect(json[:content]).to include status.text end @@ -665,7 +486,7 @@ describe StatusesController do get :show, params: { account_username: status.account.username, id: status.id, format: format } end - context 'as JSON' do + context 'with JSON' do let(:format) { 'json' } it 'returns http not found' do @@ -673,7 +494,7 @@ describe StatusesController do end end - context 'as HTML' do + context 'with HTML' do let(:format) { 'html' } it 'returns http not found' do @@ -715,65 +536,180 @@ describe StatusesController do end context 'when status is public' do - pending + before do + status.update(visibility: :public) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end end context 'when status is private' do - pending + before do + status.update(visibility: :private) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http not_found' do + expect(response).to have_http_status(404) + end end context 'when status is direct' do - pending + before do + status.update(visibility: :direct) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http not_found' do + expect(response).to have_http_status(404) + end end context 'when signed-in' do + let(:user) { Fabricate(:user) } + + before do + sign_in(user) + end + context 'when status is public' do - pending + before do + status.update(visibility: :public) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end end context 'when status is private' do + before do + status.update(visibility: :private) + end + context 'when user is authorized to see it' do - pending + before do + user.account.follow!(account) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end end context 'when user is not authorized to see it' do - pending + before do + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http not_found' do + expect(response).to have_http_status(404) + end end end context 'when status is direct' do + before do + status.update(visibility: :direct) + end + context 'when user is authorized to see it' do - pending + before do + Fabricate(:mention, account: user.account, status: status) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end end context 'when user is not authorized to see it' do - pending + before do + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http not_found' do + expect(response).to have_http_status(404) + end end end end context 'with signature' do + let(:remote_account) { Fabricate(:account, domain: 'example.com') } + + before do + allow(controller).to receive(:signed_request_actor).and_return(remote_account) + end + context 'when status is public' do - pending + before do + status.update(visibility: :public) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end end context 'when status is private' do + before do + status.update(visibility: :private) + end + context 'when user is authorized to see it' do - pending + before do + remote_account.follow!(account) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end end context 'when user is not authorized to see it' do - pending + before do + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http not_found' do + expect(response).to have_http_status(404) + end end end context 'when status is direct' do + before do + status.update(visibility: :direct) + end + context 'when user is authorized to see it' do - pending + before do + Fabricate(:mention, account: remote_account, status: status) + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end end context 'when user is not authorized to see it' do - pending + before do + get :activity, params: { account_username: account.username, id: status.id } + end + + it 'returns http not_found' do + expect(response).to have_http_status(404) + end end end end @@ -814,23 +750,11 @@ describe StatusesController do get :embed, params: { account_username: status.account.username, id: status.id } end - it 'returns http success' do + it 'renders status successfully', :aggregate_failures do expect(response).to have_http_status(200) - end - - it 'returns Link header' do expect(response.headers['Link'].to_s).to include 'activity+json' - end - - it 'returns Vary header' do - expect(response.headers['Vary']).to eq 'Accept' - end - - it 'returns public Cache-Control header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' expect(response.headers['Cache-Control']).to include 'public' - end - - it 'renders status' do expect(response).to render_template(:embed) expect(response.body).to include status.text end diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb index 547bcfb395..d41e707d43 100644 --- a/spec/controllers/tags_controller_spec.rb +++ b/spec/controllers/tags_controller_spec.rb @@ -1,24 +1,55 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe TagsController, type: :controller do +RSpec.describe TagsController do render_views describe 'GET #show' do - let!(:tag) { Fabricate(:tag, name: 'test') } - let!(:local) { Fabricate(:status, tags: [tag], text: 'local #test') } - let!(:remote) { Fabricate(:status, tags: [tag], text: 'remote #test', account: Fabricate(:account, domain: 'remote')) } - let!(:late) { Fabricate(:status, tags: [tag], text: 'late #test') } + let(:format) { 'html' } + let(:tag) { Fabricate(:tag, name: 'test') } + let(:tag_name) { tag&.name } + + before do + get :show, params: { id: tag_name, format: format } + end context 'when tag exists' do - it 'returns http success' do - get :show, params: { id: 'test', max_id: late.id } - expect(response).to have_http_status(200) + context 'when requested as HTML' do + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns Vary header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + end + + it 'returns public Cache-Control header' do + expect(response.headers['Cache-Control']).to include 'public' + end + end + + context 'when requested as JSON' do + let(:format) { 'json' } + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns Vary header' do + expect(response.headers['Vary']).to eq 'Accept, Accept-Language, Cookie' + end + + it 'returns public Cache-Control header' do + expect(response.headers['Cache-Control']).to include 'public' + end end end context 'when tag does not exist' do + let(:tag_name) { 'hoge' } + it 'returns http not found' do - get :show, params: { id: 'none' } expect(response).to have_http_status(404) end end diff --git a/spec/controllers/well_known/host_meta_controller_spec.rb b/spec/controllers/well_known/host_meta_controller_spec.rb index c02aa0d596..4bd161cd9d 100644 --- a/spec/controllers/well_known/host_meta_controller_spec.rb +++ b/spec/controllers/well_known/host_meta_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -describe WellKnown::HostMetaController, type: :controller do +describe WellKnown::HostMetaController do render_views describe 'GET #show' do @@ -9,12 +11,12 @@ describe WellKnown::HostMetaController, type: :controller do expect(response).to have_http_status(200) expect(response.media_type).to eq 'application/xrd+xml' - expect(response.body).to eq < - - - -XML + expect(response.body).to eq <<~XML + + + + + XML end end end diff --git a/spec/controllers/well_known/nodeinfo_controller_spec.rb b/spec/controllers/well_known/nodeinfo_controller_spec.rb index 36e85f20d1..6ec34afd04 100644 --- a/spec/controllers/well_known/nodeinfo_controller_spec.rb +++ b/spec/controllers/well_known/nodeinfo_controller_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -describe WellKnown::NodeInfoController, type: :controller do +describe WellKnown::NodeInfoController do render_views describe 'GET #index' do @@ -26,9 +28,10 @@ describe WellKnown::NodeInfoController, type: :controller do expect(response.media_type).to eq 'application/json' json = body_as_json + foo = { 'foo' => 0 } - expect({ "foo" => 0 }).not_to match_json_schema("nodeinfo_2.0") - expect(json).to match_json_schema("nodeinfo_2.0") + expect(foo).to_not match_json_schema('nodeinfo_2.0') + expect(json).to match_json_schema('nodeinfo_2.0') expect(json[:version]).to eq '2.0' expect(json[:usage]).to be_a Hash expect(json[:software]).to be_a Hash diff --git a/spec/controllers/well_known/webfinger_controller_spec.rb b/spec/controllers/well_known/webfinger_controller_spec.rb index 0e7b34f471..20770a7211 100644 --- a/spec/controllers/well_known/webfinger_controller_spec.rb +++ b/spec/controllers/well_known/webfinger_controller_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' -describe WellKnown::WebfingerController, type: :controller do +describe WellKnown::WebfingerController do + include RoutingHelper + render_views describe 'GET #show' do @@ -165,5 +169,67 @@ describe WellKnown::WebfingerController, type: :controller do expect(response).to have_http_status(400) end end + + context 'when an account has an avatar' do + let(:alice) { Fabricate(:account, username: 'alice', avatar: attachment_fixture('attachment.jpg')) } + let(:resource) { alice.to_webfinger_s } + + it 'returns avatar in response' do + perform_show! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to_not be_nil + expect(avatar_link[:type]).to eq alice.avatar.content_type + expect(avatar_link[:href]).to eq full_asset_url(alice.avatar) + end + + context 'with limited federation mode' do + before do + allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) + end + + it 'does not return avatar in response' do + perform_show! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + + context 'when enabling DISALLOW_UNAUTHENTICATED_API_ACCESS' do + around do |example| + ClimateControl.modify DISALLOW_UNAUTHENTICATED_API_ACCESS: 'true' do + example.run + end + end + + it 'does not return avatar in response' do + perform_show! + + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + end + + context 'when an account does not have an avatar' do + let(:alice) { Fabricate(:account, username: 'alice', avatar: nil) } + let(:resource) { alice.to_webfinger_s } + + before do + perform_show! + end + + it 'does not return avatar in response' do + avatar_link = get_avatar_link(body_as_json) + expect(avatar_link).to be_nil + end + end + end + + private + + def get_avatar_link(json) + json[:links].find { |link| link[:rel] == 'http://webfinger.net/rel/avatar' } end end diff --git a/spec/fabrication/fabricators_spec.rb b/spec/fabrication/fabricators_spec.rb new file mode 100644 index 0000000000..53193378c8 --- /dev/null +++ b/spec/fabrication/fabricators_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rails_helper' + +Fabrication.manager.load_definitions if Fabrication.manager.empty? + +Fabrication.manager.schematics.map(&:first).each do |factory_name| + describe "The #{factory_name} factory" do + it 'is valid' do + factory = Fabricate(factory_name) + expect(factory).to be_valid + end + end +end diff --git a/spec/fabricators/access_grant_fabricator.rb b/spec/fabricators/access_grant_fabricator.rb index ae1945f2bb..adc2b8369d 100644 --- a/spec/fabricators/access_grant_fabricator.rb +++ b/spec/fabricators/access_grant_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator :access_grant, from: 'Doorkeeper::AccessGrant' do application resource_owner_id { Fabricate(:user).id } diff --git a/spec/fabricators/access_token_fabricator.rb b/spec/fabricators/access_token_fabricator.rb index 1856a8eb3b..508c328085 100644 --- a/spec/fabricators/access_token_fabricator.rb +++ b/spec/fabricators/access_token_fabricator.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + Fabricator :access_token, from: 'Doorkeeper::AccessToken' do end diff --git a/spec/fabricators/accessible_access_token_fabricator.rb b/spec/fabricators/accessible_access_token_fabricator.rb index 4b7e99b207..fb3d0889b1 100644 --- a/spec/fabricators/accessible_access_token_fabricator.rb +++ b/spec/fabricators/accessible_access_token_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator :accessible_access_token, from: :access_token do expires_in { nil } revoked_at { nil } diff --git a/spec/fabricators/account_alias_fabricator.rb b/spec/fabricators/account_alias_fabricator.rb deleted file mode 100644 index 94dde9bb8c..0000000000 --- a/spec/fabricators/account_alias_fabricator.rb +++ /dev/null @@ -1,5 +0,0 @@ -Fabricator(:account_alias) do - account - acct 'test@example.com' - uri 'https://example.com/users/test' -end diff --git a/spec/fabricators/account_deletion_request_fabricator.rb b/spec/fabricators/account_deletion_request_fabricator.rb deleted file mode 100644 index 08a82ba3c3..0000000000 --- a/spec/fabricators/account_deletion_request_fabricator.rb +++ /dev/null @@ -1,3 +0,0 @@ -Fabricator(:account_deletion_request) do - account -end diff --git a/spec/fabricators/account_domain_block_fabricator.rb b/spec/fabricators/account_domain_block_fabricator.rb index 2ad4b67a99..83df509da2 100644 --- a/spec/fabricators/account_domain_block_fabricator.rb +++ b/spec/fabricators/account_domain_block_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:account_domain_block) do - account + account { Fabricate.build(:account) } domain 'example.com' end diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb index 205706532e..534b8ae843 100644 --- a/spec/fabricators/account_fabricator.rb +++ b/spec/fabricators/account_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + keypair = OpenSSL::PKey::RSA.new(2048) public_key = keypair.public_key.to_pem private_key = keypair.to_pem @@ -11,5 +13,6 @@ Fabricator(:account) do suspended_at { |attrs| attrs[:suspended] ? Time.now.utc : nil } silenced_at { |attrs| attrs[:silenced] ? Time.now.utc : nil } user { |attrs| attrs[:domain].nil? ? Fabricate.build(:user, account: nil) : nil } + uri { |attrs| attrs[:domain].nil? ? '' : "https://#{attrs[:domain]}/users/#{attrs[:username]}" } discoverable true end diff --git a/spec/fabricators/account_migration_fabricator.rb b/spec/fabricators/account_migration_fabricator.rb index 2a8e747a81..ae6143a65c 100644 --- a/spec/fabricators/account_migration_fabricator.rb +++ b/spec/fabricators/account_migration_fabricator.rb @@ -1,6 +1,9 @@ +# frozen_string_literal: true + Fabricator(:account_migration) do account target_account { |attrs| Fabricate(:account, also_known_as: [ActivityPub::TagManager.instance.uri_for(attrs[:account])]) } acct { |attrs| attrs[:target_account].acct } followers_count 1234 + created_at { 60.days.ago } end diff --git a/spec/fabricators/account_moderation_note_fabricator.rb b/spec/fabricators/account_moderation_note_fabricator.rb index 9277af1655..05a687bf4e 100644 --- a/spec/fabricators/account_moderation_note_fabricator.rb +++ b/spec/fabricators/account_moderation_note_fabricator.rb @@ -1,4 +1,7 @@ +# frozen_string_literal: true + Fabricator(:account_moderation_note) do - content "MyText" - account nil + content 'MyText' + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } end diff --git a/spec/fabricators/account_note_fabricator.rb b/spec/fabricators/account_note_fabricator.rb index 1b061745a3..241362c144 100644 --- a/spec/fabricators/account_note_fabricator.rb +++ b/spec/fabricators/account_note_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:account_note) do - account - target_account { Fabricate(:account) } - comment "User note text" + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } + comment 'User note text' end diff --git a/spec/fabricators/account_pin_fabricator.rb b/spec/fabricators/account_pin_fabricator.rb index c0f8b8afbb..32a5f3bdb8 100644 --- a/spec/fabricators/account_pin_fabricator.rb +++ b/spec/fabricators/account_pin_fabricator.rb @@ -1,4 +1,7 @@ +# frozen_string_literal: true + Fabricator(:account_pin) do - account nil - target_account nil + account + target_account(fabricator: :account) + before_create { |account_pin, _| account_pin.account.follow!(account_pin.target_account) } end diff --git a/spec/fabricators/account_stat_fabricator.rb b/spec/fabricators/account_stat_fabricator.rb index 2b06b47909..20272fb22f 100644 --- a/spec/fabricators/account_stat_fabricator.rb +++ b/spec/fabricators/account_stat_fabricator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Fabricator(:account_stat) do - account nil - statuses_count "" - following_count "" - followers_count "" + account { Fabricate.build(:account) } + statuses_count '123' + following_count '456' + followers_count '789' end diff --git a/spec/fabricators/account_statuses_cleanup_policy_fabricator.rb b/spec/fabricators/account_statuses_cleanup_policy_fabricator.rb index 29cf1d1339..fcf7a53475 100644 --- a/spec/fabricators/account_statuses_cleanup_policy_fabricator.rb +++ b/spec/fabricators/account_statuses_cleanup_policy_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:account_statuses_cleanup_policy) do - account + account { Fabricate.build(:account) } end diff --git a/spec/fabricators/account_tag_stat_fabricator.rb b/spec/fabricators/account_tag_stat_fabricator.rb deleted file mode 100644 index 9edb550bec..0000000000 --- a/spec/fabricators/account_tag_stat_fabricator.rb +++ /dev/null @@ -1,3 +0,0 @@ -Fabricator(:account_tag_stat) do - accounts_count "" -end diff --git a/spec/fabricators/account_warning_fabricator.rb b/spec/fabricators/account_warning_fabricator.rb index 72fe835d9a..70005a927b 100644 --- a/spec/fabricators/account_warning_fabricator.rb +++ b/spec/fabricators/account_warning_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:account_warning) do - account + account { Fabricate.build(:account) } target_account(fabricator: :account) text { Faker::Lorem.paragraph } action 'suspend' diff --git a/spec/fabricators/account_warning_preset_fabricator.rb b/spec/fabricators/account_warning_preset_fabricator.rb index 6c0b87e7cd..c50e08bf4f 100644 --- a/spec/fabricators/account_warning_preset_fabricator.rb +++ b/spec/fabricators/account_warning_preset_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:account_warning_preset) do - text "MyText" + text { Faker::Lorem.paragraph } end diff --git a/spec/fabricators/admin_action_log_fabricator.rb b/spec/fabricators/admin_action_log_fabricator.rb index 2f44e953d9..3acedbffd3 100644 --- a/spec/fabricators/admin_action_log_fabricator.rb +++ b/spec/fabricators/admin_action_log_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator('Admin::ActionLog') do - account nil - action "MyString" + account { Fabricate.build(:account) } + action 'MyString' target nil end diff --git a/spec/fabricators/announcement_fabricator.rb b/spec/fabricators/announcement_fabricator.rb index 5a3871d901..5d77365875 100644 --- a/spec/fabricators/announcement_fabricator.rb +++ b/spec/fabricators/announcement_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:announcement) do text { Faker::Lorem.paragraph(sentence_count: 2) } published true diff --git a/spec/fabricators/announcement_mute_fabricator.rb b/spec/fabricators/announcement_mute_fabricator.rb deleted file mode 100644 index c4eafe8f4c..0000000000 --- a/spec/fabricators/announcement_mute_fabricator.rb +++ /dev/null @@ -1,4 +0,0 @@ -Fabricator(:announcement_mute) do - account - announcement -end diff --git a/spec/fabricators/announcement_reaction_fabricator.rb b/spec/fabricators/announcement_reaction_fabricator.rb deleted file mode 100644 index f923c59c60..0000000000 --- a/spec/fabricators/announcement_reaction_fabricator.rb +++ /dev/null @@ -1,5 +0,0 @@ -Fabricator(:announcement_reaction) do - account - announcement - name '🌿' -end diff --git a/spec/fabricators/appeal_fabricator.rb b/spec/fabricators/appeal_fabricator.rb index 339363822d..039086c4e5 100644 --- a/spec/fabricators/appeal_fabricator.rb +++ b/spec/fabricators/appeal_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:appeal) do strike(fabricator: :account_warning) account { |attrs| attrs[:strike].target_account } diff --git a/spec/fabricators/application_fabricator.rb b/spec/fabricators/application_fabricator.rb index 42b7009dc2..272821304c 100644 --- a/spec/fabricators/application_fabricator.rb +++ b/spec/fabricators/application_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:application, from: Doorkeeper::Application) do name 'Example' website 'http://example.com' diff --git a/spec/fabricators/backup_fabricator.rb b/spec/fabricators/backup_fabricator.rb index 99a5bdcda1..58e37c9875 100644 --- a/spec/fabricators/backup_fabricator.rb +++ b/spec/fabricators/backup_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:backup) do - user + user { Fabricate.build(:user) } end diff --git a/spec/fabricators/block_fabricator.rb b/spec/fabricators/block_fabricator.rb index 379931ba65..c4087e46d2 100644 --- a/spec/fabricators/block_fabricator.rb +++ b/spec/fabricators/block_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:block) do - account - target_account { Fabricate(:account) } + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } end diff --git a/spec/fabricators/bookmark_fabricator.rb b/spec/fabricators/bookmark_fabricator.rb index 12cbc5bfa4..994ac6e687 100644 --- a/spec/fabricators/bookmark_fabricator.rb +++ b/spec/fabricators/bookmark_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:bookmark) do - account - status + account { Fabricate.build(:account) } + status { Fabricate.build(:status) } end diff --git a/spec/fabricators/bulk_import_fabricator.rb b/spec/fabricators/bulk_import_fabricator.rb new file mode 100644 index 0000000000..d30758dfe0 --- /dev/null +++ b/spec/fabricators/bulk_import_fabricator.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +Fabricator(:bulk_import) do + type 1 + state 1 + total_items 1 + processed_items 1 + imported_items 1 + finished_at '2022-11-18 14:55:07' + overwrite false + account { Fabricate.build(:account) } +end diff --git a/spec/fabricators/bulk_import_row_fabricator.rb b/spec/fabricators/bulk_import_row_fabricator.rb new file mode 100644 index 0000000000..10a4bf1608 --- /dev/null +++ b/spec/fabricators/bulk_import_row_fabricator.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +Fabricator(:bulk_import_row) do + bulk_import { Fabricate.build(:bulk_import) } + data '' +end diff --git a/spec/fabricators/canonical_email_block_fabricator.rb b/spec/fabricators/canonical_email_block_fabricator.rb index a0b6e0d221..1ef53ff4a4 100644 --- a/spec/fabricators/canonical_email_block_fabricator.rb +++ b/spec/fabricators/canonical_email_block_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:canonical_email_block) do - email "test@example.com" - reference_account { Fabricate(:account) } + email { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } } + reference_account { Fabricate.build(:account) } end diff --git a/spec/fabricators/conversation_account_fabricator.rb b/spec/fabricators/conversation_account_fabricator.rb deleted file mode 100644 index f57ffd5359..0000000000 --- a/spec/fabricators/conversation_account_fabricator.rb +++ /dev/null @@ -1,6 +0,0 @@ -Fabricator(:conversation_account) do - account nil - conversation nil - participant_account_ids "" - last_status nil -end diff --git a/spec/fabricators/conversation_fabricator.rb b/spec/fabricators/conversation_fabricator.rb index b4fadb46b8..07c6780bf9 100644 --- a/spec/fabricators/conversation_fabricator.rb +++ b/spec/fabricators/conversation_fabricator.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + Fabricator(:conversation) do end diff --git a/spec/fabricators/conversation_mute_fabricator.rb b/spec/fabricators/conversation_mute_fabricator.rb deleted file mode 100644 index 84f131c261..0000000000 --- a/spec/fabricators/conversation_mute_fabricator.rb +++ /dev/null @@ -1,2 +0,0 @@ -Fabricator(:conversation_mute) do -end diff --git a/spec/fabricators/custom_emoji_category_fabricator.rb b/spec/fabricators/custom_emoji_category_fabricator.rb deleted file mode 100644 index f593b95ed4..0000000000 --- a/spec/fabricators/custom_emoji_category_fabricator.rb +++ /dev/null @@ -1,3 +0,0 @@ -Fabricator(:custom_emoji_category) do - name "MyString" -end diff --git a/spec/fabricators/custom_emoji_fabricator.rb b/spec/fabricators/custom_emoji_fabricator.rb index 18a7d23dc4..fa570eec60 100644 --- a/spec/fabricators/custom_emoji_fabricator.rb +++ b/spec/fabricators/custom_emoji_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:custom_emoji) do shortcode 'coolcat' domain nil - image { File.open(Rails.root.join('spec', 'fixtures', 'files', 'emojo.png')) } + image { Rails.root.join('spec', 'fixtures', 'files', 'emojo.png').open } end diff --git a/spec/fabricators/custom_filter_fabricator.rb b/spec/fabricators/custom_filter_fabricator.rb index 64297a7e30..766cc3b115 100644 --- a/spec/fabricators/custom_filter_fabricator.rb +++ b/spec/fabricators/custom_filter_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:custom_filter) do - account + account { Fabricate.build(:account) } expires_at nil phrase 'discourse' context %w(home notifications) diff --git a/spec/fabricators/custom_filter_keyword_fabricator.rb b/spec/fabricators/custom_filter_keyword_fabricator.rb index 0f101dcd1a..aa4bf84739 100644 --- a/spec/fabricators/custom_filter_keyword_fabricator.rb +++ b/spec/fabricators/custom_filter_keyword_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:custom_filter_keyword) do - custom_filter - keyword 'discourse' + custom_filter { Fabricate.build(:custom_filter) } + keyword 'discourse' end diff --git a/spec/fabricators/custom_filter_status_fabricator.rb b/spec/fabricators/custom_filter_status_fabricator.rb index d082b81c5e..f66f62e561 100644 --- a/spec/fabricators/custom_filter_status_fabricator.rb +++ b/spec/fabricators/custom_filter_status_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:custom_filter_status) do - custom_filter - status + custom_filter { Fabricate.build(:custom_filter) } + status { Fabricate.build(:status) } end diff --git a/spec/fabricators/device_fabricator.rb b/spec/fabricators/device_fabricator.rb index b15d8248fb..37a2e8977d 100644 --- a/spec/fabricators/device_fabricator.rb +++ b/spec/fabricators/device_fabricator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Fabricator(:device) do - access_token - account + access_token { Fabricate.build(:access_token) } + account { Fabricate.build(:account) } device_id { Faker::Number.number(digits: 5) } name { Faker::App.name } fingerprint_key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) } diff --git a/spec/fabricators/domain_allow_fabricator.rb b/spec/fabricators/domain_allow_fabricator.rb index 6226b1e20b..12fdaaea1a 100644 --- a/spec/fabricators/domain_allow_fabricator.rb +++ b/spec/fabricators/domain_allow_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:domain_allow) do - domain "MyString" + domain { sequence(:domain) { |i| "example#{i}.com" } } end diff --git a/spec/fabricators/domain_block_fabricator.rb b/spec/fabricators/domain_block_fabricator.rb index cc1f928e58..c703a18e92 100644 --- a/spec/fabricators/domain_block_fabricator.rb +++ b/spec/fabricators/domain_block_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:domain_block) do domain { sequence(:domain) { |i| "#{i}#{Faker::Internet.domain_name}" } } end diff --git a/spec/fabricators/email_domain_block_fabricator.rb b/spec/fabricators/email_domain_block_fabricator.rb index d18af6433c..a74cca73dd 100644 --- a/spec/fabricators/email_domain_block_fabricator.rb +++ b/spec/fabricators/email_domain_block_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:email_domain_block) do domain { sequence(:domain) { |i| "#{i}#{Faker::Internet.domain_name}" } } end diff --git a/spec/fabricators/encrypted_message_fabricator.rb b/spec/fabricators/encrypted_message_fabricator.rb index e65f663024..349b659c2f 100644 --- a/spec/fabricators/encrypted_message_fabricator.rb +++ b/spec/fabricators/encrypted_message_fabricator.rb @@ -1,8 +1,7 @@ +# frozen_string_literal: true + Fabricator(:encrypted_message) do - device - from_account - from_device_id { Faker::Number.number(digits: 5) } - type 0 - body "" - message_franking "" + device { Fabricate.build(:device) } + from_account { Fabricate.build(:account) } + from_device_id { Faker::Number.number(digits: 5) } end diff --git a/spec/fabricators/favourite_fabricator.rb b/spec/fabricators/favourite_fabricator.rb index 464ac8d71a..639416987e 100644 --- a/spec/fabricators/favourite_fabricator.rb +++ b/spec/fabricators/favourite_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:favourite) do - account - status + account { Fabricate.build(:account) } + status { Fabricate.build(:status) } end diff --git a/spec/fabricators/featured_tag_fabricator.rb b/spec/fabricators/featured_tag_fabricator.rb index 25cbdaac0b..0803dc43a7 100644 --- a/spec/fabricators/featured_tag_fabricator.rb +++ b/spec/fabricators/featured_tag_fabricator.rb @@ -1,6 +1,7 @@ +# frozen_string_literal: true + Fabricator(:featured_tag) do - account - tag - statuses_count 1_337 - last_status_at Time.now.utc + account { Fabricate.build(:account) } + tag { Fabricate.build(:tag) } + name { sequence(:name) { |i| "Tag#{i}" } } end diff --git a/spec/fabricators/follow_fabricator.rb b/spec/fabricators/follow_fabricator.rb index 9b25dc547b..29886b4301 100644 --- a/spec/fabricators/follow_fabricator.rb +++ b/spec/fabricators/follow_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:follow) do - account - target_account { Fabricate(:account) } + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } end diff --git a/spec/fabricators/follow_recommendation_suppression_fabricator.rb b/spec/fabricators/follow_recommendation_suppression_fabricator.rb deleted file mode 100644 index 4a6a07a66c..0000000000 --- a/spec/fabricators/follow_recommendation_suppression_fabricator.rb +++ /dev/null @@ -1,3 +0,0 @@ -Fabricator(:follow_recommendation_suppression) do - account -end diff --git a/spec/fabricators/follow_request_fabricator.rb b/spec/fabricators/follow_request_fabricator.rb index c00ddf84d9..6b2d658a37 100644 --- a/spec/fabricators/follow_request_fabricator.rb +++ b/spec/fabricators/follow_request_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:follow_request) do - account - target_account { Fabricate(:account, locked: true) } + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account, locked: true) } end diff --git a/spec/fabricators/identity_fabricator.rb b/spec/fabricators/identity_fabricator.rb index bc832df9f7..83655ee839 100644 --- a/spec/fabricators/identity_fabricator.rb +++ b/spec/fabricators/identity_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:identity) do - user nil - provider "MyString" - uid "MyString" + user { Fabricate.build(:user) } + provider 'MyString' + uid 'MyString' end diff --git a/spec/fabricators/import_fabricator.rb b/spec/fabricators/import_fabricator.rb deleted file mode 100644 index e2eb1e0dfb..0000000000 --- a/spec/fabricators/import_fabricator.rb +++ /dev/null @@ -1,2 +0,0 @@ -Fabricator(:import) do -end diff --git a/spec/fabricators/invite_fabricator.rb b/spec/fabricators/invite_fabricator.rb index 62b9b3904a..8fdf5f9185 100644 --- a/spec/fabricators/invite_fabricator.rb +++ b/spec/fabricators/invite_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:invite) do - user + user { Fabricate.build(:user) } expires_at nil max_uses nil uses 0 diff --git a/spec/fabricators/ip_block_fabricator.rb b/spec/fabricators/ip_block_fabricator.rb deleted file mode 100644 index 31dc336e64..0000000000 --- a/spec/fabricators/ip_block_fabricator.rb +++ /dev/null @@ -1,6 +0,0 @@ -Fabricator(:ip_block) do - ip "" - severity "" - expires_at "2020-10-08 22:20:37" - comment "MyText" -end \ No newline at end of file diff --git a/spec/fabricators/list_account_fabricator.rb b/spec/fabricators/list_account_fabricator.rb index 30e4004aa5..00dde83cdf 100644 --- a/spec/fabricators/list_account_fabricator.rb +++ b/spec/fabricators/list_account_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:list_account) do - list nil - account nil - follow nil + list + account + before_create { |list_account, _| list_account.list.account.follow!(account) } end diff --git a/spec/fabricators/list_fabricator.rb b/spec/fabricators/list_fabricator.rb index c3db690fa4..d2bdc10129 100644 --- a/spec/fabricators/list_fabricator.rb +++ b/spec/fabricators/list_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:list) do - account - title "MyString" + account { Fabricate.build(:account) } + title 'MyString' end diff --git a/spec/fabricators/login_activity_fabricator.rb b/spec/fabricators/login_activity_fabricator.rb index 686fd6483d..3309a303db 100644 --- a/spec/fabricators/login_activity_fabricator.rb +++ b/spec/fabricators/login_activity_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:login_activity) do - user + user { Fabricate.build(:user) } authentication_method 'password' success true failure_reason nil diff --git a/spec/fabricators/marker_fabricator.rb b/spec/fabricators/marker_fabricator.rb index 0c94150e0d..641db6b9ec 100644 --- a/spec/fabricators/marker_fabricator.rb +++ b/spec/fabricators/marker_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:marker) do - user + user { Fabricate.build(:user) } timeline 'home' last_read_id 0 lock_version 0 diff --git a/spec/fabricators/media_attachment_fabricator.rb b/spec/fabricators/media_attachment_fabricator.rb index 651927c2dd..062d3cbfec 100644 --- a/spec/fabricators/media_attachment_fabricator.rb +++ b/spec/fabricators/media_attachment_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:media_attachment) do - account + account { Fabricate.build(:account) } file do |attrs| case attrs[:type] diff --git a/spec/fabricators/mention_fabricator.rb b/spec/fabricators/mention_fabricator.rb index cb5fe4299a..ee8160aeb3 100644 --- a/spec/fabricators/mention_fabricator.rb +++ b/spec/fabricators/mention_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:mention) do - account - status + account { Fabricate.build(:account) } + status { Fabricate.build(:status) } end diff --git a/spec/fabricators/mute_fabricator.rb b/spec/fabricators/mute_fabricator.rb index 30d20e87e9..a70d3ff26d 100644 --- a/spec/fabricators/mute_fabricator.rb +++ b/spec/fabricators/mute_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:mute) do - account - target_account { Fabricate(:account) } + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } end diff --git a/spec/fabricators/notification_fabricator.rb b/spec/fabricators/notification_fabricator.rb index 638844e0fc..fdfd7673ef 100644 --- a/spec/fabricators/notification_fabricator.rb +++ b/spec/fabricators/notification_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:notification) do - activity fabricator: [:mention, :status, :follow, :follow_request, :favourite].sample - account + activity fabricator: :status + account { Fabricate.build(:account) } end diff --git a/spec/fabricators/one_time_key_fabricator.rb b/spec/fabricators/one_time_key_fabricator.rb index 8794baeb59..505282e05d 100644 --- a/spec/fabricators/one_time_key_fabricator.rb +++ b/spec/fabricators/one_time_key_fabricator.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + Fabricator(:one_time_key) do - device + device { Fabricate.build(:device) } key_id { Faker::Alphanumeric.alphanumeric(number: 10) } - key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) } + key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) } signature do |attrs| signing_key = Ed25519::SigningKey.generate diff --git a/spec/fabricators/poll_fabricator.rb b/spec/fabricators/poll_fabricator.rb index 746610f7c6..0203609ce7 100644 --- a/spec/fabricators/poll_fabricator.rb +++ b/spec/fabricators/poll_fabricator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Fabricator(:poll) do - account - status + account { Fabricate.build(:account) } + status { Fabricate.build(:status) } expires_at { 7.days.from_now } options %w(Foo Bar) multiple false diff --git a/spec/fabricators/poll_vote_fabricator.rb b/spec/fabricators/poll_vote_fabricator.rb index 51f9b006e6..47813cdb71 100644 --- a/spec/fabricators/poll_vote_fabricator.rb +++ b/spec/fabricators/poll_vote_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:poll_vote) do - account + account { Fabricate.build(:account) } poll - choice 0 + choice 0 end diff --git a/spec/fabricators/preview_card_fabricator.rb b/spec/fabricators/preview_card_fabricator.rb index 99b5edc435..b8f2c50972 100644 --- a/spec/fabricators/preview_card_fabricator.rb +++ b/spec/fabricators/preview_card_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:preview_card) do url { Faker::Internet.url } title { Faker::Lorem.sentence } diff --git a/spec/fabricators/preview_card_provider_fabricator.rb b/spec/fabricators/preview_card_provider_fabricator.rb new file mode 100644 index 0000000000..78db710003 --- /dev/null +++ b/spec/fabricators/preview_card_provider_fabricator.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Fabricator(:preview_card_provider) do + domain { Faker::Internet.domain_name } +end diff --git a/spec/fabricators/relay_fabricator.rb b/spec/fabricators/relay_fabricator.rb index 488913f772..ad8ba86fcf 100644 --- a/spec/fabricators/relay_fabricator.rb +++ b/spec/fabricators/relay_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:relay) do - inbox_url "https://example.com/inbox" + inbox_url 'https://example.com/inbox' state :idle end diff --git a/spec/fabricators/report_fabricator.rb b/spec/fabricators/report_fabricator.rb index 2c7101e094..ed890230a7 100644 --- a/spec/fabricators/report_fabricator.rb +++ b/spec/fabricators/report_fabricator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Fabricator(:report) do - account - target_account { Fabricate(:account) } - comment "You nasty" + account { Fabricate.build(:account) } + target_account { Fabricate.build(:account) } + comment 'You nasty' action_taken_at nil end diff --git a/spec/fabricators/report_note_fabricator.rb b/spec/fabricators/report_note_fabricator.rb index e139efffbc..080fad51ac 100644 --- a/spec/fabricators/report_note_fabricator.rb +++ b/spec/fabricators/report_note_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:report_note) do - report - account { Fabricate(:account) } - content "Test Content" + report { Fabricate.build(:report) } + account { Fabricate.build(:account) } + content 'Test Content' end diff --git a/spec/fabricators/rule_fabricator.rb b/spec/fabricators/rule_fabricator.rb index bc29bc48e1..a29fd905a4 100644 --- a/spec/fabricators/rule_fabricator.rb +++ b/spec/fabricators/rule_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:rule) do priority 0 deleted_at nil diff --git a/spec/fabricators/scheduled_status_fabricator.rb b/spec/fabricators/scheduled_status_fabricator.rb index 52384d1378..eed275ab92 100644 --- a/spec/fabricators/scheduled_status_fabricator.rb +++ b/spec/fabricators/scheduled_status_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:scheduled_status) do - account + account { Fabricate.build(:account) } scheduled_at { 20.hours.from_now } end diff --git a/spec/fabricators/session_activation_fabricator.rb b/spec/fabricators/session_activation_fabricator.rb index 526faaec2b..4b5244cec6 100644 --- a/spec/fabricators/session_activation_fabricator.rb +++ b/spec/fabricators/session_activation_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:session_activation) do - user - session_id "MyString" + user { Fabricate.build(:user) } + session_id 'MyString' end diff --git a/spec/fabricators/setting_fabricator.rb b/spec/fabricators/setting_fabricator.rb index 336d7c3551..ce9a48e901 100644 --- a/spec/fabricators/setting_fabricator.rb +++ b/spec/fabricators/setting_fabricator.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true Fabricator(:setting) do + var 'var' end diff --git a/spec/fabricators/site_upload_fabricator.rb b/spec/fabricators/site_upload_fabricator.rb index 2efc57e280..87553ccb8a 100644 --- a/spec/fabricators/site_upload_fabricator.rb +++ b/spec/fabricators/site_upload_fabricator.rb @@ -1,3 +1,6 @@ +# frozen_string_literal: true + Fabricator(:site_upload) do - file { File.open(File.join(Rails.root, 'spec', 'fabricators', 'assets', 'utah_teapot.png')) } + file { Rails.root.join('spec', 'fabricators', 'assets', 'utah_teapot.png').open } + var 'thumbnail' end diff --git a/spec/fabricators/software_update_fabricator.rb b/spec/fabricators/software_update_fabricator.rb new file mode 100644 index 0000000000..622fff66e8 --- /dev/null +++ b/spec/fabricators/software_update_fabricator.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +Fabricator(:software_update) do + version '99.99.99' + urgent false + type 'patch' +end diff --git a/spec/fabricators/status_edit_fabricator.rb b/spec/fabricators/status_edit_fabricator.rb deleted file mode 100644 index 21b793747e..0000000000 --- a/spec/fabricators/status_edit_fabricator.rb +++ /dev/null @@ -1,7 +0,0 @@ -Fabricator(:status_edit) do - status nil - account nil - text "MyText" - spoiler_text "MyText" - media_attachments_changed false -end \ No newline at end of file diff --git a/spec/fabricators/status_fabricator.rb b/spec/fabricators/status_fabricator.rb index 04bbbcf4b0..32a2cbf6ac 100644 --- a/spec/fabricators/status_fabricator.rb +++ b/spec/fabricators/status_fabricator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Fabricator(:status) do - account - text "Lorem ipsum dolor sit amet" + account { Fabricate.build(:account) } + text 'Lorem ipsum dolor sit amet' after_build do |status| status.uri = Faker::Internet.device_token if !status.account.local? && status.uri.nil? diff --git a/spec/fabricators/status_pin_fabricator.rb b/spec/fabricators/status_pin_fabricator.rb index f1f1c05f38..ceaaa34a79 100644 --- a/spec/fabricators/status_pin_fabricator.rb +++ b/spec/fabricators/status_pin_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:status_pin) do - account - status { |attrs| Fabricate(:status, account: attrs[:account], visibility: :public) } + account { Fabricate.build(:account) } + status { |attrs| Fabricate.build(:status, account: attrs[:account], visibility: :public) } end diff --git a/spec/fabricators/status_stat_fabricator.rb b/spec/fabricators/status_stat_fabricator.rb index 9c67fd404a..715e6d4ab2 100644 --- a/spec/fabricators/status_stat_fabricator.rb +++ b/spec/fabricators/status_stat_fabricator.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + Fabricator(:status_stat) do - status_id nil - replies_count "" - reblogs_count "" - favourites_count "" + status + replies_count '123' + reblogs_count '456' + favourites_count '789' end diff --git a/spec/fabricators/system_key_fabricator.rb b/spec/fabricators/system_key_fabricator.rb index f808495e07..ef6cec9c40 100644 --- a/spec/fabricators/system_key_fabricator.rb +++ b/spec/fabricators/system_key_fabricator.rb @@ -1,3 +1,4 @@ -Fabricator(:system_key) do +# frozen_string_literal: true +Fabricator(:system_key) do end diff --git a/spec/fabricators/tag_fabricator.rb b/spec/fabricators/tag_fabricator.rb index 33d57c9281..a7b52e9671 100644 --- a/spec/fabricators/tag_fabricator.rb +++ b/spec/fabricators/tag_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:tag) do name { sequence(:hashtag) { |i| "#{Faker::Lorem.word}#{i}" } } end diff --git a/spec/fabricators/tag_follow_fabricator.rb b/spec/fabricators/tag_follow_fabricator.rb index a2cccb07a8..014435d606 100644 --- a/spec/fabricators/tag_follow_fabricator.rb +++ b/spec/fabricators/tag_follow_fabricator.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + Fabricator(:tag_follow) do tag - account + account { Fabricate.build(:account) } end diff --git a/spec/fabricators/unavailable_domain_fabricator.rb b/spec/fabricators/unavailable_domain_fabricator.rb index f661b87c4a..cb9707020a 100644 --- a/spec/fabricators/unavailable_domain_fabricator.rb +++ b/spec/fabricators/unavailable_domain_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:unavailable_domain) do - domain { Faker::Internet.domain } + domain { Faker::Internet.domain_name } end diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb index 10ad2c53a3..9031d5cd04 100644 --- a/spec/fabricators/user_fabricator.rb +++ b/spec/fabricators/user_fabricator.rb @@ -1,7 +1,10 @@ +# frozen_string_literal: true + Fabricator(:user) do account { Fabricate.build(:account, user: nil) } email { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } } - password "123456789" + password '123456789' confirmed_at { Time.zone.now } - agreement true + current_sign_in_at { Time.zone.now } + agreement true end diff --git a/spec/fabricators/user_invite_request_fabricator.rb b/spec/fabricators/user_invite_request_fabricator.rb deleted file mode 100644 index 5cc6ae56fe..0000000000 --- a/spec/fabricators/user_invite_request_fabricator.rb +++ /dev/null @@ -1,4 +0,0 @@ -Fabricator(:user_invite_request) do - user - text { Faker::Lorem.sentence } -end diff --git a/spec/fabricators/user_role_fabricator.rb b/spec/fabricators/user_role_fabricator.rb index ed0a7dc1f3..d443227605 100644 --- a/spec/fabricators/user_role_fabricator.rb +++ b/spec/fabricators/user_role_fabricator.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + Fabricator(:user_role) do - name "MyString" - color "" + name 'MyString' + color '' permissions 0 end diff --git a/spec/fabricators/web_push_subscription_fabricator.rb b/spec/fabricators/web_push_subscription_fabricator.rb index 97f90675de..baffdbf83e 100644 --- a/spec/fabricators/web_push_subscription_fabricator.rb +++ b/spec/fabricators/web_push_subscription_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:web_push_subscription, from: Web::PushSubscription) do endpoint Faker::Internet.url key_p256dh Faker::Internet.password diff --git a/spec/fabricators/web_setting_fabricator.rb b/spec/fabricators/web_setting_fabricator.rb deleted file mode 100644 index 369b86bc18..0000000000 --- a/spec/fabricators/web_setting_fabricator.rb +++ /dev/null @@ -1,2 +0,0 @@ -Fabricator(:web_setting, from: Web::Setting) do -end diff --git a/spec/fabricators/webauthn_credential_fabricator.rb b/spec/fabricators/webauthn_credential_fabricator.rb index ba59ce9677..b578d55f00 100644 --- a/spec/fabricators/webauthn_credential_fabricator.rb +++ b/spec/fabricators/webauthn_credential_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:webauthn_credential) do user_id { Fabricate(:user).id } external_id { Base64.urlsafe_encode64(SecureRandom.random_bytes(16)) } diff --git a/spec/fabricators/webhook_fabricator.rb b/spec/fabricators/webhook_fabricator.rb index fa4f17b554..477e715efa 100644 --- a/spec/fabricators/webhook_fabricator.rb +++ b/spec/fabricators/webhook_fabricator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Fabricator(:webhook) do url { Faker::Internet.url } secret { SecureRandom.hex } diff --git a/spec/features/admin/domain_blocks_spec.rb b/spec/features/admin/domain_blocks_spec.rb new file mode 100644 index 0000000000..4672c1e1a9 --- /dev/null +++ b/spec/features/admin/domain_blocks_spec.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'blocking domains through the moderation interface' do + before do + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user + end + + context 'when silencing a new domain' do + it 'adds a new domain block' do + visit new_admin_domain_block_path + + fill_in 'domain_block_domain', with: 'example.com' + select I18n.t('admin.domain_blocks.new.severity.silence'), from: 'domain_block_severity' + click_on I18n.t('admin.domain_blocks.new.create') + + expect(DomainBlock.exists?(domain: 'example.com', severity: 'silence')).to be true + end + end + + context 'when suspending a new domain' do + it 'presents a confirmation screen before suspending the domain' do + visit new_admin_domain_block_path + + fill_in 'domain_block_domain', with: 'example.com' + select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' + click_on I18n.t('admin.domain_blocks.new.create') + + # It presents a confirmation screen + expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) + + # Confirming creates a block + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') + + expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be true + end + end + + context 'when suspending a domain that is already silenced' do + it 'presents a confirmation screen before suspending the domain' do + domain_block = Fabricate(:domain_block, domain: 'example.com', severity: 'silence') + + visit new_admin_domain_block_path + + fill_in 'domain_block_domain', with: 'example.com' + select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' + click_on I18n.t('admin.domain_blocks.new.create') + + # It presents a confirmation screen + expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) + + # Confirming updates the block + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') + + expect(domain_block.reload.severity).to eq 'suspend' + end + end + + context 'when suspending a subdomain of an already-silenced domain' do + it 'presents a confirmation screen before suspending the domain' do + domain_block = Fabricate(:domain_block, domain: 'example.com', severity: 'silence') + + visit new_admin_domain_block_path + + fill_in 'domain_block_domain', with: 'subdomain.example.com' + select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' + click_on I18n.t('admin.domain_blocks.new.create') + + # It presents a confirmation screen + expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'subdomain.example.com')) + + # Confirming creates the block + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') + + expect(DomainBlock.where(domain: 'subdomain.example.com', severity: 'suspend')).to exist + + # And leaves the previous block alone + expect(domain_block.reload.severity).to eq 'silence' + expect(domain_block.reload.domain).to eq 'example.com' + end + end + + context 'when editing a domain block' do + it 'presents a confirmation screen before suspending the domain' do + domain_block = Fabricate(:domain_block, domain: 'example.com', severity: 'silence') + + visit edit_admin_domain_block_path(domain_block) + + select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' + click_on I18n.t('generic.save_changes') + + # It presents a confirmation screen + expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) + + # Confirming updates the block + click_on I18n.t('admin.domain_blocks.confirm_suspension.confirm') + + expect(domain_block.reload.severity).to eq 'suspend' + end + end +end diff --git a/spec/features/admin/software_updates_spec.rb b/spec/features/admin/software_updates_spec.rb new file mode 100644 index 0000000000..4a635d1a79 --- /dev/null +++ b/spec/features/admin/software_updates_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'finding software updates through the admin interface' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'major', urgent: true, release_notes: 'https://github.com/mastodon/mastodon/releases/v99') + + sign_in Fabricate(:user, role: UserRole.find_by(name: 'Owner')), scope: :user + end + + it 'shows a link to the software updates page, which links to release notes' do + visit settings_profile_path + click_on I18n.t('admin.critical_update_pending') + + expect(page).to have_title(I18n.t('admin.software_updates.title')) + + expect(page).to have_content('99.99.99') + + click_on I18n.t('admin.software_updates.release_notes') + expect(page).to have_current_path('https://github.com/mastodon/mastodon/releases/v99', url: true) + end +end diff --git a/spec/features/captcha_spec.rb b/spec/features/captcha_spec.rb new file mode 100644 index 0000000000..db89ff3e61 --- /dev/null +++ b/spec/features/captcha_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'email confirmation flow when captcha is enabled' do + let(:user) { Fabricate(:user, confirmed_at: nil, confirmation_token: 'foobar', created_by_application: client_app) } + let(:client_app) { nil } + + before do + # rubocop:disable RSpec/AnyInstance -- easiest way to deal with that that I know of + allow_any_instance_of(Auth::ConfirmationsController).to receive(:captcha_enabled?).and_return(true) + allow_any_instance_of(Auth::ConfirmationsController).to receive(:check_captcha!).and_return(true) + allow_any_instance_of(Auth::ConfirmationsController).to receive(:render_captcha).and_return(nil) + # rubocop:enable RSpec/AnyInstance + end + + context 'when the user signed up through an app' do + let(:client_app) { Fabricate(:application) } + + it 'logs in' do + visit "/auth/confirmation?confirmation_token=#{user.confirmation_token}&redirect_to_app=true" + + # It presents the user with a captcha form + expect(page).to have_title(I18n.t('auth.captcha_confirmation.title')) + + # It does not confirm the user just yet + expect(user.reload.confirmed?).to be false + + # It redirects to app and confirms user + click_on I18n.t('challenge.confirm') + expect(user.reload.confirmed?).to be true + expect(page).to have_current_path(/\A#{client_app.confirmation_redirect_uri}/, url: true) + end + end +end diff --git a/spec/features/log_in_spec.rb b/spec/features/log_in_spec.rb index de1a6de031..c64e19d2b7 100644 --- a/spec/features/log_in_spec.rb +++ b/spec/features/log_in_spec.rb @@ -2,45 +2,45 @@ require 'rails_helper' -feature 'Log in' do +describe 'Log in' do include ProfileStories - given(:email) { "test@example.com" } - given(:password) { "password" } - given(:confirmed_at) { Time.zone.now } + subject { page } - background do + let(:email) { 'test@example.com' } + let(:password) { 'password' } + let(:confirmed_at) { Time.zone.now } + + before do as_a_registered_user visit new_user_session_path end - subject { page } - - scenario 'A valid email and password user is able to log in' do + it 'A valid email and password user is able to log in' do fill_in 'user_email', with: email fill_in 'user_password', with: password click_on I18n.t('auth.login') - is_expected.to have_css('div.app-holder') + expect(subject).to have_css('div.app-holder') end - scenario 'A invalid email and password user is not able to log in' do + it 'A invalid email and password user is not able to log in' do fill_in 'user_email', with: 'invalid_email' fill_in 'user_password', with: 'invalid_password' click_on I18n.t('auth.login') - is_expected.to have_css('.flash-message', text: failure_message('invalid')) + expect(subject).to have_css('.flash-message', text: failure_message('invalid')) end - context do - given(:confirmed_at) { nil } + context 'when confirmed at is nil' do + let(:confirmed_at) { nil } - scenario 'A unconfirmed user is able to log in' do + it 'A unconfirmed user is able to log in' do fill_in 'user_email', with: email fill_in 'user_password', with: password click_on I18n.t('auth.login') - is_expected.to have_css('div.admin-wrapper') + expect(subject).to have_css('div.admin-wrapper') end end diff --git a/spec/features/oauth_spec.rb b/spec/features/oauth_spec.rb new file mode 100644 index 0000000000..967956cc8e --- /dev/null +++ b/spec/features/oauth_spec.rb @@ -0,0 +1,190 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Using OAuth from an external app' do + let(:client_app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/', scopes: 'read') } + + context 'when the user is already logged in' do + let!(:user) { Fabricate(:user) } + + before do + sign_in user, scope: :user + end + + it 'when accepting the authorization request' do + params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } + visit "/oauth/authorize?#{params.to_query}" + + # It presents the user with an authorization page + expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) + + # Upon authorizing, it redirects to the apps' callback URL + click_on I18n.t('doorkeeper.authorizations.buttons.authorize') + expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + + # It grants the app access to the account + expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be true + end + + it 'when rejecting the authorization request' do + params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } + visit "/oauth/authorize?#{params.to_query}" + + # It presents the user with an authorization page + expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.deny')) + + # Upon denying, it redirects to the apps' callback URL + click_on I18n.t('doorkeeper.authorizations.buttons.deny') + expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + + # It does not grant the app access to the account + expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be false + end + end + + context 'when the user is not already logged in' do + let(:email) { 'test@example.com' } + let(:password) { 'testpassword' } + let(:user) { Fabricate(:user, email: email, password: password) } + + before do + user.confirm! + user.approve! + end + + it 'when accepting the authorization request' do + params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } + visit "/oauth/authorize?#{params.to_query}" + + # It presents the user with a log-in page + expect(page).to have_content(I18n.t('auth.login')) + + # Failing to log-in presents the form again + fill_in 'user_email', with: email + fill_in 'user_password', with: 'wrong password' + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('auth.login')) + + # Logging in redirects to an authorization page + fill_in 'user_email', with: email + fill_in 'user_password', with: password + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) + + # Upon authorizing, it redirects to the apps' callback URL + click_on I18n.t('doorkeeper.authorizations.buttons.authorize') + expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + + # It grants the app access to the account + expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be true + end + + it 'when rejecting the authorization request' do + params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } + visit "/oauth/authorize?#{params.to_query}" + + # It presents the user with a log-in page + expect(page).to have_content(I18n.t('auth.login')) + + # Failing to log-in presents the form again + fill_in 'user_email', with: email + fill_in 'user_password', with: 'wrong password' + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('auth.login')) + + # Logging in redirects to an authorization page + fill_in 'user_email', with: email + fill_in 'user_password', with: password + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) + + # Upon denying, it redirects to the apps' callback URL + click_on I18n.t('doorkeeper.authorizations.buttons.deny') + expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + + # It does not grant the app access to the account + expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be false + end + + context 'when the user has set up TOTP' do + let(:user) { Fabricate(:user, email: email, password: password, otp_required_for_login: true, otp_secret: User.generate_otp_secret(32)) } + + it 'when accepting the authorization request' do + params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } + visit "/oauth/authorize?#{params.to_query}" + + # It presents the user with a log-in page + expect(page).to have_content(I18n.t('auth.login')) + + # Failing to log-in presents the form again + fill_in 'user_email', with: email + fill_in 'user_password', with: 'wrong password' + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('auth.login')) + + # Logging in redirects to a two-factor authentication page + fill_in 'user_email', with: email + fill_in 'user_password', with: password + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) + + # Filling in an incorrect two-factor authentication code presents the form again + fill_in 'user_otp_attempt', with: 'wrong' + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) + + # Filling in the correct TOTP code redirects to an app authorization page + fill_in 'user_otp_attempt', with: user.current_otp + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) + + # Upon authorizing, it redirects to the apps' callback URL + click_on I18n.t('doorkeeper.authorizations.buttons.authorize') + expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + + # It grants the app access to the account + expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be true + end + + it 'when rejecting the authorization request' do + params = { client_id: client_app.uid, response_type: 'code', redirect_uri: client_app.redirect_uri, scope: 'read' } + visit "/oauth/authorize?#{params.to_query}" + + # It presents the user with a log-in page + expect(page).to have_content(I18n.t('auth.login')) + + # Failing to log-in presents the form again + fill_in 'user_email', with: email + fill_in 'user_password', with: 'wrong password' + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('auth.login')) + + # Logging in redirects to a two-factor authentication page + fill_in 'user_email', with: email + fill_in 'user_password', with: password + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) + + # Filling in an incorrect two-factor authentication code presents the form again + fill_in 'user_otp_attempt', with: 'wrong' + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('simple_form.hints.sessions.otp')) + + # Filling in the correct TOTP code redirects to an app authorization page + fill_in 'user_otp_attempt', with: user.current_otp + click_on I18n.t('auth.login') + expect(page).to have_content(I18n.t('doorkeeper.authorizations.buttons.authorize')) + + # Upon denying, it redirects to the apps' callback URL + click_on I18n.t('doorkeeper.authorizations.buttons.deny') + expect(page).to have_current_path(/\A#{client_app.redirect_uri}/, url: true) + + # It does not grant the app access to the account + expect(Doorkeeper::AccessGrant.exists?(application: client_app, resource_owner_id: user.id)).to be false + end + end + + # TODO: external auth + end +end diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index ec4f9a53fe..421b68a169 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -2,25 +2,25 @@ require 'rails_helper' -feature 'Profile' do +describe 'Profile' do include ProfileStories - given(:local_domain) { ENV['LOCAL_DOMAIN'] } + subject { page } - background do + let(:local_domain) { ENV['LOCAL_DOMAIN'] } + + before do as_a_logged_in_user with_alice_as_local_user end - subject { page } - - scenario 'I can view Annes public account' do + it 'I can view Annes public account' do visit account_path('alice') - is_expected.to have_title("alice (@alice@#{local_domain})") + expect(subject).to have_title("alice (@alice@#{local_domain})") end - scenario 'I can change my account' do + it 'I can change my account' do visit settings_profile_path fill_in 'Display name', with: 'Bob' @@ -28,6 +28,6 @@ feature 'Profile' do first('button[type=submit]').click - is_expected.to have_content 'Changes successfully saved!' + expect(subject).to have_content 'Changes successfully saved!' end end diff --git a/spec/fixtures/files/600x400.avif b/spec/fixtures/files/600x400.avif new file mode 100644 index 0000000000..f306942dbe Binary files /dev/null and b/spec/fixtures/files/600x400.avif differ diff --git a/spec/fixtures/files/600x400.heic b/spec/fixtures/files/600x400.heic new file mode 100644 index 0000000000..1add5832a8 Binary files /dev/null and b/spec/fixtures/files/600x400.heic differ diff --git a/spec/fixtures/files/600x400.jpeg b/spec/fixtures/files/600x400.jpeg new file mode 100644 index 0000000000..1c20bea515 Binary files /dev/null and b/spec/fixtures/files/600x400.jpeg differ diff --git a/spec/fixtures/files/600x400.png b/spec/fixtures/files/600x400.png new file mode 100644 index 0000000000..3b8a2dee35 Binary files /dev/null and b/spec/fixtures/files/600x400.png differ diff --git a/spec/fixtures/files/600x400.webp b/spec/fixtures/files/600x400.webp new file mode 100644 index 0000000000..56fa5151c2 Binary files /dev/null and b/spec/fixtures/files/600x400.webp differ diff --git a/spec/fixtures/files/attachment-jpg.123456_abcd b/spec/fixtures/files/attachment-jpg.123456_abcd new file mode 100644 index 0000000000..f1d40539ac Binary files /dev/null and b/spec/fixtures/files/attachment-jpg.123456_abcd differ diff --git a/spec/fixtures/files/attachment.gif b/spec/fixtures/files/attachment.gif index 2937f5abef..89dd73ad3e 100644 Binary files a/spec/fixtures/files/attachment.gif and b/spec/fixtures/files/attachment.gif differ diff --git a/spec/fixtures/files/attachment.webm b/spec/fixtures/files/attachment.webm index 3babe5cf59..edde443960 100644 Binary files a/spec/fixtures/files/attachment.webm and b/spec/fixtures/files/attachment.webm differ diff --git a/spec/fixtures/files/empty.csv b/spec/fixtures/files/empty.csv new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/fixtures/files/following_accounts.csv b/spec/fixtures/files/following_accounts.csv new file mode 100644 index 0000000000..c7917443f8 --- /dev/null +++ b/spec/fixtures/files/following_accounts.csv @@ -0,0 +1,5 @@ +Account address,Show boosts,Notify on new posts,Languages + +user@example.com,true,false, + +user@test.com,true,true,"en,fr" diff --git a/spec/fixtures/files/lists.csv b/spec/fixtures/files/lists.csv new file mode 100644 index 0000000000..3155ed6d57 --- /dev/null +++ b/spec/fixtures/files/lists.csv @@ -0,0 +1,3 @@ +Mastodon project,gargron@example.com +Mastodon project,mastodon@example.com +test,foo@example.com diff --git a/spec/fixtures/files/muted_accounts.csv b/spec/fixtures/files/muted_accounts.csv new file mode 100644 index 0000000000..66f4315bce --- /dev/null +++ b/spec/fixtures/files/muted_accounts.csv @@ -0,0 +1,5 @@ +Account address,Hide notifications + +user@example.com,true + +user@test.com,false diff --git a/spec/fixtures/requests/idn.txt b/spec/fixtures/requests/idn.txt deleted file mode 100644 index 5d07f2b796..0000000000 --- a/spec/fixtures/requests/idn.txt +++ /dev/null @@ -1,483 +0,0 @@ -HTTP/1.1 200 OK -Server: nginx -Date: Sun, 23 Apr 2017 19:37:13 GMT -Content-Type: text/html -Content-Length: 38111 -Last-Modified: Wed, 20 Jul 2016 02:50:52 GMT -Connection: keep-alive -Accept-Ranges: bytes - - - - - - - - - - - - - - - 中国域名网站 - - - -
- -
- - -
-
-

网址大全

- -
-
-
-
-
-

中文域名简介

-

- “中国域名”是中文域名的一种,特指以“中国”为后缀的中文域名,是我国域名体系和全球互联网域名体系的重要组成部分。“中国”是在全球互联网上代表中国的中文顶级域名,于2010年7月正式纳入全球互联网域名体系,全球互联网域名体系,全球网民可通过联网计算机在世界任何国家和地区实现无障碍访问。“中国”域名在使用上和 .CN,相似属于互联网上的基础服务,基于域名可以提供WWW.EMAIL FTP等应用服务。 -

-
- - - - diff --git a/spec/generators/post_deployment_migration_generator_spec.rb b/spec/generators/post_deployment_migration_generator_spec.rb new file mode 100644 index 0000000000..d552880e3b --- /dev/null +++ b/spec/generators/post_deployment_migration_generator_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'rails/generators/testing/behaviour' +require 'rails/generators/testing/assertions' + +require 'generators/post_deployment_migration/post_deployment_migration_generator' + +describe PostDeploymentMigrationGenerator, type: :generator do + include Rails::Generators::Testing::Behaviour + include Rails::Generators::Testing::Assertions + include FileUtils + + tests described_class + destination File.expand_path('../../tmp', __dir__) + before { prepare_destination } + after { rm_rf(destination_root) } + + describe 'the migration' do + it 'generates expected file' do + run_generator %w(Changes) + + assert_migration('db/post_migrate/changes.rb', /disable_ddl/) + assert_migration('db/post_migrate/changes.rb', /change/) + end + end +end diff --git a/spec/helpers/accounts_helper_spec.rb b/spec/helpers/accounts_helper_spec.rb index 2b35b23b79..2c949cde69 100644 --- a/spec/helpers/accounts_helper_spec.rb +++ b/spec/helpers/accounts_helper_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AccountsHelper, type: :helper do +RSpec.describe AccountsHelper do def set_not_embedded_view params[:controller] = "not_#{StatusesHelper::EMBEDDED_CONTROLLER}" params[:action] = "not_#{StatusesHelper::EMBEDDED_ACTION}" @@ -13,15 +15,15 @@ RSpec.describe AccountsHelper, type: :helper do describe '#display_name' do it 'uses the display name when it exists' do - account = Account.new(display_name: "Display", username: "Username") + account = Account.new(display_name: 'Display', username: 'Username') - expect(helper.display_name(account)).to eq "Display" + expect(helper.display_name(account)).to eq 'Display' end it 'uses the username when display name is nil' do - account = Account.new(display_name: nil, username: "Username") + account = Account.new(display_name: nil, username: 'Username') - expect(helper.display_name(account)).to eq "Username" + expect(helper.display_name(account)).to eq 'Username' end end diff --git a/spec/helpers/admin/account_moderation_notes_helper_spec.rb b/spec/helpers/admin/account_moderation_notes_helper_spec.rb index 622ce88065..6386f07ac9 100644 --- a/spec/helpers/admin/account_moderation_notes_helper_spec.rb +++ b/spec/helpers/admin/account_moderation_notes_helper_spec.rb @@ -2,11 +2,11 @@ require 'rails_helper' -RSpec.describe Admin::AccountModerationNotesHelper, type: :helper do +RSpec.describe Admin::AccountModerationNotesHelper do include AccountsHelper describe '#admin_account_link_to' do - context 'account is nil' do + context 'when Account is nil' do let(:account) { nil } it 'returns nil' do @@ -30,7 +30,7 @@ RSpec.describe Admin::AccountModerationNotesHelper, type: :helper do end describe '#admin_account_inline_link_to' do - context 'account is nil' do + context 'when Account is nil' do let(:account) { nil } it 'returns nil' do @@ -42,13 +42,11 @@ RSpec.describe Admin::AccountModerationNotesHelper, type: :helper do let(:account) { Fabricate(:account) } it 'calls #link_to' do - expect(helper).to receive(:link_to).with( - admin_account_path(account.id), - class: name_tag_classes(account, true), - title: account.acct - ) + result = helper.admin_account_inline_link_to(account) - helper.admin_account_inline_link_to(account) + expect(result).to match(name_tag_classes(account, true)) + expect(result).to match(account.acct) + expect(result).to match(admin_account_path(account.id)) end end end diff --git a/spec/helpers/admin/action_log_helper_spec.rb b/spec/helpers/admin/action_log_helper_spec.rb deleted file mode 100644 index 9d7ed4ab76..0000000000 --- a/spec/helpers/admin/action_log_helper_spec.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Admin::ActionLogsHelper, type: :helper do -end diff --git a/spec/helpers/admin/dashboard_helper_spec.rb b/spec/helpers/admin/dashboard_helper_spec.rb new file mode 100644 index 0000000000..59062e4839 --- /dev/null +++ b/spec/helpers/admin/dashboard_helper_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::DashboardHelper do + describe 'relevant_account_timestamp' do + context 'with an account with older sign in' do + let(:account) { Fabricate(:account) } + let(:stamp) { 10.days.ago } + + it 'returns a time element' do + account.user.update(current_sign_in_at: stamp) + result = helper.relevant_account_timestamp(account) + + expect(result).to match('time-ago') + expect(result).to match(I18n.l(stamp)) + end + end + + context 'with an account with newer sign in' do + let(:account) { Fabricate(:account) } + + it 'returns a time element' do + account.user.update(current_sign_in_at: 10.hours.ago) + result = helper.relevant_account_timestamp(account) + + expect(result).to eq(I18n.t('generic.today')) + end + end + + context 'with an account where the user is pending' do + let(:account) { Fabricate(:account) } + + it 'returns a time element' do + account.user.update(current_sign_in_at: nil) + account.user.update(approved: false) + result = helper.relevant_account_timestamp(account) + + expect(result).to match('time-ago') + expect(result).to match(I18n.l(account.user.created_at)) + end + end + + context 'with an account with a last status value' do + let(:account) { Fabricate(:account) } + let(:stamp) { 5.minutes.ago } + + it 'returns a time element' do + account.user.update(current_sign_in_at: nil) + account.account_stat.update(last_status_at: stamp) + result = helper.relevant_account_timestamp(account) + + expect(result).to match('time-ago') + expect(result).to match(I18n.l(stamp)) + end + end + + context 'with an account without sign in or last status or pending' do + let(:account) { Fabricate(:account) } + + it 'returns a time element' do + account.user.update(current_sign_in_at: nil) + result = helper.relevant_account_timestamp(account) + + expect(result).to eq('-') + end + end + end +end diff --git a/spec/helpers/admin/filter_helper_spec.rb b/spec/helpers/admin/filter_helper_spec.rb index 9d4ea28294..40ed63239f 100644 --- a/spec/helpers/admin/filter_helper_spec.rb +++ b/spec/helpers/admin/filter_helper_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Admin::FilterHelper do @@ -5,8 +7,7 @@ describe Admin::FilterHelper do params = ActionController::Parameters.new( { test: 'test' } ) - allow(helper).to receive(:params).and_return(params) - allow(helper).to receive(:url_for).and_return('/test') + allow(helper).to receive_messages(params: params, url_for: '/test') result = helper.filter_link_to('text', { resolved: true }) expect(result).to match(/text/) diff --git a/spec/helpers/admin/trends/statuses_helper_spec.rb b/spec/helpers/admin/trends/statuses_helper_spec.rb new file mode 100644 index 0000000000..92caae6909 --- /dev/null +++ b/spec/helpers/admin/trends/statuses_helper_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Trends::StatusesHelper do + describe '.one_line_preview' do + before do + allow(helper).to receive(:current_user).and_return(Fabricate.build(:user)) + end + + context 'with a local status' do + let(:status) { Fabricate.build(:status, text: 'Test local status') } + + it 'renders a correct preview text' do + result = helper.one_line_preview(status) + + expect(result).to eq 'Test local status' + end + end + + context 'with a remote status' do + let(:status) { Fabricate.build(:status, uri: 'https://sfd.sdf', text: '

Test remote status

text

') } + + it 'renders a correct preview text' do + result = helper.one_line_preview(status) + + expect(result).to eq 'Test remote status' + end + end + + context 'with a status that has empty text' do + let(:status) { Fabricate.build(:status, text: '') } + + it 'renders a correct preview text' do + result = helper.one_line_preview(status) + + expect(result).to eq '' + end + end + + context 'with a status that has emoji' do + before { Fabricate(:custom_emoji, shortcode: 'florpy') } + + let(:status) { Fabricate(:status, text: 'hello there :florpy:') } + + it 'renders a correct preview text' do + result = helper.one_line_preview(status) + + expect(result).to match 'hello there' + expect(result).to match ' Hello this is a nice message for you to quote. + > Be careful because it has two lines. + EXPECTED + end + end + + describe 'storage_host' do + context 'when S3 alias is present' do + around do |example| + ClimateControl.modify S3_ALIAS_HOST: 's3.alias' do + example.run + end + end + + it 'returns true' do + expect(helper.storage_host).to eq('https://s3.alias') + end + end + + context 'when S3 alias includes a path component' do + around do |example| + ClimateControl.modify S3_ALIAS_HOST: 's3.alias/path' do + example.run + end + end + + it 'returns a correct URL' do + expect(helper.storage_host).to eq('https://s3.alias/path') + end + end + + context 'when S3 cloudfront is present' do + around do |example| + ClimateControl.modify S3_CLOUDFRONT_HOST: 's3.cloudfront' do + example.run + end + end + + it 'returns true' do + expect(helper.storage_host).to eq('https://s3.cloudfront') + end + end + end + + describe 'storage_host?' do + context 'when S3 alias is present' do + around do |example| + ClimateControl.modify S3_ALIAS_HOST: 's3.alias' do + example.run + end + end + + it 'returns true' do + expect(helper.storage_host?).to be true + end + end + + context 'when S3 cloudfront is present' do + around do |example| + ClimateControl.modify S3_CLOUDFRONT_HOST: 's3.cloudfront' do + example.run + end + end + + it 'returns true' do + expect(helper.storage_host?).to be true + end + end + + context 'when neither env value is present' do + it 'returns false' do + expect(helper.storage_host?).to be false + end + end + end + + describe 'visibility_icon' do + it 'returns a globe icon for a public visible status' do + result = helper.visibility_icon Status.new(visibility: 'public') + expect(result).to match(/globe/) + end + + it 'returns an unlock icon for a unlisted visible status' do + result = helper.visibility_icon Status.new(visibility: 'unlisted') + expect(result).to match(/unlock/) + end + + it 'returns a lock icon for a private visible status' do + result = helper.visibility_icon Status.new(visibility: 'private') + expect(result).to match(/lock/) + end + + it 'returns an at icon for a direct visible status' do + result = helper.visibility_icon Status.new(visibility: 'direct') + expect(result).to match(/at/) + end + end + describe 'title' do around do |example| site_title = Setting.site_title @@ -115,8 +292,9 @@ describe ApplicationHelper do it 'returns site title on production environment' do Setting.site_title = 'site title' - expect(Rails.env).to receive(:production?).and_return(true) + allow(Rails.env).to receive(:production?).and_return(true) expect(helper.title).to eq 'site title' + expect(Rails.env).to have_received(:production?) end end end diff --git a/spec/helpers/flashes_helper_spec.rb b/spec/helpers/flashes_helper_spec.rb index ea143eed72..035e8a1de0 100644 --- a/spec/helpers/flashes_helper_spec.rb +++ b/spec/helpers/flashes_helper_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe FlashesHelper, type: :helper do +describe FlashesHelper do describe 'user_facing_flashes' do it 'returns user facing flashes' do flash[:alert] = 'an alert' diff --git a/spec/helpers/formatting_helper_spec.rb b/spec/helpers/formatting_helper_spec.rb index af604a87b5..d6e7631f66 100644 --- a/spec/helpers/formatting_helper_spec.rb +++ b/spec/helpers/formatting_helper_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -describe FormattingHelper, type: :helper do +describe FormattingHelper do include Devise::Test::ControllerHelpers describe '#rss_status_content_format' do diff --git a/spec/helpers/home_helper_spec.rb b/spec/helpers/home_helper_spec.rb index a3dc6f836f..c6baec5a1f 100644 --- a/spec/helpers/home_helper_spec.rb +++ b/spec/helpers/home_helper_spec.rb @@ -1,9 +1,119 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe HomeHelper, type: :helper do +RSpec.describe HomeHelper do describe 'default_props' do it 'returns default properties according to the context' do expect(helper.default_props).to eq locale: I18n.locale end end + + describe 'account_link_to' do + context 'with a missing account' do + let(:account) { nil } + + it 'returns a button' do + result = helper.account_link_to(account) + + expect(result).to match t('about.contact_missing') + end + end + + context 'with a valid account' do + let(:account) { Fabricate(:account) } + + it 'returns a link to the account' do + without_partial_double_verification do + allow(helper).to receive_messages(current_account: account, prefers_autoplay?: false) + result = helper.account_link_to(account) + + expect(result).to match "@#{account.acct}" + end + end + end + end + + describe 'obscured_counter' do + context 'with a value of less than zero' do + let(:count) { -10 } + + it 'returns the correct string' do + expect(helper.obscured_counter(count)).to eq '0' + end + end + + context 'with a value of zero' do + let(:count) { 0 } + + it 'returns the correct string' do + expect(helper.obscured_counter(count)).to eq '0' + end + end + + context 'with a value of one' do + let(:count) { 1 } + + it 'returns the correct string' do + expect(helper.obscured_counter(count)).to eq '1' + end + end + + context 'with a value of more than one' do + let(:count) { 10 } + + it 'returns the correct string' do + expect(helper.obscured_counter(count)).to eq '1+' + end + end + end + + describe 'custom_field_classes' do + context 'with a verified field' do + let(:field) { instance_double(Account::Field, verified?: true) } + + it 'returns verified string' do + result = helper.custom_field_classes(field) + expect(result).to eq 'verified' + end + end + + context 'with a non-verified field' do + let(:field) { instance_double(Account::Field, verified?: false) } + + it 'returns verified string' do + result = helper.custom_field_classes(field) + expect(result).to eq 'emojify' + end + end + end + + describe 'sign_up_messages' do + context 'with closed registrations' do + it 'returns correct sign up message' do + allow(helper).to receive(:closed_registrations?).and_return(true) + result = helper.sign_up_message + + expect(result).to eq t('auth.registration_closed', instance: 'cb6e6126.ngrok.io') + end + end + + context 'with open registrations' do + it 'returns correct sign up message' do + allow(helper).to receive_messages(closed_registrations?: false, open_registrations?: true) + result = helper.sign_up_message + + expect(result).to eq t('auth.register') + end + end + + context 'with approved registrations' do + it 'returns correct sign up message' do + allow(helper).to receive_messages(closed_registrations?: false, open_registrations?: false, approved_registrations?: true) + result = helper.sign_up_message + + expect(result).to eq t('auth.apply_for_account') + end + end + end end diff --git a/spec/helpers/jsonld_helper_spec.rb b/spec/helpers/jsonld_helper_spec.rb index 744a14f260..3575bba859 100644 --- a/spec/helpers/jsonld_helper_spec.rb +++ b/spec/helpers/jsonld_helper_spec.rb @@ -22,14 +22,14 @@ describe JsonLdHelper do end describe '#first_of_value' do - context 'value.is_a?(Array)' do + context 'when value.is_a?(Array)' do it 'returns value.first' do value = ['a'] expect(helper.first_of_value(value)).to be 'a' end end - context '!value.is_a?(Array)' do + context 'with !value.is_a?(Array)' do it 'returns value' do value = 'a' expect(helper.first_of_value(value)).to be 'a' @@ -38,14 +38,14 @@ describe JsonLdHelper do end describe '#supported_context?' do - context "!json.nil? && equals_or_includes?(json['@context'], ActivityPub::TagManager::CONTEXT)" do + context 'when json is present and in an activitypub tagmanager context' do it 'returns true' do json = { '@context' => ActivityPub::TagManager::CONTEXT }.as_json expect(helper.supported_context?(json)).to be true end end - context 'else' do + context 'when not in activitypub tagmanager context' do it 'returns false' do json = nil expect(helper.supported_context?(json)).to be false @@ -66,14 +66,14 @@ describe JsonLdHelper do stub_request(:get, 'https://mallory.test/').to_return body: '{"id": "https://marvin.test/"}' stub_request(:get, 'https://marvin.test/').to_return body: '{"id": "https://alice.test/"}' - expect(fetch_resource('https://mallory.test/', false)).to eq nil + expect(fetch_resource('https://mallory.test/', false)).to be_nil end end context 'when the second argument is true' do it 'returns nil if the retrieved ID and the given URI does not match' do stub_request(:get, 'https://mallory.test/').to_return body: '{"id": "https://alice.test/"}' - expect(fetch_resource('https://mallory.test/', true)).to eq nil + expect(fetch_resource('https://mallory.test/', true)).to be_nil end end end @@ -81,7 +81,7 @@ describe JsonLdHelper do describe '#fetch_resource_without_id_validation' do it 'returns nil if the status code is not 200' do stub_request(:get, 'https://host.test/').to_return status: 400, body: '{}' - expect(fetch_resource_without_id_validation('https://host.test/')).to eq nil + expect(fetch_resource_without_id_validation('https://host.test/')).to be_nil end it 'returns hash' do @@ -90,7 +90,7 @@ describe JsonLdHelper do end end - context 'compaction and forwarding' do + context 'with compaction and forwarding' do let(:json) do { '@context' => [ @@ -113,7 +113,7 @@ describe JsonLdHelper do { 'type' => 'Mention', 'href' => ['foo'], - } + }, ], }, 'signature' => { @@ -150,7 +150,7 @@ describe JsonLdHelper do patch_for_forwarding!(json, compacted) expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] expect(compacted.dig('object', 'tag', 0, 'href')).to eq ['foo'] - expect(safe_for_forwarding?(json, compacted)).to eq true + expect(safe_for_forwarding?(json, compacted)).to be true end end @@ -160,14 +160,14 @@ describe JsonLdHelper do compacted = compact(json) deemed_compatible = patch_for_forwarding!(json, compacted) expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] - expect(safe_for_forwarding?(json, compacted)).to eq true + expect(safe_for_forwarding?(json, compacted)).to be true end it 'deems an unsafe compacting as such' do compacted = compact(json) deemed_compatible = patch_for_forwarding!(json, compacted) expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] - expect(safe_for_forwarding?(json, compacted)).to eq false + expect(safe_for_forwarding?(json, compacted)).to be false end end end diff --git a/spec/helpers/languages_helper_spec.rb b/spec/helpers/languages_helper_spec.rb index 217c9b2397..99461b293b 100644 --- a/spec/helpers/languages_helper_spec.rb +++ b/spec/helpers/languages_helper_spec.rb @@ -10,14 +10,80 @@ describe LanguagesHelper do end describe 'native_locale_name' do - it 'finds the human readable native name from a key' do - expect(helper.native_locale_name(:de)).to eq('Deutsch') + context 'with a blank locale' do + it 'defaults to a generic value' do + expect(helper.native_locale_name(nil)).to eq(I18n.t('generic.none')) + end + end + + context 'with a locale of `und`' do + it 'defaults to a generic value' do + expect(helper.native_locale_name('und')).to eq(I18n.t('generic.none')) + end + end + + context 'with a supported locale' do + it 'finds the human readable native name from a key' do + expect(helper.native_locale_name(:de)).to eq('Deutsch') + end + end + + context 'with a regional locale' do + it 'finds the human readable regional name from a key' do + expect(helper.native_locale_name('en-GB')).to eq('English (British)') + end + end + + context 'with a non-existent locale' do + it 'returns the supplied locale value' do + expect(helper.native_locale_name(:xxx)).to eq(:xxx) + end end end describe 'standard_locale_name' do - it 'finds the human readable standard name from a key' do - expect(helper.standard_locale_name(:de)).to eq('German') + context 'with a blank locale' do + it 'defaults to a generic value' do + expect(helper.standard_locale_name(nil)).to eq(I18n.t('generic.none')) + end + end + + context 'with a non-existent locale' do + it 'returns the supplied locale value' do + expect(helper.standard_locale_name(:xxx)).to eq(:xxx) + end + end + + context 'with a supported locale' do + it 'finds the human readable standard name from a key' do + expect(helper.standard_locale_name(:de)).to eq('German') + end + end + end + + describe 'sorted_locales' do + context 'when sorting with native name' do + it 'returns Suomi after Gàidhlig' do + expect(described_class.sorted_locale_keys(%w(fi gd))).to eq(%w(gd fi)) + end + end + + context 'when sorting with diacritics' do + it 'returns Íslensk before Suomi' do + expect(described_class.sorted_locale_keys(%w(fi is))).to eq(%w(is fi)) + end + end + + context 'when sorting with non-Latin' do + it 'returns Suomi before Amharic' do + expect(described_class.sorted_locale_keys(%w(am fi))).to eq(%w(fi am)) + end + end + + context 'when sorting with local variants' do + it 'returns variant in-line' do + expect(described_class.sorted_locale_keys(%w(en eo en-GB))).to eq(%w(en en-GB eo)) + end end end end diff --git a/spec/helpers/media_component_helper_spec.rb b/spec/helpers/media_component_helper_spec.rb new file mode 100644 index 0000000000..71a9af6f3b --- /dev/null +++ b/spec/helpers/media_component_helper_spec.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe MediaComponentHelper do + describe 'render_video_component' do + let(:media) { Fabricate(:media_attachment, type: :video, status: Fabricate(:status)) } + let(:result) { helper.render_video_component(media.status) } + + before do + without_partial_double_verification do + allow(helper).to receive(:current_account).and_return(media.account) + end + end + + it 'renders a react component for the video' do + expect(parsed_html.div['data-component']).to eq('Video') + end + end + + describe 'render_audio_component' do + let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) } + let(:result) { helper.render_audio_component(media.status) } + + before do + without_partial_double_verification do + allow(helper).to receive(:current_account).and_return(media.account) + end + end + + it 'renders a react component for the audio' do + expect(parsed_html.div['data-component']).to eq('Audio') + end + end + + describe 'render_media_gallery_component' do + let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) } + let(:result) { helper.render_media_gallery_component(media.status) } + + before do + without_partial_double_verification do + allow(helper).to receive(:current_account).and_return(media.account) + end + end + + it 'renders a react component for the media gallery' do + expect(parsed_html.div['data-component']).to eq('MediaGallery') + end + end + + describe 'render_card_component' do + let(:status) { Fabricate(:status, preview_cards: [Fabricate(:preview_card)]) } + let(:result) { helper.render_card_component(status) } + + before do + without_partial_double_verification do + allow(helper).to receive(:current_account).and_return(status.account) + end + end + + it 'returns the correct react component markup' do + expect(parsed_html.div['data-component']).to eq('Card') + end + end + + describe 'render_poll_component' do + let(:status) { Fabricate(:status, poll: Fabricate(:poll)) } + let(:result) { helper.render_poll_component(status) } + + before do + without_partial_double_verification do + allow(helper).to receive(:current_account).and_return(status.account) + end + end + + it 'returns the correct react component markup' do + expect(parsed_html.div['data-component']).to eq('Poll') + end + end + + private + + def parsed_html + Nokogiri::Slop(result) + end +end diff --git a/spec/helpers/react_component_helper_spec.rb b/spec/helpers/react_component_helper_spec.rb new file mode 100644 index 0000000000..28208b619b --- /dev/null +++ b/spec/helpers/react_component_helper_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ReactComponentHelper do + describe 'react_component' do + context 'with no block passed in' do + let(:result) { helper.react_component('name', { one: :two }) } + + it 'returns a tag with data attributes' do + expect(parsed_html.div['data-component']).to eq('Name') + expect(parsed_html.div['data-props']).to eq('{"one":"two"}') + end + end + + context 'with a block passed in' do + let(:result) do + helper.react_component('name', { one: :two }) do + helper.content_tag(:nav, 'ok') + end + end + + it 'returns a tag with data attributes' do + expect(parsed_html.div['data-component']).to eq('Name') + expect(parsed_html.div['data-props']).to eq('{"one":"two"}') + expect(parsed_html.div.nav.content).to eq('ok') + end + end + end + + describe 'react_admin_component' do + let(:result) { helper.react_admin_component('name', { one: :two }) } + + it 'returns a tag with data attributes' do + expect(parsed_html.div['data-admin-component']).to eq('Name') + expect(parsed_html.div['data-props']).to eq('{"one":"two"}') + end + end + + private + + def parsed_html + Nokogiri::Slop(result) + end +end diff --git a/spec/helpers/routing_helper_spec.rb b/spec/helpers/routing_helper_spec.rb index 940392c9b0..852d02cebc 100644 --- a/spec/helpers/routing_helper_spec.rb +++ b/spec/helpers/routing_helper_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe RoutingHelper, type: :helper do +RSpec.describe RoutingHelper do describe '.full_asset_url' do around do |example| use_s3 = Rails.configuration.x.use_s3 @@ -24,7 +24,7 @@ RSpec.describe RoutingHelper, type: :helper do end end - context 'Do not use S3' do + context 'when not using S3' do before do Rails.configuration.x.use_s3 = false end @@ -32,7 +32,7 @@ RSpec.describe RoutingHelper, type: :helper do it_behaves_like 'returns full path URL' end - context 'Use S3' do + context 'when using S3' do before do Rails.configuration.x.use_s3 = true end diff --git a/spec/helpers/settings_helper_spec.rb b/spec/helpers/settings_helper_spec.rb new file mode 100644 index 0000000000..cba5c6ee89 --- /dev/null +++ b/spec/helpers/settings_helper_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe SettingsHelper do + describe 'session_device_icon' do + context 'with a mobile device' do + let(:session) { SessionActivation.new(user_agent: 'Mozilla/5.0 (iPhone)') } + + it 'detects the device and returns a descriptive string' do + result = helper.session_device_icon(session) + + expect(result).to eq('mobile') + end + end + + context 'with a tablet device' do + let(:session) { SessionActivation.new(user_agent: 'Mozilla/5.0 (iPad)') } + + it 'detects the device and returns a descriptive string' do + result = helper.session_device_icon(session) + + expect(result).to eq('tablet') + end + end + + context 'with a desktop device' do + let(:session) { SessionActivation.new(user_agent: 'Mozilla/5.0 (Macintosh)') } + + it 'detects the device and returns a descriptive string' do + result = helper.session_device_icon(session) + + expect(result).to eq('desktop') + end + end + end +end diff --git a/spec/helpers/statuses_helper_spec.rb b/spec/helpers/statuses_helper_spec.rb index cba659bfb5..c67e1f3f2b 100644 --- a/spec/helpers/statuses_helper_spec.rb +++ b/spec/helpers/statuses_helper_spec.rb @@ -1,6 +1,96 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe StatusesHelper, type: :helper do +describe StatusesHelper do + describe 'status_text_summary' do + context 'with blank text' do + let(:status) { Status.new(spoiler_text: '') } + + it 'returns immediately with nil' do + result = helper.status_text_summary(status) + expect(result).to be_nil + end + end + + context 'with present text' do + let(:status) { Status.new(spoiler_text: 'SPOILERS!!!') } + + it 'returns the content warning' do + result = helper.status_text_summary(status) + expect(result).to eq(I18n.t('statuses.content_warning', warning: 'SPOILERS!!!')) + end + end + end + + def status_text_summary(status) + return if status.spoiler_text.blank? + + I18n.t('statuses.content_warning', warning: status.spoiler_text) + end + + describe 'link_to_newer' do + it 'returns a link to newer content' do + url = 'https://example.com' + result = helper.link_to_newer(url) + + expect(result).to match('load-more') + expect(result).to match(I18n.t('statuses.show_newer')) + end + end + + describe 'link_to_older' do + it 'returns a link to older content' do + url = 'https://example.com' + result = helper.link_to_older(url) + + expect(result).to match('load-more') + expect(result).to match(I18n.t('statuses.show_older')) + end + end + + describe 'fa_visibility_icon' do + context 'with a status that is public' do + let(:status) { Status.new(visibility: 'public') } + + it 'returns the correct fa icon' do + result = helper.fa_visibility_icon(status) + + expect(result).to match('fa-globe') + end + end + + context 'with a status that is unlisted' do + let(:status) { Status.new(visibility: 'unlisted') } + + it 'returns the correct fa icon' do + result = helper.fa_visibility_icon(status) + + expect(result).to match('fa-unlock') + end + end + + context 'with a status that is private' do + let(:status) { Status.new(visibility: 'private') } + + it 'returns the correct fa icon' do + result = helper.fa_visibility_icon(status) + + expect(result).to match('fa-lock') + end + end + + context 'with a status that is direct' do + let(:status) { Status.new(visibility: 'direct') } + + it 'returns the correct fa icon' do + result = helper.fa_visibility_icon(status) + + expect(result).to match('fa-at') + end + end + end + describe '#stream_link_target' do it 'returns nil if it is not an embedded view' do set_not_embedded_view @@ -24,129 +114,4 @@ RSpec.describe StatusesHelper, type: :helper do params[:controller] = StatusesHelper::EMBEDDED_CONTROLLER params[:action] = StatusesHelper::EMBEDDED_ACTION end - - describe '#style_classes' do - it do - status = double(reblog?: false) - classes = helper.style_classes(status, false, false, false) - - expect(classes).to eq 'entry' - end - - it do - status = double(reblog?: true) - classes = helper.style_classes(status, false, false, false) - - expect(classes).to eq 'entry entry-reblog' - end - - it do - status = double(reblog?: false) - classes = helper.style_classes(status, true, false, false) - - expect(classes).to eq 'entry entry-predecessor' - end - - it do - status = double(reblog?: false) - classes = helper.style_classes(status, false, true, false) - - expect(classes).to eq 'entry entry-successor' - end - - it do - status = double(reblog?: false) - classes = helper.style_classes(status, false, false, true) - - expect(classes).to eq 'entry entry-center' - end - - it do - status = double(reblog?: true) - classes = helper.style_classes(status, true, true, true) - - expect(classes).to eq 'entry entry-predecessor entry-reblog entry-successor entry-center' - end - end - - describe '#microformats_classes' do - it do - status = double(reblog?: false) - classes = helper.microformats_classes(status, false, false) - - expect(classes).to eq '' - end - - it do - status = double(reblog?: false) - classes = helper.microformats_classes(status, true, false) - - expect(classes).to eq 'p-in-reply-to' - end - - it do - status = double(reblog?: false) - classes = helper.microformats_classes(status, false, true) - - expect(classes).to eq 'p-comment' - end - - it do - status = double(reblog?: true) - classes = helper.microformats_classes(status, true, false) - - expect(classes).to eq 'p-in-reply-to p-repost-of' - end - - it do - status = double(reblog?: true) - classes = helper.microformats_classes(status, true, true) - - expect(classes).to eq 'p-in-reply-to p-repost-of p-comment' - end - end - - describe '#microformats_h_class' do - it do - status = double(reblog?: false) - css_class = helper.microformats_h_class(status, false, false, false) - - expect(css_class).to eq 'h-entry' - end - - it do - status = double(reblog?: true) - css_class = helper.microformats_h_class(status, false, false, false) - - expect(css_class).to eq 'h-cite' - end - - it do - status = double(reblog?: false) - css_class = helper.microformats_h_class(status, true, false, false) - - expect(css_class).to eq 'h-cite' - end - - it do - status = double(reblog?: false) - css_class = helper.microformats_h_class(status, false, true, false) - - expect(css_class).to eq 'h-cite' - end - - it do - status = double(reblog?: false) - css_class = helper.microformats_h_class(status, false, false, true) - - expect(css_class).to eq '' - end - - it do - status = double(reblog?: true) - css_class = helper.microformats_h_class(status, true, true, true) - - expect(css_class).to eq 'h-cite' - end - end end diff --git a/spec/lib/account_reach_finder_spec.rb b/spec/lib/account_reach_finder_spec.rb index 1da95ba6b3..e5d85656a2 100644 --- a/spec/lib/account_reach_finder_spec.rb +++ b/spec/lib/account_reach_finder_spec.rb @@ -5,31 +5,31 @@ require 'rails_helper' RSpec.describe AccountReachFinder do let(:account) { Fabricate(:account) } - let(:follower1) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-1') } - let(:follower2) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-2') } - let(:follower3) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/a/inbox', shared_inbox_url: 'https://foo.bar/inbox') } + let(:ap_follower_example_com) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-1', domain: 'example.com') } + let(:ap_follower_example_org) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.org/inbox-2', domain: 'example.org') } + let(:ap_follower_with_shared) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/a/inbox', domain: 'foo.bar', shared_inbox_url: 'https://foo.bar/inbox') } - let(:mentioned1) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/b/inbox', shared_inbox_url: 'https://foo.bar/inbox') } - let(:mentioned2) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-3') } - let(:mentioned3) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-4') } + let(:ap_mentioned_with_shared) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/users/b/inbox', domain: 'foo.bar', shared_inbox_url: 'https://foo.bar/inbox') } + let(:ap_mentioned_example_com) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/inbox-3', domain: 'example.com') } + let(:ap_mentioned_example_org) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.org/inbox-4', domain: 'example.org') } - let(:unrelated_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/unrelated-inbox') } + let(:unrelated_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://example.com/unrelated-inbox', domain: 'example.com') } before do - follower1.follow!(account) - follower2.follow!(account) - follower3.follow!(account) + ap_follower_example_com.follow!(account) + ap_follower_example_org.follow!(account) + ap_follower_with_shared.follow!(account) Fabricate(:status, account: account).tap do |status| - status.mentions << Mention.new(account: follower1) - status.mentions << Mention.new(account: mentioned1) + status.mentions << Mention.new(account: ap_follower_example_com) + status.mentions << Mention.new(account: ap_mentioned_with_shared) end Fabricate(:status, account: account) Fabricate(:status, account: account).tap do |status| - status.mentions << Mention.new(account: mentioned2) - status.mentions << Mention.new(account: mentioned3) + status.mentions << Mention.new(account: ap_mentioned_example_com) + status.mentions << Mention.new(account: ap_mentioned_example_org) end Fabricate(:status).tap do |status| @@ -39,11 +39,11 @@ RSpec.describe AccountReachFinder do describe '#inboxes' do it 'includes the preferred inbox URL of followers' do - expect(described_class.new(account).inboxes).to include(*[follower1, follower2, follower3].map(&:preferred_inbox_url)) + expect(described_class.new(account).inboxes).to include(*[ap_follower_example_com, ap_follower_example_org, ap_follower_with_shared].map(&:preferred_inbox_url)) end it 'includes the preferred inbox URL of recently-mentioned accounts' do - expect(described_class.new(account).inboxes).to include(*[mentioned1, mentioned2, mentioned3].map(&:preferred_inbox_url)) + expect(described_class.new(account).inboxes).to include(*[ap_mentioned_with_shared, ap_mentioned_example_com, ap_mentioned_example_org].map(&:preferred_inbox_url)) end it 'does not include the inbox of unrelated users' do diff --git a/spec/models/account_statuses_filter_spec.rb b/spec/lib/account_statuses_filter_spec.rb similarity index 85% rename from spec/models/account_statuses_filter_spec.rb rename to spec/lib/account_statuses_filter_spec.rb index 03f0ffeb06..c821eb4bac 100644 --- a/spec/models/account_statuses_filter_spec.rb +++ b/spec/lib/account_statuses_filter_spec.rb @@ -3,12 +3,12 @@ require 'rails_helper' RSpec.describe AccountStatusesFilter do + subject { described_class.new(account, current_account, params) } + let(:account) { Fabricate(:account) } let(:current_account) { nil } let(:params) { {} } - subject { described_class.new(account, current_account, params) } - def status!(visibility) Fabricate(:status, account: account, visibility: visibility) end @@ -199,6 +199,34 @@ RSpec.describe AccountStatusesFilter do end end + context 'when blocking a reblogged domain' do + let(:other_account) { Fabricate(:account, domain: 'example.com') } + let(:reblogging_status) { Fabricate(:status, account: other_account) } + let!(:reblog) { Fabricate(:status, account: account, visibility: 'public', reblog: reblogging_status) } + + before do + current_account.block_domain!(other_account.domain) + end + + it 'does not return reblog of blocked domain' do + expect(subject.results.pluck(:id)).to_not include(reblog.id) + end + end + + context 'when blocking an unrelated domain' do + let(:other_account) { Fabricate(:account, domain: nil) } + let(:reblogging_status) { Fabricate(:status, account: other_account, visibility: 'public') } + let!(:reblog) { Fabricate(:status, account: account, visibility: 'public', reblog: reblogging_status) } + + before do + current_account.block_domain!('example.com') + end + + it 'returns the reblog from the non-blocked domain' do + expect(subject.results.pluck(:id)).to include(reblog.id) + end + end + context 'when muting a reblogged account' do let(:reblog) { status_with_reblog!('public') } diff --git a/spec/lib/activitypub/activity/accept_spec.rb b/spec/lib/activitypub/activity/accept_spec.rb index 304cf2208a..d6b6071279 100644 --- a/spec/lib/activitypub/activity/accept_spec.rb +++ b/spec/lib/activitypub/activity/accept_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Accept do @@ -41,7 +43,9 @@ RSpec.describe ActivityPub::Activity::Accept do end end - context 'given a relay' do + context 'when given a relay' do + subject { described_class.new(json, sender) } + let!(:relay) { Fabricate(:relay, state: :pending, follow_activity_id: 'https://abc-123/456') } let(:json) do @@ -59,8 +63,6 @@ RSpec.describe ActivityPub::Activity::Accept do }.with_indifferent_access end - subject { described_class.new(json, sender) } - it 'marks the relay as accepted' do subject.perform expect(relay.reload.accepted?).to be true diff --git a/spec/lib/activitypub/activity/add_spec.rb b/spec/lib/activitypub/activity/add_spec.rb index 0b08e2924a..ec6df01716 100644 --- a/spec/lib/activitypub/activity/add_spec.rb +++ b/spec/lib/activitypub/activity/add_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Add do @@ -24,7 +26,7 @@ RSpec.describe ActivityPub::Activity::Add do end context 'when status was not known before' do - let(:service_stub) { double } + let(:service_stub) { instance_double(ActivityPub::FetchRemoteStatusService) } let(:json) do { @@ -48,10 +50,10 @@ RSpec.describe ActivityPub::Activity::Add do end it 'fetches the status and pins it' do - allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil, request_id: nil| + allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil, request_id: nil| # rubocop:disable Lint/UnusedBlockArgument expect(uri).to eq 'https://example.com/unknown' - expect(id).to eq true - expect(on_behalf_of&.following?(sender)).to eq true + expect(id).to be true + expect(on_behalf_of&.following?(sender)).to be true status end subject.perform @@ -62,10 +64,10 @@ RSpec.describe ActivityPub::Activity::Add do context 'when there is no local follower' do it 'tries to fetch the status' do - allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil, request_id: nil| + allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil, request_id: nil| # rubocop:disable Lint/UnusedBlockArgument expect(uri).to eq 'https://example.com/unknown' - expect(id).to eq true - expect(on_behalf_of).to eq nil + expect(id).to be true + expect(on_behalf_of).to be_nil nil end subject.perform diff --git a/spec/lib/activitypub/activity/announce_spec.rb b/spec/lib/activitypub/activity/announce_spec.rb index e9cd6c68c1..8ad892975d 100644 --- a/spec/lib/activitypub/activity/announce_spec.rb +++ b/spec/lib/activitypub/activity/announce_spec.rb @@ -1,7 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Announce do - let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', uri: 'https://example.com/actor') } + subject { described_class.new(json, sender) } + + let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers', uri: 'https://example.com/actor', domain: 'example.com') } let(:recipient) { Fabricate(:account) } let(:status) { Fabricate(:status, account: recipient) } @@ -27,8 +31,6 @@ RSpec.describe ActivityPub::Activity::Announce do } end - subject { described_class.new(json, sender) } - describe '#perform' do context 'when sender is followed by a local account' do before do @@ -37,7 +39,7 @@ RSpec.describe ActivityPub::Activity::Announce do subject.perform end - context 'a known status' do + context 'with known status' do let(:object_json) do ActivityPub::TagManager.instance.uri_for(status) end @@ -47,7 +49,7 @@ RSpec.describe ActivityPub::Activity::Announce do end end - context 'an unknown status' do + context 'with unknown status' do let(:object_json) { 'https://example.com/actor/hello-world' } it 'creates a reblog by sender of status' do @@ -58,7 +60,7 @@ RSpec.describe ActivityPub::Activity::Announce do end end - context 'self-boost of a previously unknown status with correct attributedTo' do + context 'when self-boost of a previously unknown status with correct attributedTo' do let(:object_json) do { id: 'https://example.com/actor#bar', @@ -74,7 +76,7 @@ RSpec.describe ActivityPub::Activity::Announce do end end - context 'self-boost of a previously unknown status with correct attributedTo, inlined Collection in audience' do + context 'when self-boost of a previously unknown status with correct attributedTo, inlined Collection in audience' do let(:object_json) do { id: 'https://example.com/actor#bar', @@ -82,10 +84,10 @@ RSpec.describe ActivityPub::Activity::Announce do content: 'Lorem ipsum', attributedTo: 'https://example.com/actor', to: { - 'type': 'OrderedCollection', - 'id': 'http://example.com/followers', - 'first': 'http://example.com/followers?page=true', - } + type: 'OrderedCollection', + id: 'http://example.com/followers', + first: 'http://example.com/followers?page=true', + }, } end @@ -110,18 +112,18 @@ RSpec.describe ActivityPub::Activity::Announce do end context 'when the sender is relayed' do - let!(:relay_account) { Fabricate(:account, inbox_url: 'https://relay.example.com/inbox') } + subject { described_class.new(json, sender, relayed_through_actor: relay_account) } + + let!(:relay_account) { Fabricate(:account, inbox_url: 'https://relay.example.com/inbox', domain: 'relay.example.com') } let!(:relay) { Fabricate(:relay, inbox_url: 'https://relay.example.com/inbox') } let(:object_json) { 'https://example.com/actor/hello-world' } - subject { described_class.new(json, sender, relayed_through_actor: relay_account) } - before do stub_request(:get, 'https://example.com/actor/hello-world').to_return(body: Oj.dump(unknown_object_json)) end - context 'and the relay is enabled' do + context 'when the relay is enabled' do before do relay.update(state: :accepted) subject.perform @@ -133,13 +135,13 @@ RSpec.describe ActivityPub::Activity::Announce do end end - context 'and the relay is disabled' do + context 'when the relay is disabled' do before do subject.perform end it 'does not fetch the remote status' do - expect(a_request(:get, 'https://example.com/actor/hello-world')).not_to have_been_made + expect(a_request(:get, 'https://example.com/actor/hello-world')).to_not have_been_made expect(Status.find_by(uri: 'https://example.com/actor/hello-world')).to be_nil end diff --git a/spec/lib/activitypub/activity/block_spec.rb b/spec/lib/activitypub/activity/block_spec.rb index 42bdfdc810..6f68984018 100644 --- a/spec/lib/activitypub/activity/block_spec.rb +++ b/spec/lib/activitypub/activity/block_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Block do diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 1a25395fad..d7c4c131a2 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Create do @@ -29,7 +31,7 @@ RSpec.describe ActivityPub::Activity::Create do subject.perform end - context 'object has been edited' do + context 'when object has been edited' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -51,11 +53,11 @@ RSpec.describe ActivityPub::Activity::Create do status = sender.statuses.first expect(status).to_not be_nil - expect(status.edited?).to eq true + expect(status.edited?).to be true end end - context 'object has update date equal to creation date' do + context 'when object has update date equal to creation date' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -77,11 +79,11 @@ RSpec.describe ActivityPub::Activity::Create do status = sender.statuses.first expect(status).to_not be_nil - expect(status.edited?).to eq false + expect(status.edited?).to be false end end - context 'unknown object type' do + context 'with an unknown object type' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -95,7 +97,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'standalone' do + context 'with a standalone' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -119,7 +121,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'public with explicit public address' do + context 'when public with explicit public address' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -137,7 +139,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'public with as:Public' do + context 'when public with as:Public' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -155,7 +157,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'public with Public' do + context 'when public with Public' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -173,7 +175,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'unlisted with explicit public address' do + context 'when unlisted with explicit public address' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -191,7 +193,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'unlisted with as:Public' do + context 'when unlisted with as:Public' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -209,7 +211,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'unlisted with Public' do + context 'when unlisted with Public' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -227,7 +229,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'private' do + context 'when private' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -245,17 +247,17 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'private with inlined Collection in audience' do + context 'when private with inlined Collection in audience' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, type: 'Note', content: 'Lorem ipsum', to: { - 'type': 'OrderedCollection', - 'id': 'http://example.com/followers', - 'first': 'http://example.com/followers?page=true', - } + type: 'OrderedCollection', + id: 'http://example.com/followers', + first: 'http://example.com/followers?page=true', + }, } end @@ -267,7 +269,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'limited' do + context 'when limited' do let(:recipient) { Fabricate(:account) } let(:object_json) do @@ -292,7 +294,32 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'direct' do + context 'when directMessage attribute is false' do + let(:recipient) { Fabricate(:account) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + directMessage: false, + to: ActivityPub::TagManager.instance.uri_for(recipient), + tag: { + type: 'Mention', + href: ActivityPub::TagManager.instance.uri_for(recipient), + }, + } + end + + it 'creates status with limited visibility' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.visibility).to eq 'limited' + end + end + + context 'when direct' do let(:recipient) { Fabricate(:account) } let(:object_json) do @@ -308,6 +335,27 @@ RSpec.describe ActivityPub::Activity::Create do } end + it 'creates status with direct visibility' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.visibility).to eq 'direct' + end + end + + context 'when directMessage attribute is true' do + let(:recipient) { Fabricate(:account) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + to: ActivityPub::TagManager.instance.uri_for(recipient), + directMessage: true, + } + end + it 'creates status' do status = sender.statuses.first @@ -316,7 +364,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'as a reply' do + context 'with a reply' do let(:original_status) { Fabricate(:status) } let(:object_json) do @@ -408,7 +456,6 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'with media attachments with long description' do let(:object_json) do { @@ -687,7 +734,7 @@ RSpec.describe ActivityPub::Activity::Create do replies: { type: 'Collection', totalItems: 3, - } + }, }, ], } @@ -717,7 +764,7 @@ RSpec.describe ActivityPub::Activity::Create do id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, type: 'Note', name: 'Yellow', - inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status) + inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status), } end @@ -742,7 +789,7 @@ RSpec.describe ActivityPub::Activity::Create do id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, type: 'Note', name: 'Yellow', - inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status) + inReplyTo: ActivityPub::TagManager.instance.uri_for(local_status), } end @@ -753,11 +800,9 @@ RSpec.describe ActivityPub::Activity::Create do end context 'with an encrypted message' do - let(:recipient) { Fabricate(:account) } - let(:target_device) { Fabricate(:device, account: recipient) } - subject { described_class.new(json, sender, delivery: true, delivered_to_account_id: recipient.id) } + let(:recipient) { Fabricate(:account) } let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -779,6 +824,7 @@ RSpec.describe ActivityPub::Activity::Create do }, } end + let(:target_device) { Fabricate(:device, account: recipient) } before do subject.perform @@ -833,14 +879,9 @@ RSpec.describe ActivityPub::Activity::Create do end context 'when sender replies to local status' do - let!(:local_status) { Fabricate(:status) } - subject { described_class.new(json, sender, delivery: true) } - before do - subject.perform - end - + let!(:local_status) { Fabricate(:status) } let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -850,6 +891,10 @@ RSpec.describe ActivityPub::Activity::Create do } end + before do + subject.perform + end + it 'creates status' do status = sender.statuses.first @@ -859,14 +904,9 @@ RSpec.describe ActivityPub::Activity::Create do end context 'when sender targets a local user' do - let!(:local_account) { Fabricate(:account) } - subject { described_class.new(json, sender, delivery: true) } - before do - subject.perform - end - + let!(:local_account) { Fabricate(:account) } let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -876,6 +916,10 @@ RSpec.describe ActivityPub::Activity::Create do } end + before do + subject.perform + end + it 'creates status' do status = sender.statuses.first @@ -885,14 +929,9 @@ RSpec.describe ActivityPub::Activity::Create do end context 'when sender cc\'s a local user' do - let!(:local_account) { Fabricate(:account) } - subject { described_class.new(json, sender, delivery: true) } - before do - subject.perform - end - + let!(:local_account) { Fabricate(:account) } let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -902,6 +941,10 @@ RSpec.describe ActivityPub::Activity::Create do } end + before do + subject.perform + end + it 'creates status' do status = sender.statuses.first diff --git a/spec/lib/activitypub/activity/delete_spec.rb b/spec/lib/activitypub/activity/delete_spec.rb index 9dfb8a61b4..3a73b3726c 100644 --- a/spec/lib/activitypub/activity/delete_spec.rb +++ b/spec/lib/activitypub/activity/delete_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Delete do @@ -30,6 +32,7 @@ RSpec.describe ActivityPub::Activity::Delete do context 'when the status has been reblogged' do describe '#perform' do subject { described_class.new(json, sender) } + let!(:reblogger) { Fabricate(:account) } let!(:follower) { Fabricate(:account, username: 'follower', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } let!(:reblog) { Fabricate(:status, account: reblogger, reblog: status) } @@ -53,6 +56,7 @@ RSpec.describe ActivityPub::Activity::Delete do context 'when the status has been reported' do describe '#perform' do subject { described_class.new(json, sender) } + let!(:reporter) { Fabricate(:account) } before do diff --git a/spec/lib/activitypub/activity/flag_spec.rb b/spec/lib/activitypub/activity/flag_spec.rb index 2f2d138767..8593d567f4 100644 --- a/spec/lib/activitypub/activity/flag_spec.rb +++ b/spec/lib/activitypub/activity/flag_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Flag do @@ -37,6 +39,37 @@ RSpec.describe ActivityPub::Activity::Flag do end end + context 'when the report comment is excessively long' do + subject do + described_class.new({ + '@context': 'https://www.w3.org/ns/activitystreams', + id: flag_id, + type: 'Flag', + content: long_comment, + actor: ActivityPub::TagManager.instance.uri_for(sender), + object: [ + ActivityPub::TagManager.instance.uri_for(flagged), + ActivityPub::TagManager.instance.uri_for(status), + ], + }.with_indifferent_access, sender) + end + + let(:long_comment) { Faker::Lorem.characters(number: 6000) } + + before do + subject.perform + end + + it 'creates a report but with a truncated comment' do + report = Report.find_by(account: sender, target_account: flagged) + + expect(report).to_not be_nil + expect(report.comment.length).to eq 5000 + expect(report.comment).to eq long_comment[0...5000] + expect(report.status_ids).to eq [status.id] + end + end + context 'when the reported status is private and should not be visible to the remote server' do let(:status) { Fabricate(:status, account: flagged, uri: 'foobar', visibility: :private) } @@ -106,11 +139,41 @@ RSpec.describe ActivityPub::Activity::Flag do expect(report.status_ids).to eq [] end end + + context 'when an account is passed but no status' do + let(:mentioned) { Fabricate(:account) } + + let(:json) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: flag_id, + type: 'Flag', + content: 'Boo!!', + actor: ActivityPub::TagManager.instance.uri_for(sender), + object: [ + ActivityPub::TagManager.instance.uri_for(flagged), + ], + }.with_indifferent_access + end + + before do + subject.perform + end + + it 'creates a report with no attached status' do + report = Report.find_by(account: sender, target_account: flagged) + + expect(report).to_not be_nil + expect(report.comment).to eq 'Boo!!' + expect(report.status_ids).to eq [] + end + end end describe '#perform with a defined uri' do subject { described_class.new(json, sender) } - let (:flag_id) { 'http://example.com/reports/1' } + + let(:flag_id) { 'http://example.com/reports/1' } before do subject.perform diff --git a/spec/lib/activitypub/activity/follow_spec.rb b/spec/lib/activitypub/activity/follow_spec.rb index fd4ede82b7..c1829cb8d7 100644 --- a/spec/lib/activitypub/activity/follow_spec.rb +++ b/spec/lib/activitypub/activity/follow_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Follow do @@ -18,7 +20,7 @@ RSpec.describe ActivityPub::Activity::Follow do subject { described_class.new(json, sender) } context 'with no prior follow' do - context 'unlocked account' do + context 'with an unlocked account' do before do subject.perform end @@ -33,7 +35,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'silenced account following an unlocked account' do + context 'when silenced account following an unlocked account' do before do sender.touch(:silenced_at) subject.perform @@ -49,7 +51,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'unlocked account muting the sender' do + context 'with an unlocked account muting the sender' do before do recipient.mute!(sender) subject.perform @@ -65,7 +67,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'locked account' do + context 'when locked account' do before do recipient.update(locked: true) subject.perform @@ -87,7 +89,7 @@ RSpec.describe ActivityPub::Activity::Follow do sender.active_relationships.create!(target_account: recipient, uri: 'bar') end - context 'unlocked account' do + context 'with an unlocked account' do before do subject.perform end @@ -101,7 +103,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'silenced account following an unlocked account' do + context 'when silenced account following an unlocked account' do before do sender.touch(:silenced_at) subject.perform @@ -116,7 +118,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'unlocked account muting the sender' do + context 'with an unlocked account muting the sender' do before do recipient.mute!(sender) subject.perform @@ -131,7 +133,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'locked account' do + context 'when locked account' do before do recipient.update(locked: true) subject.perform @@ -152,7 +154,7 @@ RSpec.describe ActivityPub::Activity::Follow do sender.follow_requests.create!(target_account: recipient, uri: 'bar') end - context 'silenced account following an unlocked account' do + context 'when silenced account following an unlocked account' do before do sender.touch(:silenced_at) subject.perform @@ -168,7 +170,7 @@ RSpec.describe ActivityPub::Activity::Follow do end end - context 'locked account' do + context 'when locked account' do before do recipient.update(locked: true) subject.perform diff --git a/spec/lib/activitypub/activity/like_spec.rb b/spec/lib/activitypub/activity/like_spec.rb index b69615a9d1..640d61ab36 100644 --- a/spec/lib/activitypub/activity/like_spec.rb +++ b/spec/lib/activitypub/activity/like_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Like do diff --git a/spec/lib/activitypub/activity/move_spec.rb b/spec/lib/activitypub/activity/move_spec.rb index c468fdeffc..f3973c70ce 100644 --- a/spec/lib/activitypub/activity/move_spec.rb +++ b/spec/lib/activitypub/activity/move_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Move do @@ -24,7 +26,7 @@ RSpec.describe ActivityPub::Activity::Move do stub_request(:post, old_account.inbox_url).to_return(status: 200) stub_request(:post, new_account.inbox_url).to_return(status: 200) - service_stub = double + service_stub = instance_double(ActivityPub::FetchRemoteAccountService) allow(ActivityPub::FetchRemoteAccountService).to receive(:new).and_return(service_stub) allow(service_stub).to receive(:call).and_return(returned_account) end diff --git a/spec/lib/activitypub/activity/reject_spec.rb b/spec/lib/activitypub/activity/reject_spec.rb index fed4cd8cdc..0a4243cd16 100644 --- a/spec/lib/activitypub/activity/reject_spec.rb +++ b/spec/lib/activitypub/activity/reject_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Reject do @@ -25,7 +27,7 @@ RSpec.describe ActivityPub::Activity::Reject do describe '#perform' do subject { described_class.new(json, sender) } - context 'rejecting a pending follow request by target' do + context 'when rejecting a pending follow request by target' do before do Fabricate(:follow_request, account: recipient, target_account: sender) subject.perform @@ -40,7 +42,7 @@ RSpec.describe ActivityPub::Activity::Reject do end end - context 'rejecting a pending follow request by uri' do + context 'when rejecting a pending follow request by uri' do before do Fabricate(:follow_request, account: recipient, target_account: sender, uri: 'bar') subject.perform @@ -55,7 +57,7 @@ RSpec.describe ActivityPub::Activity::Reject do end end - context 'rejecting a pending follow request by uri only' do + context 'when rejecting a pending follow request by uri only' do let(:object_json) { 'bar' } before do @@ -72,7 +74,7 @@ RSpec.describe ActivityPub::Activity::Reject do end end - context 'rejecting an existing follow relationship by target' do + context 'when rejecting an existing follow relationship by target' do before do Fabricate(:follow, account: recipient, target_account: sender) subject.perform @@ -87,7 +89,7 @@ RSpec.describe ActivityPub::Activity::Reject do end end - context 'rejecting an existing follow relationship by uri' do + context 'when rejecting an existing follow relationship by uri' do before do Fabricate(:follow, account: recipient, target_account: sender, uri: 'bar') subject.perform @@ -102,7 +104,7 @@ RSpec.describe ActivityPub::Activity::Reject do end end - context 'rejecting an existing follow relationship by uri only' do + context 'when rejecting an existing follow relationship by uri only' do let(:object_json) { 'bar' } before do @@ -120,7 +122,9 @@ RSpec.describe ActivityPub::Activity::Reject do end end - context 'given a relay' do + context 'when given a relay' do + subject { described_class.new(json, sender) } + let!(:relay) { Fabricate(:relay, state: :pending, follow_activity_id: 'https://abc-123/456') } let(:json) do @@ -138,8 +142,6 @@ RSpec.describe ActivityPub::Activity::Reject do }.with_indifferent_access end - subject { described_class.new(json, sender) } - it 'marks the relay as rejected' do subject.perform expect(relay.reload.rejected?).to be true diff --git a/spec/lib/activitypub/activity/remove_spec.rb b/spec/lib/activitypub/activity/remove_spec.rb index 4209dfde20..fc12aec8c1 100644 --- a/spec/lib/activitypub/activity/remove_spec.rb +++ b/spec/lib/activitypub/activity/remove_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Remove do diff --git a/spec/lib/activitypub/activity/undo_spec.rb b/spec/lib/activitypub/activity/undo_spec.rb index c0309e49da..58e71fc4e8 100644 --- a/spec/lib/activitypub/activity/undo_spec.rb +++ b/spec/lib/activitypub/activity/undo_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Undo do + subject { described_class.new(json, sender) } + let(:sender) { Fabricate(:account, domain: 'example.com') } let(:json) do @@ -13,8 +17,6 @@ RSpec.describe ActivityPub::Activity::Undo do }.with_indifferent_access end - subject { described_class.new(json, sender) } - describe '#perform' do context 'with Announce' do let(:status) { Fabricate(:status) } @@ -29,7 +31,7 @@ RSpec.describe ActivityPub::Activity::Undo do } end - context do + context 'when not atomUri' do before do Fabricate(:status, reblog: status, account: sender, uri: 'bar') end diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb index 4cd853af21..87e96d2d1b 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -1,24 +1,42 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Activity::Update do - let!(:sender) { Fabricate(:account) } - - before do - sender.update!(uri: ActivityPub::TagManager.instance.uri_for(sender)) - end - subject { described_class.new(json, sender) } + let!(:sender) { Fabricate(:account, domain: 'example.com', inbox_url: 'https://example.com/foo/inbox', outbox_url: 'https://example.com/foo/outbox') } + describe '#perform' do context 'with an Actor object' do - let(:modified_sender) do - sender.tap do |modified_sender| - modified_sender.display_name = 'Totally modified now' - end - end - let(:actor_json) do - ActiveModelSerializers::SerializableResource.new(modified_sender, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter).as_json + { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + manuallyApprovesFollowers: 'as:manuallyApprovesFollowers', + toot: 'http://joinmastodon.org/ns#', + featured: { '@id': 'toot:featured', '@type': '@id' }, + featuredTags: { '@id': 'toot:featuredTags', '@type': '@id' }, + }, + ], + id: sender.uri, + type: 'Person', + following: 'https://example.com/users/dfsdf/following', + followers: 'https://example.com/users/dfsdf/followers', + inbox: sender.inbox_url, + outbox: sender.outbox_url, + featured: 'https://example.com/users/dfsdf/featured', + featuredTags: 'https://example.com/users/dfsdf/tags', + preferredUsername: sender.username, + name: 'Totally modified now', + publicKey: { + id: "#{sender.uri}#main-key", + owner: sender.uri, + publicKeyPem: sender.public_key, + }, + } end let(:json) do @@ -26,7 +44,7 @@ RSpec.describe ActivityPub::Activity::Update do '@context': 'https://www.w3.org/ns/activitystreams', id: 'foo', type: 'Update', - actor: ActivityPub::TagManager.instance.uri_for(sender), + actor: sender.uri, object: actor_json, }.with_indifferent_access end @@ -36,6 +54,7 @@ RSpec.describe ActivityPub::Activity::Update do stub_request(:get, actor_json[:followers]).to_return(status: 404) stub_request(:get, actor_json[:following]).to_return(status: 404) stub_request(:get, actor_json[:featured]).to_return(status: 404) + stub_request(:get, actor_json[:featuredTags]).to_return(status: 404) subject.perform end @@ -47,17 +66,17 @@ RSpec.describe ActivityPub::Activity::Update do context 'with a Question object' do let!(:at_time) { Time.now.utc } - let!(:status) { Fabricate(:status, account: sender, poll: Poll.new(account: sender, options: %w(Bar Baz), cached_tallies: [0, 0], expires_at: at_time + 5.days)) } + let!(:status) { Fabricate(:status, uri: 'https://example.com/statuses/poll', account: sender, poll: Poll.new(account: sender, options: %w(Bar Baz), cached_tallies: [0, 0], expires_at: at_time + 5.days)) } let(:json) do { '@context': 'https://www.w3.org/ns/activitystreams', id: 'foo', type: 'Update', - actor: ActivityPub::TagManager.instance.uri_for(sender), + actor: sender.uri, object: { type: 'Question', - id: ActivityPub::TagManager.instance.uri_for(status), + id: status.uri, content: 'Foo', endTime: (at_time + 5.days).iso8601, oneOf: [ diff --git a/spec/lib/activitypub/adapter_spec.rb b/spec/lib/activitypub/adapter_spec.rb index ea03797aab..f9f8b8dce0 100644 --- a/spec/lib/activitypub/adapter_spec.rb +++ b/spec/lib/activitypub/adapter_spec.rb @@ -1,50 +1,60 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Adapter do - class TestObject < ActiveModelSerializers::Model - attributes :foo - end - - class TestWithBasicContextSerializer < ActivityPub::Serializer - attributes :foo - end - - class TestWithNamedContextSerializer < ActivityPub::Serializer - context :security - attributes :foo - end - - class TestWithNestedNamedContextSerializer < ActivityPub::Serializer - attributes :foo - - has_one :virtual_object, key: :baz, serializer: TestWithNamedContextSerializer - - def virtual_object - object + before do + test_object_class = Class.new(ActiveModelSerializers::Model) do + attributes :foo end - end + stub_const('TestObject', test_object_class) - class TestWithContextExtensionSerializer < ActivityPub::Serializer - context_extensions :sensitive - attributes :foo - end - - class TestWithNestedContextExtensionSerializer < ActivityPub::Serializer - context_extensions :manually_approves_followers - attributes :foo - - has_one :virtual_object, key: :baz, serializer: TestWithContextExtensionSerializer - - def virtual_object - object + test_with_basic_context_serializer = Class.new(ActivityPub::Serializer) do + attributes :foo end + stub_const('TestWithBasicContextSerializer', test_with_basic_context_serializer) + + test_with_named_context_serializer = Class.new(ActivityPub::Serializer) do + context :security + attributes :foo + end + stub_const('TestWithNamedContextSerializer', test_with_named_context_serializer) + + test_with_nested_named_context_serializer = Class.new(ActivityPub::Serializer) do + attributes :foo + + has_one :virtual_object, key: :baz, serializer: TestWithNamedContextSerializer + + def virtual_object + object + end + end + stub_const('TestWithNestedNamedContextSerializer', test_with_nested_named_context_serializer) + + test_with_context_extension_serializer = Class.new(ActivityPub::Serializer) do + context_extensions :sensitive + attributes :foo + end + stub_const('TestWithContextExtensionSerializer', test_with_context_extension_serializer) + + test_with_nested_context_extension_serializer = Class.new(ActivityPub::Serializer) do + context_extensions :manually_approves_followers + attributes :foo + + has_one :virtual_object, key: :baz, serializer: TestWithContextExtensionSerializer + + def virtual_object + object + end + end + stub_const('TestWithNestedContextExtensionSerializer', test_with_nested_context_extension_serializer) end describe '#serializable_hash' do - let(:serializer_class) {} - subject { ActiveModelSerializers::SerializableResource.new(TestObject.new(foo: 'bar'), serializer: serializer_class, adapter: described_class).as_json } + let(:serializer_class) {} + context 'when serializer defines no context' do let(:serializer_class) { TestWithBasicContextSerializer } diff --git a/spec/lib/activitypub/dereferencer_spec.rb b/spec/lib/activitypub/dereferencer_spec.rb index e50b497c7e..11078de866 100644 --- a/spec/lib/activitypub/dereferencer_spec.rb +++ b/spec/lib/activitypub/dereferencer_spec.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::Dereferencer do describe '#object' do + subject { described_class.new(uri, permitted_origin: permitted_origin, signature_actor: signature_actor).object } + let(:object) { { '@context': 'https://www.w3.org/ns/activitystreams', id: 'https://example.com/foo', type: 'Note', content: 'Hoge' } } let(:permitted_origin) { 'https://example.com' } let(:signature_actor) { nil } let(:uri) { nil } - subject { described_class.new(uri, permitted_origin: permitted_origin, signature_actor: signature_actor).object } - before do stub_request(:get, 'https://example.com/foo').to_return(body: Oj.dump(object), headers: { 'Content-Type' => 'application/activity+json' }) end diff --git a/spec/lib/activitypub/linked_data_signature_spec.rb b/spec/lib/activitypub/linked_data_signature_spec.rb index d55a7c7fa8..6a6ad1a706 100644 --- a/spec/lib/activitypub/linked_data_signature_spec.rb +++ b/spec/lib/activitypub/linked_data_signature_spec.rb @@ -1,9 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::LinkedDataSignature do include JsonLdHelper - let!(:sender) { Fabricate(:account, uri: 'http://example.com/alice') } + subject { described_class.new(json) } + + let!(:sender) { Fabricate(:account, uri: 'http://example.com/alice', domain: 'example.com') } let(:raw_json) do { @@ -14,8 +18,6 @@ RSpec.describe ActivityPub::LinkedDataSignature do let(:json) { raw_json.merge('signature' => signature) } - subject { described_class.new(json) } - before do stub_jsonld_contexts! end diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index 606a1de2e5..2bff125a6a 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::TagManager do @@ -137,7 +139,7 @@ RSpec.describe ActivityPub::TagManager do end it 'returns the remote account by matching URI without fragment part' do - account = Fabricate(:account, uri: 'https://example.com/123') + account = Fabricate(:account, uri: 'https://example.com/123', domain: 'example.com') expect(subject.uri_to_resource('https://example.com/123#456', Account)).to eq account end diff --git a/spec/lib/admin/metrics/dimension/instance_accounts_dimension_spec.rb b/spec/lib/admin/metrics/dimension/instance_accounts_dimension_spec.rb new file mode 100644 index 0000000000..106717f97b --- /dev/null +++ b/spec/lib/admin/metrics/dimension/instance_accounts_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::InstanceAccountsDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/instance_languages_dimension_spec.rb b/spec/lib/admin/metrics/dimension/instance_languages_dimension_spec.rb new file mode 100644 index 0000000000..f9f6430ca0 --- /dev/null +++ b/spec/lib/admin/metrics/dimension/instance_languages_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::InstanceLanguagesDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/languages_dimension_spec.rb b/spec/lib/admin/metrics/dimension/languages_dimension_spec.rb new file mode 100644 index 0000000000..1722c4c616 --- /dev/null +++ b/spec/lib/admin/metrics/dimension/languages_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::LanguagesDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/servers_dimension_spec.rb b/spec/lib/admin/metrics/dimension/servers_dimension_spec.rb new file mode 100644 index 0000000000..7e2bb9ac0b --- /dev/null +++ b/spec/lib/admin/metrics/dimension/servers_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::ServersDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/software_versions_dimension_spec.rb b/spec/lib/admin/metrics/dimension/software_versions_dimension_spec.rb new file mode 100644 index 0000000000..ee14917330 --- /dev/null +++ b/spec/lib/admin/metrics/dimension/software_versions_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::SoftwareVersionsDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/sources_dimension_spec.rb b/spec/lib/admin/metrics/dimension/sources_dimension_spec.rb new file mode 100644 index 0000000000..d6b581a9bb --- /dev/null +++ b/spec/lib/admin/metrics/dimension/sources_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::SourcesDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/space_usage_dimension_spec.rb b/spec/lib/admin/metrics/dimension/space_usage_dimension_spec.rb new file mode 100644 index 0000000000..65d04cfedd --- /dev/null +++ b/spec/lib/admin/metrics/dimension/space_usage_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::SpaceUsageDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/tag_languages_dimension_spec.rb b/spec/lib/admin/metrics/dimension/tag_languages_dimension_spec.rb new file mode 100644 index 0000000000..721d24fa18 --- /dev/null +++ b/spec/lib/admin/metrics/dimension/tag_languages_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::TagLanguagesDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/dimension/tag_servers_dimension_spec.rb b/spec/lib/admin/metrics/dimension/tag_servers_dimension_spec.rb new file mode 100644 index 0000000000..3054716816 --- /dev/null +++ b/spec/lib/admin/metrics/dimension/tag_servers_dimension_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Dimension::TagServersDimension do + subject(:dimension) { described_class.new(start_at, end_at, limit, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:limit) { 10 } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { dimension.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/active_users_measure_spec.rb b/spec/lib/admin/metrics/measure/active_users_measure_spec.rb new file mode 100644 index 0000000000..55164ed88a --- /dev/null +++ b/spec/lib/admin/metrics/measure/active_users_measure_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::ActiveUsersMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/instance_accounts_measure_spec.rb b/spec/lib/admin/metrics/measure/instance_accounts_measure_spec.rb new file mode 100644 index 0000000000..8e414963f3 --- /dev/null +++ b/spec/lib/admin/metrics/measure/instance_accounts_measure_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InstanceAccountsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:domain) { 'example.com' } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + + let(:params) { ActionController::Parameters.new(domain: domain) } + + before do + Fabricate(:account, domain: domain, created_at: 1.year.ago) + Fabricate(:account, domain: domain, created_at: 1.month.ago) + Fabricate(:account, domain: domain) + + Fabricate(:account, domain: "foo.#{domain}", created_at: 1.year.ago) + Fabricate(:account, domain: "foo.#{domain}") + Fabricate(:account, domain: "bar.#{domain}") + end + + describe 'total' do + context 'without include_subdomains' do + it 'returns the expected number of accounts' do + expect(measure.total).to eq 3 + end + end + + context 'with include_subdomains' do + let(:params) { ActionController::Parameters.new(domain: domain, include_subdomains: 'true') } + + it 'returns the expected number of accounts' do + expect(measure.total).to eq 6 + end + end + end + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/instance_followers_measure_spec.rb b/spec/lib/admin/metrics/measure/instance_followers_measure_spec.rb new file mode 100644 index 0000000000..c627e6cede --- /dev/null +++ b/spec/lib/admin/metrics/measure/instance_followers_measure_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InstanceFollowersMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:domain) { 'example.com' } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + + let(:params) { ActionController::Parameters.new(domain: domain) } + + before do + local_account = Fabricate(:account) + + Fabricate(:account, domain: domain).follow!(local_account) + Fabricate(:account, domain: domain).follow!(local_account) + Fabricate(:account, domain: domain) + + Fabricate(:account, domain: "foo.#{domain}").follow!(local_account) + Fabricate(:account, domain: "foo.#{domain}").follow!(local_account) + Fabricate(:account, domain: "bar.#{domain}") + end + + describe 'total' do + context 'without include_subdomains' do + it 'returns the expected number of accounts' do + expect(measure.total).to eq 2 + end + end + + context 'with include_subdomains' do + let(:params) { ActionController::Parameters.new(domain: domain, include_subdomains: 'true') } + + it 'returns the expected number of accounts' do + expect(measure.total).to eq 4 + end + end + end + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/instance_follows_measure_spec.rb b/spec/lib/admin/metrics/measure/instance_follows_measure_spec.rb new file mode 100644 index 0000000000..42f33dfc35 --- /dev/null +++ b/spec/lib/admin/metrics/measure/instance_follows_measure_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InstanceFollowsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:domain) { 'example.com' } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + + let(:params) { ActionController::Parameters.new(domain: domain) } + + before do + local_account = Fabricate(:account) + + local_account.follow!(Fabricate(:account, domain: domain)) + local_account.follow!(Fabricate(:account, domain: domain)) + Fabricate(:account, domain: domain) + + local_account.follow!(Fabricate(:account, domain: "foo.#{domain}")) + local_account.follow!(Fabricate(:account, domain: "foo.#{domain}")) + Fabricate(:account, domain: "bar.#{domain}") + end + + describe 'total' do + context 'without include_subdomains' do + it 'returns the expected number of accounts' do + expect(measure.total).to eq 2 + end + end + + context 'with include_subdomains' do + let(:params) { ActionController::Parameters.new(domain: domain, include_subdomains: 'true') } + + it 'returns the expected number of accounts' do + expect(measure.total).to eq 4 + end + end + end + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/instance_media_attachments_measure_spec.rb b/spec/lib/admin/metrics/measure/instance_media_attachments_measure_spec.rb new file mode 100644 index 0000000000..c103307f97 --- /dev/null +++ b/spec/lib/admin/metrics/measure/instance_media_attachments_measure_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:domain) { 'example.com' } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + + let(:params) { ActionController::Parameters.new(domain: domain) } + + let(:remote_account) { Fabricate(:account, domain: domain) } + let(:remote_account_on_subdomain) { Fabricate(:account, domain: "foo.#{domain}") } + + before do + remote_account.media_attachments.create!(file: attachment_fixture('attachment.jpg')) + remote_account_on_subdomain.media_attachments.create!(file: attachment_fixture('attachment.jpg')) + end + + describe 'total' do + context 'without include_subdomains' do + it 'returns the expected number of accounts' do + expected_total = remote_account.media_attachments.sum(:file_file_size) + remote_account.media_attachments.sum(:thumbnail_file_size) + expect(measure.total).to eq expected_total + end + end + + context 'with include_subdomains' do + let(:params) { ActionController::Parameters.new(domain: domain, include_subdomains: 'true') } + + it 'returns the expected number of accounts' do + expected_total = [remote_account, remote_account_on_subdomain].sum do |account| + account.media_attachments.sum(:file_file_size) + account.media_attachments.sum(:thumbnail_file_size) + end + + expect(measure.total).to eq expected_total + end + end + end + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/instance_reports_measure_spec.rb b/spec/lib/admin/metrics/measure/instance_reports_measure_spec.rb new file mode 100644 index 0000000000..62fcf84ac1 --- /dev/null +++ b/spec/lib/admin/metrics/measure/instance_reports_measure_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InstanceReportsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:domain) { 'example.com' } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + + let(:params) { ActionController::Parameters.new(domain: domain) } + + before do + Fabricate(:report, target_account: Fabricate(:account, domain: domain)) + Fabricate(:report, target_account: Fabricate(:account, domain: domain)) + + Fabricate(:report, target_account: Fabricate(:account, domain: "foo.#{domain}")) + Fabricate(:report, target_account: Fabricate(:account, domain: "foo.#{domain}")) + Fabricate(:report, target_account: Fabricate(:account, domain: "bar.#{domain}")) + end + + describe 'total' do + context 'without include_subdomains' do + it 'returns the expected number of accounts' do + expect(measure.total).to eq 2 + end + end + + context 'with include_subdomains' do + let(:params) { ActionController::Parameters.new(domain: domain, include_subdomains: 'true') } + + it 'returns the expected number of accounts' do + expect(measure.total).to eq 5 + end + end + end + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/instance_statuses_measure_spec.rb b/spec/lib/admin/metrics/measure/instance_statuses_measure_spec.rb new file mode 100644 index 0000000000..df4cfe207b --- /dev/null +++ b/spec/lib/admin/metrics/measure/instance_statuses_measure_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InstanceStatusesMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:domain) { 'example.com' } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + + let(:params) { ActionController::Parameters.new(domain: domain) } + + before do + Fabricate(:status, account: Fabricate(:account, domain: domain)) + Fabricate(:status, account: Fabricate(:account, domain: domain)) + + Fabricate(:status, account: Fabricate(:account, domain: "foo.#{domain}")) + Fabricate(:status, account: Fabricate(:account, domain: "foo.#{domain}")) + Fabricate(:status, account: Fabricate(:account, domain: "bar.#{domain}")) + end + + describe 'total' do + context 'without include_subdomains' do + it 'returns the expected number of accounts' do + expect(measure.total).to eq 2 + end + end + + context 'with include_subdomains' do + let(:params) { ActionController::Parameters.new(domain: domain, include_subdomains: 'true') } + + it 'returns the expected number of accounts' do + expect(measure.total).to eq 5 + end + end + end + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/interactions_measure_spec.rb b/spec/lib/admin/metrics/measure/interactions_measure_spec.rb new file mode 100644 index 0000000000..e98c830598 --- /dev/null +++ b/spec/lib/admin/metrics/measure/interactions_measure_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::InteractionsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/new_users_measure_spec.rb b/spec/lib/admin/metrics/measure/new_users_measure_spec.rb new file mode 100644 index 0000000000..fe82f8219b --- /dev/null +++ b/spec/lib/admin/metrics/measure/new_users_measure_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::NewUsersMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/opened_reports_measure_spec.rb b/spec/lib/admin/metrics/measure/opened_reports_measure_spec.rb new file mode 100644 index 0000000000..deed64ae88 --- /dev/null +++ b/spec/lib/admin/metrics/measure/opened_reports_measure_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::OpenedReportsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/resolved_reports_measure_spec.rb b/spec/lib/admin/metrics/measure/resolved_reports_measure_spec.rb new file mode 100644 index 0000000000..cb98df2dc2 --- /dev/null +++ b/spec/lib/admin/metrics/measure/resolved_reports_measure_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::ResolvedReportsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/tag_accounts_measure_spec.rb b/spec/lib/admin/metrics/measure/tag_accounts_measure_spec.rb new file mode 100644 index 0000000000..938b67afa3 --- /dev/null +++ b/spec/lib/admin/metrics/measure/tag_accounts_measure_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::TagAccountsMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let!(:tag) { Fabricate(:tag) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new(id: tag.id) } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/tag_servers_measure_spec.rb b/spec/lib/admin/metrics/measure/tag_servers_measure_spec.rb new file mode 100644 index 0000000000..e09a2b04e5 --- /dev/null +++ b/spec/lib/admin/metrics/measure/tag_servers_measure_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::TagServersMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let!(:tag) { Fabricate(:tag) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new(id: tag.id) } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/metrics/measure/tag_uses_measure_spec.rb b/spec/lib/admin/metrics/measure/tag_uses_measure_spec.rb new file mode 100644 index 0000000000..869e937445 --- /dev/null +++ b/spec/lib/admin/metrics/measure/tag_uses_measure_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::Metrics::Measure::TagUsesMeasure do + subject(:measure) { described_class.new(start_at, end_at, params) } + + let!(:tag) { Fabricate(:tag) } + + let(:start_at) { 2.days.ago } + let(:end_at) { Time.now.utc } + let(:params) { ActionController::Parameters.new(id: tag.id) } + + describe '#data' do + it 'runs data query without error' do + expect { measure.data }.to_not raise_error + end + end +end diff --git a/spec/lib/admin/system_check/base_check_spec.rb b/spec/lib/admin/system_check/base_check_spec.rb new file mode 100644 index 0000000000..fdd9f6b6c4 --- /dev/null +++ b/spec/lib/admin/system_check/base_check_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::BaseCheck do + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + describe 'skip?' do + it 'returns false' do + expect(check.skip?).to be false + end + end + + describe 'pass?' do + it 'raises not implemented error' do + expect { check.pass? }.to raise_error(NotImplementedError) + end + end + + describe 'message' do + it 'raises not implemented error' do + expect { check.message }.to raise_error(NotImplementedError) + end + end +end diff --git a/spec/lib/admin/system_check/database_schema_check_spec.rb b/spec/lib/admin/system_check/database_schema_check_spec.rb new file mode 100644 index 0000000000..db1dcb52fa --- /dev/null +++ b/spec/lib/admin/system_check/database_schema_check_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::DatabaseSchemaCheck do + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + it_behaves_like 'a check available to devops users' + + describe 'pass?' do + context 'when database needs migration' do + before do + context = instance_double(ActiveRecord::MigrationContext, needs_migration?: true) + allow(ActiveRecord::Base.connection).to receive(:migration_context).and_return(context) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + + context 'when database does not need migration' do + before do + context = instance_double(ActiveRecord::MigrationContext, needs_migration?: false) + allow(ActiveRecord::Base.connection).to receive(:migration_context).and_return(context) + end + + it 'returns true' do + expect(check.pass?).to be true + end + end + end + + describe 'message' do + it 'sends class name symbol to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new).with(:database_schema_check) + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new).with(:database_schema_check) + end + end +end diff --git a/spec/lib/admin/system_check/elasticsearch_check_spec.rb b/spec/lib/admin/system_check/elasticsearch_check_spec.rb new file mode 100644 index 0000000000..a885640ce0 --- /dev/null +++ b/spec/lib/admin/system_check/elasticsearch_check_spec.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::ElasticsearchCheck do + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + it_behaves_like 'a check available to devops users' + + describe 'pass?' do + context 'when chewy is enabled' do + before do + allow(Chewy).to receive(:enabled?).and_return(true) + allow(Chewy.client.cluster).to receive(:health).and_return({ 'status' => 'green', 'number_of_nodes' => 1 }) + allow(Chewy.client.indices).to receive_messages(get_mapping: { + AccountsIndex.index_name => AccountsIndex.mappings_hash.deep_stringify_keys, + StatusesIndex.index_name => StatusesIndex.mappings_hash.deep_stringify_keys, + PublicStatusesIndex.index_name => PublicStatusesIndex.mappings_hash.deep_stringify_keys, + InstancesIndex.index_name => InstancesIndex.mappings_hash.deep_stringify_keys, + TagsIndex.index_name => TagsIndex.mappings_hash.deep_stringify_keys, + }, get_settings: { + 'chewy_specifications' => { + 'settings' => { + 'index' => { + 'number_of_replicas' => 0, + }, + }, + }, + }) + end + + context 'when running version is present and high enough' do + before do + allow(Chewy.client).to receive(:info) + .and_return({ 'version' => { 'number' => '999.99.9' } }) + end + + it 'returns true' do + expect(check.pass?).to be true + end + end + + context 'when running version is present and too low' do + context 'when compatible version is too low' do + before do + allow(Chewy.client).to receive(:info) + .and_return({ 'version' => { 'number' => '1.2.3', 'minimum_wire_compatibility_version' => '1.0' } }) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + + context 'when compatible version is high enough' do + before do + allow(Chewy.client).to receive(:info) + .and_return({ 'version' => { 'number' => '1.2.3', 'minimum_wire_compatibility_version' => '99.9' } }) + end + + it 'returns true' do + expect(check.pass?).to be true + end + end + end + + context 'when running version is missing' do + before { stub_elasticsearch_error } + + it 'returns false' do + expect(check.pass?).to be false + end + end + end + + context 'when chewy is not enabled' do + before { allow(Chewy).to receive(:enabled?).and_return(false) } + + it 'returns true' do + expect(check.pass?).to be true + end + end + end + + describe 'message' do + before do + allow(Chewy).to receive(:enabled?).and_return(true) + allow(Chewy.client.cluster).to receive(:health).and_return({ 'status' => 'green', 'number_of_nodes' => 1 }) + allow(Chewy.client.indices).to receive(:get_mapping).and_return({ + AccountsIndex.index_name => AccountsIndex.mappings_hash.deep_stringify_keys, + StatusesIndex.index_name => StatusesIndex.mappings_hash.deep_stringify_keys, + PublicStatusesIndex.index_name => PublicStatusesIndex.mappings_hash.deep_stringify_keys, + InstancesIndex.index_name => InstancesIndex.mappings_hash.deep_stringify_keys, + TagsIndex.index_name => TagsIndex.mappings_hash.deep_stringify_keys, + }) + end + + context 'when running version is present' do + before { allow(Chewy.client).to receive(:info).and_return({ 'version' => { 'number' => '1.2.3' } }) } + + it 'sends class name symbol to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new) + .with(:elasticsearch_version_check, anything) + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new) + .with(:elasticsearch_version_check, 'Elasticsearch 1.2.3 is running while 7.x is required') + end + end + + context 'when running version is missing' do + before { stub_elasticsearch_error } + + it 'sends class name symbol to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new) + .with(:elasticsearch_running_check) + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new) + .with(:elasticsearch_running_check) + end + end + end + + def stub_elasticsearch_error + client = instance_double(Elasticsearch::Transport::Client) + allow(client).to receive(:info).and_raise(Elasticsearch::Transport::Transport::Error) + allow(Chewy).to receive(:client).and_return(client) + end +end diff --git a/spec/lib/admin/system_check/media_privacy_check_spec.rb b/spec/lib/admin/system_check/media_privacy_check_spec.rb new file mode 100644 index 0000000000..316bf12156 --- /dev/null +++ b/spec/lib/admin/system_check/media_privacy_check_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::MediaPrivacyCheck do + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + it_behaves_like 'a check available to devops users' + + describe 'pass?' do + context 'when the media cannot be listed' do + before do + stub_request(:get, /ngrok.io/).to_return(status: 200, body: 'a list of no files') + end + + it 'returns true' do + expect(check.pass?).to be true + end + end + end + + describe 'message' do + it 'sends values to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new).with(nil, nil, nil, true) + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new).with(nil, nil, nil, true) + end + end +end diff --git a/spec/lib/admin/system_check/message_spec.rb b/spec/lib/admin/system_check/message_spec.rb new file mode 100644 index 0000000000..c0671f3452 --- /dev/null +++ b/spec/lib/admin/system_check/message_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::Message do + subject(:check) { described_class.new(:key_value, :value_value, :action_value, :critical_value) } + + it 'providers readers when initialized' do + expect(check.key).to eq :key_value + expect(check.value).to eq :value_value + expect(check.action).to eq :action_value + expect(check.critical).to eq :critical_value + end +end diff --git a/spec/lib/admin/system_check/rules_check_spec.rb b/spec/lib/admin/system_check/rules_check_spec.rb new file mode 100644 index 0000000000..fb3293fb2d --- /dev/null +++ b/spec/lib/admin/system_check/rules_check_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::RulesCheck do + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + describe 'skip?' do + context 'when user can manage rules' do + before { allow(user).to receive(:can?).with(:manage_rules).and_return(true) } + + it 'returns false' do + expect(check.skip?).to be false + end + end + + context 'when user cannot manage rules' do + before { allow(user).to receive(:can?).with(:manage_rules).and_return(false) } + + it 'returns true' do + expect(check.skip?).to be true + end + end + end + + describe 'pass?' do + context 'when there is not a kept rule' do + it 'returns false' do + expect(check.pass?).to be false + end + end + + context 'when there is a kept rule' do + before { Fabricate(:rule) } + + it 'returns true' do + expect(check.pass?).to be true + end + end + end + + describe 'message' do + it 'sends class name symbol to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new).with(:rules_check, nil, '/admin/rules') + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new).with(:rules_check, nil, '/admin/rules') + end + end +end diff --git a/spec/lib/admin/system_check/sidekiq_process_check_spec.rb b/spec/lib/admin/system_check/sidekiq_process_check_spec.rb new file mode 100644 index 0000000000..9bd9daddf6 --- /dev/null +++ b/spec/lib/admin/system_check/sidekiq_process_check_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::SidekiqProcessCheck do + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + it_behaves_like 'a check available to devops users' + + describe 'pass?' do + context 'when missing queues is empty' do + before do + process_set = instance_double(Sidekiq::ProcessSet, reduce: []) + allow(Sidekiq::ProcessSet).to receive(:new).and_return(process_set) + end + + it 'returns true' do + expect(check.pass?).to be true + end + end + + context 'when missing queues is not empty' do + before do + process_set = instance_double(Sidekiq::ProcessSet, reduce: [:something]) + allow(Sidekiq::ProcessSet).to receive(:new).and_return(process_set) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + end + + describe 'message' do + it 'sends values to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new).with(:sidekiq_process_check, 'default, push, mailers, pull, scheduler, ingress') + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new).with(:sidekiq_process_check, 'default, push, mailers, pull, scheduler, ingress') + end + end +end diff --git a/spec/lib/admin/system_check/software_version_check_spec.rb b/spec/lib/admin/system_check/software_version_check_spec.rb new file mode 100644 index 0000000000..de4335fc51 --- /dev/null +++ b/spec/lib/admin/system_check/software_version_check_spec.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck::SoftwareVersionCheck do + include RoutingHelper + + subject(:check) { described_class.new(user) } + + let(:user) { Fabricate(:user) } + + describe 'skip?' do + context 'when user cannot view devops' do + before { allow(user).to receive(:can?).with(:view_devops).and_return(false) } + + it 'returns true' do + expect(check.skip?).to be true + end + end + + context 'when user can view devops' do + before { allow(user).to receive(:can?).with(:view_devops).and_return(true) } + + it 'returns false' do + expect(check.skip?).to be false + end + + context 'when checks are disabled' do + around do |example| + ClimateControl.modify UPDATE_CHECK_URL: '' do + example.run + end + end + + it 'returns true' do + expect(check.skip?).to be true + end + end + end + end + + describe 'pass?' do + context 'when there is no known update' do + it 'returns true' do + expect(check.pass?).to be true + end + end + + context 'when there is a non-urgent major release' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'major', urgent: false) + end + + it 'returns true' do + expect(check.pass?).to be true + end + end + + context 'when there is an urgent major release' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'major', urgent: true) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + + context 'when there is an urgent minor release' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'minor', urgent: true) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + + context 'when there is an urgent patch release' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'patch', urgent: true) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + + context 'when there is a non-urgent patch release' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'patch', urgent: false) + end + + it 'returns false' do + expect(check.pass?).to be false + end + end + end + + describe 'message' do + context 'when there is a non-urgent patch release pending' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'patch', urgent: false) + end + + it 'sends class name symbol to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new) + .with(:software_version_patch_check, anything, anything) + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new) + .with(:software_version_patch_check, nil, admin_software_updates_path) + end + end + + context 'when there is an urgent patch release pending' do + before do + Fabricate(:software_update, version: '99.99.99', type: 'patch', urgent: true) + end + + it 'sends class name symbol to message instance' do + allow(Admin::SystemCheck::Message).to receive(:new) + .with(:software_version_critical_check, anything, anything, anything) + + check.message + + expect(Admin::SystemCheck::Message).to have_received(:new) + .with(:software_version_critical_check, nil, admin_software_updates_path, true) + end + end + end +end diff --git a/spec/lib/admin/system_check_spec.rb b/spec/lib/admin/system_check_spec.rb new file mode 100644 index 0000000000..30048fd3ad --- /dev/null +++ b/spec/lib/admin/system_check_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::SystemCheck do + let(:user) { Fabricate(:user) } + + describe 'perform' do + let(:result) { described_class.perform(user) } + + it 'runs all the checks' do + expect(result).to be_an(Array) + end + end +end diff --git a/spec/lib/advanced_text_formatter_spec.rb b/spec/lib/advanced_text_formatter_spec.rb new file mode 100644 index 0000000000..f923852196 --- /dev/null +++ b/spec/lib/advanced_text_formatter_spec.rb @@ -0,0 +1,300 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe AdvancedTextFormatter do + describe '#to_s' do + subject { described_class.new(text, preloaded_accounts: preloaded_accounts, content_type: content_type).to_s } + + let(:preloaded_accounts) { nil } + let(:content_type) { 'text/markdown' } + + context 'with a markdown source' do + let(:content_type) { 'text/markdown' } + + context 'with text containing plain text' do + let(:text) { 'text' } + + it 'paragraphizes the text' do + expect(subject).to eq '

text

' + end + end + + context 'with text containing line feeds' do + let(:text) { "line\nfeed" } + + it 'removes line feeds' do + expect(subject).to_not include "\n" + end + end + + context 'with some inline code using backticks' do + let(:text) { 'test `foo` bar' } + + it 'formats code using ' do + expect(subject).to include 'test foo bar' + end + end + + context 'with a block code' do + let(:text) { "test\n\n```\nint main(void) {\n return 0; // https://joinmastodon.org/foo\n}\n```\n" } + + it 'formats code using
 and ' do
+          expect(subject).to include '
int main'
+        end
+
+        it 'does not strip leading spaces' do
+          expect(subject).to include '>  return 0'
+        end
+
+        it 'does not format links' do
+          expect(subject).to include 'return 0; // https://joinmastodon.org/foo'
+        end
+      end
+
+      context 'with a link in inline code using backticks' do
+        let(:text) { 'test `https://foo.bar/bar` bar' }
+
+        it 'does not rewrite the link' do
+          expect(subject).to include 'test https://foo.bar/bar bar'
+        end
+      end
+
+      context 'with text with a local-domain mention' do
+        let(:text) { 'foo https://cb6e6126.ngrok.io/about/more' }
+
+        it 'creates a link' do
+          expect(subject).to include '@alice'
+        end
+      end
+
+      context 'with text containing unlinkable mentions' do
+        let(:preloaded_accounts) { [] }
+        let(:text) { '@alice' }
+
+        it 'does not create a mention link' do
+          expect(subject).to include '@alice'
+        end
+      end
+
+      context 'with a stand-alone medium URL' do
+        let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"'
+        end
+      end
+
+      context 'with a stand-alone google URL' do
+        let(:text) { 'http://google.com' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="http://google.com"'
+        end
+      end
+
+      context 'with a stand-alone URL with a newer TLD' do
+        let(:text) { 'http://example.gay' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="http://example.gay"'
+        end
+      end
+
+      context 'with a stand-alone IDN URL' do
+        let(:text) { 'https://nic.みんな/' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="https://nic.みんな/"'
+        end
+
+        it 'has display URL' do
+          expect(subject).to include 'nic.みんな/'
+        end
+      end
+
+      context 'with a URL with a trailing period' do
+        let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' }
+
+        it 'matches the full URL but not the period' do
+          expect(subject).to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"'
+        end
+      end
+
+      context 'with a URL enclosed with parentheses' do
+        let(:text) { '(http://google.com/)' }
+
+        it 'matches the full URL but not the parentheses' do
+          expect(subject).to include 'href="http://google.com/"'
+        end
+      end
+
+      context 'with a URL with a trailing exclamation point' do
+        let(:text) { 'http://www.google.com!' }
+
+        it 'matches the full URL but not the exclamation point' do
+          expect(subject).to include 'href="http://www.google.com"'
+        end
+      end
+
+      context 'with a URL with a trailing single quote' do
+        let(:text) { "http://www.google.com'" }
+
+        it 'matches the full URL but not the single quote' do
+          expect(subject).to include 'href="http://www.google.com"'
+        end
+      end
+    end
+
+    context 'with a URL with a trailing angle bracket' do
+      let(:text) { 'http://www.google.com>' }
+
+      it 'matches the full URL but not the angle bracket' do
+        expect(subject).to include 'href="http://www.google.com"'
+      end
+    end
+
+    context 'with a URL with a query string' do
+      context 'with escaped unicode character' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink"'
+        end
+      end
+
+      context 'with unicode character' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&q=autolink"'
+        end
+      end
+
+      context 'with unicode character at the end' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"'
+        end
+      end
+
+      context 'with escaped and not escaped unicode characters' do
+        let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' }
+
+        it 'preserves escaped unicode characters' do
+          expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink"'
+        end
+      end
+
+      context 'with a URL with parentheses in it' do
+        let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' }
+
+        it 'matches the full URL' do
+          expect(subject).to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"'
+        end
+      end
+
+      context 'with a URL in quotation marks' do
+        let(:text) { '"https://example.com/"' }
+
+        it 'does not match the quotation marks' do
+          expect(subject).to include 'href="https://example.com/"'
+        end
+      end
+
+      context 'with a URL in angle brackets' do
+        let(:text) { '' }
+
+        it 'does not match the angle brackets' do
+          expect(subject).to include 'href="https://example.com/"'
+        end
+      end
+
+      context 'with a URL containing unsafe code (XSS attack, invisible part)' do
+        let(:text) { 'http://example.com/blahblahblahblah/a' }
+
+        it 'does not include the HTML in the URL' do
+          expect(subject).to include '"http://example.com/blahblahblahblah/a"'
+        end
+
+        it 'does not include a script tag' do
+          expect(subject).to_not include '' }
+
+        it 'does not include a script tag' do
+          expect(subject).to_not include '' }
 
         it 'strips the scripts' do
-          is_expected.to_not include ''
+          expect(subject).to_not include ''
         end
       end
 
-      context 'given text containing malicious classes' do
+      context 'when given text containing malicious classes' do
         let(:text) { 'Show more' }
 
         it 'strips the malicious classes' do
-          is_expected.to_not include 'status__content__spoiler-link'
+          expect(subject).to_not include 'status__content__spoiler-link'
         end
       end
     end
diff --git a/spec/lib/importer/accounts_index_importer_spec.rb b/spec/lib/importer/accounts_index_importer_spec.rb
new file mode 100644
index 0000000000..73f9bce399
--- /dev/null
+++ b/spec/lib/importer/accounts_index_importer_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Importer::AccountsIndexImporter do
+  describe 'import!' do
+    let(:pool) { Concurrent::FixedThreadPool.new(5) }
+    let(:importer) { described_class.new(batch_size: 123, executor: pool) }
+
+    before { Fabricate(:account) }
+
+    it 'indexes relevant accounts' do
+      expect { importer.import! }.to update_index(AccountsIndex)
+    end
+  end
+end
diff --git a/spec/lib/importer/base_importer_spec.rb b/spec/lib/importer/base_importer_spec.rb
new file mode 100644
index 0000000000..78e9a869b8
--- /dev/null
+++ b/spec/lib/importer/base_importer_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Importer::BaseImporter do
+  describe 'import!' do
+    let(:pool) { Concurrent::FixedThreadPool.new(5) }
+    let(:importer) { described_class.new(batch_size: 123, executor: pool) }
+
+    it 'raises an error' do
+      expect { importer.import! }.to raise_error(NotImplementedError)
+    end
+  end
+end
diff --git a/spec/lib/importer/public_statuses_index_importer_spec.rb b/spec/lib/importer/public_statuses_index_importer_spec.rb
new file mode 100644
index 0000000000..bc7c038a97
--- /dev/null
+++ b/spec/lib/importer/public_statuses_index_importer_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Importer::PublicStatusesIndexImporter do
+  describe 'import!' do
+    let(:pool) { Concurrent::FixedThreadPool.new(5) }
+    let(:importer) { described_class.new(batch_size: 123, executor: pool) }
+
+    before { Fabricate(:status, account: Fabricate(:account, indexable: true)) }
+
+    it 'indexes relevant statuses' do
+      expect { importer.import! }.to update_index(PublicStatusesIndex)
+    end
+  end
+end
diff --git a/spec/lib/importer/statuses_index_importer_spec.rb b/spec/lib/importer/statuses_index_importer_spec.rb
new file mode 100644
index 0000000000..d5e1c9f2cb
--- /dev/null
+++ b/spec/lib/importer/statuses_index_importer_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Importer::StatusesIndexImporter do
+  describe 'import!' do
+    let(:pool) { Concurrent::FixedThreadPool.new(5) }
+    let(:importer) { described_class.new(batch_size: 123, executor: pool) }
+
+    before { Fabricate(:status) }
+
+    it 'indexes relevant statuses' do
+      expect { importer.import! }.to update_index(StatusesIndex)
+    end
+  end
+end
diff --git a/spec/lib/importer/tags_index_importer_spec.rb b/spec/lib/importer/tags_index_importer_spec.rb
new file mode 100644
index 0000000000..348990c01e
--- /dev/null
+++ b/spec/lib/importer/tags_index_importer_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe Importer::TagsIndexImporter do
+  describe 'import!' do
+    let(:pool) { Concurrent::FixedThreadPool.new(5) }
+    let(:importer) { described_class.new(batch_size: 123, executor: pool) }
+
+    before { Fabricate(:tag) }
+
+    it 'indexes relevant tags' do
+      expect { importer.import! }.to update_index(TagsIndex)
+    end
+  end
+end
diff --git a/spec/lib/link_details_extractor_spec.rb b/spec/lib/link_details_extractor_spec.rb
index 7ea867c614..599bc4e6de 100644
--- a/spec/lib/link_details_extractor_spec.rb
+++ b/spec/lib/link_details_extractor_spec.rb
@@ -1,33 +1,33 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 RSpec.describe LinkDetailsExtractor do
-  let(:original_url) { '' }
-  let(:html) { '' }
-  let(:html_charset) { nil }
+  subject { described_class.new(original_url, html, nil) }
 
-  subject { described_class.new(original_url, html, html_charset) }
+  let(:original_url) { 'https://example.com/dog.html?tracking=123' }
 
   describe '#canonical_url' do
-    let(:original_url) { 'https://foo.com/article?bar=baz123' }
+    let(:html) { "" }
 
-    context 'when canonical URL points to another host' do
-      let(:html) { '' }
+    context 'when canonical URL points to the same host' do
+      let(:url) { 'https://example.com/dog.html' }
 
       it 'ignores the canonical URLs' do
-        expect(subject.canonical_url).to eq original_url
+        expect(subject.canonical_url).to eq 'https://example.com/dog.html'
       end
     end
 
-    context 'when canonical URL points to the same host' do
-      let(:html) { '' }
+    context 'when canonical URL points to another host' do
+      let(:url) { 'https://different.example.net/dog.html' }
 
       it 'ignores the canonical URLs' do
-        expect(subject.canonical_url).to eq 'https://foo.com/article'
+        expect(subject.canonical_url).to eq original_url
       end
     end
 
     context 'when canonical URL is set to "null"' do
-      let(:html) { '' }
+      let(:url) { 'null' }
 
       it 'ignores the canonical URLs' do
         expect(subject.canonical_url).to eq original_url
@@ -35,124 +35,257 @@ RSpec.describe LinkDetailsExtractor do
     end
   end
 
+  context 'when only basic metadata is present' do
+    let(:html) { <<~HTML }
+      
+      
+      
+        Man bites dog
+        
+      
+      
+    HTML
+
+    describe '#title' do
+      it 'returns the title from title tag' do
+        expect(subject.title).to eq 'Man bites dog'
+      end
+    end
+
+    describe '#description' do
+      it 'returns the description from meta tag' do
+        expect(subject.description).to eq "A dog's tale"
+      end
+    end
+
+    describe '#language' do
+      it 'returns the language from lang attribute' do
+        expect(subject.language).to eq 'en'
+      end
+    end
+  end
+
   context 'when structured data is present' do
-    let(:original_url) { 'https://example.com/page.html' }
-
-    context 'and is wrapped in CDATA tags' do
-      let(:html) { <<-HTML }
-
-
-
-  
-
-
-      HTML
+    let(:ld_json) do
+      {
+        '@context' => 'https://schema.org',
+        '@type' => 'NewsArticle',
+        'headline' => 'Man bites dog',
+        'description' => "A dog's tale",
+        'datePublished' => '2022-01-31T19:53:00+00:00',
+        'author' => {
+          '@type' => 'Organization',
+          'name' => 'Charlie Brown',
+        },
+        'publisher' => {
+          '@type' => 'NewsMediaOrganization',
+          'name' => 'Pet News',
+          'url' => 'https://example.com',
+        },
+      }.to_json
+    end
 
+    shared_examples 'structured data' do
       describe '#title' do
         it 'returns the title from structured data' do
-          expect(subject.title).to eq 'Foo'
+          expect(subject.title).to eq 'Man bites dog'
         end
       end
 
       describe '#description' do
         it 'returns the description from structured data' do
-          expect(subject.description).to eq 'Bar'
+          expect(subject.description).to eq "A dog's tale"
         end
       end
 
-      describe '#provider_name' do
-        it 'returns the provider name from structured data' do
-          expect(subject.provider_name).to eq 'Baz'
+      describe '#published_at' do
+        it 'returns the publicaton time from structured data' do
+          expect(subject.published_at).to eq '2022-01-31T19:53:00+00:00'
         end
       end
 
       describe '#author_name' do
         it 'returns the author name from structured data' do
-          expect(subject.author_name).to eq 'Hoge'
+          expect(subject.author_name).to eq 'Charlie Brown'
+        end
+      end
+
+      describe '#provider_name' do
+        it 'returns the provider name from structured data' do
+          expect(subject.provider_name).to eq 'Pet News'
         end
       end
     end
 
-    context 'but the first tag is invalid JSON' do
-      let(:html) { <<-HTML }
-
-
-
-  
-  
-
-
+    context 'when is wrapped in CDATA tags' do
+      let(:html) { <<~HTML }
+        
+        
+          
+            
+          
+        
       HTML
 
-      describe '#title' do
-        it 'returns the title from structured data' do
-          expect(subject.title).to eq 'Foo'
-        end
-      end
+      include_examples 'structured data'
+    end
 
-      describe '#description' do
-        it 'returns the description from structured data' do
-          expect(subject.description).to eq 'Bar'
-        end
-      end
+    context 'with the first tag is invalid JSON' do
+      let(:html) { <<~HTML }
+        
+        
+        
+          
+          
+        
+        
+      HTML
 
-      describe '#provider_name' do
-        it 'returns the provider name from structured data' do
-          expect(subject.provider_name).to eq 'Baz'
-        end
-      end
+      include_examples 'structured data'
+    end
 
-      describe '#author_name' do
-        it 'returns the author name from structured data' do
-          expect(subject.author_name).to eq 'Hoge'
-        end
+    context 'with preceding block of unsupported LD+JSON' do
+      let(:html) { <<~HTML }
+        
+        
+        
+          
+          
+        
+        
+      HTML
+
+      include_examples 'structured data'
+    end
+
+    context 'with unsupported in same block LD+JSON' do
+      let(:html) { <<~HTML }
+        
+        
+        
+          
+        
+        
+      HTML
+
+      include_examples 'structured data'
+    end
+  end
+
+  context 'when Open Graph protocol data is present' do
+    let(:html) { <<~HTML }
+      
+      
+      
+        
+        
+        
+        
+        
+        
+        
+        
+        
+      
+      
+    HTML
+
+    describe '#canonical_url' do
+      it 'returns the URL from Open Graph protocol data' do
+        expect(subject.canonical_url).to eq 'https://example.com/dog.html'
+      end
+    end
+
+    describe '#title' do
+      it 'returns the title from Open Graph protocol data' do
+        expect(subject.title).to eq 'Man bites dog'
+      end
+    end
+
+    describe '#description' do
+      it 'returns the description from Open Graph protocol data' do
+        expect(subject.description).to eq "A dog's tale"
+      end
+    end
+
+    describe '#published_at' do
+      it 'returns the publicaton time from Open Graph protocol data' do
+        expect(subject.published_at).to eq '2022-01-31T19:53:00+00:00'
+      end
+    end
+
+    describe '#author_name' do
+      it 'returns the author name from Open Graph protocol data' do
+        expect(subject.author_name).to eq 'Charlie Brown'
+      end
+    end
+
+    describe '#language' do
+      it 'returns the language from Open Graph protocol data' do
+        expect(subject.language).to eq 'en'
+      end
+    end
+
+    describe '#image' do
+      it 'returns the image from Open Graph protocol data' do
+        expect(subject.image).to eq 'https://example.com/snoopy.jpg'
+      end
+    end
+
+    describe '#image:alt' do
+      it 'returns the image description from Open Graph protocol data' do
+        expect(subject.image_alt).to eq 'A good boy'
+      end
+    end
+
+    describe '#provider_name' do
+      it 'returns the provider name from Open Graph protocol data' do
+        expect(subject.provider_name).to eq 'Pet News'
       end
     end
   end
diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb
new file mode 100644
index 0000000000..a263d673de
--- /dev/null
+++ b/spec/lib/mastodon/cli/accounts_spec.rb
@@ -0,0 +1,1364 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/accounts'
+
+describe Mastodon::CLI::Accounts do
+  let(:cli) { described_class.new }
+
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe '#create' do
+    shared_examples 'a new user with given email address and username' do
+      it 'creates a new user with the specified email address' do
+        cli.invoke(:create, arguments, options)
+
+        expect(User.find_by(email: options[:email])).to be_present
+      end
+
+      it 'creates a new local account with the specified username' do
+        cli.invoke(:create, arguments, options)
+
+        expect(Account.find_local('tootctl_username')).to be_present
+      end
+
+      it 'returns "OK" and newly generated password' do
+        allow(SecureRandom).to receive(:hex).and_return('test_password')
+
+        expect { cli.invoke(:create, arguments, options) }.to output(
+          a_string_including("OK\nNew password: test_password")
+        ).to_stdout
+      end
+    end
+
+    context 'when required USERNAME and --email are provided' do
+      let(:arguments) { ['tootctl_username'] }
+
+      context 'with USERNAME and --email only' do
+        let(:options) { { email: 'tootctl@example.com' } }
+
+        it_behaves_like 'a new user with given email address and username'
+
+        context 'with invalid --email value' do
+          let(:options) { { email: 'invalid' } }
+
+          it 'exits with an error message' do
+            expect { cli.invoke(:create, arguments, options) }.to output(
+              a_string_including('Failure/Error: email')
+            ).to_stdout
+              .and raise_error(SystemExit)
+          end
+        end
+      end
+
+      context 'with --confirmed option' do
+        let(:options) { { email: 'tootctl@example.com', confirmed: true } }
+
+        it_behaves_like 'a new user with given email address and username'
+
+        it 'creates a new user with confirmed status' do
+          cli.invoke(:create, arguments, options)
+
+          user = User.find_by(email: options[:email])
+
+          expect(user.confirmed?).to be(true)
+        end
+      end
+
+      context 'with --approve option' do
+        let(:options) { { email: 'tootctl@example.com', approve: true } }
+
+        before do
+          Form::AdminSettings.new(registrations_mode: 'approved').save
+        end
+
+        it_behaves_like 'a new user with given email address and username'
+
+        it 'creates a new user with approved status' do
+          cli.invoke(:create, arguments, options)
+
+          user = User.find_by(email: options[:email])
+
+          expect(user.approved?).to be(true)
+        end
+      end
+
+      context 'with --role option' do
+        context 'when role exists' do
+          let(:default_role) { Fabricate(:user_role) }
+          let(:options) { { email: 'tootctl@example.com', role: default_role.name } }
+
+          it_behaves_like 'a new user with given email address and username'
+
+          it 'creates a new user and assigns the specified role' do
+            cli.invoke(:create, arguments, options)
+
+            role = User.find_by(email: options[:email])&.role
+
+            expect(role.name).to eq(default_role.name)
+          end
+        end
+
+        context 'when role does not exist' do
+          let(:options) { { email: 'tootctl@example.com', role: '404' } }
+
+          it 'exits with an error message indicating the role name was not found' do
+            expect { cli.invoke(:create, arguments, options) }.to output(
+              a_string_including('Cannot find user role with that name')
+            ).to_stdout
+              .and raise_error(SystemExit)
+          end
+        end
+      end
+
+      context 'with --reattach option' do
+        context "when account's user is present" do
+          let(:options) { { email: 'tootctl_new@example.com', reattach: true } }
+          let(:user) { Fabricate.build(:user, email: 'tootctl@example.com') }
+
+          before do
+            Fabricate(:account, username: 'tootctl_username', user: user)
+          end
+
+          it 'returns an error message indicating the username is already taken' do
+            expect { cli.invoke(:create, arguments, options) }.to output(
+              a_string_including("The chosen username is currently in use\nUse --force to reattach it anyway and delete the other user")
+            ).to_stdout
+          end
+
+          context 'with --force option' do
+            let(:options) { { email: 'tootctl_new@example.com', reattach: true, force: true } }
+
+            it 'reattaches the account to the new user and deletes the previous user' do
+              cli.invoke(:create, arguments, options)
+
+              user = Account.find_local('tootctl_username')&.user
+
+              expect(user.email).to eq(options[:email])
+            end
+          end
+        end
+
+        context "when account's user is not present" do
+          let(:options) { { email: 'tootctl@example.com', reattach: true } }
+
+          before do
+            Fabricate(:account, username: 'tootctl_username', user: nil)
+          end
+
+          it_behaves_like 'a new user with given email address and username'
+        end
+      end
+    end
+
+    context 'when required --email option is not provided' do
+      let(:arguments) { ['tootctl_username'] }
+
+      it 'raises a required argument missing error (Thor::RequiredArgumentMissingError)' do
+        expect { cli.invoke(:create, arguments) }
+          .to raise_error(Thor::RequiredArgumentMissingError)
+      end
+    end
+  end
+
+  describe '#modify' do
+    context 'when the given username is not found' do
+      let(:arguments) { ['non_existent_username'] }
+
+      it 'exits with an error message indicating the user was not found' do
+        expect { cli.invoke(:modify, arguments) }.to output(
+          a_string_including('No user with such username')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when the given username is found' do
+      let(:user) { Fabricate(:user) }
+      let(:arguments) { [user.account.username] }
+
+      context 'when no option is provided' do
+        it 'returns a successful message' do
+          expect { cli.invoke(:modify, arguments) }.to output(
+            a_string_including('OK')
+          ).to_stdout
+        end
+
+        it 'does not modify the user' do
+          cli.invoke(:modify, arguments)
+
+          expect(user).to eq(user.reload)
+        end
+      end
+
+      context 'with --role option' do
+        context 'when the given role is not found' do
+          let(:options) { { role: '404' } }
+
+          it 'exits with an error message indicating the role was not found' do
+            expect { cli.invoke(:modify, arguments, options) }.to output(
+              a_string_including('Cannot find user role with that name')
+            ).to_stdout
+              .and raise_error(SystemExit)
+          end
+        end
+
+        context 'when the given role is found' do
+          let(:default_role) { Fabricate(:user_role) }
+          let(:options) { { role: default_role.name } }
+
+          it "updates the user's role to the specified role" do
+            cli.invoke(:modify, arguments, options)
+
+            role = user.reload.role
+
+            expect(role.name).to eq(default_role.name)
+          end
+        end
+      end
+
+      context 'with --remove-role option' do
+        let(:options) { { remove_role: true } }
+        let(:role) { Fabricate(:user_role) }
+        let(:user) { Fabricate(:user, role: role) }
+
+        it "removes the user's role successfully" do
+          cli.invoke(:modify, arguments, options)
+
+          role = user.reload.role
+
+          expect(role.name).to be_empty
+        end
+      end
+
+      context 'with --email option' do
+        let(:user) { Fabricate(:user, email: 'old_email@email.com') }
+        let(:options) { { email: 'new_email@email.com' } }
+
+        it "sets the user's unconfirmed email to the provided email address" do
+          cli.invoke(:modify, arguments, options)
+
+          expect(user.reload.unconfirmed_email).to eq(options[:email])
+        end
+
+        it "does not update the user's original email address" do
+          cli.invoke(:modify, arguments, options)
+
+          expect(user.reload.email).to eq('old_email@email.com')
+        end
+
+        context 'with --confirm option' do
+          let(:user) { Fabricate(:user, email: 'old_email@email.com', confirmed_at: nil) }
+          let(:options) { { email: 'new_email@email.com', confirm: true } }
+
+          it "updates the user's email address to the provided email" do
+            cli.invoke(:modify, arguments, options)
+
+            expect(user.reload.email).to eq(options[:email])
+          end
+
+          it "sets the user's email address as confirmed" do
+            cli.invoke(:modify, arguments, options)
+
+            expect(user.reload.confirmed?).to be(true)
+          end
+        end
+      end
+
+      context 'with --confirm option' do
+        let(:user) { Fabricate(:user, confirmed_at: nil) }
+        let(:options) { { confirm: true } }
+
+        it "confirms the user's email address" do
+          cli.invoke(:modify, arguments, options)
+
+          expect(user.reload.confirmed?).to be(true)
+        end
+      end
+
+      context 'with --approve option' do
+        let(:user) { Fabricate(:user, approved: false) }
+        let(:options) { { approve: true } }
+
+        before do
+          Form::AdminSettings.new(registrations_mode: 'approved').save
+        end
+
+        it 'approves the user' do
+          expect { cli.invoke(:modify, arguments, options) }.to change { user.reload.approved }.from(false).to(true)
+        end
+      end
+
+      context 'with --disable option' do
+        let(:user) { Fabricate(:user, disabled: false) }
+        let(:options) { { disable: true } }
+
+        it 'disables the user' do
+          expect { cli.invoke(:modify, arguments, options) }.to change { user.reload.disabled }.from(false).to(true)
+        end
+      end
+
+      context 'with --enable option' do
+        let(:user) { Fabricate(:user, disabled: true) }
+        let(:options) { { enable: true } }
+
+        it 'enables the user' do
+          expect { cli.invoke(:modify, arguments, options) }.to change { user.reload.disabled }.from(true).to(false)
+        end
+      end
+
+      context 'with --reset-password option' do
+        let(:options) { { reset_password: true } }
+
+        it 'returns a new password for the user' do
+          allow(SecureRandom).to receive(:hex).and_return('new_password')
+
+          expect { cli.invoke(:modify, arguments, options) }.to output(
+            a_string_including('new_password')
+          ).to_stdout
+        end
+      end
+
+      context 'with --disable-2fa option' do
+        let(:user) { Fabricate(:user, otp_required_for_login: true) }
+        let(:options) { { disable_2fa: true } }
+
+        it 'disables the two-factor authentication for the user' do
+          expect { cli.invoke(:modify, arguments, options) }.to change { user.reload.otp_required_for_login }.from(true).to(false)
+        end
+      end
+
+      context 'when provided data is invalid' do
+        let(:user) { Fabricate(:user) }
+        let(:options) { { email: 'invalid' } }
+
+        it 'exits with an error message' do
+          expect { cli.invoke(:modify, arguments, options) }.to output(
+            a_string_including('Failure/Error: email')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+    end
+  end
+
+  describe '#delete' do
+    let(:account) { Fabricate(:account) }
+    let(:arguments) { [account.username] }
+    let(:options) { { email: account.user.email } }
+    let(:delete_account_service) { instance_double(DeleteAccountService) }
+
+    before do
+      allow(DeleteAccountService).to receive(:new).and_return(delete_account_service)
+      allow(delete_account_service).to receive(:call)
+    end
+
+    context 'when both username and --email are provided' do
+      it 'exits with an error message indicating that only one should be used' do
+        expect { cli.invoke(:delete, arguments, options) }.to output(
+          a_string_including('Use username or --email, not both')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when neither username nor --email are provided' do
+      it 'exits with an error message indicating that no username was provided' do
+        expect { cli.invoke(:delete) }.to output(
+          a_string_including('No username provided')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when username is provided' do
+      it 'deletes the specified user successfully' do
+        cli.invoke(:delete, arguments)
+
+        expect(delete_account_service).to have_received(:call).with(account, reserve_email: false).once
+      end
+
+      context 'with --dry-run option' do
+        let(:options) { { dry_run: true } }
+
+        it 'does not delete the specified user' do
+          cli.invoke(:delete, arguments, options)
+
+          expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false)
+        end
+
+        it 'outputs a successful message in dry run mode' do
+          expect { cli.invoke(:delete, arguments, options) }.to output(
+            a_string_including('OK (DRY RUN)')
+          ).to_stdout
+        end
+      end
+
+      context 'when the given username is not found' do
+        let(:arguments) { ['non_existent_username'] }
+
+        it 'exits with an error message indicating that no user was found' do
+          expect { cli.invoke(:delete, arguments) }.to output(
+            a_string_including('No user with such username')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+    end
+
+    context 'when --email is provided' do
+      it 'deletes the specified user successfully' do
+        cli.invoke(:delete, nil, options)
+
+        expect(delete_account_service).to have_received(:call).with(account, reserve_email: false).once
+      end
+
+      context 'with --dry-run option' do
+        let(:options) { { email: account.user.email, dry_run: true } }
+
+        it 'does not delete the user' do
+          cli.invoke(:delete, nil, options)
+
+          expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false)
+        end
+
+        it 'outputs a successful message in dry run mode' do
+          expect { cli.invoke(:delete, nil, options) }.to output(
+            a_string_including('OK (DRY RUN)')
+          ).to_stdout
+        end
+      end
+
+      context 'when the given email address is not found' do
+        let(:options) { { email: '404@example.com' } }
+
+        it 'exits with an error message indicating that no user was found' do
+          expect { cli.invoke(:delete, nil, options) }.to output(
+            a_string_including('No user with such email')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+    end
+  end
+
+  describe '#approve' do
+    let(:total_users) { 10 }
+
+    before do
+      Form::AdminSettings.new(registrations_mode: 'approved').save
+      Fabricate.times(total_users, :user)
+    end
+
+    context 'with --all option' do
+      it 'approves all pending registrations' do
+        cli.invoke(:approve, nil, all: true)
+
+        expect(User.pluck(:approved).all?(true)).to be(true)
+      end
+    end
+
+    context 'with --number option' do
+      context 'when the number is positive' do
+        let(:options) { { number: 3 } }
+
+        it 'approves the earliest n pending registrations' do
+          cli.invoke(:approve, nil, options)
+
+          n_earliest_pending_registrations = User.order(created_at: :asc).first(options[:number])
+
+          expect(n_earliest_pending_registrations.all?(&:approved?)).to be(true)
+        end
+
+        it 'does not approve the remaining pending registrations' do
+          cli.invoke(:approve, nil, options)
+
+          pending_registrations = User.order(created_at: :asc).last(total_users - options[:number])
+
+          expect(pending_registrations.all?(&:approved?)).to be(false)
+        end
+      end
+
+      context 'when the number is negative' do
+        it 'exits with an error message indicating that the number must be positive' do
+          expect { cli.invoke(:approve, nil, number: -1) }.to output(
+            a_string_including('Number must be positive')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+
+      context 'when the given number is greater than the number of users' do
+        let(:options) { { number: total_users * 2 } }
+
+        it 'approves all users' do
+          cli.invoke(:approve, nil, options)
+
+          expect(User.pluck(:approved).all?(true)).to be(true)
+        end
+
+        it 'does not raise any error' do
+          expect { cli.invoke(:approve, nil, options) }
+            .to_not raise_error
+        end
+      end
+    end
+
+    context 'with username argument' do
+      context 'when the given username is found' do
+        let(:user) { User.last }
+        let(:arguments) { [user.account.username] }
+
+        it 'approves the specified user successfully' do
+          cli.invoke(:approve, arguments)
+
+          expect(user.reload.approved?).to be(true)
+        end
+      end
+
+      context 'when the given username is not found' do
+        let(:arguments) { ['non_existent_username'] }
+
+        it 'exits with an error message indicating that no such account was found' do
+          expect { cli.invoke(:approve, arguments) }.to output(
+            a_string_including('No such account')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+    end
+  end
+
+  describe '#follow' do
+    context 'when the given username is not found' do
+      let(:arguments) { ['non_existent_username'] }
+
+      it 'exits with an error message indicating that no account with the given username was found' do
+        expect { cli.invoke(:follow, arguments) }.to output(
+          a_string_including('No such account')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when the given username is found' do
+      let!(:target_account)   { Fabricate(:account) }
+      let!(:follower_bob)     { Fabricate(:account, username: 'bob') }
+      let!(:follower_rony)    { Fabricate(:account, username: 'rony') }
+      let!(:follower_charles) { Fabricate(:account, username: 'charles') }
+      let(:follow_service)    { instance_double(FollowService, call: nil) }
+      let(:scope)             { Account.local.without_suspended }
+
+      before do
+        allow(cli).to receive(:parallelize_with_progress).and_yield(follower_bob)
+                                                         .and_yield(follower_rony)
+                                                         .and_yield(follower_charles)
+                                                         .and_return([3, nil])
+        allow(FollowService).to receive(:new).and_return(follow_service)
+      end
+
+      it 'makes all local accounts follow the target account' do
+        cli.follow(target_account.username)
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(follow_service).to have_received(:call).with(follower_bob, target_account, any_args).once
+        expect(follow_service).to have_received(:call).with(follower_rony, target_account, any_args).once
+        expect(follow_service).to have_received(:call).with(follower_charles, target_account, any_args).once
+      end
+
+      it 'displays a successful message' do
+        expect { cli.follow(target_account.username) }.to output(
+          a_string_including('OK, followed target from 3 accounts')
+        ).to_stdout
+      end
+    end
+  end
+
+  describe '#unfollow' do
+    context 'when the given username is not found' do
+      let(:arguments) { ['non_existent_username'] }
+
+      it 'exits with an error message indicating that no account with the given username was found' do
+        expect { cli.invoke(:unfollow, arguments) }.to output(
+          a_string_including('No such account')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when the given username is found' do
+      let!(:target_account)  { Fabricate(:account) }
+      let!(:follower_chris)  { Fabricate(:account, username: 'chris') }
+      let!(:follower_rambo)  { Fabricate(:account, username: 'rambo') }
+      let!(:follower_ana)    { Fabricate(:account, username: 'ana') }
+      let(:unfollow_service) { instance_double(UnfollowService, call: nil) }
+      let(:scope)            { target_account.followers.local }
+
+      before do
+        accounts = [follower_chris, follower_rambo, follower_ana]
+        accounts.each { |account| target_account.follow!(account) }
+        allow(cli).to receive(:parallelize_with_progress).and_yield(follower_chris)
+                                                         .and_yield(follower_rambo)
+                                                         .and_yield(follower_ana)
+                                                         .and_return([3, nil])
+        allow(UnfollowService).to receive(:new).and_return(unfollow_service)
+      end
+
+      it 'makes all local accounts unfollow the target account' do
+        cli.unfollow(target_account.username)
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(unfollow_service).to have_received(:call).with(follower_chris, target_account).once
+        expect(unfollow_service).to have_received(:call).with(follower_rambo, target_account).once
+        expect(unfollow_service).to have_received(:call).with(follower_ana, target_account).once
+      end
+
+      it 'displays a successful message' do
+        expect { cli.unfollow(target_account.username) }.to output(
+          a_string_including('OK, unfollowed target from 3 accounts')
+        ).to_stdout
+      end
+    end
+  end
+
+  describe '#backup' do
+    context 'when the given username is not found' do
+      let(:arguments) { ['non_existent_username'] }
+
+      it 'exits with an error message indicating that there is no such account' do
+        expect { cli.invoke(:backup, arguments) }.to output(
+          a_string_including('No user with such username')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when the given username is found' do
+      let(:account) { Fabricate(:account) }
+      let(:user) { account.user }
+      let(:arguments) { [account.username] }
+
+      it 'creates a new backup for the specified user' do
+        expect { cli.invoke(:backup, arguments) }.to change { user.backups.count }.by(1)
+      end
+
+      it 'creates a backup job' do
+        allow(BackupWorker).to receive(:perform_async)
+
+        cli.invoke(:backup, arguments)
+        latest_backup = user.backups.last
+
+        expect(BackupWorker).to have_received(:perform_async).with(latest_backup.id).once
+      end
+
+      it 'displays a successful message' do
+        expect { cli.invoke(:backup, arguments) }.to output(
+          a_string_including('OK')
+        ).to_stdout
+      end
+    end
+  end
+
+  describe '#refresh' do
+    context 'with --all option' do
+      let!(:local_account)              { Fabricate(:account, domain: nil) }
+      let!(:remote_account_example_com) { Fabricate(:account, domain: 'example.com') }
+      let!(:account_example_net)        { Fabricate(:account, domain: 'example.net') }
+      let(:scope)                       { Account.remote }
+
+      before do
+        allow(cli).to receive(:parallelize_with_progress).and_yield(remote_account_example_com)
+                                                         .and_yield(account_example_net)
+                                                         .and_return([2, nil])
+        cli.options = { all: true }
+      end
+
+      it 'refreshes the avatar for all remote accounts' do
+        allow(remote_account_example_com).to receive(:reset_avatar!)
+        allow(account_example_net).to receive(:reset_avatar!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(remote_account_example_com).to have_received(:reset_avatar!).once
+        expect(account_example_net).to have_received(:reset_avatar!).once
+      end
+
+      it 'does not refresh avatar for local accounts' do
+        allow(local_account).to receive(:reset_avatar!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(local_account).to_not have_received(:reset_avatar!)
+      end
+
+      it 'refreshes the header for all remote accounts' do
+        allow(remote_account_example_com).to receive(:reset_header!)
+        allow(account_example_net).to receive(:reset_header!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(remote_account_example_com).to have_received(:reset_header!).once
+        expect(account_example_net).to have_received(:reset_header!).once
+      end
+
+      it 'does not refresh the header for local accounts' do
+        allow(local_account).to receive(:reset_header!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(local_account).to_not have_received(:reset_header!)
+      end
+
+      it 'displays a successful message' do
+        expect { cli.refresh }.to output(
+          a_string_including('Refreshed 2 accounts')
+        ).to_stdout
+      end
+
+      context 'with --dry-run option' do
+        before do
+          cli.options = { all: true, dry_run: true }
+        end
+
+        it 'does not refresh the avatar for any account' do
+          allow(local_account).to receive(:reset_avatar!)
+          allow(remote_account_example_com).to receive(:reset_avatar!)
+          allow(account_example_net).to receive(:reset_avatar!)
+
+          cli.refresh
+
+          expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+          expect(local_account).to_not have_received(:reset_avatar!)
+          expect(remote_account_example_com).to_not have_received(:reset_avatar!)
+          expect(account_example_net).to_not have_received(:reset_avatar!)
+        end
+
+        it 'does not refresh the header for any account' do
+          allow(local_account).to receive(:reset_header!)
+          allow(remote_account_example_com).to receive(:reset_header!)
+          allow(account_example_net).to receive(:reset_header!)
+
+          cli.refresh
+
+          expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+          expect(local_account).to_not have_received(:reset_header!)
+          expect(remote_account_example_com).to_not have_received(:reset_header!)
+          expect(account_example_net).to_not have_received(:reset_header!)
+        end
+
+        it 'displays a successful message with (DRY RUN)' do
+          expect { cli.refresh }.to output(
+            a_string_including('Refreshed 2 accounts (DRY RUN)')
+          ).to_stdout
+        end
+      end
+    end
+
+    context 'with a list of accts' do
+      let!(:account_example_com_a) { Fabricate(:account, domain: 'example.com') }
+      let!(:account_example_com_b) { Fabricate(:account, domain: 'example.com') }
+      let!(:account_example_net)   { Fabricate(:account, domain: 'example.net') }
+      let(:arguments)              { [account_example_com_a.acct, account_example_com_b.acct] }
+
+      before do
+        allow(Account).to receive(:find_remote).with(account_example_com_a.username, account_example_com_a.domain).and_return(account_example_com_a)
+        allow(Account).to receive(:find_remote).with(account_example_com_b.username, account_example_com_b.domain).and_return(account_example_com_b)
+        allow(Account).to receive(:find_remote).with(account_example_net.username, account_example_net.domain).and_return(account_example_net)
+      end
+
+      it 'resets the avatar for the specified accounts' do
+        allow(account_example_com_a).to receive(:reset_avatar!)
+        allow(account_example_com_b).to receive(:reset_avatar!)
+
+        cli.refresh(*arguments)
+
+        expect(account_example_com_a).to have_received(:reset_avatar!).once
+        expect(account_example_com_b).to have_received(:reset_avatar!).once
+      end
+
+      it 'does not reset the avatar for unspecified accounts' do
+        allow(account_example_net).to receive(:reset_avatar!)
+
+        cli.refresh(*arguments)
+
+        expect(account_example_net).to_not have_received(:reset_avatar!)
+      end
+
+      it 'resets the header for the specified accounts' do
+        allow(account_example_com_a).to receive(:reset_header!)
+        allow(account_example_com_b).to receive(:reset_header!)
+
+        cli.refresh(*arguments)
+
+        expect(account_example_com_a).to have_received(:reset_header!).once
+        expect(account_example_com_b).to have_received(:reset_header!).once
+      end
+
+      it 'does not reset the header for unspecified accounts' do
+        allow(account_example_net).to receive(:reset_header!)
+
+        cli.refresh(*arguments)
+
+        expect(account_example_net).to_not have_received(:reset_header!)
+      end
+
+      context 'when an UnexpectedResponseError is raised' do
+        it 'displays a failure message' do
+          allow(account_example_com_a).to receive(:reset_avatar!).and_raise(Mastodon::UnexpectedResponseError)
+
+          expect { cli.refresh(*arguments) }
+            .to output(
+              a_string_including("Account failed: #{account_example_com_a.username}@#{account_example_com_a.domain}")
+            ).to_stdout
+        end
+      end
+
+      context 'when a specified account is not found' do
+        it 'exits with an error message' do
+          allow(Account).to receive(:find_remote).with(account_example_com_b.username, account_example_com_b.domain).and_return(nil)
+
+          expect { cli.refresh(*arguments) }.to output(
+            a_string_including('No such account')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+
+      context 'with --dry-run option' do
+        before do
+          cli.options = { dry_run: true }
+        end
+
+        it 'does not refresh the avatar for any account' do
+          allow(account_example_com_a).to receive(:reset_avatar!)
+          allow(account_example_com_b).to receive(:reset_avatar!)
+
+          cli.refresh(*arguments)
+
+          expect(account_example_com_a).to_not have_received(:reset_avatar!)
+          expect(account_example_com_b).to_not have_received(:reset_avatar!)
+        end
+
+        it 'does not refresh the header for any account' do
+          allow(account_example_com_a).to receive(:reset_header!)
+          allow(account_example_com_b).to receive(:reset_header!)
+
+          cli.refresh(*arguments)
+
+          expect(account_example_com_a).to_not have_received(:reset_header!)
+          expect(account_example_com_b).to_not have_received(:reset_header!)
+        end
+      end
+    end
+
+    context 'with --domain option' do
+      let!(:account_example_com_a) { Fabricate(:account, domain: 'example.com') }
+      let!(:account_example_com_b) { Fabricate(:account, domain: 'example.com') }
+      let!(:account_example_net)   { Fabricate(:account, domain: 'example.net') }
+      let(:domain)                 { 'example.com' }
+      let(:scope)                  { Account.remote.where(domain: domain) }
+
+      before do
+        allow(cli).to receive(:parallelize_with_progress).and_yield(account_example_com_a)
+                                                         .and_yield(account_example_com_b)
+                                                         .and_return([2, nil])
+
+        cli.options = { domain: domain }
+      end
+
+      it 'refreshes the avatar for all accounts on specified domain' do
+        allow(account_example_com_a).to receive(:reset_avatar!)
+        allow(account_example_com_b).to receive(:reset_avatar!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(account_example_com_a).to have_received(:reset_avatar!).once
+        expect(account_example_com_b).to have_received(:reset_avatar!).once
+      end
+
+      it 'does not refresh the avatar for accounts outside specified domain' do
+        allow(account_example_net).to receive(:reset_avatar!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(account_example_net).to_not have_received(:reset_avatar!)
+      end
+
+      it 'refreshes the header for all accounts on specified domain' do
+        allow(account_example_com_a).to receive(:reset_header!)
+        allow(account_example_com_b).to receive(:reset_header!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope)
+        expect(account_example_com_a).to have_received(:reset_header!).once
+        expect(account_example_com_b).to have_received(:reset_header!).once
+      end
+
+      it 'does not refresh the header for accounts outside specified domain' do
+        allow(account_example_net).to receive(:reset_header!)
+
+        cli.refresh
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(account_example_net).to_not have_received(:reset_header!)
+      end
+    end
+
+    context 'when neither a list of accts nor options are provided' do
+      it 'exits with an error message' do
+        expect { cli.refresh }.to output(
+          a_string_including('No account(s) given')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+  end
+
+  describe '#rotate' do
+    context 'when neither username nor --all option are given' do
+      it 'exits with an error message' do
+        expect { cli.rotate }.to output(
+          a_string_including('No account(s) given')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when a username is given' do
+      let(:account) { Fabricate(:account) }
+
+      it 'correctly rotates keys for the specified account' do
+        old_private_key = account.private_key
+        old_public_key = account.public_key
+
+        cli.rotate(account.username)
+        account.reload
+
+        expect(account.private_key).to_not eq(old_private_key)
+        expect(account.public_key).to_not eq(old_public_key)
+      end
+
+      it 'broadcasts the new keys for the specified account' do
+        allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_in)
+
+        cli.rotate(account.username)
+
+        expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once
+      end
+
+      context 'when the given username is not found' do
+        it 'exits with an error message when the specified username is not found' do
+          expect { cli.rotate('non_existent_username') }.to output(
+            a_string_including('No such account')
+          ).to_stdout
+            .and raise_error(SystemExit)
+        end
+      end
+    end
+
+    context 'when --all option is provided' do
+      let(:accounts) { Fabricate.times(3, :account) }
+      let(:options)  { { all: true } }
+
+      before do
+        allow(Account).to receive(:local).and_return(Account.where(id: accounts.map(&:id)))
+        cli.options = { all: true }
+      end
+
+      it 'correctly rotates keys for all local accounts' do
+        old_private_keys = accounts.map(&:private_key)
+        old_public_keys = accounts.map(&:public_key)
+
+        cli.rotate
+        accounts.each(&:reload)
+
+        expect(accounts.map(&:private_key)).to_not eq(old_private_keys)
+        expect(accounts.map(&:public_key)).to_not eq(old_public_keys)
+      end
+
+      it 'broadcasts the new keys for each account' do
+        allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_in)
+
+        cli.rotate
+
+        accounts.each do |account|
+          expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once
+        end
+      end
+    end
+  end
+
+  describe '#merge' do
+    shared_examples 'an account not found' do |acct|
+      it 'exits with an error message indicating that there is no such account' do
+        expect { cli.invoke(:merge, arguments) }.to output(
+          a_string_including("No such account (#{acct})")
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when "from_account" is not found' do
+      let(:to_account) { Fabricate(:account, domain: 'example.com') }
+      let(:arguments)  { ['non_existent_username@domain.com', "#{to_account.username}@#{to_account.domain}"] }
+
+      it_behaves_like 'an account not found', 'non_existent_username@domain.com'
+    end
+
+    context 'when "from_account" is a local account' do
+      let(:from_account) { Fabricate(:account, domain: nil, username: 'bob') }
+      let(:to_account)   { Fabricate(:account, domain: 'example.com') }
+      let(:arguments)    { [from_account.username, "#{to_account.username}@#{to_account.domain}"] }
+
+      it_behaves_like 'an account not found', 'bob'
+    end
+
+    context 'when "to_account" is not found' do
+      let(:from_account) { Fabricate(:account, domain: 'example.com') }
+      let(:arguments)    { ["#{from_account.username}@#{from_account.domain}", 'non_existent_username'] }
+
+      it_behaves_like 'an account not found', 'non_existent_username'
+    end
+
+    context 'when "to_account" is local' do
+      let(:from_account) { Fabricate(:account, domain: 'example.com') }
+      let(:to_account)   { Fabricate(:account, domain: nil, username: 'bob') }
+      let(:arguments) do
+        ["#{from_account.username}@#{from_account.domain}", "#{to_account.username}@#{to_account.domain}"]
+      end
+
+      it_behaves_like 'an account not found', 'bob@'
+    end
+
+    context 'when "from_account" and "to_account" public keys do not match' do
+      let(:from_account) { instance_double(Account, username: 'bob', domain: 'example1.com', local?: false, public_key: 'from_account') }
+      let(:to_account)   { instance_double(Account, username: 'bob', domain: 'example2.com', local?: false, public_key: 'to_account') }
+      let(:arguments) do
+        ["#{from_account.username}@#{from_account.domain}", "#{to_account.username}@#{to_account.domain}"]
+      end
+
+      before do
+        allow(Account).to receive(:find_remote).with(from_account.username, from_account.domain).and_return(from_account)
+        allow(Account).to receive(:find_remote).with(to_account.username, to_account.domain).and_return(to_account)
+      end
+
+      it 'exits with an error message indicating that the accounts do not have the same pub key' do
+        expect { cli.invoke(:merge, arguments) }.to output(
+          a_string_including("Accounts don't have the same public key, might not be duplicates!\nOverride with --force")
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+
+      context 'with --force option' do
+        let(:options) { { force: true } }
+
+        before do
+          allow(to_account).to receive(:merge_with!)
+          allow(from_account).to receive(:destroy)
+        end
+
+        it 'merges "from_account" into "to_account"' do
+          cli.invoke(:merge, arguments, options)
+
+          expect(to_account).to have_received(:merge_with!).with(from_account).once
+        end
+
+        it 'deletes "from_account"' do
+          cli.invoke(:merge, arguments, options)
+
+          expect(from_account).to have_received(:destroy).once
+        end
+      end
+    end
+
+    context 'when "from_account" and "to_account" public keys match' do
+      let(:from_account) { instance_double(Account, username: 'bob', domain: 'example1.com', local?: false, public_key: 'pub_key') }
+      let(:to_account)   { instance_double(Account, username: 'bob', domain: 'example2.com', local?: false, public_key: 'pub_key') }
+      let(:arguments) do
+        ["#{from_account.username}@#{from_account.domain}", "#{to_account.username}@#{to_account.domain}"]
+      end
+
+      before do
+        allow(Account).to receive(:find_remote).with(from_account.username, from_account.domain).and_return(from_account)
+        allow(Account).to receive(:find_remote).with(to_account.username, to_account.domain).and_return(to_account)
+        allow(to_account).to receive(:merge_with!)
+        allow(from_account).to receive(:destroy)
+      end
+
+      it 'merges "from_account" into "to_account"' do
+        cli.invoke(:merge, arguments)
+
+        expect(to_account).to have_received(:merge_with!).with(from_account).once
+      end
+
+      it 'deletes "from_account"' do
+        cli.invoke(:merge, arguments)
+
+        expect(from_account).to have_received(:destroy)
+      end
+    end
+  end
+
+  describe '#cull' do
+    let(:delete_account_service) { instance_double(DeleteAccountService, call: nil) }
+    let!(:tom)                   { Fabricate(:account, updated_at: 30.days.ago, username: 'tom', uri: 'https://example.com/users/tom', domain: 'example.com') }
+    let!(:bob)                   { Fabricate(:account, updated_at: 30.days.ago, last_webfingered_at: nil, username: 'bob', uri: 'https://example.org/users/bob', domain: 'example.org') }
+    let!(:gon)                   { Fabricate(:account, updated_at: 15.days.ago, last_webfingered_at: 15.days.ago, username: 'gon', uri: 'https://example.net/users/gon', domain: 'example.net') }
+    let!(:ana)                   { Fabricate(:account, username: 'ana', uri: 'https://example.com/users/ana', domain: 'example.com') }
+    let!(:tales)                 { Fabricate(:account, updated_at: 10.days.ago, last_webfingered_at: nil, username: 'tales', uri: 'https://example.net/users/tales', domain: 'example.net') }
+
+    before do
+      allow(DeleteAccountService).to receive(:new).and_return(delete_account_service)
+    end
+
+    context 'when no domain is specified' do
+      let(:scope) { Account.remote.where(protocol: :activitypub).partitioned }
+
+      before do
+        allow(cli).to receive(:parallelize_with_progress).and_yield(tom)
+                                                         .and_yield(bob)
+                                                         .and_yield(gon)
+                                                         .and_yield(ana)
+                                                         .and_yield(tales)
+                                                         .and_return([5, 3])
+        stub_request(:head, 'https://example.org/users/bob').to_return(status: 404)
+        stub_request(:head, 'https://example.net/users/gon').to_return(status: 410)
+        stub_request(:head, 'https://example.net/users/tales').to_return(status: 200)
+      end
+
+      it 'deletes all inactive remote accounts that longer exist in the origin server' do
+        cli.cull
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(delete_account_service).to have_received(:call).with(bob, reserve_username: false).once
+        expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once
+      end
+
+      it 'does not delete any active remote account that still exists in the origin server' do
+        cli.cull
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(delete_account_service).to_not have_received(:call).with(tom, reserve_username: false)
+        expect(delete_account_service).to_not have_received(:call).with(ana, reserve_username: false)
+        expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false)
+      end
+
+      it 'touches inactive remote accounts that have not been deleted' do
+        allow(tales).to receive(:touch)
+
+        cli.cull
+
+        expect(tales).to have_received(:touch).once
+      end
+
+      it 'displays the summary correctly' do
+        expect { cli.cull }.to output(
+          a_string_including('Visited 5 accounts, removed 3')
+        ).to_stdout
+      end
+    end
+
+    context 'when a domain is specified' do
+      let(:domain) { 'example.net' }
+      let(:scope)  { Account.remote.where(protocol: :activitypub, domain: domain).partitioned }
+
+      before do
+        allow(cli).to receive(:parallelize_with_progress).and_yield(gon)
+                                                         .and_yield(tales)
+                                                         .and_return([2, 2])
+        stub_request(:head, 'https://example.net/users/gon').to_return(status: 410)
+        stub_request(:head, 'https://example.net/users/tales').to_return(status: 404)
+      end
+
+      it 'deletes inactive remote accounts that longer exist in the specified domain' do
+        cli.cull(domain)
+
+        expect(cli).to have_received(:parallelize_with_progress).with(scope).once
+        expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once
+        expect(delete_account_service).to have_received(:call).with(tales, reserve_username: false).once
+      end
+
+      it 'displays the summary correctly' do
+        expect { cli.cull }.to output(
+          a_string_including('Visited 2 accounts, removed 2')
+        ).to_stdout
+      end
+    end
+
+    context 'when a domain is unavailable' do
+      shared_examples 'an unavailable domain' do
+        before do
+          allow(cli).to receive(:parallelize_with_progress).and_yield(tales).and_return([1, 0])
+        end
+
+        it 'skips accounts from the unavailable domain' do
+          cli.cull
+
+          expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false)
+        end
+
+        it 'displays the summary correctly' do
+          expect { cli.cull }.to output(
+            a_string_including("Visited 1 accounts, removed 0\nThe following domains were not available during the check:\n    example.net")
+          ).to_stdout
+        end
+      end
+
+      context 'when a connection timeout occurs' do
+        before do
+          stub_request(:head, 'https://example.net/users/tales').to_timeout
+        end
+
+        it_behaves_like 'an unavailable domain'
+      end
+
+      context 'when a connection error occurs' do
+        before do
+          stub_request(:head, 'https://example.net/users/tales').to_raise(HTTP::ConnectionError)
+        end
+
+        it_behaves_like 'an unavailable domain'
+      end
+
+      context 'when an ssl error occurs' do
+        before do
+          stub_request(:head, 'https://example.net/users/tales').to_raise(OpenSSL::SSL::SSLError)
+        end
+
+        it_behaves_like 'an unavailable domain'
+      end
+
+      context 'when a private network address error occurs' do
+        before do
+          stub_request(:head, 'https://example.net/users/tales').to_raise(Mastodon::PrivateNetworkAddressError)
+        end
+
+        it_behaves_like 'an unavailable domain'
+      end
+    end
+  end
+
+  describe '#reset_relationships' do
+    let(:target_account) { Fabricate(:account) }
+    let(:arguments)      { [target_account.username] }
+
+    context 'when no option is given' do
+      it 'exits with an error message indicating that at least one option is required' do
+        expect { cli.invoke(:reset_relationships, arguments) }.to output(
+          a_string_including('Please specify either --follows or --followers, or both')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when the given username is not found' do
+      let(:arguments) { ['non_existent_username'] }
+
+      it 'exits with an error message indicating that there is no such account' do
+        expect { cli.invoke(:reset_relationships, arguments, follows: true) }.to output(
+          a_string_including('No such account')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+
+    context 'when the given username is found' do
+      let(:total_relationships) { 10 }
+      let!(:accounts)           { Fabricate.times(total_relationships, :account) }
+
+      context 'with --follows option' do
+        let(:options) { { follows: true } }
+
+        before do
+          accounts.each { |account| target_account.follow!(account) }
+        end
+
+        it 'resets all "following" relationships from the target account' do
+          cli.invoke(:reset_relationships, arguments, options)
+
+          expect(target_account.reload.following).to be_empty
+        end
+
+        it 'calls BootstrapTimelineWorker once to rebuild the timeline' do
+          allow(BootstrapTimelineWorker).to receive(:perform_async)
+
+          cli.invoke(:reset_relationships, arguments, options)
+
+          expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once
+        end
+
+        it 'displays a successful message' do
+          expect { cli.invoke(:reset_relationships, arguments, options) }.to output(
+            a_string_including("Processed #{total_relationships} relationships")
+          ).to_stdout
+        end
+      end
+
+      context 'with --followers option' do
+        let(:options) { { followers: true } }
+
+        before do
+          accounts.each { |account| account.follow!(target_account) }
+        end
+
+        it 'resets all "followers" relationships from the target account' do
+          cli.invoke(:reset_relationships, arguments, options)
+
+          expect(target_account.reload.followers).to be_empty
+        end
+
+        it 'displays a successful message' do
+          expect { cli.invoke(:reset_relationships, arguments, options) }.to output(
+            a_string_including("Processed #{total_relationships} relationships")
+          ).to_stdout
+        end
+      end
+
+      context 'with --follows and --followers options' do
+        let(:options) { { followers: true, follows: true } }
+
+        before do
+          accounts.first(6).each { |account| account.follow!(target_account) }
+          accounts.last(4).each  { |account| target_account.follow!(account) }
+        end
+
+        it 'resets all "followers" relationships from the target account' do
+          cli.invoke(:reset_relationships, arguments, options)
+
+          expect(target_account.reload.followers).to be_empty
+        end
+
+        it 'resets all "following" relationships from the target account' do
+          cli.invoke(:reset_relationships, arguments, options)
+
+          expect(target_account.reload.following).to be_empty
+        end
+
+        it 'calls BootstrapTimelineWorker once to rebuild the timeline' do
+          allow(BootstrapTimelineWorker).to receive(:perform_async)
+
+          cli.invoke(:reset_relationships, arguments, options)
+
+          expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once
+        end
+
+        it 'displays a successful message' do
+          expect { cli.invoke(:reset_relationships, arguments, options) }.to output(
+            a_string_including("Processed #{total_relationships} relationships")
+          ).to_stdout
+        end
+      end
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/cache_spec.rb b/spec/lib/mastodon/cli/cache_spec.rb
new file mode 100644
index 0000000000..3ab42dc8ce
--- /dev/null
+++ b/spec/lib/mastodon/cli/cache_spec.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/cache'
+
+describe Mastodon::CLI::Cache do
+  let(:cli) { described_class.new }
+
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe '#clear' do
+    before { allow(Rails.cache).to receive(:clear) }
+
+    it 'clears the Rails cache' do
+      expect { cli.invoke(:clear) }.to output(
+        a_string_including('OK')
+      ).to_stdout
+      expect(Rails.cache).to have_received(:clear)
+    end
+  end
+
+  describe '#recount' do
+    context 'with the `accounts` argument' do
+      let(:arguments) { ['accounts'] }
+      let(:account_stat) { Fabricate(:account_stat) }
+
+      before do
+        account_stat.update(statuses_count: 123)
+      end
+
+      it 're-calculates account records in the cache' do
+        expect { cli.invoke(:recount, arguments) }.to output(
+          a_string_including('OK')
+        ).to_stdout
+
+        expect(account_stat.reload.statuses_count).to be_zero
+      end
+    end
+
+    context 'with the `statuses` argument' do
+      let(:arguments) { ['statuses'] }
+      let(:status_stat) { Fabricate(:status_stat) }
+
+      before do
+        status_stat.update(replies_count: 123)
+      end
+
+      it 're-calculates account records in the cache' do
+        expect { cli.invoke(:recount, arguments) }.to output(
+          a_string_including('OK')
+        ).to_stdout
+
+        expect(status_stat.reload.replies_count).to be_zero
+      end
+    end
+
+    context 'with an unknown type' do
+      let(:arguments) { ['other-type'] }
+
+      it 'Exits with an error message' do
+        expect { cli.invoke(:recount, arguments) }.to output(
+          a_string_including('Unknown')
+        ).to_stdout.and raise_error(SystemExit)
+      end
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb b/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb
new file mode 100644
index 0000000000..eb57a3cd15
--- /dev/null
+++ b/spec/lib/mastodon/cli/canonical_email_blocks_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/canonical_email_blocks'
+
+describe Mastodon::CLI::CanonicalEmailBlocks do
+  let(:cli) { described_class.new }
+
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe '#find' do
+    let(:arguments) { ['user@example.com'] }
+
+    context 'when a block is present' do
+      before { Fabricate(:canonical_email_block, email: 'user@example.com') }
+
+      it 'announces the presence of the block' do
+        expect { cli.invoke(:find, arguments) }.to output(
+          a_string_including('user@example.com is blocked')
+        ).to_stdout
+      end
+    end
+
+    context 'when a block is not present' do
+      it 'announces the absence of the block' do
+        expect { cli.invoke(:find, arguments) }.to output(
+          a_string_including('user@example.com is not blocked')
+        ).to_stdout
+      end
+    end
+  end
+
+  describe '#remove' do
+    let(:arguments) { ['user@example.com'] }
+
+    context 'when a block is present' do
+      before { Fabricate(:canonical_email_block, email: 'user@example.com') }
+
+      it 'removes the block' do
+        expect { cli.invoke(:remove, arguments) }.to output(
+          a_string_including('Unblocked user@example.com')
+        ).to_stdout
+
+        expect(CanonicalEmailBlock.matching_email('user@example.com')).to be_empty
+      end
+    end
+
+    context 'when a block is not present' do
+      it 'announces the absence of the block' do
+        expect { cli.invoke(:remove, arguments) }.to output(
+          a_string_including('user@example.com is not blocked')
+        ).to_stdout
+      end
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/domains_spec.rb b/spec/lib/mastodon/cli/domains_spec.rb
new file mode 100644
index 0000000000..ea58845c00
--- /dev/null
+++ b/spec/lib/mastodon/cli/domains_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/domains'
+
+describe Mastodon::CLI::Domains do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/email_domain_blocks_spec.rb b/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
new file mode 100644
index 0000000000..333ae3f2b7
--- /dev/null
+++ b/spec/lib/mastodon/cli/email_domain_blocks_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/email_domain_blocks'
+
+describe Mastodon::CLI::EmailDomainBlocks do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/emoji_spec.rb b/spec/lib/mastodon/cli/emoji_spec.rb
new file mode 100644
index 0000000000..9b58653729
--- /dev/null
+++ b/spec/lib/mastodon/cli/emoji_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/emoji'
+
+describe Mastodon::CLI::Emoji do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/feeds_spec.rb b/spec/lib/mastodon/cli/feeds_spec.rb
new file mode 100644
index 0000000000..030f087212
--- /dev/null
+++ b/spec/lib/mastodon/cli/feeds_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/feeds'
+
+describe Mastodon::CLI::Feeds do
+  let(:cli) { described_class.new }
+
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe '#build' do
+    before { Fabricate(:account) }
+
+    context 'with --all option' do
+      let(:options) { { all: true } }
+
+      it 'regenerates feeds for all accounts' do
+        expect { cli.invoke(:build, [], options) }.to output(
+          a_string_including('Regenerated feeds')
+        ).to_stdout
+      end
+    end
+
+    context 'with a username' do
+      before { Fabricate(:account, username: 'alice') }
+
+      let(:arguments) { ['alice'] }
+
+      it 'regenerates feeds for the account' do
+        expect { cli.invoke(:build, arguments) }.to output(
+          a_string_including('OK')
+        ).to_stdout
+      end
+    end
+
+    context 'with invalid username' do
+      let(:arguments) { ['invalid-username'] }
+
+      it 'displays an error and exits' do
+        expect { cli.invoke(:build, arguments) }.to output(
+          a_string_including('No such account')
+        ).to_stdout.and raise_error(SystemExit)
+      end
+    end
+  end
+
+  describe '#clear' do
+    before do
+      allow(redis).to receive(:del).with(key_namespace)
+    end
+
+    it 'clears the redis `feed:*` namespace' do
+      expect { cli.invoke(:clear) }.to output(
+        a_string_including('OK')
+      ).to_stdout
+
+      expect(redis).to have_received(:del).with(key_namespace).once
+    end
+
+    def key_namespace
+      redis.keys('feed:*')
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/ip_blocks_spec.rb b/spec/lib/mastodon/cli/ip_blocks_spec.rb
new file mode 100644
index 0000000000..030d9fcb19
--- /dev/null
+++ b/spec/lib/mastodon/cli/ip_blocks_spec.rb
@@ -0,0 +1,298 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/ip_blocks'
+
+describe Mastodon::CLI::IpBlocks do
+  let(:cli) { described_class.new }
+
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe '#add' do
+    let(:ip_list) do
+      [
+        '192.0.2.1',
+        '172.16.0.1',
+        '192.0.2.0/24',
+        '172.16.0.0/16',
+        '10.0.0.0/8',
+        '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
+        'fe80::1',
+        '::1',
+        '2001:0db8::/32',
+        'fe80::/10',
+        '::/128',
+      ]
+    end
+    let(:options) { { severity: 'no_access' } }
+
+    shared_examples 'ip address blocking' do
+      it 'blocks all specified IP addresses' do
+        cli.invoke(:add, ip_list, options)
+
+        blocked_ip_addresses = IpBlock.where(ip: ip_list).pluck(:ip)
+        expected_ip_addresses = ip_list.map { |ip| IPAddr.new(ip) }
+
+        expect(blocked_ip_addresses).to match_array(expected_ip_addresses)
+      end
+
+      it 'sets the severity for all blocked IP addresses' do
+        cli.invoke(:add, ip_list, options)
+
+        blocked_ips_severity = IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity])
+
+        expect(blocked_ips_severity).to be(true)
+      end
+
+      it 'displays a success message with a summary' do
+        expect { cli.invoke(:add, ip_list, options) }.to output(
+          a_string_including("Added #{ip_list.size}, skipped 0, failed 0")
+        ).to_stdout
+      end
+    end
+
+    context 'with valid IP addresses' do
+      include_examples 'ip address blocking'
+    end
+
+    context 'when a specified IP address is already blocked' do
+      let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: options[:severity]) }
+
+      it 'skips the already blocked IP address' do
+        allow(IpBlock).to receive(:new).and_call_original
+
+        cli.invoke(:add, ip_list, options)
+
+        expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last)
+      end
+
+      it 'displays the correct summary' do
+        expect { cli.invoke(:add, ip_list, options) }.to output(
+          a_string_including("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0")
+        ).to_stdout
+      end
+
+      context 'with --force option' do
+        let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: 'no_access') }
+        let(:options) { { severity: 'sign_up_requires_approval', force: true } }
+
+        it 'overwrites the existing IP block record' do
+          expect { cli.invoke(:add, ip_list, options) }
+            .to change { blocked_ip.reload.severity }
+            .from('no_access')
+            .to('sign_up_requires_approval')
+        end
+
+        include_examples 'ip address blocking'
+      end
+    end
+
+    context 'when a specified IP address is invalid' do
+      let(:ip_list) { ['320.15.175.0', '9.5.105.255', '0.0.0.0'] }
+
+      it 'displays the correct summary' do
+        expect { cli.invoke(:add, ip_list, options) }.to output(
+          a_string_including("#{ip_list.first} is invalid\nAdded #{ip_list.size - 1}, skipped 0, failed 1")
+        ).to_stdout
+      end
+    end
+
+    context 'with --comment option' do
+      let(:options) { { severity: 'no_access', comment: 'Spam' } }
+
+      include_examples 'ip address blocking'
+    end
+
+    context 'with --duration option' do
+      let(:options) { { severity: 'no_access', duration: 10.days } }
+
+      include_examples 'ip address blocking'
+    end
+
+    context 'with "sign_up_requires_approval" severity' do
+      let(:options) { { severity: 'sign_up_requires_approval' } }
+
+      include_examples 'ip address blocking'
+    end
+
+    context 'with "sign_up_block" severity' do
+      let(:options) { { severity: 'sign_up_block' } }
+
+      include_examples 'ip address blocking'
+    end
+
+    context 'when a specified IP address fails to be blocked' do
+      let(:ip_address) { '127.0.0.1' }
+      let(:ip_block) { instance_double(IpBlock, ip: ip_address, save: false) }
+
+      before do
+        allow(IpBlock).to receive(:new).and_return(ip_block)
+        allow(ip_block).to receive(:severity=)
+        allow(ip_block).to receive(:expires_in=)
+      end
+
+      it 'displays an error message' do
+        expect { cli.invoke(:add, [ip_address], options) }
+          .to output(
+            a_string_including("#{ip_address} could not be saved")
+          ).to_stdout
+      end
+    end
+
+    context 'when no IP address is provided' do
+      it 'exits with an error message' do
+        expect { cli.add }.to output(
+          a_string_including('No IP(s) given')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+  end
+
+  describe '#remove' do
+    context 'when removing exact matches' do
+      let(:ip_list) do
+        [
+          '192.0.2.1',
+          '172.16.0.1',
+          '192.0.2.0/24',
+          '172.16.0.0/16',
+          '10.0.0.0/8',
+          '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
+          'fe80::1',
+          '::1',
+          '2001:0db8::/32',
+          'fe80::/10',
+          '::/128',
+        ]
+      end
+
+      before do
+        ip_list.each { |ip| IpBlock.create(ip: ip, severity: :no_access) }
+      end
+
+      it 'removes exact IP blocks' do
+        cli.invoke(:remove, ip_list)
+
+        expect(IpBlock.where(ip: ip_list)).to_not exist
+      end
+
+      it 'displays success message with a summary' do
+        expect { cli.invoke(:remove, ip_list) }.to output(
+          a_string_including("Removed #{ip_list.size}, skipped 0")
+        ).to_stdout
+      end
+    end
+
+    context 'with --force option' do
+      let!(:first_ip_range_block) { IpBlock.create(ip: '192.168.0.0/24', severity: :no_access) }
+      let!(:second_ip_range_block) { IpBlock.create(ip: '10.0.0.0/16', severity: :no_access) }
+      let!(:third_ip_range_block) { IpBlock.create(ip: '172.16.0.0/20', severity: :no_access) }
+      let(:arguments) { ['192.168.0.5', '10.0.1.50'] }
+      let(:options) { { force: true } }
+
+      it 'removes blocks for IP ranges that cover given IP(s)' do
+        cli.invoke(:remove, arguments, options)
+
+        expect(IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])).to_not exist
+      end
+
+      it 'does not remove other IP ranges' do
+        cli.invoke(:remove, arguments, options)
+
+        expect(IpBlock.where(id: third_ip_range_block.id)).to exist
+      end
+    end
+
+    context 'when a specified IP address is not blocked' do
+      let(:unblocked_ip) { '192.0.2.1' }
+
+      it 'skips the IP address' do
+        expect { cli.invoke(:remove, [unblocked_ip]) }.to output(
+          a_string_including("#{unblocked_ip} is not yet blocked")
+        ).to_stdout
+      end
+
+      it 'displays the summary correctly' do
+        expect { cli.invoke(:remove, [unblocked_ip]) }.to output(
+          a_string_including('Removed 0, skipped 1')
+        ).to_stdout
+      end
+    end
+
+    context 'when a specified IP address is invalid' do
+      let(:invalid_ip) { '320.15.175.0' }
+
+      it 'skips the invalid IP address' do
+        expect { cli.invoke(:remove, [invalid_ip]) }.to output(
+          a_string_including("#{invalid_ip} is invalid")
+        ).to_stdout
+      end
+
+      it 'displays the summary correctly' do
+        expect { cli.invoke(:remove, [invalid_ip]) }.to output(
+          a_string_including('Removed 0, skipped 1')
+        ).to_stdout
+      end
+    end
+
+    context 'when no IP address is provided' do
+      it 'exits with an error message' do
+        expect { cli.remove }.to output(
+          a_string_including('No IP(s) given')
+        ).to_stdout
+          .and raise_error(SystemExit)
+      end
+    end
+  end
+
+  describe '#export' do
+    let(:first_ip_range_block) { IpBlock.create(ip: '192.168.0.0/24', severity: :no_access) }
+    let(:second_ip_range_block) { IpBlock.create(ip: '10.0.0.0/16', severity: :no_access) }
+    let(:third_ip_range_block) { IpBlock.create(ip: '127.0.0.1', severity: :sign_up_block) }
+
+    context 'when --format option is set to "plain"' do
+      let(:options) { { format: 'plain' } }
+
+      it 'exports blocked IPs with "no_access" severity in plain format' do
+        expect { cli.invoke(:export, nil, options) }.to output(
+          a_string_including("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
+        ).to_stdout
+      end
+
+      it 'does not export bloked IPs with different severities' do
+        expect { cli.invoke(:export, nil, options) }.to_not output(
+          a_string_including("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}")
+        ).to_stdout
+      end
+    end
+
+    context 'when --format option is set to "nginx"' do
+      let(:options) { { format: 'nginx' } }
+
+      it 'exports blocked IPs with "no_access" severity in plain format' do
+        expect { cli.invoke(:export, nil, options) }.to output(
+          a_string_including("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};")
+        ).to_stdout
+      end
+
+      it 'does not export bloked IPs with different severities' do
+        expect { cli.invoke(:export, nil, options) }.to_not output(
+          a_string_including("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};")
+        ).to_stdout
+      end
+    end
+
+    context 'when --format option is not provided' do
+      it 'exports blocked IPs in plain format by default' do
+        expect { cli.export }.to output(
+          a_string_including("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
+        ).to_stdout
+      end
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/main_spec.rb b/spec/lib/mastodon/cli/main_spec.rb
new file mode 100644
index 0000000000..e3709afe37
--- /dev/null
+++ b/spec/lib/mastodon/cli/main_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/main'
+
+describe Mastodon::CLI::Main do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe 'version' do
+    it 'returns the Mastodon version' do
+      expect { described_class.new.invoke(:version) }.to output(
+        a_string_including(Mastodon::Version.to_s)
+      ).to_stdout
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/maintenance_spec.rb b/spec/lib/mastodon/cli/maintenance_spec.rb
new file mode 100644
index 0000000000..12cd9ca8a6
--- /dev/null
+++ b/spec/lib/mastodon/cli/maintenance_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/maintenance'
+
+describe Mastodon::CLI::Maintenance do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/media_spec.rb b/spec/lib/mastodon/cli/media_spec.rb
new file mode 100644
index 0000000000..29f7d424a9
--- /dev/null
+++ b/spec/lib/mastodon/cli/media_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/media'
+
+describe Mastodon::CLI::Media do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/preview_cards_spec.rb b/spec/lib/mastodon/cli/preview_cards_spec.rb
new file mode 100644
index 0000000000..b4b018b3be
--- /dev/null
+++ b/spec/lib/mastodon/cli/preview_cards_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/preview_cards'
+
+describe Mastodon::CLI::PreviewCards do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/search_spec.rb b/spec/lib/mastodon/cli/search_spec.rb
new file mode 100644
index 0000000000..d5cae5bf49
--- /dev/null
+++ b/spec/lib/mastodon/cli/search_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/search'
+
+describe Mastodon::CLI::Search do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/settings_spec.rb b/spec/lib/mastodon/cli/settings_spec.rb
new file mode 100644
index 0000000000..ae58e74e56
--- /dev/null
+++ b/spec/lib/mastodon/cli/settings_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/settings'
+
+describe Mastodon::CLI::Settings do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+
+  describe 'subcommand "registrations"' do
+    let(:cli) { Mastodon::CLI::Registrations.new }
+
+    before do
+      Setting.registrations_mode = nil
+    end
+
+    describe '#open' do
+      it 'changes "registrations_mode" to "open"' do
+        expect { cli.open }.to change(Setting, :registrations_mode).from(nil).to('open')
+      end
+
+      it 'displays success message' do
+        expect { cli.open }.to output(
+          a_string_including('OK')
+        ).to_stdout
+      end
+    end
+
+    describe '#approved' do
+      it 'changes "registrations_mode" to "approved"' do
+        expect { cli.approved }.to change(Setting, :registrations_mode).from(nil).to('approved')
+      end
+
+      it 'displays success message' do
+        expect { cli.approved }.to output(
+          a_string_including('OK')
+        ).to_stdout
+      end
+
+      context 'with --require-reason' do
+        before do
+          cli.options = { require_reason: true }
+        end
+
+        it 'changes "registrations_mode" to "approved"' do
+          expect { cli.approved }.to change(Setting, :registrations_mode).from(nil).to('approved')
+        end
+
+        it 'sets "require_invite_text" to "true"' do
+          expect { cli.approved }.to change(Setting, :require_invite_text).from(false).to(true)
+        end
+      end
+    end
+
+    describe '#close' do
+      it 'changes "registrations_mode" to "none"' do
+        expect { cli.close }.to change(Setting, :registrations_mode).from(nil).to('none')
+      end
+
+      it 'displays success message' do
+        expect { cli.close }.to output(
+          a_string_including('OK')
+        ).to_stdout
+      end
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/statuses_spec.rb b/spec/lib/mastodon/cli/statuses_spec.rb
new file mode 100644
index 0000000000..2430a88416
--- /dev/null
+++ b/spec/lib/mastodon/cli/statuses_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/statuses'
+
+describe Mastodon::CLI::Statuses do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/cli/upgrade_spec.rb b/spec/lib/mastodon/cli/upgrade_spec.rb
new file mode 100644
index 0000000000..9e0ab9d06e
--- /dev/null
+++ b/spec/lib/mastodon/cli/upgrade_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/cli/upgrade'
+
+describe Mastodon::CLI::Upgrade do
+  describe '.exit_on_failure?' do
+    it 'returns true' do
+      expect(described_class.exit_on_failure?).to be true
+    end
+  end
+end
diff --git a/spec/lib/mastodon/migration_warning_spec.rb b/spec/lib/mastodon/migration_warning_spec.rb
new file mode 100644
index 0000000000..4adf0837ab
--- /dev/null
+++ b/spec/lib/mastodon/migration_warning_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'mastodon/migration_warning'
+
+describe Mastodon::MigrationWarning do
+  describe 'migration_duration_warning' do
+    before do
+      allow(migration).to receive(:valid_environment?).and_return(true)
+      allow(migration).to receive(:sleep).with(1)
+    end
+
+    let(:migration) { Class.new(ActiveRecord::Migration[6.1]).extend(described_class) }
+
+    context 'with the default message' do
+      it 'warns about long migrations' do
+        expectation = expect { migration.migration_duration_warning }
+
+        expectation.to output(/interrupt this migration/).to_stdout
+        expectation.to output(/Continuing in 5/).to_stdout
+      end
+    end
+
+    context 'with an additional message' do
+      it 'warns about long migrations' do
+        expectation = expect { migration.migration_duration_warning('Get ready for it') }
+
+        expectation.to output(/interrupt this migration/).to_stdout
+        expectation.to output(/Get ready for it/).to_stdout
+        expectation.to output(/Continuing in 5/).to_stdout
+      end
+    end
+  end
+end
diff --git a/spec/lib/ostatus/tag_manager_spec.rb b/spec/lib/ostatus/tag_manager_spec.rb
index 31195bae21..0e20f26c7c 100644
--- a/spec/lib/ostatus/tag_manager_spec.rb
+++ b/spec/lib/ostatus/tag_manager_spec.rb
@@ -5,65 +5,65 @@ require 'rails_helper'
 describe OStatus::TagManager do
   describe '#unique_tag' do
     it 'returns a unique tag' do
-      expect(OStatus::TagManager.instance.unique_tag(Time.utc(2000), 12, 'Status')).to eq 'tag:cb6e6126.ngrok.io,2000-01-01:objectId=12:objectType=Status'
+      expect(described_class.instance.unique_tag(Time.utc(2000), 12, 'Status')).to eq 'tag:cb6e6126.ngrok.io,2000-01-01:objectId=12:objectType=Status'
     end
   end
 
   describe '#unique_tag_to_local_id' do
     it 'returns the ID part' do
-      expect(OStatus::TagManager.instance.unique_tag_to_local_id('tag:cb6e6126.ngrok.io,2000-01-01:objectId=12:objectType=Status', 'Status')).to eql '12'
+      expect(described_class.instance.unique_tag_to_local_id('tag:cb6e6126.ngrok.io,2000-01-01:objectId=12:objectType=Status', 'Status')).to eql '12'
     end
 
     it 'returns nil if it is not local id' do
-      expect(OStatus::TagManager.instance.unique_tag_to_local_id('tag:remote,2000-01-01:objectId=12:objectType=Status', 'Status')).to eq nil
+      expect(described_class.instance.unique_tag_to_local_id('tag:remote,2000-01-01:objectId=12:objectType=Status', 'Status')).to be_nil
     end
 
     it 'returns nil if it is not expected type' do
-      expect(OStatus::TagManager.instance.unique_tag_to_local_id('tag:cb6e6126.ngrok.io,2000-01-01:objectId=12:objectType=Block', 'Status')).to eq nil
+      expect(described_class.instance.unique_tag_to_local_id('tag:cb6e6126.ngrok.io,2000-01-01:objectId=12:objectType=Block', 'Status')).to be_nil
     end
 
     it 'returns nil if it does not have object ID' do
-      expect(OStatus::TagManager.instance.unique_tag_to_local_id('tag:cb6e6126.ngrok.io,2000-01-01:objectType=Status', 'Status')).to eq nil
+      expect(described_class.instance.unique_tag_to_local_id('tag:cb6e6126.ngrok.io,2000-01-01:objectType=Status', 'Status')).to be_nil
     end
   end
 
   describe '#local_id?' do
     it 'returns true for a local ID' do
-      expect(OStatus::TagManager.instance.local_id?('tag:cb6e6126.ngrok.io;objectId=12:objectType=Status')).to be true
+      expect(described_class.instance.local_id?('tag:cb6e6126.ngrok.io;objectId=12:objectType=Status')).to be true
     end
 
     it 'returns false for a foreign ID' do
-      expect(OStatus::TagManager.instance.local_id?('tag:foreign.tld;objectId=12:objectType=Status')).to be false
+      expect(described_class.instance.local_id?('tag:foreign.tld;objectId=12:objectType=Status')).to be false
     end
   end
 
   describe '#uri_for' do
-    subject { OStatus::TagManager.instance.uri_for(target) }
+    subject { described_class.instance.uri_for(target) }
 
-    context 'comment object' do
+    context 'with comment object' do
       let(:target) { Fabricate(:status, created_at: '2000-01-01T00:00:00Z', reply: true) }
 
       it 'returns the unique tag for status' do
         expect(target.object_type).to eq :comment
-        is_expected.to eq target.uri
+        expect(subject).to eq target.uri
       end
     end
 
-    context 'note object' do
+    context 'with note object' do
       let(:target) { Fabricate(:status, created_at: '2000-01-01T00:00:00Z', reply: false, thread: nil) }
 
       it 'returns the unique tag for status' do
         expect(target.object_type).to eq :note
-        is_expected.to eq target.uri
+        expect(subject).to eq target.uri
       end
     end
 
-    context 'person object' do
+    context 'when person object' do
       let(:target) { Fabricate(:account, username: 'alice') }
 
       it 'returns the URL for account' do
         expect(target.object_type).to eq :person
-        is_expected.to eq 'https://cb6e6126.ngrok.io/users/alice'
+        expect(subject).to eq 'https://cb6e6126.ngrok.io/users/alice'
       end
     end
   end
diff --git a/spec/lib/plain_text_formatter_spec.rb b/spec/lib/plain_text_formatter_spec.rb
index 81e4ae286e..80b3c331a6 100644
--- a/spec/lib/plain_text_formatter_spec.rb
+++ b/spec/lib/plain_text_formatter_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 
 RSpec.describe PlainTextFormatter do
@@ -8,7 +10,7 @@ RSpec.describe PlainTextFormatter do
       let(:status) { Fabricate(:status, text: '

a text by a nerd who uses an HTML tag in text

', uri: nil) } it 'returns the raw text' do - is_expected.to eq '

a text by a nerd who uses an HTML tag in text

' + expect(subject).to eq '

a text by a nerd who uses an HTML tag in text

' end end diff --git a/spec/lib/request_pool_spec.rb b/spec/lib/request_pool_spec.rb index 4a144d7c7f..f179e6ca94 100644 --- a/spec/lib/request_pool_spec.rb +++ b/spec/lib/request_pool_spec.rb @@ -33,7 +33,7 @@ describe RequestPool do subject - threads = 20.times.map do |i| + threads = Array.new(20) do |_i| Thread.new do 20.times do subject.with('http://example.com') do |http_client| @@ -48,16 +48,25 @@ describe RequestPool do expect(subject.size).to be > 1 end - it 'closes idle connections' do - stub_request(:get, 'http://example.com/').to_return(status: 200, body: 'Hello!') - - subject.with('http://example.com') do |http_client| - http_client.get('/').flush + context 'with an idle connection' do + before do + stub_const('RequestPool::MAX_IDLE_TIME', 1) # Lower idle time limit to 1 seconds + stub_const('RequestPool::REAPER_FREQUENCY', 0.1) # Run reaper every 0.1 seconds + stub_request(:get, 'http://example.com/').to_return(status: 200, body: 'Hello!') end - expect(subject.size).to eq 1 - sleep RequestPool::MAX_IDLE_TIME + 30 + 1 - expect(subject.size).to eq 0 + it 'closes the connections' do + subject.with('http://example.com') do |http_client| + http_client.get('/').flush + end + + expect { reaper_observes_idle_timeout }.to change(subject, :size).from(1).to(0) + end + + def reaper_observes_idle_timeout + # One full idle period and 2 reaper cycles more + sleep RequestPool::MAX_IDLE_TIME + (RequestPool::REAPER_FREQUENCY * 2) + end end end end diff --git a/spec/lib/request_spec.rb b/spec/lib/request_spec.rb index 8539944e28..f0861376b9 100644 --- a/spec/lib/request_spec.rb +++ b/spec/lib/request_spec.rb @@ -4,7 +4,7 @@ require 'rails_helper' require 'securerandom' describe Request do - subject { Request.new(:get, 'http://example.com') } + subject { described_class.new(:get, 'http://example.com') } describe '#headers' do it 'returns user agent' do @@ -43,29 +43,29 @@ describe Request do before { stub_request(:get, 'http://example.com') } it 'executes a HTTP request' do - expect { |block| subject.perform &block }.to yield_control + expect { |block| subject.perform(&block) }.to yield_control expect(a_request(:get, 'http://example.com')).to have_been_made.once end it 'executes a HTTP request when the first address is private' do - resolver = double + resolver = instance_double(Resolv::DNS) allow(resolver).to receive(:getaddresses).with('example.com').and_return(%w(0.0.0.0 2001:4860:4860::8844)) allow(resolver).to receive(:timeouts=).and_return(nil) allow(Resolv::DNS).to receive(:open).and_yield(resolver) - expect { |block| subject.perform &block }.to yield_control + expect { |block| subject.perform(&block) }.to yield_control expect(a_request(:get, 'http://example.com')).to have_been_made.once end it 'sets headers' do - expect { |block| subject.perform &block }.to yield_control + expect { |block| subject.perform(&block) }.to yield_control expect(a_request(:get, 'http://example.com').with(headers: subject.headers)).to have_been_made end it 'closes underlying connection' do expect_any_instance_of(HTTP::Client).to receive(:close) - expect { |block| subject.perform &block }.to yield_control + expect { |block| subject.perform(&block) }.to yield_control end it 'returns response which implements body_with_limit' do @@ -83,7 +83,7 @@ describe Request do end it 'raises Mastodon::ValidationError' do - resolver = double + resolver = instance_double(Resolv::DNS) allow(resolver).to receive(:getaddresses).with('example.com').and_return(%w(0.0.0.0 2001:db8::face)) allow(resolver).to receive(:timeouts=).and_return(nil) @@ -97,12 +97,12 @@ describe Request do describe "response's body_with_limit method" do it 'rejects body more than 1 megabyte by default' do stub_request(:any, 'http://example.com').to_return(body: SecureRandom.random_bytes(2.megabytes)) - expect { subject.perform { |response| response.body_with_limit } }.to raise_error Mastodon::LengthValidationError + expect { subject.perform(&:body_with_limit) }.to raise_error Mastodon::LengthValidationError end it 'accepts body less than 1 megabyte by default' do stub_request(:any, 'http://example.com').to_return(body: SecureRandom.random_bytes(2.kilobytes)) - expect { subject.perform { |response| response.body_with_limit } }.not_to raise_error + expect { subject.perform(&:body_with_limit) }.to_not raise_error end it 'rejects body by given size' do @@ -112,12 +112,12 @@ describe Request do it 'rejects too large chunked body' do stub_request(:any, 'http://example.com').to_return(body: SecureRandom.random_bytes(2.megabytes), headers: { 'Transfer-Encoding' => 'chunked' }) - expect { subject.perform { |response| response.body_with_limit } }.to raise_error Mastodon::LengthValidationError + expect { subject.perform(&:body_with_limit) }.to raise_error Mastodon::LengthValidationError end it 'rejects too large monolithic body' do stub_request(:any, 'http://example.com').to_return(body: SecureRandom.random_bytes(2.megabytes), headers: { 'Content-Length' => 2.megabytes }) - expect { subject.perform { |response| response.body_with_limit } }.to raise_error Mastodon::LengthValidationError + expect { subject.perform(&:body_with_limit) }.to raise_error Mastodon::LengthValidationError end it 'truncates large monolithic body' do diff --git a/spec/lib/sanitize_config_spec.rb b/spec/lib/sanitize_config_spec.rb index c9543ceb0c..cc9916bfd4 100644 --- a/spec/lib/sanitize_config_spec.rb +++ b/spec/lib/sanitize_config_spec.rb @@ -3,27 +3,17 @@ require 'rails_helper' describe Sanitize::Config do - describe '::MASTODON_STRICT' do - subject { Sanitize::Config::MASTODON_STRICT } - - it 'converts h1 to p' do - expect(Sanitize.fragment('

Foo

', subject)).to eq '

Foo

' + shared_examples 'common HTML sanitization' do + it 'keeps h1' do + expect(Sanitize.fragment('

Foo

', subject)).to eq '

Foo

' end - it 'converts ul to p' do - expect(Sanitize.fragment('

Check out:

  • Foo
  • Bar
', subject)).to eq '

Check out:

Foo
Bar

' + it 'keeps ul' do + expect(Sanitize.fragment('

Check out:

  • Foo
  • Bar
', subject)).to eq '

Check out:

  • Foo
  • Bar
' end - it 'converts p inside ul' do - expect(Sanitize.fragment('
  • Foo

    Bar

  • Baz
', subject)).to eq '

Foo
Bar
Baz

' - end - - it 'converts ul inside ul' do - expect(Sanitize.fragment('
  • Foo
    • Bar
    • Baz
', subject)).to eq '

Foo
Bar
Baz

' - end - - it 'keep links in lists' do - expect(Sanitize.fragment('

Check out:

', subject)).to eq '

Check out:

joinmastodon.org
Bar

' + it 'keeps start and reversed attributes of ol' do + expect(Sanitize.fragment('

Check out:

  1. Foo
  2. Bar
', subject)).to eq '

Check out:

  1. Foo
  2. Bar
' end it 'removes a without href' do @@ -45,5 +35,42 @@ describe Sanitize::Config do it 'keeps a with href' do expect(Sanitize.fragment('Test', subject)).to eq 'Test' end + + it 'keeps a with translate="no"' do + expect(Sanitize.fragment('Test', subject)).to eq 'Test' + end + + it 'removes "translate" attribute with invalid value' do + expect(Sanitize.fragment('Test', subject)).to eq 'Test' + end + + it 'removes a with unparsable href' do + expect(Sanitize.fragment('Test', subject)).to eq 'Test' + end + + it 'keeps a with supported scheme and no host' do + expect(Sanitize.fragment('Test', subject)).to eq 'Test' + end + + it 'keeps title in abbr' do + expect(Sanitize.fragment('HTML', subject)).to eq 'HTML' + end + end + + describe '::MASTODON_OUTGOING' do + subject { Sanitize::Config::MASTODON_OUTGOING } + + around do |example| + original_web_domain = Rails.configuration.x.web_domain + example.run + Rails.configuration.x.web_domain = original_web_domain + end + + it_behaves_like 'common HTML sanitization' + + it 'keeps a with href and rel tag, not adding to rel or target if url is local' do + Rails.configuration.x.web_domain = 'domain.test' + expect(Sanitize.fragment('', subject)).to eq '' + end end end diff --git a/spec/lib/scope_transformer_spec.rb b/spec/lib/scope_transformer_spec.rb index e5a992144d..8a9c7cf967 100644 --- a/spec/lib/scope_transformer_spec.rb +++ b/spec/lib/scope_transformer_spec.rb @@ -20,67 +20,67 @@ describe ScopeTransformer do end end - context 'for scope "read"' do + context 'with scope "read"' do let(:input) { 'read' } it_behaves_like 'a scope', nil, 'all', 'read' end - context 'for scope "write"' do + context 'with scope "write"' do let(:input) { 'write' } it_behaves_like 'a scope', nil, 'all', 'write' end - context 'for scope "follow"' do + context 'with scope "follow"' do let(:input) { 'follow' } it_behaves_like 'a scope', nil, 'follow', 'read/write' end - context 'for scope "crypto"' do + context 'with scope "crypto"' do let(:input) { 'crypto' } it_behaves_like 'a scope', nil, 'crypto', 'read/write' end - context 'for scope "push"' do + context 'with scope "push"' do let(:input) { 'push' } it_behaves_like 'a scope', nil, 'push', 'read/write' end - context 'for scope "admin:read"' do + context 'with scope "admin:read"' do let(:input) { 'admin:read' } it_behaves_like 'a scope', 'admin', 'all', 'read' end - context 'for scope "admin:write"' do + context 'with scope "admin:write"' do let(:input) { 'admin:write' } it_behaves_like 'a scope', 'admin', 'all', 'write' end - context 'for scope "admin:read:accounts"' do + context 'with scope "admin:read:accounts"' do let(:input) { 'admin:read:accounts' } it_behaves_like 'a scope', 'admin', 'accounts', 'read' end - context 'for scope "admin:write:accounts"' do + context 'with scope "admin:write:accounts"' do let(:input) { 'admin:write:accounts' } it_behaves_like 'a scope', 'admin', 'accounts', 'write' end - context 'for scope "read:accounts"' do + context 'with scope "read:accounts"' do let(:input) { 'read:accounts' } it_behaves_like 'a scope', nil, 'accounts', 'read' end - context 'for scope "write:accounts"' do + context 'with scope "write:accounts"' do let(:input) { 'write:accounts' } it_behaves_like 'a scope', nil, 'accounts', 'write' diff --git a/spec/lib/search_query_parser_spec.rb b/spec/lib/search_query_parser_spec.rb new file mode 100644 index 0000000000..66b0e8f9e2 --- /dev/null +++ b/spec/lib/search_query_parser_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'parslet/rig/rspec' + +describe SearchQueryParser do + let(:parser) { described_class.new } + + context 'with term' do + it 'consumes "hello"' do + expect(parser.term).to parse('hello') + end + end + + context 'with prefix' do + it 'consumes "foo:"' do + expect(parser.prefix).to parse('foo:') + end + end + + context 'with operator' do + it 'consumes "+"' do + expect(parser.operator).to parse('+') + end + + it 'consumes "-"' do + expect(parser.operator).to parse('-') + end + end + + context 'with shortcode' do + it 'consumes ":foo:"' do + expect(parser.shortcode).to parse(':foo:') + end + end + + context 'with phrase' do + it 'consumes "hello world"' do + expect(parser.phrase).to parse('"hello world"') + end + end + + context 'with clause' do + it 'consumes "foo"' do + expect(parser.clause).to parse('foo') + end + + it 'consumes "-foo"' do + expect(parser.clause).to parse('-foo') + end + + it 'consumes "foo:bar"' do + expect(parser.clause).to parse('foo:bar') + end + + it 'consumes "-foo:bar"' do + expect(parser.clause).to parse('-foo:bar') + end + + it 'consumes \'foo:"hello world"\'' do + expect(parser.clause).to parse('foo:"hello world"') + end + + it 'consumes \'-foo:"hello world"\'' do + expect(parser.clause).to parse('-foo:"hello world"') + end + + it 'consumes "foo:"' do + expect(parser.clause).to parse('foo:') + end + + it 'consumes \'"\'' do + expect(parser.clause).to parse('"') + end + end + + context 'with query' do + it 'consumes "hello -world"' do + expect(parser.query).to parse('hello -world') + end + + it 'consumes \'foo "hello world"\'' do + expect(parser.query).to parse('foo "hello world"') + end + + it 'consumes "foo:bar hello"' do + expect(parser.query).to parse('foo:bar hello') + end + + it 'consumes \'"hello" world "\'' do + expect(parser.query).to parse('"hello" world "') + end + + it 'consumes "foo:bar bar: hello"' do + expect(parser.query).to parse('foo:bar bar: hello') + end + end +end diff --git a/spec/lib/search_query_transformer_spec.rb b/spec/lib/search_query_transformer_spec.rb new file mode 100644 index 0000000000..5817e3d1d2 --- /dev/null +++ b/spec/lib/search_query_transformer_spec.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe SearchQueryTransformer do + subject { described_class.new.apply(parser, current_account: account) } + + let(:account) { Fabricate(:account) } + let(:parser) { SearchQueryParser.new.parse(query) } + + context 'with "hello world"' do + let(:query) { 'hello world' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:term)).to match_array %w(hello world) + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses)).to be_empty + end + end + + context 'with "hello -world"' do + let(:query) { 'hello -world' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:term)).to match_array %w(hello) + expect(subject.send(:must_not_clauses).map(&:term)).to match_array %w(world) + expect(subject.send(:filter_clauses)).to be_empty + end + end + + context 'with "hello is:reply"' do + let(:query) { 'hello is:reply' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:term)).to match_array %w(hello) + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses).map(&:term)).to match_array %w(reply) + end + end + + context 'with "foo: bar"' do + let(:query) { 'foo: bar' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:term)).to match_array %w(foo bar) + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses)).to be_empty + end + end + + context 'with "foo:bar"' do + let(:query) { 'foo:bar' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:term)).to contain_exactly('foo bar') + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses)).to be_empty + end + end + + context 'with \'"hello world"\'' do + let(:query) { '"hello world"' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses).map(&:phrase)).to contain_exactly('hello world') + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses)).to be_empty + end + end + + context 'with \'before:"2022-01-01 23:00"\'' do + let(:query) { 'before:"2022-01-01 23:00"' } + + it 'transforms clauses' do + expect(subject.send(:must_clauses)).to be_empty + expect(subject.send(:must_not_clauses)).to be_empty + expect(subject.send(:filter_clauses).map(&:term)).to contain_exactly(lt: '2022-01-01 23:00', time_zone: 'UTC') + end + end +end diff --git a/spec/lib/settings/extend_spec.rb b/spec/lib/settings/extend_spec.rb deleted file mode 100644 index 83ced4230c..0000000000 --- a/spec/lib/settings/extend_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Settings::Extend do - class User - include Settings::Extend - end - - describe '#settings' do - it 'sets @settings as an instance of Settings::ScopedSettings' do - user = Fabricate(:user) - expect(user.settings).to be_kind_of Settings::ScopedSettings - end - end -end diff --git a/spec/lib/settings/scoped_settings_spec.rb b/spec/lib/settings/scoped_settings_spec.rb deleted file mode 100644 index 7566685b4a..0000000000 --- a/spec/lib/settings/scoped_settings_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Settings::ScopedSettings do - let(:object) { Fabricate(:user) } - let(:scoped_setting) { described_class.new(object) } - let(:val) { 'whatever' } - let(:methods) { %i(auto_play_gif default_sensitive unfollow_modal boost_modal delete_modal reduce_motion system_font_ui noindex theme) } - - describe '.initialize' do - it 'sets @object' do - scoped_setting = described_class.new(object) - expect(scoped_setting.instance_variable_get(:@object)).to be object - end - end - - describe '#method_missing' do - it 'sets scoped_setting.method_name = val' do - methods.each do |key| - scoped_setting.send("#{key}=", val) - expect(scoped_setting.send(key)).to eq val - end - end - end - - describe '#[]= and #[]' do - it 'sets [key] = val' do - methods.each do |key| - scoped_setting[key] = val - expect(scoped_setting[key]).to eq val - end - end - end -end diff --git a/spec/lib/status_cache_hydrator_spec.rb b/spec/lib/status_cache_hydrator_spec.rb index 5c78de7116..5b80ccb970 100644 --- a/spec/lib/status_cache_hydrator_spec.rb +++ b/spec/lib/status_cache_hydrator_spec.rb @@ -44,7 +44,7 @@ describe StatusCacheHydrator do let(:reblog) { Fabricate(:status) } let(:status) { Fabricate(:status, reblog: reblog) } - context 'that has been favourited' do + context 'when it has been favourited' do before do FavouriteService.new.call(account, reblog) end @@ -54,7 +54,7 @@ describe StatusCacheHydrator do end end - context 'that has been reblogged' do + context 'when it has been reblogged' do before do ReblogService.new.call(account, reblog) end @@ -64,7 +64,7 @@ describe StatusCacheHydrator do end end - context 'that has been pinned' do + context 'when it has been pinned' do let(:reblog) { Fabricate(:status, account: account) } before do @@ -76,7 +76,7 @@ describe StatusCacheHydrator do end end - context 'that has been followed tags' do + context 'when it has been followed tags' do let(:followed_tag) { Fabricate(:tag) } before do @@ -90,7 +90,7 @@ describe StatusCacheHydrator do end end - context 'that has a poll authored by the user' do + context 'when it has a poll authored by the user' do let(:poll) { Fabricate(:poll, account: account) } let(:reblog) { Fabricate(:status, poll: poll, account: account) } @@ -99,7 +99,7 @@ describe StatusCacheHydrator do end end - context 'that has been voted in' do + context 'when it has been voted in' do let(:poll) { Fabricate(:poll, options: %w(Yellow Blue)) } let(:reblog) { Fabricate(:status, poll: poll) } @@ -112,7 +112,7 @@ describe StatusCacheHydrator do end end - context 'that matches account filters' do + context 'when it matches account filters' do let(:reblog) { Fabricate(:status, text: 'this toot is about that banned word') } before do diff --git a/spec/lib/status_filter_spec.rb b/spec/lib/status_filter_spec.rb index a851014d9c..c994ad419f 100644 --- a/spec/lib/status_filter_spec.rb +++ b/spec/lib/status_filter_spec.rb @@ -7,10 +7,10 @@ describe StatusFilter do let(:status) { Fabricate(:status) } context 'without an account' do - subject { described_class.new(status, nil) } + subject(:filter) { described_class.new(status, nil) } context 'when there are no connections' do - it { is_expected.not_to be_filtered } + it { is_expected.to_not be_filtered } end context 'when status account is silenced' do @@ -22,20 +22,21 @@ describe StatusFilter do end context 'when status policy does not allow show' do - before do - expect_any_instance_of(StatusPolicy).to receive(:show?).and_return(false) - end + it 'filters the status' do + allow_any_instance_of(StatusPolicy).to receive(:show?).and_return(false) - it { is_expected.to be_filtered } + expect(filter).to be_filtered + end end end context 'with real account' do + subject(:filter) { described_class.new(status, account) } + let(:account) { Fabricate(:account) } - subject { described_class.new(status, account) } context 'when there are no connections' do - it { is_expected.not_to be_filtered } + it { is_expected.to_not be_filtered } end context 'when status account is blocked' do @@ -72,11 +73,11 @@ describe StatusFilter do end context 'when status policy does not allow show' do - before do - expect_any_instance_of(StatusPolicy).to receive(:show?).and_return(false) - end + it 'filters the status' do + allow_any_instance_of(StatusPolicy).to receive(:show?).and_return(false) - it { is_expected.to be_filtered } + expect(filter).to be_filtered + end end end end diff --git a/spec/lib/status_finder_spec.rb b/spec/lib/status_finder_spec.rb index 61483f4bfe..53f5039af9 100644 --- a/spec/lib/status_finder_spec.rb +++ b/spec/lib/status_finder_spec.rb @@ -18,10 +18,13 @@ describe StatusFinder do it 'raises an error if action is not :show' do recognized = Rails.application.routes.recognize_path(url) - expect(recognized).to receive(:[]).with(:action).and_return(:create) - expect(Rails.application.routes).to receive(:recognize_path).with(url).and_return(recognized) + allow(recognized).to receive(:[]).with(:action).and_return(:create) + allow(Rails.application.routes).to receive(:recognize_path).with(url).and_return(recognized) expect { subject.status }.to raise_error(ActiveRecord::RecordNotFound) + + expect(Rails.application.routes).to have_received(:recognize_path) + expect(recognized).to have_received(:[]) end end diff --git a/spec/lib/status_reach_finder_spec.rb b/spec/lib/status_reach_finder_spec.rb index f0c22b1651..7181717dc1 100644 --- a/spec/lib/status_reach_finder_spec.rb +++ b/spec/lib/status_reach_finder_spec.rb @@ -4,14 +4,14 @@ require 'rails_helper' describe StatusReachFinder do describe '#inboxes' do - context 'for a local status' do + context 'with a local status' do + subject { described_class.new(status) } + let(:parent_status) { nil } let(:visibility) { :public } let(:alice) { Fabricate(:account, username: 'alice') } let(:status) { Fabricate(:status, account: alice, thread: parent_status, visibility: visibility) } - subject { described_class.new(status) } - context 'when it contains mentions of remote accounts' do let(:bob) { Fabricate(:account, username: 'bob', domain: 'foo.bar', protocol: :activitypub, inbox_url: 'https://foo.bar/inbox') } @@ -71,10 +71,8 @@ describe StatusReachFinder do bob.statuses.create!(thread: status, text: 'Hoge') end - context do - it 'includes the inbox of the replier' do - expect(subject.inboxes).to include 'https://foo.bar/inbox' - end + it 'includes the inbox of the replier' do + expect(subject.inboxes).to include 'https://foo.bar/inbox' end context 'when status is not public' do @@ -90,10 +88,8 @@ describe StatusReachFinder do let(:bob) { Fabricate(:account, username: 'bob', domain: 'foo.bar', protocol: :activitypub, inbox_url: 'https://foo.bar/inbox') } let(:parent_status) { Fabricate(:status, account: bob) } - context do - it 'includes the inbox of the replied-to account' do - expect(subject.inboxes).to include 'https://foo.bar/inbox' - end + it 'includes the inbox of the replied-to account' do + expect(subject.inboxes).to include 'https://foo.bar/inbox' end context 'when status is not public and replied-to account is not mentioned' do diff --git a/spec/lib/suspicious_sign_in_detector_spec.rb b/spec/lib/suspicious_sign_in_detector_spec.rb index 101a18aa01..9e64aff08a 100644 --- a/spec/lib/suspicious_sign_in_detector_spec.rb +++ b/spec/lib/suspicious_sign_in_detector_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe SuspiciousSignInDetector do describe '#suspicious?' do - let(:user) { Fabricate(:user, current_sign_in_at: 1.day.ago) } - let(:request) { double(remote_ip: remote_ip) } - let(:remote_ip) { nil } - subject { described_class.new(user).suspicious?(request) } + let(:user) { Fabricate(:user, current_sign_in_at: 1.day.ago) } + let(:request) { instance_double(ActionDispatch::Request, remote_ip: remote_ip) } + let(:remote_ip) { nil } + context 'when user has 2FA enabled' do before do user.update!(otp_required_for_login: true) diff --git a/spec/lib/tag_manager_spec.rb b/spec/lib/tag_manager_spec.rb index cd9fb936cd..38203a55f7 100644 --- a/spec/lib/tag_manager_spec.rb +++ b/spec/lib/tag_manager_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe TagManager do @@ -14,15 +16,15 @@ RSpec.describe TagManager do end it 'returns true for nil' do - expect(TagManager.instance.local_domain?(nil)).to eq true + expect(described_class.instance.local_domain?(nil)).to be true end it 'returns true if the slash-stripped string equals to local domain' do - expect(TagManager.instance.local_domain?('DoMaIn.Example.com/')).to eq true + expect(described_class.instance.local_domain?('DoMaIn.Example.com/')).to be true end it 'returns false for irrelevant string' do - expect(TagManager.instance.local_domain?('DoMaIn.Example.com!')).to eq false + expect(described_class.instance.local_domain?('DoMaIn.Example.com!')).to be false end end @@ -39,25 +41,25 @@ RSpec.describe TagManager do end it 'returns true for nil' do - expect(TagManager.instance.web_domain?(nil)).to eq true + expect(described_class.instance.web_domain?(nil)).to be true end it 'returns true if the slash-stripped string equals to web domain' do - expect(TagManager.instance.web_domain?('DoMaIn.Example.com/')).to eq true + expect(described_class.instance.web_domain?('DoMaIn.Example.com/')).to be true end it 'returns false for string with irrelevant characters' do - expect(TagManager.instance.web_domain?('DoMaIn.Example.com!')).to eq false + expect(described_class.instance.web_domain?('DoMaIn.Example.com!')).to be false end end describe '#normalize_domain' do it 'returns nil if the given parameter is nil' do - expect(TagManager.instance.normalize_domain(nil)).to eq nil + expect(described_class.instance.normalize_domain(nil)).to be_nil end it 'returns normalized domain' do - expect(TagManager.instance.normalize_domain('DoMaIn.Example.com/')).to eq 'domain.example.com' + expect(described_class.instance.normalize_domain('DoMaIn.Example.com/')).to eq 'domain.example.com' end end @@ -70,17 +72,17 @@ RSpec.describe TagManager do it 'returns true if the normalized string with port is local URL' do Rails.configuration.x.web_domain = 'domain.example.com:42' - expect(TagManager.instance.local_url?('https://DoMaIn.Example.com:42/')).to eq true + expect(described_class.instance.local_url?('https://DoMaIn.Example.com:42/')).to be true end it 'returns true if the normalized string without port is local URL' do Rails.configuration.x.web_domain = 'domain.example.com' - expect(TagManager.instance.local_url?('https://DoMaIn.Example.com/')).to eq true + expect(described_class.instance.local_url?('https://DoMaIn.Example.com/')).to be true end it 'returns false for string with irrelevant characters' do Rails.configuration.x.web_domain = 'domain.example.com' - expect(TagManager.instance.local_url?('https://domain.example.net/')).to eq false + expect(described_class.instance.local_url?('https://domain.example.net/')).to be false end end end diff --git a/spec/lib/text_formatter_spec.rb b/spec/lib/text_formatter_spec.rb index 52a9d24988..8b922c018b 100644 --- a/spec/lib/text_formatter_spec.rb +++ b/spec/lib/text_formatter_spec.rb @@ -1,127 +1,129 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe TextFormatter do describe '#to_s' do - let(:preloaded_accounts) { nil } - subject { described_class.new(text, preloaded_accounts: preloaded_accounts).to_s } - context 'given text containing plain text' do + let(:preloaded_accounts) { nil } + + context 'when given text containing plain text' do let(:text) { 'text' } it 'paragraphizes the text' do - is_expected.to eq '

text

' + expect(subject).to eq '

text

' end end - context 'given text containing line feeds' do + context 'when given text containing line feeds' do let(:text) { "line\nfeed" } it 'removes line feeds' do - is_expected.not_to include "\n" + expect(subject).to_not include "\n" end end - context 'given text containing linkable mentions' do + context 'when given text containing linkable mentions' do let(:preloaded_accounts) { [Fabricate(:account, username: 'alice')] } let(:text) { '@alice' } it 'creates a mention link' do - is_expected.to include '@alice' + expect(subject).to include '@alice' end end - context 'given text containing unlinkable mentions' do + context 'when given text containing unlinkable mentions' do let(:preloaded_accounts) { [] } let(:text) { '@alice' } it 'does not create a mention link' do - is_expected.to include '@alice' + expect(subject).to include '@alice' end end - context 'given a stand-alone medium URL' do + context 'when given a stand-alone medium URL' do let(:text) { 'https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4' } it 'matches the full URL' do - is_expected.to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"' + expect(subject).to include 'href="https://hackernoon.com/the-power-to-build-communities-a-response-to-mark-zuckerberg-3f2cac9148a4"' end end - context 'given a stand-alone google URL' do + context 'when given a stand-alone google URL' do let(:text) { 'http://google.com' } it 'matches the full URL' do - is_expected.to include 'href="http://google.com"' + expect(subject).to include 'href="http://google.com"' end end - context 'given a stand-alone URL with a newer TLD' do + context 'when given a stand-alone URL with a newer TLD' do let(:text) { 'http://example.gay' } it 'matches the full URL' do - is_expected.to include 'href="http://example.gay"' + expect(subject).to include 'href="http://example.gay"' end end - context 'given a stand-alone IDN URL' do + context 'when given a stand-alone IDN URL' do let(:text) { 'https://nic.みんな/' } it 'matches the full URL' do - is_expected.to include 'href="https://nic.みんな/"' + expect(subject).to include 'href="https://nic.みんな/"' end it 'has display URL' do - is_expected.to include 'nic.みんな/' + expect(subject).to include 'nic.みんな/' end end - context 'given a URL with a trailing period' do + context 'when given a URL with a trailing period' do let(:text) { 'http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona. ' } it 'matches the full URL but not the period' do - is_expected.to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"' + expect(subject).to include 'href="http://www.mcmansionhell.com/post/156408871451/50-states-of-mcmansion-hell-scottsdale-arizona"' end end - context 'given a URL enclosed with parentheses' do + context 'when given a URL enclosed with parentheses' do let(:text) { '(http://google.com/)' } it 'matches the full URL but not the parentheses' do - is_expected.to include 'href="http://google.com/"' + expect(subject).to include 'href="http://google.com/"' end end - context 'given a URL with a trailing exclamation point' do + context 'when given a URL with a trailing exclamation point' do let(:text) { 'http://www.google.com!' } it 'matches the full URL but not the exclamation point' do - is_expected.to include 'href="http://www.google.com"' + expect(subject).to include 'href="http://www.google.com"' end end - context 'given a URL with a trailing single quote' do + context 'when given a URL with a trailing single quote' do let(:text) { "http://www.google.com'" } it 'matches the full URL but not the single quote' do - is_expected.to include 'href="http://www.google.com"' + expect(subject).to include 'href="http://www.google.com"' end end - context 'given a URL with a trailing angle bracket' do + context 'when given a URL with a trailing angle bracket' do let(:text) { 'http://www.google.com>' } it 'matches the full URL but not the angle bracket' do - is_expected.to include 'href="http://www.google.com"' + expect(subject).to include 'href="http://www.google.com"' end end - context 'given a URL with a query string' do + context 'when given a URL with a query string' do context 'with escaped unicode character' do let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink' } it 'matches the full URL' do - is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink"' + expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&q=autolink"' end end @@ -129,7 +131,7 @@ RSpec.describe TextFormatter do let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓&q=autolink' } it 'matches the full URL' do - is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&q=autolink"' + expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=✓&q=autolink"' end end @@ -137,7 +139,7 @@ RSpec.describe TextFormatter do let(:text) { 'https://www.ruby-toolbox.com/search?utf8=✓' } it 'matches the full URL' do - is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"' + expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=✓"' end end @@ -145,168 +147,168 @@ RSpec.describe TextFormatter do let(:text) { 'https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink' } it 'preserves escaped unicode characters' do - is_expected.to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink"' + expect(subject).to include 'href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&utf81=✓&q=autolink"' end end end - context 'given a URL with parentheses in it' do + context 'when given a URL with parentheses in it' do let(:text) { 'https://en.wikipedia.org/wiki/Diaspora_(software)' } it 'matches the full URL' do - is_expected.to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"' + expect(subject).to include 'href="https://en.wikipedia.org/wiki/Diaspora_(software)"' end end - context 'given a URL in quotation marks' do + context 'when given a URL in quotation marks' do let(:text) { '"https://example.com/"' } it 'does not match the quotation marks' do - is_expected.to include 'href="https://example.com/"' + expect(subject).to include 'href="https://example.com/"' end end - context 'given a URL in angle brackets' do + context 'when given a URL in angle brackets' do let(:text) { '' } it 'does not match the angle brackets' do - is_expected.to include 'href="https://example.com/"' + expect(subject).to include 'href="https://example.com/"' end end - context 'given a URL with Japanese path string' do + context 'when given a URL with Japanese path string' do let(:text) { 'https://ja.wikipedia.org/wiki/日本' } it 'matches the full URL' do - is_expected.to include 'href="https://ja.wikipedia.org/wiki/日本"' + expect(subject).to include 'href="https://ja.wikipedia.org/wiki/日本"' end end - context 'given a URL with Korean path string' do + context 'when given a URL with Korean path string' do let(:text) { 'https://ko.wikipedia.org/wiki/대한민국' } it 'matches the full URL' do - is_expected.to include 'href="https://ko.wikipedia.org/wiki/대한민국"' + expect(subject).to include 'href="https://ko.wikipedia.org/wiki/대한민국"' end end - context 'given a URL with a full-width space' do + context 'when given a URL with a full-width space' do let(:text) { 'https://example.com/ abc123' } it 'does not match the full-width space' do - is_expected.to include 'href="https://example.com/"' + expect(subject).to include 'href="https://example.com/"' end end - context 'given a URL in Japanese quotation marks' do + context 'when given a URL in Japanese quotation marks' do let(:text) { '「[https://example.org/」' } it 'does not match the quotation marks' do - is_expected.to include 'href="https://example.org/"' + expect(subject).to include 'href="https://example.org/"' end end - context 'given a URL with Simplified Chinese path string' do + context 'when given a URL with Simplified Chinese path string' do let(:text) { 'https://baike.baidu.com/item/中华人民共和国' } it 'matches the full URL' do - is_expected.to include 'href="https://baike.baidu.com/item/中华人民共和国"' + expect(subject).to include 'href="https://baike.baidu.com/item/中华人民共和国"' end end - context 'given a URL with Traditional Chinese path string' do + context 'when given a URL with Traditional Chinese path string' do let(:text) { 'https://zh.wikipedia.org/wiki/臺灣' } it 'matches the full URL' do - is_expected.to include 'href="https://zh.wikipedia.org/wiki/臺灣"' + expect(subject).to include 'href="https://zh.wikipedia.org/wiki/臺灣"' end end - context 'given a URL containing unsafe code (XSS attack, visible part)' do - let(:text) { %q{http://example.com/bb} } + context 'when given a URL containing unsafe code (XSS attack, visible part)' do + let(:text) { 'http://example.com/bb' } it 'does not include the HTML in the URL' do - is_expected.to include '"http://example.com/b"' + expect(subject).to include '"http://example.com/b"' end it 'escapes the HTML' do - is_expected.to include '<del>b</del>' + expect(subject).to include '<del>b</del>' end end - context 'given a URL containing unsafe code (XSS attack, invisible part)' do - let(:text) { %q{http://example.com/blahblahblahblah/a} } + context 'when given a URL containing unsafe code (XSS attack, invisible part)' do + let(:text) { 'http://example.com/blahblahblahblah/a' } it 'does not include the HTML in the URL' do - is_expected.to include '"http://example.com/blahblahblahblah/a"' + expect(subject).to include '"http://example.com/blahblahblahblah/a"' end it 'escapes the HTML' do - is_expected.to include '<script>alert("Hello")</script>' + expect(subject).to include '<script>alert("Hello")</script>' end end - context 'given text containing HTML code (script tag)' do + context 'when given text containing HTML code (script tag)' do let(:text) { '' } it 'escapes the HTML' do - is_expected.to include '

<script>alert("Hello")</script>

' + expect(subject).to include '

<script>alert("Hello")</script>

' end end - context 'given text containing HTML (XSS attack)' do + context 'when given text containing HTML (XSS attack)' do let(:text) { %q{} } it 'escapes the HTML' do - is_expected.to include '

<img src="javascript:alert('XSS');">

' + expect(subject).to include '

<img src="javascript:alert('XSS');">

' end end - context 'given an invalid URL' do + context 'when given an invalid URL' do let(:text) { 'http://www\.google\.com' } it 'outputs the raw URL' do - is_expected.to eq '

http://www\.google\.com

' + expect(subject).to eq '

http://www\.google\.com

' end end - context 'given text containing a hashtag' do + context 'when given text containing a hashtag' do let(:text) { '#hashtag' } it 'creates a hashtag link' do - is_expected.to include '/tags/hashtag" class="mention hashtag" rel="tag">#hashtag' + expect(subject).to include '/tags/hashtag" class="mention hashtag" rel="tag">#hashtag' end end - context 'given text containing a hashtag with Unicode chars' do + context 'when given text containing a hashtag with Unicode chars' do let(:text) { '#hashtagタグ' } it 'creates a hashtag link' do - is_expected.to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#hashtagタグ' + expect(subject).to include '/tags/hashtag%E3%82%BF%E3%82%B0" class="mention hashtag" rel="tag">#hashtagタグ' end end - context 'given text with a stand-alone xmpp: URI' do + context 'when given text with a stand-alone xmpp: URI' do let(:text) { 'xmpp:user@instance.com' } it 'matches the full URI' do - is_expected.to include 'href="xmpp:user@instance.com"' + expect(subject).to include 'href="xmpp:user@instance.com"' end end - context 'given text with an xmpp: URI with a query-string' do + context 'when given text with an xmpp: URI with a query-string' do let(:text) { 'please join xmpp:muc@instance.com?join right now' } it 'matches the full URI' do - is_expected.to include 'href="xmpp:muc@instance.com?join"' + expect(subject).to include 'href="xmpp:muc@instance.com?join"' end end - context 'given text containing a magnet: URI' do + context 'when given text containing a magnet: URI' do let(:text) { 'wikipedia gives this example of a magnet uri: magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a' } it 'matches the full URI' do - is_expected.to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"' + expect(subject).to include 'href="magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a"' end end end diff --git a/spec/lib/translation_service/deepl_spec.rb b/spec/lib/translation_service/deepl_spec.rb new file mode 100644 index 0000000000..5a1d0f094a --- /dev/null +++ b/spec/lib/translation_service/deepl_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe TranslationService::DeepL do + subject(:service) { described_class.new(plan, 'my-api-key') } + + let(:plan) { 'advanced' } + + before do + stub_request(:get, 'https://api.deepl.com/v2/languages?type=source').to_return( + body: '[{"language":"EN","name":"English"},{"language":"UK","name":"Ukrainian"}]' + ) + stub_request(:get, 'https://api.deepl.com/v2/languages?type=target').to_return( + body: '[{"language":"EN-GB","name":"English (British)"},{"language":"ZH","name":"Chinese"}]' + ) + end + + describe '#translate' do + it 'returns translation with specified source language' do + stub_request(:post, 'https://api.deepl.com/v2/translate') + .with(body: 'text=Hasta+la+vista&source_lang=ES&target_lang=en&tag_handling=html') + .to_return(body: '{"translations":[{"detected_source_language":"ES","text":"See you soon"}]}') + + translations = service.translate(['Hasta la vista'], 'es', 'en') + expect(translations.size).to eq 1 + + translation = translations.first + expect(translation.detected_source_language).to eq 'es' + expect(translation.provider).to eq 'DeepL.com' + expect(translation.text).to eq 'See you soon' + end + + it 'returns translation with auto-detected source language' do + stub_request(:post, 'https://api.deepl.com/v2/translate') + .with(body: 'text=Guten+Tag&source_lang&target_lang=en&tag_handling=html') + .to_return(body: '{"translations":[{"detected_source_language":"DE","text":"Good morning"}]}') + + translations = service.translate(['Guten Tag'], nil, 'en') + expect(translations.size).to eq 1 + + translation = translations.first + expect(translation.detected_source_language).to eq 'de' + expect(translation.provider).to eq 'DeepL.com' + expect(translation.text).to eq 'Good morning' + end + + it 'returns translation of multiple texts' do + stub_request(:post, 'https://api.deepl.com/v2/translate') + .with(body: 'text=Guten+Morgen&text=Gute+Nacht&source_lang=DE&target_lang=en&tag_handling=html') + .to_return(body: '{"translations":[{"detected_source_language":"DE","text":"Good morning"},{"detected_source_language":"DE","text":"Good night"}]}') + + translations = service.translate(['Guten Morgen', 'Gute Nacht'], 'de', 'en') + expect(translations.size).to eq 2 + + expect(translations.first.text).to eq 'Good morning' + expect(translations.last.text).to eq 'Good night' + end + end + + describe '#languages' do + it 'returns source languages' do + expect(service.languages.keys).to eq [nil, 'en', 'uk'] + end + + it 'returns target languages for each source language' do + expect(service.languages['en']).to eq %w(pt en-GB zh) + expect(service.languages['uk']).to eq %w(en pt en-GB zh) + end + + it 'returns target languages for auto-detection' do + expect(service.languages[nil]).to eq %w(en pt en-GB zh) + end + end + + describe '#request' do + before do + stub_request(:any, //) + # rubocop:disable Lint/EmptyBlock + service.send(:request, :get, '/v2/languages') { |res| } + # rubocop:enable Lint/EmptyBlock + end + + it 'uses paid plan base URL' do + expect(a_request(:get, 'https://api.deepl.com/v2/languages')).to have_been_made.once + end + + context 'with free plan' do + let(:plan) { 'free' } + + it 'uses free plan base URL' do + expect(a_request(:get, 'https://api-free.deepl.com/v2/languages')).to have_been_made.once + end + end + + it 'sends API key' do + expect(a_request(:get, 'https://api.deepl.com/v2/languages').with(headers: { Authorization: 'DeepL-Auth-Key my-api-key' })).to have_been_made.once + end + end +end diff --git a/spec/lib/translation_service/libre_translate_spec.rb b/spec/lib/translation_service/libre_translate_spec.rb new file mode 100644 index 0000000000..90966a8ebf --- /dev/null +++ b/spec/lib/translation_service/libre_translate_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe TranslationService::LibreTranslate do + subject(:service) { described_class.new('https://libretranslate.example.com', 'my-api-key') } + + before do + stub_request(:get, 'https://libretranslate.example.com/languages').to_return( + body: '[{"code": "en","name": "English","targets": ["de","en","es"]},{"code": "da","name": "Danish","targets": ["en","pt"]}]' + ) + end + + describe '#languages' do + subject(:languages) { service.languages } + + it 'returns source languages' do + expect(languages.keys).to eq ['en', 'da', nil] + end + + it 'returns target languages for each source language' do + expect(languages['en']).to eq %w(de es) + expect(languages['da']).to eq %w(en pt) + end + + it 'returns target languages for auto-detected language' do + expect(languages[nil]).to eq %w(de en es pt) + end + end + + describe '#translate' do + it 'returns translation with specified source language' do + stub_request(:post, 'https://libretranslate.example.com/translate') + .with(body: '{"q":["Hasta la vista"],"source":"es","target":"en","format":"html","api_key":"my-api-key"}') + .to_return(body: '{"translatedText": ["See you"]}') + + translations = service.translate(['Hasta la vista'], 'es', 'en') + expect(translations.size).to eq 1 + + translation = translations.first + expect(translation.detected_source_language).to be 'es' + expect(translation.provider).to eq 'LibreTranslate' + expect(translation.text).to eq 'See you' + end + + it 'returns translation with auto-detected source language' do + stub_request(:post, 'https://libretranslate.example.com/translate') + .with(body: '{"q":["Guten Morgen"],"source":"auto","target":"en","format":"html","api_key":"my-api-key"}') + .to_return(body: '{"detectedLanguage": [{"confidence": 92, "language": "de"}], "translatedText": ["Good morning"]}') + + translations = service.translate(['Guten Morgen'], nil, 'en') + expect(translations.size).to eq 1 + + translation = translations.first + expect(translation.detected_source_language).to eq 'de' + expect(translation.provider).to eq 'LibreTranslate' + expect(translation.text).to eq 'Good morning' + end + + it 'returns translation of multiple texts' do + stub_request(:post, 'https://libretranslate.example.com/translate') + .with(body: '{"q":["Guten Morgen","Gute Nacht"],"source":"de","target":"en","format":"html","api_key":"my-api-key"}') + .to_return(body: '{"translatedText": ["Good morning", "Good night"]}') + + translations = service.translate(['Guten Morgen', 'Gute Nacht'], 'de', 'en') + expect(translations.size).to eq 2 + + expect(translations.first.text).to eq 'Good morning' + expect(translations.last.text).to eq 'Good night' + end + end +end diff --git a/spec/lib/user_settings_decorator_spec.rb b/spec/lib/user_settings_decorator_spec.rb deleted file mode 100644 index 462c5b1249..0000000000 --- a/spec/lib/user_settings_decorator_spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe UserSettingsDecorator do - describe 'update' do - let(:user) { Fabricate(:user) } - let(:settings) { described_class.new(user) } - - it 'updates the user settings value for email notifications' do - values = { 'notification_emails' => { 'follow' => '1' } } - - settings.update(values) - expect(user.settings['notification_emails']['follow']).to eq true - end - - it 'updates the user settings value for interactions' do - values = { 'interactions' => { 'must_be_follower' => '0' } } - - settings.update(values) - expect(user.settings['interactions']['must_be_follower']).to eq false - end - - it 'updates the user settings value for privacy' do - values = { 'setting_default_privacy' => 'public' } - - settings.update(values) - expect(user.settings['default_privacy']).to eq 'public' - end - - it 'updates the user settings value for sensitive' do - values = { 'setting_default_sensitive' => '1' } - - settings.update(values) - expect(user.settings['default_sensitive']).to eq true - end - - it 'updates the user settings value for unfollow modal' do - values = { 'setting_unfollow_modal' => '0' } - - settings.update(values) - expect(user.settings['unfollow_modal']).to eq false - end - - it 'updates the user settings value for boost modal' do - values = { 'setting_boost_modal' => '1' } - - settings.update(values) - expect(user.settings['boost_modal']).to eq true - end - - it 'updates the user settings value for delete toot modal' do - values = { 'setting_delete_modal' => '0' } - - settings.update(values) - expect(user.settings['delete_modal']).to eq false - end - - it 'updates the user settings value for gif auto play' do - values = { 'setting_auto_play_gif' => '0' } - - settings.update(values) - expect(user.settings['auto_play_gif']).to eq false - end - - it 'updates the user settings value for system font in UI' do - values = { 'setting_system_font_ui' => '0' } - - settings.update(values) - expect(user.settings['system_font_ui']).to eq false - end - - it 'decoerces setting values before applying' do - values = { - 'setting_delete_modal' => 'false', - 'setting_boost_modal' => 'true', - } - - settings.update(values) - expect(user.settings['delete_modal']).to eq false - expect(user.settings['boost_modal']).to eq true - end - end -end diff --git a/spec/lib/vacuum/access_tokens_vacuum_spec.rb b/spec/lib/vacuum/access_tokens_vacuum_spec.rb index 39c8cdb397..54760c41bd 100644 --- a/spec/lib/vacuum/access_tokens_vacuum_spec.rb +++ b/spec/lib/vacuum/access_tokens_vacuum_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::AccessTokensVacuum do diff --git a/spec/lib/vacuum/applications_vacuum_spec.rb b/spec/lib/vacuum/applications_vacuum_spec.rb new file mode 100644 index 0000000000..57a222aafc --- /dev/null +++ b/spec/lib/vacuum/applications_vacuum_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Vacuum::ApplicationsVacuum do + subject { described_class.new } + + describe '#perform' do + let!(:app_with_token) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app_with_grant) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app_with_signup) { Fabricate(:application, created_at: 1.month.ago) } + let!(:app_with_owner) { Fabricate(:application, created_at: 1.month.ago, owner: Fabricate(:user)) } + let!(:unused_app) { Fabricate(:application, created_at: 1.month.ago) } + let!(:recent_app) { Fabricate(:application, created_at: 1.hour.ago) } + + let!(:active_access_token) { Fabricate(:access_token, application: app_with_token) } + let!(:active_access_grant) { Fabricate(:access_grant, application: app_with_grant) } + let!(:user) { Fabricate(:user, created_by_application: app_with_signup) } + + before do + subject.perform + end + + it 'does not delete applications with valid access tokens' do + expect { app_with_token.reload }.to_not raise_error + end + + it 'does not delete applications with valid access grants' do + expect { app_with_grant.reload }.to_not raise_error + end + + it 'does not delete applications that were used to create users' do + expect { app_with_signup.reload }.to_not raise_error + end + + it 'does not delete owned applications' do + expect { app_with_owner.reload }.to_not raise_error + end + + it 'does not delete applications registered less than a day ago' do + expect { recent_app.reload }.to_not raise_error + end + + it 'deletes unused applications' do + expect { unused_app.reload }.to raise_error ActiveRecord::RecordNotFound + end + end +end diff --git a/spec/lib/vacuum/backups_vacuum_spec.rb b/spec/lib/vacuum/backups_vacuum_spec.rb index 4e2de083f8..867dbe4020 100644 --- a/spec/lib/vacuum/backups_vacuum_spec.rb +++ b/spec/lib/vacuum/backups_vacuum_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::BackupsVacuum do - let(:retention_period) { 7.days } - subject { described_class.new(retention_period) } + let(:retention_period) { 7.days } + describe '#perform' do let!(:expired_backup) { Fabricate(:backup, created_at: (retention_period + 1.day).ago) } let!(:current_backup) { Fabricate(:backup) } diff --git a/spec/lib/vacuum/feeds_vacuum_spec.rb b/spec/lib/vacuum/feeds_vacuum_spec.rb index 0aec26740f..ede1e3c360 100644 --- a/spec/lib/vacuum/feeds_vacuum_spec.rb +++ b/spec/lib/vacuum/feeds_vacuum_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::FeedsVacuum do diff --git a/spec/lib/vacuum/imports_vacuum_spec.rb b/spec/lib/vacuum/imports_vacuum_spec.rb new file mode 100644 index 0000000000..1e0abc5e01 --- /dev/null +++ b/spec/lib/vacuum/imports_vacuum_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Vacuum::ImportsVacuum do + subject { described_class.new } + + let!(:old_unconfirmed) { Fabricate(:bulk_import, state: :unconfirmed, created_at: 2.days.ago) } + let!(:new_unconfirmed) { Fabricate(:bulk_import, state: :unconfirmed, created_at: 10.seconds.ago) } + let!(:recent_ongoing) { Fabricate(:bulk_import, state: :in_progress, created_at: 20.minutes.ago) } + let!(:recent_finished) { Fabricate(:bulk_import, state: :finished, created_at: 1.day.ago) } + let!(:old_finished) { Fabricate(:bulk_import, state: :finished, created_at: 2.months.ago) } + + describe '#perform' do + it 'cleans up the expected imports' do + expect { subject.perform }.to change { BulkImport.all.pluck(:id) }.from([old_unconfirmed, new_unconfirmed, recent_ongoing, recent_finished, old_finished].map(&:id)).to([new_unconfirmed, recent_ongoing, recent_finished].map(&:id)) + end + end +end diff --git a/spec/lib/vacuum/media_attachments_vacuum_spec.rb b/spec/lib/vacuum/media_attachments_vacuum_spec.rb index be8458d9bf..3c17ecb000 100644 --- a/spec/lib/vacuum/media_attachments_vacuum_spec.rb +++ b/spec/lib/vacuum/media_attachments_vacuum_spec.rb @@ -1,10 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::MediaAttachmentsVacuum do - let(:retention_period) { 7.days } - subject { described_class.new(retention_period) } + let(:retention_period) { 7.days } let(:remote_status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com')) } let(:local_status) { Fabricate(:status) } diff --git a/spec/lib/vacuum/preview_cards_vacuum_spec.rb b/spec/lib/vacuum/preview_cards_vacuum_spec.rb index 275f9ba92f..c1b7f7e9c5 100644 --- a/spec/lib/vacuum/preview_cards_vacuum_spec.rb +++ b/spec/lib/vacuum/preview_cards_vacuum_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::PreviewCardsVacuum do - let(:retention_period) { 7.days } - subject { described_class.new(retention_period) } + let(:retention_period) { 7.days } + describe '#perform' do let!(:orphaned_preview_card) { Fabricate(:preview_card, created_at: 2.days.ago) } let!(:old_preview_card) { Fabricate(:preview_card, updated_at: (retention_period + 1.day).ago) } diff --git a/spec/lib/vacuum/statuses_vacuum_spec.rb b/spec/lib/vacuum/statuses_vacuum_spec.rb index 83f3c5c9f1..d5c0139506 100644 --- a/spec/lib/vacuum/statuses_vacuum_spec.rb +++ b/spec/lib/vacuum/statuses_vacuum_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::StatusesVacuum do + subject { described_class.new(retention_period) } + let(:retention_period) { 7.days } let(:remote_account) { Fabricate(:account, domain: 'example.com') } - subject { described_class.new(retention_period) } - describe '#perform' do let!(:remote_status_old) { Fabricate(:status, account: remote_account, created_at: (retention_period + 2.days).ago) } let!(:remote_status_recent) { Fabricate(:status, account: remote_account, created_at: (retention_period - 2.days).ago) } diff --git a/spec/lib/vacuum/system_keys_vacuum_spec.rb b/spec/lib/vacuum/system_keys_vacuum_spec.rb index 565892f025..84cae30411 100644 --- a/spec/lib/vacuum/system_keys_vacuum_spec.rb +++ b/spec/lib/vacuum/system_keys_vacuum_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Vacuum::SystemKeysVacuum do diff --git a/spec/lib/webfinger_resource_spec.rb b/spec/lib/webfinger_resource_spec.rb index 5c7f475d69..558a318927 100644 --- a/spec/lib/webfinger_resource_spec.rb +++ b/spec/lib/webfinger_resource_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe WebfingerResource do @@ -14,9 +16,9 @@ describe WebfingerResource do it 'raises with a route whose controller is not AccountsController' do resource = 'https://example.com/users/alice/other' - expect { - WebfingerResource.new(resource).username - }.to raise_error(ActiveRecord::RecordNotFound) + expect do + described_class.new(resource).username + end.to raise_error(ActiveRecord::RecordNotFound) end it 'raises with a route whose action is not show' do @@ -25,41 +27,42 @@ describe WebfingerResource do recognized = Rails.application.routes.recognize_path(resource) allow(recognized).to receive(:[]).with(:controller).and_return('accounts') allow(recognized).to receive(:[]).with(:username).and_return('alice') - expect(recognized).to receive(:[]).with(:action).and_return('create') + allow(recognized).to receive(:[]).with(:action).and_return('create') expect(Rails.application.routes).to receive(:recognize_path).with(resource).and_return(recognized).at_least(:once) - expect { - WebfingerResource.new(resource).username - }.to raise_error(ActiveRecord::RecordNotFound) + expect do + described_class.new(resource).username + end.to raise_error(ActiveRecord::RecordNotFound) + expect(recognized).to have_received(:[]).exactly(3).times end it 'raises with a string that doesnt start with URL' do resource = 'website for http://example.com/users/alice/other' - expect { - WebfingerResource.new(resource).username - }.to raise_error(WebfingerResource::InvalidRequest) + expect do + described_class.new(resource).username + end.to raise_error(WebfingerResource::InvalidRequest) end it 'finds the username in a valid https route' do resource = 'https://example.com/users/alice' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end it 'finds the username in a mixed case http route' do resource = 'HTTp://exAMPLe.com/users/alice' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end it 'finds the username in a valid http route' do resource = 'http://example.com/users/alice' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end end @@ -68,16 +71,16 @@ describe WebfingerResource do it 'raises on a non-local domain' do resource = 'user@remote-host.com' - expect { - WebfingerResource.new(resource).username - }.to raise_error(ActiveRecord::RecordNotFound) + expect do + described_class.new(resource).username + end.to raise_error(ActiveRecord::RecordNotFound) end it 'finds username for a local domain' do Rails.configuration.x.local_domain = 'example.com' resource = 'alice@example.com' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end @@ -85,7 +88,7 @@ describe WebfingerResource do Rails.configuration.x.web_domain = 'example.com' resource = 'alice@example.com' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end end @@ -94,24 +97,24 @@ describe WebfingerResource do it 'raises on a non-local domain' do resource = 'acct:user@remote-host.com' - expect { - WebfingerResource.new(resource).username - }.to raise_error(ActiveRecord::RecordNotFound) + expect do + described_class.new(resource).username + end.to raise_error(ActiveRecord::RecordNotFound) end it 'raises on a nonsense domain' do resource = 'acct:user@remote-host@remote-hostess.remote.local@remote' - expect { - WebfingerResource.new(resource).username - }.to raise_error(ActiveRecord::RecordNotFound) + expect do + described_class.new(resource).username + end.to raise_error(ActiveRecord::RecordNotFound) end it 'finds the username for a local account if the domain is the local one' do Rails.configuration.x.local_domain = 'example.com' resource = 'acct:alice@example.com' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end @@ -119,7 +122,7 @@ describe WebfingerResource do Rails.configuration.x.web_domain = 'example.com' resource = 'acct:alice@example.com' - result = WebfingerResource.new(resource).username + result = described_class.new(resource).username expect(result).to eq 'alice' end end @@ -128,9 +131,9 @@ describe WebfingerResource do it 'raises InvalidRequest' do resource = 'df/:dfkj' - expect { - WebfingerResource.new(resource).username - }.to raise_error(WebfingerResource::InvalidRequest) + expect do + described_class.new(resource).username + end.to raise_error(WebfingerResource::InvalidRequest) end end end diff --git a/spec/lib/webhooks/payload_renderer_spec.rb b/spec/lib/webhooks/payload_renderer_spec.rb new file mode 100644 index 0000000000..074847c74c --- /dev/null +++ b/spec/lib/webhooks/payload_renderer_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Webhooks::PayloadRenderer do + subject(:renderer) { described_class.new(json) } + + let(:event) { Webhooks::EventPresenter.new(type, object) } + let(:payload) { ActiveModelSerializers::SerializableResource.new(event, serializer: REST::Admin::WebhookEventSerializer, scope: nil, scope_name: :current_user).as_json } + let(:json) { Oj.dump(payload) } + + describe '#render' do + context 'when event is account.approved' do + let(:type) { 'account.approved' } + let(:object) { Fabricate(:account, display_name: 'Foo"') } + + it 'renders event-related variables into template' do + expect(renderer.render('foo={{event}}')).to eq 'foo=account.approved' + end + + it 'renders event-specific variables into template' do + expect(renderer.render('foo={{object.username}}')).to eq "foo=#{object.username}" + end + + it 'escapes values for use in JSON' do + expect(renderer.render('foo={{object.account.display_name}}')).to eq 'foo=Foo\\"' + end + end + end +end diff --git a/spec/locales/i18n_spec.rb b/spec/locales/i18n_spec.rb new file mode 100644 index 0000000000..cfce8e2234 --- /dev/null +++ b/spec/locales/i18n_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'I18n' do + describe 'Pluralizing locale translations' do + subject { I18n.t('generic.validation_errors', count: 1) } + + context 'with the `en` locale which has `one` and `other` plural values' do + around do |example| + I18n.with_locale(:en) do + example.run + end + end + + it 'translates to `en` correctly and without error' do + expect { subject }.to_not raise_error + expect(subject).to match(/the error below/) + end + end + + context 'with the `my` locale which has only `other` plural value' do + around do |example| + I18n.with_locale(:my) do + example.run + end + end + + it 'translates to `my` correctly and without error' do + expect { subject }.to_not raise_error + expect(subject).to match(/1/) + end + end + end +end diff --git a/spec/mailers/admin_mailer_spec.rb b/spec/mailers/admin_mailer_spec.rb index 29fb586a34..423dce88ab 100644 --- a/spec/mailers/admin_mailer_spec.rb +++ b/spec/mailers/admin_mailer_spec.rb @@ -2,12 +2,12 @@ require 'rails_helper' -RSpec.describe AdminMailer, type: :mailer do +RSpec.describe AdminMailer do describe '.new_report' do let(:sender) { Fabricate(:account, username: 'John') } let(:recipient) { Fabricate(:account, username: 'Mike') } let(:report) { Fabricate(:report, account: sender, target_account: recipient) } - let(:mail) { described_class.new_report(recipient, report) } + let(:mail) { described_class.with(recipient: recipient).new_report(report) } before do recipient.user.update(locale: :en) @@ -23,4 +23,108 @@ RSpec.describe AdminMailer, type: :mailer do expect(mail.body.encoded).to eq("Mike,\r\n\r\nJohn has reported Mike\r\n\r\nView: https://cb6e6126.ngrok.io/admin/reports/#{report.id}\r\n") end end + + describe '.new_appeal' do + let(:appeal) { Fabricate(:appeal) } + let(:recipient) { Fabricate(:account, username: 'Kurt') } + let(:mail) { described_class.with(recipient: recipient).new_appeal(appeal) } + + before do + recipient.user.update(locale: :en) + end + + it 'renders the headers' do + expect(mail.subject).to eq("#{appeal.account.username} is appealing a moderation decision on cb6e6126.ngrok.io") + expect(mail.to).to eq [recipient.user_email] + expect(mail.from).to eq ['notifications@localhost'] + end + + it 'renders the body' do + expect(mail.body.encoded).to match "#{appeal.account.username} is appealing a moderation decision by #{appeal.strike.account.username}" + end + end + + describe '.new_pending_account' do + let(:recipient) { Fabricate(:account, username: 'Barklums') } + let(:user) { Fabricate(:user) } + let(:mail) { described_class.with(recipient: recipient).new_pending_account(user) } + + before do + recipient.user.update(locale: :en) + end + + it 'renders the headers' do + expect(mail.subject).to eq("New account up for review on cb6e6126.ngrok.io (#{user.account.username})") + expect(mail.to).to eq [recipient.user_email] + expect(mail.from).to eq ['notifications@localhost'] + end + + it 'renders the body' do + expect(mail.body.encoded).to match 'The details of the new account are below. You can approve or reject this application.' + end + end + + describe '.new_trends' do + let(:recipient) { Fabricate(:account, username: 'Snurf') } + let(:links) { [] } + let(:statuses) { [] } + let(:tags) { [] } + let(:mail) { described_class.with(recipient: recipient).new_trends(links, tags, statuses) } + + before do + recipient.user.update(locale: :en) + end + + it 'renders the headers' do + expect(mail.subject).to eq('New trends up for review on cb6e6126.ngrok.io') + expect(mail.to).to eq [recipient.user_email] + expect(mail.from).to eq ['notifications@localhost'] + end + + it 'renders the body' do + expect(mail.body.encoded).to match 'The following items need a review before they can be displayed publicly' + end + end + + describe '.new_software_updates' do + let(:recipient) { Fabricate(:account, username: 'Bob') } + let(:mail) { described_class.with(recipient: recipient).new_software_updates } + + before do + recipient.user.update(locale: :en) + end + + it 'renders the headers' do + expect(mail.subject).to eq('New Mastodon versions are available for cb6e6126.ngrok.io!') + expect(mail.to).to eq [recipient.user_email] + expect(mail.from).to eq ['notifications@localhost'] + end + + it 'renders the body' do + expect(mail.body.encoded).to match 'New Mastodon versions have been released, you may want to update!' + end + end + + describe '.new_critical_software_updates' do + let(:recipient) { Fabricate(:account, username: 'Bob') } + let(:mail) { described_class.with(recipient: recipient).new_critical_software_updates } + + before do + recipient.user.update(locale: :en) + end + + it 'renders the headers', :aggregate_failures do + expect(mail.subject).to eq('Critical Mastodon updates are available for cb6e6126.ngrok.io!') + expect(mail.to).to eq [recipient.user_email] + expect(mail.from).to eq ['notifications@localhost'] + + expect(mail['Importance'].value).to eq 'high' + expect(mail['Priority'].value).to eq 'urgent' + expect(mail['X-Priority'].value).to eq '1' + end + + it 'renders the body' do + expect(mail.body.encoded).to match 'New critical versions of Mastodon have been released, you may want to update as soon as possible!' + end + end end diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index 29bdc349b8..78a497c06b 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -1,104 +1,125 @@ -require "rails_helper" +# frozen_string_literal: true -RSpec.describe NotificationMailer, type: :mailer do - let(:receiver) { Fabricate(:user) } +require 'rails_helper' + +RSpec.describe NotificationMailer do + let(:receiver) { Fabricate(:user, account_attributes: { username: 'alice' }) } let(:sender) { Fabricate(:account, username: 'bob') } let(:foreign_status) { Fabricate(:status, account: sender, text: 'The body of the foreign status') } let(:own_status) { Fabricate(:status, account: receiver.account, text: 'The body of the own status') } - shared_examples 'localized subject' do |*args, **kwrest| - it 'renders subject localized for the locale of the receiver' do - locale = %i(de en).sample - receiver.update!(locale: locale) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: locale)) + shared_examples 'headers' do |type, thread| + it 'renders the to and from headers' do + expect(mail[:to].value).to eq "#{receiver.account.username} <#{receiver.email}>" + expect(mail.from).to eq ['notifications@localhost'] end - it 'renders subject localized for the default locale if the locale of the receiver is unavailable' do - receiver.update!(locale: nil) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: I18n.default_locale)) + it 'renders the list headers' do + expect(mail['List-ID'].value).to eq "<#{type}.alice.cb6e6126.ngrok.io>" + expect(mail['List-Unsubscribe'].value).to match(%r{}) + expect(mail['List-Unsubscribe'].value).to match("&type=#{type}") + expect(mail['List-Unsubscribe-Post'].value).to eq 'List-Unsubscribe=One-Click' + end + + if thread + it 'renders the thread headers' do + expect(mail['In-Reply-To'].value).to match(//) + expect(mail['References'].value).to match(//) + end end end - describe "mention" do + describe 'mention' do let(:mention) { Mention.create!(account: receiver.account, status: foreign_status) } - let(:mail) { NotificationMailer.mention(receiver.account, Notification.create!(account: receiver.account, activity: mention)) } + let(:notification) { Notification.create!(account: receiver.account, activity: mention) } + let(:mail) { prepared_mailer_for(receiver.account).mention } include_examples 'localized subject', 'notification_mailer.mention.subject', name: 'bob' + include_examples 'headers', 'mention', true - it "renders the headers" do - expect(mail.subject).to eq("You were mentioned by bob") - expect(mail.to).to eq([receiver.email]) + it 'renders the subject' do + expect(mail.subject).to eq('You were mentioned by bob') end - it "renders the body" do - expect(mail.body.encoded).to match("You were mentioned by bob") + it 'renders the body' do + expect(mail.body.encoded).to match('You were mentioned by bob') expect(mail.body.encoded).to include 'The body of the foreign status' end end - describe "follow" do + describe 'follow' do let(:follow) { sender.follow!(receiver.account) } - let(:mail) { NotificationMailer.follow(receiver.account, Notification.create!(account: receiver.account, activity: follow)) } + let(:notification) { Notification.create!(account: receiver.account, activity: follow) } + let(:mail) { prepared_mailer_for(receiver.account).follow } include_examples 'localized subject', 'notification_mailer.follow.subject', name: 'bob' + include_examples 'headers', 'follow', false - it "renders the headers" do - expect(mail.subject).to eq("bob is now following you") - expect(mail.to).to eq([receiver.email]) + it 'renders the subject' do + expect(mail.subject).to eq('bob is now following you') end - it "renders the body" do - expect(mail.body.encoded).to match("bob is now following you") + it 'renders the body' do + expect(mail.body.encoded).to match('bob is now following you') end end - describe "favourite" do + describe 'favourite' do let(:favourite) { Favourite.create!(account: sender, status: own_status) } - let(:mail) { NotificationMailer.favourite(own_status.account, Notification.create!(account: receiver.account, activity: favourite)) } + let(:notification) { Notification.create!(account: receiver.account, activity: favourite) } + let(:mail) { prepared_mailer_for(own_status.account).favourite } include_examples 'localized subject', 'notification_mailer.favourite.subject', name: 'bob' + include_examples 'headers', 'favourite', true - it "renders the headers" do - expect(mail.subject).to eq("bob favourited your post") - expect(mail.to).to eq([receiver.email]) + it 'renders the subject' do + expect(mail.subject).to eq('bob favorited your post') end - it "renders the body" do - expect(mail.body.encoded).to match("Your post was favourited by bob") + it 'renders the body' do + expect(mail.body.encoded).to match('Your post was favorited by bob') expect(mail.body.encoded).to include 'The body of the own status' end end - describe "reblog" do + describe 'reblog' do let(:reblog) { Status.create!(account: sender, reblog: own_status) } - let(:mail) { NotificationMailer.reblog(own_status.account, Notification.create!(account: receiver.account, activity: reblog)) } + let(:notification) { Notification.create!(account: receiver.account, activity: reblog) } + let(:mail) { prepared_mailer_for(own_status.account).reblog } include_examples 'localized subject', 'notification_mailer.reblog.subject', name: 'bob' + include_examples 'headers', 'reblog', true - it "renders the headers" do - expect(mail.subject).to eq("bob boosted your post") - expect(mail.to).to eq([receiver.email]) + it 'renders the subject' do + expect(mail.subject).to eq('bob boosted your post') end - it "renders the body" do - expect(mail.body.encoded).to match("Your post was boosted by bob") + it 'renders the body' do + expect(mail.body.encoded).to match('Your post was boosted by bob') expect(mail.body.encoded).to include 'The body of the own status' end end describe 'follow_request' do let(:follow_request) { Fabricate(:follow_request, account: sender, target_account: receiver.account) } - let(:mail) { NotificationMailer.follow_request(receiver.account, Notification.create!(account: receiver.account, activity: follow_request)) } + let(:notification) { Notification.create!(account: receiver.account, activity: follow_request) } + let(:mail) { prepared_mailer_for(receiver.account).follow_request } include_examples 'localized subject', 'notification_mailer.follow_request.subject', name: 'bob' + include_examples 'headers', 'follow_request', false - it 'renders the headers' do + it 'renders the subject' do expect(mail.subject).to eq('Pending follower: bob') - expect(mail.to).to eq([receiver.email]) end it 'renders the body' do - expect(mail.body.encoded).to match("bob has requested to follow you") + expect(mail.body.encoded).to match('bob has requested to follow you') end end + + private + + def prepared_mailer_for(recipient) + described_class.with(recipient: recipient, notification: notification) + end end diff --git a/spec/mailers/previews/admin_mailer_preview.rb b/spec/mailers/previews/admin_mailer_preview.rb index 0ec9e9882c..bc8f0193b9 100644 --- a/spec/mailers/previews/admin_mailer_preview.rb +++ b/spec/mailers/previews/admin_mailer_preview.rb @@ -1,18 +1,20 @@ +# frozen_string_literal: true + # Preview all emails at http://localhost:3000/rails/mailers/admin_mailer class AdminMailerPreview < ActionMailer::Preview # Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_pending_account def new_pending_account - AdminMailer.new_pending_account(Account.first, User.pending.first) + AdminMailer.with(recipient: Account.first).new_pending_account(User.pending.first) end # Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_trends def new_trends - AdminMailer.new_trends(Account.first, PreviewCard.joins(:trend).limit(3), Tag.limit(3), Status.joins(:trend).where(reblog_of_id: nil).limit(3)) + AdminMailer.with(recipient: Account.first).new_trends(PreviewCard.joins(:trend).limit(3), Tag.limit(3), Status.joins(:trend).where(reblog_of_id: nil).limit(3)) end # Preview this email at http://localhost:3000/rails/mailers/admin_mailer/new_appeal def new_appeal - AdminMailer.new_appeal(Account.first, Appeal.first) + AdminMailer.with(recipient: Account.first).new_appeal(Appeal.first) end end diff --git a/spec/mailers/previews/notification_mailer_preview.rb b/spec/mailers/previews/notification_mailer_preview.rb index e31445c365..a63c20c27c 100644 --- a/spec/mailers/previews/notification_mailer_preview.rb +++ b/spec/mailers/previews/notification_mailer_preview.rb @@ -1,38 +1,44 @@ +# frozen_string_literal: true + # Preview all emails at http://localhost:3000/rails/mailers/notification_mailer class NotificationMailerPreview < ActionMailer::Preview # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/mention def mention - m = Mention.last - NotificationMailer.mention(m.account, Notification.find_by(activity: m)) + activity = Mention.last + mailer_for(activity.account, activity).mention end # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/follow def follow - f = Follow.last - NotificationMailer.follow(f.target_account, Notification.find_by(activity: f)) + activity = Follow.last + mailer_for(activity.target_account, activity).follow end # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/follow_request def follow_request - f = Follow.last - NotificationMailer.follow_request(f.target_account, Notification.find_by(activity: f)) + activity = Follow.last + mailer_for(activity.target_account, activity).follow_request end # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/favourite def favourite - f = Favourite.last - NotificationMailer.favourite(f.status.account, Notification.find_by(activity: f)) + activity = Favourite.last + mailer_for(activity.status.account, activity).favourite end # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/reblog def reblog - r = Status.where.not(reblog_of_id: nil).first - NotificationMailer.reblog(r.reblog.account, Notification.find_by(activity: r)) + activity = Status.where.not(reblog_of_id: nil).first + mailer_for(activity.reblog.account, activity).reblog end - # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/digest - def digest - NotificationMailer.digest(Account.first, since: 90.days.ago) + private + + def mailer_for(account, activity) + NotificationMailer.with( + recipient: account, + notification: Notification.find_by(activity: activity) + ) end end diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index 95712e6cf4..098c9cd901 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Preview all emails at http://localhost:3000/rails/mailers/user_mailer class UserMailerPreview < ActionMailer::Preview diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 2ed33c1e4a..5affa66e07 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -2,24 +2,11 @@ require 'rails_helper' -describe UserMailer, type: :mailer do +describe UserMailer do let(:receiver) { Fabricate(:user) } - shared_examples 'localized subject' do |*args, **kwrest| - it 'renders subject localized for the locale of the receiver' do - locale = I18n.available_locales.sample - receiver.update!(locale: locale) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: locale)) - end - - it 'renders subject localized for the default locale if the locale of the receiver is unavailable' do - receiver.update!(locale: nil) - expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: I18n.default_locale)) - end - end - describe 'confirmation_instructions' do - let(:mail) { UserMailer.confirmation_instructions(receiver, 'spec') } + let(:mail) { described_class.confirmation_instructions(receiver, 'spec') } it 'renders confirmation instructions' do receiver.update!(locale: nil) @@ -34,7 +21,7 @@ describe UserMailer, type: :mailer do end describe 'reconfirmation_instructions' do - let(:mail) { UserMailer.confirmation_instructions(receiver, 'spec') } + let(:mail) { described_class.confirmation_instructions(receiver, 'spec') } it 'renders reconfirmation instructions' do receiver.update!(email: 'new-email@example.com', locale: nil) @@ -48,7 +35,7 @@ describe UserMailer, type: :mailer do end describe 'reset_password_instructions' do - let(:mail) { UserMailer.reset_password_instructions(receiver, 'spec') } + let(:mail) { described_class.reset_password_instructions(receiver, 'spec') } it 'renders reset password instructions' do receiver.update!(locale: nil) @@ -61,7 +48,7 @@ describe UserMailer, type: :mailer do end describe 'password_change' do - let(:mail) { UserMailer.password_change(receiver) } + let(:mail) { described_class.password_change(receiver) } it 'renders password change notification' do receiver.update!(locale: nil) @@ -73,7 +60,7 @@ describe UserMailer, type: :mailer do end describe 'email_changed' do - let(:mail) { UserMailer.email_changed(receiver) } + let(:mail) { described_class.email_changed(receiver) } it 'renders email change notification' do receiver.update!(locale: nil) @@ -86,12 +73,115 @@ describe UserMailer, type: :mailer do describe 'warning' do let(:strike) { Fabricate(:account_warning, target_account: receiver.account, text: 'dont worry its just the testsuite', action: 'suspend') } - let(:mail) { UserMailer.warning(receiver, strike) } + let(:mail) { described_class.warning(receiver, strike) } it 'renders warning notification' do receiver.update!(locale: nil) - expect(mail.body.encoded).to include I18n.t("user_mailer.warning.title.suspend", acct: receiver.account.acct) + expect(mail.body.encoded).to include I18n.t('user_mailer.warning.title.suspend', acct: receiver.account.acct) expect(mail.body.encoded).to include strike.text end end + + describe 'webauthn_credential_deleted' do + let(:credential) { Fabricate(:webauthn_credential, user_id: receiver.id) } + let(:mail) { described_class.webauthn_credential_deleted(receiver, credential) } + + it 'renders webauthn credential deleted notification' do + receiver.update!(locale: nil) + expect(mail.body.encoded).to include I18n.t('devise.mailer.webauthn_credential.deleted.title') + end + + include_examples 'localized subject', + 'devise.mailer.webauthn_credential.deleted.subject' + end + + describe 'suspicious_sign_in' do + let(:ip) { '192.168.0.1' } + let(:agent) { 'NCSA_Mosaic/2.0 (Windows 3.1)' } + let(:timestamp) { Time.now.utc } + let(:mail) { described_class.suspicious_sign_in(receiver, ip, agent, timestamp) } + + it 'renders suspicious sign in notification' do + receiver.update!(locale: nil) + expect(mail.body.encoded).to include I18n.t('user_mailer.suspicious_sign_in.explanation') + end + + include_examples 'localized subject', + 'user_mailer.suspicious_sign_in.subject' + end + + describe 'appeal_approved' do + let(:appeal) { Fabricate(:appeal, account: receiver.account, approved_at: Time.now.utc) } + let(:mail) { described_class.appeal_approved(receiver, appeal) } + + it 'renders appeal_approved notification' do + expect(mail.subject).to eq I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at)) + expect(mail.body.encoded).to include I18n.t('user_mailer.appeal_approved.title') + end + end + + describe 'appeal_rejected' do + let(:appeal) { Fabricate(:appeal, account: receiver.account, rejected_at: Time.now.utc) } + let(:mail) { described_class.appeal_rejected(receiver, appeal) } + + it 'renders appeal_rejected notification' do + expect(mail.subject).to eq I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at)) + expect(mail.body.encoded).to include I18n.t('user_mailer.appeal_rejected.title') + end + end + + describe 'two_factor_enabled' do + let(:mail) { described_class.two_factor_enabled(receiver) } + + it 'renders two_factor_enabled mail' do + expect(mail.subject).to eq I18n.t('devise.mailer.two_factor_enabled.subject') + expect(mail.body.encoded).to include I18n.t('devise.mailer.two_factor_enabled.explanation') + end + end + + describe 'two_factor_disabled' do + let(:mail) { described_class.two_factor_disabled(receiver) } + + it 'renders two_factor_disabled mail' do + expect(mail.subject).to eq I18n.t('devise.mailer.two_factor_disabled.subject') + expect(mail.body.encoded).to include I18n.t('devise.mailer.two_factor_disabled.explanation') + end + end + + describe 'webauthn_enabled' do + let(:mail) { described_class.webauthn_enabled(receiver) } + + it 'renders webauthn_enabled mail' do + expect(mail.subject).to eq I18n.t('devise.mailer.webauthn_enabled.subject') + expect(mail.body.encoded).to include I18n.t('devise.mailer.webauthn_enabled.explanation') + end + end + + describe 'webauthn_disabled' do + let(:mail) { described_class.webauthn_disabled(receiver) } + + it 'renders webauthn_disabled mail' do + expect(mail.subject).to eq I18n.t('devise.mailer.webauthn_disabled.subject') + expect(mail.body.encoded).to include I18n.t('devise.mailer.webauthn_disabled.explanation') + end + end + + describe 'two_factor_recovery_codes_changed' do + let(:mail) { described_class.two_factor_recovery_codes_changed(receiver) } + + it 'renders two_factor_recovery_codes_changed mail' do + expect(mail.subject).to eq I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject') + expect(mail.body.encoded).to include I18n.t('devise.mailer.two_factor_recovery_codes_changed.explanation') + end + end + + describe 'webauthn_credential_added' do + let(:credential) { Fabricate.build(:webauthn_credential) } + let(:mail) { described_class.webauthn_credential_added(receiver, credential) } + + it 'renders webauthn_credential_added mail' do + expect(mail.subject).to eq I18n.t('devise.mailer.webauthn_credential.added.subject') + expect(mail.body.encoded).to include I18n.t('devise.mailer.webauthn_credential.added.explanation') + end + end end diff --git a/spec/models/account/field_spec.rb b/spec/models/account/field_spec.rb index 0ac9769bcc..22593bb218 100644 --- a/spec/models/account/field_spec.rb +++ b/spec/models/account/field_spec.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Account::Field, type: :model do +RSpec.describe Account::Field do describe '#verified?' do - let(:account) { double('Account', local?: true) } - subject { described_class.new(account, 'name' => 'Foo', 'value' => 'Bar', 'verified_at' => verified_at) } + let(:account) { instance_double(Account, local?: true) } + context 'when verified_at is set' do let(:verified_at) { Time.now.utc.iso8601 } @@ -24,11 +26,11 @@ RSpec.describe Account::Field, type: :model do end describe '#mark_verified!' do - let(:account) { double('Account', local?: true) } - let(:original_hash) { { 'name' => 'Foo', 'value' => 'Bar' } } - subject { described_class.new(account, original_hash) } + let(:account) { instance_double(Account, local?: true) } + let(:original_hash) { { 'name' => 'Foo', 'value' => 'Bar' } } + before do subject.mark_verified! end @@ -43,14 +45,14 @@ RSpec.describe Account::Field, type: :model do end describe '#verifiable?' do - let(:account) { double('Account', local?: local) } - subject { described_class.new(account, 'name' => 'Foo', 'value' => value) } - context 'for local accounts' do + let(:account) { instance_double(Account, local?: local) } + + context 'with local accounts' do let(:local) { true } - context 'for a URL with misleading authentication' do + context 'with a URL with misleading authentication' do let(:value) { 'https://spacex.com @h.43z.one' } it 'returns false' do @@ -58,7 +60,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for a URL' do + context 'with a URL' do let(:value) { 'https://example.com' } it 'returns true' do @@ -66,7 +68,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for an IDN URL' do + context 'with an IDN URL' do let(:value) { 'https://twitter.com∕dougallj∕status∕1590357240443437057.ê.cc/twitter.html' } it 'returns false' do @@ -74,7 +76,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for a URL with a non-normalized path' do + context 'with a URL with a non-normalized path' do let(:value) { 'https://github.com/octocatxxxxxxxx/../mastodon' } it 'returns false' do @@ -82,7 +84,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for text that is not a URL' do + context 'with text that is not a URL' do let(:value) { 'Hello world' } it 'returns false' do @@ -90,15 +92,15 @@ RSpec.describe Account::Field, type: :model do end end - context 'for text that contains a URL' do + context 'with text that contains a URL' do let(:value) { 'Hello https://example.com world' } it 'returns false' do expect(subject.verifiable?).to be false end end - - context 'for text which is blank' do + + context 'with text which is blank' do let(:value) { '' } it 'returns false' do @@ -107,10 +109,10 @@ RSpec.describe Account::Field, type: :model do end end - context 'for remote accounts' do + context 'with remote accounts' do let(:local) { false } - context 'for a link' do + context 'with a link' do let(:value) { 'patreon.com/mastodon' } it 'returns true' do @@ -118,7 +120,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for a link with misleading authentication' do + context 'with a link with misleading authentication' do let(:value) { 'google.com' } it 'returns false' do @@ -126,7 +128,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for HTML that has more than just a link' do + context 'with HTML that has more than just a link' do let(:value) { 'google.com @h.43z.one' } it 'returns false' do @@ -134,7 +136,7 @@ RSpec.describe Account::Field, type: :model do end end - context 'for a link with different visible text' do + context 'with a link with different visible text' do let(:value) { 'https://example.com/foo' } it 'returns false' do @@ -142,15 +144,15 @@ RSpec.describe Account::Field, type: :model do end end - context 'for text that is a URL but is not linked' do + context 'with text that is a URL but is not linked' do let(:value) { 'https://example.com/foo' } it 'returns false' do expect(subject.verifiable?).to be false end end - - context 'for text which is blank' do + + context 'with text which is blank' do let(:value) { '' } it 'returns false' do diff --git a/spec/models/account_alias_spec.rb b/spec/models/account_alias_spec.rb deleted file mode 100644 index 27ec215aa4..0000000000 --- a/spec/models/account_alias_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe AccountAlias, type: :model do - -end diff --git a/spec/models/account_conversation_spec.rb b/spec/models/account_conversation_spec.rb index 70a76281ef..4e8727ca39 100644 --- a/spec/models/account_conversation_spec.rb +++ b/spec/models/account_conversation_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AccountConversation, type: :model do +RSpec.describe AccountConversation do let!(:alice) { Fabricate(:account, username: 'alice') } let!(:bob) { Fabricate(:account, username: 'bob') } let!(:mark) { Fabricate(:account, username: 'mark') } @@ -10,7 +12,7 @@ RSpec.describe AccountConversation, type: :model do status = Fabricate(:status, account: alice, visibility: :direct) status.mentions.create(account: bob) - conversation = AccountConversation.add_status(alice, status) + conversation = described_class.add_status(alice, status) expect(conversation.participant_accounts).to include(bob) expect(conversation.last_status).to eq status @@ -19,12 +21,12 @@ RSpec.describe AccountConversation, type: :model do it 'appends to old record when there is a match' do last_status = Fabricate(:status, account: alice, visibility: :direct) - conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id]) + conversation = described_class.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id]) status = Fabricate(:status, account: bob, visibility: :direct, thread: last_status) status.mentions.create(account: alice) - new_conversation = AccountConversation.add_status(alice, status) + new_conversation = described_class.add_status(alice, status) expect(new_conversation.id).to eq conversation.id expect(new_conversation.participant_accounts).to include(bob) @@ -34,13 +36,13 @@ RSpec.describe AccountConversation, type: :model do it 'creates new record when new participants are added' do last_status = Fabricate(:status, account: alice, visibility: :direct) - conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id]) + conversation = described_class.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id]) status = Fabricate(:status, account: bob, visibility: :direct, thread: last_status) status.mentions.create(account: alice) status.mentions.create(account: mark) - new_conversation = AccountConversation.add_status(alice, status) + new_conversation = described_class.add_status(alice, status) expect(new_conversation.id).to_not eq conversation.id expect(new_conversation.participant_accounts).to include(bob, mark) @@ -53,7 +55,7 @@ RSpec.describe AccountConversation, type: :model do it 'updates last status to a previous value' do last_status = Fabricate(:status, account: alice, visibility: :direct) status = Fabricate(:status, account: alice, visibility: :direct) - conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [status.id, last_status.id]) + conversation = described_class.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [status.id, last_status.id]) last_status.mentions.create(account: bob) last_status.destroy! conversation.reload @@ -63,10 +65,10 @@ RSpec.describe AccountConversation, type: :model do it 'removes the record if no other statuses are referenced' do last_status = Fabricate(:status, account: alice, visibility: :direct) - conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id]) + conversation = described_class.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id]) last_status.mentions.create(account: bob) last_status.destroy! - expect(AccountConversation.where(id: conversation.id).count).to eq 0 + expect(described_class.where(id: conversation.id).count).to eq 0 end end end diff --git a/spec/models/account_deletion_request_spec.rb b/spec/models/account_deletion_request_spec.rb deleted file mode 100644 index afaecbe228..0000000000 --- a/spec/models/account_deletion_request_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe AccountDeletionRequest, type: :model do -end diff --git a/spec/models/account_domain_block_spec.rb b/spec/models/account_domain_block_spec.rb index 469bc05cb1..10bd579363 100644 --- a/spec/models/account_domain_block_spec.rb +++ b/spec/models/account_domain_block_spec.rb @@ -1,22 +1,24 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AccountDomainBlock, type: :model do +RSpec.describe AccountDomainBlock do it 'removes blocking cache after creation' do account = Fabricate(:account) Rails.cache.write("exclude_domains_for:#{account.id}", 'a.domain.already.blocked') - AccountDomainBlock.create!(account: account, domain: 'a.domain.blocked.later') + described_class.create!(account: account, domain: 'a.domain.blocked.later') - expect(Rails.cache.exist?("exclude_domains_for:#{account.id}")).to eq false + expect(Rails.cache.exist?("exclude_domains_for:#{account.id}")).to be false end it 'removes blocking cache after destruction' do account = Fabricate(:account) - block = AccountDomainBlock.create!(account: account, domain: 'domain') + block = described_class.create!(account: account, domain: 'domain') Rails.cache.write("exclude_domains_for:#{account.id}", 'domain') block.destroy! - expect(Rails.cache.exist?("exclude_domains_for:#{account.id}")).to eq false + expect(Rails.cache.exist?("exclude_domains_for:#{account.id}")).to be false end end diff --git a/spec/models/account_filter_spec.rb b/spec/models/account_filter_spec.rb index c2bd8c2202..fa47b5954a 100644 --- a/spec/models/account_filter_spec.rb +++ b/spec/models/account_filter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe AccountFilter do @@ -16,4 +18,49 @@ describe AccountFilter do expect { filter.results }.to raise_error(/wrong/) end end + + describe 'with origin and by_domain interacting' do + let!(:local_account) { Fabricate(:account, domain: nil) } + let!(:remote_account_one) { Fabricate(:account, domain: 'example.org') } + let(:remote_account_two) { Fabricate(:account, domain: 'other.domain') } + + it 'works with domain first and origin remote' do + filter = described_class.new(by_domain: 'example.org', origin: 'remote') + expect(filter.results).to contain_exactly(remote_account_one) + end + + it 'works with domain last and origin remote' do + filter = described_class.new(origin: 'remote', by_domain: 'example.org') + expect(filter.results).to contain_exactly(remote_account_one) + end + + it 'works with domain first and origin local' do + filter = described_class.new(by_domain: 'example.org', origin: 'local') + expect(filter.results).to contain_exactly(local_account) + end + + it 'works with domain last and origin local' do + filter = described_class.new(origin: 'local', by_domain: 'example.org') + expect(filter.results).to contain_exactly(remote_account_one) + end + end + + describe 'with username' do + let!(:local_account) { Fabricate(:account, domain: nil, username: 'validUserName') } + + it 'works with @ at the beginning of the username' do + filter = described_class.new(username: '@validUserName') + expect(filter.results).to contain_exactly(local_account) + end + + it 'does not work with more than one @ at the beginning of the username' do + filter = described_class.new(username: '@@validUserName') + expect(filter.results).to_not contain_exactly(local_account) + end + + it 'does not work with @ outside the beginning of the username' do + filter = described_class.new(username: 'validUserName@') + expect(filter.results).to_not contain_exactly(local_account) + end + end end diff --git a/spec/models/account_migration_spec.rb b/spec/models/account_migration_spec.rb index 5f66fe8da3..1f32c6082e 100644 --- a/spec/models/account_migration_spec.rb +++ b/spec/models/account_migration_spec.rb @@ -1,19 +1,21 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AccountMigration, type: :model do +RSpec.describe AccountMigration do describe 'validations' do + subject { described_class.new(account: source_account, acct: target_acct) } + let(:source_account) { Fabricate(:account) } let(:target_acct) { target_account.acct } - let(:subject) { AccountMigration.new(account: source_account, acct: target_acct) } - context 'with valid properties' do let(:target_account) { Fabricate(:account, username: 'target', domain: 'remote.org') } before do target_account.aliases.create!(acct: source_account.acct) - service_double = double + service_double = instance_double(ResolveAccountService) allow(ResolveAccountService).to receive(:new).and_return(service_double) allow(service_double).to receive(:call).with(target_acct, anything).and_return(target_account) end @@ -23,11 +25,11 @@ RSpec.describe AccountMigration, type: :model do end end - context 'with unresolveable account' do + context 'with unresolvable account' do let(:target_acct) { 'target@remote' } before do - service_double = double + service_double = instance_double(ResolveAccountService) allow(ResolveAccountService).to receive(:new).and_return(service_double) allow(service_double).to receive(:call).with(target_acct, anything).and_return(nil) end diff --git a/spec/models/account_moderation_note_spec.rb b/spec/models/account_moderation_note_spec.rb deleted file mode 100644 index 69bd5500a5..0000000000 --- a/spec/models/account_moderation_note_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe AccountModerationNote, type: :model do -end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 6cd769dc84..fc7a43110b 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1,10 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Account, type: :model do - context do - let(:bob) { Fabricate(:account, username: 'bob') } +RSpec.describe Account do + context 'with an account record' do subject { Fabricate(:account) } + let(:bob) { Fabricate(:account, username: 'bob') } + describe '#suspend!' do it 'marks the account as suspended' do subject.suspend! @@ -17,7 +20,9 @@ RSpec.describe Account, type: :model do end context 'when the account is of a local user' do - let!(:subject) { Fabricate(:user, email: 'foo+bar@domain.org').account } + subject { local_user_account } + + let!(:local_user_account) { Fabricate(:user, email: 'foo+bar@domain.org').account } it 'creates a canonical domain block' do subject.suspend! @@ -30,7 +35,7 @@ RSpec.describe Account, type: :model do end it 'does not raise an error' do - expect { subject.suspend! }.not_to raise_error + expect { subject.suspend! }.to_not raise_error end end end @@ -86,14 +91,14 @@ RSpec.describe Account, type: :model do end describe 'Local domain user methods' do + subject { Fabricate(:account, domain: nil, username: 'alice') } + around do |example| before = Rails.configuration.x.local_domain example.run Rails.configuration.x.local_domain = before end - subject { Fabricate(:account, domain: nil, username: 'alice') } - describe '#to_webfinger_s' do it 'returns a webfinger string for the account' do Rails.configuration.x.local_domain = 'example.com' @@ -159,7 +164,7 @@ RSpec.describe Account, type: :model do it 'sets default avatar, header, avatar_remote_url, and header_remote_url' do expect(account.avatar_remote_url).to eq 'https://remote.test/invalid_avatar' expect(account.header_remote_url).to eq expectation.header_remote_url - expect(account.avatar_file_name).to eq nil + expect(account.avatar_file_name).to be_nil expect(account.header_file_name).to eq expectation.header_file_name end end @@ -168,7 +173,7 @@ RSpec.describe Account, type: :model do describe '#possibly_stale?' do let(:account) { Fabricate(:account, last_webfingered_at: last_webfingered_at) } - context 'last_webfingered_at is nil' do + context 'when last_webfingered_at is nil' do let(:last_webfingered_at) { nil } it 'returns true' do @@ -176,7 +181,7 @@ RSpec.describe Account, type: :model do end end - context 'last_webfingered_at is more than 24 hours before' do + context 'when last_webfingered_at is more than 24 hours before' do let(:last_webfingered_at) { 25.hours.ago } it 'returns true' do @@ -184,7 +189,7 @@ RSpec.describe Account, type: :model do end end - context 'last_webfingered_at is less than 24 hours before' do + context 'when last_webfingered_at is less than 24 hours before' do let(:last_webfingered_at) { 23.hours.ago } it 'returns false' do @@ -197,7 +202,7 @@ RSpec.describe Account, type: :model do let(:account) { Fabricate(:account, domain: domain) } let(:acct) { account.acct } - context 'domain is nil' do + context 'when domain is nil' do let(:domain) { nil } it 'returns nil' do @@ -205,12 +210,12 @@ RSpec.describe Account, type: :model do end it 'calls not ResolveAccountService#call' do - expect_any_instance_of(ResolveAccountService).not_to receive(:call).with(acct) + expect_any_instance_of(ResolveAccountService).to_not receive(:call).with(acct) account.refresh! end end - context 'domain is present' do + context 'when domain is present' do let(:domain) { 'example.com' } it 'calls ResolveAccountService#call' do @@ -242,13 +247,13 @@ RSpec.describe Account, type: :model do end describe '#favourited?' do + subject { Fabricate(:account) } + let(:original_status) do author = Fabricate(:account, username: 'original') Fabricate(:status, account: author) end - subject { Fabricate(:account) } - context 'when the status is a reblog of another status' do let(:original_reblog) do author = Fabricate(:account, username: 'original_reblogger') @@ -258,11 +263,11 @@ RSpec.describe Account, type: :model do it 'is true when this account has favourited it' do Fabricate(:favourite, status: original_reblog, account: subject) - expect(subject.favourited?(original_status)).to eq true + expect(subject.favourited?(original_status)).to be true end it 'is false when this account has not favourited it' do - expect(subject.favourited?(original_status)).to eq false + expect(subject.favourited?(original_status)).to be false end end @@ -270,23 +275,23 @@ RSpec.describe Account, type: :model do it 'is true when this account has favourited it' do Fabricate(:favourite, status: original_status, account: subject) - expect(subject.favourited?(original_status)).to eq true + expect(subject.favourited?(original_status)).to be true end it 'is false when this account has not favourited it' do - expect(subject.favourited?(original_status)).to eq false + expect(subject.favourited?(original_status)).to be false end end end describe '#reblogged?' do + subject { Fabricate(:account) } + let(:original_status) do author = Fabricate(:account, username: 'original') Fabricate(:status, account: author) end - subject { Fabricate(:account) } - context 'when the status is a reblog of another status' do let(:original_reblog) do author = Fabricate(:account, username: 'original_reblogger') @@ -296,11 +301,11 @@ RSpec.describe Account, type: :model do it 'is true when this account has reblogged it' do Fabricate(:status, reblog: original_reblog, account: subject) - expect(subject.reblogged?(original_reblog)).to eq true + expect(subject.reblogged?(original_reblog)).to be true end it 'is false when this account has not reblogged it' do - expect(subject.reblogged?(original_reblog)).to eq false + expect(subject.reblogged?(original_reblog)).to be false end end @@ -308,11 +313,11 @@ RSpec.describe Account, type: :model do it 'is true when this account has reblogged it' do Fabricate(:status, reblog: original_status, account: subject) - expect(subject.reblogged?(original_status)).to eq true + expect(subject.reblogged?(original_status)).to be true end it 'is false when this account has not reblogged it' do - expect(subject.reblogged?(original_status)).to eq false + expect(subject.reblogged?(original_status)).to be false end end end @@ -336,7 +341,7 @@ RSpec.describe Account, type: :model do it 'returns the domains blocked by the account' do account = Fabricate(:account) account.block_domain!('domain') - expect(account.excluded_from_timeline_domains).to match_array ['domain'] + expect(account.excluded_from_timeline_domains).to contain_exactly('domain') end end @@ -344,9 +349,9 @@ RSpec.describe Account, type: :model do before do _missing = Fabricate( :account, - display_name: "Missing", - username: "missing", - domain: "missing.com" + display_name: 'Missing', + username: 'missing', + domain: 'missing.com' ) end @@ -359,7 +364,7 @@ RSpec.describe Account, type: :model do suspended: true ) - results = Account.search_for('username') + results = described_class.search_for('username') expect(results).to eq [] end @@ -372,7 +377,7 @@ RSpec.describe Account, type: :model do match.user.update(approved: false) - results = Account.search_for('username') + results = described_class.search_for('username') expect(results).to eq [] end @@ -385,7 +390,7 @@ RSpec.describe Account, type: :model do match.user.update(confirmed_at: nil) - results = Account.search_for('username') + results = described_class.search_for('username') expect(results).to eq [] end @@ -397,65 +402,65 @@ RSpec.describe Account, type: :model do domain: 'example.com' ) - results = Account.search_for('A?l\i:c e') + results = described_class.search_for('A?l\i:c e') expect(results).to eq [match] end it 'finds accounts with matching display_name' do match = Fabricate( :account, - display_name: "Display Name", - username: "username", - domain: "example.com" + display_name: 'Display Name', + username: 'username', + domain: 'example.com' ) - results = Account.search_for("display") + results = described_class.search_for('display') expect(results).to eq [match] end it 'finds accounts with matching username' do match = Fabricate( :account, - display_name: "Display Name", - username: "username", - domain: "example.com" + display_name: 'Display Name', + username: 'username', + domain: 'example.com' ) - results = Account.search_for("username") + results = described_class.search_for('username') expect(results).to eq [match] end it 'finds accounts with matching domain' do match = Fabricate( :account, - display_name: "Display Name", - username: "username", - domain: "example.com" + display_name: 'Display Name', + username: 'username', + domain: 'example.com' ) - results = Account.search_for("example") + results = described_class.search_for('example') expect(results).to eq [match] end it 'limits by 10 by default' do - 11.times.each { Fabricate(:account, display_name: "Display Name") } - results = Account.search_for("display") + 11.times.each { Fabricate(:account, display_name: 'Display Name') } + results = described_class.search_for('display') expect(results.size).to eq 10 end it 'accepts arbitrary limits' do - 2.times.each { Fabricate(:account, display_name: "Display Name") } - results = Account.search_for("display", limit: 1) + 2.times.each { Fabricate(:account, display_name: 'Display Name') } + results = described_class.search_for('display', limit: 1) expect(results.size).to eq 1 end it 'ranks multiple matches higher' do matches = [ - { username: "username", display_name: "username" }, - { display_name: "Display Name", username: "username", domain: "example.com" }, + { username: 'username', display_name: 'username' }, + { display_name: 'Display Name', username: 'username', domain: 'example.com' }, ].map(&method(:Fabricate).curry(2).call(:account)) - results = Account.search_for("username") + results = described_class.search_for('username') expect(results).to eq matches end end @@ -473,7 +478,7 @@ RSpec.describe Account, type: :model do ) account.follow!(match) - results = Account.advanced_search_for('A?l\i:c e', account, limit: 10, following: true) + results = described_class.advanced_search_for('A?l\i:c e', account, limit: 10, following: true) expect(results).to eq [match] end @@ -485,7 +490,7 @@ RSpec.describe Account, type: :model do domain: 'example.com' ) - results = Account.advanced_search_for('A?l\i:c e', account, limit: 10, following: true) + results = described_class.advanced_search_for('A?l\i:c e', account, limit: 10, following: true) expect(results).to eq [] end @@ -498,7 +503,7 @@ RSpec.describe Account, type: :model do suspended: true ) - results = Account.advanced_search_for('username', account, limit: 10, following: true) + results = described_class.advanced_search_for('username', account, limit: 10, following: true) expect(results).to eq [] end @@ -511,7 +516,7 @@ RSpec.describe Account, type: :model do match.user.update(approved: false) - results = Account.advanced_search_for('username', account, limit: 10, following: true) + results = described_class.advanced_search_for('username', account, limit: 10, following: true) expect(results).to eq [] end @@ -524,7 +529,7 @@ RSpec.describe Account, type: :model do match.user.update(confirmed_at: nil) - results = Account.advanced_search_for('username', account, limit: 10, following: true) + results = described_class.advanced_search_for('username', account, limit: 10, following: true) expect(results).to eq [] end end @@ -538,7 +543,7 @@ RSpec.describe Account, type: :model do suspended: true ) - results = Account.advanced_search_for('username', account) + results = described_class.advanced_search_for('username', account) expect(results).to eq [] end @@ -551,7 +556,7 @@ RSpec.describe Account, type: :model do match.user.update(approved: false) - results = Account.advanced_search_for('username', account) + results = described_class.advanced_search_for('username', account) expect(results).to eq [] end @@ -564,7 +569,7 @@ RSpec.describe Account, type: :model do match.user.update(confirmed_at: nil) - results = Account.advanced_search_for('username', account) + results = described_class.advanced_search_for('username', account) expect(results).to eq [] end @@ -576,28 +581,28 @@ RSpec.describe Account, type: :model do domain: 'example.com' ) - results = Account.advanced_search_for('A?l\i:c e', account) + results = described_class.advanced_search_for('A?l\i:c e', account) expect(results).to eq [match] end it 'limits by 10 by default' do - 11.times { Fabricate(:account, display_name: "Display Name") } - results = Account.advanced_search_for("display", account) + 11.times { Fabricate(:account, display_name: 'Display Name') } + results = described_class.advanced_search_for('display', account) expect(results.size).to eq 10 end it 'accepts arbitrary limits' do - 2.times { Fabricate(:account, display_name: "Display Name") } - results = Account.advanced_search_for("display", account, limit: 1) + 2.times { Fabricate(:account, display_name: 'Display Name') } + results = described_class.advanced_search_for('display', account, limit: 1) expect(results.size).to eq 1 end it 'ranks followed accounts higher' do - match = Fabricate(:account, username: "Matching") - followed_match = Fabricate(:account, username: "Matcher") + match = Fabricate(:account, username: 'Matching') + followed_match = Fabricate(:account, username: 'Matcher') Fabricate(:follow, account: account, target_account: followed_match) - results = Account.advanced_search_for("match", account) + results = described_class.advanced_search_for('match', account) expect(results).to eq [followed_match, match] expect(results.first.rank).to be > results.last.rank end @@ -636,31 +641,31 @@ RSpec.describe Account, type: :model do describe '.following_map' do it 'returns an hash' do - expect(Account.following_map([], 1)).to be_a Hash + expect(described_class.following_map([], 1)).to be_a Hash end end describe '.followed_by_map' do it 'returns an hash' do - expect(Account.followed_by_map([], 1)).to be_a Hash + expect(described_class.followed_by_map([], 1)).to be_a Hash end end describe '.blocking_map' do it 'returns an hash' do - expect(Account.blocking_map([], 1)).to be_a Hash + expect(described_class.blocking_map([], 1)).to be_a Hash end end describe '.requested_map' do it 'returns an hash' do - expect(Account.requested_map([], 1)).to be_a Hash + expect(described_class.requested_map([], 1)).to be_a Hash end end describe '.requested_by_map' do it 'returns an hash' do - expect(Account.requested_by_map([], 1)).to be_a Hash + expect(described_class.requested_by_map([], 1)).to be_a Hash end end @@ -695,18 +700,12 @@ RSpec.describe Account, type: :model do expect(subject.match('Check this out https://medium.com/@alice/some-article#.abcdef123')).to be_nil end - xit 'does not match URL querystring' do + it 'does not match URL query string' do expect(subject.match('https://example.com/?x=@alice')).to be_nil end end describe 'validations' do - it 'has a valid fabricator' do - account = Fabricate.build(:account) - account.valid? - expect(account).to be_valid - end - it 'is invalid without a username' do account = Fabricate.build(:account, username: nil) account.valid? @@ -810,19 +809,19 @@ RSpec.describe Account, type: :model do it 'is valid even if the username is longer than 30 characters' do account = Fabricate.build(:account, domain: 'domain', username: Faker::Lorem.characters(number: 31)) account.valid? - expect(account).not_to model_have_error_on_field(:username) + expect(account).to_not model_have_error_on_field(:username) end it 'is valid even if the display name is longer than 30 characters' do account = Fabricate.build(:account, domain: 'domain', display_name: Faker::Lorem.characters(number: 31)) account.valid? - expect(account).not_to model_have_error_on_field(:display_name) + expect(account).to_not model_have_error_on_field(:display_name) end it 'is valid even if the note is longer than 500 characters' do account = Fabricate.build(:account, domain: 'domain', note: Faker::Lorem.characters(number: 501)) account.valid? - expect(account).not_to model_have_error_on_field(:note) + expect(account).to_not model_have_error_on_field(:note) end end end @@ -837,7 +836,7 @@ RSpec.describe Account, type: :model do { username: 'b', domain: 'b' }, ].map(&method(:Fabricate).curry(2).call(:account)) - expect(Account.where('id > 0').alphabetic).to eq matches + expect(described_class.where('id > 0').alphabetic).to eq matches end end @@ -846,7 +845,7 @@ RSpec.describe Account, type: :model do match = Fabricate(:account, display_name: 'pattern and suffix') Fabricate(:account, display_name: 'prefix and pattern') - expect(Account.matches_display_name('pattern')).to eq [match] + expect(described_class.matches_display_name('pattern')).to eq [match] end end @@ -855,24 +854,24 @@ RSpec.describe Account, type: :model do match = Fabricate(:account, username: 'pattern_and_suffix') Fabricate(:account, username: 'prefix_and_pattern') - expect(Account.matches_username('pattern')).to eq [match] + expect(described_class.matches_username('pattern')).to eq [match] end end describe 'by_domain_and_subdomains' do it 'returns exact domain matches' do account = Fabricate(:account, domain: 'example.com') - expect(Account.by_domain_and_subdomains('example.com')).to eq [account] + expect(described_class.by_domain_and_subdomains('example.com')).to eq [account] end it 'returns subdomains' do account = Fabricate(:account, domain: 'foo.example.com') - expect(Account.by_domain_and_subdomains('example.com')).to eq [account] + expect(described_class.by_domain_and_subdomains('example.com')).to eq [account] end it 'does not return partially matching domains' do account = Fabricate(:account, domain: 'grexample.com') - expect(Account.by_domain_and_subdomains('example.com')).to_not eq [account] + expect(described_class.by_domain_and_subdomains('example.com')).to_not eq [account] end end @@ -880,7 +879,7 @@ RSpec.describe Account, type: :model do it 'returns an array of accounts who have a domain' do account_1 = Fabricate(:account, domain: nil) account_2 = Fabricate(:account, domain: 'example.com') - expect(Account.remote).to match_array([account_2]) + expect(described_class.remote).to contain_exactly(account_2) end end @@ -888,25 +887,25 @@ RSpec.describe Account, type: :model do it 'returns an array of accounts who do not have a domain' do account_1 = Fabricate(:account, domain: nil) account_2 = Fabricate(:account, domain: 'example.com') - expect(Account.where('id > 0').local).to match_array([account_1]) + expect(described_class.where('id > 0').local).to contain_exactly(account_1) end end describe 'partitioned' do it 'returns a relation of accounts partitioned by domain' do - matches = ['a', 'b', 'a', 'b'] + matches = %w(a b a b) matches.size.times.to_a.shuffle.each do |index| matches[index] = Fabricate(:account, domain: matches[index]) end - expect(Account.where('id > 0').partitioned).to match_array(matches) + expect(described_class.where('id > 0').partitioned).to match_array(matches) end end describe 'recent' do it 'returns a relation of accounts sorted by recent creation' do - matches = 2.times.map { Fabricate(:account) } - expect(Account.where('id > 0').recent).to match_array(matches) + matches = Array.new(2) { Fabricate(:account) } + expect(described_class.where('id > 0').recent).to match_array(matches) end end @@ -914,7 +913,7 @@ RSpec.describe Account, type: :model do it 'returns an array of accounts who are silenced' do account_1 = Fabricate(:account, silenced: true) account_2 = Fabricate(:account, silenced: false) - expect(Account.silenced).to match_array([account_1]) + expect(described_class.silenced).to contain_exactly(account_1) end end @@ -922,7 +921,7 @@ RSpec.describe Account, type: :model do it 'returns an array of accounts who are suspended' do account_1 = Fabricate(:account, suspended: true) account_2 = Fabricate(:account, suspended: false) - expect(Account.suspended).to match_array([account_1]) + expect(described_class.suspended).to contain_exactly(account_1) end end @@ -944,32 +943,32 @@ RSpec.describe Account, type: :model do end it 'returns every usable non-suspended account' do - expect(Account.searchable).to match_array([silenced_local, silenced_remote, local_account, remote_account]) + expect(described_class.searchable).to contain_exactly(silenced_local, silenced_remote, local_account, remote_account) end it 'does not mess with previously-applied scopes' do - expect(Account.where.not(id: remote_account.id).searchable).to match_array([silenced_local, silenced_remote, local_account]) + expect(described_class.where.not(id: remote_account.id).searchable).to contain_exactly(silenced_local, silenced_remote, local_account) end end end context 'when is local' do - # Test disabled because test environment omits autogenerating keys for performance - xit 'generates keys' do - account = Account.create!(domain: nil, username: Faker::Internet.user_name(separators: ['_'])) - expect(account.keypair.private?).to eq true + it 'generates keys' do + account = described_class.create!(domain: nil, username: Faker::Internet.user_name(separators: ['_'])) + expect(account.keypair).to be_private + expect(account.keypair).to be_public end end context 'when is remote' do it 'does not generate keys' do key = OpenSSL::PKey::RSA.new(1024).public_key - account = Account.create!(domain: 'remote', username: Faker::Internet.user_name(separators: ['_']), public_key: key.to_pem) + account = described_class.create!(domain: 'remote', uri: 'https://remote/actor', username: Faker::Internet.user_name(separators: ['_']), public_key: key.to_pem) expect(account.keypair.params).to eq key.params end it 'normalizes domain' do - account = Account.create!(domain: 'にゃん', username: Faker::Internet.user_name(separators: ['_'])) + account = described_class.create!(domain: 'にゃん', uri: 'https://xn--r9j5b5b/actor', username: Faker::Internet.user_name(separators: ['_'])) expect(account.domain).to eq 'xn--r9j5b5b' end end @@ -989,7 +988,7 @@ RSpec.describe Account, type: :model do threads = Array.new(increment_by) do Thread.new do true while wait_for_start - Account.find(subject.id).increment_count!(:followers_count) + described_class.find(subject.id).increment_count!(:followers_count) end end diff --git a/spec/models/account_statuses_cleanup_policy_spec.rb b/spec/models/account_statuses_cleanup_policy_spec.rb index b01321a205..7405bdfa2d 100644 --- a/spec/models/account_statuses_cleanup_policy_spec.rb +++ b/spec/models/account_statuses_cleanup_policy_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe AccountStatusesCleanupPolicy, type: :model do +RSpec.describe AccountStatusesCleanupPolicy do let(:account) { Fabricate(:account, username: 'alice', domain: nil) } describe 'validation' do @@ -16,16 +18,15 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do context 'when widening a policy' do let!(:account_statuses_cleanup_policy) do Fabricate(:account_statuses_cleanup_policy, - account: account, - keep_direct: true, - keep_pinned: true, - keep_polls: true, - keep_media: true, - keep_self_fav: true, - keep_self_bookmark: true, - min_favs: 1, - min_reblogs: 1 - ) + account: account, + keep_direct: true, + keep_pinned: true, + keep_polls: true, + keep_media: true, + keep_self_fav: true, + keep_self_bookmark: true, + min_favs: 1, + min_reblogs: 1) end before do @@ -35,77 +36,76 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do it 'invalidates last_inspected when widened because of keep_direct' do account_statuses_cleanup_policy.keep_direct = false account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of keep_pinned' do account_statuses_cleanup_policy.keep_pinned = false account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of keep_polls' do account_statuses_cleanup_policy.keep_polls = false account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of keep_media' do account_statuses_cleanup_policy.keep_media = false account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of keep_self_fav' do account_statuses_cleanup_policy.keep_self_fav = false account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of keep_self_bookmark' do account_statuses_cleanup_policy.keep_self_bookmark = false account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of higher min_favs' do account_statuses_cleanup_policy.min_favs = 5 account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of disabled min_favs' do account_statuses_cleanup_policy.min_favs = nil account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of higher min_reblogs' do account_statuses_cleanup_policy.min_reblogs = 5 account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end it 'invalidates last_inspected when widened because of disable min_reblogs' do account_statuses_cleanup_policy.min_reblogs = nil account_statuses_cleanup_policy.save - expect(account_statuses_cleanup_policy.last_inspected).to be nil + expect(account_statuses_cleanup_policy.last_inspected).to be_nil end end context 'when narrowing a policy' do let!(:account_statuses_cleanup_policy) do Fabricate(:account_statuses_cleanup_policy, - account: account, - keep_direct: false, - keep_pinned: false, - keep_polls: false, - keep_media: false, - keep_self_fav: false, - keep_self_bookmark: false, - min_favs: nil, - min_reblogs: nil - ) + account: account, + keep_direct: false, + keep_pinned: false, + keep_polls: false, + keep_media: false, + keep_self_fav: false, + keep_self_bookmark: false, + min_favs: nil, + min_reblogs: nil) end it 'does not unnecessarily invalidate last_inspected' do @@ -134,9 +134,10 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end describe '#invalidate_last_inspected' do + subject { account_statuses_cleanup_policy.invalidate_last_inspected(status, action) } + let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) } let(:status) { Fabricate(:status, id: 10, account: account) } - subject { account_statuses_cleanup_policy.invalidate_last_inspected(status, action) } before do account_statuses_cleanup_policy.record_last_inspected(42) @@ -232,11 +233,11 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end describe '#compute_cutoff_id' do - let!(:unrelated_status) { Fabricate(:status, created_at: 3.years.ago) } - let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) } - subject { account_statuses_cleanup_policy.compute_cutoff_id } + let!(:unrelated_status) { Fabricate(:status, created_at: 3.years.ago) } + let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) } + context 'when the account has posted multiple toots' do let!(:very_old_status) { Fabricate(:status, created_at: 3.years.ago, account: account) } let!(:old_status) { Fabricate(:status, created_at: 3.weeks.ago, account: account) } @@ -255,18 +256,20 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end describe '#statuses_to_delete' do + subject { account_statuses_cleanup_policy.statuses_to_delete } + let!(:unrelated_status) { Fabricate(:status, created_at: 3.years.ago) } let!(:very_old_status) { Fabricate(:status, created_at: 3.years.ago, account: account) } let!(:pinned_status) { Fabricate(:status, created_at: 1.year.ago, account: account) } let!(:direct_message) { Fabricate(:status, created_at: 1.year.ago, account: account, visibility: :direct) } let!(:self_faved) { Fabricate(:status, created_at: 1.year.ago, account: account) } let!(:self_bookmarked) { Fabricate(:status, created_at: 1.year.ago, account: account) } - let!(:status_with_poll) { Fabricate(:status, created_at: 1.year.ago, account: account, poll_attributes: { account: account, voters_count: 0, options: ['a', 'b'], expires_in: 2.days }) } + let!(:status_with_poll) { Fabricate(:status, created_at: 1.year.ago, account: account, poll_attributes: { account: account, voters_count: 0, options: %w(a b), expires_in: 2.days }) } let!(:status_with_media) { Fabricate(:status, created_at: 1.year.ago, account: account) } - let!(:faved4) { Fabricate(:status, created_at: 1.year.ago, account: account) } - let!(:faved5) { Fabricate(:status, created_at: 1.year.ago, account: account) } - let!(:reblogged4) { Fabricate(:status, created_at: 1.year.ago, account: account) } - let!(:reblogged5) { Fabricate(:status, created_at: 1.year.ago, account: account) } + let!(:faved_primary) { Fabricate(:status, created_at: 1.year.ago, account: account) } + let!(:faved_secondary) { Fabricate(:status, created_at: 1.year.ago, account: account) } + let!(:reblogged_primary) { Fabricate(:status, created_at: 1.year.ago, account: account) } + let!(:reblogged_secondary) { Fabricate(:status, created_at: 1.year.ago, account: account) } let!(:recent_status) { Fabricate(:status, created_at: 2.days.ago, account: account) } let!(:media_attachment) { Fabricate(:media_attachment, account: account, status: status_with_media) } @@ -276,21 +279,19 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do let(:account_statuses_cleanup_policy) { Fabricate(:account_statuses_cleanup_policy, account: account) } - subject { account_statuses_cleanup_policy.statuses_to_delete } - before do - 4.times { faved4.increment_count!(:favourites_count) } - 5.times { faved5.increment_count!(:favourites_count) } - 4.times { reblogged4.increment_count!(:reblogs_count) } - 5.times { reblogged5.increment_count!(:reblogs_count) } + 4.times { faved_primary.increment_count!(:favourites_count) } + 5.times { faved_secondary.increment_count!(:favourites_count) } + 4.times { reblogged_primary.increment_count!(:reblogs_count) } + 5.times { reblogged_secondary.increment_count!(:reblogs_count) } end context 'when passed a max_id' do + subject { account_statuses_cleanup_policy.statuses_to_delete(50, old_status.id).pluck(:id) } + let!(:old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) } let!(:slightly_less_old_status) { Fabricate(:status, created_at: 6.months.ago, account: account) } - subject { account_statuses_cleanup_policy.statuses_to_delete(50, old_status.id).pluck(:id) } - it 'returns statuses including max_id' do expect(subject).to include(old_status.id) end @@ -305,11 +306,11 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end context 'when passed a min_id' do + subject { account_statuses_cleanup_policy.statuses_to_delete(50, recent_status.id, old_status.id).pluck(:id) } + let!(:old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) } let!(:slightly_less_old_status) { Fabricate(:status, created_at: 6.months.ago, account: account) } - subject { account_statuses_cleanup_policy.statuses_to_delete(50, recent_status.id, old_status.id).pluck(:id) } - it 'returns statuses including min_id' do expect(subject).to include(old_status.id) end @@ -358,7 +359,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -377,7 +378,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, status_with_poll.id, status_with_media.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, status_with_poll.id, status_with_media.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -396,7 +397,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -415,7 +416,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -434,7 +435,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_media.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_media.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -453,7 +454,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -476,7 +477,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns every other old status for deletion' do - expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(direct_message.id, very_old_status.id, pinned_status.id, self_faved.id, self_bookmarked.id, status_with_poll.id, status_with_media.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -495,7 +496,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns only normal statuses for deletion' do - expect(subject.pluck(:id)).to match_array([very_old_status.id, faved4.id, faved5.id, reblogged4.id, reblogged5.id]) + expect(subject.pluck(:id)).to contain_exactly(very_old_status.id, faved_primary.id, faved_secondary.id, reblogged_primary.id, reblogged_secondary.id) end end @@ -509,7 +510,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'does not return the toot reblogged 5 times' do - expect(subject.pluck(:id)).to_not include(reblogged5.id) + expect(subject.pluck(:id)).to_not include(reblogged_secondary.id) end it 'does not return the unrelated toot' do @@ -517,7 +518,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns old statuses not reblogged as much' do - expect(subject.pluck(:id)).to include(very_old_status.id, faved4.id, faved5.id, reblogged4.id) + expect(subject.pluck(:id)).to include(very_old_status.id, faved_primary.id, faved_secondary.id, reblogged_primary.id) end end @@ -531,7 +532,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'does not return the toot faved 5 times' do - expect(subject.pluck(:id)).to_not include(faved5.id) + expect(subject.pluck(:id)).to_not include(faved_secondary.id) end it 'does not return the unrelated toot' do @@ -539,7 +540,7 @@ RSpec.describe AccountStatusesCleanupPolicy, type: :model do end it 'returns old statuses not faved as much' do - expect(subject.pluck(:id)).to include(very_old_status.id, faved4.id, reblogged4.id, reblogged5.id) + expect(subject.pluck(:id)).to include(very_old_status.id, faved_primary.id, reblogged_primary.id, reblogged_secondary.id) end end end diff --git a/spec/models/account_warning_preset_spec.rb b/spec/models/account_warning_preset_spec.rb new file mode 100644 index 0000000000..f171df7c97 --- /dev/null +++ b/spec/models/account_warning_preset_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountWarningPreset do + describe 'alphabetical' do + let(:first) { Fabricate(:account_warning_preset, title: 'aaa', text: 'aaa') } + let(:second) { Fabricate(:account_warning_preset, title: 'bbb', text: 'aaa') } + let(:third) { Fabricate(:account_warning_preset, title: 'bbb', text: 'bbb') } + + it 'returns records in order of title and text' do + results = described_class.alphabetic + + expect(results).to eq([first, second, third]) + end + end +end diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb index b6a052b769..b47561dd48 100644 --- a/spec/models/admin/account_action_spec.rb +++ b/spec/models/admin/account_action_spec.rb @@ -1,23 +1,26 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Admin::AccountAction, type: :model do +RSpec.describe Admin::AccountAction do let(:account_action) { described_class.new } describe '#save!' do subject { account_action.save! } + let(:account) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:target_account) { Fabricate(:account) } let(:type) { 'disable' } before do account_action.assign_attributes( - type: type, + type: type, current_account: account, - target_account: target_account + target_account: target_account ) end - context 'type is "disable"' do + context 'when type is "disable"' do let(:type) { 'disable' } it 'disable user' do @@ -26,7 +29,7 @@ RSpec.describe Admin::AccountAction, type: :model do end end - context 'type is "silence"' do + context 'when type is "silence"' do let(:type) { 'silence' } it 'silences account' do @@ -35,7 +38,7 @@ RSpec.describe Admin::AccountAction, type: :model do end end - context 'type is "suspend"' do + context 'when type is "suspend"' do let(:type) { 'suspend' } it 'suspends account' do @@ -52,10 +55,26 @@ RSpec.describe Admin::AccountAction, type: :model do end end + context 'when type is invalid' do + let(:type) { 'whatever' } + + it 'raises an invalid record error' do + expect { subject }.to raise_error(ActiveRecord::RecordInvalid) + end + end + + context 'when type is not given' do + let(:type) { '' } + + it 'raises an invalid record error' do + expect { subject }.to raise_error(ActiveRecord::RecordInvalid) + end + end + it 'creates Admin::ActionLog' do expect do subject - end.to change { Admin::ActionLog.count }.by 1 + end.to change(Admin::ActionLog, :count).by 1 end it 'calls process_email!' do @@ -72,7 +91,7 @@ RSpec.describe Admin::AccountAction, type: :model do describe '#report' do subject { account_action.report } - context 'report_id.present?' do + context 'with report_id.present?' do before do account_action.report_id = Fabricate(:report).id end @@ -82,7 +101,7 @@ RSpec.describe Admin::AccountAction, type: :model do end end - context '!report_id.present?' do + context 'with !report_id.present?' do it 'returns nil' do expect(subject).to be_nil end @@ -92,7 +111,7 @@ RSpec.describe Admin::AccountAction, type: :model do describe '#with_report?' do subject { account_action.with_report? } - context '!report.nil?' do + context 'with !report.nil?' do before do account_action.report_id = Fabricate(:report).id end @@ -102,7 +121,7 @@ RSpec.describe Admin::AccountAction, type: :model do end end - context '!(!report.nil?)' do + context 'with !(!report.nil?)' do it 'returns false' do expect(subject).to be false end @@ -112,7 +131,7 @@ RSpec.describe Admin::AccountAction, type: :model do describe '.types_for_account' do subject { described_class.types_for_account(account) } - context 'account.local?' do + context 'when Account.local?' do let(:account) { Fabricate(:account, domain: nil) } it 'returns ["none", "disable", "sensitive", "silence", "suspend"]' do @@ -120,7 +139,7 @@ RSpec.describe Admin::AccountAction, type: :model do end end - context '!account.local?' do + context 'with !account.local?' do let(:account) { Fabricate(:account, domain: 'hoge.com') } it 'returns ["sensitive", "silence", "suspend"]' do diff --git a/spec/models/admin/action_log_spec.rb b/spec/models/admin/action_log_spec.rb index 3495cc5141..1e3649b833 100644 --- a/spec/models/admin/action_log_spec.rb +++ b/spec/models/admin/action_log_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Admin::ActionLog, type: :model do +RSpec.describe Admin::ActionLog do describe '#action' do it 'returns action' do action_log = described_class.new(action: 'hoge') diff --git a/spec/models/admin/appeal_filter_spec.rb b/spec/models/admin/appeal_filter_spec.rb new file mode 100644 index 0000000000..e840bc3bc1 --- /dev/null +++ b/spec/models/admin/appeal_filter_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::AppealFilter do + describe '#results' do + let(:approved_appeal) { Fabricate(:appeal, approved_at: 10.days.ago) } + let(:not_approved_appeal) { Fabricate(:appeal, approved_at: nil) } + + it 'returns filtered appeals' do + filter = described_class.new(status: 'approved') + + expect(filter.results).to eq([approved_appeal]) + end + end +end diff --git a/spec/models/announcement_mute_spec.rb b/spec/models/announcement_mute_spec.rb deleted file mode 100644 index 9d0e4c9037..0000000000 --- a/spec/models/announcement_mute_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe AnnouncementMute, type: :model do -end diff --git a/spec/models/announcement_reaction_spec.rb b/spec/models/announcement_reaction_spec.rb deleted file mode 100644 index f6e1515840..0000000000 --- a/spec/models/announcement_reaction_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe AnnouncementReaction, type: :model do -end diff --git a/spec/models/announcement_spec.rb b/spec/models/announcement_spec.rb deleted file mode 100644 index 7f7b647a9e..0000000000 --- a/spec/models/announcement_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe Announcement, type: :model do -end diff --git a/spec/models/appeal_spec.rb b/spec/models/appeal_spec.rb index 14062dc4f4..12373a9494 100644 --- a/spec/models/appeal_spec.rb +++ b/spec/models/appeal_spec.rb @@ -1,5 +1,38 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Appeal, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe Appeal do + describe 'scopes' do + describe 'approved' do + let(:approved_appeal) { Fabricate(:appeal, approved_at: 10.days.ago) } + let(:not_approved_appeal) { Fabricate(:appeal, approved_at: nil) } + + it 'finds the correct records' do + results = described_class.approved + expect(results).to eq([approved_appeal]) + end + end + + describe 'rejected' do + let(:rejected_appeal) { Fabricate(:appeal, rejected_at: 10.days.ago) } + let(:not_rejected_appeal) { Fabricate(:appeal, rejected_at: nil) } + + it 'finds the correct records' do + results = described_class.rejected + expect(results).to eq([rejected_appeal]) + end + end + + describe 'pending' do + let(:approved_appeal) { Fabricate(:appeal, approved_at: 10.days.ago) } + let(:rejected_appeal) { Fabricate(:appeal, rejected_at: 10.days.ago) } + let(:pending_appeal) { Fabricate(:appeal, rejected_at: nil, approved_at: nil) } + + it 'finds the correct records' do + results = described_class.pending + expect(results).to eq([pending_appeal]) + end + end + end end diff --git a/spec/models/backup_spec.rb b/spec/models/backup_spec.rb deleted file mode 100644 index 45230986d7..0000000000 --- a/spec/models/backup_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe Backup, type: :model do -end diff --git a/spec/models/block_spec.rb b/spec/models/block_spec.rb index acbdc77f5b..8249503c59 100644 --- a/spec/models/block_spec.rb +++ b/spec/models/block_spec.rb @@ -1,12 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Block, type: :model do +RSpec.describe Block do describe 'validations' do - it 'has a valid fabricator' do - block = Fabricate.build(:block) - expect(block).to be_valid - end - it 'is invalid without an account' do block = Fabricate.build(:block, account: nil) block.valid? @@ -26,22 +23,22 @@ RSpec.describe Block, type: :model do Rails.cache.write("exclude_account_ids_for:#{account.id}", []) Rails.cache.write("exclude_account_ids_for:#{target_account.id}", []) - Block.create!(account: account, target_account: target_account) + described_class.create!(account: account, target_account: target_account) - expect(Rails.cache.exist?("exclude_account_ids_for:#{account.id}")).to eq false - expect(Rails.cache.exist?("exclude_account_ids_for:#{target_account.id}")).to eq false + expect(Rails.cache.exist?("exclude_account_ids_for:#{account.id}")).to be false + expect(Rails.cache.exist?("exclude_account_ids_for:#{target_account.id}")).to be false end it 'removes blocking cache after destruction' do account = Fabricate(:account) target_account = Fabricate(:account) - block = Block.create!(account: account, target_account: target_account) + block = described_class.create!(account: account, target_account: target_account) Rails.cache.write("exclude_account_ids_for:#{account.id}", [target_account.id]) Rails.cache.write("exclude_account_ids_for:#{target_account.id}", [account.id]) block.destroy! - expect(Rails.cache.exist?("exclude_account_ids_for:#{account.id}")).to eq false - expect(Rails.cache.exist?("exclude_account_ids_for:#{target_account.id}")).to eq false + expect(Rails.cache.exist?("exclude_account_ids_for:#{account.id}")).to be false + expect(Rails.cache.exist?("exclude_account_ids_for:#{target_account.id}")).to be false end end diff --git a/spec/models/canonical_email_block_spec.rb b/spec/models/canonical_email_block_spec.rb index 8e0050d65a..0acff82377 100644 --- a/spec/models/canonical_email_block_spec.rb +++ b/spec/models/canonical_email_block_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe CanonicalEmailBlock, type: :model do +RSpec.describe CanonicalEmailBlock do describe '#email=' do let(:target_hash) { '973dfe463ec85785f5f95af5ba3906eedb2d931c24e69824a89ea65dba4e813b' } diff --git a/spec/models/concerns/account_counters_spec.rb b/spec/models/concerns/account_counters_spec.rb index 4350496e79..fb02d79f11 100644 --- a/spec/models/concerns/account_counters_spec.rb +++ b/spec/models/concerns/account_counters_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe AccountCounters do diff --git a/spec/models/concerns/account_interactions_spec.rb b/spec/models/concerns/account_interactions_spec.rb index 1d1898ab0c..41aedd18b2 100644 --- a/spec/models/concerns/account_interactions_spec.rb +++ b/spec/models/concerns/account_interactions_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe AccountInteractions do @@ -11,16 +13,23 @@ describe AccountInteractions do describe '.following_map' do subject { Account.following_map(target_account_ids, account_id) } - context 'account with Follow' do + context 'when Account with Follow' do it 'returns { target_account_id => true }' do Fabricate(:follow, account: account, target_account: target_account) - is_expected.to eq(target_account_id => { reblogs: true, notify: false, languages: nil }) + expect(subject).to eq(target_account_id => { reblogs: true, notify: false, languages: nil }) end end - context 'account without Follow' do + context 'when Account with Follow but with reblogs disabled' do + it 'returns { target_account_id => { reblogs: false } }' do + Fabricate(:follow, account: account, target_account: target_account, show_reblogs: false) + expect(subject).to eq(target_account_id => { reblogs: false, notify: false, languages: nil }) + end + end + + context 'when Account without Follow' do it 'returns {}' do - is_expected.to eq({}) + expect(subject).to eq({}) end end end @@ -28,16 +37,16 @@ describe AccountInteractions do describe '.followed_by_map' do subject { Account.followed_by_map(target_account_ids, account_id) } - context 'account with Follow' do + context 'when Account with Follow' do it 'returns { target_account_id => true }' do Fabricate(:follow, account: target_account, target_account: account) - is_expected.to eq(target_account_id => true) + expect(subject).to eq(target_account_id => true) end end - context 'account without Follow' do + context 'when Account without Follow' do it 'returns {}' do - is_expected.to eq({}) + expect(subject).to eq({}) end end end @@ -45,16 +54,16 @@ describe AccountInteractions do describe '.blocking_map' do subject { Account.blocking_map(target_account_ids, account_id) } - context 'account with Block' do + context 'when Account with Block' do it 'returns { target_account_id => true }' do Fabricate(:block, account: account, target_account: target_account) - is_expected.to eq(target_account_id => true) + expect(subject).to eq(target_account_id => true) end end - context 'account without Block' do + context 'when Account without Block' do it 'returns {}' do - is_expected.to eq({}) + expect(subject).to eq({}) end end end @@ -62,31 +71,31 @@ describe AccountInteractions do describe '.muting_map' do subject { Account.muting_map(target_account_ids, account_id) } - context 'account with Mute' do + context 'when Account with Mute' do before do Fabricate(:mute, target_account: target_account, account: account, hide_notifications: hide) end - context 'if Mute#hide_notifications?' do + context 'when Mute#hide_notifications?' do let(:hide) { true } it 'returns { target_account_id => { notifications: true } }' do - is_expected.to eq(target_account_id => { notifications: true }) + expect(subject).to eq(target_account_id => { notifications: true }) end end - context 'unless Mute#hide_notifications?' do + context 'when not Mute#hide_notifications?' do let(:hide) { false } it 'returns { target_account_id => { notifications: false } }' do - is_expected.to eq(target_account_id => { notifications: false }) + expect(subject).to eq(target_account_id => { notifications: false }) end end end - context 'account without Mute' do + context 'when Account without Mute' do it 'returns {}' do - is_expected.to eq({}) + expect(subject).to eq({}) end end end @@ -94,7 +103,7 @@ describe AccountInteractions do describe '#follow!' do it 'creates and returns Follow' do expect do - expect(account.follow!(target_account)).to be_kind_of Follow + expect(account.follow!(target_account)).to be_a Follow end.to change { account.following.count }.by 1 end end @@ -102,7 +111,7 @@ describe AccountInteractions do describe '#block' do it 'creates and returns Block' do expect do - expect(account.block!(target_account)).to be_kind_of Block + expect(account.block!(target_account)).to be_a Block end.to change { account.block_relationships.count }.by 1 end end @@ -110,113 +119,113 @@ describe AccountInteractions do describe '#mute!' do subject { account.mute!(target_account, notifications: arg_notifications) } - context 'Mute does not exist yet' do - context 'arg :notifications is nil' do + context 'when Mute does not exist yet' do + context 'when arg :notifications is nil' do let(:arg_notifications) { nil } it 'creates Mute, and returns Mute' do expect do - expect(subject).to be_kind_of Mute + expect(subject).to be_a Mute end.to change { account.mute_relationships.count }.by 1 end end - context 'arg :notifications is false' do + context 'when arg :notifications is false' do let(:arg_notifications) { false } it 'creates Mute, and returns Mute' do expect do - expect(subject).to be_kind_of Mute + expect(subject).to be_a Mute end.to change { account.mute_relationships.count }.by 1 end end - context 'arg :notifications is true' do + context 'when arg :notifications is true' do let(:arg_notifications) { true } it 'creates Mute, and returns Mute' do expect do - expect(subject).to be_kind_of Mute + expect(subject).to be_a Mute end.to change { account.mute_relationships.count }.by 1 end end end - context 'Mute already exists' do + context 'when Mute already exists' do before do account.mute_relationships << mute end let(:mute) do Fabricate(:mute, - account: account, - target_account: target_account, + account: account, + target_account: target_account, hide_notifications: hide_notifications) end - context 'mute.hide_notifications is true' do + context 'when mute.hide_notifications is true' do let(:hide_notifications) { true } - context 'arg :notifications is nil' do + context 'when arg :notifications is nil' do let(:arg_notifications) { nil } it 'returns Mute without updating mute.hide_notifications' do expect do - expect(subject).to be_kind_of Mute - end.not_to change { mute.reload.hide_notifications? }.from(true) + expect(subject).to be_a Mute + end.to_not change { mute.reload.hide_notifications? }.from(true) end end - context 'arg :notifications is false' do + context 'when arg :notifications is false' do let(:arg_notifications) { false } it 'returns Mute, and updates mute.hide_notifications false' do expect do - expect(subject).to be_kind_of Mute + expect(subject).to be_a Mute end.to change { mute.reload.hide_notifications? }.from(true).to(false) end end - context 'arg :notifications is true' do + context 'when arg :notifications is true' do let(:arg_notifications) { true } it 'returns Mute without updating mute.hide_notifications' do expect do - expect(subject).to be_kind_of Mute - end.not_to change { mute.reload.hide_notifications? }.from(true) + expect(subject).to be_a Mute + end.to_not change { mute.reload.hide_notifications? }.from(true) end end end - context 'mute.hide_notifications is false' do + context 'when mute.hide_notifications is false' do let(:hide_notifications) { false } - context 'arg :notifications is nil' do + context 'when arg :notifications is nil' do let(:arg_notifications) { nil } it 'returns Mute, and updates mute.hide_notifications true' do expect do - expect(subject).to be_kind_of Mute + expect(subject).to be_a Mute end.to change { mute.reload.hide_notifications? }.from(false).to(true) end end - context 'arg :notifications is false' do + context 'when arg :notifications is false' do let(:arg_notifications) { false } it 'returns Mute without updating mute.hide_notifications' do expect do - expect(subject).to be_kind_of Mute - end.not_to change { mute.reload.hide_notifications? }.from(false) + expect(subject).to be_a Mute + end.to_not change { mute.reload.hide_notifications? }.from(false) end end - context 'arg :notifications is true' do + context 'when arg :notifications is true' do let(:arg_notifications) { true } it 'returns Mute, and updates mute.hide_notifications true' do expect do - expect(subject).to be_kind_of Mute + expect(subject).to be_a Mute end.to change { mute.reload.hide_notifications? }.from(false).to(true) end end @@ -225,25 +234,25 @@ describe AccountInteractions do end describe '#mute_conversation!' do - let(:conversation) { Fabricate(:conversation) } - subject { account.mute_conversation!(conversation) } + let(:conversation) { Fabricate(:conversation) } + it 'creates and returns ConversationMute' do expect do - is_expected.to be_kind_of ConversationMute + expect(subject).to be_a ConversationMute end.to change { account.conversation_mutes.count }.by 1 end end describe '#block_domain!' do - let(:domain) { 'example.com' } - subject { account.block_domain!(domain) } + let(:domain) { 'example.com' } + it 'creates and returns AccountDomainBlock' do expect do - is_expected.to be_kind_of AccountDomainBlock + expect(subject).to be_a AccountDomainBlock end.to change { account.domain_blocks.count }.by 1 end end @@ -251,17 +260,17 @@ describe AccountInteractions do describe '#unfollow!' do subject { account.unfollow!(target_account) } - context 'following target_account' do + context 'when following target_account' do it 'returns destroyed Follow' do account.active_relationships.create(target_account: target_account) - is_expected.to be_kind_of Follow + expect(subject).to be_a Follow expect(subject).to be_destroyed end end - context 'not following target_account' do + context 'when not following target_account' do it 'returns nil' do - is_expected.to be_nil + expect(subject).to be_nil end end end @@ -269,17 +278,17 @@ describe AccountInteractions do describe '#unblock!' do subject { account.unblock!(target_account) } - context 'blocking target_account' do + context 'when blocking target_account' do it 'returns destroyed Block' do account.block_relationships.create(target_account: target_account) - is_expected.to be_kind_of Block + expect(subject).to be_a Block expect(subject).to be_destroyed end end - context 'not blocking target_account' do + context 'when not blocking target_account' do it 'returns nil' do - is_expected.to be_nil + expect(subject).to be_nil end end end @@ -287,58 +296,58 @@ describe AccountInteractions do describe '#unmute!' do subject { account.unmute!(target_account) } - context 'muting target_account' do + context 'when muting target_account' do it 'returns destroyed Mute' do account.mute_relationships.create(target_account: target_account) - is_expected.to be_kind_of Mute + expect(subject).to be_a Mute expect(subject).to be_destroyed end end - context 'not muting target_account' do + context 'when not muting target_account' do it 'returns nil' do - is_expected.to be_nil + expect(subject).to be_nil end end end describe '#unmute_conversation!' do - let(:conversation) { Fabricate(:conversation) } - subject { account.unmute_conversation!(conversation) } - context 'muting the conversation' do + let(:conversation) { Fabricate(:conversation) } + + context 'when muting the conversation' do it 'returns destroyed ConversationMute' do account.conversation_mutes.create(conversation: conversation) - is_expected.to be_kind_of ConversationMute + expect(subject).to be_a ConversationMute expect(subject).to be_destroyed end end - context 'not muting the conversation' do + context 'when not muting the conversation' do it 'returns nil' do - is_expected.to be nil + expect(subject).to be_nil end end end describe '#unblock_domain!' do - let(:domain) { 'example.com' } - subject { account.unblock_domain!(domain) } - context 'blocking the domain' do + let(:domain) { 'example.com' } + + context 'when blocking the domain' do it 'returns destroyed AccountDomainBlock' do account_domain_block = Fabricate(:account_domain_block, domain: domain) account.domain_blocks << account_domain_block - is_expected.to be_kind_of AccountDomainBlock + expect(subject).to be_a AccountDomainBlock expect(subject).to be_destroyed end end - context 'unblocking the domain' do + context 'when unblocking the domain' do it 'returns nil' do - is_expected.to be_nil + expect(subject).to be_nil end end end @@ -346,16 +355,16 @@ describe AccountInteractions do describe '#following?' do subject { account.following?(target_account) } - context 'following target_account' do + context 'when following target_account' do it 'returns true' do account.active_relationships.create(target_account: target_account) - is_expected.to be true + expect(subject).to be true end end - context 'not following target_account' do + context 'when not following target_account' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end @@ -363,16 +372,16 @@ describe AccountInteractions do describe '#followed_by?' do subject { account.followed_by?(target_account) } - context 'followed by target_account' do + context 'when followed by target_account' do it 'returns true' do account.passive_relationships.create(account: target_account) - is_expected.to be true + expect(subject).to be true end end - context 'not followed by target_account' do + context 'when not followed by target_account' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end @@ -380,36 +389,36 @@ describe AccountInteractions do describe '#blocking?' do subject { account.blocking?(target_account) } - context 'blocking target_account' do + context 'when blocking target_account' do it 'returns true' do account.block_relationships.create(target_account: target_account) - is_expected.to be true + expect(subject).to be true end end - context 'not blocking target_account' do + context 'when not blocking target_account' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#domain_blocking?' do - let(:domain) { 'example.com' } - subject { account.domain_blocking?(domain) } - context 'blocking the domain' do - it' returns true' do + let(:domain) { 'example.com' } + + context 'when blocking the domain' do + it 'returns true' do account_domain_block = Fabricate(:account_domain_block, domain: domain) account.domain_blocks << account_domain_block - is_expected.to be true + expect(subject).to be true end end - context 'not blocking the domain' do + context 'when not blocking the domain' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end @@ -417,61 +426,61 @@ describe AccountInteractions do describe '#muting?' do subject { account.muting?(target_account) } - context 'muting target_account' do + context 'when muting target_account' do it 'returns true' do mute = Fabricate(:mute, account: account, target_account: target_account) account.mute_relationships << mute - is_expected.to be true + expect(subject).to be true end end - context 'not muting target_account' do + context 'when not muting target_account' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#muting_conversation?' do - let(:conversation) { Fabricate(:conversation) } - subject { account.muting_conversation?(conversation) } - context 'muting the conversation' do + let(:conversation) { Fabricate(:conversation) } + + context 'when muting the conversation' do it 'returns true' do account.conversation_mutes.create(conversation: conversation) - is_expected.to be true + expect(subject).to be true end end - context 'not muting the conversation' do + context 'when not muting the conversation' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#muting_notifications?' do + subject { account.muting_notifications?(target_account) } + before do mute = Fabricate(:mute, target_account: target_account, account: account, hide_notifications: hide) account.mute_relationships << mute end - subject { account.muting_notifications?(target_account) } - - context 'muting notifications of target_account' do + context 'when muting notifications of target_account' do let(:hide) { true } it 'returns true' do - is_expected.to be true + expect(subject).to be true end end - context 'not muting notifications of target_account' do + context 'when not muting notifications of target_account' do let(:hide) { false } it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end @@ -479,96 +488,96 @@ describe AccountInteractions do describe '#requested?' do subject { account.requested?(target_account) } - context 'requested by target_account' do + context 'with requested by target_account' do it 'returns true' do Fabricate(:follow_request, account: account, target_account: target_account) - is_expected.to be true + expect(subject).to be true end end - context 'not requested by target_account' do + context 'when not requested by target_account' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#favourited?' do - let(:status) { Fabricate(:status, account: account, favourites: favourites) } - subject { account.favourited?(status) } - context 'favorited' do + let(:status) { Fabricate(:status, account: account, favourites: favourites) } + + context 'when favorited' do let(:favourites) { [Fabricate(:favourite, account: account)] } it 'returns true' do - is_expected.to be true + expect(subject).to be true end end - context 'not favorited' do + context 'when not favorited' do let(:favourites) { [] } it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#reblogged?' do - let(:status) { Fabricate(:status, account: account, reblogs: reblogs) } - subject { account.reblogged?(status) } - context 'reblogged' do + let(:status) { Fabricate(:status, account: account, reblogs: reblogs) } + + context 'with reblogged' do let(:reblogs) { [Fabricate(:status, account: account)] } it 'returns true' do - is_expected.to be true + expect(subject).to be true end end - context 'not reblogged' do + context 'when not reblogged' do let(:reblogs) { [] } it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#pinned?' do - let(:status) { Fabricate(:status, account: account) } - subject { account.pinned?(status) } - context 'pinned' do + let(:status) { Fabricate(:status, account: account) } + + context 'when pinned' do it 'returns true' do Fabricate(:status_pin, account: account, status: status) - is_expected.to be true + expect(subject).to be true end end - context 'not pinned' do + context 'when not pinned' do it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe '#remote_followers_hash' do let(:me) { Fabricate(:account, username: 'Me') } - let(:remote_1) { Fabricate(:account, username: 'alice', domain: 'example.org', uri: 'https://example.org/users/alice') } - let(:remote_2) { Fabricate(:account, username: 'bob', domain: 'example.org', uri: 'https://example.org/users/bob') } - let(:remote_3) { Fabricate(:account, username: 'instance-actor', domain: 'example.org', uri: 'https://example.org') } - let(:remote_4) { Fabricate(:account, username: 'eve', domain: 'foo.org', uri: 'https://foo.org/users/eve') } + let(:remote_alice) { Fabricate(:account, username: 'alice', domain: 'example.org', uri: 'https://example.org/users/alice') } + let(:remote_bob) { Fabricate(:account, username: 'bob', domain: 'example.org', uri: 'https://example.org/users/bob') } + let(:remote_instance_actor) { Fabricate(:account, username: 'instance-actor', domain: 'example.org', uri: 'https://example.org') } + let(:remote_eve) { Fabricate(:account, username: 'eve', domain: 'foo.org', uri: 'https://foo.org/users/eve') } before do - remote_1.follow!(me) - remote_2.follow!(me) - remote_3.follow!(me) - remote_4.follow!(me) - me.follow!(remote_1) + remote_alice.follow!(me) + remote_bob.follow!(me) + remote_instance_actor.follow!(me) + remote_eve.follow!(me) + me.follow!(remote_alice) end it 'returns correct hash for remote domains' do @@ -580,33 +589,33 @@ describe AccountInteractions do it 'invalidates cache as needed when removing or adding followers' do expect(me.remote_followers_hash('https://example.org/')).to eq '20aecbe774b3d61c25094370baf370012b9271c5b172ecedb05caff8d79ef0c7' - remote_3.unfollow!(me) + remote_instance_actor.unfollow!(me) expect(me.remote_followers_hash('https://example.org/')).to eq '707962e297b7bd94468a21bc8e506a1bcea607a9142cd64e27c9b106b2a5f6ec' - remote_1.unfollow!(me) + remote_alice.unfollow!(me) expect(me.remote_followers_hash('https://example.org/')).to eq '241b00794ce9b46aa864f3220afadef128318da2659782985bac5ed5bd436bff' - remote_1.follow!(me) + remote_alice.follow!(me) expect(me.remote_followers_hash('https://example.org/')).to eq '707962e297b7bd94468a21bc8e506a1bcea607a9142cd64e27c9b106b2a5f6ec' end end describe '#local_followers_hash' do let(:me) { Fabricate(:account, username: 'Me') } - let(:remote_1) { Fabricate(:account, username: 'alice', domain: 'example.org', uri: 'https://example.org/users/alice') } + let(:remote_alice) { Fabricate(:account, username: 'alice', domain: 'example.org', uri: 'https://example.org/users/alice') } before do - me.follow!(remote_1) + me.follow!(remote_alice) end it 'returns correct hash for local users' do - expect(remote_1.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) + expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) end it 'invalidates cache as needed when removing or adding followers' do - expect(remote_1.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) - me.unfollow!(remote_1) - expect(remote_1.local_followers_hash).to eq '0000000000000000000000000000000000000000000000000000000000000000' - me.follow!(remote_1) - expect(remote_1.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) + expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) + me.unfollow!(remote_alice) + expect(remote_alice.local_followers_hash).to eq '0000000000000000000000000000000000000000000000000000000000000000' + me.follow!(remote_alice) + expect(remote_alice.local_followers_hash).to eq Digest::SHA256.hexdigest(ActivityPub::TagManager.instance.uri_for(me)) end end @@ -681,4 +690,32 @@ describe AccountInteractions do end end end + + describe '#lists_for_local_distribution' do + let(:account) { Fabricate(:user, current_sign_in_at: Time.now.utc).account } + let!(:inactive_follower_user) { Fabricate(:user, current_sign_in_at: 5.years.ago) } + let!(:follower_user) { Fabricate(:user, current_sign_in_at: Time.now.utc) } + let!(:follow_request_user) { Fabricate(:user, current_sign_in_at: Time.now.utc) } + + let!(:inactive_follower_list) { Fabricate(:list, account: inactive_follower_user.account) } + let!(:follower_list) { Fabricate(:list, account: follower_user.account) } + let!(:follow_request_list) { Fabricate(:list, account: follow_request_user.account) } + + let!(:self_list) { Fabricate(:list, account: account) } + + before do + inactive_follower_user.account.follow!(account) + follower_user.account.follow!(account) + follow_request_user.account.follow_requests.create!(target_account: account) + + inactive_follower_list.accounts << account + follower_list.accounts << account + follow_request_list.accounts << account + self_list.accounts << account + end + + it 'includes only the list from the active follower and from oneself' do + expect(account.lists_for_local_distribution.to_a).to contain_exactly(follower_list, self_list) + end + end end diff --git a/spec/models/concerns/account_statuses_search_spec.rb b/spec/models/concerns/account_statuses_search_spec.rb new file mode 100644 index 0000000000..46362936f4 --- /dev/null +++ b/spec/models/concerns/account_statuses_search_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountStatusesSearch do + let(:account) { Fabricate(:account, indexable: indexable) } + + before do + allow(Chewy).to receive(:enabled?).and_return(true) + end + + describe '#enqueue_update_public_statuses_index' do + before do + allow(account).to receive(:enqueue_add_to_public_statuses_index) + allow(account).to receive(:enqueue_remove_from_public_statuses_index) + end + + context 'when account is indexable' do + let(:indexable) { true } + + it 'enqueues add_to_public_statuses_index and not to remove_from_public_statuses_index' do + account.enqueue_update_public_statuses_index + expect(account).to have_received(:enqueue_add_to_public_statuses_index) + expect(account).to_not have_received(:enqueue_remove_from_public_statuses_index) + end + end + + context 'when account is not indexable' do + let(:indexable) { false } + + it 'enqueues remove_from_public_statuses_index and not to add_to_public_statuses_index' do + account.enqueue_update_public_statuses_index + expect(account).to have_received(:enqueue_remove_from_public_statuses_index) + expect(account).to_not have_received(:enqueue_add_to_public_statuses_index) + end + end + end + + describe '#enqueue_add_to_public_statuses_index' do + let(:indexable) { true } + let(:worker) { AddToPublicStatusesIndexWorker } + + before do + allow(worker).to receive(:perform_async) + end + + it 'enqueues AddToPublicStatusesIndexWorker' do + account.enqueue_add_to_public_statuses_index + expect(worker).to have_received(:perform_async).with(account.id) + end + end + + describe '#enqueue_remove_from_public_statuses_index' do + let(:indexable) { false } + let(:worker) { RemoveFromPublicStatusesIndexWorker } + + before do + allow(worker).to receive(:perform_async) + end + + it 'enqueues RemoveFromPublicStatusesIndexWorker' do + account.enqueue_remove_from_public_statuses_index + expect(worker).to have_received(:perform_async).with(account.id) + end + end +end diff --git a/spec/models/concerns/remotable_spec.rb b/spec/models/concerns/remotable_spec.rb index ca2d65d2d1..b2aa56a704 100644 --- a/spec/models/concerns/remotable_spec.rb +++ b/spec/models/concerns/remotable_spec.rb @@ -3,48 +3,47 @@ require 'rails_helper' RSpec.describe Remotable do - class Foo - def initialize - @attrs = {} - end + let(:foo_class) do + Class.new do + def initialize + @attrs = {} + end - def [](arg) - @attrs[arg] - end + def [](arg) + @attrs[arg] + end - def []=(arg1, arg2) - @attrs[arg1] = arg2 - end + def []=(arg1, arg2) + @attrs[arg1] = arg2 + end - def hoge=(arg); end + def hoge=(arg); end - def hoge_file_name; end + def hoge_file_name; end - def hoge_file_name=(arg); end + def hoge_file_name=(arg); end - def has_attribute?(arg); end + def has_attribute?(arg); end - def self.attachment_definitions - { hoge: nil } - end - end - - before do - class Foo - include Remotable - - remotable_attachment :hoge, 1.kilobyte + def self.attachment_definitions + { hoge: nil } + end end end let(:attribute_name) { "#{hoge}_remote_url".to_sym } let(:code) { 200 } let(:file) { 'filename="foo.txt"' } - let(:foo) { Foo.new } + let(:foo) { foo_class.new } let(:headers) { { 'content-disposition' => file } } let(:hoge) { :hoge } let(:url) { 'https://google.com' } + before do + foo_class.include described_class + foo_class.remotable_attachment :hoge, 1.kilobyte + end + it 'defines a method #hoge_remote_url=' do expect(foo).to respond_to(:hoge_remote_url=) end @@ -147,8 +146,8 @@ RSpec.describe Remotable do let(:code) { 500 } it 'does not assign file' do - expect(foo).not_to receive(:public_send).with("#{hoge}=", any_args) - expect(foo).not_to receive(:public_send).with("#{hoge}_file_name=", any_args) + expect(foo).to_not receive(:public_send).with("#{hoge}=", any_args) + expect(foo).to_not receive(:public_send).with("#{hoge}_file_name=", any_args) foo.hoge_remote_url = url end @@ -157,7 +156,7 @@ RSpec.describe Remotable do context 'when the response is successful' do let(:code) { 200 } - context 'and contains Content-Disposition header' do + context 'when contains Content-Disposition header' do let(:file) { 'filename="foo.txt"' } let(:headers) { { 'content-disposition' => file } } diff --git a/spec/models/concerns/status_threading_concern_spec.rb b/spec/models/concerns/status_threading_concern_spec.rb index 50286ef77b..2eac1ca6e5 100644 --- a/spec/models/concerns/status_threading_concern_spec.rb +++ b/spec/models/concerns/status_threading_concern_spec.rb @@ -8,40 +8,40 @@ describe StatusThreadingConcern do let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') } let!(:jeff) { Fabricate(:account, username: 'jeff') } let!(:status) { Fabricate(:status, account: alice) } - let!(:reply1) { Fabricate(:status, thread: status, account: jeff) } - let!(:reply2) { Fabricate(:status, thread: reply1, account: bob) } - let!(:reply3) { Fabricate(:status, thread: reply2, account: alice) } + let!(:reply_to_status) { Fabricate(:status, thread: status, account: jeff) } + let!(:reply_to_first_reply) { Fabricate(:status, thread: reply_to_status, account: bob) } + let!(:reply_to_second_reply) { Fabricate(:status, thread: reply_to_first_reply, account: alice) } let!(:viewer) { Fabricate(:account, username: 'viewer') } it 'returns conversation history' do - expect(reply3.ancestors(4)).to include(status, reply1, reply2) + expect(reply_to_second_reply.ancestors(4)).to include(status, reply_to_status, reply_to_first_reply) end it 'does not return conversation history user is not allowed to see' do - reply1.update(visibility: :private) + reply_to_status.update(visibility: :private) status.update(visibility: :direct) - expect(reply3.ancestors(4, viewer)).to_not include(reply1, status) + expect(reply_to_second_reply.ancestors(4, viewer)).to_not include(reply_to_status, status) end it 'does not return conversation history from blocked users' do viewer.block!(jeff) - expect(reply3.ancestors(4, viewer)).to_not include(reply1) + expect(reply_to_second_reply.ancestors(4, viewer)).to_not include(reply_to_status) end it 'does not return conversation history from muted users' do viewer.mute!(jeff) - expect(reply3.ancestors(4, viewer)).to_not include(reply1) + expect(reply_to_second_reply.ancestors(4, viewer)).to_not include(reply_to_status) end it 'does not return conversation history from silenced and not followed users' do jeff.silence! - expect(reply3.ancestors(4, viewer)).to_not include(reply1) + expect(reply_to_second_reply.ancestors(4, viewer)).to_not include(reply_to_status) end it 'does not return conversation history from blocked domains' do viewer.block_domain!('example.com') - expect(reply3.ancestors(4, viewer)).to_not include(reply2) + expect(reply_to_second_reply.ancestors(4, viewer)).to_not include(reply_to_first_reply) end it 'ignores deleted records' do @@ -83,40 +83,40 @@ describe StatusThreadingConcern do let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') } let!(:jeff) { Fabricate(:account, username: 'jeff') } let!(:status) { Fabricate(:status, account: alice) } - let!(:reply1) { Fabricate(:status, thread: status, account: alice) } - let!(:reply2) { Fabricate(:status, thread: status, account: bob) } - let!(:reply3) { Fabricate(:status, thread: reply1, account: jeff) } + let!(:reply_to_status_from_alice) { Fabricate(:status, thread: status, account: alice) } + let!(:reply_to_status_from_bob) { Fabricate(:status, thread: status, account: bob) } + let!(:reply_to_alice_reply_from_jeff) { Fabricate(:status, thread: reply_to_status_from_alice, account: jeff) } let!(:viewer) { Fabricate(:account, username: 'viewer') } it 'returns replies' do - expect(status.descendants(4)).to include(reply1, reply2, reply3) + expect(status.descendants(4)).to include(reply_to_status_from_alice, reply_to_status_from_bob, reply_to_alice_reply_from_jeff) end it 'does not return replies user is not allowed to see' do - reply1.update(visibility: :private) - reply3.update(visibility: :direct) + reply_to_status_from_alice.update(visibility: :private) + reply_to_alice_reply_from_jeff.update(visibility: :direct) - expect(status.descendants(4, viewer)).to_not include(reply1, reply3) + expect(status.descendants(4, viewer)).to_not include(reply_to_status_from_alice, reply_to_alice_reply_from_jeff) end it 'does not return replies from blocked users' do viewer.block!(jeff) - expect(status.descendants(4, viewer)).to_not include(reply3) + expect(status.descendants(4, viewer)).to_not include(reply_to_alice_reply_from_jeff) end it 'does not return replies from muted users' do viewer.mute!(jeff) - expect(status.descendants(4, viewer)).to_not include(reply3) + expect(status.descendants(4, viewer)).to_not include(reply_to_alice_reply_from_jeff) end it 'does not return replies from silenced and not followed users' do jeff.silence! - expect(status.descendants(4, viewer)).to_not include(reply3) + expect(status.descendants(4, viewer)).to_not include(reply_to_alice_reply_from_jeff) end it 'does not return replies from blocked domains' do viewer.block_domain!('example.com') - expect(status.descendants(4, viewer)).to_not include(reply2) + expect(status.descendants(4, viewer)).to_not include(reply_to_status_from_bob) end it 'promotes self-replies to the top while leaving the rest in order' do diff --git a/spec/models/conversation_mute_spec.rb b/spec/models/conversation_mute_spec.rb deleted file mode 100644 index 3fc2915d4f..0000000000 --- a/spec/models/conversation_mute_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe ConversationMute, type: :model do -end diff --git a/spec/models/conversation_spec.rb b/spec/models/conversation_spec.rb index 8b5e4fdaf7..c1d6659aa7 100644 --- a/spec/models/conversation_spec.rb +++ b/spec/models/conversation_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Conversation, type: :model do +RSpec.describe Conversation do describe '#local?' do it 'returns true when URI is nil' do expect(Fabricate(:conversation).local?).to be true diff --git a/spec/models/custom_emoji_category_spec.rb b/spec/models/custom_emoji_category_spec.rb index 160033f4d4..30de07bd81 100644 --- a/spec/models/custom_emoji_category_spec.rb +++ b/spec/models/custom_emoji_category_spec.rb @@ -1,5 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe CustomEmojiCategory, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe CustomEmojiCategory do + describe 'validations' do + it 'validates name presence' do + record = described_class.new(name: nil) + + expect(record).to_not be_valid + expect(record).to model_have_error_on_field(:name) + end + end end diff --git a/spec/models/custom_emoji_filter_spec.rb b/spec/models/custom_emoji_filter_spec.rb index 2b1b5dc542..c36fecd60d 100644 --- a/spec/models/custom_emoji_filter_spec.rb +++ b/spec/models/custom_emoji_filter_spec.rb @@ -4,50 +4,50 @@ require 'rails_helper' RSpec.describe CustomEmojiFilter do describe '#results' do - let!(:custom_emoji_0) { Fabricate(:custom_emoji, domain: 'a') } - let!(:custom_emoji_1) { Fabricate(:custom_emoji, domain: 'b') } - let!(:custom_emoji_2) { Fabricate(:custom_emoji, domain: nil, shortcode: 'hoge') } - subject { described_class.new(params).results } - context 'params have values' do - context 'local' do + let!(:custom_emoji_domain_a) { Fabricate(:custom_emoji, domain: 'a') } + let!(:custom_emoji_domain_b) { Fabricate(:custom_emoji, domain: 'b') } + let!(:custom_emoji_domain_nil) { Fabricate(:custom_emoji, domain: nil, shortcode: 'hoge') } + + context 'when params have values' do + context 'when local' do let(:params) { { local: true } } it 'returns ActiveRecord::Relation' do - expect(subject).to be_kind_of(ActiveRecord::Relation) - expect(subject).to match_array([custom_emoji_2]) + expect(subject).to be_a(ActiveRecord::Relation) + expect(subject).to contain_exactly(custom_emoji_domain_nil) end end - context 'remote' do + context 'when remote' do let(:params) { { remote: true } } it 'returns ActiveRecord::Relation' do - expect(subject).to be_kind_of(ActiveRecord::Relation) - expect(subject).to match_array([custom_emoji_0, custom_emoji_1]) + expect(subject).to be_a(ActiveRecord::Relation) + expect(subject).to contain_exactly(custom_emoji_domain_a, custom_emoji_domain_b) end end - context 'by_domain' do + context 'with by_domain' do let(:params) { { by_domain: 'a' } } it 'returns ActiveRecord::Relation' do - expect(subject).to be_kind_of(ActiveRecord::Relation) - expect(subject).to match_array([custom_emoji_0]) + expect(subject).to be_a(ActiveRecord::Relation) + expect(subject).to contain_exactly(custom_emoji_domain_a) end end - context 'shortcode' do + context 'when shortcode' do let(:params) { { shortcode: 'hoge' } } it 'returns ActiveRecord::Relation' do - expect(subject).to be_kind_of(ActiveRecord::Relation) - expect(subject).to match_array([custom_emoji_2]) + expect(subject).to be_a(ActiveRecord::Relation) + expect(subject).to contain_exactly(custom_emoji_domain_nil) end end - context 'else' do + context 'when some other case' do let(:params) { { else: 'else' } } it 'raises Mastodon::InvalidParameterError' do @@ -58,12 +58,12 @@ RSpec.describe CustomEmojiFilter do end end - context 'params without value' do + context 'when params without value' do let(:params) { { hoge: nil } } it 'returns ActiveRecord::Relation' do - expect(subject).to be_kind_of(ActiveRecord::Relation) - expect(subject).to match_array([custom_emoji_0, custom_emoji_1, custom_emoji_2]) + expect(subject).to be_a(ActiveRecord::Relation) + expect(subject).to contain_exactly(custom_emoji_domain_a, custom_emoji_domain_b, custom_emoji_domain_nil) end end end diff --git a/spec/models/custom_emoji_spec.rb b/spec/models/custom_emoji_spec.rb index 9de218b4fe..8a6487c321 100644 --- a/spec/models/custom_emoji_spec.rb +++ b/spec/models/custom_emoji_spec.rb @@ -1,48 +1,50 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe CustomEmoji, type: :model do +RSpec.describe CustomEmoji do describe '#search' do - let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: shortcode) } - subject { described_class.search(search_term) } - context 'shortcode is exact' do + let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: shortcode) } + + context 'when shortcode is exact' do let(:shortcode) { 'blobpats' } let(:search_term) { 'blobpats' } it 'finds emoji' do - is_expected.to include(custom_emoji) + expect(subject).to include(custom_emoji) end end - context 'shortcode is partial' do + context 'when shortcode is partial' do let(:shortcode) { 'blobpats' } let(:search_term) { 'blob' } it 'finds emoji' do - is_expected.to include(custom_emoji) + expect(subject).to include(custom_emoji) end end end describe '#local?' do - let(:custom_emoji) { Fabricate(:custom_emoji, domain: domain) } - subject { custom_emoji.local? } - context 'domain is nil' do + let(:custom_emoji) { Fabricate(:custom_emoji, domain: domain) } + + context 'when domain is nil' do let(:domain) { nil } it 'returns true' do - is_expected.to be true + expect(subject).to be true end end - context 'domain is present' do + context 'when domain is present' do let(:domain) { 'example.com' } it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end @@ -55,15 +57,15 @@ RSpec.describe CustomEmoji, type: :model do end describe '.from_text' do - let!(:emojo) { Fabricate(:custom_emoji) } - subject { described_class.from_text(text, nil) } + let!(:emojo) { Fabricate(:custom_emoji) } + context 'with plain text' do let(:text) { 'Hello :coolcat:' } it 'returns records used via shortcodes in text' do - is_expected.to include(emojo) + expect(subject).to include(emojo) end end @@ -71,7 +73,7 @@ RSpec.describe CustomEmoji, type: :model do let(:text) { '

Hello :coolcat:

' } it 'returns records used via shortcodes in text' do - is_expected.to include(emojo) + expect(subject).to include(emojo) end end end @@ -79,7 +81,7 @@ RSpec.describe CustomEmoji, type: :model do describe 'pre_validation' do let(:custom_emoji) { Fabricate(:custom_emoji, domain: 'wWw.MaStOdOn.CoM') } - it 'should downcase' do + it 'downcases' do custom_emoji.valid? expect(custom_emoji.domain).to eq('www.mastodon.com') end diff --git a/spec/models/custom_filter_keyword_spec.rb b/spec/models/custom_filter_keyword_spec.rb deleted file mode 100644 index e15b9dad50..0000000000 --- a/spec/models/custom_filter_keyword_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe CustomFilterKeyword, type: :model do -end diff --git a/spec/models/custom_filter_spec.rb b/spec/models/custom_filter_spec.rb deleted file mode 100644 index 3943dd5f1a..0000000000 --- a/spec/models/custom_filter_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe CustomFilter, type: :model do -end diff --git a/spec/models/device_spec.rb b/spec/models/device_spec.rb deleted file mode 100644 index f56fbf9785..0000000000 --- a/spec/models/device_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe Device, type: :model do - -end diff --git a/spec/models/domain_allow_spec.rb b/spec/models/domain_allow_spec.rb index e65435127d..49e16376ea 100644 --- a/spec/models/domain_allow_spec.rb +++ b/spec/models/domain_allow_spec.rb @@ -1,5 +1,18 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe DomainAllow, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe DomainAllow do + describe 'scopes' do + describe 'matches_domain' do + let(:domain) { Fabricate(:domain_allow, domain: 'example.com') } + let(:other_domain) { Fabricate(:domain_allow, domain: 'example.biz') } + + it 'returns the correct records' do + results = described_class.matches_domain('example.com') + + expect(results).to eq([domain]) + end + end + end end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index 28647dc89c..67f53fa785 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -1,12 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe DomainBlock, type: :model do +RSpec.describe DomainBlock do describe 'validations' do - it 'has a valid fabricator' do - domain_block = Fabricate.build(:domain_block) - expect(domain_block).to be_valid - end - it 'is invalid without a domain' do domain_block = Fabricate.build(:domain_block, domain: nil) domain_block.valid? @@ -24,74 +21,92 @@ RSpec.describe DomainBlock, type: :model do describe '.blocked?' do it 'returns true if the domain is suspended' do Fabricate(:domain_block, domain: 'example.com', severity: :suspend) - expect(DomainBlock.blocked?('example.com')).to eq true + expect(described_class.blocked?('example.com')).to be true end it 'returns false even if the domain is silenced' do Fabricate(:domain_block, domain: 'example.com', severity: :silence) - expect(DomainBlock.blocked?('example.com')).to eq false + expect(described_class.blocked?('example.com')).to be false end it 'returns false if the domain is not suspended nor silenced' do - expect(DomainBlock.blocked?('example.com')).to eq false + expect(described_class.blocked?('example.com')).to be false end end describe '.rule_for' do it 'returns rule matching a blocked domain' do block = Fabricate(:domain_block, domain: 'example.com') - expect(DomainBlock.rule_for('example.com')).to eq block + expect(described_class.rule_for('example.com')).to eq block end it 'returns a rule matching a subdomain of a blocked domain' do block = Fabricate(:domain_block, domain: 'example.com') - expect(DomainBlock.rule_for('sub.example.com')).to eq block + expect(described_class.rule_for('sub.example.com')).to eq block end it 'returns a rule matching a blocked subdomain' do block = Fabricate(:domain_block, domain: 'sub.example.com') - expect(DomainBlock.rule_for('sub.example.com')).to eq block + expect(described_class.rule_for('sub.example.com')).to eq block end it 'returns a rule matching a blocked TLD' do block = Fabricate(:domain_block, domain: 'google') - expect(DomainBlock.rule_for('google')).to eq block + expect(described_class.rule_for('google')).to eq block end it 'returns a rule matching a subdomain of a blocked TLD' do block = Fabricate(:domain_block, domain: 'google') - expect(DomainBlock.rule_for('maps.google')).to eq block + expect(described_class.rule_for('maps.google')).to eq block end end describe '#stricter_than?' do it 'returns true if the new block has suspend severity while the old has lower severity' do - suspend = DomainBlock.new(domain: 'domain', severity: :suspend) - silence = DomainBlock.new(domain: 'domain', severity: :silence) - noop = DomainBlock.new(domain: 'domain', severity: :noop) + suspend = described_class.new(domain: 'domain', severity: :suspend) + silence = described_class.new(domain: 'domain', severity: :silence) + noop = described_class.new(domain: 'domain', severity: :noop) expect(suspend.stricter_than?(silence)).to be true expect(suspend.stricter_than?(noop)).to be true end it 'returns false if the new block has lower severity than the old one' do - suspend = DomainBlock.new(domain: 'domain', severity: :suspend) - silence = DomainBlock.new(domain: 'domain', severity: :silence) - noop = DomainBlock.new(domain: 'domain', severity: :noop) + suspend = described_class.new(domain: 'domain', severity: :suspend) + silence = described_class.new(domain: 'domain', severity: :silence) + noop = described_class.new(domain: 'domain', severity: :noop) expect(silence.stricter_than?(suspend)).to be false expect(noop.stricter_than?(suspend)).to be false expect(noop.stricter_than?(silence)).to be false end it 'returns false if the new block does is less strict regarding reports' do - older = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: true) - newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_reports: false) + older = described_class.new(domain: 'domain', severity: :silence, reject_reports: true) + newer = described_class.new(domain: 'domain', severity: :silence, reject_reports: false) expect(newer.stricter_than?(older)).to be false end it 'returns false if the new block does is less strict regarding media' do - older = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: true) - newer = DomainBlock.new(domain: 'domain', severity: :silence, reject_media: false) + older = described_class.new(domain: 'domain', severity: :silence, reject_media: true) + newer = described_class.new(domain: 'domain', severity: :silence, reject_media: false) expect(newer.stricter_than?(older)).to be false end end + + describe '#public_domain' do + context 'with a domain block that is obfuscated' do + let(:domain_block) { Fabricate(:domain_block, domain: 'hostname.example.com', obfuscate: true) } + + it 'garbles the domain' do + expect(domain_block.public_domain).to eq 'hostna**.******e.com' + end + end + + context 'with a domain block that is not obfuscated' do + let(:domain_block) { Fabricate(:domain_block, domain: 'example.com', obfuscate: false) } + + it 'returns the domain value' do + expect(domain_block.public_domain).to eq 'example.com' + end + end + end end diff --git a/spec/models/email_domain_block_spec.rb b/spec/models/email_domain_block_spec.rb index e23116888c..5874c5e53c 100644 --- a/spec/models/email_domain_block_spec.rb +++ b/spec/models/email_domain_block_spec.rb @@ -1,34 +1,29 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe EmailDomainBlock, type: :model do - describe 'validations' do - it 'has a valid fabricator' do - email_domain_block = Fabricate.build(:email_domain_block) - expect(email_domain_block).to be_valid - end - end - +RSpec.describe EmailDomainBlock do describe 'block?' do let(:input) { nil } - context 'given an e-mail address' do + context 'when given an e-mail address' do let(:input) { "foo@#{domain}" } - context do + context 'with a top level domain' do let(:domain) { 'example.com' } it 'returns true if the domain is blocked' do Fabricate(:email_domain_block, domain: 'example.com') - expect(EmailDomainBlock.block?(input)).to be true + expect(described_class.block?(input)).to be true end it 'returns false if the domain is not blocked' do Fabricate(:email_domain_block, domain: 'other-example.com') - expect(EmailDomainBlock.block?(input)).to be false + expect(described_class.block?(input)).to be false end end - context do + context 'with a subdomain' do let(:domain) { 'mail.example.com' } it 'returns true if it is a subdomain of a blocked domain' do @@ -38,12 +33,12 @@ RSpec.describe EmailDomainBlock, type: :model do end end - context 'given an array of domains' do + context 'when given an array of domains' do let(:input) { %w(foo.com mail.foo.com) } it 'returns true if the domain is blocked' do Fabricate(:email_domain_block, domain: 'mail.foo.com') - expect(EmailDomainBlock.block?(input)).to be true + expect(described_class.block?(input)).to be true end end end diff --git a/spec/models/encrypted_message_spec.rb b/spec/models/encrypted_message_spec.rb deleted file mode 100644 index 1238d57b68..0000000000 --- a/spec/models/encrypted_message_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe EncryptedMessage, type: :model do - -end diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb index 135d7a36ba..75468898d2 100644 --- a/spec/models/export_spec.rb +++ b/spec/models/export_spec.rb @@ -1,16 +1,18 @@ +# frozen_string_literal: true + require 'rails_helper' describe Export do let(:account) { Fabricate(:account) } let(:target_accounts) do - [ {}, { username: 'one', domain: 'local.host' } ].map(&method(:Fabricate).curry(2).call(:account)) + [{}, { username: 'one', domain: 'local.host' }].map(&method(:Fabricate).curry(2).call(:account)) end describe 'to_csv' do it 'returns a csv of the blocked accounts' do - target_accounts.each(&account.method(:block!)) + target_accounts.each { |target_account| account.block!(target_account) } - export = Export.new(account).to_blocked_accounts_csv + export = described_class.new(account).to_blocked_accounts_csv results = export.strip.split expect(results.size).to eq 2 @@ -18,9 +20,9 @@ describe Export do end it 'returns a csv of the muted accounts' do - target_accounts.each(&account.method(:mute!)) + target_accounts.each { |target_account| account.mute!(target_account) } - export = Export.new(account).to_muted_accounts_csv + export = described_class.new(account).to_muted_accounts_csv results = export.strip.split("\n") expect(results.size).to eq 3 @@ -29,9 +31,9 @@ describe Export do end it 'returns a csv of the following accounts' do - target_accounts.each(&account.method(:follow!)) + target_accounts.each { |target_account| account.follow!(target_account) } - export = Export.new(account).to_following_accounts_csv + export = described_class.new(account).to_following_accounts_csv results = export.strip.split("\n") expect(results.size).to eq 3 @@ -43,24 +45,24 @@ describe Export do describe 'total_storage' do it 'returns the total size of the media attachments' do media_attachment = Fabricate(:media_attachment, account: account) - expect(Export.new(account).total_storage).to eq media_attachment.file_file_size || 0 + expect(described_class.new(account).total_storage).to eq media_attachment.file_file_size || 0 end end describe 'total_follows' do it 'returns the total number of the followed accounts' do - target_accounts.each(&account.method(:follow!)) - expect(Export.new(account.reload).total_follows).to eq 2 + target_accounts.each { |target_account| account.follow!(target_account) } + expect(described_class.new(account.reload).total_follows).to eq 2 end it 'returns the total number of the blocked accounts' do - target_accounts.each(&account.method(:block!)) - expect(Export.new(account.reload).total_blocks).to eq 2 + target_accounts.each { |target_account| account.block!(target_account) } + expect(described_class.new(account.reload).total_blocks).to eq 2 end it 'returns the total number of the muted accounts' do - target_accounts.each(&account.method(:mute!)) - expect(Export.new(account.reload).total_mutes).to eq 2 + target_accounts.each { |target_account| account.mute!(target_account) } + expect(described_class.new(account.reload).total_mutes).to eq 2 end end end diff --git a/spec/models/extended_description_spec.rb b/spec/models/extended_description_spec.rb new file mode 100644 index 0000000000..ecc27c0f6d --- /dev/null +++ b/spec/models/extended_description_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ExtendedDescription do + describe '.current' do + context 'with the default values' do + it 'makes a new instance' do + record = described_class.current + + expect(record.text).to be_nil + expect(record.updated_at).to be_nil + end + end + + context 'with a custom setting value' do + before do + setting = instance_double(Setting, value: 'Extended text', updated_at: 10.days.ago) + allow(Setting).to receive(:find_by).with(var: 'site_extended_description').and_return(setting) + end + + it 'has the privacy text' do + record = described_class.current + + expect(record.text).to eq('Extended text') + end + end + end +end diff --git a/spec/models/favourite_spec.rb b/spec/models/favourite_spec.rb index ba1410a453..ef7fbdefcd 100644 --- a/spec/models/favourite_spec.rb +++ b/spec/models/favourite_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Favourite, type: :model do +RSpec.describe Favourite do let(:account) { Fabricate(:account) } context 'when status is a reblog' do @@ -8,12 +10,12 @@ RSpec.describe Favourite, type: :model do let(:status) { Fabricate(:status, reblog: reblog) } it 'invalidates if the reblogged status is already a favourite' do - Favourite.create!(account: account, status: reblog) - expect(Favourite.new(account: account, status: status).valid?).to eq false + described_class.create!(account: account, status: reblog) + expect(described_class.new(account: account, status: status).valid?).to be false end it 'replaces status with the reblogged one if it is a reblog' do - favourite = Favourite.create!(account: account, status: status) + favourite = described_class.create!(account: account, status: status) expect(favourite.status).to eq reblog end end @@ -22,7 +24,7 @@ RSpec.describe Favourite, type: :model do let(:status) { Fabricate(:status, reblog: nil) } it 'saves with the specified status' do - favourite = Favourite.create!(account: account, status: status) + favourite = described_class.create!(account: account, status: status) expect(favourite.status).to eq status end end diff --git a/spec/models/featured_tag_spec.rb b/spec/models/featured_tag_spec.rb deleted file mode 100644 index 07533e0b90..0000000000 --- a/spec/models/featured_tag_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe FeaturedTag, type: :model do -end diff --git a/spec/models/follow_recommendation_suppression_spec.rb b/spec/models/follow_recommendation_suppression_spec.rb deleted file mode 100644 index 39107a2b04..0000000000 --- a/spec/models/follow_recommendation_suppression_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe FollowRecommendationSuppression, type: :model do -end diff --git a/spec/models/follow_request_spec.rb b/spec/models/follow_request_spec.rb index 901eabc9df..01faec0e70 100644 --- a/spec/models/follow_request_spec.rb +++ b/spec/models/follow_request_spec.rb @@ -1,18 +1,41 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe FollowRequest, type: :model do +RSpec.describe FollowRequest do describe '#authorize!' do - let(:follow_request) { Fabricate(:follow_request, account: account, target_account: target_account) } - let(:account) { Fabricate(:account) } - let(:target_account) { Fabricate(:account) } + let!(:follow_request) { Fabricate(:follow_request, account: account, target_account: target_account) } + let(:account) { Fabricate(:account) } + let(:target_account) { Fabricate(:account) } + + context 'when the to-be-followed person has been added to a list' do + let!(:list) { Fabricate(:list, account: account) } + + before do + list.accounts << target_account + end + + it 'updates the ListAccount' do + expect { follow_request.authorize! }.to change { [list.list_accounts.first.follow_request_id, list.list_accounts.first.follow_id] }.from([follow_request.id, nil]).to([nil, anything]) + end + end it 'calls Account#follow!, MergeWorker.perform_async, and #destroy!' do - expect(account).to receive(:follow!).with(target_account, reblogs: true, notify: false, uri: follow_request.uri, languages: nil, bypass_limit: true) - expect(MergeWorker).to receive(:perform_async).with(target_account.id, account.id) + expect(account).to receive(:follow!).with(target_account, reblogs: true, notify: false, uri: follow_request.uri, languages: nil, bypass_limit: true) do + account.active_relationships.create!(target_account: target_account) + end + expect(MergeWorker).to receive(:perform_async).with(target_account.id, account.id) expect(follow_request).to receive(:destroy!) follow_request.authorize! end + it 'generates a Follow' do + follow_request = Fabricate.create(:follow_request) + follow_request.authorize! + target = follow_request.target_account + expect(follow_request.account.following?(target)).to be true + end + it 'correctly passes show_reblogs when true' do follow_request = Fabricate.create(:follow_request, show_reblogs: true) follow_request.authorize! @@ -27,4 +50,22 @@ RSpec.describe FollowRequest, type: :model do expect(follow_request.account.muting_reblogs?(target)).to be true end end + + describe '#reject!' do + let!(:follow_request) { Fabricate(:follow_request, account: account, target_account: target_account) } + let(:account) { Fabricate(:account) } + let(:target_account) { Fabricate(:account) } + + context 'when the to-be-followed person has been added to a list' do + let!(:list) { Fabricate(:list, account: account) } + + before do + list.accounts << target_account + end + + it 'deletes the ListAccount record' do + expect { follow_request.reject! }.to change { list.accounts.count }.from(1).to(0) + end + end + end end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index e723a1ef21..c7743183cc 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -1,16 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Follow, type: :model do +RSpec.describe Follow do let(:alice) { Fabricate(:account, username: 'alice') } let(:bob) { Fabricate(:account, username: 'bob') } describe 'validations' do - subject { Follow.new(account: alice, target_account: bob, rate_limit: true) } - - it 'has a valid fabricator' do - follow = Fabricate.build(:follow) - expect(follow).to be_valid - end + subject { described_class.new(account: alice, target_account: bob, rate_limit: true) } it 'is invalid without an account' do follow = Fabricate.build(:follow, account: nil) @@ -41,10 +38,10 @@ RSpec.describe Follow, type: :model do describe 'recent' do it 'sorts so that more recent follows comes earlier' do - follow0 = Follow.create!(account: alice, target_account: bob) - follow1 = Follow.create!(account: bob, target_account: alice) + follow0 = described_class.create!(account: alice, target_account: bob) + follow1 = described_class.create!(account: bob, target_account: alice) - a = Follow.recent.to_a + a = described_class.recent.to_a expect(a.size).to eq 2 expect(a[0]).to eq follow1 diff --git a/spec/models/form/admin_settings_spec.rb b/spec/models/form/admin_settings_spec.rb new file mode 100644 index 0000000000..0dc2d881ad --- /dev/null +++ b/spec/models/form/admin_settings_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Form::AdminSettings do + describe 'validations' do + describe 'site_contact_username' do + context 'with no accounts' do + it 'is not valid' do + setting = described_class.new(site_contact_username: 'Test') + setting.valid? + + expect(setting).to model_have_error_on_field(:site_contact_username) + end + end + + context 'with an account' do + before { Fabricate(:account, username: 'Glorp') } + + it 'is not valid when account doesnt match' do + setting = described_class.new(site_contact_username: 'Test') + setting.valid? + + expect(setting).to model_have_error_on_field(:site_contact_username) + end + + it 'is valid when account matches' do + setting = described_class.new(site_contact_username: 'Glorp') + setting.valid? + + expect(setting).to_not model_have_error_on_field(:site_contact_username) + end + end + end + end +end diff --git a/spec/models/form/import_spec.rb b/spec/models/form/import_spec.rb new file mode 100644 index 0000000000..2b70e396b9 --- /dev/null +++ b/spec/models/form/import_spec.rb @@ -0,0 +1,318 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Form::Import do + subject { described_class.new(current_account: account, type: import_type, mode: import_mode, data: data) } + + let(:account) { Fabricate(:account) } + let(:data) { fixture_file_upload(import_file) } + let(:import_mode) { 'merge' } + + describe 'validations' do + shared_examples 'incompatible import type' do |type, file| + let(:import_file) { file } + let(:import_type) { type } + + it 'has errors' do + subject.validate + expect(subject.errors[:data]).to include(I18n.t('imports.errors.incompatible_type')) + end + end + + shared_examples 'too many CSV rows' do |type, file, allowed_rows| + let(:import_file) { file } + let(:import_type) { type } + + before do + stub_const 'Form::Import::ROWS_PROCESSING_LIMIT', allowed_rows + end + + it 'has errors' do + subject.validate + expect(subject.errors[:data]).to include(I18n.t('imports.errors.over_rows_processing_limit', count: Form::Import::ROWS_PROCESSING_LIMIT)) + end + end + + shared_examples 'valid import' do |type, file| + let(:import_file) { file } + let(:import_type) { type } + + it 'passes validation' do + expect(subject).to be_valid + end + end + + context 'when the file too large' do + let(:import_type) { 'following' } + let(:import_file) { 'imports.txt' } + + before do + stub_const 'Form::Import::FILE_SIZE_LIMIT', 5 + end + + it 'has errors' do + subject.validate + expect(subject.errors[:data]).to include(I18n.t('imports.errors.too_large')) + end + end + + context 'when the CSV file is malformed CSV' do + let(:import_type) { 'following' } + let(:import_file) { 'boop.ogg' } + + it 'has errors' do + # NOTE: not testing more specific error because we don't know the string to match + expect(subject).to model_have_error_on_field(:data) + end + end + + context 'when importing more follows than allowed' do + let(:import_type) { 'following' } + let(:import_file) { 'imports.txt' } + + before do + allow(FollowLimitValidator).to receive(:limit_for_account).with(account).and_return(1) + end + + it 'has errors' do + subject.validate + expect(subject.errors[:data]).to include(I18n.t('users.follow_limit_reached', limit: 1)) + end + end + + it_behaves_like 'too many CSV rows', 'following', 'imports.txt', 1 + it_behaves_like 'too many CSV rows', 'blocking', 'imports.txt', 1 + it_behaves_like 'too many CSV rows', 'muting', 'imports.txt', 1 + it_behaves_like 'too many CSV rows', 'domain_blocking', 'domain_blocks.csv', 2 + it_behaves_like 'too many CSV rows', 'bookmarks', 'bookmark-imports.txt', 3 + it_behaves_like 'too many CSV rows', 'lists', 'lists.csv', 2 + + # Importing list of addresses with no headers into various types + it_behaves_like 'valid import', 'following', 'imports.txt' + it_behaves_like 'valid import', 'blocking', 'imports.txt' + it_behaves_like 'valid import', 'muting', 'imports.txt' + + # Importing domain blocks with headers into expected type + it_behaves_like 'valid import', 'domain_blocking', 'domain_blocks.csv' + + # Importing bookmarks list with no headers into expected type + it_behaves_like 'valid import', 'bookmarks', 'bookmark-imports.txt' + + # Importing lists with no headers into expected type + it_behaves_like 'valid import', 'lists', 'lists.csv' + + # Importing followed accounts with headers into various compatible types + it_behaves_like 'valid import', 'following', 'following_accounts.csv' + it_behaves_like 'valid import', 'blocking', 'following_accounts.csv' + it_behaves_like 'valid import', 'muting', 'following_accounts.csv' + + # Importing domain blocks with headers into incompatible types + it_behaves_like 'incompatible import type', 'following', 'domain_blocks.csv' + it_behaves_like 'incompatible import type', 'blocking', 'domain_blocks.csv' + it_behaves_like 'incompatible import type', 'muting', 'domain_blocks.csv' + it_behaves_like 'incompatible import type', 'bookmarks', 'domain_blocks.csv' + + # Importing followed accounts with headers into incompatible types + it_behaves_like 'incompatible import type', 'domain_blocking', 'following_accounts.csv' + it_behaves_like 'incompatible import type', 'bookmarks', 'following_accounts.csv' + end + + describe '#guessed_type' do + shared_examples 'with enough information' do |type, file, original_filename, expected_guess| + let(:import_file) { file } + let(:import_type) { type } + + before do + allow(data).to receive(:original_filename).and_return(original_filename) + end + + it 'guesses the expected type' do + expect(subject.guessed_type).to eq expected_guess + end + end + + context 'when the headers are enough to disambiguate' do + it_behaves_like 'with enough information', 'following', 'following_accounts.csv', 'import.csv', :following + it_behaves_like 'with enough information', 'blocking', 'following_accounts.csv', 'import.csv', :following + it_behaves_like 'with enough information', 'muting', 'following_accounts.csv', 'import.csv', :following + + it_behaves_like 'with enough information', 'following', 'muted_accounts.csv', 'imports.csv', :muting + it_behaves_like 'with enough information', 'blocking', 'muted_accounts.csv', 'imports.csv', :muting + it_behaves_like 'with enough information', 'muting', 'muted_accounts.csv', 'imports.csv', :muting + end + + context 'when the file name is enough to disambiguate' do + it_behaves_like 'with enough information', 'following', 'imports.txt', 'following_accounts.csv', :following + it_behaves_like 'with enough information', 'blocking', 'imports.txt', 'following_accounts.csv', :following + it_behaves_like 'with enough information', 'muting', 'imports.txt', 'following_accounts.csv', :following + + it_behaves_like 'with enough information', 'following', 'imports.txt', 'follows.csv', :following + it_behaves_like 'with enough information', 'blocking', 'imports.txt', 'follows.csv', :following + it_behaves_like 'with enough information', 'muting', 'imports.txt', 'follows.csv', :following + + it_behaves_like 'with enough information', 'following', 'imports.txt', 'blocked_accounts.csv', :blocking + it_behaves_like 'with enough information', 'blocking', 'imports.txt', 'blocked_accounts.csv', :blocking + it_behaves_like 'with enough information', 'muting', 'imports.txt', 'blocked_accounts.csv', :blocking + + it_behaves_like 'with enough information', 'following', 'imports.txt', 'blocks.csv', :blocking + it_behaves_like 'with enough information', 'blocking', 'imports.txt', 'blocks.csv', :blocking + it_behaves_like 'with enough information', 'muting', 'imports.txt', 'blocks.csv', :blocking + + it_behaves_like 'with enough information', 'following', 'imports.txt', 'muted_accounts.csv', :muting + it_behaves_like 'with enough information', 'blocking', 'imports.txt', 'muted_accounts.csv', :muting + it_behaves_like 'with enough information', 'muting', 'imports.txt', 'muted_accounts.csv', :muting + + it_behaves_like 'with enough information', 'following', 'imports.txt', 'mutes.csv', :muting + it_behaves_like 'with enough information', 'blocking', 'imports.txt', 'mutes.csv', :muting + it_behaves_like 'with enough information', 'muting', 'imports.txt', 'mutes.csv', :muting + end + end + + describe '#likely_mismatched?' do + shared_examples 'with matching types' do |type, file, original_filename = nil| + let(:import_file) { file } + let(:import_type) { type } + + before do + allow(data).to receive(:original_filename).and_return(original_filename) if original_filename.present? + end + + it 'returns false' do + expect(subject.likely_mismatched?).to be false + end + end + + shared_examples 'with mismatching types' do |type, file, original_filename = nil| + let(:import_file) { file } + let(:import_type) { type } + + before do + allow(data).to receive(:original_filename).and_return(original_filename) if original_filename.present? + end + + it 'returns true' do + expect(subject.likely_mismatched?).to be true + end + end + + it_behaves_like 'with matching types', 'following', 'following_accounts.csv' + it_behaves_like 'with matching types', 'following', 'following_accounts.csv', 'imports.txt' + it_behaves_like 'with matching types', 'following', 'imports.txt' + it_behaves_like 'with matching types', 'blocking', 'imports.txt', 'blocks.csv' + it_behaves_like 'with matching types', 'blocking', 'imports.txt' + it_behaves_like 'with matching types', 'muting', 'muted_accounts.csv' + it_behaves_like 'with matching types', 'muting', 'muted_accounts.csv', 'imports.txt' + it_behaves_like 'with matching types', 'muting', 'imports.txt' + it_behaves_like 'with matching types', 'domain_blocking', 'domain_blocks.csv' + it_behaves_like 'with matching types', 'domain_blocking', 'domain_blocks.csv', 'imports.txt' + it_behaves_like 'with matching types', 'bookmarks', 'bookmark-imports.txt' + it_behaves_like 'with matching types', 'bookmarks', 'bookmark-imports.txt', 'imports.txt' + + it_behaves_like 'with mismatching types', 'following', 'imports.txt', 'blocks.csv' + it_behaves_like 'with mismatching types', 'following', 'imports.txt', 'blocked_accounts.csv' + it_behaves_like 'with mismatching types', 'following', 'imports.txt', 'mutes.csv' + it_behaves_like 'with mismatching types', 'following', 'imports.txt', 'muted_accounts.csv' + it_behaves_like 'with mismatching types', 'following', 'muted_accounts.csv' + it_behaves_like 'with mismatching types', 'following', 'muted_accounts.csv', 'imports.txt' + it_behaves_like 'with mismatching types', 'blocking', 'following_accounts.csv' + it_behaves_like 'with mismatching types', 'blocking', 'following_accounts.csv', 'imports.txt' + it_behaves_like 'with mismatching types', 'blocking', 'muted_accounts.csv' + it_behaves_like 'with mismatching types', 'blocking', 'muted_accounts.csv', 'imports.txt' + it_behaves_like 'with mismatching types', 'blocking', 'imports.txt', 'follows.csv' + it_behaves_like 'with mismatching types', 'blocking', 'imports.txt', 'following_accounts.csv' + it_behaves_like 'with mismatching types', 'blocking', 'imports.txt', 'mutes.csv' + it_behaves_like 'with mismatching types', 'blocking', 'imports.txt', 'muted_accounts.csv' + it_behaves_like 'with mismatching types', 'muting', 'following_accounts.csv' + it_behaves_like 'with mismatching types', 'muting', 'following_accounts.csv', 'imports.txt' + it_behaves_like 'with mismatching types', 'muting', 'imports.txt', 'follows.csv' + it_behaves_like 'with mismatching types', 'muting', 'imports.txt', 'following_accounts.csv' + it_behaves_like 'with mismatching types', 'muting', 'imports.txt', 'blocks.csv' + it_behaves_like 'with mismatching types', 'muting', 'imports.txt', 'blocked_accounts.csv' + end + + describe 'save' do + shared_examples 'on successful import' do |type, mode, file, expected_rows| + let(:import_type) { type } + let(:import_file) { file } + let(:import_mode) { mode } + + before do + subject.save + end + + it 'creates the expected rows' do + expect(account.bulk_imports.first.rows.pluck(:data)).to match_array(expected_rows) + end + + context 'with a BulkImport' do + let(:bulk_import) { account.bulk_imports.first } + + it 'creates a non-nil bulk import' do + expect(bulk_import).to_not be_nil + end + + it 'matches the subjects type' do + expect(bulk_import.type.to_sym).to eq subject.type.to_sym + end + + it 'matches the subjects original filename' do + expect(bulk_import.original_filename).to eq subject.data.original_filename + end + + it 'matches the subjects likely_mismatched? value' do + expect(bulk_import.likely_mismatched?).to eq subject.likely_mismatched? + end + + it 'matches the subject overwrite value' do + expect(bulk_import.overwrite?).to eq !!subject.overwrite # rubocop:disable Style/DoubleNegation + end + + it 'has zero processed items' do + expect(bulk_import.processed_items).to eq 0 + end + + it 'has zero imported items' do + expect(bulk_import.imported_items).to eq 0 + end + + it 'has a correct total_items value' do + expect(bulk_import.total_items).to eq bulk_import.rows.count + end + + it 'defaults to unconfirmed true' do + expect(bulk_import.unconfirmed?).to be true + end + end + end + + it_behaves_like 'on successful import', 'following', 'merge', 'imports.txt', (%w(user@example.com user@test.com).map { |acct| { 'acct' => acct } }) + it_behaves_like 'on successful import', 'following', 'overwrite', 'imports.txt', (%w(user@example.com user@test.com).map { |acct| { 'acct' => acct } }) + it_behaves_like 'on successful import', 'blocking', 'merge', 'imports.txt', (%w(user@example.com user@test.com).map { |acct| { 'acct' => acct } }) + it_behaves_like 'on successful import', 'blocking', 'overwrite', 'imports.txt', (%w(user@example.com user@test.com).map { |acct| { 'acct' => acct } }) + it_behaves_like 'on successful import', 'muting', 'merge', 'imports.txt', (%w(user@example.com user@test.com).map { |acct| { 'acct' => acct } }) + it_behaves_like 'on successful import', 'domain_blocking', 'merge', 'domain_blocks.csv', (%w(bad.domain worse.domain reject.media).map { |domain| { 'domain' => domain } }) + it_behaves_like 'on successful import', 'bookmarks', 'merge', 'bookmark-imports.txt', (%w(https://example.com/statuses/1312 https://local.com/users/foo/statuses/42 https://unknown-remote.com/users/bar/statuses/1 https://example.com/statuses/direct).map { |uri| { 'uri' => uri } }) + + it_behaves_like 'on successful import', 'following', 'merge', 'following_accounts.csv', [ + { 'acct' => 'user@example.com', 'show_reblogs' => true, 'notify' => false, 'languages' => nil }, + { 'acct' => 'user@test.com', 'show_reblogs' => true, 'notify' => true, 'languages' => ['en', 'fr'] }, + ] + + it_behaves_like 'on successful import', 'muting', 'merge', 'muted_accounts.csv', [ + { 'acct' => 'user@example.com', 'hide_notifications' => true }, + { 'acct' => 'user@test.com', 'hide_notifications' => false }, + ] + + it_behaves_like 'on successful import', 'lists', 'merge', 'lists.csv', [ + { 'acct' => 'gargron@example.com', 'list_name' => 'Mastodon project' }, + { 'acct' => 'mastodon@example.com', 'list_name' => 'Mastodon project' }, + { 'acct' => 'foo@example.com', 'list_name' => 'test' }, + ] + + # Based on the bug report 20571 where UTF-8 encoded domains were rejecting import of their users + # + # https://github.com/mastodon/mastodon/issues/20571 + it_behaves_like 'on successful import', 'following', 'merge', 'utf8-followers.txt', [{ 'acct' => 'nare@թութ.հայ' }] + end +end diff --git a/spec/models/form/status_filter_batch_action_spec.rb b/spec/models/form/status_filter_batch_action_spec.rb new file mode 100644 index 0000000000..f06a11cc8b --- /dev/null +++ b/spec/models/form/status_filter_batch_action_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Form::StatusFilterBatchAction do + describe '#save!' do + it 'does nothing if status_filter_ids is empty' do + batch_action = described_class.new(status_filter_ids: []) + + expect(batch_action.save!).to be_nil + end + end +end diff --git a/spec/models/home_feed_spec.rb b/spec/models/home_feed_spec.rb index 80f6edbff6..bd649d8269 100644 --- a/spec/models/home_feed_spec.rb +++ b/spec/models/home_feed_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe HomeFeed, type: :model do - let(:account) { Fabricate(:account) } - +RSpec.describe HomeFeed do subject { described_class.new(account) } + let(:account) { Fabricate(:account) } + describe '#get' do before do Fabricate(:status, account: account, id: 1) diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb index 689c9b797f..2fca1e1c14 100644 --- a/spec/models/identity_spec.rb +++ b/spec/models/identity_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Identity, type: :model do +RSpec.describe Identity do describe '.find_for_oauth' do let(:auth) { Fabricate(:identity, user: Fabricate(:user)) } @@ -10,7 +12,7 @@ RSpec.describe Identity, type: :model do end it 'returns an instance of Identity' do - expect(described_class.find_for_oauth(auth)).to be_instance_of Identity + expect(described_class.find_for_oauth(auth)).to be_instance_of described_class end end end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index a5eec17226..3605f0b9bf 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -1,33 +1,25 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Import, type: :model do - let (:account) { Fabricate(:account) } - let (:type) { 'following' } - let (:data) { attachment_fixture('imports.txt') } +RSpec.describe Import do + let(:account) { Fabricate(:account) } + let(:type) { 'following' } + let(:data) { attachment_fixture('imports.txt') } describe 'validations' do it 'has a valid parameters' do - import = Import.create(account: account, type: type, data: data) + import = described_class.create(account: account, type: type, data: data) expect(import).to be_valid end it 'is invalid without an type' do - import = Import.create(account: account, data: data) + import = described_class.create(account: account, data: data) expect(import).to model_have_error_on_field(:type) end it 'is invalid without a data' do - import = Import.create(account: account, type: type) - expect(import).to model_have_error_on_field(:data) - end - - it 'is invalid with too many rows in data' do - import = Import.create(account: account, type: type, data: StringIO.new("foo@bar.com\n" * (ImportService::ROWS_PROCESSING_LIMIT + 10))) - expect(import).to model_have_error_on_field(:data) - end - - it 'is invalid when there are more rows when following limit' do - import = Import.create(account: account, type: type, data: StringIO.new("foo@bar.com\n" * (FollowLimitValidator.limit_for_account(account) + 10))) + import = described_class.create(account: account, type: type) expect(import).to model_have_error_on_field(:data) end end diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index b0596c5612..4ad589f2c7 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Invite, type: :model do +RSpec.describe Invite do describe '#valid_for_use?' do it 'returns true when there are no limitations' do invite = Fabricate(:invite, max_uses: nil, expires_at: nil) diff --git a/spec/models/ip_block_spec.rb b/spec/models/ip_block_spec.rb index 6603c6417a..ed58826672 100644 --- a/spec/models/ip_block_spec.rb +++ b/spec/models/ip_block_spec.rb @@ -1,5 +1,15 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe IpBlock, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe IpBlock do + describe 'to_log_human_identifier' do + let(:ip_block) { described_class.new(ip: '192.168.0.1') } + + it 'combines the IP and prefix into a string' do + result = ip_block.to_log_human_identifier + + expect(result).to eq('192.168.0.1/32') + end + end end diff --git a/spec/models/list_account_spec.rb b/spec/models/list_account_spec.rb deleted file mode 100644 index a0cf02efe2..0000000000 --- a/spec/models/list_account_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe ListAccount, type: :model do -end diff --git a/spec/models/list_spec.rb b/spec/models/list_spec.rb deleted file mode 100644 index b780bb1de0..0000000000 --- a/spec/models/list_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe List, type: :model do -end diff --git a/spec/models/login_activity_spec.rb b/spec/models/login_activity_spec.rb deleted file mode 100644 index ba2d207c91..0000000000 --- a/spec/models/login_activity_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe LoginActivity, type: :model do - -end diff --git a/spec/models/marker_spec.rb b/spec/models/marker_spec.rb index d716aa75c2..51dd584388 100644 --- a/spec/models/marker_spec.rb +++ b/spec/models/marker_spec.rb @@ -1,5 +1,16 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Marker, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe Marker do + describe 'validations' do + describe 'timeline' do + it 'must be included in valid list' do + record = described_class.new(timeline: 'not real timeline') + + expect(record).to_not be_valid + expect(record).to model_have_error_on_field(:timeline) + end + end + end end diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb index c3283ccb04..6a82c8135a 100644 --- a/spec/models/media_attachment_spec.rb +++ b/spec/models/media_attachment_spec.rb @@ -1,72 +1,74 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe MediaAttachment, type: :model do +RSpec.describe MediaAttachment, paperclip_processing: true do describe 'local?' do - let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url) } - subject { media_attachment.local? } - context 'remote_url is blank' do + let(:media_attachment) { described_class.new(remote_url: remote_url) } + + context 'when remote_url is blank' do let(:remote_url) { '' } it 'returns true' do - is_expected.to be true + expect(subject).to be true end end - context 'remote_url is present' do + context 'when remote_url is present' do let(:remote_url) { 'remote_url' } it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end describe 'needs_redownload?' do - let(:media_attachment) { Fabricate(:media_attachment, remote_url: remote_url, file: file) } - subject { media_attachment.needs_redownload? } - context 'file is blank' do + let(:media_attachment) { described_class.new(remote_url: remote_url, file: file) } + + context 'when file is blank' do let(:file) { nil } - context 'remote_url is present' do + context 'when remote_url is present' do let(:remote_url) { 'remote_url' } it 'returns true' do - is_expected.to be true + expect(subject).to be true end end end - context 'file is present' do + context 'when file is present' do let(:file) { attachment_fixture('avatar.gif') } - context 'remote_url is blank' do + context 'when remote_url is blank' do let(:remote_url) { '' } it 'returns false' do - is_expected.to be false + expect(subject).to be false end end - context 'remote_url is present' do + context 'when remote_url is present' do let(:remote_url) { 'remote_url' } it 'returns true' do - is_expected.to be false + expect(subject).to be false end end end end describe '#to_param' do - let(:media_attachment) { Fabricate(:media_attachment, shortcode: shortcode) } - let(:shortcode) { nil } + let(:media_attachment) { Fabricate.build(:media_attachment, shortcode: shortcode, id: id) } context 'when media attachment has a shortcode' do let(:shortcode) { 'foo' } + let(:id) { 123 } it 'returns shortcode' do expect(media_attachment.to_param).to eq shortcode @@ -75,31 +77,104 @@ RSpec.describe MediaAttachment, type: :model do context 'when media attachment does not have a shortcode' do let(:shortcode) { nil } + let(:id) { 123 } it 'returns string representation of id' do - expect(media_attachment.to_param).to eq media_attachment.id.to_s + expect(media_attachment.to_param).to eq id.to_s end end end - describe 'animated gif conversion' do - let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('avatar.gif')) } - - it 'sets type to gifv' do - expect(media.type).to eq 'gifv' + shared_examples 'static 600x400 image' do |content_type, extension| + after do + media.destroy end - it 'converts original file to mp4' do - expect(media.file_content_type).to eq 'video/mp4' + it 'saves media attachment with correct file metadata' do + expect(media.persisted?).to be true + expect(media.file).to_not be_nil + + # completes processing + expect(media.processing_complete?).to be true + + # sets type + expect(media.type).to eq 'image' + + # sets content type + expect(media.file_content_type).to eq content_type + + # sets file extension + expect(media.file_file_name).to end_with extension + + # Rack::Mime (used by PublicFileServerMiddleware) recognizes file extension + expect(Rack::Mime.mime_type(extension, nil)).to eq content_type end - it 'sets meta' do - expect(media.file.meta["original"]["width"]).to eq 128 - expect(media.file.meta["original"]["height"]).to eq 128 + it 'saves media attachment with correct size metadata' do + # strips original file name + expect(media.file_file_name).to_not start_with '600x400' + + # sets meta for original + expect(media.file.meta['original']['width']).to eq 600 + expect(media.file.meta['original']['height']).to eq 400 + expect(media.file.meta['original']['aspect']).to eq 1.5 + + # sets meta for thumbnail + expect(media.file.meta['small']['width']).to eq 588 + expect(media.file.meta['small']['height']).to eq 392 + expect(media.file.meta['small']['aspect']).to eq 1.5 end end - describe 'non-animated gif non-conversion' do + describe 'jpeg' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.jpeg')) } + + it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg' + end + + describe 'png' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.png')) } + + it_behaves_like 'static 600x400 image', 'image/png', '.png' + end + + describe 'webp' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.webp')) } + + it_behaves_like 'static 600x400 image', 'image/webp', '.webp' + end + + describe 'avif' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.avif')) } + + it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg' + end + + describe 'heic' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('600x400.heic')) } + + it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg' + end + + describe 'base64-encoded image' do + let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('600x400.jpeg').read)}" } + let(:media) { Fabricate(:media_attachment, file: base64_attachment) } + + it_behaves_like 'static 600x400 image', 'image/jpeg', '.jpeg' + end + + describe 'animated gif' do + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('avatar.gif')) } + + it 'sets correct file metadata' do + expect(media.type).to eq 'gifv' + expect(media.file_content_type).to eq 'video/mp4' + expect(media.file.meta['original']['width']).to eq 128 + expect(media.file.meta['original']['height']).to eq 128 + end + end + + describe 'static gif' do fixtures = [ { filename: 'attachment.gif', width: 600, height: 400, aspect: 1.5 }, { filename: 'mini-static.gif', width: 32, height: 32, aspect: 1.0 }, @@ -107,51 +182,33 @@ RSpec.describe MediaAttachment, type: :model do fixtures.each do |fixture| context fixture[:filename] do - let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture(fixture[:filename])) } + let(:media) { Fabricate(:media_attachment, file: attachment_fixture(fixture[:filename])) } - it 'sets type to image' do + it 'sets correct file metadata' do expect(media.type).to eq 'image' - end - - it 'leaves original file as-is' do expect(media.file_content_type).to eq 'image/gif' - end - - it 'sets meta' do - expect(media.file.meta["original"]["width"]).to eq fixture[:width] - expect(media.file.meta["original"]["height"]).to eq fixture[:height] - expect(media.file.meta["original"]["aspect"]).to eq fixture[:aspect] + expect(media.file.meta['original']['width']).to eq fixture[:width] + expect(media.file.meta['original']['height']).to eq fixture[:height] + expect(media.file.meta['original']['aspect']).to eq fixture[:aspect] end end end end describe 'ogg with cover art' do - let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('boop.ogg')) } + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('boop.ogg')) } - it 'detects it as an audio file' do + it 'sets correct file metadata' do expect(media.type).to eq 'audio' - end - - it 'sets meta for the duration' do expect(media.file.meta['original']['duration']).to be_within(0.05).of(0.235102) - end - - it 'extracts thumbnail' do - expect(media.thumbnail.present?).to eq true - end - - it 'extracts colors from thumbnail' do + expect(media.thumbnail.present?).to be true expect(media.file.meta['colors']['background']).to eq '#3088d4' - end - - it 'gives the file a random name' do expect(media.file_file_name).to_not eq 'boop.ogg' end end describe 'mp3 with large cover art' do - let(:media) { described_class.create(account: Fabricate(:account), file: attachment_fixture('boop.mp3')) } + let(:media) { Fabricate(:media_attachment, file: attachment_fixture('boop.mp3')) } it 'detects it as an audio file' do expect(media.type).to eq 'audio' @@ -170,66 +227,37 @@ RSpec.describe MediaAttachment, type: :model do end end - describe 'jpeg' do - let(:media) { MediaAttachment.create(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) } - - it 'sets meta for different style' do - expect(media.file.meta["original"]["width"]).to eq 600 - expect(media.file.meta["original"]["height"]).to eq 400 - expect(media.file.meta["original"]["aspect"]).to eq 1.5 - expect(media.file.meta["small"]["width"]).to eq 588 - expect(media.file.meta["small"]["height"]).to eq 392 - expect(media.file.meta["small"]["aspect"]).to eq 1.5 - end - - it 'gives the file a random name' do - expect(media.file_file_name).to_not eq 'attachment.jpg' - end - end - - describe 'base64-encoded jpeg' do - let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('attachment.jpg').read)}" } - let(:media) { MediaAttachment.create(account: Fabricate(:account), file: base64_attachment) } - - it 'saves media attachment' do - expect(media.persisted?).to be true - expect(media.file).to_not be_nil - end - - it 'gives the file a file name' do - expect(media.file_file_name).to_not be_blank - end - end - it 'is invalid without file' do - media = MediaAttachment.new(account: Fabricate(:account)) + media = described_class.new + expect(media.valid?).to be false + expect(media).to model_have_error_on_field(:file) end describe 'size limit validation' do it 'rejects video files that are too large' do stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte - expect { MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm')) }.to raise_error(ActiveRecord::RecordInvalid) + expect { Fabricate(:media_attachment, file: attachment_fixture('attachment.webm')) }.to raise_error(ActiveRecord::RecordInvalid) end it 'accepts video files that are small enough' do stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes - media = MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.webm')) + media = Fabricate(:media_attachment, file: attachment_fixture('attachment.webm')) expect(media.valid?).to be true end it 'rejects image files that are too large' do stub_const 'MediaAttachment::IMAGE_LIMIT', 1.kilobyte stub_const 'MediaAttachment::VIDEO_LIMIT', 100.megabytes - expect { MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) }.to raise_error(ActiveRecord::RecordInvalid) + expect { Fabricate(:media_attachment, file: attachment_fixture('attachment.jpg')) }.to raise_error(ActiveRecord::RecordInvalid) end it 'accepts image files that are small enough' do stub_const 'MediaAttachment::IMAGE_LIMIT', 100.megabytes stub_const 'MediaAttachment::VIDEO_LIMIT', 1.kilobyte - media = MediaAttachment.create!(account: Fabricate(:account), file: attachment_fixture('attachment.jpg')) + media = Fabricate(:media_attachment, file: attachment_fixture('attachment.jpg')) expect(media.valid?).to be true end end diff --git a/spec/models/mention_spec.rb b/spec/models/mention_spec.rb index dbcf6a32c1..b241049a54 100644 --- a/spec/models/mention_spec.rb +++ b/spec/models/mention_spec.rb @@ -1,12 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Mention, type: :model do +RSpec.describe Mention do describe 'validations' do - it 'has a valid fabricator' do - mention = Fabricate.build(:mention) - expect(mention).to be_valid - end - it 'is invalid without an account' do mention = Fabricate.build(:mention, account: nil) mention.valid? diff --git a/spec/models/mute_spec.rb b/spec/models/mute_spec.rb deleted file mode 100644 index 38a87bdf4a..0000000000 --- a/spec/models/mute_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe Mute, type: :model do -end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index 1e9e45d8d6..d6e2282022 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Notification, type: :model do +RSpec.describe Notification do describe '#target_status' do let(:notification) { Fabricate(:notification, activity: activity) } let(:status) { Fabricate(:status) } @@ -8,7 +10,7 @@ RSpec.describe Notification, type: :model do let(:favourite) { Fabricate(:favourite, status: status) } let(:mention) { Fabricate(:mention, status: status) } - context 'activity is reblog' do + context 'when Activity is reblog' do let(:activity) { reblog } it 'returns status' do @@ -16,7 +18,7 @@ RSpec.describe Notification, type: :model do end end - context 'activity is favourite' do + context 'when Activity is favourite' do let(:type) { :favourite } let(:activity) { favourite } @@ -25,7 +27,7 @@ RSpec.describe Notification, type: :model do end end - context 'activity is mention' do + context 'when Activity is mention' do let(:activity) { mention } it 'returns status' do @@ -36,22 +38,22 @@ RSpec.describe Notification, type: :model do describe '#type' do it 'returns :reblog for a Status' do - notification = Notification.new(activity: Status.new) + notification = described_class.new(activity: Status.new) expect(notification.type).to eq :reblog end it 'returns :mention for a Mention' do - notification = Notification.new(activity: Mention.new) + notification = described_class.new(activity: Mention.new) expect(notification.type).to eq :mention end it 'returns :favourite for a Favourite' do - notification = Notification.new(activity: Favourite.new) + notification = described_class.new(activity: Favourite.new) expect(notification.type).to eq :favourite end it 'returns :follow for a Follow' do - notification = Notification.new(activity: Follow.new) + notification = described_class.new(activity: Follow.new) expect(notification.type).to eq :follow end end @@ -64,15 +66,15 @@ RSpec.describe Notification, type: :model do end end - context 'notifications are empty' do + context 'when notifications are empty' do let(:notifications) { [] } it 'returns []' do - is_expected.to eq [] + expect(subject).to eq [] end end - context 'notifications are present' do + context 'when notifications are present' do before do notifications.each(&:reload) end @@ -97,73 +99,87 @@ RSpec.describe Notification, type: :model do ] end - it 'preloads target status' do - # mention - expect(subject[0].type).to eq :mention - expect(subject[0].association(:mention)).to be_loaded - expect(subject[0].mention.association(:status)).to be_loaded + context 'with a preloaded target status' do + it 'preloads mention' do + expect(subject[0].type).to eq :mention + expect(subject[0].association(:mention)).to be_loaded + expect(subject[0].mention.association(:status)).to be_loaded + end - # status - expect(subject[1].type).to eq :status - expect(subject[1].association(:status)).to be_loaded + it 'preloads status' do + expect(subject[1].type).to eq :status + expect(subject[1].association(:status)).to be_loaded + end - # reblog - expect(subject[2].type).to eq :reblog - expect(subject[2].association(:status)).to be_loaded - expect(subject[2].status.association(:reblog)).to be_loaded + it 'preloads reblog' do + expect(subject[2].type).to eq :reblog + expect(subject[2].association(:status)).to be_loaded + expect(subject[2].status.association(:reblog)).to be_loaded + end - # follow: nothing - expect(subject[3].type).to eq :follow - expect(subject[3].target_status).to be_nil + it 'preloads follow as nil' do + expect(subject[3].type).to eq :follow + expect(subject[3].target_status).to be_nil + end - # follow_request: nothing - expect(subject[4].type).to eq :follow_request - expect(subject[4].target_status).to be_nil + it 'preloads follow_request as nill' do + expect(subject[4].type).to eq :follow_request + expect(subject[4].target_status).to be_nil + end - # favourite - expect(subject[5].type).to eq :favourite - expect(subject[5].association(:favourite)).to be_loaded - expect(subject[5].favourite.association(:status)).to be_loaded + it 'preloads favourite' do + expect(subject[5].type).to eq :favourite + expect(subject[5].association(:favourite)).to be_loaded + expect(subject[5].favourite.association(:status)).to be_loaded + end - # poll - expect(subject[6].type).to eq :poll - expect(subject[6].association(:poll)).to be_loaded - expect(subject[6].poll.association(:status)).to be_loaded + it 'preloads poll' do + expect(subject[6].type).to eq :poll + expect(subject[6].association(:poll)).to be_loaded + expect(subject[6].poll.association(:status)).to be_loaded + end end - it 'replaces to cached status' do - # mention - expect(subject[0].type).to eq :mention - expect(subject[0].target_status.association(:account)).to be_loaded - expect(subject[0].target_status).to eq mention.status + context 'with a cached status' do + it 'replaces mention' do + expect(subject[0].type).to eq :mention + expect(subject[0].target_status.association(:account)).to be_loaded + expect(subject[0].target_status).to eq mention.status + end - # status - expect(subject[1].type).to eq :status - expect(subject[1].target_status.association(:account)).to be_loaded - expect(subject[1].target_status).to eq status + it 'replaces status' do + expect(subject[1].type).to eq :status + expect(subject[1].target_status.association(:account)).to be_loaded + expect(subject[1].target_status).to eq status + end - # reblog - expect(subject[2].type).to eq :reblog - expect(subject[2].target_status.association(:account)).to be_loaded - expect(subject[2].target_status).to eq reblog.reblog + it 'replaces reblog' do + expect(subject[2].type).to eq :reblog + expect(subject[2].target_status.association(:account)).to be_loaded + expect(subject[2].target_status).to eq reblog.reblog + end - # follow: nothing - expect(subject[3].type).to eq :follow - expect(subject[3].target_status).to be_nil + it 'replaces follow' do + expect(subject[3].type).to eq :follow + expect(subject[3].target_status).to be_nil + end - # follow_request: nothing - expect(subject[4].type).to eq :follow_request - expect(subject[4].target_status).to be_nil + it 'replaces follow_request' do + expect(subject[4].type).to eq :follow_request + expect(subject[4].target_status).to be_nil + end - # favourite - expect(subject[5].type).to eq :favourite - expect(subject[5].target_status.association(:account)).to be_loaded - expect(subject[5].target_status).to eq favourite.status + it 'replaces favourite' do + expect(subject[5].type).to eq :favourite + expect(subject[5].target_status.association(:account)).to be_loaded + expect(subject[5].target_status).to eq favourite.status + end - # poll - expect(subject[6].type).to eq :poll - expect(subject[6].target_status.association(:account)).to be_loaded - expect(subject[6].target_status).to eq poll.status + it 'replaces poll' do + expect(subject[6].type).to eq :poll + expect(subject[6].target_status.association(:account)).to be_loaded + expect(subject[6].target_status).to eq poll.status + end end end end diff --git a/spec/models/one_time_key_spec.rb b/spec/models/one_time_key_spec.rb index 34598334cc..6ff7ffc5c1 100644 --- a/spec/models/one_time_key_spec.rb +++ b/spec/models/one_time_key_spec.rb @@ -1,5 +1,23 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe OneTimeKey, type: :model do +describe OneTimeKey do + describe 'validations' do + context 'with an invalid signature' do + let(:one_time_key) { Fabricate.build(:one_time_key, signature: 'wrong!') } + it 'is invalid' do + expect(one_time_key).to_not be_valid + end + end + + context 'with an invalid key' do + let(:one_time_key) { Fabricate.build(:one_time_key, key: 'wrong!') } + + it 'is invalid' do + expect(one_time_key).to_not be_valid + end + end + end end diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb index 666f8ca683..8ae04ca41f 100644 --- a/spec/models/poll_spec.rb +++ b/spec/models/poll_spec.rb @@ -1,5 +1,32 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Poll, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe Poll do + describe 'scopes' do + let(:status) { Fabricate(:status) } + let(:attached_poll) { Fabricate(:poll, status: status) } + let(:not_attached_poll) do + Fabricate(:poll).tap do |poll| + poll.status = nil + poll.save(validate: false) + end + end + + describe 'attached' do + it 'finds the correct records' do + results = described_class.attached + + expect(results).to eq([attached_poll]) + end + end + + describe 'unattached' do + it 'finds the correct records' do + results = described_class.unattached + + expect(results).to eq([not_attached_poll]) + end + end + end end diff --git a/spec/models/poll_vote_spec.rb b/spec/models/poll_vote_spec.rb index 563f346993..b017ea5279 100644 --- a/spec/models/poll_vote_spec.rb +++ b/spec/models/poll_vote_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe PollVote, type: :model do +RSpec.describe PollVote do describe '#object_type' do let(:poll_vote) { Fabricate.build(:poll_vote) } @@ -10,4 +10,53 @@ RSpec.describe PollVote, type: :model do expect(poll_vote.object_type).to eq :vote end end + + describe 'validations' do + context 'with a vote on an expired poll' do + it 'marks the vote invalid' do + poll = Fabricate.build(:poll, expires_at: 30.days.ago) + + vote = Fabricate.build(:poll_vote, poll: poll) + expect(vote).to_not be_valid + end + end + + context 'with invalid choices' do + it 'marks vote invalid with negative choice' do + poll = Fabricate.build(:poll) + + vote = Fabricate.build(:poll_vote, poll: poll, choice: -100) + expect(vote).to_not be_valid + end + + it 'marks vote invalid with choice in excess of options' do + poll = Fabricate.build(:poll, options: %w(a b c)) + + vote = Fabricate.build(:poll_vote, poll: poll, choice: 10) + expect(vote).to_not be_valid + end + end + + context 'with a poll where multiple is true' do + it 'does not allow a second vote on same choice from same account' do + poll = Fabricate(:poll, multiple: true, options: %w(a b c)) + first_vote = Fabricate(:poll_vote, poll: poll, choice: 1) + expect(first_vote).to be_valid + + second_vote = Fabricate.build(:poll_vote, account: first_vote.account, poll: poll, choice: 1) + expect(second_vote).to_not be_valid + end + end + + context 'with a poll where multiple is false' do + it 'does not allow a second vote from same account' do + poll = Fabricate(:poll, multiple: false, options: %w(a b c)) + first_vote = Fabricate(:poll_vote, poll: poll) + expect(first_vote).to be_valid + + second_vote = Fabricate.build(:poll_vote, account: first_vote.account, poll: poll) + expect(second_vote).to_not be_valid + end + end + end end diff --git a/spec/models/preview_card_provider_spec.rb b/spec/models/preview_card_provider_spec.rb new file mode 100644 index 0000000000..7425b93946 --- /dev/null +++ b/spec/models/preview_card_provider_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PreviewCardProvider do + describe 'scopes' do + let(:trendable_and_reviewed) { Fabricate(:preview_card_provider, trendable: true, reviewed_at: 5.days.ago) } + let(:not_trendable_and_not_reviewed) { Fabricate(:preview_card_provider, trendable: false, reviewed_at: nil) } + + describe 'trendable' do + it 'returns the relevant records' do + results = described_class.trendable + + expect(results).to eq([trendable_and_reviewed]) + end + end + + describe 'not_trendable' do + it 'returns the relevant records' do + results = described_class.not_trendable + + expect(results).to eq([not_trendable_and_not_reviewed]) + end + end + + describe 'reviewed' do + it 'returns the relevant records' do + results = described_class.reviewed + + expect(results).to eq([trendable_and_reviewed]) + end + end + + describe 'pending_review' do + it 'returns the relevant records' do + results = described_class.pending_review + + expect(results).to eq([not_trendable_and_not_reviewed]) + end + end + end +end diff --git a/spec/models/preview_card_spec.rb b/spec/models/preview_card_spec.rb deleted file mode 100644 index 45233d1d4f..0000000000 --- a/spec/models/preview_card_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe PreviewCard, type: :model do -end diff --git a/spec/models/preview_card_trend_spec.rb b/spec/models/preview_card_trend_spec.rb deleted file mode 100644 index c7ab6ed146..0000000000 --- a/spec/models/preview_card_trend_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe PreviewCardTrend, type: :model do -end diff --git a/spec/models/privacy_policy_spec.rb b/spec/models/privacy_policy_spec.rb new file mode 100644 index 0000000000..0d74713755 --- /dev/null +++ b/spec/models/privacy_policy_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PrivacyPolicy do + describe '.current' do + context 'with the default values' do + it 'has the privacy text' do + policy = described_class.current + + expect(policy.text).to eq(PrivacyPolicy::DEFAULT_PRIVACY_POLICY) + end + end + + context 'with a custom setting value' do + before do + terms_setting = instance_double(Setting, value: 'Terms text', updated_at: 10.days.ago) + allow(Setting).to receive(:find_by).with(var: 'site_terms').and_return(terms_setting) + end + + it 'has the privacy text' do + policy = described_class.current + + expect(policy.text).to eq('Terms text') + end + end + end +end diff --git a/spec/models/public_feed_spec.rb b/spec/models/public_feed_spec.rb index 0ffc343f17..fbbdf62584 100644 --- a/spec/models/public_feed_spec.rb +++ b/spec/models/public_feed_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe PublicFeed, type: :model do +RSpec.describe PublicFeed do let(:account) { Fabricate(:account) } describe '#get' do @@ -11,7 +13,7 @@ RSpec.describe PublicFeed, type: :model do private_status = Fabricate(:status, visibility: :private) expect(subject).to include(public_status.id) - expect(subject).not_to include(private_status.id) + expect(subject).to_not include(private_status.id) end it 'does not include replies' do @@ -19,7 +21,7 @@ RSpec.describe PublicFeed, type: :model do reply = Fabricate(:status, in_reply_to_id: status.id) expect(subject).to include(status.id) - expect(subject).not_to include(reply.id) + expect(subject).to_not include(reply.id) end it 'does not include boosts' do @@ -27,7 +29,7 @@ RSpec.describe PublicFeed, type: :model do boost = Fabricate(:status, reblog_of_id: status.id) expect(subject).to include(status.id) - expect(subject).not_to include(boost.id) + expect(subject).to_not include(boost.id) end it 'filters out silenced accounts' do @@ -36,18 +38,19 @@ RSpec.describe PublicFeed, type: :model do silenced_status = Fabricate(:status, account: silenced_account) expect(subject).to include(status.id) - expect(subject).not_to include(silenced_status.id) + expect(subject).to_not include(silenced_status.id) end context 'without local_only option' do + subject { described_class.new(viewer).get(20).map(&:id) } + let(:viewer) { nil } let!(:local_account) { Fabricate(:account, domain: nil) } let!(:remote_account) { Fabricate(:account, domain: 'test.com') } let!(:local_status) { Fabricate(:status, account: local_account) } let!(:remote_status) { Fabricate(:status, account: remote_account) } - - subject { described_class.new(viewer).get(20).map(&:id) } + let!(:local_only_status) { Fabricate(:status, account: local_account, local_only: true) } context 'without a viewer' do let(:viewer) { nil } @@ -59,6 +62,10 @@ RSpec.describe PublicFeed, type: :model do it 'includes local statuses' do expect(subject).to include(local_status.id) end + + it 'does not include local-only statuses' do + expect(subject).to_not include(local_only_status.id) + end end context 'with a viewer' do @@ -71,23 +78,76 @@ RSpec.describe PublicFeed, type: :model do it 'includes local statuses' do expect(subject).to include(local_status.id) end + + it 'does not include local-only statuses' do + expect(subject).to_not include(local_only_status.id) + end + end + end + + context 'without local_only option but allow_local_only' do + subject { described_class.new(viewer, allow_local_only: true).get(20).map(&:id) } + + let(:viewer) { nil } + + let!(:local_account) { Fabricate(:account, domain: nil) } + let!(:remote_account) { Fabricate(:account, domain: 'test.com') } + let!(:local_status) { Fabricate(:status, account: local_account) } + let!(:remote_status) { Fabricate(:status, account: remote_account) } + let!(:local_only_status) { Fabricate(:status, account: local_account, local_only: true) } + + context 'without a viewer' do + let(:viewer) { nil } + + it 'includes remote instances statuses' do + expect(subject).to include(remote_status.id) + end + + it 'includes local statuses' do + expect(subject).to include(local_status.id) + end + + it 'does not include local-only statuses' do + expect(subject).to_not include(local_only_status.id) + end + end + + context 'with a viewer' do + let(:viewer) { Fabricate(:account, username: 'viewer') } + + it 'includes remote instances statuses' do + expect(subject).to include(remote_status.id) + end + + it 'includes local statuses' do + expect(subject).to include(local_status.id) + end + + it 'includes local-only statuses' do + expect(subject).to include(local_only_status.id) + end end end context 'with a local_only option set' do + subject { described_class.new(viewer, local: true).get(20).map(&:id) } + let!(:local_account) { Fabricate(:account, domain: nil) } let!(:remote_account) { Fabricate(:account, domain: 'test.com') } let!(:local_status) { Fabricate(:status, account: local_account) } let!(:remote_status) { Fabricate(:status, account: remote_account) } - - subject { described_class.new(viewer, local: true).get(20).map(&:id) } + let!(:local_only_status) { Fabricate(:status, account: local_account, local_only: true) } context 'without a viewer' do let(:viewer) { nil } it 'does not include remote instances statuses' do expect(subject).to include(local_status.id) - expect(subject).not_to include(remote_status.id) + expect(subject).to_not include(remote_status.id) + end + + it 'does not include local-only statuses' do + expect(subject).to_not include(local_only_status.id) end end @@ -96,30 +156,34 @@ RSpec.describe PublicFeed, type: :model do it 'does not include remote instances statuses' do expect(subject).to include(local_status.id) - expect(subject).not_to include(remote_status.id) + expect(subject).to_not include(remote_status.id) end it 'is not affected by personal domain blocks' do viewer.block_domain!('test.com') expect(subject).to include(local_status.id) - expect(subject).not_to include(remote_status.id) + expect(subject).to_not include(remote_status.id) + end + + it 'includes local-only statuses' do + expect(subject).to include(local_only_status.id) end end end context 'with a remote_only option set' do + subject { described_class.new(viewer, remote: true).get(20).map(&:id) } + let!(:local_account) { Fabricate(:account, domain: nil) } let!(:remote_account) { Fabricate(:account, domain: 'test.com') } let!(:local_status) { Fabricate(:status, account: local_account) } let!(:remote_status) { Fabricate(:status, account: remote_account) } - subject { described_class.new(viewer, remote: true).get(20).map(&:id) } - context 'without a viewer' do let(:viewer) { nil } it 'does not include local instances statuses' do - expect(subject).not_to include(local_status.id) + expect(subject).to_not include(local_status.id) expect(subject).to include(remote_status.id) end end @@ -128,25 +192,25 @@ RSpec.describe PublicFeed, type: :model do let(:viewer) { Fabricate(:account, username: 'viewer') } it 'does not include local instances statuses' do - expect(subject).not_to include(local_status.id) + expect(subject).to_not include(local_status.id) expect(subject).to include(remote_status.id) end end end describe 'with an account passed in' do + subject { described_class.new(@account).get(20).map(&:id) } + before do @account = Fabricate(:account) end - subject { described_class.new(@account).get(20).map(&:id) } - it 'excludes statuses from accounts blocked by the account' do blocked = Fabricate(:account) @account.block!(blocked) blocked_status = Fabricate(:status, account: blocked) - expect(subject).not_to include(blocked_status.id) + expect(subject).to_not include(blocked_status.id) end it 'excludes statuses from accounts who have blocked the account' do @@ -154,7 +218,7 @@ RSpec.describe PublicFeed, type: :model do blocker.block!(@account) blocked_status = Fabricate(:status, account: blocker) - expect(subject).not_to include(blocked_status.id) + expect(subject).to_not include(blocked_status.id) end it 'excludes statuses from accounts muted by the account' do @@ -162,7 +226,7 @@ RSpec.describe PublicFeed, type: :model do @account.mute!(muted) muted_status = Fabricate(:status, account: muted) - expect(subject).not_to include(muted_status.id) + expect(subject).to_not include(muted_status.id) end it 'excludes statuses from accounts from personally blocked domains' do @@ -170,7 +234,7 @@ RSpec.describe PublicFeed, type: :model do @account.block_domain!(blocked.domain) blocked_status = Fabricate(:status, account: blocked) - expect(subject).not_to include(blocked_status.id) + expect(subject).to_not include(blocked_status.id) end context 'with language preferences' do @@ -182,7 +246,7 @@ RSpec.describe PublicFeed, type: :model do expect(subject).to include(en_status.id) expect(subject).to include(es_status.id) - expect(subject).not_to include(fr_status.id) + expect(subject).to_not include(fr_status.id) end it 'includes all languages when user does not have a setting' do diff --git a/spec/models/relationship_filter_spec.rb b/spec/models/relationship_filter_spec.rb index 7c0f37a06f..fccd42aaad 100644 --- a/spec/models/relationship_filter_spec.rb +++ b/spec/models/relationship_filter_spec.rb @@ -6,32 +6,60 @@ describe RelationshipFilter do let(:account) { Fabricate(:account) } describe '#results' do - context 'when default params are used' do - let(:subject) do - RelationshipFilter.new(account, 'order' => 'active').results + let(:account_of_7_months) { Fabricate(:account_stat, statuses_count: 1, last_status_at: 7.months.ago).account } + let(:account_of_1_day) { Fabricate(:account_stat, statuses_count: 1, last_status_at: 1.day.ago).account } + let(:account_of_3_days) { Fabricate(:account_stat, statuses_count: 1, last_status_at: 3.days.ago).account } + let(:silent_account) { Fabricate(:account_stat, statuses_count: 0, last_status_at: nil).account } + + before do + account.follow!(account_of_7_months) + account.follow!(account_of_1_day) + account.follow!(account_of_3_days) + account.follow!(silent_account) + end + + context 'when ordering by last activity' do + context 'when not filtering' do + subject do + described_class.new(account, 'order' => 'active').results + end + + it 'returns followings ordered by last activity' do + expect(subject).to eq [account_of_1_day, account_of_3_days, account_of_7_months, silent_account] + end end - before do - add_following_account_with(last_status_at: 7.days.ago) - add_following_account_with(last_status_at: 1.day.ago) - add_following_account_with(last_status_at: 3.days.ago) + context 'when filtering for dormant accounts' do + subject do + described_class.new(account, 'order' => 'active', 'activity' => 'dormant').results + end + + it 'returns dormant followings ordered by last activity' do + expect(subject).to eq [account_of_7_months, silent_account] + end + end + end + + context 'when ordering by account creation' do + context 'when not filtering' do + subject do + described_class.new(account, 'order' => 'recent').results + end + + it 'returns followings ordered by last account creation' do + expect(subject).to eq [silent_account, account_of_3_days, account_of_1_day, account_of_7_months] + end end - it 'returns followings ordered by last activity' do - expected_result = account.following.eager_load(:account_stat).reorder(nil).by_recent_status + context 'when filtering for dormant accounts' do + subject do + described_class.new(account, 'order' => 'recent', 'activity' => 'dormant').results + end - expect(subject).to eq expected_result + it 'returns dormant followings ordered by last activity' do + expect(subject).to eq [silent_account, account_of_7_months] + end end end end - - def add_following_account_with(last_status_at:) - following_account = Fabricate(:account) - Fabricate(:account_stat, account: following_account, - last_status_at: last_status_at, - statuses_count: 1, - following_count: 0, - followers_count: 0) - Fabricate(:follow, account: account, target_account: following_account).account - end end diff --git a/spec/models/relay_spec.rb b/spec/models/relay_spec.rb deleted file mode 100644 index 12dc0f20f6..0000000000 --- a/spec/models/relay_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe Relay, type: :model do -end diff --git a/spec/models/remote_follow_spec.rb b/spec/models/remote_follow_spec.rb index 5b4c19b5bb..81c726a40b 100644 --- a/spec/models/remote_follow_spec.rb +++ b/spec/models/remote_follow_spec.rb @@ -13,19 +13,19 @@ RSpec.describe RemoteFollow do describe '.initialize' do subject { remote_follow.acct } - context 'attrs with acct' do + context 'when attrs with acct' do let(:attrs) { { acct: 'gargron@quitter.no' } } it 'returns acct' do - is_expected.to eq 'gargron@quitter.no' + expect(subject).to eq 'gargron@quitter.no' end end - context 'attrs without acct' do + context 'when attrs without acct' do let(:attrs) { {} } it do - is_expected.to be_nil + expect(subject).to be_nil end end end @@ -33,24 +33,26 @@ RSpec.describe RemoteFollow do describe '#valid?' do subject { remote_follow.valid? } - context 'attrs with acct' do + context 'when attrs with acct' do let(:attrs) { { acct: 'gargron@quitter.no' } } it do - is_expected.to be true + expect(subject).to be true end end - context 'attrs without acct' do + context 'when attrs without acct' do let(:attrs) { {} } it do - is_expected.to be false + expect(subject).to be false end end end describe '#subscribe_address_for' do + subject { remote_follow.subscribe_address_for(account) } + before do remote_follow.valid? end @@ -58,10 +60,8 @@ RSpec.describe RemoteFollow do let(:attrs) { { acct: 'gargron@quitter.no' } } let(:account) { Fabricate(:account, username: 'alice') } - subject { remote_follow.subscribe_address_for(account) } - it 'returns subscribe address' do - is_expected.to eq 'https://quitter.no/main/ostatussub?profile=https%3A%2F%2Fcb6e6126.ngrok.io%2Fusers%2Falice' + expect(subject).to eq 'https://quitter.no/main/ostatussub?profile=https%3A%2F%2Fcb6e6126.ngrok.io%2Fusers%2Falice' end end end diff --git a/spec/models/report_filter_spec.rb b/spec/models/report_filter_spec.rb index 099c0731d3..6baf0ea421 100644 --- a/spec/models/report_filter_spec.rb +++ b/spec/models/report_filter_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' describe ReportFilter do describe 'with empty params' do it 'defaults to unresolved reports list' do - filter = ReportFilter.new({}) + filter = described_class.new({}) expect(filter.results).to eq Report.unresolved end @@ -11,7 +13,7 @@ describe ReportFilter do describe 'with invalid params' do it 'raises with key error' do - filter = ReportFilter.new(wrong: true) + filter = described_class.new(wrong: true) expect { filter.results }.to raise_error(/wrong/) end @@ -19,10 +21,9 @@ describe ReportFilter do describe 'with valid params' do it 'combines filters on Report' do - filter = ReportFilter.new(account_id: '123', resolved: true, target_account_id: '456') + filter = described_class.new(account_id: '123', resolved: true, target_account_id: '456') - allow(Report).to receive(:where).and_return(Report.none) - allow(Report).to receive(:resolved).and_return(Report.none) + allow(Report).to receive_messages(where: Report.none, resolved: Report.none) filter.results expect(Report).to have_received(:where).with(account_id: '123') expect(Report).to have_received(:where).with(target_account_id: '456') diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index 874be41328..0093dcd8de 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Report do @@ -33,7 +35,7 @@ describe Report do end it 'assigns to a given account' do - is_expected.to eq current_account.id + expect(subject).to eq current_account.id end end @@ -48,7 +50,7 @@ describe Report do end it 'unassigns' do - is_expected.to be_nil + expect(subject).to be_nil end end @@ -87,13 +89,13 @@ describe Report do let(:report) { Fabricate(:report, action_taken_at: action_taken) } - context 'if action is taken' do + context 'when action is taken' do let(:action_taken) { Time.now.utc } it { is_expected.to be false } end - context 'if action not is taken' do + context 'when action not is taken' do let(:action_taken) { nil } it { is_expected.to be true } @@ -119,16 +121,17 @@ describe Report do end describe 'validations' do - it 'has a valid fabricator' do - report = Fabricate(:report) - report.valid? - expect(report).to be_valid + let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') } + + it 'is invalid if comment is longer than 1000 characters only if reporter is local' do + report = Fabricate.build(:report, comment: Faker::Lorem.characters(number: 1001)) + expect(report.valid?).to be false + expect(report).to model_have_error_on_field(:comment) end - it 'is invalid if comment is longer than 1000 characters' do - report = Fabricate.build(:report, comment: Faker::Lorem.characters(number: 1001)) - report.valid? - expect(report).to model_have_error_on_field(:comment) + it 'is valid if comment is longer than 1000 characters and reporter is not local' do + report = Fabricate.build(:report, account: remote_account, comment: Faker::Lorem.characters(number: 1001)) + expect(report.valid?).to be true end end end diff --git a/spec/models/rule_spec.rb b/spec/models/rule_spec.rb index 8666bda713..c9b9c55028 100644 --- a/spec/models/rule_spec.rb +++ b/spec/models/rule_spec.rb @@ -1,5 +1,19 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Rule, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe Rule do + describe 'scopes' do + describe 'ordered' do + let(:deleted_rule) { Fabricate(:rule, deleted_at: 10.days.ago) } + let(:first_rule) { Fabricate(:rule, deleted_at: nil, priority: 1) } + let(:last_rule) { Fabricate(:rule, deleted_at: nil, priority: 10) } + + it 'finds the correct records' do + results = described_class.ordered + + expect(results).to eq([first_rule, last_rule]) + end + end + end end diff --git a/spec/models/scheduled_status_spec.rb b/spec/models/scheduled_status_spec.rb deleted file mode 100644 index f8c9d8b81f..0000000000 --- a/spec/models/scheduled_status_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe ScheduledStatus, type: :model do -end diff --git a/spec/models/session_activation_spec.rb b/spec/models/session_activation_spec.rb index 8db06c6227..75842e25ba 100644 --- a/spec/models/session_activation_spec.rb +++ b/spec/models/session_activation_spec.rb @@ -2,12 +2,12 @@ require 'rails_helper' -RSpec.describe SessionActivation, type: :model do +RSpec.describe SessionActivation do describe '#detection' do let(:session_activation) { Fabricate(:session_activation, user_agent: 'Chrome/62.0.3202.89') } it 'sets a Browser instance as detection' do - expect(session_activation.detection).to be_kind_of Browser::Chrome + expect(session_activation.detection).to be_a Browser::Chrome end end @@ -16,7 +16,7 @@ RSpec.describe SessionActivation, type: :model do allow(session_activation).to receive(:detection).and_return(detection) end - let(:detection) { double(id: 1) } + let(:detection) { instance_double(Browser::Chrome, id: 1) } let(:session_activation) { Fabricate(:session_activation) } it 'returns detection.id' do @@ -30,7 +30,7 @@ RSpec.describe SessionActivation, type: :model do end let(:session_activation) { Fabricate(:session_activation) } - let(:detection) { double(platform: double(id: 1)) } + let(:detection) { instance_double(Browser::Chrome, platform: instance_double(Browser::Platform, id: 1)) } it 'returns detection.platform.id' do expect(session_activation.platform).to be 1 @@ -40,31 +40,31 @@ RSpec.describe SessionActivation, type: :model do describe '.active?' do subject { described_class.active?(id) } - context 'id is absent' do + context 'when id is absent' do let(:id) { nil } it 'returns nil' do - is_expected.to be nil + expect(subject).to be_nil end end - context 'id is present' do + context 'when id is present' do let(:id) { '1' } let!(:session_activation) { Fabricate(:session_activation, session_id: id) } - context 'id exists as session_id' do + context 'when id exists as session_id' do it 'returns true' do - is_expected.to be true + expect(subject).to be true end end - context 'id does not exist as session_id' do + context 'when id does not exist as session_id' do before do session_activation.update!(session_id: '2') end it 'returns false' do - is_expected.to be false + expect(subject).to be false end end end @@ -80,20 +80,20 @@ RSpec.describe SessionActivation, type: :model do end it 'returns an instance of SessionActivation' do - expect(described_class.activate(**options)).to be_kind_of SessionActivation + expect(described_class.activate(**options)).to be_a described_class end end describe '.deactivate' do - context 'id is absent' do + context 'when id is absent' do let(:id) { nil } it 'returns nil' do - expect(described_class.deactivate(id)).to be nil + expect(described_class.deactivate(id)).to be_nil end end - context 'id exists' do + context 'when id exists' do let(:id) { '1' } it 'calls where.destroy_all' do diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index 3ccc21d6c4..5ed5c5d766 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe Setting, type: :model do +RSpec.describe Setting do describe '#to_param' do let(:setting) { Fabricate(:setting, var: var) } let(:var) { 'var' } @@ -19,7 +19,7 @@ RSpec.describe Setting, type: :model do let(:key) { 'key' } - context 'rails_initialized? is falsey' do + context 'when rails_initialized? is falsey' do let(:rails_initialized) { false } it 'calls RailsSettings::Base#[]' do @@ -28,7 +28,7 @@ RSpec.describe Setting, type: :model do end end - context 'rails_initialized? is truthy' do + context 'when rails_initialized? is truthy' do before do allow(RailsSettings::Base).to receive(:cache_key).with(key, nil).and_return(cache_key) end @@ -38,11 +38,11 @@ RSpec.describe Setting, type: :model do let(:cache_value) { 'cache-value' } it 'calls not RailsSettings::Base#[]' do - expect(RailsSettings::Base).not_to receive(:[]).with(key) + expect(RailsSettings::Base).to_not receive(:[]).with(key) described_class[key] end - context 'Rails.cache does not exists' do + context 'when Rails.cache does not exists' do before do allow(RailsSettings::Settings).to receive(:object).with(key).and_return(object) allow(described_class).to receive(:default_settings).and_return(default_settings) @@ -60,11 +60,11 @@ RSpec.describe Setting, type: :model do described_class[key] end - context 'RailsSettings::Settings.object returns truthy' do + context 'when RailsSettings::Settings.object returns truthy' do let(:object) { db_val } - let(:db_val) { double(value: 'db_val') } + let(:db_val) { instance_double(described_class, value: 'db_val') } - context 'default_value is a Hash' do + context 'when default_value is a Hash' do let(:default_value) { { default_value: 'default_value' } } it 'calls default_value.with_indifferent_access.merge!' do @@ -75,7 +75,7 @@ RSpec.describe Setting, type: :model do end end - context 'default_value is not a Hash' do + context 'when default_value is not a Hash' do let(:default_value) { 'default_value' } it 'returns db_val.value' do @@ -84,7 +84,7 @@ RSpec.describe Setting, type: :model do end end - context 'RailsSettings::Settings.object returns falsey' do + context 'when RailsSettings::Settings.object returns falsey' do let(:object) { nil } it 'returns default_settings[key]' do @@ -93,7 +93,7 @@ RSpec.describe Setting, type: :model do end end - context 'Rails.cache exists' do + context 'when Rails.cache exists' do before do Rails.cache.write(cache_key, cache_value) end @@ -104,7 +104,7 @@ RSpec.describe Setting, type: :model do ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do described_class[key] end - expect(callback).not_to have_received(:call) + expect(callback).to_not have_received(:call) end it 'returns the cached value' do @@ -127,10 +127,10 @@ RSpec.describe Setting, type: :model do let(:records) { [original_setting] } it 'returns a Hash' do - expect(described_class.all_as_records).to be_kind_of Hash + expect(described_class.all_as_records).to be_a Hash end - context 'records includes Setting with var as the key' do + context 'when records includes Setting with var as the key' do let(:records) { [original_setting] } it 'includes the original Setting' do @@ -139,20 +139,20 @@ RSpec.describe Setting, type: :model do end end - context 'records includes nothing' do + context 'when records includes nothing' do let(:records) { [] } - context 'default_value is not a Hash' do + context 'when default_value is not a Hash' do it 'includes Setting with value of default_value' do setting = described_class.all_as_records[key] - expect(setting).to be_kind_of Setting + expect(setting).to be_a described_class expect(setting).to have_attributes(var: key) expect(setting).to have_attributes(value: 'default_value') end end - context 'default_value is a Hash' do + context 'when default_value is a Hash' do let(:default_value) { { 'foo' => 'fuga' } } it 'returns {}' do @@ -163,25 +163,25 @@ RSpec.describe Setting, type: :model do end describe '.default_settings' do + subject { described_class.default_settings } + before do allow(RailsSettings::Default).to receive(:enabled?).and_return(enabled) end - subject { described_class.default_settings } - - context 'RailsSettings::Default.enabled? is false' do + context 'when RailsSettings::Default.enabled? is false' do let(:enabled) { false } it 'returns {}' do - is_expected.to eq({}) + expect(subject).to eq({}) end end - context 'RailsSettings::Settings.enabled? is true' do + context 'when RailsSettings::Settings.enabled? is true' do let(:enabled) { true } it 'returns instance of RailsSettings::Default' do - is_expected.to be_kind_of RailsSettings::Default + expect(subject).to be_a RailsSettings::Default end end end diff --git a/spec/models/site_upload_spec.rb b/spec/models/site_upload_spec.rb index f7ea069213..9689bce9ee 100644 --- a/spec/models/site_upload_spec.rb +++ b/spec/models/site_upload_spec.rb @@ -2,9 +2,9 @@ require 'rails_helper' -RSpec.describe SiteUpload, type: :model do +RSpec.describe SiteUpload do describe '#cache_key' do - let(:site_upload) { SiteUpload.new(var: 'var') } + let(:site_upload) { described_class.new(var: 'var') } it 'returns cache_key' do expect(site_upload.cache_key).to eq 'site_uploads/var' diff --git a/spec/models/software_update_spec.rb b/spec/models/software_update_spec.rb new file mode 100644 index 0000000000..0a494b0c4c --- /dev/null +++ b/spec/models/software_update_spec.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SoftwareUpdate do + describe '.pending_to_a' do + before do + allow(Mastodon::Version).to receive(:gem_version).and_return(Gem::Version.new(mastodon_version)) + + Fabricate(:software_update, version: '3.4.42', type: 'patch', urgent: true) + Fabricate(:software_update, version: '3.5.0', type: 'minor', urgent: false) + Fabricate(:software_update, version: '4.2.0', type: 'major', urgent: false) + end + + context 'when the Mastodon version is an outdated release' do + let(:mastodon_version) { '3.4.0' } + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to contain_exactly('3.4.42', '3.5.0', '4.2.0') + end + end + + context 'when the Mastodon version is more recent than anything last returned by the server' do + let(:mastodon_version) { '5.0.0' } + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to eq [] + end + end + + context 'when the Mastodon version is an outdated nightly' do + let(:mastodon_version) { '4.3.0-nightly.2023-09-10' } + + before do + Fabricate(:software_update, version: '4.3.0-nightly.2023-09-12', type: 'major', urgent: true) + end + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to contain_exactly('4.3.0-nightly.2023-09-12') + end + end + + context 'when the Mastodon version is a very outdated nightly' do + let(:mastodon_version) { '4.2.0-nightly.2023-07-10' } + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to contain_exactly('4.2.0') + end + end + + context 'when the Mastodon version is an outdated dev version' do + let(:mastodon_version) { '4.3.0-0.dev.0' } + + before do + Fabricate(:software_update, version: '4.3.0-0.dev.2', type: 'major', urgent: true) + end + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to contain_exactly('4.3.0-0.dev.2') + end + end + + context 'when the Mastodon version is an outdated beta version' do + let(:mastodon_version) { '4.3.0-beta1' } + + before do + Fabricate(:software_update, version: '4.3.0-beta2', type: 'major', urgent: true) + end + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to contain_exactly('4.3.0-beta2') + end + end + + context 'when the Mastodon version is an outdated beta version and there is a rc' do + let(:mastodon_version) { '4.3.0-beta1' } + + before do + Fabricate(:software_update, version: '4.3.0-rc1', type: 'major', urgent: true) + end + + it 'returns the expected versions' do + expect(described_class.pending_to_a.pluck(:version)).to contain_exactly('4.3.0-rc1') + end + end + end +end diff --git a/spec/models/status_edit_spec.rb b/spec/models/status_edit_spec.rb index 2ecafef734..2d33514522 100644 --- a/spec/models/status_edit_spec.rb +++ b/spec/models/status_edit_spec.rb @@ -1,5 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe StatusEdit, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe StatusEdit do + describe '#reblog?' do + it 'returns false' do + record = described_class.new + + expect(record).to_not be_a_reblog + end + end end diff --git a/spec/models/status_pin_spec.rb b/spec/models/status_pin_spec.rb index c18faca782..660b2e92ac 100644 --- a/spec/models/status_pin_spec.rb +++ b/spec/models/status_pin_spec.rb @@ -1,19 +1,21 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe StatusPin, type: :model do +RSpec.describe StatusPin do describe 'validations' do it 'allows pins of own statuses' do account = Fabricate(:account) status = Fabricate(:status, account: account) - expect(StatusPin.new(account: account, status: status).save).to be true + expect(described_class.new(account: account, status: status).save).to be true end it 'does not allow pins of statuses by someone else' do account = Fabricate(:account) status = Fabricate(:status) - expect(StatusPin.new(account: account, status: status).save).to be false + expect(described_class.new(account: account, status: status).save).to be false end it 'does not allow pins of reblogs' do @@ -21,21 +23,21 @@ RSpec.describe StatusPin, type: :model do status = Fabricate(:status, account: account) reblog = Fabricate(:status, reblog: status) - expect(StatusPin.new(account: account, status: reblog).save).to be false + expect(described_class.new(account: account, status: reblog).save).to be false end it 'does allow pins of direct statuses' do account = Fabricate(:account) status = Fabricate(:status, account: account, visibility: :private) - expect(StatusPin.new(account: account, status: status).save).to be true + expect(described_class.new(account: account, status: status).save).to be true end it 'does not allow pins of direct statuses' do account = Fabricate(:account) status = Fabricate(:status, account: account, visibility: :direct) - expect(StatusPin.new(account: account, status: status).save).to be false + expect(described_class.new(account: account, status: status).save).to be false end max_pins = 5 @@ -48,10 +50,10 @@ RSpec.describe StatusPin, type: :model do end max_pins.times do |i| - expect(StatusPin.new(account: account, status: status[i]).save).to be true + expect(described_class.new(account: account, status: status[i]).save).to be true end - expect(StatusPin.new(account: account, status: status[max_pins]).save).to be false + expect(described_class.new(account: account, status: status[max_pins]).save).to be false end it 'allows pins above the max for remote accounts' do @@ -63,10 +65,10 @@ RSpec.describe StatusPin, type: :model do end max_pins.times do |i| - expect(StatusPin.new(account: account, status: status[i]).save).to be true + expect(described_class.new(account: account, status: status[i]).save).to be true end - expect(StatusPin.new(account: account, status: status[max_pins]).save).to be true + expect(described_class.new(account: account, status: status[max_pins]).save).to be true end end end diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index 78cc059596..f38e7c2371 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Status, type: :model do +RSpec.describe Status do + subject { Fabricate(:status, account: alice) } + let(:alice) { Fabricate(:account, username: 'alice') } let(:bob) { Fabricate(:account, username: 'bob') } let(:other) { Fabricate(:status, account: bob, text: 'Skulls for the skull god! The enemy\'s gates are sideways!') } - subject { Fabricate(:status, account: alice) } - describe '#local?' do it 'returns true when no remote URI is set' do expect(subject.local?).to be true @@ -47,22 +49,22 @@ RSpec.describe Status, type: :model do end describe '#verb' do - context 'if destroyed?' do + context 'when destroyed?' do it 'returns :delete' do subject.destroy! expect(subject.verb).to be :delete end end - context 'unless destroyed?' do - context 'if reblog?' do + context 'when not destroyed?' do + context 'when reblog?' do it 'returns :share' do subject.reblog = other expect(subject.verb).to be :share end end - context 'unless reblog?' do + context 'when not reblog?' do it 'returns :post' do subject.reblog = nil expect(subject.verb).to be :post @@ -83,28 +85,28 @@ RSpec.describe Status, type: :model do end describe '#hidden?' do - context 'if private_visibility?' do + context 'when private_visibility?' do it 'returns true' do subject.visibility = :private expect(subject.hidden?).to be true end end - context 'if direct_visibility?' do + context 'when direct_visibility?' do it 'returns true' do subject.visibility = :direct expect(subject.hidden?).to be true end end - context 'if public_visibility?' do + context 'when public_visibility?' do it 'returns false' do subject.visibility = :public expect(subject.hidden?).to be false end end - context 'if unlisted_visibility?' do + context 'when unlisted_visibility?' do it 'returns false' do subject.visibility = :unlisted expect(subject.hidden?).to be false @@ -158,7 +160,7 @@ RSpec.describe Status, type: :model do reblog = Fabricate(:status, account: bob, reblog: subject) expect(subject.reblogs_count).to eq 1 expect { subject.destroy }.to_not raise_error - expect(Status.find_by(id: reblog.id)).to be_nil + expect(described_class.find_by(id: reblog.id)).to be_nil end end @@ -203,12 +205,49 @@ RSpec.describe Status, type: :model do end end + describe 'on create' do + subject { described_class.new } + + let(:local_account) { Fabricate(:account, username: 'local', domain: nil) } + let(:remote_account) { Fabricate(:account, username: 'remote', domain: 'example.com') } + + describe 'on a status that ends with the local-only emoji' do + before do + subject.text = "A toot #{subject.local_only_emoji}" + end + + context 'when the status originates from this instance' do + before do + subject.account = local_account + end + + it 'is marked local-only' do + subject.save! + + expect(subject).to be_local_only + end + end + + context 'when the status is remote' do + before do + subject.account = remote_account + end + + it 'is not marked local-only' do + subject.save! + + expect(subject).to_not be_local_only + end + end + end + end + describe '.mutes_map' do + subject { described_class.mutes_map([status.conversation.id], account) } + let(:status) { Fabricate(:status) } let(:account) { Fabricate(:account) } - subject { Status.mutes_map([status.conversation.id], account) } - it 'returns a hash' do expect(subject).to be_a Hash end @@ -220,11 +259,11 @@ RSpec.describe Status, type: :model do end describe '.favourites_map' do + subject { described_class.favourites_map([status], account) } + let(:status) { Fabricate(:status) } let(:account) { Fabricate(:account) } - subject { Status.favourites_map([status], account) } - it 'returns a hash' do expect(subject).to be_a Hash end @@ -236,11 +275,11 @@ RSpec.describe Status, type: :model do end describe '.reblogs_map' do + subject { described_class.reblogs_map([status], account) } + let(:status) { Fabricate(:status) } let(:account) { Fabricate(:account) } - subject { Status.reblogs_map([status], account) } - it 'returns a hash' do expect(subject).to be_a Hash end @@ -251,83 +290,133 @@ RSpec.describe Status, type: :model do end end + describe '.as_direct_timeline' do + subject(:results) { described_class.as_direct_timeline(account) } + + let(:account) { Fabricate(:account) } + let(:followed) { Fabricate(:account) } + let(:not_followed) { Fabricate(:account) } + + let!(:self_public_status) { Fabricate(:status, account: account, visibility: :public) } + let!(:self_direct_status) { Fabricate(:status, account: account, visibility: :direct) } + let!(:followed_public_status) { Fabricate(:status, account: followed, visibility: :public) } + let!(:followed_direct_status) { Fabricate(:status, account: followed, visibility: :direct) } + let!(:not_followed_direct_status) { Fabricate(:status, account: not_followed, visibility: :direct) } + + before do + account.follow!(followed) + end + + it 'does not include public statuses from self' do + expect(results).to_not include(self_public_status) + end + + it 'includes direct statuses from self' do + expect(results).to include(self_direct_status) + end + + it 'does not include public statuses from followed' do + expect(results).to_not include(followed_public_status) + end + + it 'does not include direct statuses not mentioning recipient from followed' do + expect(results).to_not include(followed_direct_status) + end + + it 'does not include direct statuses not mentioning recipient from non-followed' do + expect(results).to_not include(not_followed_direct_status) + end + + it 'includes direct statuses mentioning recipient from followed' do + Fabricate(:mention, account: account, status: followed_direct_status) + results2 = described_class.as_direct_timeline(account) + expect(results2).to include(followed_direct_status) + end + + it 'includes direct statuses mentioning recipient from non-followed' do + Fabricate(:mention, account: account, status: not_followed_direct_status) + results2 = described_class.as_direct_timeline(account) + expect(results2).to include(not_followed_direct_status) + end + end + describe '.tagged_with' do - let(:tag1) { Fabricate(:tag) } - let(:tag2) { Fabricate(:tag) } - let(:tag3) { Fabricate(:tag) } - let!(:status1) { Fabricate(:status, tags: [tag1]) } - let!(:status2) { Fabricate(:status, tags: [tag2]) } - let!(:status3) { Fabricate(:status, tags: [tag3]) } - let!(:status4) { Fabricate(:status, tags: []) } - let!(:status5) { Fabricate(:status, tags: [tag1, tag2, tag3]) } + let(:tag_cats) { Fabricate(:tag, name: 'cats') } + let(:tag_dogs) { Fabricate(:tag, name: 'dogs') } + let(:tag_zebras) { Fabricate(:tag, name: 'zebras') } + let!(:status_with_tag_cats) { Fabricate(:status, tags: [tag_cats]) } + let!(:status_with_tag_dogs) { Fabricate(:status, tags: [tag_dogs]) } + let!(:status_tagged_with_zebras) { Fabricate(:status, tags: [tag_zebras]) } + let!(:status_without_tags) { Fabricate(:status, tags: []) } + let!(:status_with_all_tags) { Fabricate(:status, tags: [tag_cats, tag_dogs, tag_zebras]) } context 'when given one tag' do it 'returns the expected statuses' do - expect(Status.tagged_with([tag1.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status5.id]) - expect(Status.tagged_with([tag2.id]).reorder(:id).pluck(:id).uniq).to match_array([status2.id, status5.id]) - expect(Status.tagged_with([tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status3.id, status5.id]) + expect(described_class.tagged_with([tag_cats.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_with_all_tags.id) + expect(described_class.tagged_with([tag_dogs.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_dogs.id, status_with_all_tags.id) + expect(described_class.tagged_with([tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_tagged_with_zebras.id, status_with_all_tags.id) end end context 'when given multiple tags' do it 'returns the expected statuses' do - expect(Status.tagged_with([tag1.id, tag2.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status2.id, status5.id]) - expect(Status.tagged_with([tag1.id, tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status3.id, status5.id]) - expect(Status.tagged_with([tag2.id, tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status2.id, status3.id, status5.id]) + expect(described_class.tagged_with([tag_cats.id, tag_dogs.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_with_tag_dogs.id, status_with_all_tags.id) + expect(described_class.tagged_with([tag_cats.id, tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_tagged_with_zebras.id, status_with_all_tags.id) + expect(described_class.tagged_with([tag_dogs.id, tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_dogs.id, status_tagged_with_zebras.id, status_with_all_tags.id) end end end describe '.tagged_with_all' do - let(:tag1) { Fabricate(:tag) } - let(:tag2) { Fabricate(:tag) } - let(:tag3) { Fabricate(:tag) } - let!(:status1) { Fabricate(:status, tags: [tag1]) } - let!(:status2) { Fabricate(:status, tags: [tag2]) } - let!(:status3) { Fabricate(:status, tags: [tag3]) } - let!(:status4) { Fabricate(:status, tags: []) } - let!(:status5) { Fabricate(:status, tags: [tag1, tag2]) } + let(:tag_cats) { Fabricate(:tag, name: 'cats') } + let(:tag_dogs) { Fabricate(:tag, name: 'dogs') } + let(:tag_zebras) { Fabricate(:tag, name: 'zebras') } + let!(:status_with_tag_cats) { Fabricate(:status, tags: [tag_cats]) } + let!(:status_with_tag_dogs) { Fabricate(:status, tags: [tag_dogs]) } + let!(:status_tagged_with_zebras) { Fabricate(:status, tags: [tag_zebras]) } + let!(:status_without_tags) { Fabricate(:status, tags: []) } + let!(:status_with_all_tags) { Fabricate(:status, tags: [tag_cats, tag_dogs]) } context 'when given one tag' do it 'returns the expected statuses' do - expect(Status.tagged_with_all([tag1.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status5.id]) - expect(Status.tagged_with_all([tag2.id]).reorder(:id).pluck(:id).uniq).to match_array([status2.id, status5.id]) - expect(Status.tagged_with_all([tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status3.id]) + expect(described_class.tagged_with_all([tag_cats.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_with_all_tags.id) + expect(described_class.tagged_with_all([tag_dogs.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_dogs.id, status_with_all_tags.id) + expect(described_class.tagged_with_all([tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_tagged_with_zebras.id) end end context 'when given multiple tags' do it 'returns the expected statuses' do - expect(Status.tagged_with_all([tag1.id, tag2.id]).reorder(:id).pluck(:id).uniq).to match_array([status5.id]) - expect(Status.tagged_with_all([tag1.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq [] - expect(Status.tagged_with_all([tag2.id, tag3.id]).reorder(:id).pluck(:id).uniq).to eq [] + expect(described_class.tagged_with_all([tag_cats.id, tag_dogs.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_all_tags.id) + expect(described_class.tagged_with_all([tag_cats.id, tag_zebras.id]).reorder(:id).pluck(:id).uniq).to eq [] + expect(described_class.tagged_with_all([tag_dogs.id, tag_zebras.id]).reorder(:id).pluck(:id).uniq).to eq [] end end end describe '.tagged_with_none' do - let(:tag1) { Fabricate(:tag) } - let(:tag2) { Fabricate(:tag) } - let(:tag3) { Fabricate(:tag) } - let!(:status1) { Fabricate(:status, tags: [tag1]) } - let!(:status2) { Fabricate(:status, tags: [tag2]) } - let!(:status3) { Fabricate(:status, tags: [tag3]) } - let!(:status4) { Fabricate(:status, tags: []) } - let!(:status5) { Fabricate(:status, tags: [tag1, tag2, tag3]) } + let(:tag_cats) { Fabricate(:tag, name: 'cats') } + let(:tag_dogs) { Fabricate(:tag, name: 'dogs') } + let(:tag_zebras) { Fabricate(:tag, name: 'zebras') } + let!(:status_with_tag_cats) { Fabricate(:status, tags: [tag_cats]) } + let!(:status_with_tag_dogs) { Fabricate(:status, tags: [tag_dogs]) } + let!(:status_tagged_with_zebras) { Fabricate(:status, tags: [tag_zebras]) } + let!(:status_without_tags) { Fabricate(:status, tags: []) } + let!(:status_with_all_tags) { Fabricate(:status, tags: [tag_cats, tag_dogs, tag_zebras]) } context 'when given one tag' do it 'returns the expected statuses' do - expect(Status.tagged_with_none([tag1.id]).reorder(:id).pluck(:id).uniq).to match_array([status2.id, status3.id, status4.id]) - expect(Status.tagged_with_none([tag2.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status3.id, status4.id]) - expect(Status.tagged_with_none([tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status2.id, status4.id]) + expect(described_class.tagged_with_none([tag_cats.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_dogs.id, status_tagged_with_zebras.id, status_without_tags.id) + expect(described_class.tagged_with_none([tag_dogs.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_tagged_with_zebras.id, status_without_tags.id) + expect(described_class.tagged_with_none([tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_with_tag_dogs.id, status_without_tags.id) end end context 'when given multiple tags' do it 'returns the expected statuses' do - expect(Status.tagged_with_none([tag1.id, tag2.id]).reorder(:id).pluck(:id).uniq).to match_array([status3.id, status4.id]) - expect(Status.tagged_with_none([tag1.id, tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status2.id, status4.id]) - expect(Status.tagged_with_none([tag2.id, tag3.id]).reorder(:id).pluck(:id).uniq).to match_array([status1.id, status4.id]) + expect(described_class.tagged_with_none([tag_cats.id, tag_dogs.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_tagged_with_zebras.id, status_without_tags.id) + expect(described_class.tagged_with_none([tag_cats.id, tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_dogs.id, status_without_tags.id) + expect(described_class.tagged_with_none([tag_dogs.id, tag_zebras.id]).reorder(:id).pluck(:id).uniq).to contain_exactly(status_with_tag_cats.id, status_without_tags.id) end end end @@ -342,21 +431,21 @@ RSpec.describe Status, type: :model do end it 'creates new conversation for stand-alone status' do - expect(Status.create(account: alice, text: 'First').conversation_id).to_not be_nil + expect(described_class.create(account: alice, text: 'First').conversation_id).to_not be_nil end it 'keeps conversation of parent node' do parent = Fabricate(:status, text: 'First') - expect(Status.create(account: alice, thread: parent, text: 'Response').conversation_id).to eq parent.conversation_id + expect(described_class.create(account: alice, thread: parent, text: 'Response').conversation_id).to eq parent.conversation_id end it 'sets `local` to true for status by local account' do - expect(Status.create(account: alice, text: 'foo').local).to be true + expect(described_class.create(account: alice, text: 'foo').local).to be true end it 'sets `local` to false for status by remote account' do alice.update(domain: 'example.com') - expect(Status.create(account: alice, text: 'foo').local).to be false + expect(described_class.create(account: alice, text: 'foo').local).to be false end end @@ -370,7 +459,7 @@ RSpec.describe Status, type: :model do describe 'after_create' do it 'saves ActivityPub uri as uri for local status' do - status = Status.create(account: alice, text: 'foo') + status = described_class.create(account: alice, text: 'foo') status.reload expect(status.uri).to start_with('https://') end diff --git a/spec/models/status_stat_spec.rb b/spec/models/status_stat_spec.rb deleted file mode 100644 index af1a6f288b..0000000000 --- a/spec/models/status_stat_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe StatusStat, type: :model do -end diff --git a/spec/models/status_trend_spec.rb b/spec/models/status_trend_spec.rb deleted file mode 100644 index 6b82204a60..0000000000 --- a/spec/models/status_trend_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe StatusTrend, type: :model do -end diff --git a/spec/models/system_key_spec.rb b/spec/models/system_key_spec.rb deleted file mode 100644 index a138bc1313..0000000000 --- a/spec/models/system_key_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe SystemKey, type: :model do - -end diff --git a/spec/models/tag_feed_spec.rb b/spec/models/tag_feed_spec.rb index 819fe37657..e836144f04 100644 --- a/spec/models/tag_feed_spec.rb +++ b/spec/models/tag_feed_spec.rb @@ -1,68 +1,84 @@ +# frozen_string_literal: true + require 'rails_helper' describe TagFeed, type: :service do describe '#get' do let(:account) { Fabricate(:account) } - let(:tag1) { Fabricate(:tag) } - let(:tag2) { Fabricate(:tag) } - let!(:status1) { Fabricate(:status, tags: [tag1]) } - let!(:status2) { Fabricate(:status, tags: [tag2]) } - let!(:both) { Fabricate(:status, tags: [tag1, tag2]) } + let(:tag_cats) { Fabricate(:tag, name: 'cats') } + let(:tag_dogs) { Fabricate(:tag, name: 'dogs') } + let!(:status_tagged_with_cats) { Fabricate(:status, tags: [tag_cats]) } + let!(:status_tagged_with_dogs) { Fabricate(:status, tags: [tag_dogs]) } + let!(:both) { Fabricate(:status, tags: [tag_cats, tag_dogs]) } it 'can add tags in "any" mode' do - results = described_class.new(tag1, nil, any: [tag2.name]).get(20) - expect(results).to include status1 - expect(results).to include status2 + results = described_class.new(tag_cats, nil, any: [tag_dogs.name]).get(20) + expect(results).to include status_tagged_with_cats + expect(results).to include status_tagged_with_dogs expect(results).to include both end it 'can remove tags in "all" mode' do - results = described_class.new(tag1, nil, all: [tag2.name]).get(20) - expect(results).to_not include status1 - expect(results).to_not include status2 + results = described_class.new(tag_cats, nil, all: [tag_dogs.name]).get(20) + expect(results).to_not include status_tagged_with_cats + expect(results).to_not include status_tagged_with_dogs expect(results).to include both end it 'can remove tags in "none" mode' do - results = described_class.new(tag1, nil, none: [tag2.name]).get(20) - expect(results).to include status1 - expect(results).to_not include status2 + results = described_class.new(tag_cats, nil, none: [tag_dogs.name]).get(20) + expect(results).to include status_tagged_with_cats + expect(results).to_not include status_tagged_with_dogs expect(results).to_not include both end it 'ignores an invalid mode' do - results = described_class.new(tag1, nil, wark: [tag2.name]).get(20) - expect(results).to include status1 - expect(results).to_not include status2 + results = described_class.new(tag_cats, nil, wark: [tag_dogs.name]).get(20) + expect(results).to include status_tagged_with_cats + expect(results).to_not include status_tagged_with_dogs expect(results).to include both end it 'handles being passed non existent tag names' do - results = described_class.new(tag1, nil, any: ['wark']).get(20) - expect(results).to include status1 - expect(results).to_not include status2 + results = described_class.new(tag_cats, nil, any: ['wark']).get(20) + expect(results).to include status_tagged_with_cats + expect(results).to_not include status_tagged_with_dogs expect(results).to include both end it 'can restrict to an account' do - BlockService.new.call(account, status1.account) - results = described_class.new(tag1, account, none: [tag2.name]).get(20) - expect(results).to_not include status1 + BlockService.new.call(account, status_tagged_with_cats.account) + results = described_class.new(tag_cats, account, none: [tag_dogs.name]).get(20) + expect(results).to_not include status_tagged_with_cats end it 'can restrict to local' do - status1.account.update(domain: 'example.com') - status1.update(local: false, uri: 'example.com/toot') - results = described_class.new(tag1, nil, any: [tag2.name], local: true).get(20) - expect(results).to_not include status1 + status_tagged_with_cats.account.update(domain: 'example.com') + status_tagged_with_cats.update(local: false, uri: 'example.com/toot') + results = described_class.new(tag_cats, nil, any: [tag_dogs.name], local: true).get(20) + expect(results).to_not include status_tagged_with_cats end it 'allows replies to be included' do original = Fabricate(:status) - status = Fabricate(:status, tags: [tag1], in_reply_to_id: original.id) + status = Fabricate(:status, tags: [tag_cats], in_reply_to_id: original.id) - results = described_class.new(tag1, nil).get(20) + results = described_class.new(tag_cats, nil).get(20) expect(results).to include(status) end + + context 'when the feed contains a local-only status' do + let!(:status) { Fabricate(:status, tags: [tag_cats], local_only: true) } + + it 'does not show local-only statuses without a viewer' do + results = described_class.new(tag_cats, nil).get(20) + expect(results).to_not include(status) + end + + it 'shows local-only statuses given a viewer' do + results = described_class.new(tag_cats, account).get(20) + expect(results).to include(status) + end + end end end diff --git a/spec/models/tag_follow_spec.rb b/spec/models/tag_follow_spec.rb deleted file mode 100644 index 50c04d2e46..0000000000 --- a/spec/models/tag_follow_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe TagFollow, type: :model do -end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 102d2f6251..4d6e5c380b 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -1,18 +1,19 @@ # frozen_string_literal: true + require 'rails_helper' RSpec.describe Tag do describe 'validations' do it 'invalid with #' do - expect(described_class.new(name: '#hello_world')).not_to be_valid + expect(described_class.new(name: '#hello_world')).to_not be_valid end it 'invalid with .' do - expect(described_class.new(name: '.abcdef123')).not_to be_valid + expect(described_class.new(name: '.abcdef123')).to_not be_valid end it 'invalid with spaces' do - expect(described_class.new(name: 'hello world')).not_to be_valid + expect(described_class.new(name: 'hello world')).to_not be_valid end it 'valid with aesthetic' do diff --git a/spec/models/trends/statuses_spec.rb b/spec/models/trends/statuses_spec.rb index 5f338a65e8..7c30b5b997 100644 --- a/spec/models/trends/statuses_spec.rb +++ b/spec/models/trends/statuses_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Trends::Statuses do @@ -9,12 +11,12 @@ RSpec.describe Trends::Statuses do let!(:query) { subject.query } let!(:today) { at_time } - let!(:status1) { Fabricate(:status, text: 'Foo', language: 'en', trendable: true, created_at: today) } - let!(:status2) { Fabricate(:status, text: 'Bar', language: 'en', trendable: true, created_at: today) } + let!(:status_foo) { Fabricate(:status, text: 'Foo', language: 'en', trendable: true, created_at: today) } + let!(:status_bar) { Fabricate(:status, text: 'Bar', language: 'en', trendable: true, created_at: today) } before do - 15.times { reblog(status1, today) } - 12.times { reblog(status2, today) } + default_threshold_value.times { reblog(status_foo, today) } + default_threshold_value.times { reblog(status_bar, today) } subject.refresh(today) end @@ -27,18 +29,18 @@ RSpec.describe Trends::Statuses do end it 'filters out blocked accounts' do - account.block!(status1.account) - expect(query.filtered_for(account).to_a).to eq [status2] + account.block!(status_foo.account) + expect(query.filtered_for(account).to_a).to eq [status_bar] end it 'filters out muted accounts' do - account.mute!(status2.account) - expect(query.filtered_for(account).to_a).to eq [status1] + account.mute!(status_bar.account) + expect(query.filtered_for(account).to_a).to eq [status_foo] end it 'filters out blocked-by accounts' do - status1.account.block!(account) - expect(query.filtered_for(account).to_a).to eq [status2] + status_foo.account.block!(account) + expect(query.filtered_for(account).to_a).to eq [status_bar] end end end @@ -69,36 +71,35 @@ RSpec.describe Trends::Statuses do let!(:today) { at_time } let!(:yesterday) { today - 1.day } - let!(:status1) { Fabricate(:status, text: 'Foo', language: 'en', trendable: true, created_at: yesterday) } - let!(:status2) { Fabricate(:status, text: 'Bar', language: 'en', trendable: true, created_at: today) } - let!(:status3) { Fabricate(:status, text: 'Baz', language: 'en', trendable: true, created_at: today) } + let!(:status_foo) { Fabricate(:status, text: 'Foo', language: 'en', trendable: true, created_at: yesterday) } + let!(:status_bar) { Fabricate(:status, text: 'Bar', language: 'en', trendable: true, created_at: today) } + let!(:status_baz) { Fabricate(:status, text: 'Baz', language: 'en', trendable: true, created_at: today) } before do - 13.times { reblog(status1, today) } - 13.times { reblog(status2, today) } - 4.times { reblog(status3, today) } + default_threshold_value.times { reblog(status_foo, today) } + default_threshold_value.times { reblog(status_bar, today) } + (default_threshold_value - 1).times { reblog(status_baz, today) } end - context do + context 'when status trends are refreshed' do before do subject.refresh(today) end - it 'calculates and re-calculates scores' do - expect(subject.query.limit(10).to_a).to eq [status2, status1] - end + it 'returns correct statuses from query' do + results = subject.query.limit(10).to_a - it 'omits statuses below threshold' do - expect(subject.query.limit(10).to_a).to_not include(status3) + expect(results).to eq [status_bar, status_foo] + expect(results).to_not include(status_baz) end end it 'decays scores' do subject.refresh(today) - original_score = status2.trend.score + original_score = status_bar.trend.score expect(original_score).to be_a Float subject.refresh(today + subject.options[:score_halflife]) - decayed_score = status2.trend.reload.score + decayed_score = status_bar.trend.reload.score expect(decayed_score).to be <= original_score / 2 end end @@ -107,4 +108,8 @@ RSpec.describe Trends::Statuses do reblog = Fabricate(:status, reblog: status, created_at: at_time) subject.add(status, reblog.account_id, at_time) end + + def default_threshold_value + described_class.default_options[:threshold] + end end diff --git a/spec/models/trends/tags_spec.rb b/spec/models/trends/tags_spec.rb index f48c735035..f2818fca87 100644 --- a/spec/models/trends/tags_spec.rb +++ b/spec/models/trends/tags_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe Trends::Tags do @@ -22,45 +24,47 @@ RSpec.describe Trends::Tags do end describe '#query' do - pending + it 'returns a composable query scope' do + expect(subject.query).to be_a Trends::Query + end end describe '#refresh' do let!(:today) { at_time } let!(:yesterday) { today - 1.day } - let!(:tag1) { Fabricate(:tag, name: 'Catstodon', trendable: true) } - let!(:tag2) { Fabricate(:tag, name: 'DogsOfMastodon', trendable: true) } - let!(:tag3) { Fabricate(:tag, name: 'OCs', trendable: true) } + let!(:tag_cats) { Fabricate(:tag, name: 'Catstodon', trendable: true) } + let!(:tag_dogs) { Fabricate(:tag, name: 'DogsOfMastodon', trendable: true) } + let!(:tag_ocs) { Fabricate(:tag, name: 'OCs', trendable: true) } before do - 2.times { |i| subject.add(tag1, i, yesterday) } - 13.times { |i| subject.add(tag3, i, yesterday) } - 16.times { |i| subject.add(tag1, i, today) } - 4.times { |i| subject.add(tag2, i, today) } + 2.times { |i| subject.add(tag_cats, i, yesterday) } + 13.times { |i| subject.add(tag_ocs, i, yesterday) } + 16.times { |i| subject.add(tag_cats, i, today) } + 4.times { |i| subject.add(tag_dogs, i, today) } end - context do + context 'when tag trends are refreshed' do before do subject.refresh(yesterday + 12.hours) subject.refresh(at_time) end it 'calculates and re-calculates scores' do - expect(subject.query.limit(10).to_a).to eq [tag1, tag3] + expect(subject.query.limit(10).to_a).to eq [tag_cats, tag_ocs] end it 'omits hashtags below threshold' do - expect(subject.query.limit(10).to_a).to_not include(tag2) + expect(subject.query.limit(10).to_a).to_not include(tag_dogs) end end it 'decays scores' do subject.refresh(yesterday + 12.hours) - original_score = subject.score(tag3.id) + original_score = subject.score(tag_ocs.id) expect(original_score).to eq 144.0 subject.refresh(yesterday + 12.hours + subject.options[:max_score_halflife]) - decayed_score = subject.score(tag3.id) + decayed_score = subject.score(tag_ocs.id) expect(decayed_score).to be <= original_score / 2 end end diff --git a/spec/models/unavailable_domain_spec.rb b/spec/models/unavailable_domain_spec.rb deleted file mode 100644 index 3f2621034c..0000000000 --- a/spec/models/unavailable_domain_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe UnavailableDomain, type: :model do -end diff --git a/spec/models/user_invite_request_spec.rb b/spec/models/user_invite_request_spec.rb deleted file mode 100644 index 1be38d8a47..0000000000 --- a/spec/models/user_invite_request_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe UserInviteRequest, type: :model do -end diff --git a/spec/models/user_role_spec.rb b/spec/models/user_role_spec.rb index 28019593e5..f7cfe9bb04 100644 --- a/spec/models/user_role_spec.rb +++ b/spec/models/user_role_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe UserRole, type: :model do +RSpec.describe UserRole do subject { described_class.create(name: 'Foo', position: 1) } describe '#can?' do @@ -58,7 +60,7 @@ RSpec.describe UserRole, type: :model do end describe '#permissions_as_keys=' do - let(:input) { } + let(:input) {} before do subject.permissions_as_keys = input @@ -91,7 +93,7 @@ RSpec.describe UserRole, type: :model do describe '#computed_permissions' do context 'when the role is nobody' do - let(:subject) { described_class.nobody } + subject { described_class.nobody } it 'returns none' do expect(subject.computed_permissions).to eq UserRole::Flags::NONE @@ -99,7 +101,7 @@ RSpec.describe UserRole, type: :model do end context 'when the role is everyone' do - let(:subject) { described_class.everyone } + subject { described_class.everyone } it 'returns permissions' do expect(subject.computed_permissions).to eq subject.permissions @@ -116,10 +118,8 @@ RSpec.describe UserRole, type: :model do end end - context do - it 'returns permissions combined with the everyone role' do - expect(subject.computed_permissions).to eq described_class.everyone.permissions - end + it 'returns permissions combined with the everyone role' do + expect(subject.computed_permissions).to eq described_class.everyone.permissions end end @@ -127,7 +127,7 @@ RSpec.describe UserRole, type: :model do subject { described_class.everyone } it 'returns a role' do - expect(subject).to be_kind_of(described_class) + expect(subject).to be_a(described_class) end it 'is identified as the everyone role' do @@ -139,7 +139,7 @@ RSpec.describe UserRole, type: :model do end it 'has negative position' do - expect(subject.position).to eq -1 + expect(subject.position).to eq(-1) end end @@ -147,7 +147,7 @@ RSpec.describe UserRole, type: :model do subject { described_class.nobody } it 'returns a role' do - expect(subject).to be_kind_of(described_class) + expect(subject).to be_a(described_class) end it 'is identified as the nobody role' do @@ -159,7 +159,7 @@ RSpec.describe UserRole, type: :model do end it 'has negative position' do - expect(subject.position).to eq -1 + expect(subject.position).to eq(-1) end end diff --git a/spec/models/user_settings/namespace_spec.rb b/spec/models/user_settings/namespace_spec.rb new file mode 100644 index 0000000000..ae2fa7b482 --- /dev/null +++ b/spec/models/user_settings/namespace_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe UserSettings::Namespace do + subject { described_class.new(name) } + + let(:name) { :foo } + + describe '#setting' do + before do + subject.setting :bar, default: 'baz' + end + + it 'adds setting to definitions' do + expect(subject.definitions[:'foo.bar']).to have_attributes(name: :bar, namespace: :foo, default_value: 'baz') + end + end + + describe '#definitions' do + it 'returns a hash' do + expect(subject.definitions).to be_a Hash + end + end +end diff --git a/spec/models/user_settings/setting_spec.rb b/spec/models/user_settings/setting_spec.rb new file mode 100644 index 0000000000..8c8d31ec54 --- /dev/null +++ b/spec/models/user_settings/setting_spec.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe UserSettings::Setting do + subject { described_class.new(name, options) } + + let(:name) { :foo } + let(:options) { { default: default, namespace: namespace } } + let(:default) { false } + let(:namespace) { nil } + + describe '#default_value' do + context 'when default value is a primitive value' do + it 'returns default value' do + expect(subject.default_value).to eq default + end + end + + context 'when default value is a proc' do + let(:default) { -> { 'bar' } } + + it 'returns value from proc' do + expect(subject.default_value).to eq 'bar' + end + end + end + + describe '#type' do + it 'returns a type' do + expect(subject.type).to be_a ActiveModel::Type::Value + end + + context 'when default value is a boolean' do + let(:default) { false } + + it 'returns boolean' do + expect(subject.type).to be_a ActiveModel::Type::Boolean + end + end + + context 'when default value is a string' do + let(:default) { '' } + + it 'returns string' do + expect(subject.type).to be_a ActiveModel::Type::String + end + end + + context 'when default value is a lambda returning a boolean' do + let(:default) { -> { false } } + + it 'returns boolean' do + expect(subject.type).to be_a ActiveModel::Type::Boolean + end + end + + context 'when default value is a lambda returning a string' do + let(:default) { -> { '' } } + + it 'returns boolean' do + expect(subject.type).to be_a ActiveModel::Type::String + end + end + end + + describe '#type_cast' do + context 'when default value is a boolean' do + let(:default) { false } + + it 'returns boolean' do + expect(subject.type_cast('1')).to be true + end + end + + context 'when default value is a string' do + let(:default) { '' } + + it 'returns string' do + expect(subject.type_cast(1)).to eq '1' + end + end + end + + describe '#to_a' do + it 'returns an array' do + expect(subject.to_a).to eq [name, default] + end + end + + describe '#key' do + context 'when there is no namespace' do + it 'returns a symbol' do + expect(subject.key).to eq :foo + end + end + + context 'when there is a namespace' do + let(:namespace) { :bar } + + it 'returns a symbol' do + expect(subject.key).to eq :'bar.foo' + end + end + end +end diff --git a/spec/models/user_settings_spec.rb b/spec/models/user_settings_spec.rb new file mode 100644 index 0000000000..653597c90d --- /dev/null +++ b/spec/models/user_settings_spec.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe UserSettings do + subject { described_class.new(json) } + + let(:json) { {} } + + describe '#[]' do + context 'when setting is not set' do + it 'returns default value' do + expect(subject[:always_send_emails]).to be false + end + end + + context 'when setting is set' do + let(:json) { { default_language: 'fr' } } + + it 'returns value' do + expect(subject[:default_language]).to eq 'fr' + end + end + + context 'when setting was not defined' do + it 'raises error' do + expect { subject[:foo] }.to raise_error UserSettings::KeyError + end + end + end + + describe '#[]=' do + context 'when value matches type' do + before do + subject[:always_send_emails] = true + end + + it 'updates value' do + expect(subject[:always_send_emails]).to be true + end + end + + context 'when value needs to be type-cast' do + before do + subject[:always_send_emails] = '1' + end + + it 'updates value with a type-cast' do + expect(subject[:always_send_emails]).to be true + end + end + + context 'when the setting has a closed set of values' do + it 'updates the attribute when given a valid value' do + expect { subject[:'web.display_media'] = :show_all }.to change { subject[:'web.display_media'] }.from('default').to('show_all') + end + + it 'raises an error when given an invalid value' do + expect { subject[:'web.display_media'] = 'invalid value' }.to raise_error ArgumentError + end + end + end + + describe '#update' do + before do + subject.update(always_send_emails: true, default_language: 'fr', default_privacy: nil) + end + + it 'updates values' do + expect(subject[:always_send_emails]).to be true + expect(subject[:default_language]).to eq 'fr' + end + + it 'does not set values that are nil' do + expect(subject.as_json).to_not include(default_privacy: nil) + end + end + + describe '#as_json' do + let(:json) { { default_language: 'fr' } } + + it 'returns hash' do + expect(subject.as_json).to eq json + end + end + + describe '.keys' do + it 'returns an array' do + expect(described_class.keys).to be_a Array + end + end + + describe '.definition_for' do + context 'when key is defined' do + it 'returns a setting' do + expect(described_class.definition_for(:always_send_emails)).to be_a UserSettings::Setting + end + end + + context 'when key is not defined' do + it 'returns nil' do + expect(described_class.definition_for(:foo)).to be_nil + end + end + end + + describe '.definition_for?' do + context 'when key is defined' do + it 'returns true' do + expect(described_class.definition_for?(:always_send_emails)).to be true + end + end + + context 'when key is not defined' do + it 'returns false' do + expect(described_class.definition_for?(:foo)).to be false + end + end + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 4b3d6101fd..bb61c02a63 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,7 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' require 'devise_two_factor/spec_helpers' -RSpec.describe User, type: :model do +RSpec.describe User do + let(:password) { 'abcd1234' } + let(:account) { Fabricate(:account, username: 'alice') } + it_behaves_like 'two_factor_backupable' describe 'otp_secret' do @@ -43,7 +48,7 @@ RSpec.describe User, type: :model do it 'cleans out empty string from languages' do user = Fabricate.build(:user, chosen_languages: ['']) user.valid? - expect(user.chosen_languages).to eq nil + expect(user.chosen_languages).to be_nil end end @@ -52,7 +57,7 @@ RSpec.describe User, type: :model do it 'returns an array of recent users ordered by id' do user_1 = Fabricate(:user) user_2 = Fabricate(:user) - expect(User.recent).to eq [user_2, user_1] + expect(described_class.recent).to eq [user_2, user_1] end end @@ -60,7 +65,7 @@ RSpec.describe User, type: :model do it 'returns an array of users who are confirmed' do user_1 = Fabricate(:user, confirmed_at: nil) user_2 = Fabricate(:user, confirmed_at: Time.zone.now) - expect(User.confirmed).to match_array([user_2]) + expect(described_class.confirmed).to contain_exactly(user_2) end end @@ -69,7 +74,7 @@ RSpec.describe User, type: :model do specified = Fabricate(:user, current_sign_in_at: 15.days.ago) Fabricate(:user, current_sign_in_at: 6.days.ago) - expect(User.inactive).to match_array([specified]) + expect(described_class.inactive).to contain_exactly(specified) end end @@ -78,7 +83,7 @@ RSpec.describe User, type: :model do specified = Fabricate(:user, email: 'specified@spec') Fabricate(:user, email: 'unspecified@spec') - expect(User.matches_email('specified')).to match_array([specified]) + expect(described_class.matches_email('specified')).to contain_exactly(specified) end end @@ -91,14 +96,11 @@ RSpec.describe User, type: :model do Fabricate(:session_activation, user: user2, ip: '2160:8888::24', session_id: '3') Fabricate(:session_activation, user: user2, ip: '2160:8888::25', session_id: '4') - expect(User.matches_ip('2160:2160::/32')).to match_array([user1]) + expect(described_class.matches_ip('2160:2160::/32')).to contain_exactly(user1) end end end - let(:account) { Fabricate(:account, username: 'alice') } - let(:password) { 'abcd1234' } - describe 'blacklist' do around(:each) do |example| old_blacklist = Rails.configuration.x.email_blacklist @@ -110,22 +112,22 @@ RSpec.describe User, type: :model do Rails.configuration.x.email_domains_blacklist = old_blacklist end - it 'should allow a non-blacklisted user to be created' do - user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true) + it 'allows a non-blacklisted user to be created' do + user = described_class.new(email: 'foo@example.com', account: account, password: password, agreement: true) - expect(user.valid?).to be_truthy + expect(user).to be_valid end - it 'should not allow a blacklisted user to be created' do - user = User.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true) + it 'does not allow a blacklisted user to be created' do + user = described_class.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true) - expect(user.valid?).to be_falsey + expect(user).to_not be_valid end - it 'should not allow a subdomain blacklisted user to be created' do - user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true) + it 'does not allow a subdomain blacklisted user to be created' do + user = described_class.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true) - expect(user.valid?).to be_falsey + expect(user).to_not be_valid end end @@ -142,10 +144,10 @@ RSpec.describe User, type: :model do end describe '#confirm' do - let(:new_email) { 'new-email@example.com' } - subject { user.confirm } + let(:new_email) { 'new-email@example.com' } + before do allow(TriggerWebhookWorker).to receive(:perform_async) end @@ -159,7 +161,7 @@ RSpec.describe User, type: :model do it 'does not trigger the account.approved Web Hook' do subject - expect(TriggerWebhookWorker).not_to have_received(:perform_async).with('account.approved', 'Account', user.account_id) + expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id) end end @@ -270,7 +272,7 @@ RSpec.describe User, type: :model do it 'does not trigger the account.approved Web Hook' do subject - expect(TriggerWebhookWorker).not_to have_received(:perform_async).with('account.approved', 'Account', user.account_id) + expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id) end end end @@ -285,7 +287,7 @@ RSpec.describe User, type: :model do it 'saves nil for otp_secret' do user = Fabricate.build(:user, otp_secret: 'oldotpcode') user.disable_two_factor! - expect(user.reload.otp_secret).to be nil + expect(user.reload.otp_secret).to be_nil end it 'saves cleared otp_backup_codes' do @@ -311,9 +313,9 @@ RSpec.describe User, type: :model do end describe 'settings' do - it 'is instance of Settings::ScopedSettings' do + it 'is instance of UserSettings' do user = Fabricate(:user) - expect(user.settings).to be_kind_of Settings::ScopedSettings + expect(user.settings).to be_a UserSettings end end @@ -346,47 +348,37 @@ RSpec.describe User, type: :model do Rails.configuration.x.email_domains_whitelist = old_whitelist end - it 'should not allow a user to be created unless they are whitelisted' do - user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true) - expect(user.valid?).to be_falsey + it 'does not allow a user to be created unless they are whitelisted' do + user = described_class.new(email: 'foo@example.com', account: account, password: password, agreement: true) + expect(user).to_not be_valid end - it 'should allow a user to be created if they are whitelisted' do - user = User.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true) - expect(user.valid?).to be_truthy + it 'allows a user to be created if they are whitelisted' do + user = described_class.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true) + expect(user).to be_valid end - it 'should not allow a user with a whitelisted top domain as subdomain in their email address to be created' do - user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true) - expect(user.valid?).to be_falsey + it 'does not allow a user with a whitelisted top domain as subdomain in their email address to be created' do + user = described_class.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true) + expect(user).to_not be_valid end - context do + context 'with a blacklisted subdomain' do around do |example| old_blacklist = Rails.configuration.x.email_blacklist example.run Rails.configuration.x.email_domains_blacklist = old_blacklist end - it 'should not allow a user to be created with a specific blacklisted subdomain even if the top domain is whitelisted' do + it 'does not allow a user to be created with a specific blacklisted subdomain even if the top domain is whitelisted' do Rails.configuration.x.email_domains_blacklist = 'blacklisted.mastodon.space' - user = User.new(email: 'foo@blacklisted.mastodon.space', account: account, password: password) - expect(user.valid?).to be_falsey + user = described_class.new(email: 'foo@blacklisted.mastodon.space', account: account, password: password) + expect(user).to_not be_valid end end end - it_behaves_like 'Settings-extended' do - def create! - User.create!(account: Fabricate(:account, user: nil), email: 'foo@mastodon.space', password: 'abcd1234', agreement: true) - end - - def fabricate - Fabricate(:user) - end - end - describe 'token_for_app' do let(:user) { Fabricate(:user) } let(:app) { Fabricate(:application, owner: user) } @@ -409,6 +401,7 @@ RSpec.describe User, type: :model do describe '#disable!' do subject(:user) { Fabricate(:user, disabled: false, current_sign_in_at: current_sign_in_at, last_sign_in_at: nil) } + let(:current_sign_in_at) { Time.zone.now } before do @@ -497,6 +490,7 @@ RSpec.describe User, type: :model do describe '#active_for_authentication?' do subject { user.active_for_authentication? } + let(:user) { Fabricate(:user, disabled: disabled, confirmed_at: confirmed_at) } context 'when user is disabled' do @@ -533,6 +527,28 @@ RSpec.describe User, type: :model do end describe '.those_who_can' do - pending + before { Fabricate(:user, role: UserRole.find_by(name: 'Moderator')) } + + context 'when there are not any user roles' do + before { UserRole.destroy_all } + + it 'returns an empty list' do + expect(described_class.those_who_can(:manage_blocks)).to eq([]) + end + end + + context 'when there are not users with the needed role' do + it 'returns an empty list' do + expect(described_class.those_who_can(:manage_blocks)).to eq([]) + end + end + + context 'when there are users with roles' do + let!(:admin_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } + + it 'returns the users with the role' do + expect(described_class.those_who_can(:manage_blocks)).to eq([admin_user]) + end + end end end diff --git a/spec/models/web/push_subscription_spec.rb b/spec/models/web/push_subscription_spec.rb index bd57195937..3c2cd3bac1 100644 --- a/spec/models/web/push_subscription_spec.rb +++ b/spec/models/web/push_subscription_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Web::PushSubscription, type: :model do +RSpec.describe Web::PushSubscription do + subject { described_class.new(data: data) } + let(:account) { Fabricate(:account) } let(:policy) { 'all' } @@ -19,8 +23,6 @@ RSpec.describe Web::PushSubscription, type: :model do } end - subject { described_class.new(data: data) } - describe '#pushable?' do let(:notification_type) { :mention } let(:notification) { Fabricate(:notification, account: account, type: notification_type) } @@ -29,7 +31,7 @@ RSpec.describe Web::PushSubscription, type: :model do context "when notification is a #{type}" do let(:notification_type) { type } - it "returns boolean corresponding to alert setting" do + it 'returns boolean corresponding to alert setting' do expect(subject.pushable?(notification)).to eq data[:alerts][type] end end @@ -39,7 +41,7 @@ RSpec.describe Web::PushSubscription, type: :model do let(:policy) { 'all' } it 'returns true' do - expect(subject.pushable?(notification)).to eq true + expect(subject.pushable?(notification)).to be true end end @@ -47,26 +49,26 @@ RSpec.describe Web::PushSubscription, type: :model do let(:policy) { 'none' } it 'returns false' do - expect(subject.pushable?(notification)).to eq false + expect(subject.pushable?(notification)).to be false end end context 'when policy is followed' do let(:policy) { 'followed' } - context 'and notification is from someone you follow' do + context 'when notification is from someone you follow' do before do account.follow!(notification.from_account) end it 'returns true' do - expect(subject.pushable?(notification)).to eq true + expect(subject.pushable?(notification)).to be true end end - context 'and notification is not from someone you follow' do + context 'when notification is not from someone you follow' do it 'returns false' do - expect(subject.pushable?(notification)).to eq false + expect(subject.pushable?(notification)).to be false end end end @@ -74,19 +76,19 @@ RSpec.describe Web::PushSubscription, type: :model do context 'when policy is follower' do let(:policy) { 'follower' } - context 'and notification is from someone who follows you' do + context 'when notification is from someone who follows you' do before do notification.from_account.follow!(account) end it 'returns true' do - expect(subject.pushable?(notification)).to eq true + expect(subject.pushable?(notification)).to be true end end - context 'and notification is not from someone who follows you' do + context 'when notification is not from someone who follows you' do it 'returns false' do - expect(subject.pushable?(notification)).to eq false + expect(subject.pushable?(notification)).to be false end end end diff --git a/spec/models/web/setting_spec.rb b/spec/models/web/setting_spec.rb deleted file mode 100644 index 6657d4030f..0000000000 --- a/spec/models/web/setting_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'rails_helper' - -RSpec.describe Web::Setting, type: :model do -end diff --git a/spec/models/webauthn_credentials_spec.rb b/spec/models/webauthn_credentials_spec.rb index a63ae6cd24..4579ebb82e 100644 --- a/spec/models/webauthn_credentials_spec.rb +++ b/spec/models/webauthn_credentials_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe WebauthnCredential, type: :model do +RSpec.describe WebauthnCredential do describe 'validations' do it 'is invalid without an external id' do webauthn_credential = Fabricate.build(:webauthn_credential, external_id: nil) @@ -35,8 +37,8 @@ RSpec.describe WebauthnCredential, type: :model do end it 'is invalid if already exist a webauthn credential with the same external id' do - existing_webauthn_credential = Fabricate(:webauthn_credential, external_id: "_Typ0ygudDnk9YUVWLQayw") - new_webauthn_credential = Fabricate.build(:webauthn_credential, external_id: "_Typ0ygudDnk9YUVWLQayw") + existing_webauthn_credential = Fabricate(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw') + new_webauthn_credential = Fabricate.build(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw') new_webauthn_credential.valid? diff --git a/spec/models/webhook_spec.rb b/spec/models/webhook_spec.rb index 60c3d9524f..715dd7574f 100644 --- a/spec/models/webhook_spec.rb +++ b/spec/models/webhook_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Webhook, type: :model do +RSpec.describe Webhook do let(:webhook) { Fabricate(:webhook) } describe '#rotate_secret!' do diff --git a/spec/policies/account_moderation_note_policy_spec.rb b/spec/policies/account_moderation_note_policy_spec.rb index 8467473465..8c37acc39f 100644 --- a/spec/policies/account_moderation_note_policy_spec.rb +++ b/spec/policies/account_moderation_note_policy_spec.rb @@ -4,20 +4,21 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe AccountModerationNotePolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :create? do - context 'staff' do + context 'when staff' do it 'grants to create' do - expect(subject).to permit(admin, AccountModerationNotePolicy) + expect(subject).to permit(admin, described_class) end end - context 'not staff' do + context 'when not staff' do it 'denies to create' do - expect(subject).to_not permit(john, AccountModerationNotePolicy) + expect(subject).to_not permit(john, described_class) end end end @@ -29,19 +30,19 @@ RSpec.describe AccountModerationNotePolicy do target_account: Fabricate(:account)) end - context 'admin' do + context 'when admin' do it 'grants to destroy' do expect(subject).to permit(admin, account_moderation_note) end end - context 'owner' do + context 'when owner' do it 'grants to destroy' do expect(subject).to permit(john, account_moderation_note) end end - context 'neither admin nor owner' do + context 'when neither admin nor owner' do let(:kevin) { Fabricate(:account) } it 'denies to destroy' do diff --git a/spec/policies/account_policy_spec.rb b/spec/policies/account_policy_spec.rb index 0f23fd97e2..d7a21d8e39 100644 --- a/spec/policies/account_policy_spec.rb +++ b/spec/policies/account_policy_spec.rb @@ -4,19 +4,20 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe AccountPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } let(:alice) { Fabricate(:account) } permissions :index? do - context 'staff' do + context 'when staff' do it 'permits' do expect(subject).to permit(admin) end end - context 'not staff' do + context 'when not staff' do it 'denies' do expect(subject).to_not permit(john) end @@ -24,13 +25,13 @@ RSpec.describe AccountPolicy do end permissions :show?, :unsilence?, :unsensitive?, :remove_avatar?, :remove_header? do - context 'staff' do + context 'when staff' do it 'permits' do expect(subject).to permit(admin, alice) end end - context 'not staff' do + context 'when not staff' do it 'denies' do expect(subject).to_not permit(john, alice) end @@ -42,13 +43,13 @@ RSpec.describe AccountPolicy do alice.suspend! end - context 'staff' do + context 'when staff' do it 'permits' do expect(subject).to permit(admin, alice) end end - context 'not staff' do + context 'when not staff' do it 'denies' do expect(subject).to_not permit(john, alice) end @@ -56,13 +57,13 @@ RSpec.describe AccountPolicy do end permissions :redownload? do - context 'admin' do + context 'when admin' do it 'permits' do expect(subject).to permit(admin) end end - context 'not admin' do + context 'when not admin' do it 'denies' do expect(subject).to_not permit(john) end @@ -72,21 +73,21 @@ RSpec.describe AccountPolicy do permissions :suspend?, :silence? do let(:staff) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } - context 'staff' do - context 'record is staff' do + context 'when staff' do + context 'when record is staff' do it 'denies' do expect(subject).to_not permit(admin, staff) end end - context 'record is not staff' do + context 'when record is not staff' do it 'permits' do expect(subject).to permit(admin, john) end end end - context 'not staff' do + context 'when not staff' do it 'denies' do expect(subject).to_not permit(john, Account) end @@ -96,24 +97,64 @@ RSpec.describe AccountPolicy do permissions :memorialize? do let(:other_admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } - context 'admin' do - context 'record is admin' do + context 'when admin' do + context 'when record is admin' do it 'denies' do expect(subject).to_not permit(admin, other_admin) end end - context 'record is not admin' do + context 'when record is not admin' do it 'permits' do expect(subject).to permit(admin, john) end end end - context 'not admin' do + context 'when not admin' do it 'denies' do expect(subject).to_not permit(john, Account) end end end + + permissions :review? do + context 'when admin' do + it 'permits' do + expect(subject).to permit(admin) + end + end + + context 'when not admin' do + it 'denies' do + expect(subject).to_not permit(john) + end + end + end + + permissions :destroy? do + context 'when admin' do + context 'with a temporarily suspended account' do + before { allow(alice).to receive(:suspended_temporarily?).and_return(true) } + + it 'permits' do + expect(subject).to permit(admin, alice) + end + end + + context 'with a not temporarily suspended account' do + before { allow(alice).to receive(:suspended_temporarily?).and_return(false) } + + it 'denies' do + expect(subject).to_not permit(admin, alice) + end + end + end + + context 'when not admin' do + it 'denies' do + expect(subject).to_not permit(john, alice) + end + end + end end diff --git a/spec/policies/account_warning_preset_policy_spec.rb b/spec/policies/account_warning_preset_policy_spec.rb new file mode 100644 index 0000000000..63bf33de24 --- /dev/null +++ b/spec/policies/account_warning_preset_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe AccountWarningPresetPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :create?, :update?, :destroy? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/admin/status_policy_spec.rb b/spec/policies/admin/status_policy_spec.rb new file mode 100644 index 0000000000..af9f7716be --- /dev/null +++ b/spec/policies/admin/status_policy_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe Admin::StatusPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + let(:status) { Fabricate(:status, visibility: status_visibility) } + let(:status_visibility) { :public } + + permissions :index?, :update?, :review?, :destroy? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end + + permissions :show? do + context 'with an admin' do + context 'with a public visible status' do + let(:status_visibility) { :public } + + it 'permits' do + expect(policy).to permit(admin, status) + end + end + + context 'with a not public visible status' do + let(:status_visibility) { :direct } + + it 'denies' do + expect(policy).to_not permit(admin, status) + end + + context 'when the status mentions the admin' do + before do + status.mentions.create!(account: admin) + end + + it 'permits' do + expect(policy).to permit(admin, status) + end + end + end + end + + context 'with a non admin' do + it 'denies' do + expect(policy).to_not permit(john, status) + end + end + end +end diff --git a/spec/policies/announcement_policy_spec.rb b/spec/policies/announcement_policy_spec.rb new file mode 100644 index 0000000000..3d230b3cb4 --- /dev/null +++ b/spec/policies/announcement_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe AnnouncementPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :create?, :update?, :destroy? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/appeal_policy_spec.rb b/spec/policies/appeal_policy_spec.rb new file mode 100644 index 0000000000..d7498eb9f0 --- /dev/null +++ b/spec/policies/appeal_policy_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe AppealPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + let(:appeal) { Fabricate(:appeal) } + + permissions :index? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end + + permissions :reject? do + context 'with an admin' do + context 'with a pending appeal' do + before { allow(appeal).to receive(:pending?).and_return(true) } + + it 'permits' do + expect(policy).to permit(admin, appeal) + end + end + + context 'with a not pending appeal' do + before { allow(appeal).to receive(:pending?).and_return(false) } + + it 'denies' do + expect(policy).to_not permit(admin, appeal) + end + end + end + + context 'with a non admin' do + it 'denies' do + expect(policy).to_not permit(john, appeal) + end + end + end +end diff --git a/spec/policies/backup_policy_spec.rb b/spec/policies/backup_policy_spec.rb index 6b31c6f7c7..28cb65d789 100644 --- a/spec/policies/backup_policy_spec.rb +++ b/spec/policies/backup_policy_spec.rb @@ -4,24 +4,25 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe BackupPolicy do - let(:subject) { described_class } - let(:john) { Fabricate(:account) } + subject { described_class } + + let(:john) { Fabricate(:account) } permissions :create? do - context 'not user_signed_in?' do + context 'when not user_signed_in?' do it 'denies' do expect(subject).to_not permit(nil, Backup) end end - context 'user_signed_in?' do - context 'no backups' do + context 'when user_signed_in?' do + context 'with no backups' do it 'permits' do expect(subject).to permit(john, Backup) end end - context 'backups are too old' do + context 'when backups are too old' do it 'permits' do travel(-8.days) do Fabricate(:backup, user: john.user) @@ -31,7 +32,7 @@ RSpec.describe BackupPolicy do end end - context 'backups are newer' do + context 'when backups are newer' do it 'denies' do travel(-3.days) do Fabricate(:backup, user: john.user) diff --git a/spec/policies/canonical_email_block_policy_spec.rb b/spec/policies/canonical_email_block_policy_spec.rb new file mode 100644 index 0000000000..0e55febfa9 --- /dev/null +++ b/spec/policies/canonical_email_block_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe CanonicalEmailBlockPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :show?, :test?, :create?, :destroy? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/custom_emoji_policy_spec.rb b/spec/policies/custom_emoji_policy_spec.rb index 6a6ef6694d..cb869c7d9a 100644 --- a/spec/policies/custom_emoji_policy_spec.rb +++ b/spec/policies/custom_emoji_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe CustomEmojiPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :index?, :enable?, :disable? do - context 'staff' do + context 'when staff' do it 'permits' do expect(subject).to permit(admin, CustomEmoji) end end - context 'not staff' do + context 'when not staff' do it 'denies' do expect(subject).to_not permit(john, CustomEmoji) end @@ -23,13 +24,13 @@ RSpec.describe CustomEmojiPolicy do end permissions :create?, :update?, :copy?, :destroy? do - context 'admin' do + context 'when admin' do it 'permits' do expect(subject).to permit(admin, CustomEmoji) end end - context 'not admin' do + context 'when not admin' do it 'denies' do expect(subject).to_not permit(john, CustomEmoji) end diff --git a/spec/policies/delivery_policy_spec.rb b/spec/policies/delivery_policy_spec.rb new file mode 100644 index 0000000000..fbcbf390d7 --- /dev/null +++ b/spec/policies/delivery_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe DeliveryPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :clear_delivery_errors?, :restart_delivery?, :stop_delivery? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/domain_block_policy_spec.rb b/spec/policies/domain_block_policy_spec.rb index 01b97e823a..4c89f3f374 100644 --- a/spec/policies/domain_block_policy_spec.rb +++ b/spec/policies/domain_block_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe DomainBlockPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :index?, :show?, :create?, :destroy? do - context 'admin' do + context 'when admin' do it 'permits' do expect(subject).to permit(admin, DomainBlock) end end - context 'not admin' do + context 'when not admin' do it 'denies' do expect(subject).to_not permit(john, DomainBlock) end diff --git a/spec/policies/email_domain_block_policy_spec.rb b/spec/policies/email_domain_block_policy_spec.rb index 913075c3d2..7ecff4be49 100644 --- a/spec/policies/email_domain_block_policy_spec.rb +++ b/spec/policies/email_domain_block_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe EmailDomainBlockPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } - permissions :index?, :create?, :destroy? do - context 'admin' do + permissions :index?, :show?, :create?, :destroy? do + context 'when admin' do it 'permits' do expect(subject).to permit(admin, EmailDomainBlock) end end - context 'not admin' do + context 'when not admin' do it 'denies' do expect(subject).to_not permit(john, EmailDomainBlock) end diff --git a/spec/policies/follow_recommendation_policy_spec.rb b/spec/policies/follow_recommendation_policy_spec.rb new file mode 100644 index 0000000000..01f4da0be2 --- /dev/null +++ b/spec/policies/follow_recommendation_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe FollowRecommendationPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :show?, :suppress?, :unsuppress? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/instance_policy_spec.rb b/spec/policies/instance_policy_spec.rb index f6f51af068..a0d9a008b7 100644 --- a/spec/policies/instance_policy_spec.rb +++ b/spec/policies/instance_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe InstancePolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :index?, :show?, :destroy? do - context 'admin' do + context 'when admin' do it 'permits' do expect(subject).to permit(admin, Instance) end end - context 'not admin' do + context 'when not admin' do it 'denies' do expect(subject).to_not permit(john, Instance) end diff --git a/spec/policies/invite_policy_spec.rb b/spec/policies/invite_policy_spec.rb index 01660322f1..cbe3735d80 100644 --- a/spec/policies/invite_policy_spec.rb +++ b/spec/policies/invite_policy_spec.rb @@ -4,12 +4,13 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe InvitePolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:user).account } permissions :index? do - context 'staff?' do + context 'when staff?' do it 'permits' do expect(subject).to permit(admin, Invite) end @@ -17,7 +18,7 @@ RSpec.describe InvitePolicy do end permissions :create? do - context 'has privilege' do + context 'with privilege' do before do UserRole.everyone.update(permissions: UserRole::FLAGS[:invite_users]) end @@ -27,7 +28,7 @@ RSpec.describe InvitePolicy do end end - context 'does not have privilege' do + context 'when does not have privilege' do before do UserRole.everyone.update(permissions: UserRole::Flags::NONE) end @@ -39,13 +40,13 @@ RSpec.describe InvitePolicy do end permissions :deactivate_all? do - context 'admin?' do + context 'when admin?' do it 'permits' do expect(subject).to permit(admin, Invite) end end - context 'not admin?' do + context 'when not admin?' do it 'denies' do expect(subject).to_not permit(john, Invite) end @@ -53,20 +54,20 @@ RSpec.describe InvitePolicy do end permissions :destroy? do - context 'owner?' do + context 'when owner?' do it 'permits' do expect(subject).to permit(john, Fabricate(:invite, user: john.user)) end end - context 'not owner?' do - context 'admin?' do + context 'when not owner?' do + context 'when admin?' do it 'permits' do expect(subject).to permit(admin, Fabricate(:invite)) end end - context 'not admin?' do + context 'when not admin?' do it 'denies' do expect(subject).to_not permit(john, Fabricate(:invite)) end diff --git a/spec/policies/ip_block_policy_spec.rb b/spec/policies/ip_block_policy_spec.rb new file mode 100644 index 0000000000..3cfa85863c --- /dev/null +++ b/spec/policies/ip_block_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe IpBlockPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :show?, :create?, :update?, :destroy? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/preview_card_policy_spec.rb b/spec/policies/preview_card_policy_spec.rb new file mode 100644 index 0000000000..d6675c5b34 --- /dev/null +++ b/spec/policies/preview_card_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe PreviewCardPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :review? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/preview_card_provider_policy_spec.rb b/spec/policies/preview_card_provider_policy_spec.rb new file mode 100644 index 0000000000..8d3715de95 --- /dev/null +++ b/spec/policies/preview_card_provider_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe PreviewCardProviderPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :review? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/relay_policy_spec.rb b/spec/policies/relay_policy_spec.rb index 2c50ba1e9f..29ba02c26a 100644 --- a/spec/policies/relay_policy_spec.rb +++ b/spec/policies/relay_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe RelayPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :update? do - context 'admin?' do + context 'when admin?' do it 'permits' do expect(subject).to permit(admin, Relay) end end - context '!admin?' do + context 'with !admin?' do it 'denies' do expect(subject).to_not permit(john, Relay) end diff --git a/spec/policies/report_note_policy_spec.rb b/spec/policies/report_note_policy_spec.rb index 99f5ffb8e3..b40a878887 100644 --- a/spec/policies/report_note_policy_spec.rb +++ b/spec/policies/report_note_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe ReportNotePolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :create? do - context 'staff?' do + context 'when staff?' do it 'permits' do expect(subject).to permit(admin, ReportNote) end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, ReportNote) end @@ -23,26 +24,24 @@ RSpec.describe ReportNotePolicy do end permissions :destroy? do - context 'admin?' do + context 'when admin?' do it 'permit' do report_note = Fabricate(:report_note, account: john) expect(subject).to permit(admin, report_note) end end - context 'admin?' do - context 'owner?' do - it 'permit' do - report_note = Fabricate(:report_note, account: john) - expect(subject).to permit(john, report_note) - end + context 'when owner?' do + it 'permit' do + report_note = Fabricate(:report_note, account: john) + expect(subject).to permit(john, report_note) end + end - context '!owner?' do - it 'denies' do - report_note = Fabricate(:report_note) - expect(subject).to_not permit(john, report_note) - end + context 'with !owner?' do + it 'denies' do + report_note = Fabricate(:report_note) + expect(subject).to_not permit(john, report_note) end end end diff --git a/spec/policies/report_policy_spec.rb b/spec/policies/report_policy_spec.rb index 8b005d8ddd..4fc4178075 100644 --- a/spec/policies/report_policy_spec.rb +++ b/spec/policies/report_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe ReportPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :update?, :index?, :show? do - context 'staff?' do + context 'when staff?' do it 'permits' do expect(subject).to permit(admin, Report) end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, Report) end diff --git a/spec/policies/rule_policy_spec.rb b/spec/policies/rule_policy_spec.rb new file mode 100644 index 0000000000..0e45f6df02 --- /dev/null +++ b/spec/policies/rule_policy_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe RulePolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :create?, :update?, :destroy? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Tag) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Tag) + end + end + end +end diff --git a/spec/policies/settings_policy_spec.rb b/spec/policies/settings_policy_spec.rb index e16ee51a48..4a99314905 100644 --- a/spec/policies/settings_policy_spec.rb +++ b/spec/policies/settings_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe SettingsPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } - permissions :update?, :show? do - context 'admin?' do + permissions :update?, :show?, :destroy? do + context 'when admin?' do it 'permits' do expect(subject).to permit(admin, Settings) end end - context '!admin?' do + context 'with !admin?' do it 'denies' do expect(subject).to_not permit(john, Settings) end diff --git a/spec/policies/software_update_policy_spec.rb b/spec/policies/software_update_policy_spec.rb new file mode 100644 index 0000000000..e19ba61612 --- /dev/null +++ b/spec/policies/software_update_policy_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +RSpec.describe SoftwareUpdatePolicy do + subject { described_class } + + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Owner')).account } + let(:john) { Fabricate(:account) } + + permissions :index? do + context 'when owner' do + it 'permits' do + expect(subject).to permit(admin, SoftwareUpdate) + end + end + + context 'when not owner' do + it 'denies' do + expect(subject).to_not permit(john, SoftwareUpdate) + end + end + end +end diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb index b88521708a..725bd0bbb3 100644 --- a/spec/policies/status_policy_spec.rb +++ b/spec/policies/status_policy_spec.rb @@ -11,119 +11,151 @@ RSpec.describe StatusPolicy, type: :model do let(:bob) { Fabricate(:account, username: 'bob') } let(:status) { Fabricate(:status, account: alice) } - permissions :show?, :reblog? do - it 'grants access when no viewer' do - expect(subject).to permit(nil, status) - end + context 'with the permissions of show? and reblog?' do + permissions :show?, :reblog? do + it 'grants access when no viewer' do + expect(subject).to permit(nil, status) + end - it 'denies access when viewer is blocked' do - block = Fabricate(:block) - status.visibility = :private - status.account = block.target_account + it 'denies access when viewer is blocked' do + block = Fabricate(:block) + status.visibility = :private + status.account = block.target_account - expect(subject).to_not permit(block.account, status) + expect(subject).to_not permit(block.account, status) + end end end - permissions :show? do - it 'grants access when direct and account is viewer' do - status.visibility = :direct + context 'with the permission of show?' do + permissions :show? do + it 'grants access when direct and account is viewer' do + status.visibility = :direct - expect(subject).to permit(status.account, status) - end + expect(subject).to permit(status.account, status) + end - it 'grants access when direct and viewer is mentioned' do - status.visibility = :direct - status.mentions = [Fabricate(:mention, account: alice)] + it 'grants access when direct and viewer is mentioned' do + status.visibility = :direct + status.mentions = [Fabricate(:mention, account: alice)] - expect(subject).to permit(alice, status) - end + expect(subject).to permit(alice, status) + end - it 'denies access when direct and viewer is not mentioned' do - viewer = Fabricate(:account) - status.visibility = :direct + it 'grants access when direct and non-owner viewer is mentioned and mentions are loaded' do + status.visibility = :direct + status.mentions = [Fabricate(:mention, account: bob)] + status.mentions.load - expect(subject).to_not permit(viewer, status) - end + expect(subject).to permit(bob, status) + end - it 'grants access when private and account is viewer' do - status.visibility = :private + it 'denies access when direct and viewer is not mentioned' do + viewer = Fabricate(:account) + status.visibility = :direct - expect(subject).to permit(status.account, status) - end + expect(subject).to_not permit(viewer, status) + end - it 'grants access when private and account is following viewer' do - follow = Fabricate(:follow) - status.visibility = :private - status.account = follow.target_account + it 'grants access when private and account is viewer' do + status.visibility = :private - expect(subject).to permit(follow.account, status) - end + expect(subject).to permit(status.account, status) + end - it 'grants access when private and viewer is mentioned' do - status.visibility = :private - status.mentions = [Fabricate(:mention, account: alice)] + it 'grants access when private and account is following viewer' do + follow = Fabricate(:follow) + status.visibility = :private + status.account = follow.target_account - expect(subject).to permit(alice, status) - end + expect(subject).to permit(follow.account, status) + end - it 'denies access when private and viewer is not mentioned or followed' do - viewer = Fabricate(:account) - status.visibility = :private + it 'grants access when private and viewer is mentioned' do + status.visibility = :private + status.mentions = [Fabricate(:mention, account: alice)] - expect(subject).to_not permit(viewer, status) + expect(subject).to permit(alice, status) + end + + it 'denies access when private and viewer is not mentioned or followed' do + viewer = Fabricate(:account) + status.visibility = :private + + expect(subject).to_not permit(viewer, status) + end + + it 'denies access when local-only and the viewer is not logged in' do + allow(status).to receive(:local_only?).and_return(true) + + expect(subject).to_not permit(nil, status) + end + + it 'denies access when local-only and the viewer is from another domain' do + viewer = Fabricate(:account, domain: 'remote-domain') + allow(status).to receive(:local_only?).and_return(true) + expect(subject).to_not permit(viewer, status) + end end end - permissions :reblog? do - it 'denies access when private' do - viewer = Fabricate(:account) - status.visibility = :private + context 'with the permission of reblog?' do + permissions :reblog? do + it 'denies access when private' do + viewer = Fabricate(:account) + status.visibility = :private - expect(subject).to_not permit(viewer, status) - end + expect(subject).to_not permit(viewer, status) + end - it 'denies access when direct' do - viewer = Fabricate(:account) - status.visibility = :direct + it 'denies access when direct' do + viewer = Fabricate(:account) + status.visibility = :direct - expect(subject).to_not permit(viewer, status) + expect(subject).to_not permit(viewer, status) + end end end - permissions :destroy?, :unreblog? do - it 'grants access when account is deleter' do - expect(subject).to permit(status.account, status) - end + context 'with the permissions of destroy? and unreblog?' do + permissions :destroy?, :unreblog? do + it 'grants access when account is deleter' do + expect(subject).to permit(status.account, status) + end - it 'denies access when account is not deleter' do - expect(subject).to_not permit(bob, status) - end + it 'denies access when account is not deleter' do + expect(subject).to_not permit(bob, status) + end - it 'denies access when no deleter' do - expect(subject).to_not permit(nil, status) + it 'denies access when no deleter' do + expect(subject).to_not permit(nil, status) + end end end - permissions :favourite? do - it 'grants access when viewer is not blocked' do - follow = Fabricate(:follow) - status.account = follow.target_account + context 'with the permission of favourite?' do + permissions :favourite? do + it 'grants access when viewer is not blocked' do + follow = Fabricate(:follow) + status.account = follow.target_account - expect(subject).to permit(follow.account, status) - end + expect(subject).to permit(follow.account, status) + end - it 'denies when viewer is blocked' do - block = Fabricate(:block) - status.account = block.target_account + it 'denies when viewer is blocked' do + block = Fabricate(:block) + status.account = block.target_account - expect(subject).to_not permit(block.account, status) + expect(subject).to_not permit(block.account, status) + end end end - permissions :update? do - it 'grants access if owner' do - expect(subject).to permit(status.account, status) + context 'with the permission of update?' do + permissions :update? do + it 'grants access if owner' do + expect(subject).to permit(status.account, status) + end end end end diff --git a/spec/policies/tag_policy_spec.rb b/spec/policies/tag_policy_spec.rb index 9be7140fc2..35da3cc62a 100644 --- a/spec/policies/tag_policy_spec.rb +++ b/spec/policies/tag_policy_spec.rb @@ -4,18 +4,19 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe TagPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } - permissions :index?, :show?, :update? do - context 'staff?' do + permissions :index?, :show?, :update?, :review? do + context 'when staff?' do it 'permits' do expect(subject).to permit(admin, Tag) end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, Tag) end diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb index ff0916674e..fa476a9fc3 100644 --- a/spec/policies/user_policy_spec.rb +++ b/spec/policies/user_policy_spec.rb @@ -4,26 +4,27 @@ require 'rails_helper' require 'pundit/rspec' RSpec.describe UserPolicy do - let(:subject) { described_class } + subject { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } let(:john) { Fabricate(:account) } permissions :reset_password?, :change_email? do - context 'staff?' do - context '!record.staff?' do + context 'when staff?' do + context 'with !record.staff?' do it 'permits' do expect(subject).to permit(admin, john.user) end end - context 'record.staff?' do + context 'when record.staff?' do it 'denies' do expect(subject).to_not permit(admin, admin.user) end end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, User) end @@ -31,21 +32,21 @@ RSpec.describe UserPolicy do end permissions :disable_2fa? do - context 'admin?' do - context '!record.staff?' do + context 'when admin?' do + context 'with !record.staff?' do it 'permits' do expect(subject).to permit(admin, john.user) end end - context 'record.staff?' do + context 'when record.staff?' do it 'denies' do expect(subject).to_not permit(admin, admin.user) end end end - context '!admin?' do + context 'with !admin?' do it 'denies' do expect(subject).to_not permit(john, User) end @@ -53,15 +54,15 @@ RSpec.describe UserPolicy do end permissions :confirm? do - context 'staff?' do - context '!record.confirmed?' do + context 'when staff?' do + context 'with !record.confirmed?' do it 'permits' do john.user.update(confirmed_at: nil) expect(subject).to permit(admin, john.user) end end - context 'record.confirmed?' do + context 'when record.confirmed?' do it 'denies' do john.user.confirm! expect(subject).to_not permit(admin, john.user) @@ -69,7 +70,7 @@ RSpec.describe UserPolicy do end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, User) end @@ -77,13 +78,13 @@ RSpec.describe UserPolicy do end permissions :enable? do - context 'staff?' do + context 'when staff?' do it 'permits' do expect(subject).to permit(admin, User) end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, User) end @@ -91,21 +92,21 @@ RSpec.describe UserPolicy do end permissions :disable? do - context 'staff?' do - context '!record.admin?' do + context 'when staff?' do + context 'with !record.admin?' do it 'permits' do expect(subject).to permit(admin, john.user) end end - context 'record.admin?' do + context 'when record.admin?' do it 'denies' do expect(subject).to_not permit(admin, admin.user) end end end - context '!staff?' do + context 'with !staff?' do it 'denies' do expect(subject).to_not permit(john, User) end diff --git a/spec/policies/webhook_policy_spec.rb b/spec/policies/webhook_policy_spec.rb new file mode 100644 index 0000000000..909311461a --- /dev/null +++ b/spec/policies/webhook_policy_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'pundit/rspec' + +describe WebhookPolicy do + let(:policy) { described_class } + let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account } + let(:john) { Fabricate(:account) } + + permissions :index?, :create? do + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, Webhook) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, Webhook) + end + end + end + + permissions :show?, :update?, :enable?, :disable?, :rotate_secret?, :destroy? do + let(:webhook) { Fabricate(:webhook, events: ['account.created', 'report.created']) } + + context 'with an admin' do + it 'permits' do + expect(policy).to permit(admin, webhook) + end + end + + context 'with a non-admin' do + it 'denies' do + expect(policy).to_not permit(john, webhook) + end + end + end +end diff --git a/spec/presenters/account_relationships_presenter_spec.rb b/spec/presenters/account_relationships_presenter_spec.rb index 8a485d2b9a..5c2ba54e00 100644 --- a/spec/presenters/account_relationships_presenter_spec.rb +++ b/spec/presenters/account_relationships_presenter_spec.rb @@ -14,12 +14,12 @@ RSpec.describe AccountRelationshipsPresenter do allow(Account).to receive(:domain_blocking_map).with(account_ids, current_account_id).and_return(default_map) end - let(:presenter) { AccountRelationshipsPresenter.new(account_ids, current_account_id, **options) } + let(:presenter) { described_class.new(account_ids, current_account_id, **options) } let(:current_account_id) { Fabricate(:account).id } let(:account_ids) { [Fabricate(:account).id] } let(:default_map) { { 1 => true } } - context 'options are not set' do + context 'when options are not set' do let(:options) { {} } it 'sets default maps' do @@ -32,7 +32,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:following_map] is set' do + context 'when options[:following_map] is set' do let(:options) { { following_map: { 2 => true } } } it 'sets @following merged with default_map and options[:following_map]' do @@ -40,7 +40,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:followed_by_map] is set' do + context 'when options[:followed_by_map] is set' do let(:options) { { followed_by_map: { 3 => true } } } it 'sets @followed_by merged with default_map and options[:followed_by_map]' do @@ -48,7 +48,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:blocking_map] is set' do + context 'when options[:blocking_map] is set' do let(:options) { { blocking_map: { 4 => true } } } it 'sets @blocking merged with default_map and options[:blocking_map]' do @@ -56,7 +56,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:muting_map] is set' do + context 'when options[:muting_map] is set' do let(:options) { { muting_map: { 5 => true } } } it 'sets @muting merged with default_map and options[:muting_map]' do @@ -64,7 +64,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:requested_map] is set' do + context 'when options[:requested_map] is set' do let(:options) { { requested_map: { 6 => true } } } it 'sets @requested merged with default_map and options[:requested_map]' do @@ -72,7 +72,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:requested_by_map] is set' do + context 'when options[:requested_by_map] is set' do let(:options) { { requested_by_map: { 6 => true } } } it 'sets @requested merged with default_map and options[:requested_by_map]' do @@ -80,7 +80,7 @@ RSpec.describe AccountRelationshipsPresenter do end end - context 'options[:domain_blocking_map] is set' do + context 'when options[:domain_blocking_map] is set' do let(:options) { { domain_blocking_map: { 7 => true } } } it 'sets @domain_blocking merged with default_map and options[:domain_blocking_map]' do diff --git a/spec/presenters/familiar_followers_presenter_spec.rb b/spec/presenters/familiar_followers_presenter_spec.rb index 17be4b9715..c21ffd36ec 100644 --- a/spec/presenters/familiar_followers_presenter_spec.rb +++ b/spec/presenters/familiar_followers_presenter_spec.rb @@ -4,12 +4,12 @@ require 'rails_helper' RSpec.describe FamiliarFollowersPresenter do describe '#accounts' do + subject { described_class.new(requested_accounts, account.id) } + let(:account) { Fabricate(:account) } let(:familiar_follower) { Fabricate(:account) } let(:requested_accounts) { Fabricate.times(2, :account) } - subject { described_class.new(requested_accounts, account.id) } - before do familiar_follower.follow!(requested_accounts.first) account.follow!(familiar_follower) @@ -24,7 +24,7 @@ RSpec.describe FamiliarFollowersPresenter do expect(result).to_not be_nil expect(result.id).to eq requested_accounts.first.id - expect(result.accounts).to match_array([familiar_follower]) + expect(result.accounts).to contain_exactly(familiar_follower) end context 'when requested account hides followers' do diff --git a/spec/presenters/instance_presenter_spec.rb b/spec/presenters/instance_presenter_spec.rb index 659c2cc2ff..f20dce5931 100644 --- a/spec/presenters/instance_presenter_spec.rb +++ b/spec/presenters/instance_presenter_spec.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' describe InstancePresenter do - let(:instance_presenter) { InstancePresenter.new } + let(:instance_presenter) { described_class.new } describe '#description' do around do |example| @@ -10,9 +12,9 @@ describe InstancePresenter do Setting.site_short_description = site_description end - it "delegates site_description to Setting" do - Setting.site_short_description = "Site desc" - expect(instance_presenter.description).to eq "Site desc" + it 'delegates site_description to Setting' do + Setting.site_short_description = 'Site desc' + expect(instance_presenter.description).to eq 'Site desc' end end @@ -23,9 +25,9 @@ describe InstancePresenter do Setting.site_extended_description = site_extended_description end - it "delegates site_extended_description to Setting" do - Setting.site_extended_description = "Extended desc" - expect(instance_presenter.extended_description).to eq "Extended desc" + it 'delegates site_extended_description to Setting' do + Setting.site_extended_description = 'Extended desc' + expect(instance_presenter.extended_description).to eq 'Extended desc' end end @@ -36,9 +38,9 @@ describe InstancePresenter do Setting.site_contact_email = site_contact_email end - it "delegates contact_email to Setting" do - Setting.site_contact_email = "admin@example.com" - expect(instance_presenter.contact.email).to eq "admin@example.com" + it 'delegates contact_email to Setting' do + Setting.site_contact_email = 'admin@example.com' + expect(instance_presenter.contact.email).to eq 'admin@example.com' end end @@ -49,15 +51,15 @@ describe InstancePresenter do Setting.site_contact_username = site_contact_username end - it "returns the account for the site contact username" do - Setting.site_contact_username = "aaa" - account = Fabricate(:account, username: "aaa") + it 'returns the account for the site contact username' do + Setting.site_contact_username = 'aaa' + account = Fabricate(:account, username: 'aaa') expect(instance_presenter.contact.account).to eq(account) end end describe '#user_count' do - it "returns the number of site users" do + it 'returns the number of site users' do Rails.cache.write 'user_count', 123 expect(instance_presenter.user_count).to eq(123) @@ -65,7 +67,7 @@ describe InstancePresenter do end describe '#status_count' do - it "returns the number of local statuses" do + it 'returns the number of local statuses' do Rails.cache.write 'local_status_count', 234 expect(instance_presenter.status_count).to eq(234) @@ -73,7 +75,7 @@ describe InstancePresenter do end describe '#domain_count' do - it "returns the number of known domains" do + it 'returns the number of known domains' do Rails.cache.write 'distinct_domain_count', 345 expect(instance_presenter.domain_count).to eq(345) @@ -87,8 +89,28 @@ describe InstancePresenter do end describe '#source_url' do - it 'returns "https://github.com/mastodon/mastodon"' do - expect(instance_presenter.source_url).to eq('https://github.com/mastodon/mastodon') + context 'with the GITHUB_REPOSITORY env variable set' do + around do |example| + ClimateControl.modify GITHUB_REPOSITORY: 'other/repo' do + example.run + end + end + + it 'uses the env variable to build a repo URL' do + expect(instance_presenter.source_url).to eq('https://github.com/other/repo') + end + end + + context 'without the GITHUB_REPOSITORY env variable set' do + around do |example| + ClimateControl.modify GITHUB_REPOSITORY: nil do + example.run + end + end + + it 'defaults to the core glitch-soc repo URL' do + expect(instance_presenter.source_url).to eq('https://github.com/glitch-soc/mastodon') + end end end diff --git a/spec/presenters/status_relationships_presenter_spec.rb b/spec/presenters/status_relationships_presenter_spec.rb index eaab922fd9..7746c8cd78 100644 --- a/spec/presenters/status_relationships_presenter_spec.rb +++ b/spec/presenters/status_relationships_presenter_spec.rb @@ -12,13 +12,13 @@ RSpec.describe StatusRelationshipsPresenter do allow(Status).to receive(:pins_map).with(anything, current_account_id).and_return(default_map) end - let(:presenter) { StatusRelationshipsPresenter.new(statuses, current_account_id, **options) } + let(:presenter) { described_class.new(statuses, current_account_id, **options) } let(:current_account_id) { Fabricate(:account).id } let(:statuses) { [Fabricate(:status)] } - let(:status_ids) { statuses.map(&:id) + statuses.map(&:reblog_of_id).compact } + let(:status_ids) { statuses.map(&:id) + statuses.filter_map(&:reblog_of_id) } let(:default_map) { { 1 => true } } - context 'options are not set' do + context 'when options are not set' do let(:options) { {} } it 'sets default maps' do @@ -30,7 +30,7 @@ RSpec.describe StatusRelationshipsPresenter do end end - context 'options[:reblogs_map] is set' do + context 'when options[:reblogs_map] is set' do let(:options) { { reblogs_map: { 2 => true } } } it 'sets @reblogs_map merged with default_map and options[:reblogs_map]' do @@ -38,7 +38,7 @@ RSpec.describe StatusRelationshipsPresenter do end end - context 'options[:favourites_map] is set' do + context 'when options[:favourites_map] is set' do let(:options) { { favourites_map: { 3 => true } } } it 'sets @favourites_map merged with default_map and options[:favourites_map]' do @@ -46,7 +46,7 @@ RSpec.describe StatusRelationshipsPresenter do end end - context 'options[:bookmarks_map] is set' do + context 'when options[:bookmarks_map] is set' do let(:options) { { bookmarks_map: { 4 => true } } } it 'sets @bookmarks_map merged with default_map and options[:bookmarks_map]' do @@ -54,7 +54,7 @@ RSpec.describe StatusRelationshipsPresenter do end end - context 'options[:mutes_map] is set' do + context 'when options[:mutes_map] is set' do let(:options) { { mutes_map: { 5 => true } } } it 'sets @mutes_map merged with default_map and options[:mutes_map]' do @@ -62,7 +62,7 @@ RSpec.describe StatusRelationshipsPresenter do end end - context 'options[:pins_map] is set' do + context 'when options[:pins_map] is set' do let(:options) { { pins_map: { 6 => true } } } it 'sets @pins_map merged with default_map and options[:pins_map]' do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index c197bc0075..7b8dccb6a0 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,21 +1,43 @@ +# frozen_string_literal: true + ENV['RAILS_ENV'] ||= 'test' + +# This needs to be defined before Rails is initialized +RUN_SYSTEM_SPECS = ENV.fetch('RUN_SYSTEM_SPECS', false) +RUN_SEARCH_SPECS = ENV.fetch('RUN_SEARCH_SPECS', false) + +if RUN_SYSTEM_SPECS + STREAMING_PORT = ENV.fetch('TEST_STREAMING_PORT', '4020') + ENV['STREAMING_API_BASE_URL'] = "http://localhost:#{STREAMING_PORT}" +end + +if RUN_SEARCH_SPECS + # Include any configuration or setups specific to search tests here +end + require File.expand_path('../config/environment', __dir__) -abort("The Rails environment is running in production mode!") if Rails.env.production? +abort('The Rails environment is running in production mode!') if Rails.env.production? require 'spec_helper' require 'rspec/rails' require 'webmock/rspec' require 'paperclip/matchers' require 'capybara/rspec' +require 'chewy/rspec' -Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } +Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } ActiveRecord::Migration.maintain_test_schema! -WebMock.disable_net_connect!(allow: Chewy.settings[:host]) +WebMock.disable_net_connect!(allow: Chewy.settings[:host], allow_localhost: RUN_SYSTEM_SPECS) Sidekiq::Testing.inline! Sidekiq.logger = nil +# System tests config +DatabaseCleaner.strategy = [:deletion] +streaming_server_manager = StreamingServerManager.new +search_data_manager = SearchDataManager.new + Devise::Test::ControllerHelpers.module_eval do alias_method :original_sign_in, :sign_in @@ -32,22 +54,64 @@ Devise::Test::ControllerHelpers.module_eval do end end +module SignedRequestHelpers + def get(path, headers: nil, sign_with: nil, **args) + return super path, headers: headers, **args if sign_with.nil? + + headers ||= {} + headers['Date'] = Time.now.utc.httpdate + headers['Host'] = ENV.fetch('LOCAL_DOMAIN') + signed_headers = headers.merge('(request-target)' => "get #{path}").slice('(request-target)', 'Host', 'Date') + + key_id = ActivityPub::TagManager.instance.key_uri_for(sign_with) + keypair = sign_with.keypair + signed_string = signed_headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n") + signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string)) + + headers['Signature'] = "keyId=\"#{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\"" + + super path, headers: headers, **args + end +end + RSpec.configure do |config| - config.fixture_path = "#{::Rails.root}/spec/fixtures" + # This is set before running spec:system, see lib/tasks/tests.rake + config.filter_run_excluding type: lambda { |type| + case type + when :system + !RUN_SYSTEM_SPECS + when :search + !RUN_SEARCH_SPECS + end + } + config.fixture_path = Rails.root.join('spec', 'fixtures') config.use_transactional_fixtures = true config.order = 'random' config.infer_spec_type_from_file_location! config.filter_rails_from_backtrace! + config.define_derived_metadata(file_path: Regexp.new('spec/lib/mastodon/cli')) do |metadata| + metadata[:type] = :cli + end + config.include Devise::Test::ControllerHelpers, type: :controller + config.include Devise::Test::ControllerHelpers, type: :helper config.include Devise::Test::ControllerHelpers, type: :view + config.include Devise::Test::IntegrationHelpers, type: :feature + config.include Devise::Test::IntegrationHelpers, type: :request config.include Paperclip::Shoulda::Matchers config.include ActiveSupport::Testing::TimeHelpers + config.include Chewy::Rspec::Helpers config.include Redisable + config.include SignedRequestHelpers, type: :request + + config.before :each, type: :cli do + stub_stdout + stub_reset_connection_pools + end config.before :each, type: :feature do - https = ENV['LOCAL_HTTPS'] == 'true' - Capybara.app_host = "http#{https ? 's' : ''}://#{ENV.fetch('LOCAL_DOMAIN')}" + Capybara.current_driver = :rack_test end config.before :each, type: :controller do @@ -58,10 +122,66 @@ RSpec.configure do |config| stub_jsonld_contexts! end + config.before :suite do + if RUN_SYSTEM_SPECS + Webpacker.compile + streaming_server_manager.start(port: STREAMING_PORT) + end + + if RUN_SEARCH_SPECS + Chewy.strategy(:urgent) + search_data_manager.prepare_test_data + end + end + + config.after :suite do + streaming_server_manager.stop + + search_data_manager.cleanup_test_data if RUN_SEARCH_SPECS + end + + config.around :each, type: :system do |example| + # driven_by :selenium, using: :chrome, screen_size: [1600, 1200] + driven_by :selenium, using: :headless_chrome, screen_size: [1600, 1200] + + # The streaming server needs access to the database + # but with use_transactional_tests every transaction + # is rolled-back, so the streaming server never sees the data + # So we disable this feature for system tests, and use DatabaseCleaner to clean + # the database tables between each test + self.use_transactional_tests = false + + DatabaseCleaner.cleaning do + example.run + end + + self.use_transactional_tests = true + end + + config.around :each, type: :search do |example| + search_data_manager.populate_indexes + example.run + search_data_manager.remove_indexes + end + + config.before(:each) do |example| + unless example.metadata[:paperclip_processing] + allow_any_instance_of(Paperclip::Attachment).to receive(:post_process).and_return(true) # rubocop:disable RSpec/AnyInstance + end + end + config.after :each do Rails.cache.clear redis.del(redis.keys) end + + # Assign types based on dir name for non-inferred types + config.define_derived_metadata(file_path: %r{/spec/}) do |metadata| + unless metadata.key?(:type) + match = metadata[:location].match(%r{/spec/([^/]+)/}) + metadata[:type] = match[1].singularize.to_sym + end + end end RSpec::Sidekiq.configure do |config| @@ -71,11 +191,26 @@ end RSpec::Matchers.define_negated_matcher :not_change, :change def request_fixture(name) - File.read(Rails.root.join('spec', 'fixtures', 'requests', name)) + Rails.root.join('spec', 'fixtures', 'requests', name).read end def attachment_fixture(name) - File.open(Rails.root.join('spec', 'fixtures', 'files', name)) + Rails.root.join('spec', 'fixtures', 'files', name).open +end + +def stub_stdout + # TODO: Is there a bettery way to: + # - Avoid CLI command output being printed out + # - Allow rspec to assert things against STDOUT + # - Avoid disabling stdout for other desirable output (deprecation warnings, for example) + allow($stdout).to receive(:write) +end + +def stub_reset_connection_pools + # TODO: Is there a better way to correctly run specs without stubbing this? + # (Avoids reset_connection_pools! in test env) + allow(ActiveRecord::Base).to receive(:establish_connection) + allow(RedisConfiguration).to receive(:establish_pool) end def stub_jsonld_contexts! diff --git a/spec/requests/anonymous_cookies_spec.rb b/spec/requests/anonymous_cookies_spec.rb new file mode 100644 index 0000000000..427f54e449 --- /dev/null +++ b/spec/requests/anonymous_cookies_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'rails_helper' + +context 'when visited anonymously' do + around do |example| + old = ActionController::Base.allow_forgery_protection + ActionController::Base.allow_forgery_protection = true + + example.run + + ActionController::Base.allow_forgery_protection = old + end + + describe 'account pages' do + it 'do not set cookies' do + alice = Fabricate(:account, username: 'alice', display_name: 'Alice') + _status = Fabricate(:status, account: alice, text: 'Hello World') + + get '/@alice' + + expect(response.cookies).to be_empty + end + end + + describe 'status pages' do + it 'do not set cookies' do + alice = Fabricate(:account, username: 'alice', display_name: 'Alice') + status = Fabricate(:status, account: alice, text: 'Hello World') + + get short_account_status_url(alice, status) + + expect(response.cookies).to be_empty + end + end + + describe 'the /about page' do + it 'does not set cookies' do + get '/about' + + expect(response.cookies).to be_empty + end + end +end diff --git a/spec/requests/api/v1/accounts/credentials_spec.rb b/spec/requests/api/v1/accounts/credentials_spec.rb new file mode 100644 index 0000000000..b13e79b12b --- /dev/null +++ b/spec/requests/api/v1/accounts/credentials_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'credentials API' do + let(:user) { Fabricate(:user, account_attributes: { discoverable: false, locked: true, indexable: false }) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts write:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/accounts/verify_credentials' do + subject do + get '/api/v1/accounts/verify_credentials', headers: headers + end + + it_behaves_like 'forbidden for wrong scope', 'write write:accounts' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected content' do + subject + + expect(body_as_json).to include({ + source: hash_including({ + discoverable: false, + indexable: false, + }), + locked: true, + }) + end + end + + describe 'POST /api/v1/accounts/update_credentials' do + subject do + patch '/api/v1/accounts/update_credentials', headers: headers, params: params + end + + let(:params) { { discoverable: true, locked: false, indexable: true } } + + it_behaves_like 'forbidden for wrong scope', 'read read:accounts' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns JSON with updated attributes' do + subject + + expect(body_as_json).to include({ + source: hash_including({ + discoverable: true, + indexable: true, + }), + locked: false, + }) + end + end +end diff --git a/spec/requests/api/v1/accounts_show_spec.rb b/spec/requests/api/v1/accounts_show_spec.rb new file mode 100644 index 0000000000..ee6e925aa9 --- /dev/null +++ b/spec/requests/api/v1/accounts_show_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'GET /api/v1/accounts/{account_id}' do + it 'returns account entity as 200 OK' do + account = Fabricate(:account) + + get "/api/v1/accounts/#{account.id}" + + aggregate_failures do + expect(response).to have_http_status(200) + expect(body_as_json[:id]).to eq(account.id.to_s) + end + end + + it 'returns 404 if account not found' do + get '/api/v1/accounts/1' + + aggregate_failures do + expect(response).to have_http_status(404) + expect(body_as_json[:error]).to eq('Record not found') + end + end + + context 'when with token' do + it 'returns account entity as 200 OK if token is valid' do + account = Fabricate(:account) + user = Fabricate(:user, account: account) + token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts').token + + get "/api/v1/accounts/#{account.id}", headers: { Authorization: "Bearer #{token}" } + + aggregate_failures do + expect(response).to have_http_status(200) + expect(body_as_json[:id]).to eq(account.id.to_s) + end + end + + it 'returns 403 if scope of token is invalid' do + account = Fabricate(:account) + user = Fabricate(:user, account: account) + token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:statuses').token + + get "/api/v1/accounts/#{account.id}", headers: { Authorization: "Bearer #{token}" } + + aggregate_failures do + expect(response).to have_http_status(403) + expect(body_as_json[:error]).to eq('This action is outside the authorized scopes') + end + end + end +end diff --git a/spec/requests/api/v1/admin/account_actions_spec.rb b/spec/requests/api/v1/admin/account_actions_spec.rb new file mode 100644 index 0000000000..9295d262d6 --- /dev/null +++ b/spec/requests/api/v1/admin/account_actions_spec.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Account actions' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:write admin:write:accounts' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:mailer) { instance_double(ActionMailer::MessageDelivery, deliver_later!: nil) } + + before do + allow(UserMailer).to receive(:warning).with(target_account.user, anything).and_return(mailer) + end + + shared_examples 'a successful notification delivery' do + it 'notifies the user about the action taken' do + subject + + expect(UserMailer).to have_received(:warning).with(target_account.user, anything).once + expect(mailer).to have_received(:deliver_later!).once + end + end + + shared_examples 'a successful logged action' do |action_type, target_type| + it 'logs action' do + subject + + log_item = Admin::ActionLog.last + + expect(log_item).to be_present + expect(log_item.action).to eq(action_type) + expect(log_item.account_id).to eq(user.account_id) + expect(log_item.target_id).to eq(target_type == :user ? target_account.user.id : target_account.id) + end + end + + describe 'POST /api/v1/admin/accounts/:id/action' do + subject do + post "/api/v1/admin/accounts/#{target_account.id}/action", headers: headers, params: params + end + + let(:target_account) { Fabricate(:account) } + + context 'with type of disable' do + let(:params) { { type: 'disable' } } + + it_behaves_like 'forbidden for wrong scope', 'admin:read admin:read:accounts' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'a successful notification delivery' + it_behaves_like 'a successful logged action', :disable, :user + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'disables the target account' do + expect { subject }.to change { target_account.reload.user_disabled? }.from(false).to(true) + end + end + + context 'with type of sensitive' do + let(:params) { { type: 'sensitive' } } + + it_behaves_like 'forbidden for wrong scope', 'admin:read admin:read:accounts' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'a successful notification delivery' + it_behaves_like 'a successful logged action', :sensitive, :account + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'marks the target account as sensitive' do + expect { subject }.to change { target_account.reload.sensitized? }.from(false).to(true) + end + end + + context 'with type of silence' do + let(:params) { { type: 'silence' } } + + it_behaves_like 'forbidden for wrong scope', 'admin:read admin:read:accounts' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'a successful notification delivery' + it_behaves_like 'a successful logged action', :silence, :account + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'marks the target account as silenced' do + expect { subject }.to change { target_account.reload.silenced? }.from(false).to(true) + end + end + + context 'with type of suspend' do + let(:params) { { type: 'suspend' } } + + it_behaves_like 'forbidden for wrong scope', 'admin:read admin:read:accounts' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'a successful notification delivery' + it_behaves_like 'a successful logged action', :suspend, :account + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'marks the target account as suspended' do + expect { subject }.to change { target_account.reload.suspended? }.from(false).to(true) + end + end + + context 'with type of none' do + let(:params) { { type: 'none' } } + + it_behaves_like 'a successful notification delivery' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + + context 'with no type' do + let(:params) { {} } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'with invalid type' do + let(:params) { { type: 'invalid' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end +end diff --git a/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb b/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb new file mode 100644 index 0000000000..4382cb84e5 --- /dev/null +++ b/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb @@ -0,0 +1,285 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Canonical Email Blocks' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'admin:read:canonical_email_blocks admin:write:canonical_email_blocks' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/canonical_email_blocks' do + subject do + get '/api/v1/admin/canonical_email_blocks', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there is no canonical email block' do + it 'returns an empty list' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are canonical email blocks' do + let!(:canonical_email_blocks) { Fabricate.times(5, :canonical_email_block) } + let(:expected_email_hashes) { canonical_email_blocks.pluck(:canonical_email_hash) } + + it 'returns the correct canonical email hashes' do + subject + + expect(body_as_json.pluck(:canonical_email_hash)).to match_array(expected_email_hashes) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of canonical email blocks' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + + context 'with since_id param' do + let(:params) { { since_id: canonical_email_blocks[1].id } } + + it 'returns only the canonical email blocks after since_id' do + subject + + canonical_email_blocks_ids = canonical_email_blocks.pluck(:id).map(&:to_s) + + expect(body_as_json.pluck(:id)).to match_array(canonical_email_blocks_ids[2..]) + end + end + + context 'with max_id param' do + let(:params) { { max_id: canonical_email_blocks[3].id } } + + it 'returns only the canonical email blocks before max_id' do + subject + + canonical_email_blocks_ids = canonical_email_blocks.pluck(:id).map(&:to_s) + + expect(body_as_json.pluck(:id)).to match_array(canonical_email_blocks_ids[..2]) + end + end + end + end + + describe 'GET /api/v1/admin/canonical_email_blocks/:id' do + subject do + get "/api/v1/admin/canonical_email_blocks/#{canonical_email_block.id}", headers: headers + end + + let!(:canonical_email_block) { Fabricate(:canonical_email_block) } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + context 'when the requested canonical email block exists' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the requested canonical email block data correctly' do + subject + + json = body_as_json + + expect(json[:id]).to eq(canonical_email_block.id.to_s) + expect(json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) + end + end + + context 'when the requested canonical block does not exist' do + it 'returns http not found' do + get '/api/v1/admin/canonical_email_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/admin/canonical_email_blocks/test' do + subject do + post '/api/v1/admin/canonical_email_blocks/test', headers: headers, params: params + end + + let(:params) { { email: 'email@example.com' } } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + context 'when the required email param is not provided' do + let(:params) { {} } + + it 'returns http bad request' do + subject + + expect(response).to have_http_status(400) + end + end + + context 'when the required email param is provided' do + context 'when there is a matching canonical email block' do + let!(:canonical_email_block) { CanonicalEmailBlock.create(params) } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected canonical email hash' do + subject + + expect(body_as_json[0][:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) + end + end + + context 'when there is no matching canonical email block' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns an empty list' do + subject + + expect(body_as_json).to be_empty + end + end + end + end + + describe 'POST /api/v1/admin/canonical_email_blocks' do + subject do + post '/api/v1/admin/canonical_email_blocks', headers: headers, params: params + end + + let(:params) { { email: 'example@email.com' } } + let(:canonical_email_block) { CanonicalEmailBlock.new(email: params[:email]) } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the canonical_email_hash correctly' do + subject + + expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) + end + + context 'when the required email param is not provided' do + let(:params) { {} } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the canonical_email_hash param is provided instead of email' do + let(:params) { { canonical_email_hash: 'dd501ce4e6b08698f19df96f2f15737e48a75660b1fa79b6ff58ea25ee4851a4' } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the correct canonical_email_hash' do + subject + + expect(body_as_json[:canonical_email_hash]).to eq(params[:canonical_email_hash]) + end + end + + context 'when both email and canonical_email_hash params are provided' do + let(:params) { { email: 'example@email.com', canonical_email_hash: 'dd501ce4e6b08698f19df96f2f15737e48a75660b1fa79b6ff58ea25ee4851a4' } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'ignores the canonical_email_hash param' do + subject + + expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash) + end + end + + context 'when the given canonical email was already blocked' do + before do + canonical_email_block.save + end + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'DELETE /api/v1/admin/canonical_email_blocks/:id' do + subject do + delete "/api/v1/admin/canonical_email_blocks/#{canonical_email_block.id}", headers: headers + end + + let!(:canonical_email_block) { Fabricate(:canonical_email_block) } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'deletes the canonical email block' do + subject + + expect(CanonicalEmailBlock.find_by(id: canonical_email_block.id)).to be_nil + end + + context 'when the canonical email block is not found' do + it 'returns http not found' do + delete '/api/v1/admin/canonical_email_blocks/0', headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/admin/domain_allows_spec.rb b/spec/requests/api/v1/admin/domain_allows_spec.rb new file mode 100644 index 0000000000..96000e3ef4 --- /dev/null +++ b/spec/requests/api/v1/admin/domain_allows_spec.rb @@ -0,0 +1,194 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Domain Allows' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/domain_allows' do + subject do + get '/api/v1/admin/domain_allows', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there is no allowed domains' do + it 'returns an empty body' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are allowed domains' do + let!(:domain_allows) { Fabricate.times(5, :domain_allow) } + let(:expected_response) do + domain_allows.map do |domain_allow| + { + id: domain_allow.id.to_s, + domain: domain_allow.domain, + created_at: domain_allow.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'), + } + end + end + + it 'returns the correct allowed domains' do + subject + + expect(body_as_json).to match_array(expected_response) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of allowed domains' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + end + end + + describe 'GET /api/v1/admin/domain_allows/:id' do + subject do + get "/api/v1/admin/domain_allows/#{domain_allow.id}", headers: headers + end + + let!(:domain_allow) { Fabricate(:domain_allow) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected allowed domain name' do + subject + + expect(body_as_json[:domain]).to eq domain_allow.domain + end + + context 'when the requested allowed domain does not exist' do + it 'returns http not found' do + get '/api/v1/admin/domain_allows/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/admin/domain_allows' do + subject do + post '/api/v1/admin/domain_allows', headers: headers, params: params + end + + let(:params) { { domain: 'foo.bar.com' } } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + context 'with a valid domain name' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected domain name' do + subject + + expect(body_as_json[:domain]).to eq 'foo.bar.com' + end + + it 'creates a domain allow' do + subject + + expect(DomainAllow.find_by(domain: 'foo.bar.com')).to be_present + end + end + + context 'with invalid domain name' do + let(:params) { 'foo bar' } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when domain name is not specified' do + let(:params) { {} } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the domain is already allowed' do + before do + DomainAllow.create(params) + end + + it 'returns the existing allowed domain name' do + subject + + expect(body_as_json[:domain]).to eq(params[:domain]) + end + end + end + + describe 'DELETE /api/v1/admin/domain_allows/:id' do + subject do + delete "/api/v1/admin/domain_allows/#{domain_allow.id}", headers: headers + end + + let!(:domain_allow) { Fabricate(:domain_allow) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'deletes the allowed domain' do + subject + + expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil + end + + context 'when the allowed domain does not exist' do + it 'returns http not found' do + delete '/api/v1/admin/domain_allows/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/admin/domain_blocks_spec.rb b/spec/requests/api/v1/admin/domain_blocks_spec.rb new file mode 100644 index 0000000000..7a5ac28c56 --- /dev/null +++ b/spec/requests/api/v1/admin/domain_blocks_spec.rb @@ -0,0 +1,264 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Domain Blocks' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read:domain_blocks admin:write:domain_blocks' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/domain_blocks' do + subject do + get '/api/v1/admin/domain_blocks', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there are no domain blocks' do + it 'returns an empty list' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are domain blocks' do + let!(:domain_blocks) do + [ + Fabricate(:domain_block, severity: :silence, reject_media: true), + Fabricate(:domain_block, severity: :suspend, obfuscate: true), + Fabricate(:domain_block, severity: :noop, reject_reports: true), + Fabricate(:domain_block, public_comment: 'Spam'), + Fabricate(:domain_block, private_comment: 'Spam'), + ] + end + let(:expected_responde) do + domain_blocks.map do |domain_block| + { + id: domain_block.id.to_s, + domain: domain_block.domain, + created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'), + severity: domain_block.severity.to_s, + reject_media: domain_block.reject_media, + reject_reports: domain_block.reject_reports, + private_comment: domain_block.private_comment, + public_comment: domain_block.public_comment, + obfuscate: domain_block.obfuscate, + } + end + end + + it 'returns the expected domain blocks' do + subject + + expect(body_as_json).to match_array(expected_responde) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of domain blocks' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + end + end + + describe 'GET /api/v1/admin/domain_blocks/:id' do + subject do + get "/api/v1/admin/domain_blocks/#{domain_block.id}", headers: headers + end + + let!(:domain_block) { Fabricate(:domain_block) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected domain block content' do + subject + + expect(body_as_json).to eq( + { + id: domain_block.id.to_s, + domain: domain_block.domain, + created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'), + severity: domain_block.severity.to_s, + reject_media: domain_block.reject_media, + reject_reports: domain_block.reject_reports, + private_comment: domain_block.private_comment, + public_comment: domain_block.public_comment, + obfuscate: domain_block.obfuscate, + } + ) + end + + context 'when the requested domain block does not exist' do + it 'returns http not found' do + get '/api/v1/admin/domain_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/admin/domain_blocks' do + subject do + post '/api/v1/admin/domain_blocks', headers: headers, params: params + end + + let(:params) { { domain: 'foo.bar.com', severity: :silence } } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns expected domain name and severity' do + subject + + body = body_as_json + + expect(body).to match a_hash_including( + { + domain: 'foo.bar.com', + severity: 'silence', + } + ) + end + + it 'creates a domain block' do + subject + + expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present + end + + context 'when a stricter domain block already exists' do + before do + Fabricate(:domain_block, domain: 'bar.com', severity: :suspend) + end + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + + it 'returns existing domain block in error' do + subject + + expect(body_as_json[:existing_domain_block][:domain]).to eq('bar.com') + end + end + + context 'when given domain name is invalid' do + let(:params) { { domain: 'foo bar', severity: :silence } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'PUT /api/v1/admin/domain_blocks/:id' do + subject do + put "/api/v1/admin/domain_blocks/#{domain_block.id}", headers: headers, params: params + end + + let!(:domain_block) { Fabricate(:domain_block, domain: 'example.com', severity: :silence) } + let(:params) { { domain: 'example.com', severity: 'suspend' } } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the updated domain block' do + subject + + expect(body_as_json).to match a_hash_including( + { + id: domain_block.id.to_s, + domain: domain_block.domain, + severity: 'suspend', + } + ) + end + + it 'updates the block severity' do + expect { subject }.to change { domain_block.reload.severity }.from('silence').to('suspend') + end + + context 'when domain block does not exist' do + it 'returns http not found' do + put '/api/v1/admin/domain_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE /api/v1/admin/domain_blocks/:id' do + subject do + delete "/api/v1/admin/domain_blocks/#{domain_block.id}", headers: headers + end + + let!(:domain_block) { Fabricate(:domain_block) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'deletes the domain block' do + subject + + expect(DomainBlock.find_by(id: domain_block.id)).to be_nil + end + + context 'when domain block does not exist' do + it 'returns http not found' do + delete '/api/v1/admin/domain_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/admin/email_domain_blocks_spec.rb b/spec/requests/api/v1/admin/email_domain_blocks_spec.rb new file mode 100644 index 0000000000..d512def866 --- /dev/null +++ b/spec/requests/api/v1/admin/email_domain_blocks_spec.rb @@ -0,0 +1,211 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Email Domain Blocks' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:account) { Fabricate(:account) } + let(:scopes) { 'admin:read:email_domain_blocks admin:write:email_domain_blocks' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/email_domain_blocks' do + subject do + get '/api/v1/admin/email_domain_blocks', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there is no email domain block' do + it 'returns an empty list' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are email domain blocks' do + let!(:email_domain_blocks) { Fabricate.times(5, :email_domain_block) } + let(:blocked_email_domains) { email_domain_blocks.pluck(:domain) } + + it 'return the correct blocked email domains' do + subject + + expect(body_as_json.pluck(:domain)).to match_array(blocked_email_domains) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of email domain blocks' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + + context 'with since_id param' do + let(:params) { { since_id: email_domain_blocks[1].id } } + + it 'returns only the email domain blocks after since_id' do + subject + + email_domain_blocks_ids = email_domain_blocks.pluck(:id).map(&:to_s) + + expect(body_as_json.pluck(:id)).to match_array(email_domain_blocks_ids[2..]) + end + end + + context 'with max_id param' do + let(:params) { { max_id: email_domain_blocks[3].id } } + + it 'returns only the email domain blocks before max_id' do + subject + + email_domain_blocks_ids = email_domain_blocks.pluck(:id).map(&:to_s) + + expect(body_as_json.pluck(:id)).to match_array(email_domain_blocks_ids[..2]) + end + end + end + end + + describe 'GET /api/v1/admin/email_domain_blocks/:id' do + subject do + get "/api/v1/admin/email_domain_blocks/#{email_domain_block.id}", headers: headers + end + + let!(:email_domain_block) { Fabricate(:email_domain_block) } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + context 'when email domain block exists' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the correct blocked domain' do + subject + + expect(body_as_json[:domain]).to eq(email_domain_block.domain) + end + end + + context 'when email domain block does not exist' do + it 'returns http not found' do + get '/api/v1/admin/email_domain_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/admin/email_domain_blocks' do + subject do + post '/api/v1/admin/email_domain_blocks', headers: headers, params: params + end + + let(:params) { { domain: 'example.com' } } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the correct blocked email domain' do + subject + + expect(body_as_json[:domain]).to eq(params[:domain]) + end + + context 'when domain param is not provided' do + let(:params) { { domain: '' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when provided domain name has an invalid character' do + let(:params) { { domain: 'do\uD800.com' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when provided domain is already blocked' do + before do + EmailDomainBlock.create(params) + end + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'DELETE /api/v1/admin/email_domain_blocks' do + subject do + delete "/api/v1/admin/email_domain_blocks/#{email_domain_block.id}", headers: headers + end + + let!(:email_domain_block) { Fabricate(:email_domain_block) } + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns an empty body' do + subject + + expect(body_as_json).to be_empty + end + + it 'deletes email domain block' do + subject + + expect(EmailDomainBlock.find_by(id: email_domain_block.id)).to be_nil + end + + context 'when email domain block does not exist' do + it 'returns http not found' do + delete '/api/v1/admin/email_domain_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/admin/ip_blocks_spec.rb b/spec/requests/api/v1/admin/ip_blocks_spec.rb new file mode 100644 index 0000000000..d03886c51b --- /dev/null +++ b/spec/requests/api/v1/admin/ip_blocks_spec.rb @@ -0,0 +1,255 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'IP Blocks' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'admin:read:ip_blocks admin:write:ip_blocks' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/ip_blocks' do + subject do + get '/api/v1/admin/ip_blocks', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'admin:write:ip_blocks' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there is no ip block' do + it 'returns an empty body' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are ip blocks' do + let!(:ip_blocks) do + [ + IpBlock.create(ip: '192.0.2.0/24', severity: :no_access), + IpBlock.create(ip: '172.16.0.1', severity: :sign_up_requires_approval, comment: 'Spam'), + IpBlock.create(ip: '2001:0db8::/32', severity: :sign_up_block, expires_in: 10.days), + ] + end + let(:expected_response) do + ip_blocks.map do |ip_block| + { + id: ip_block.id.to_s, + ip: ip_block.ip, + severity: ip_block.severity.to_s, + comment: ip_block.comment, + created_at: ip_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'), + expires_at: ip_block.expires_at&.strftime('%Y-%m-%dT%H:%M:%S.%LZ'), + } + end + end + + it 'returns the correct blocked ips' do + subject + + expect(body_as_json).to match_array(expected_response) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of ip blocks' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + end + end + + describe 'GET /api/v1/admin/ip_blocks/:id' do + subject do + get "/api/v1/admin/ip_blocks/#{ip_block.id}", headers: headers + end + + let!(:ip_block) { IpBlock.create(ip: '192.0.2.0/24', severity: :no_access) } + + it_behaves_like 'forbidden for wrong scope', 'admin:write:ip_blocks' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the correct ip block' do + subject + + json = body_as_json + + expect(json[:ip]).to eq("#{ip_block.ip}/#{ip_block.ip.prefix}") + expect(json[:severity]).to eq(ip_block.severity.to_s) + end + + context 'when ip block does not exist' do + it 'returns http not found' do + get '/api/v1/admin/ip_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/admin/ip_blocks' do + subject do + post '/api/v1/admin/ip_blocks', headers: headers, params: params + end + + let(:params) { { ip: '151.0.32.55', severity: 'no_access', comment: 'Spam' } } + + it_behaves_like 'forbidden for wrong scope', 'admin:read:ip_blocks' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the correct ip block' do + subject + + json = body_as_json + + expect(json[:ip]).to eq("#{params[:ip]}/32") + expect(json[:severity]).to eq(params[:severity]) + expect(json[:comment]).to eq(params[:comment]) + end + + context 'when the required ip param is not provided' do + let(:params) { { ip: '', severity: 'no_access' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the required severity param is not provided' do + let(:params) { { ip: '173.65.23.1', severity: '' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the given ip address is already blocked' do + before do + IpBlock.create(params) + end + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the given ip address is invalid' do + let(:params) { { ip: '520.13.54.120', severity: 'no_access' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'PUT /api/v1/admin/ip_blocks/:id' do + subject do + put "/api/v1/admin/ip_blocks/#{ip_block.id}", headers: headers, params: params + end + + let!(:ip_block) { IpBlock.create(ip: '185.200.13.3', severity: 'no_access', comment: 'Spam', expires_in: 48.hours) } + let(:params) { { severity: 'sign_up_requires_approval', comment: 'Decreasing severity' } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the correct ip block' do + subject + + expect(body_as_json).to match(hash_including({ + ip: "#{ip_block.ip}/#{ip_block.ip.prefix}", + severity: 'sign_up_requires_approval', + comment: 'Decreasing severity', + })) + end + + it 'updates the severity correctly' do + expect { subject }.to change { ip_block.reload.severity }.from('no_access').to('sign_up_requires_approval') + end + + it 'updates the comment correctly' do + expect { subject }.to change { ip_block.reload.comment }.from('Spam').to('Decreasing severity') + end + + context 'when ip block does not exist' do + it 'returns http not found' do + put '/api/v1/admin/ip_blocks/-1', headers: headers, params: params + + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE /api/v1/admin/ip_blocks/:id' do + subject do + delete "/api/v1/admin/ip_blocks/#{ip_block.id}", headers: headers + end + + let!(:ip_block) { IpBlock.create(ip: '185.200.13.3', severity: 'no_access') } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns an empty body' do + subject + + expect(body_as_json).to be_empty + end + + it 'deletes the ip block' do + subject + + expect(IpBlock.find_by(id: ip_block.id)).to be_nil + end + + context 'when ip block does not exist' do + it 'returns http not found' do + delete '/api/v1/admin/ip_blocks/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/admin/reports_spec.rb b/spec/requests/api/v1/admin/reports_spec.rb new file mode 100644 index 0000000000..91c3c11f5d --- /dev/null +++ b/spec/requests/api/v1/admin/reports_spec.rb @@ -0,0 +1,272 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Reports' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read:reports admin:write:reports' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/reports' do + subject do + get '/api/v1/admin/reports', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there are no reports' do + it 'returns an empty list' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are reports' do + let!(:reporter) { Fabricate(:account) } + let!(:spammer) { Fabricate(:account) } + let(:expected_response) do + scope.map do |report| + hash_including({ + id: report.id.to_s, + action_taken: report.action_taken?, + category: report.category, + comment: report.comment, + account: hash_including(id: report.account.id.to_s), + target_account: hash_including(id: report.target_account.id.to_s), + statuses: report.statuses, + rules: report.rules, + forwarded: report.forwarded, + }) + end + end + let(:scope) { Report.unresolved } + + before do + Fabricate(:report) + Fabricate(:report, target_account: spammer) + Fabricate(:report, account: reporter, target_account: spammer) + Fabricate(:report, action_taken_at: 4.days.ago, account: reporter) + Fabricate(:report, action_taken_at: 20.days.ago) + end + + it 'returns all unresolved reports' do + subject + + expect(body_as_json).to match_array(expected_response) + end + + context 'with resolved param' do + let(:params) { { resolved: true } } + let(:scope) { Report.resolved } + + it 'returns only the resolved reports' do + subject + + expect(body_as_json).to match_array(expected_response) + end + end + + context 'with account_id param' do + let(:params) { { account_id: reporter.id } } + let(:scope) { Report.unresolved.where(account: reporter) } + + it 'returns all unresolved reports filed by the specified account' do + subject + + expect(body_as_json).to match_array(expected_response) + end + end + + context 'with target_account_id param' do + let(:params) { { target_account_id: spammer.id } } + let(:scope) { Report.unresolved.where(target_account: spammer) } + + it 'returns all unresolved reports targeting the specified account' do + subject + + expect(body_as_json).to match_array(expected_response) + end + end + + context 'with limit param' do + let(:params) { { limit: 1 } } + + it 'returns only the requested number of reports' do + subject + + expect(body_as_json.size).to eq(1) + end + end + end + end + + describe 'GET /api/v1/admin/reports/:id' do + subject do + get "/api/v1/admin/reports/#{report.id}", headers: headers + end + + let(:report) { Fabricate(:report) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the requested report content' do + subject + + expect(body_as_json).to include( + { + id: report.id.to_s, + action_taken: report.action_taken?, + category: report.category, + comment: report.comment, + account: a_hash_including(id: report.account.id.to_s), + target_account: a_hash_including(id: report.target_account.id.to_s), + statuses: report.statuses, + rules: report.rules, + forwarded: report.forwarded, + } + ) + end + end + + describe 'PUT /api/v1/admin/reports/:id' do + subject do + put "/api/v1/admin/reports/#{report.id}", headers: headers, params: params + end + + let!(:report) { Fabricate(:report, category: :other) } + let(:params) { { category: 'spam' } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'updates the report category' do + expect { subject }.to change { report.reload.category }.from('other').to('spam') + end + + it 'returns the updated report content' do + subject + + report.reload + + expect(body_as_json).to include( + { + id: report.id.to_s, + action_taken: report.action_taken?, + category: report.category, + comment: report.comment, + account: a_hash_including(id: report.account.id.to_s), + target_account: a_hash_including(id: report.target_account.id.to_s), + statuses: report.statuses, + rules: report.rules, + forwarded: report.forwarded, + } + ) + end + end + + describe 'POST #resolve' do + subject do + post "/api/v1/admin/reports/#{report.id}/resolve", headers: headers + end + + let(:report) { Fabricate(:report, action_taken_at: nil) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'marks report as resolved' do + expect { subject }.to change { report.reload.unresolved? }.from(true).to(false) + end + end + + describe 'POST #reopen' do + subject do + post "/api/v1/admin/reports/#{report.id}/reopen", headers: headers + end + + let(:report) { Fabricate(:report, action_taken_at: 10.days.ago) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'marks report as unresolved' do + expect { subject }.to change { report.reload.unresolved? }.from(false).to(true) + end + end + + describe 'POST #assign_to_self' do + subject do + post "/api/v1/admin/reports/#{report.id}/assign_to_self", headers: headers + end + + let(:report) { Fabricate(:report) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'assigns report to the requesting user' do + expect { subject }.to change { report.reload.assigned_account_id }.from(nil).to(user.account.id) + end + end + + describe 'POST #unassign' do + subject do + post "/api/v1/admin/reports/#{report.id}/unassign", headers: headers + end + + let(:report) { Fabricate(:report, assigned_account_id: user.account.id) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'unassigns report from assignee' do + expect { subject }.to change { report.reload.assigned_account_id }.from(user.account.id).to(nil) + end + end +end diff --git a/spec/requests/api/v1/admin/tags_spec.rb b/spec/requests/api/v1/admin/tags_spec.rb new file mode 100644 index 0000000000..031be17f52 --- /dev/null +++ b/spec/requests/api/v1/admin/tags_spec.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Tags' do + let(:role) { UserRole.find_by(name: 'Admin') } + let(:user) { Fabricate(:user, role: role) } + let(:scopes) { 'admin:read admin:write' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:tag) { Fabricate(:tag) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/admin/tags' do + subject do + get '/api/v1/admin/tags', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + context 'when there are no tags' do + it 'returns an empty list' do + subject + + expect(body_as_json).to be_empty + end + end + + context 'when there are tagss' do + let!(:tags) do + [ + Fabricate(:tag), + Fabricate(:tag), + Fabricate(:tag), + Fabricate(:tag), + ] + end + + it 'returns the expected tags' do + subject + tags.each do |tag| + expect(body_as_json.find { |item| item[:id] == tag.id.to_s && item[:name] == tag.name }).to_not be_nil + end + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of tags' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + end + end + + describe 'GET /api/v1/admin/tags/:id' do + subject do + get "/api/v1/admin/tags/#{tag.id}", headers: headers + end + + let!(:tag) { Fabricate(:tag) } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns expected tag content' do + subject + + expect(body_as_json[:id].to_i).to eq(tag.id) + expect(body_as_json[:name]).to eq(tag.name) + end + + context 'when the requested tag does not exist' do + it 'returns http not found' do + get '/api/v1/admin/tags/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'PUT /api/v1/admin/tags/:id' do + subject do + put "/api/v1/admin/tags/#{tag.id}", headers: headers, params: params + end + + let!(:tag) { Fabricate(:tag) } + let(:params) { { display_name: tag.name.upcase } } + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong scope', 'admin:read' + it_behaves_like 'forbidden for wrong role', '' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns updated tag' do + subject + + expect(body_as_json[:id].to_i).to eq(tag.id) + expect(body_as_json[:name]).to eq(tag.name.upcase) + end + + context 'when the updated display name is invalid' do + let(:params) { { display_name: tag.name + tag.id.to_s } } + + it 'returns http unprocessable content' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the requested tag does not exist' do + it 'returns http not found' do + get '/api/v1/admin/tags/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/apps/credentials_spec.rb b/spec/requests/api/v1/apps/credentials_spec.rb new file mode 100644 index 0000000000..dafe168c56 --- /dev/null +++ b/spec/requests/api/v1/apps/credentials_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Credentials' do + describe 'GET /api/v1/apps/verify_credentials' do + subject do + get '/api/v1/apps/verify_credentials', headers: headers + end + + context 'with an oauth token' do + let(:token) { Fabricate(:accessible_access_token, scopes: 'read', application: Fabricate(:application)) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the app information correctly' do + subject + + expect(body_as_json).to match( + a_hash_including( + name: token.application.name, + website: token.application.website, + vapid_key: Rails.configuration.x.vapid_public_key + ) + ) + end + end + + context 'without an oauth token' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/controllers/api/v1/apps_controller_spec.rb b/spec/requests/api/v1/apps_spec.rb similarity index 63% rename from spec/controllers/api/v1/apps_controller_spec.rb rename to spec/requests/api/v1/apps_spec.rb index 70cd62d482..88f9eee360 100644 --- a/spec/controllers/api/v1/apps_controller_spec.rb +++ b/spec/requests/api/v1/apps_spec.rb @@ -1,15 +1,19 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.describe Api::V1::AppsController, type: :controller do - render_views +RSpec.describe 'Apps' do + describe 'POST /api/v1/apps' do + subject do + post '/api/v1/apps', params: params + end - describe 'POST #create' do - let(:client_name) { 'Test app' } - let(:scopes) { nil } + let(:client_name) { 'Test app' } + let(:scopes) { nil } let(:redirect_uris) { 'urn:ietf:wg:oauth:2.0:oob' } - let(:website) { nil } + let(:website) { nil } - let(:app_params) do + let(:params) do { client_name: client_name, redirect_uris: redirect_uris, @@ -18,24 +22,26 @@ RSpec.describe Api::V1::AppsController, type: :controller do } end - before do - post :create, params: app_params - end - context 'with valid params' do it 'returns http success' do + subject + expect(response).to have_http_status(200) end it 'creates an OAuth app' do - expect(Doorkeeper::Application.find_by(name: client_name)).to_not be nil + subject + + expect(Doorkeeper::Application.find_by(name: client_name)).to be_present end it 'returns client ID and client secret' do - json = body_as_json + subject - expect(json[:client_id]).to_not be_blank - expect(json[:client_secret]).to_not be_blank + body = body_as_json + + expect(body[:client_id]).to be_present + expect(body[:client_secret]).to be_present end end @@ -43,6 +49,8 @@ RSpec.describe Api::V1::AppsController, type: :controller do let(:scopes) { 'hoge' } it 'returns http unprocessable entity' do + subject + expect(response).to have_http_status(422) end end @@ -51,10 +59,14 @@ RSpec.describe Api::V1::AppsController, type: :controller do let(:scopes) { (%w(read) * 40).join(' ') } it 'returns http success' do + subject + expect(response).to have_http_status(200) end it 'only saves the scope once' do + subject + expect(Doorkeeper::Application.find_by(name: client_name).scopes.to_s).to eq 'read' end end @@ -63,22 +75,39 @@ RSpec.describe Api::V1::AppsController, type: :controller do let(:client_name) { 'hoge' * 20 } it 'returns http unprocessable entity' do + subject + expect(response).to have_http_status(422) end end context 'with a too-long website' do - let(:website) { 'https://foo.bar/' + ('hoge' * 2_000) } + let(:website) { "https://foo.bar/#{'hoge' * 2_000}" } it 'returns http unprocessable entity' do + subject + expect(response).to have_http_status(422) end end context 'with a too-long redirect_uris' do - let(:redirect_uris) { 'https://foo.bar/' + ('hoge' * 2_000) } + let(:redirect_uris) { "https://foo.bar/#{'hoge' * 2_000}" } it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'without required params' do + let(:client_name) { '' } + let(:redirect_uris) { '' } + + it 'returns http unprocessable entity' do + subject + expect(response).to have_http_status(422) end end diff --git a/spec/requests/api/v1/bookmarks_spec.rb b/spec/requests/api/v1/bookmarks_spec.rb new file mode 100644 index 0000000000..1f1cd35caa --- /dev/null +++ b/spec/requests/api/v1/bookmarks_spec.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Bookmarks' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:bookmarks' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/bookmarks' do + subject do + get '/api/v1/bookmarks', headers: headers, params: params + end + + let(:params) { {} } + let!(:bookmarks) { Fabricate.times(3, :bookmark, account: user.account) } + + let(:expected_response) do + bookmarks.map do |bookmark| + a_hash_including(id: bookmark.status.id.to_s, account: a_hash_including(id: bookmark.status.account.id.to_s)) + end + end + + it_behaves_like 'forbidden for wrong scope', 'write' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the bookmarked statuses' do + subject + + expect(body_as_json).to match_array(expected_response) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'paginates correctly', :aggregate_failures do + subject + + expect(body_as_json.size).to eq(params[:limit]) + expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq(api_v1_bookmarks_url(limit: params[:limit], min_id: bookmarks.last.id)) + expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_bookmarks_url(limit: params[:limit], max_id: bookmarks[1].id)) + end + end + + context 'without the authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v1/domain_blocks_spec.rb b/spec/requests/api/v1/domain_blocks_spec.rb new file mode 100644 index 0000000000..0f4fd4e90e --- /dev/null +++ b/spec/requests/api/v1/domain_blocks_spec.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Domain blocks' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:blocks write:blocks' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/domain_blocks' do + subject do + get '/api/v1/domain_blocks', headers: headers, params: params + end + + let(:blocked_domains) { ['example.com', 'example.net', 'example.org', 'example.com.br'] } + let(:params) { {} } + + before do + blocked_domains.each { |domain| user.account.block_domain!(domain) } + end + + it_behaves_like 'forbidden for wrong scope', 'write:blocks' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the domains blocked by the requesting user' do + subject + + expect(body_as_json).to match_array(blocked_domains) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of blocked domains' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + end + + describe 'POST /api/v1/domain_blocks' do + subject do + post '/api/v1/domain_blocks', headers: headers, params: params + end + + let(:params) { { domain: 'example.com' } } + + it_behaves_like 'forbidden for wrong scope', 'read read:blocks' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'creates a domain block' do + subject + + expect(user.account.domain_blocking?(params[:domain])).to be(true) + end + + context 'when no domain name is given' do + let(:params) { { domain: '' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the given domain name is invalid' do + let(:params) { { domain: 'example com' } } + + it 'returns unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'DELETE /api/v1/domain_blocks' do + subject do + delete '/api/v1/domain_blocks/', headers: headers, params: params + end + + let(:params) { { domain: 'example.com' } } + + before do + user.account.block_domain!('example.com') + end + + it_behaves_like 'forbidden for wrong scope', 'read read:blocks' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'deletes the specified domain block' do + subject + + expect(user.account.domain_blocking?('example.com')).to be(false) + end + + context 'when the given domain name is not blocked' do + let(:params) { { domain: 'example.org' } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + end +end diff --git a/spec/requests/api/v1/emails/confirmations_spec.rb b/spec/requests/api/v1/emails/confirmations_spec.rb new file mode 100644 index 0000000000..8f5171ee78 --- /dev/null +++ b/spec/requests/api/v1/emails/confirmations_spec.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Confirmations' do + let(:confirmed_at) { nil } + let(:user) { Fabricate(:user, confirmed_at: confirmed_at) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts write:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'POST /api/v1/emails/confirmations' do + subject do + post '/api/v1/emails/confirmations', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'read read:accounts' + + context 'with an oauth token' do + context 'when user was created by a different application' do + let(:user) { Fabricate(:user, confirmed_at: confirmed_at, created_by_application: Fabricate(:application)) } + + it 'returns http forbidden' do + subject + + expect(response).to have_http_status(403) + end + end + + context 'when user was created by the same application' do + before do + user.update(created_by_application: token.application) + end + + context 'when the account is already confirmed' do + let(:confirmed_at) { Time.now.utc } + + it 'returns http forbidden' do + subject + + expect(response).to have_http_status(403) + end + + context 'when user changed e-mail and has not confirmed it' do + before do + user.update(email: 'foo@bar.com') + end + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + end + + context 'when the account is unconfirmed' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + + context 'with email param' do + let(:params) { { email: 'foo@bar.com' } } + + it "updates the user's e-mail address", :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.reload.unconfirmed_email).to eq('foo@bar.com') + end + end + + context 'with invalid email param' do + let(:params) { { email: 'invalid' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + end + + context 'without an oauth token' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end + + describe 'GET /api/v1/emails/check_confirmation' do + subject do + get '/api/v1/emails/check_confirmation', headers: headers + end + + it_behaves_like 'forbidden for wrong scope', 'write' + + context 'with an oauth token' do + context 'when the account is not confirmed' do + it 'returns the confirmation status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to be false + end + end + + context 'when the account is confirmed' do + let(:confirmed_at) { Time.now.utc } + + it 'returns the confirmation status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to be true + end + end + end + + context 'with an authentication cookie' do + let(:headers) { {} } + + before do + sign_in user, scope: :user + end + + context 'when the account is not confirmed' do + it 'returns the confirmation status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to be false + end + end + + context 'when the account is confirmed' do + let(:confirmed_at) { Time.now.utc } + + it 'returns the confirmation status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to be true + end + end + end + + context 'without an oauth token and an authentication cookie' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v1/featured_tags_spec.rb b/spec/requests/api/v1/featured_tags_spec.rb new file mode 100644 index 0000000000..6c171f6e47 --- /dev/null +++ b/spec/requests/api/v1/featured_tags_spec.rb @@ -0,0 +1,193 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'FeaturedTags' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts write:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/featured_tags' do + context 'with wrong scope' do + before do + get '/api/v1/featured_tags', headers: headers + end + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + end + + context 'when Authorization header is missing' do + it 'returns http unauthorized' do + get '/api/v1/featured_tags' + + expect(response).to have_http_status(401) + end + end + + it 'returns http success' do + get '/api/v1/featured_tags', headers: headers + + expect(response).to have_http_status(200) + end + + context 'when the requesting user has no featured tag' do + before { Fabricate.times(3, :featured_tag) } + + it 'returns an empty body' do + get '/api/v1/featured_tags', headers: headers + + body = body_as_json + + expect(body).to be_empty + end + end + + context 'when the requesting user has featured tags' do + let!(:user_featured_tags) { Fabricate.times(5, :featured_tag, account: user.account) } + + it 'returns only the featured tags belonging to the requesting user' do + get '/api/v1/featured_tags', headers: headers + + body = body_as_json + expected_ids = user_featured_tags.pluck(:id).map(&:to_s) + + expect(body.pluck(:id)).to match_array(expected_ids) + end + end + end + + describe 'POST /api/v1/featured_tags' do + let(:params) { { name: 'tag' } } + + it 'returns http success' do + post '/api/v1/featured_tags', headers: headers, params: params + + expect(response).to have_http_status(200) + end + + it 'returns the correct tag name' do + post '/api/v1/featured_tags', headers: headers, params: params + + body = body_as_json + + expect(body[:name]).to eq(params[:name]) + end + + it 'creates a new featured tag for the requesting user' do + post '/api/v1/featured_tags', headers: headers, params: params + + featured_tag = FeaturedTag.find_by(name: params[:name], account: user.account) + + expect(featured_tag).to be_present + end + + context 'with wrong scope' do + before do + post '/api/v1/featured_tags', headers: headers, params: params + end + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + end + + context 'when Authorization header is missing' do + it 'returns http unauthorized' do + post '/api/v1/featured_tags', params: params + + expect(response).to have_http_status(401) + end + end + + context 'when required param "name" is not provided' do + it 'returns http bad request' do + post '/api/v1/featured_tags', headers: headers + + expect(response).to have_http_status(400) + end + end + + context 'when provided tag name is invalid' do + let(:params) { { name: 'asj&*!' } } + + it 'returns http unprocessable entity' do + post '/api/v1/featured_tags', headers: headers, params: params + + expect(response).to have_http_status(422) + end + end + + context 'when tag name is already taken' do + before do + FeaturedTag.create(name: params[:name], account: user.account) + end + + it 'returns http unprocessable entity' do + post '/api/v1/featured_tags', headers: headers, params: params + + expect(response).to have_http_status(422) + end + end + end + + describe 'DELETE /api/v1/featured_tags' do + let!(:featured_tag) { FeaturedTag.create(name: 'tag', account: user.account) } + let(:id) { featured_tag.id } + + it 'returns http success' do + delete "/api/v1/featured_tags/#{id}", headers: headers + + expect(response).to have_http_status(200) + end + + it 'returns an empty body' do + delete "/api/v1/featured_tags/#{id}", headers: headers + + body = body_as_json + + expect(body).to be_empty + end + + it 'deletes the featured tag' do + delete "/api/v1/featured_tags/#{id}", headers: headers + + featured_tag = FeaturedTag.find_by(id: id) + + expect(featured_tag).to be_nil + end + + context 'with wrong scope' do + before do + delete "/api/v1/featured_tags/#{id}", headers: headers + end + + it_behaves_like 'forbidden for wrong scope', 'read:statuses' + end + + context 'when Authorization header is missing' do + it 'returns http unauthorized' do + delete "/api/v1/featured_tags/#{id}" + + expect(response).to have_http_status(401) + end + end + + context 'when featured tag with given id does not exist' do + it 'returns http not found' do + delete '/api/v1/featured_tags/0', headers: headers + + expect(response).to have_http_status(404) + end + end + + context 'when deleting a featured tag of another user' do + let!(:other_user_featured_tag) { Fabricate(:featured_tag) } + let(:id) { other_user_featured_tag.id } + + it 'returns http not found' do + delete "/api/v1/featured_tags/#{id}", headers: headers + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/follow_requests_spec.rb b/spec/requests/api/v1/follow_requests_spec.rb new file mode 100644 index 0000000000..9d4ef8cd55 --- /dev/null +++ b/spec/requests/api/v1/follow_requests_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Follow requests' do + let(:user) { Fabricate(:user, account_attributes: { locked: true }) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:follows write:follows' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/follow_requests' do + subject do + get '/api/v1/follow_requests', headers: headers, params: params + end + + let(:accounts) { Fabricate.times(5, :account) } + let(:params) { {} } + + let(:expected_response) do + accounts.map do |account| + a_hash_including( + id: account.id.to_s, + username: account.username, + acct: account.acct + ) + end + end + + before do + accounts.each { |account| FollowService.new.call(account, user.account) } + end + + it_behaves_like 'forbidden for wrong scope', 'write write:follows' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected content from accounts requesting to follow' do + subject + + expect(body_as_json).to match_array(expected_response) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of follow requests' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + end + end + + describe 'POST /api/v1/follow_requests/:account_id/authorize' do + subject do + post "/api/v1/follow_requests/#{follower.id}/authorize", headers: headers + end + + let(:follower) { Fabricate(:account) } + + before do + FollowService.new.call(follower, user.account) + end + + it_behaves_like 'forbidden for wrong scope', 'read read:follows' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'allows the requesting follower to follow' do + expect { subject }.to change { follower.following?(user.account) }.from(false).to(true) + end + + it 'returns JSON with followed_by set to true' do + subject + + expect(body_as_json[:followed_by]).to be true + end + end + + describe 'POST /api/v1/follow_requests/:account_id/reject' do + subject do + post "/api/v1/follow_requests/#{follower.id}/reject", headers: headers + end + + let(:follower) { Fabricate(:account) } + + before do + FollowService.new.call(follower, user.account) + end + + it_behaves_like 'forbidden for wrong scope', 'read read:follows' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'removes the follow request' do + subject + + expect(FollowRequest.where(target_account: user.account, account: follower)).to_not exist + end + + it 'returns JSON with followed_by set to false' do + subject + + expect(body_as_json[:followed_by]).to be false + end + end +end diff --git a/spec/requests/api/v1/instances/languages_spec.rb b/spec/requests/api/v1/instances/languages_spec.rb new file mode 100644 index 0000000000..8ab8bf99ce --- /dev/null +++ b/spec/requests/api/v1/instances/languages_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Languages' do + describe 'GET /api/v1/instance/languages' do + before do + get '/api/v1/instance/languages' + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns the supported languages' do + expect(body_as_json.pluck(:code)).to match_array LanguagesHelper::SUPPORTED_LOCALES.keys.map(&:to_s) + end + end +end diff --git a/spec/requests/api/v1/lists_spec.rb b/spec/requests/api/v1/lists_spec.rb new file mode 100644 index 0000000000..383e09d0c3 --- /dev/null +++ b/spec/requests/api/v1/lists_spec.rb @@ -0,0 +1,247 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Lists' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:lists write:lists' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/lists' do + subject do + get '/api/v1/lists', headers: headers + end + + let!(:lists) do + [ + Fabricate(:list, account: user.account, title: 'first list', replies_policy: :followed), + Fabricate(:list, account: user.account, title: 'second list', replies_policy: :list), + Fabricate(:list, account: user.account, title: 'third list', replies_policy: :none), + Fabricate(:list, account: user.account, title: 'fourth list', exclusive: true), + ] + end + + let(:expected_response) do + lists.map do |list| + { + id: list.id.to_s, + title: list.title, + replies_policy: list.replies_policy, + exclusive: list.exclusive, + } + end + end + + before do + Fabricate(:list) + end + + it_behaves_like 'forbidden for wrong scope', 'write write:lists' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the expected lists' do + subject + + expect(body_as_json).to match_array(expected_response) + end + end + + describe 'GET /api/v1/lists/:id' do + subject do + get "/api/v1/lists/#{list.id}", headers: headers + end + + let(:list) { Fabricate(:list, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'write write:lists' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the requested list correctly' do + subject + + expect(body_as_json).to eq({ + id: list.id.to_s, + title: list.title, + replies_policy: list.replies_policy, + exclusive: list.exclusive, + }) + end + + context 'when the list belongs to a different user' do + let(:list) { Fabricate(:list) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'when the list does not exist' do + it 'returns http not found' do + get '/api/v1/lists/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/lists' do + subject do + post '/api/v1/lists', headers: headers, params: params + end + + let(:params) { { title: 'my list', replies_policy: 'none', exclusive: 'true' } } + + it_behaves_like 'forbidden for wrong scope', 'read read:lists' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the new list' do + subject + + expect(body_as_json).to match(a_hash_including(title: 'my list', replies_policy: 'none', exclusive: true)) + end + + it 'creates a list' do + subject + + expect(List.where(account: user.account).count).to eq(1) + end + + context 'when a title is not given' do + let(:params) { { title: '' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the given replies_policy is invalid' do + let(:params) { { title: 'a list', replies_policy: 'whatever' } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'PUT /api/v1/lists/:id' do + subject do + put "/api/v1/lists/#{list.id}", headers: headers, params: params + end + + let(:list) { Fabricate(:list, account: user.account, title: 'my list') } + let(:params) { { title: 'list', replies_policy: 'followed', exclusive: 'true' } } + + it_behaves_like 'forbidden for wrong scope', 'read read:lists' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the updated list' do + subject + + list.reload + + expect(body_as_json).to eq({ + id: list.id.to_s, + title: list.title, + replies_policy: list.replies_policy, + exclusive: list.exclusive, + }) + end + + it 'updates the list title' do + expect { subject }.to change { list.reload.title }.from('my list').to('list') + end + + it 'updates the list replies_policy' do + expect { subject }.to change { list.reload.replies_policy }.from('list').to('followed') + end + + it 'updates the list exclusive' do + expect { subject }.to change { list.reload.exclusive }.from(false).to(true) + end + + context 'when the list does not exist' do + it 'returns http not found' do + put '/api/v1/lists/-1', headers: headers, params: params + + expect(response).to have_http_status(404) + end + end + + context 'when the list belongs to another user' do + let(:list) { Fabricate(:list) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE /api/v1/lists/:id' do + subject do + delete "/api/v1/lists/#{list.id}", headers: headers + end + + let(:list) { Fabricate(:list, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'read read:lists' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'deletes the list' do + subject + + expect(List.where(id: list.id)).to_not exist + end + + context 'when the list does not exist' do + it 'returns http not found' do + delete '/api/v1/lists/-1', headers: headers + + expect(response).to have_http_status(404) + end + end + + context 'when the list belongs to another user' do + let(:list) { Fabricate(:list) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/mutes_spec.rb b/spec/requests/api/v1/mutes_spec.rb new file mode 100644 index 0000000000..9a1d16200a --- /dev/null +++ b/spec/requests/api/v1/mutes_spec.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Mutes' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'read:mutes' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/mutes' do + subject do + get '/api/v1/mutes', headers: headers, params: params + end + + let!(:mutes) { Fabricate.times(3, :mute, account: user.account) } + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write write:mutes' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the muted accounts' do + subject + + muted_accounts = mutes.map(&:target_account) + + expect(body_as_json.pluck(:id)).to match_array(muted_accounts.map { |account| account.id.to_s }) + end + + context 'with limit param' do + let(:params) { { limit: 2 } } + + it 'returns only the requested number of muted accounts' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + + it 'sets the correct pagination headers', :aggregate_failures do + subject + + headers = response.headers['Link'] + + expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_mutes_url(limit: params[:limit], since_id: mutes[2].id.to_s)) + expect(headers.find_link(%w(rel next)).href).to eq(api_v1_mutes_url(limit: params[:limit], max_id: mutes[1].id.to_s)) + end + end + + context 'with max_id param' do + let(:params) { { max_id: mutes[1].id } } + + it 'queries mutes in range according to max_id', :aggregate_failures do + subject + + body = body_as_json + + expect(body.size).to eq 1 + expect(body[0][:id]).to eq mutes[0].target_account_id.to_s + end + end + + context 'with since_id param' do + let(:params) { { since_id: mutes[0].id } } + + it 'queries mutes in range according to since_id', :aggregate_failures do + subject + + body = body_as_json + + expect(body.size).to eq 2 + expect(body[0][:id]).to eq mutes[2].target_account_id.to_s + end + end + + context 'without an authentication header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v1/polls_spec.rb b/spec/requests/api/v1/polls_spec.rb new file mode 100644 index 0000000000..1c8a818d59 --- /dev/null +++ b/spec/requests/api/v1/polls_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Polls' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'read:statuses' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/polls/:id' do + subject do + get "/api/v1/polls/#{poll.id}", headers: headers + end + + let(:poll) { Fabricate(:poll, status: Fabricate(:status, visibility: visibility)) } + let(:visibility) { 'public' } + + it_behaves_like 'forbidden for wrong scope', 'write write:statuses' + + context 'when parent status is public' do + it 'returns the poll data successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to match( + a_hash_including( + id: poll.id.to_s, + voted: false, + voters_count: poll.voters_count, + votes_count: poll.votes_count + ) + ) + end + end + + context 'when parent status is private' do + let(:visibility) { 'private' } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/profiles_spec.rb b/spec/requests/api/v1/profiles_spec.rb new file mode 100644 index 0000000000..26a9b848e5 --- /dev/null +++ b/spec/requests/api/v1/profiles_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Deleting profile images' do + let(:account) do + Fabricate( + :account, + avatar: fixture_file_upload('avatar.gif', 'image/gif'), + header: fixture_file_upload('attachment.jpg', 'image/jpeg') + ) + end + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: account.user.id, scopes: scopes) } + let(:scopes) { 'write:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'DELETE /api/v1/profile' do + before do + allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) + end + + context 'when deleting an avatar' do + context 'with wrong scope' do + before do + delete '/api/v1/profile/avatar', headers: headers + end + + it_behaves_like 'forbidden for wrong scope', 'read' + end + + it 'returns http success' do + delete '/api/v1/profile/avatar', headers: headers + + expect(response).to have_http_status(200) + end + + it 'deletes the avatar' do + delete '/api/v1/profile/avatar', headers: headers + + account.reload + + expect(account.avatar).to_not exist + end + + it 'does not delete the header' do + delete '/api/v1/profile/avatar', headers: headers + + account.reload + + expect(account.header).to exist + end + + it 'queues up an account update distribution' do + delete '/api/v1/profile/avatar', headers: headers + + expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id) + end + end + + context 'when deleting a header' do + context 'with wrong scope' do + before do + delete '/api/v1/profile/header', headers: headers + end + + it_behaves_like 'forbidden for wrong scope', 'read' + end + + it 'returns http success' do + delete '/api/v1/profile/header', headers: headers + + expect(response).to have_http_status(200) + end + + it 'does not delete the avatar' do + delete '/api/v1/profile/header', headers: headers + + account.reload + + expect(account.avatar).to exist + end + + it 'deletes the header' do + delete '/api/v1/profile/header', headers: headers + + account.reload + + expect(account.header).to_not exist + end + + it 'queues up an account update distribution' do + delete '/api/v1/profile/header', headers: headers + + expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id) + end + end + end +end diff --git a/spec/requests/api/v1/statuses/bookmarks_spec.rb b/spec/requests/api/v1/statuses/bookmarks_spec.rb new file mode 100644 index 0000000000..d3007740a5 --- /dev/null +++ b/spec/requests/api/v1/statuses/bookmarks_spec.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Bookmarks' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'write:bookmarks' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'POST /api/v1/statuses/:status_id/bookmark' do + subject do + post "/api/v1/statuses/#{status.id}/bookmark", headers: headers + end + + let(:status) { Fabricate(:status) } + + it_behaves_like 'forbidden for wrong scope', 'read' + + context 'with public status' do + it 'bookmarks the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.bookmarked?(status)).to be true + end + + it 'returns json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, bookmarked: true) + ) + end + end + + context 'with private status of not-followed account' do + let(:status) { Fabricate(:status, visibility: :private) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'with private status of followed account' do + let(:status) { Fabricate(:status, visibility: :private) } + + before do + user.account.follow!(status.account) + end + + it 'bookmarks the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.bookmarked?(status)).to be true + end + end + + context 'when the status does not exist' do + it 'returns http not found' do + post '/api/v1/statuses/-1/bookmark', headers: headers + + expect(response).to have_http_status(404) + end + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end + + describe 'POST /api/v1/statuses/:status_id/unbookmark' do + subject do + post "/api/v1/statuses/#{status.id}/unbookmark", headers: headers + end + + let(:status) { Fabricate(:status) } + + it_behaves_like 'forbidden for wrong scope', 'read' + + context 'with public status' do + context 'when the status was previously bookmarked' do + before do + Bookmark.find_or_create_by!(account: user.account, status: status) + end + + it 'unbookmarks the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.bookmarked?(status)).to be false + end + + it 'returns json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, bookmarked: false) + ) + end + end + + context 'when the requesting user was blocked by the status author' do + let(:status) { Fabricate(:status) } + + before do + Bookmark.find_or_create_by!(account: user.account, status: status) + status.account.block!(user.account) + end + + it 'unbookmarks the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.bookmarked?(status)).to be false + end + + it 'returns json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, bookmarked: false) + ) + end + end + + context 'when the status is not bookmarked' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + end + + context 'with private status that was not bookmarked' do + let(:status) { Fabricate(:status, visibility: :private) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/statuses/favourites_spec.rb b/spec/requests/api/v1/statuses/favourites_spec.rb new file mode 100644 index 0000000000..ac5e86f297 --- /dev/null +++ b/spec/requests/api/v1/statuses/favourites_spec.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Favourites' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'write:favourites' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'POST /api/v1/statuses/:status_id/favourite' do + subject do + post "/api/v1/statuses/#{status.id}/favourite", headers: headers + end + + let(:status) { Fabricate(:status) } + + it_behaves_like 'forbidden for wrong scope', 'read read:favourites' + + context 'with public status' do + it 'favourites the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.favourited?(status)).to be true + end + + it 'returns json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, favourites_count: 1, favourited: true) + ) + end + end + + context 'with private status of not-followed account' do + let(:status) { Fabricate(:status, visibility: :private) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'with private status of followed account' do + let(:status) { Fabricate(:status, visibility: :private) } + + before do + user.account.follow!(status.account) + end + + it 'favourites the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.favourited?(status)).to be true + end + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end + + describe 'POST /api/v1/statuses/:status_id/unfavourite' do + subject do + post "/api/v1/statuses/#{status.id}/unfavourite", headers: headers + end + + let(:status) { Fabricate(:status) } + + around do |example| + Sidekiq::Testing.fake! do + example.run + end + end + + it_behaves_like 'forbidden for wrong scope', 'read read:favourites' + + context 'with public status' do + before do + FavouriteService.new.call(user.account, status) + end + + it 'unfavourites the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.favourited?(status)).to be true + + UnfavouriteWorker.drain + expect(user.account.favourited?(status)).to be false + end + + it 'returns json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, favourites_count: 0, favourited: false) + ) + end + end + + context 'when the requesting user was blocked by the status author' do + before do + FavouriteService.new.call(user.account, status) + status.account.block!(user.account) + end + + it 'unfavourites the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.favourited?(status)).to be true + + UnfavouriteWorker.drain + expect(user.account.favourited?(status)).to be false + end + + it 'returns json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, favourites_count: 0, favourited: false) + ) + end + end + + context 'when status is not favourited' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + + context 'with private status that was not favourited' do + let(:status) { Fabricate(:status, visibility: :private) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/statuses/pins_spec.rb b/spec/requests/api/v1/statuses/pins_spec.rb new file mode 100644 index 0000000000..db07fa424f --- /dev/null +++ b/spec/requests/api/v1/statuses/pins_spec.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Pins' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'write:accounts' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'POST /api/v1/statuses/:status_id/pin' do + subject do + post "/api/v1/statuses/#{status.id}/pin", headers: headers + end + + let(:status) { Fabricate(:status, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'read read:accounts' + + context 'when the status is public' do + it 'pins the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.pinned?(status)).to be true + end + + it 'return json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, pinned: true) + ) + end + end + + context 'when the status is private' do + let(:status) { Fabricate(:status, account: user.account, visibility: :private) } + + it 'pins the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.pinned?(status)).to be true + end + end + + context 'when the status belongs to somebody else' do + let(:status) { Fabricate(:status) } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the status does not exist' do + it 'returns http not found' do + post '/api/v1/statuses/-1/pin', headers: headers + + expect(response).to have_http_status(404) + end + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end + + describe 'POST /api/v1/statuses/:status_id/unpin' do + subject do + post "/api/v1/statuses/#{status.id}/unpin", headers: headers + end + + let(:status) { Fabricate(:status, account: user.account) } + + context 'when the status is pinned' do + before do + Fabricate(:status_pin, status: status, account: user.account) + end + + it 'unpins the status successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(user.account.pinned?(status)).to be false + end + + it 'return json with updated attributes' do + subject + + expect(body_as_json).to match( + a_hash_including(id: status.id.to_s, pinned: false) + ) + end + end + + context 'when the status is not pinned' do + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + + context 'when the status does not exist' do + it 'returns http not found' do + post '/api/v1/statuses/-1/unpin', headers: headers + + expect(response).to have_http_status(404) + end + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v1/suggestions_spec.rb b/spec/requests/api/v1/suggestions_spec.rb new file mode 100644 index 0000000000..42b7f86629 --- /dev/null +++ b/spec/requests/api/v1/suggestions_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Suggestions' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/suggestions' do + subject do + get '/api/v1/suggestions', headers: headers, params: params + end + + let(:bob) { Fabricate(:account) } + let(:jeff) { Fabricate(:account) } + let(:params) { {} } + + before do + PotentialFriendshipTracker.record(user.account_id, bob.id, :reblog) + PotentialFriendshipTracker.record(user.account_id, jeff.id, :favourite) + end + + it_behaves_like 'forbidden for wrong scope', 'write' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns accounts' do + subject + + body = body_as_json + + expect(body.size).to eq 2 + expect(body.pluck(:id)).to match_array([bob, jeff].map { |i| i.id.to_s }) + end + + context 'with limit param' do + let(:params) { { limit: 1 } } + + it 'returns only the requested number of accounts' do + subject + + expect(body_as_json.size).to eq 1 + end + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end + + describe 'DELETE /api/v1/suggestions/:id' do + subject do + delete "/api/v1/suggestions/#{jeff.id}", headers: headers + end + + let(:suggestions_source) { instance_double(AccountSuggestions::PastInteractionsSource, remove: nil) } + let(:bob) { Fabricate(:account) } + let(:jeff) { Fabricate(:account) } + + before do + PotentialFriendshipTracker.record(user.account_id, bob.id, :reblog) + PotentialFriendshipTracker.record(user.account_id, jeff.id, :favourite) + allow(AccountSuggestions::PastInteractionsSource).to receive(:new).and_return(suggestions_source) + end + + it_behaves_like 'forbidden for wrong scope', 'write' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'removes the specified suggestion' do + subject + + expect(suggestions_source).to have_received(:remove).with(user.account, jeff.id.to_s).once + expect(suggestions_source).to_not have_received(:remove).with(user.account, bob.id.to_s) + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v1/tags_spec.rb b/spec/requests/api/v1/tags_spec.rb new file mode 100644 index 0000000000..300ddf805c --- /dev/null +++ b/spec/requests/api/v1/tags_spec.rb @@ -0,0 +1,169 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Tags' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'write:follows' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/tags/:id' do + subject do + get "/api/v1/tags/#{name}" + end + + context 'when the tag exists' do + let!(:tag) { Fabricate(:tag) } + let(:name) { tag.name } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the tag' do + subject + + expect(body_as_json[:name]).to eq(name) + end + end + + context 'when the tag does not exist' do + let(:name) { 'hoge' } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + end + + context 'when the tag name is invalid' do + let(:name) { 'tag-name' } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + describe 'POST /api/v1/tags/:id/follow' do + subject do + post "/api/v1/tags/#{name}/follow", headers: headers + end + + let!(:tag) { Fabricate(:tag) } + let(:name) { tag.name } + + it_behaves_like 'forbidden for wrong scope', 'read read:follows' + + context 'when the tag exists' do + it 'returns http success' do + subject + + expect(response).to have_http_status(:success) + end + + it 'creates follow' do + subject + + expect(TagFollow.where(tag: tag, account: user.account)).to exist + end + end + + context 'when the tag does not exist' do + let(:name) { 'hoge' } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'creates a new tag with the specified name' do + subject + + expect(Tag.where(name: name)).to exist + end + + it 'creates follow' do + subject + + expect(TagFollow.where(tag: Tag.find_by(name: name), account: user.account)).to exist + end + end + + context 'when the tag name is invalid' do + let(:name) { 'tag-name' } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'when the Authorization header is missing' do + let(:headers) { {} } + let(:name) { 'unauthorized' } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end + + describe 'POST #unfollow' do + subject do + post "/api/v1/tags/#{name}/unfollow", headers: headers + end + + let(:name) { tag.name } + let!(:tag) { Fabricate(:tag, name: 'foo') } + + before do + Fabricate(:tag_follow, account: user.account, tag: tag) + end + + it_behaves_like 'forbidden for wrong scope', 'read read:follows' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'removes the follow' do + subject + + expect(TagFollow.where(tag: tag, account: user.account)).to_not exist + end + + context 'when the tag name is invalid' do + let(:name) { 'tag-name' } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'when the Authorization header is missing' do + let(:headers) { {} } + let(:name) { 'unauthorized' } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + end +end diff --git a/spec/requests/api/v1/timelines/home_spec.rb b/spec/requests/api/v1/timelines/home_spec.rb new file mode 100644 index 0000000000..5834b90955 --- /dev/null +++ b/spec/requests/api/v1/timelines/home_spec.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Home' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'read:statuses' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/timelines/home' do + subject do + get '/api/v1/timelines/home', headers: headers, params: params + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'write write:statuses' + + context 'when the timeline is available' do + let(:home_statuses) { bob.statuses + ana.statuses } + let!(:bob) { Fabricate(:account) } + let!(:tim) { Fabricate(:account) } + let!(:ana) { Fabricate(:account) } + + before do + user.account.follow!(bob) + user.account.follow!(ana) + PostStatusService.new.call(bob, text: 'New toot from bob.') + PostStatusService.new.call(tim, text: 'New toot from tim.') + PostStatusService.new.call(ana, text: 'New toot from ana.') + end + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the statuses of followed users' do + subject + + expect(body_as_json.pluck(:id)).to match_array(home_statuses.map { |status| status.id.to_s }) + end + + context 'with limit param' do + let(:params) { { limit: 1 } } + + it 'returns only the requested number of statuses' do + subject + + expect(body_as_json.size).to eq(params[:limit]) + end + + it 'sets the correct pagination headers', :aggregate_failures do + subject + + headers = response.headers['Link'] + + expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_timelines_home_url(limit: 1, min_id: ana.statuses.first.id.to_s)) + expect(headers.find_link(%w(rel next)).href).to eq(api_v1_timelines_home_url(limit: 1, max_id: ana.statuses.first.id.to_s)) + end + end + end + + context 'when the timeline is regenerating' do + let(:timeline) { instance_double(HomeFeed, regenerating?: true, get: []) } + + before do + allow(HomeFeed).to receive(:new).and_return(timeline) + end + + it 'returns http partial content' do + subject + + expect(response).to have_http_status(206) + end + end + + context 'without an authorization header' do + let(:headers) { {} } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + + context 'without a user context' do + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: scopes) } + + it 'returns http unprocessable entity', :aggregate_failures do + subject + + expect(response).to have_http_status(422) + expect(response.headers['Link']).to be_nil + end + end + end +end diff --git a/spec/requests/api/v1/timelines/public_spec.rb b/spec/requests/api/v1/timelines/public_spec.rb new file mode 100644 index 0000000000..4afa40e580 --- /dev/null +++ b/spec/requests/api/v1/timelines/public_spec.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Public' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'read:statuses' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + shared_examples 'a successful request to the public timeline' do + it 'returns the expected statuses successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json.pluck(:id)).to match_array(expected_statuses.map { |status| status.id.to_s }) + end + end + + describe 'GET /api/v1/timelines/public' do + subject do + get '/api/v1/timelines/public', headers: headers, params: params + end + + let!(:private_status) { Fabricate(:status, visibility: :private) } # rubocop:disable RSpec/LetSetup + let!(:local_status) { Fabricate(:status, account: Fabricate.build(:account, domain: nil)) } + let!(:remote_status) { Fabricate(:status, account: Fabricate.build(:account, domain: 'example.com')) } + let!(:media_status) { Fabricate(:status, media_attachments: [Fabricate.build(:media_attachment)]) } + + let(:params) { {} } + + context 'when the instance allows public preview' do + let(:expected_statuses) { [local_status, remote_status, media_status] } + + before do + Setting.timeline_preview = true + end + + context 'with an authorized user' do + it_behaves_like 'a successful request to the public timeline' + end + + context 'with an anonymous user' do + let(:headers) { {} } + + it_behaves_like 'a successful request to the public timeline' + end + + context 'with local param' do + let(:params) { { local: true } } + let(:expected_statuses) { [local_status, media_status] } + + it_behaves_like 'a successful request to the public timeline' + end + + context 'with remote param' do + let(:params) { { remote: true } } + let(:expected_statuses) { [remote_status] } + + it_behaves_like 'a successful request to the public timeline' + end + + context 'with local and remote params' do + let(:params) { { local: true, remote: true } } + let(:expected_statuses) { [local_status, remote_status, media_status] } + + it_behaves_like 'a successful request to the public timeline' + end + + context 'with only_media param' do + let(:params) { { only_media: true } } + let(:expected_statuses) { [media_status] } + + it_behaves_like 'a successful request to the public timeline' + end + + context 'with limit param' do + let(:params) { { limit: 1 } } + + it 'returns only the requested number of statuses', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json.size).to eq(params[:limit]) + end + + it 'sets the correct pagination headers', :aggregate_failures do + subject + + headers = response.headers['Link'] + + expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_timelines_public_url(limit: 1, min_id: media_status.id.to_s)) + expect(headers.find_link(%w(rel next)).href).to eq(api_v1_timelines_public_url(limit: 1, max_id: media_status.id.to_s)) + end + end + end + + context 'when the instance does not allow public preview' do + before do + Form::AdminSettings.new(timeline_preview: false).save + end + + context 'with an authenticated user' do + let(:expected_statuses) { [local_status, remote_status, media_status] } + + it_behaves_like 'a successful request to the public timeline' + end + + context 'with an unauthenticated user' do + let(:headers) { {} } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + end +end diff --git a/spec/requests/api/v2/filters/filters_spec.rb b/spec/requests/api/v2/filters/filters_spec.rb new file mode 100644 index 0000000000..2ee24d8095 --- /dev/null +++ b/spec/requests/api/v2/filters/filters_spec.rb @@ -0,0 +1,248 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Filters' do + let(:user) { Fabricate(:user) } + let(:scopes) { 'read:filters write:filters' } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + shared_examples 'unauthorized for invalid token' do + let(:headers) { { 'Authorization' => '' } } + + it 'returns http unauthorized' do + subject + + expect(response).to have_http_status(401) + end + end + + describe 'GET /api/v2/filters' do + subject do + get '/api/v2/filters', headers: headers + end + + let!(:filters) { Fabricate.times(3, :custom_filter, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'write write:filters' + it_behaves_like 'unauthorized for invalid token' + + it 'returns the existing filters successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json.pluck(:id)).to match_array(filters.map { |filter| filter.id.to_s }) + end + end + + describe 'POST /api/v2/filters' do + subject do + post '/api/v2/filters', params: params, headers: headers + end + + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'read read:filters' + it_behaves_like 'unauthorized for invalid token' + + context 'with valid params' do + let(:params) { { title: 'magic', context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns a filter with keywords', :aggregate_failures do + subject + + json = body_as_json + + expect(json[:title]).to eq 'magic' + expect(json[:filter_action]).to eq 'hide' + expect(json[:context]).to eq ['home'] + expect(json[:keywords].map { |keyword| keyword.slice(:keyword, :whole_word) }).to eq [{ keyword: 'magic', whole_word: true }] + end + + it 'creates a filter', :aggregate_failures do + subject + + filter = user.account.custom_filters.first + + expect(filter).to be_present + expect(filter.keywords.pluck(:keyword)).to eq ['magic'] + expect(filter.context).to eq %w(home) + expect(filter.irreversible?).to be true + expect(filter.expires_at).to be_nil + end + end + + context 'when the required title param is missing' do + let(:params) { { context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the required context param is missing' do + let(:params) { { title: 'magic', filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + + context 'when the given context value is invalid' do + let(:params) { { title: 'magic', context: %w(shaolin), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + describe 'GET /api/v2/filters/:id' do + subject do + get "/api/v2/filters/#{filter.id}", headers: headers + end + + let(:filter) { Fabricate(:custom_filter, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'write write:filters' + it_behaves_like 'unauthorized for invalid token' + + it 'returns the filter successfully', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json[:id]).to eq(filter.id.to_s) + end + + context 'when the filter belongs to someone else' do + let(:filter) { Fabricate(:custom_filter) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + describe 'PUT /api/v2/filters/:id' do + subject do + put "/api/v2/filters/#{filter.id}", params: params, headers: headers + end + + let!(:filter) { Fabricate(:custom_filter, account: user.account) } + let!(:keyword) { Fabricate(:custom_filter_keyword, custom_filter: filter) } + let(:params) { {} } + + it_behaves_like 'forbidden for wrong scope', 'read read:filters' + it_behaves_like 'unauthorized for invalid token' + + context 'when updating filter parameters' do + context 'with valid params' do + let(:params) { { title: 'updated', context: %w(home public) } } + + it 'updates the filter successfully', :aggregate_failures do + subject + + filter.reload + + expect(response).to have_http_status(200) + expect(filter.title).to eq 'updated' + expect(filter.reload.context).to eq %w(home public) + end + end + + context 'with invalid params' do + let(:params) { { title: 'updated', context: %w(word) } } + + it 'returns http unprocessable entity' do + subject + + expect(response).to have_http_status(422) + end + end + end + + context 'when updating keywords in bulk' do + let(:params) { { keywords_attributes: [{ id: keyword.id, keyword: 'updated' }] } } + + before do + allow(redis).to receive_messages(publish: nil) + end + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'updates the keyword' do + subject + + expect(keyword.reload.keyword).to eq 'updated' + end + + it 'sends exactly one filters_changed event' do + subject + + expect(redis).to have_received(:publish).with("timeline:#{user.account.id}", Oj.dump(event: :filters_changed)).once + end + end + + context 'when the filter belongs to someone else' do + let(:filter) { Fabricate(:custom_filter) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + describe 'DELETE /api/v2/filters/:id' do + subject do + delete "/api/v2/filters/#{filter.id}", headers: headers + end + + let(:filter) { Fabricate(:custom_filter, account: user.account) } + + it_behaves_like 'forbidden for wrong scope', 'read read:filters' + it_behaves_like 'unauthorized for invalid token' + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'removes the filter' do + subject + + expect { filter.reload }.to raise_error ActiveRecord::RecordNotFound + end + + context 'when the filter belongs to someone else' do + let(:filter) { Fabricate(:custom_filter) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v2/media_spec.rb b/spec/requests/api/v2/media_spec.rb new file mode 100644 index 0000000000..89384d0ca3 --- /dev/null +++ b/spec/requests/api/v2/media_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Media API', paperclip_processing: true do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'write' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'POST /api/v2/media' do + it 'returns http success' do + post '/api/v2/media', headers: headers, params: { file: fixture_file_upload('attachment-jpg.123456_abcd', 'image/jpeg') } + expect(File.exist?(user.account.media_attachments.first.file.path(:small))).to be true + expect(response).to have_http_status(200) + end + end +end diff --git a/spec/requests/api/web/embeds_spec.rb b/spec/requests/api/web/embeds_spec.rb new file mode 100644 index 0000000000..6314f43aaf --- /dev/null +++ b/spec/requests/api/web/embeds_spec.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe '/api/web/embed' do + subject { get "/api/web/embeds/#{id}", headers: headers } + + context 'when accessed anonymously' do + let(:headers) { {} } + + context 'when the requested status is local' do + let(:id) { status.id } + + context 'when the requested status is public' do + let(:status) { Fabricate(:status, visibility: :public) } + + it 'returns JSON with an html attribute' do + subject + + expect(response).to have_http_status(200) + expect(body_as_json[:html]).to be_present + end + end + + context 'when the requested status is private' do + let(:status) { Fabricate(:status, visibility: :private) } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + context 'when the requested status is remote' do + let(:remote_account) { Fabricate(:account, domain: 'example.com') } + let(:status) { Fabricate(:status, visibility: :public, account: remote_account, url: 'https://example.com/statuses/1') } + let(:id) { status.id } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'when the requested status does not exist' do + let(:id) { -1 } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + context 'with an API token' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + context 'when the requested status is local' do + let(:id) { status.id } + + context 'when the requested status is public' do + let(:status) { Fabricate(:status, visibility: :public) } + + it 'returns JSON with an html attribute' do + subject + + expect(response).to have_http_status(200) + expect(body_as_json[:html]).to be_present + end + + context 'when the requesting user is blocked' do + before do + status.account.block!(user.account) + end + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + context 'when the requested status is private' do + let(:status) { Fabricate(:status, visibility: :private) } + + before do + user.account.follow!(status.account) + end + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + context 'when the requested status is remote' do + let(:remote_account) { Fabricate(:account, domain: 'example.com') } + let(:status) { Fabricate(:status, visibility: :public, account: remote_account, url: 'https://example.com/statuses/1') } + let(:id) { status.id } + + let(:service_instance) { instance_double(FetchOEmbedService) } + + before do + allow(FetchOEmbedService).to receive(:new) { service_instance } + allow(service_instance).to receive(:call) { call_result } + end + + context 'when the requesting user is blocked' do + before do + status.account.block!(user.account) + end + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + + context 'when successfully fetching OEmbed' do + let(:call_result) { { html: 'ok' } } + + it 'returns JSON with an html attribute' do + subject + + expect(response).to have_http_status(200) + expect(body_as_json[:html]).to be_present + end + end + + context 'when failing to fetch OEmbed' do + let(:call_result) { nil } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end + + context 'when the requested status does not exist' do + let(:id) { -1 } + + it 'returns http not found' do + subject + + expect(response).to have_http_status(404) + end + end + end +end diff --git a/spec/requests/backups_spec.rb b/spec/requests/backups_spec.rb new file mode 100644 index 0000000000..a6c2efe0db --- /dev/null +++ b/spec/requests/backups_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Backups' do + include RoutingHelper + + describe 'GET backups#download' do + let(:user) { Fabricate(:user) } + let(:backup) { Fabricate(:backup, user: user) } + + before do + sign_in user + end + + it 'Downloads a user backup' do + get download_backup_path(backup) + + expect(response).to redirect_to(backup_dump_url) + end + + def backup_dump_url + full_asset_url(backup.dump.url) + end + end +end diff --git a/spec/requests/cache_spec.rb b/spec/requests/cache_spec.rb new file mode 100644 index 0000000000..c391c8b3da --- /dev/null +++ b/spec/requests/cache_spec.rb @@ -0,0 +1,686 @@ +# frozen_string_literal: true + +require 'rails_helper' + +module TestEndpoints + # Endpoints that do not include authorization-dependent results + # and should be cacheable no matter what. + ALWAYS_CACHED = %w( + /.well-known/host-meta + /.well-known/nodeinfo + /nodeinfo/2.0 + /manifest + /custom.css + /actor + /api/v1/instance/extended_description + /api/v1/instance/rules + /api/v1/instance/peers + /api/v1/instance + /api/v2/instance + ).freeze + + # Endpoints that should be cachable when accessed anonymously but have a Vary + # on Cookie to prevent logged-in users from getting values from logged-out cache. + COOKIE_DEPENDENT_CACHABLE = %w( + / + /explore + /public + /about + /privacy-policy + /directory + /@alice + /@alice/110224538612341312 + /deck/home + ).freeze + + # Endpoints that should be cachable when accessed anonymously but have a Vary + # on Authorization to prevent logged-in users from getting values from logged-out cache. + AUTHORIZATION_DEPENDENT_CACHABLE = %w( + /api/v1/accounts/lookup?acct=alice + /api/v1/statuses/110224538612341312 + /api/v1/statuses/110224538612341312/context + /api/v1/polls/12345 + /api/v1/trends/statuses + /api/v1/directory + ).freeze + + # Private status that should only be returned with to a valid signature from + # a specific user. + # Should never be cached. + REQUIRE_SIGNATURE = %w( + /users/alice/statuses/110224538643211312 + ).freeze + + # Pages only available to logged-in users. + # Should never be cached. + REQUIRE_LOGIN = %w( + /settings/preferences/appearance + /settings/profile + /settings/featured_tags + /settings/export + /relationships + /filters + /statuses_cleanup + /auth/edit + /oauth/authorized_applications + /admin/dashboard + ).freeze + + # API endpoints only available to logged-in users. + # Should never be cached. + REQUIRE_TOKEN = %w( + /api/v1/announcements + /api/v1/timelines/home + /api/v1/notifications + /api/v1/bookmarks + /api/v1/favourites + /api/v1/follow_requests + /api/v1/conversations + /api/v1/statuses/110224538643211312 + /api/v1/statuses/110224538643211312/context + /api/v1/lists + /api/v2/filters + ).freeze + + # Pages that are only shown to logged-out users, and should never get cached + # because of CSRF protection. + REQUIRE_LOGGED_OUT = %w( + /invite/abcdef + /auth/sign_in + /auth/sign_up + /auth/password/new + /auth/confirmation/new + ).freeze + + # Non-exhaustive list of endpoints that feature language-dependent results + # and thus need to have a Vary on Accept-Language + LANGUAGE_DEPENDENT = %w( + / + /explore + /about + /api/v1/trends/statuses + ).freeze + + module AuthorizedFetch + # Endpoints that require a signature with AUTHORIZED_FETCH and LIMITED_FEDERATION_MODE + # and thus should not be cached in those modes. + REQUIRE_SIGNATURE = %w( + /users/alice + ).freeze + end + + module DisabledAnonymousAPI + # Endpoints that require a signature with DISALLOW_UNAUTHENTICATED_API_ACCESS + # and thus should not be cached in this mode. + REQUIRE_TOKEN = %w( + /api/v1/custom_emojis + ).freeze + end +end + +describe 'Caching behavior' do + shared_examples 'cachable response' do + it 'does not set cookies' do + expect(response.cookies).to be_empty + end + + it 'sets public cache control' do + # expect(response.cache_control[:max_age]&.to_i).to be_positive + expect(response.cache_control[:public]).to be_truthy + expect(response.cache_control[:private]).to be_falsy + expect(response.cache_control[:no_store]).to be_falsy + expect(response.cache_control[:no_cache]).to be_falsy + end + end + + shared_examples 'non-cacheable response' do + it 'sets private cache control' do + expect(response.cache_control[:private]).to be_truthy + expect(response.cache_control[:no_store]).to be_truthy + end + end + + shared_examples 'non-cacheable error' do + it 'does not return HTTP success' do + expect(response).to_not have_http_status(200) + end + + it 'does not have cache headers' do + expect(response.cache_control[:public]).to be_falsy + end + end + + shared_examples 'language-dependent' do + it 'has a Vary on Accept-Language' do + expect(response.headers['Vary']&.split(',')&.map { |x| x.strip.downcase }).to include('accept-language') + end + end + + # Enable CSRF protection like it is in production, as it can cause cookies + # to be set and thus mess with cache. + around do |example| + old = ActionController::Base.allow_forgery_protection + ActionController::Base.allow_forgery_protection = true + + example.run + + ActionController::Base.allow_forgery_protection = old + end + + let(:alice) { Fabricate(:account, username: 'alice') } + let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Moderator')) } + + before do + # rubocop:disable Style/NumericLiterals + status = Fabricate(:status, account: alice, id: 110224538612341312) + Fabricate(:status, account: alice, id: 110224538643211312, visibility: :private) + Fabricate(:invite, code: 'abcdef') + Fabricate(:poll, status: status, account: alice, id: 12345) + # rubocop:enable Style/NumericLiterals + + user.account.follow!(alice) + end + + context 'when anonymously accessed' do + TestEndpoints::ALWAYS_CACHED.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'cachable response' + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::COOKIE_DEPENDENT_CACHABLE.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'cachable response' + + it 'has a Vary on Cookie' do + expect(response.headers['Vary']&.split(',')&.map { |x| x.strip.downcase }).to include('cookie') + end + + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::AUTHORIZATION_DEPENDENT_CACHABLE.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'cachable response' + + it 'has a Vary on Authorization' do + expect(response.headers['Vary']&.split(',')&.map { |x| x.strip.downcase }).to include('authorization') + end + + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::REQUIRE_LOGGED_OUT.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable response' + end + end + + (TestEndpoints::REQUIRE_SIGNATURE + TestEndpoints::REQUIRE_LOGIN + TestEndpoints::REQUIRE_TOKEN).each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable error' + end + end + + describe '/api/v1/instance/domain_blocks' do + around do |example| + old_setting = Setting.show_domain_blocks + Setting.show_domain_blocks = show_domain_blocks + + example.run + + Setting.show_domain_blocks = old_setting + end + + before { get '/api/v1/instance/domain_blocks' } + + context 'when set to be publicly-available' do + let(:show_domain_blocks) { 'all' } + + it_behaves_like 'cachable response' + end + + context 'when allowed for local users only' do + let(:show_domain_blocks) { 'users' } + + it_behaves_like 'non-cacheable error' + end + + context 'when disabled' do + let(:show_domain_blocks) { 'disabled' } + + it_behaves_like 'non-cacheable error' + end + end + end + + context 'when logged in' do + before do + sign_in user, scope: :user + + # Unfortunately, devise's `sign_in` helper causes the `session` to be + # loaded in the next request regardless of whether it's actually accessed + # by the client code. + # + # So, we make an extra query to clear issue a session cookie instead. + # + # A less resource-intensive way to deal with that would be to generate the + # session cookie manually, but this seems pretty involved. + get '/' + end + + TestEndpoints::ALWAYS_CACHED.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'cachable response' + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::COOKIE_DEPENDENT_CACHABLE.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable response' + + it 'has a Vary on Cookie' do + expect(response.headers['Vary']&.split(',')&.map { |x| x.strip.downcase }).to include('cookie') + end + end + end + + TestEndpoints::REQUIRE_LOGIN.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + end + + TestEndpoints::REQUIRE_LOGGED_OUT.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable error' + end + end + end + + context 'with an auth token' do + let!(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') } + + TestEndpoints::ALWAYS_CACHED.each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Authorization' => "Bearer #{token.token}" } + end + + it_behaves_like 'cachable response' + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::AUTHORIZATION_DEPENDENT_CACHABLE.each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Authorization' => "Bearer #{token.token}" } + end + + it_behaves_like 'non-cacheable response' + + it 'has a Vary on Authorization' do + expect(response.headers['Vary']&.split(',')&.map { |x| x.strip.downcase }).to include('authorization') + end + end + end + + (TestEndpoints::REQUIRE_LOGGED_OUT + TestEndpoints::REQUIRE_TOKEN).each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Authorization' => "Bearer #{token.token}" } + end + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + end + + describe '/api/v1/instance/domain_blocks' do + around do |example| + old_setting = Setting.show_domain_blocks + Setting.show_domain_blocks = show_domain_blocks + + example.run + + Setting.show_domain_blocks = old_setting + end + + before do + get '/api/v1/instance/domain_blocks', headers: { 'Authorization' => "Bearer #{token.token}" } + end + + context 'when set to be publicly-available' do + let(:show_domain_blocks) { 'all' } + + it_behaves_like 'cachable response' + end + + context 'when allowed for local users only' do + let(:show_domain_blocks) { 'users' } + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + context 'when disabled' do + let(:show_domain_blocks) { 'disabled' } + + it_behaves_like 'non-cacheable error' + end + end + end + + context 'with a Signature header' do + let(:remote_actor) { Fabricate(:account, domain: 'example.org', uri: 'https://example.org/remote', protocol: :activitypub) } + let(:dummy_signature) { 'dummy-signature' } + + before do + remote_actor.follow!(alice) + end + + describe '/actor' do + before do + get '/actor', sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'cachable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + TestEndpoints::REQUIRE_SIGNATURE.each do |endpoint| + describe endpoint do + before do + get endpoint, sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + end + end + + context 'when enabling AUTHORIZED_FETCH mode' do + around do |example| + ClimateControl.modify AUTHORIZED_FETCH: 'true' do + example.run + end + end + + context 'when not providing a Signature' do + describe '/actor' do + before do + get '/actor', headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'cachable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + (TestEndpoints::REQUIRE_SIGNATURE + TestEndpoints::AuthorizedFetch::REQUIRE_SIGNATURE).each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'non-cacheable error' + end + end + end + + context 'when providing a Signature' do + let(:remote_actor) { Fabricate(:account, domain: 'example.org', uri: 'https://example.org/remote', protocol: :activitypub) } + let(:dummy_signature) { 'dummy-signature' } + + before do + remote_actor.follow!(alice) + end + + describe '/actor' do + before do + get '/actor', sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'cachable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + (TestEndpoints::REQUIRE_SIGNATURE + TestEndpoints::AuthorizedFetch::REQUIRE_SIGNATURE).each do |endpoint| + describe endpoint do + before do + get endpoint, sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + end + end + end + + context 'when enabling LIMITED_FEDERATION_MODE mode' do + around do |example| + ClimateControl.modify LIMITED_FEDERATION_MODE: 'true' do + old_limited_federation_mode = Rails.configuration.x.limited_federation_mode + Rails.configuration.x.limited_federation_mode = true + + example.run + + Rails.configuration.x.limited_federation_mode = old_limited_federation_mode + end + end + + context 'when not providing a Signature' do + describe '/actor' do + before do + get '/actor', headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'cachable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + (TestEndpoints::REQUIRE_SIGNATURE + TestEndpoints::AuthorizedFetch::REQUIRE_SIGNATURE).each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'non-cacheable error' + end + end + end + + context 'when providing a Signature from an allowed domain' do + let(:remote_actor) { Fabricate(:account, domain: 'example.org', uri: 'https://example.org/remote', protocol: :activitypub) } + let(:dummy_signature) { 'dummy-signature' } + + before do + DomainAllow.create!(domain: remote_actor.domain) + remote_actor.follow!(alice) + end + + describe '/actor' do + before do + get '/actor', sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'cachable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + (TestEndpoints::REQUIRE_SIGNATURE + TestEndpoints::AuthorizedFetch::REQUIRE_SIGNATURE).each do |endpoint| + describe endpoint do + before do + get endpoint, sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + end + end + + context 'when providing a Signature from a non-allowed domain' do + let(:remote_actor) { Fabricate(:account, domain: 'example.org', uri: 'https://example.org/remote', protocol: :activitypub) } + let(:dummy_signature) { 'dummy-signature' } + + describe '/actor' do + before do + get '/actor', sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'cachable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + + (TestEndpoints::REQUIRE_SIGNATURE + TestEndpoints::AuthorizedFetch::REQUIRE_SIGNATURE).each do |endpoint| + describe endpoint do + before do + get endpoint, sign_with: remote_actor, headers: { 'Accept' => 'application/activity+json' } + end + + it_behaves_like 'non-cacheable error' + end + end + end + end + + context 'when enabling DISALLOW_UNAUTHENTICATED_API_ACCESS' do + around do |example| + ClimateControl.modify DISALLOW_UNAUTHENTICATED_API_ACCESS: 'true' do + example.run + end + end + + context 'when anonymously accessed' do + TestEndpoints::ALWAYS_CACHED.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'cachable response' + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::REQUIRE_LOGGED_OUT.each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable response' + end + end + + (TestEndpoints::REQUIRE_TOKEN + TestEndpoints::AUTHORIZATION_DEPENDENT_CACHABLE + TestEndpoints::DisabledAnonymousAPI::REQUIRE_TOKEN).each do |endpoint| + describe endpoint do + before { get endpoint } + + it_behaves_like 'non-cacheable error' + end + end + end + + context 'with an auth token' do + let!(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') } + + TestEndpoints::ALWAYS_CACHED.each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Authorization' => "Bearer #{token.token}" } + end + + it_behaves_like 'cachable response' + it_behaves_like 'language-dependent' if TestEndpoints::LANGUAGE_DEPENDENT.include?(endpoint) + end + end + + TestEndpoints::AUTHORIZATION_DEPENDENT_CACHABLE.each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Authorization' => "Bearer #{token.token}" } + end + + it_behaves_like 'non-cacheable response' + + it 'has a Vary on Authorization' do + expect(response.headers['Vary']&.split(',')&.map { |x| x.strip.downcase }).to include('authorization') + end + end + end + + (TestEndpoints::REQUIRE_LOGGED_OUT + TestEndpoints::REQUIRE_TOKEN + TestEndpoints::DisabledAnonymousAPI::REQUIRE_TOKEN).each do |endpoint| + describe endpoint do + before do + get endpoint, headers: { 'Authorization' => "Bearer #{token.token}" } + end + + it_behaves_like 'non-cacheable response' + + it 'returns HTTP success' do + expect(response).to have_http_status(200) + end + end + end + end + end +end diff --git a/spec/requests/catch_all_route_request_spec.rb b/spec/requests/catch_all_route_request_spec.rb index f965f55221..e600bedfe0 100644 --- a/spec/requests/catch_all_route_request_spec.rb +++ b/spec/requests/catch_all_route_request_spec.rb @@ -1,21 +1,23 @@ -require "rails_helper" +# frozen_string_literal: true -describe "The catch all route" do - describe "with a simple value" do - it "returns a 404 page as html" do - get "/test" +require 'rails_helper' - expect(response.status).to eq 404 - expect(response.media_type).to eq "text/html" +describe 'The catch all route' do + describe 'with a simple value' do + it 'returns a 404 page as html' do + get '/test' + + expect(response).to have_http_status 404 + expect(response.media_type).to eq 'text/html' end end - describe "with an implied format" do - it "returns a 404 page as html" do - get "/test.test" + describe 'with an implied format' do + it 'returns a 404 page as html' do + get '/test.test' - expect(response.status).to eq 404 - expect(response.media_type).to eq "text/html" + expect(response).to have_http_status 404 + expect(response.media_type).to eq 'text/html' end end end diff --git a/spec/requests/content_security_policy_spec.rb b/spec/requests/content_security_policy_spec.rb new file mode 100644 index 0000000000..d327ac1b45 --- /dev/null +++ b/spec/requests/content_security_policy_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Content-Security-Policy' do + it 'sets the expected CSP headers' do + allow(SecureRandom).to receive(:base64).with(16).and_return('ZbA+JmE7+bK8F5qvADZHuQ==') + + get '/' + expect(response.headers['Content-Security-Policy'].split(';').map(&:strip)).to contain_exactly( + "base-uri 'none'", + "default-src 'none'", + "frame-ancestors 'none'", + "font-src 'self' https://cb6e6126.ngrok.io", + "img-src 'self' data: blob: https://cb6e6126.ngrok.io", + "style-src 'self' https://cb6e6126.ngrok.io 'nonce-ZbA+JmE7+bK8F5qvADZHuQ=='", + "media-src 'self' data: https://cb6e6126.ngrok.io", + "frame-src 'self' https:", + "manifest-src 'self' https://cb6e6126.ngrok.io", + "form-action 'self'", + "child-src 'self' blob: https://cb6e6126.ngrok.io", + "worker-src 'self' blob: https://cb6e6126.ngrok.io", + "connect-src 'self' blob: data: ws://localhost:4000 https://cb6e6126.ngrok.io", + "script-src 'self' https://cb6e6126.ngrok.io 'wasm-unsafe-eval'" + ) + end +end diff --git a/spec/requests/follower_accounts_spec.rb b/spec/requests/follower_accounts_spec.rb new file mode 100644 index 0000000000..52e86e13fe --- /dev/null +++ b/spec/requests/follower_accounts_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'FollowerAccountsController' do + describe 'The follower_accounts route' do + it "returns a http 'moved_permanently' code" do + get '/users/:username/followers' + + expect(response).to have_http_status(301) + end + end +end diff --git a/spec/requests/following_accounts_spec.rb b/spec/requests/following_accounts_spec.rb new file mode 100644 index 0000000000..f0955ceb36 --- /dev/null +++ b/spec/requests/following_accounts_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'FollowingAccountsController' do + describe 'The following_accounts route' do + it "returns a http 'moved_permanently' code" do + get '/users/:username/following' + + expect(response).to have_http_status(301) + end + end +end diff --git a/spec/requests/host_meta_request_spec.rb b/spec/requests/host_meta_request_spec.rb index 0ca6414613..ec26ecba7d 100644 --- a/spec/requests/host_meta_request_spec.rb +++ b/spec/requests/host_meta_request_spec.rb @@ -1,12 +1,14 @@ -require "rails_helper" +# frozen_string_literal: true -describe "The host_meta route" do - describe "requested without accepts headers" do - it "returns an xml response" do +require 'rails_helper' + +describe 'The host_meta route' do + describe 'requested without accepts headers' do + it 'returns an xml response' do get host_meta_url expect(response).to have_http_status(200) - expect(response.media_type).to eq "application/xrd+xml" + expect(response.media_type).to eq 'application/xrd+xml' end end end diff --git a/spec/requests/link_headers_spec.rb b/spec/requests/link_headers_spec.rb index c32e0f79a9..b822adbfb8 100644 --- a/spec/requests/link_headers_spec.rb +++ b/spec/requests/link_headers_spec.rb @@ -13,7 +13,7 @@ describe 'Link headers' do it 'contains webfinger url in link header' do link_header = link_header_with_type('application/jrd+json') - expect(link_header.href).to match 'http://www.example.com/.well-known/webfinger?resource=acct%3Atest%40cb6e6126.ngrok.io' + expect(link_header.href).to eq 'http://www.example.com/.well-known/webfinger?resource=acct%3Atest%40cb6e6126.ngrok.io' expect(link_header.attr_pairs.first).to eq %w(rel lrdd) end @@ -26,7 +26,7 @@ describe 'Link headers' do def link_header_with_type(type) LinkHeader.parse(response.headers['Link'].to_s).links.find do |link| - link.attr_pairs.any? { |pair| pair == ['type', type] } + link.attr_pairs.any?(['type', type]) end end end diff --git a/spec/requests/localization_spec.rb b/spec/requests/localization_spec.rb index 0bc2786ac4..b7fb53ed8d 100644 --- a/spec/requests/localization_spec.rb +++ b/spec/requests/localization_spec.rb @@ -3,14 +3,16 @@ require 'rails_helper' describe 'Localization' do - after(:all) do - I18n.locale = I18n.default_locale + around do |example| + I18n.with_locale(I18n.locale) do + example.run + end end it 'uses a specific region when provided' do headers = { 'Accept-Language' => 'zh-HK' } - get "/auth/sign_in", headers: headers + get '/auth/sign_in', headers: headers expect(response.body).to include( I18n.t('auth.login', locale: 'zh-HK') @@ -20,7 +22,7 @@ describe 'Localization' do it 'falls back to a locale when region missing' do headers = { 'Accept-Language' => 'es-FAKE' } - get "/auth/sign_in", headers: headers + get '/auth/sign_in', headers: headers expect(response.body).to include( I18n.t('auth.login', locale: 'es') @@ -30,7 +32,7 @@ describe 'Localization' do it 'falls back to english when locale is missing' do headers = { 'Accept-Language' => '12-FAKE' } - get "/auth/sign_in", headers: headers + get '/auth/sign_in', headers: headers expect(response.body).to include( I18n.t('auth.login', locale: 'en') diff --git a/spec/requests/mail_subscriptions_spec.rb b/spec/requests/mail_subscriptions_spec.rb new file mode 100644 index 0000000000..cc6557cab0 --- /dev/null +++ b/spec/requests/mail_subscriptions_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'MailSubscriptionsController' do + let(:user) { Fabricate(:user) } + let(:token) { user.to_sgid(for: 'unsubscribe').to_s } + let(:type) { 'follow' } + + shared_examples 'not found with invalid token' do + context 'with invalid token' do + let(:token) { 'invalid-token' } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + + shared_examples 'not found with invalid type' do + context 'with invalid type' do + let(:type) { 'invalid_type' } + + it 'returns http not found' do + expect(response).to have_http_status(404) + end + end + end + + describe 'on the unsubscribe confirmation page' do + before do + get unsubscribe_url(token: token, type: type) + end + + it_behaves_like 'not found with invalid token' + it_behaves_like 'not found with invalid type' + + it 'shows unsubscribe form' do + expect(response).to have_http_status(200) + + expect(response.body).to include( + I18n.t('mail_subscriptions.unsubscribe.action') + ) + expect(response.body).to include(user.email) + end + end + + describe 'submitting the unsubscribe confirmation page' do + before do + user.settings.update('notification_emails.follow': true) + user.save! + + post unsubscribe_url, params: { token: token, type: type } + end + + it_behaves_like 'not found with invalid token' + it_behaves_like 'not found with invalid type' + + it 'shows confirmation page' do + expect(response).to have_http_status(200) + + expect(response.body).to include( + I18n.t('mail_subscriptions.unsubscribe.complete') + ) + expect(response.body).to include(user.email) + end + + it 'updates notification settings' do + user.reload + expect(user.settings['notification_emails.follow']).to be false + end + end + + describe 'unsubscribing with List-Unsubscribe-Post' do + around do |example| + old = ActionController::Base.allow_forgery_protection + ActionController::Base.allow_forgery_protection = true + + example.run + + ActionController::Base.allow_forgery_protection = old + end + + before do + user.settings.update('notification_emails.follow': true) + user.save! + + post unsubscribe_url(token: token, type: type), params: { 'List-Unsubscribe' => 'One-Click' } + end + + it_behaves_like 'not found with invalid token' + it_behaves_like 'not found with invalid type' + + it 'return http success' do + expect(response).to have_http_status(200) + end + + it 'updates notification settings' do + user.reload + expect(user.settings['notification_emails.follow']).to be false + end + end +end diff --git a/spec/requests/omniauth_callbacks_spec.rb b/spec/requests/omniauth_callbacks_spec.rb new file mode 100644 index 0000000000..27aa5ec506 --- /dev/null +++ b/spec/requests/omniauth_callbacks_spec.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'OmniAuth callbacks' do + shared_examples 'omniauth provider callbacks' do |provider| + subject { post send "user_#{provider}_omniauth_callback_path" } + + context 'with full information in response' do + before do + mock_omniauth(provider, { + provider: provider.to_s, + uid: '123', + info: { + verified: 'true', + email: 'user@host.example', + }, + }) + end + + context 'without a matching user' do + it 'creates a user and an identity and redirects to root path' do + expect { subject } + .to change(User, :count) + .by(1) + .and change(Identity, :count) + .by(1) + .and change(LoginActivity, :count) + .by(1) + + expect(User.last.email).to eq('user@host.example') + expect(Identity.find_by(user: User.last).uid).to eq('123') + expect(response).to redirect_to(root_path) + end + end + + context 'with a matching user and no matching identity' do + before do + Fabricate(:user, email: 'user@host.example') + end + + it 'matches the existing user, creates an identity, and redirects to root path' do + expect { subject } + .to not_change(User, :count) + .and change(Identity, :count) + .by(1) + .and change(LoginActivity, :count) + .by(1) + + expect(Identity.find_by(user: User.last).uid).to eq('123') + expect(response).to redirect_to(root_path) + end + end + + context 'with a matching user and a matching identity' do + before do + user = Fabricate(:user, email: 'user@host.example') + Fabricate(:identity, user: user, uid: '123', provider: provider) + end + + it 'matches the existing records and redirects to root path' do + expect { subject } + .to not_change(User, :count) + .and not_change(Identity, :count) + .and change(LoginActivity, :count) + .by(1) + + expect(response).to redirect_to(root_path) + end + end + end + + context 'with a response missing email address' do + before do + mock_omniauth(provider, { + provider: provider.to_s, + uid: '123', + info: { + verified: 'true', + }, + }) + end + + it 'redirects to the auth setup page' do + expect { subject } + .to change(User, :count) + .by(1) + .and change(Identity, :count) + .by(1) + .and change(LoginActivity, :count) + .by(1) + + expect(response).to redirect_to(auth_setup_path(missing_email: '1')) + end + end + + context 'when a user cannot be built' do + before do + allow(User).to receive(:find_for_oauth).and_return(User.new) + end + + it 'redirects to the new user signup page' do + expect { subject } + .to not_change(User, :count) + .and not_change(Identity, :count) + .and not_change(LoginActivity, :count) + + expect(response).to redirect_to(new_user_registration_url) + end + end + end + + describe '#openid_connect', if: ENV['OIDC_ENABLED'] == 'true' && ENV['OIDC_SCOPE'].present? do + include_examples 'omniauth provider callbacks', :openid_connect + end + + describe '#cas', if: ENV['CAS_ENABLED'] == 'true' do + include_examples 'omniauth provider callbacks', :cas + end + + describe '#saml', if: ENV['SAML_ENABLED'] == 'true' do + include_examples 'omniauth provider callbacks', :saml + end +end diff --git a/spec/requests/webfinger_request_spec.rb b/spec/requests/webfinger_request_spec.rb index 209fda72aa..68a1478bed 100644 --- a/spec/requests/webfinger_request_spec.rb +++ b/spec/requests/webfinger_request_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe 'The webfinger route' do diff --git a/spec/routing/accounts_routing_spec.rb b/spec/routing/accounts_routing_spec.rb index 3f0e9b3e95..8b2c124fd2 100644 --- a/spec/routing/accounts_routing_spec.rb +++ b/spec/routing/accounts_routing_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe 'Routes under accounts/' do diff --git a/spec/routing/api_routing_spec.rb b/spec/routing/api_routing_spec.rb index 2683ccb8d1..a822fba4c5 100644 --- a/spec/routing/api_routing_spec.rb +++ b/spec/routing/api_routing_spec.rb @@ -5,99 +5,99 @@ require 'rails_helper' describe 'API routes' do describe 'Credentials routes' do it 'routes to verify credentials' do - expect(get('/api/v1/accounts/verify_credentials')). - to route_to('api/v1/accounts/credentials#show') + expect(get('/api/v1/accounts/verify_credentials')) + .to route_to('api/v1/accounts/credentials#show') end it 'routes to update credentials' do - expect(patch('/api/v1/accounts/update_credentials')). - to route_to('api/v1/accounts/credentials#update') + expect(patch('/api/v1/accounts/update_credentials')) + .to route_to('api/v1/accounts/credentials#update') end end describe 'Account routes' do it 'routes to statuses' do - expect(get('/api/v1/accounts/user/statuses')). - to route_to('api/v1/accounts/statuses#index', account_id: 'user') + expect(get('/api/v1/accounts/user/statuses')) + .to route_to('api/v1/accounts/statuses#index', account_id: 'user') end it 'routes to followers' do - expect(get('/api/v1/accounts/user/followers')). - to route_to('api/v1/accounts/follower_accounts#index', account_id: 'user') + expect(get('/api/v1/accounts/user/followers')) + .to route_to('api/v1/accounts/follower_accounts#index', account_id: 'user') end it 'routes to following' do - expect(get('/api/v1/accounts/user/following')). - to route_to('api/v1/accounts/following_accounts#index', account_id: 'user') + expect(get('/api/v1/accounts/user/following')) + .to route_to('api/v1/accounts/following_accounts#index', account_id: 'user') end it 'routes to search' do - expect(get('/api/v1/accounts/search')). - to route_to('api/v1/accounts/search#show') + expect(get('/api/v1/accounts/search')) + .to route_to('api/v1/accounts/search#show') end it 'routes to relationships' do - expect(get('/api/v1/accounts/relationships')). - to route_to('api/v1/accounts/relationships#index') + expect(get('/api/v1/accounts/relationships')) + .to route_to('api/v1/accounts/relationships#index') end end describe 'Statuses routes' do it 'routes reblogged_by' do - expect(get('/api/v1/statuses/123/reblogged_by')). - to route_to('api/v1/statuses/reblogged_by_accounts#index', status_id: '123') + expect(get('/api/v1/statuses/123/reblogged_by')) + .to route_to('api/v1/statuses/reblogged_by_accounts#index', status_id: '123') end it 'routes favourited_by' do - expect(get('/api/v1/statuses/123/favourited_by')). - to route_to('api/v1/statuses/favourited_by_accounts#index', status_id: '123') + expect(get('/api/v1/statuses/123/favourited_by')) + .to route_to('api/v1/statuses/favourited_by_accounts#index', status_id: '123') end it 'routes reblog' do - expect(post('/api/v1/statuses/123/reblog')). - to route_to('api/v1/statuses/reblogs#create', status_id: '123') + expect(post('/api/v1/statuses/123/reblog')) + .to route_to('api/v1/statuses/reblogs#create', status_id: '123') end it 'routes unreblog' do - expect(post('/api/v1/statuses/123/unreblog')). - to route_to('api/v1/statuses/reblogs#destroy', status_id: '123') + expect(post('/api/v1/statuses/123/unreblog')) + .to route_to('api/v1/statuses/reblogs#destroy', status_id: '123') end it 'routes favourite' do - expect(post('/api/v1/statuses/123/favourite')). - to route_to('api/v1/statuses/favourites#create', status_id: '123') + expect(post('/api/v1/statuses/123/favourite')) + .to route_to('api/v1/statuses/favourites#create', status_id: '123') end it 'routes unfavourite' do - expect(post('/api/v1/statuses/123/unfavourite')). - to route_to('api/v1/statuses/favourites#destroy', status_id: '123') + expect(post('/api/v1/statuses/123/unfavourite')) + .to route_to('api/v1/statuses/favourites#destroy', status_id: '123') end it 'routes mute' do - expect(post('/api/v1/statuses/123/mute')). - to route_to('api/v1/statuses/mutes#create', status_id: '123') + expect(post('/api/v1/statuses/123/mute')) + .to route_to('api/v1/statuses/mutes#create', status_id: '123') end it 'routes unmute' do - expect(post('/api/v1/statuses/123/unmute')). - to route_to('api/v1/statuses/mutes#destroy', status_id: '123') + expect(post('/api/v1/statuses/123/unmute')) + .to route_to('api/v1/statuses/mutes#destroy', status_id: '123') end end describe 'Timeline routes' do it 'routes to home timeline' do - expect(get('/api/v1/timelines/home')). - to route_to('api/v1/timelines/home#show') + expect(get('/api/v1/timelines/home')) + .to route_to('api/v1/timelines/home#show') end it 'routes to public timeline' do - expect(get('/api/v1/timelines/public')). - to route_to('api/v1/timelines/public#show') + expect(get('/api/v1/timelines/public')) + .to route_to('api/v1/timelines/public#show') end it 'routes to tag timeline' do - expect(get('/api/v1/timelines/tag/test')). - to route_to('api/v1/timelines/tag#show', id: 'test') + expect(get('/api/v1/timelines/tag/test')) + .to route_to('api/v1/timelines/tag#show', id: 'test') end end end diff --git a/spec/routing/well_known_routes_spec.rb b/spec/routing/well_known_routes_spec.rb index 2e25605c2e..8cf08c13c1 100644 --- a/spec/routing/well_known_routes_spec.rb +++ b/spec/routing/well_known_routes_spec.rb @@ -1,15 +1,19 @@ +# frozen_string_literal: true + require 'rails_helper' -describe 'the host-meta route' do - it 'routes to correct place with xml format' do - expect(get('/.well-known/host-meta')). - to route_to('well_known/host_meta#show', format: 'xml') +describe 'Well Known routes' do + describe 'the host-meta route' do + it 'routes to correct place with xml format' do + expect(get('/.well-known/host-meta')) + .to route_to('well_known/host_meta#show', format: 'xml') + end end -end -describe 'the webfinger route' do - it 'routes to correct place with json format' do - expect(get('/.well-known/webfinger')). - to route_to('well_known/webfinger#show') + describe 'the webfinger route' do + it 'routes to correct place with json format' do + expect(get('/.well-known/webfinger')) + .to route_to('well_known/webfinger#show') + end end end diff --git a/spec/search/models/concerns/account_search_spec.rb b/spec/search/models/concerns/account_search_spec.rb new file mode 100644 index 0000000000..65e1e4de1c --- /dev/null +++ b/spec/search/models/concerns/account_search_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountSearch do + describe 'a non-discoverable account becoming discoverable' do + let(:account) { Account.find_by(username: 'search_test_account_1') } + + context 'when picking a non-discoverable account' do + it 'its bio is not in the AccountsIndex' do + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to be_nil + end + end + + context 'when the non-discoverable account becomes discoverable' do + it 'its bio is added to the AccountsIndex' do + account.discoverable = true + account.save! + + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to eq(account.note) + end + end + end + + describe 'a discoverable account becoming non-discoverable' do + let(:account) { Account.find_by(username: 'search_test_account_0') } + + context 'when picking an discoverable account' do + it 'has its bio in the AccountsIndex' do + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to eq(account.note) + end + end + + context 'when the discoverable account becomes non-discoverable' do + it 'its bio is removed from the AccountsIndex' do + account.discoverable = false + account.save! + + results = AccountsIndex.filter(term: { username: account.username }) + expect(results.count).to eq(1) + expect(results.first.text).to be_nil + end + end + end +end diff --git a/spec/search/models/concerns/account_statuses_search_spec.rb b/spec/search/models/concerns/account_statuses_search_spec.rb new file mode 100644 index 0000000000..d35cfa5639 --- /dev/null +++ b/spec/search/models/concerns/account_statuses_search_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AccountStatusesSearch do + describe 'a non-indexable account becoming indexable' do + let(:account) { Account.find_by(username: 'search_test_account_1') } + + context 'when picking a non-indexable account' do + it 'has no statuses in the PublicStatusesIndex' do + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(0) + end + + it 'has statuses in the StatusesIndex' do + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + + context 'when the non-indexable account becomes indexable' do + it 'adds the public statuses to the PublicStatusesIndex' do + account.indexable = true + account.save! + + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.where(visibility: :public).count) + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + end + + describe 'an indexable account becoming non-indexable' do + let(:account) { Account.find_by(username: 'search_test_account_0') } + + context 'when picking an indexable account' do + it 'has statuses in the PublicStatusesIndex' do + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.where(visibility: :public).count) + end + + it 'has statuses in the StatusesIndex' do + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + + context 'when the indexable account becomes non-indexable' do + it 'removes the statuses from the PublicStatusesIndex' do + account.indexable = false + account.save! + + expect(PublicStatusesIndex.filter(term: { account_id: account.id }).count).to eq(0) + expect(StatusesIndex.filter(term: { account_id: account.id }).count).to eq(account.statuses.count) + end + end + end +end diff --git a/spec/serializers/activitypub/device_serializer_spec.rb b/spec/serializers/activitypub/device_serializer_spec.rb new file mode 100644 index 0000000000..2a3be82121 --- /dev/null +++ b/spec/serializers/activitypub/device_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::DeviceSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Fabricate(:device) } + + describe 'type' do + it 'returns correct serialized type' do + expect(serialization['type']).to eq('Device') + end + end +end diff --git a/spec/serializers/activitypub/note_serializer_spec.rb b/spec/serializers/activitypub/note_serializer_spec.rb new file mode 100644 index 0000000000..31ee31f132 --- /dev/null +++ b/spec/serializers/activitypub/note_serializer_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::NoteSerializer do + subject { JSON.parse(@serialization.to_json) } + + let!(:account) { Fabricate(:account) } + let!(:other) { Fabricate(:account) } + let!(:parent) { Fabricate(:status, account: account, visibility: :public, language: 'zh-TW') } + let!(:reply_by_account_first) { Fabricate(:status, account: account, thread: parent, visibility: :public) } + let!(:reply_by_account_next) { Fabricate(:status, account: account, thread: parent, visibility: :public) } + let!(:reply_by_other_first) { Fabricate(:status, account: other, thread: parent, visibility: :public) } + let!(:reply_by_account_third) { Fabricate(:status, account: account, thread: parent, visibility: :public) } + let!(:reply_by_account_visibility_direct) { Fabricate(:status, account: account, thread: parent, visibility: :direct) } + + before(:each) do + @serialization = ActiveModelSerializers::SerializableResource.new(parent, serializer: described_class, adapter: ActivityPub::Adapter) + end + + it 'has the expected shape' do + expect(subject).to include({ + '@context' => include('https://www.w3.org/ns/activitystreams'), + 'type' => 'Note', + 'attributedTo' => ActivityPub::TagManager.instance.uri_for(account), + 'contentMap' => include({ + 'zh-TW' => a_kind_of(String), + }), + }) + end + + it 'has a replies collection' do + expect(subject['replies']['type']).to eql('Collection') + end + + it 'has a replies collection with a first Page' do + expect(subject['replies']['first']['type']).to eql('CollectionPage') + end + + it 'includes public self-replies in its replies collection' do + expect(subject['replies']['first']['items']).to include(reply_by_account_first.uri, reply_by_account_next.uri, reply_by_account_third.uri) + end + + it 'does not include replies from others in its replies collection' do + expect(subject['replies']['first']['items']).to_not include(reply_by_other_first.uri) + end + + it 'does not include replies with direct visibility in its replies collection' do + expect(subject['replies']['first']['items']).to_not include(reply_by_account_visibility_direct.uri) + end +end diff --git a/spec/serializers/activitypub/note_spec.rb b/spec/serializers/activitypub/note_spec.rb deleted file mode 100644 index 55bfbc16bf..0000000000 --- a/spec/serializers/activitypub/note_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe ActivityPub::NoteSerializer do - let!(:account) { Fabricate(:account) } - let!(:other) { Fabricate(:account) } - let!(:parent) { Fabricate(:status, account: account, visibility: :public) } - let!(:reply1) { Fabricate(:status, account: account, thread: parent, visibility: :public) } - let!(:reply2) { Fabricate(:status, account: account, thread: parent, visibility: :public) } - let!(:reply3) { Fabricate(:status, account: other, thread: parent, visibility: :public) } - let!(:reply4) { Fabricate(:status, account: account, thread: parent, visibility: :public) } - let!(:reply5) { Fabricate(:status, account: account, thread: parent, visibility: :direct) } - - before(:each) do - @serialization = ActiveModelSerializers::SerializableResource.new(parent, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter) - end - - subject { JSON.parse(@serialization.to_json) } - - it 'has a Note type' do - expect(subject['type']).to eql('Note') - end - - it 'has a replies collection' do - expect(subject['replies']['type']).to eql('Collection') - end - - it 'has a replies collection with a first Page' do - expect(subject['replies']['first']['type']).to eql('CollectionPage') - end - - it 'includes public self-replies in its replies collection' do - expect(subject['replies']['first']['items']).to include(reply1.uri, reply2.uri, reply4.uri) - end - - it 'does not include replies from others in its replies collection' do - expect(subject['replies']['first']['items']).to_not include(reply3.uri) - end - - it 'does not include replies with direct visibility in its replies collection' do - expect(subject['replies']['first']['items']).to_not include(reply5.uri) - end -end diff --git a/spec/serializers/activitypub/one_time_key_serializer_spec.rb b/spec/serializers/activitypub/one_time_key_serializer_spec.rb new file mode 100644 index 0000000000..6fe1f06185 --- /dev/null +++ b/spec/serializers/activitypub/one_time_key_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::OneTimeKeySerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Fabricate(:one_time_key) } + + describe 'type' do + it 'returns correct serialized type' do + expect(serialization['type']).to eq('Curve25519Key') + end + end +end diff --git a/spec/serializers/activitypub/undo_like_serializer_spec.rb b/spec/serializers/activitypub/undo_like_serializer_spec.rb new file mode 100644 index 0000000000..43cf7192e4 --- /dev/null +++ b/spec/serializers/activitypub/undo_like_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::UndoLikeSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Fabricate(:favourite) } + + describe 'type' do + it 'returns correct serialized type' do + expect(serialization['type']).to eq('Undo') + end + end +end diff --git a/spec/serializers/activitypub/update_poll_spec.rb b/spec/serializers/activitypub/update_poll_serializer_spec.rb similarity index 88% rename from spec/serializers/activitypub/update_poll_spec.rb rename to spec/serializers/activitypub/update_poll_serializer_spec.rb index f9e035eab5..14c24c70cc 100644 --- a/spec/serializers/activitypub/update_poll_spec.rb +++ b/spec/serializers/activitypub/update_poll_serializer_spec.rb @@ -3,16 +3,16 @@ require 'rails_helper' describe ActivityPub::UpdatePollSerializer do + subject { JSON.parse(@serialization.to_json) } + let(:account) { Fabricate(:account) } let(:poll) { Fabricate(:poll, account: account) } let!(:status) { Fabricate(:status, account: account, poll: poll) } before(:each) do - @serialization = ActiveModelSerializers::SerializableResource.new(status, serializer: ActivityPub::UpdatePollSerializer, adapter: ActivityPub::Adapter) + @serialization = ActiveModelSerializers::SerializableResource.new(status, serializer: described_class, adapter: ActivityPub::Adapter) end - subject { JSON.parse(@serialization.to_json) } - it 'has a Update type' do expect(subject['type']).to eql('Update') end diff --git a/spec/serializers/activitypub/vote_serializer_spec.rb b/spec/serializers/activitypub/vote_serializer_spec.rb new file mode 100644 index 0000000000..c329542d79 --- /dev/null +++ b/spec/serializers/activitypub/vote_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ActivityPub::VoteSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Fabricate(:poll_vote) } + + describe 'type' do + it 'returns correct serialized type' do + expect(serialization['type']).to eq('Create') + end + end +end diff --git a/spec/serializers/rest/account_serializer_spec.rb b/spec/serializers/rest/account_serializer_spec.rb new file mode 100644 index 0000000000..e399e88f37 --- /dev/null +++ b/spec/serializers/rest/account_serializer_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::AccountSerializer do + subject { JSON.parse(ActiveModelSerializers::SerializableResource.new(account, serializer: described_class).to_json) } + + let(:role) { Fabricate(:user_role, name: 'Role', highlighted: true) } + let(:user) { Fabricate(:user, role: role) } + let(:account) { user.account } + + context 'when the account is suspended' do + before do + account.suspend! + end + + it 'returns empty roles' do + expect(subject['roles']).to eq [] + end + end + + context 'when the account has a highlighted role' do + let(:role) { Fabricate(:user_role, name: 'Role', highlighted: true) } + + it 'returns the expected role' do + expect(subject['roles'].first).to include({ 'name' => 'Role' }) + end + end + + context 'when the account has a non-highlighted role' do + let(:role) { Fabricate(:user_role, name: 'Role', highlighted: false) } + + it 'returns empty roles' do + expect(subject['roles']).to eq [] + end + end + + context 'when the account is memorialized' do + before do + account.memorialize! + end + + it 'marks it as such' do + expect(subject['memorial']).to be true + end + end +end diff --git a/spec/serializers/rest/encrypted_message_serializer_spec.rb b/spec/serializers/rest/encrypted_message_serializer_spec.rb new file mode 100644 index 0000000000..e0e70a3b84 --- /dev/null +++ b/spec/serializers/rest/encrypted_message_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::EncryptedMessageSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Fabricate(:encrypted_message) } + + describe 'account' do + it 'returns the associated account' do + expect(serialization['account_id']).to eq(record.from_account.id.to_s) + end + end +end diff --git a/spec/serializers/rest/instance_serializer_spec.rb b/spec/serializers/rest/instance_serializer_spec.rb new file mode 100644 index 0000000000..15a5de18dd --- /dev/null +++ b/spec/serializers/rest/instance_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::InstanceSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { InstancePresenter.new } + + describe 'usage' do + it 'returns recent usage data' do + expect(serialization['usage']).to eq({ 'users' => { 'active_month' => 0 } }) + end + end +end diff --git a/spec/serializers/rest/keys/claim_result_serializer_spec.rb b/spec/serializers/rest/keys/claim_result_serializer_spec.rb new file mode 100644 index 0000000000..cf9416f032 --- /dev/null +++ b/spec/serializers/rest/keys/claim_result_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::Keys::ClaimResultSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Keys::ClaimService::Result.new(Account.new(id: 123), 456) } + + describe 'account' do + it 'returns the associated account' do + expect(serialization['account_id']).to eq('123') + end + end +end diff --git a/spec/serializers/rest/keys/device_serializer_spec.rb b/spec/serializers/rest/keys/device_serializer_spec.rb new file mode 100644 index 0000000000..c15e197cb8 --- /dev/null +++ b/spec/serializers/rest/keys/device_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::Keys::DeviceSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Device.new(name: 'Device name') } + + describe 'name' do + it 'returns the name' do + expect(serialization['name']).to eq('Device name') + end + end +end diff --git a/spec/serializers/rest/keys/query_result_serializer_spec.rb b/spec/serializers/rest/keys/query_result_serializer_spec.rb new file mode 100644 index 0000000000..983780ae98 --- /dev/null +++ b/spec/serializers/rest/keys/query_result_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::Keys::QueryResultSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) { Keys::QueryService::Result.new(Account.new(id: 123), []) } + + describe 'account' do + it 'returns the associated account id' do + expect(serialization['account_id']).to eq('123') + end + end +end diff --git a/spec/serializers/rest/suggestion_serializer_spec.rb b/spec/serializers/rest/suggestion_serializer_spec.rb new file mode 100644 index 0000000000..b3c086208d --- /dev/null +++ b/spec/serializers/rest/suggestion_serializer_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::SuggestionSerializer do + let(:serialization) do + JSON.parse( + ActiveModelSerializers::SerializableResource.new( + record, serializer: described_class + ).to_json + ) + end + let(:record) do + AccountSuggestions::Suggestion.new( + account: account, + source: 'SuggestionSource' + ) + end + let(:account) { Fabricate(:account) } + + describe 'account' do + it 'returns the associated account' do + expect(serialization['account']['id']).to eq(account.id.to_s) + end + end +end diff --git a/spec/services/account_search_service_spec.rb b/spec/services/account_search_service_spec.rb index 81cbc175e5..1cd036f484 100644 --- a/spec/services/account_search_service_spec.rb +++ b/spec/services/account_search_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe AccountSearchService, type: :service do @@ -18,7 +20,7 @@ describe AccountSearchService, type: :service do end end - context 'searching for a simple term that is not an exact match' do + context 'when searching for a simple term that is not an exact match' do it 'does not return a nil entry in the array for the exact match' do account = Fabricate(:account, username: 'matchingusername') results = subject.call('match', nil, limit: 5) @@ -51,7 +53,7 @@ describe AccountSearchService, type: :service do context 'when there is a domain but no exact match' do it 'follows the remote account when resolve is true' do - service = double(call: nil) + service = instance_double(ResolveAccountService, call: nil) allow(ResolveAccountService).to receive(:new).and_return(service) results = subject.call('newuser@remote.com', nil, limit: 10, resolve: true) @@ -59,11 +61,11 @@ describe AccountSearchService, type: :service do end it 'does not follow the remote account when resolve is false' do - service = double(call: nil) + service = instance_double(ResolveAccountService, call: nil) allow(ResolveAccountService).to receive(:new).and_return(service) results = subject.call('newuser@remote.com', nil, limit: 10, resolve: false) - expect(service).not_to have_received(:call) + expect(service).to_not have_received(:call) end end @@ -76,7 +78,7 @@ describe AccountSearchService, type: :service do expect(results).to eq [partial] end - it "does not return suspended remote accounts" do + it 'does not return suspended remote accounts' do remote = Fabricate(:account, username: 'a', domain: 'remote', display_name: 'e', suspended: true) results = subject.call('a@example.com', nil, limit: 2) diff --git a/spec/services/account_statuses_cleanup_service_spec.rb b/spec/services/account_statuses_cleanup_service_spec.rb index 257655c41b..f7a88a9172 100644 --- a/spec/services/account_statuses_cleanup_service_spec.rb +++ b/spec/services/account_statuses_cleanup_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe AccountStatusesCleanupService, type: :service do @@ -18,13 +20,13 @@ describe AccountStatusesCleanupService, type: :service do let!(:another_old_status) { Fabricate(:status, created_at: 1.year.ago, account: account) } let!(:recent_status) { Fabricate(:status, created_at: 1.day.ago, account: account) } - context 'given a budget of 1' do + context 'when given a budget of 1' do it 'reports 1 deleted toot' do expect(subject.call(account_policy, 1)).to eq 1 end end - context 'given a normal budget of 10' do + context 'when given a normal budget of 10' do it 'reports 3 deleted statuses' do expect(subject.call(account_policy, 10)).to eq 3 end @@ -42,8 +44,8 @@ describe AccountStatusesCleanupService, type: :service do context 'when called repeatedly with a budget of 2' do it 'reports 2 then 1 deleted statuses' do - expect(subject.call(account_policy, 2)).to eq 2 - expect(subject.call(account_policy, 2)).to eq 1 + expect(subject.call(account_policy, 2)).to eq 2 + expect(subject.call(account_policy, 2)).to eq 1 end it 'actually deletes the statuses in the expected order' do diff --git a/spec/services/activitypub/fetch_featured_collection_service_spec.rb b/spec/services/activitypub/fetch_featured_collection_service_spec.rb index e6336dc1b1..5975c81a10 100644 --- a/spec/services/activitypub/fetch_featured_collection_service_spec.rb +++ b/spec/services/activitypub/fetch_featured_collection_service_spec.rb @@ -1,37 +1,41 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do + subject { described_class.new } + let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/account', featured_collection_url: 'https://example.com/account/pinned') } let!(:known_status) { Fabricate(:status, account: actor, uri: 'https://example.com/account/pinned/1') } - let(:status_json_1) do + let(:status_json_pinned_known) do { '@context': 'https://www.w3.org/ns/activitystreams', type: 'Note', - id: 'https://example.com/account/pinned/1', + id: 'https://example.com/account/pinned/known', content: 'foo', attributedTo: actor.uri, to: 'https://www.w3.org/ns/activitystreams#Public', } end - let(:status_json_2) do + let(:status_json_pinned_unknown_inlined) do { '@context': 'https://www.w3.org/ns/activitystreams', type: 'Note', - id: 'https://example.com/account/pinned/2', + id: 'https://example.com/account/pinned/unknown-inlined', content: 'foo', attributedTo: actor.uri, to: 'https://www.w3.org/ns/activitystreams#Public', } end - let(:status_json_4) do + let(:status_json_pinned_unknown_unreachable) do { '@context': 'https://www.w3.org/ns/activitystreams', type: 'Note', - id: 'https://example.com/account/pinned/4', + id: 'https://example.com/account/pinned/unknown-reachable', content: 'foo', attributedTo: actor.uri, to: 'https://www.w3.org/ns/activitystreams#Public', @@ -40,10 +44,10 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do let(:items) do [ - 'https://example.com/account/pinned/1', # known - status_json_2, # unknown inlined - 'https://example.com/account/pinned/3', # unknown unreachable - 'https://example.com/account/pinned/4', # unknown reachable + 'https://example.com/account/pinned/known', # known + status_json_pinned_unknown_inlined, # unknown inlined + 'https://example.com/account/pinned/unknown-unreachable', # unknown unreachable + 'https://example.com/account/pinned/unknown-reachable', # unknown reachable ] end @@ -56,20 +60,22 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do }.with_indifferent_access end - subject { described_class.new } - shared_examples 'sets pinned posts' do before do - stub_request(:get, 'https://example.com/account/pinned/1').to_return(status: 200, body: Oj.dump(status_json_1)) - stub_request(:get, 'https://example.com/account/pinned/2').to_return(status: 200, body: Oj.dump(status_json_2)) - stub_request(:get, 'https://example.com/account/pinned/3').to_return(status: 404) - stub_request(:get, 'https://example.com/account/pinned/4').to_return(status: 200, body: Oj.dump(status_json_4)) + stub_request(:get, 'https://example.com/account/pinned/known').to_return(status: 200, body: Oj.dump(status_json_pinned_known)) + stub_request(:get, 'https://example.com/account/pinned/unknown-inlined').to_return(status: 200, body: Oj.dump(status_json_pinned_unknown_inlined)) + stub_request(:get, 'https://example.com/account/pinned/unknown-unreachable').to_return(status: 404) + stub_request(:get, 'https://example.com/account/pinned/unknown-reachable').to_return(status: 200, body: Oj.dump(status_json_pinned_unknown_unreachable)) subject.call(actor, note: true, hashtag: false) end it 'sets expected posts as pinned posts' do - expect(actor.pinned_statuses.pluck(:uri)).to match_array ['https://example.com/account/pinned/1', 'https://example.com/account/pinned/2', 'https://example.com/account/pinned/4'] + expect(actor.pinned_statuses.pluck(:uri)).to contain_exactly( + 'https://example.com/account/pinned/known', + 'https://example.com/account/pinned/unknown-inlined', + 'https://example.com/account/pinned/unknown-reachable' + ) end end @@ -109,7 +115,7 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do type: 'CollectionPage', partOf: actor.featured_collection_url, items: items, - } + }, }.with_indifferent_access end diff --git a/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb b/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb index 6ca22c9fc6..071e4d92d5 100644 --- a/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb +++ b/spec/services/activitypub/fetch_featured_tags_collection_service_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchFeaturedTagsCollectionService, type: :service do + subject { described_class.new } + let(:collection_url) { 'https://example.com/account/tags' } let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/account') } @@ -21,15 +25,13 @@ RSpec.describe ActivityPub::FetchFeaturedTagsCollectionService, type: :service d }.with_indifferent_access end - subject { described_class.new } - shared_examples 'sets featured tags' do before do subject.call(actor, collection_url) end it 'sets expected tags as pinned tags' do - expect(actor.featured_tags.map(&:display_name)).to match_array ['Foo', 'bar', 'baZ'] + expect(actor.featured_tags.map(&:display_name)).to match_array %w(Foo bar baZ) end end @@ -81,7 +83,7 @@ RSpec.describe ActivityPub::FetchFeaturedTagsCollectionService, type: :service d type: 'CollectionPage', partOf: collection_url, items: items, - } + }, }.with_indifferent_access end diff --git a/spec/services/activitypub/fetch_remote_account_service_spec.rb b/spec/services/activitypub/fetch_remote_account_service_spec.rb index ec6f1f41d8..ac7484d96d 100644 --- a/spec/services/activitypub/fetch_remote_account_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_account_service_spec.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do - subject { ActivityPub::FetchRemoteAccountService.new } + subject { described_class.new } let!(:actor) do { diff --git a/spec/services/activitypub/fetch_remote_actor_service_spec.rb b/spec/services/activitypub/fetch_remote_actor_service_spec.rb index 20117c66d0..93d31b69d5 100644 --- a/spec/services/activitypub/fetch_remote_actor_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_actor_service_spec.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchRemoteActorService, type: :service do - subject { ActivityPub::FetchRemoteActorService.new } + subject { described_class.new } let!(:actor) do { diff --git a/spec/services/activitypub/fetch_remote_key_service_spec.rb b/spec/services/activitypub/fetch_remote_key_service_spec.rb index 3186c4270d..e210d20ec7 100644 --- a/spec/services/activitypub/fetch_remote_key_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_key_service_spec.rb @@ -1,12 +1,24 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchRemoteKeyService, type: :service do - subject { ActivityPub::FetchRemoteKeyService.new } + subject { described_class.new } let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } } let(:public_key_pem) do - "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3L4vnpNLzVH31MeWI39\n4F0wKeJFsLDAsNXGeOu0QF2x+h1zLWZw/agqD2R3JPU9/kaDJGPIV2Sn5zLyUA9S\n6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh\n8lDET6X4Pyw+ZJU0/OLo/41q9w+OrGtlsTm/PuPIeXnxa6BLqnDaxC+4IcjG/FiP\nahNCTINl/1F/TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq+t8nhQYkgAkt64euW\npva3qL5KD1mTIZQEP+LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3Qvu\nHQIDAQAB\n-----END PUBLIC KEY-----\n" + <<~TEXT + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3L4vnpNLzVH31MeWI39 + 4F0wKeJFsLDAsNXGeOu0QF2x+h1zLWZw/agqD2R3JPU9/kaDJGPIV2Sn5zLyUA9S + 6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh + 8lDET6X4Pyw+ZJU0/OLo/41q9w+OrGtlsTm/PuPIeXnxa6BLqnDaxC+4IcjG/FiP + ahNCTINl/1F/TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq+t8nhQYkgAkt64euW + pva3qL5KD1mTIZQEP+LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3Qvu + HQIDAQAB + -----END PUBLIC KEY----- + TEXT end let(:public_key_id) { 'https://example.com/alice#main-key' } diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index a81dcad818..826b67d884 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -1,8 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do include ActionView::Helpers::TextHelper + subject { described_class.new } + let!(:sender) { Fabricate(:account, domain: 'foo.bar', uri: 'https://foo.bar') } let!(:recipient) { Fabricate(:account) } @@ -11,15 +15,13 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:note) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234", + id: 'https://foo.bar/@foo/1234', type: 'Note', content: 'Lorem ipsum', attributedTo: ActivityPub::TagManager.instance.uri_for(sender), } end - subject { described_class.new } - before do stub_request(:get, 'https://foo.bar/watch?v=12345').to_return(status: 404, body: '') stub_request(:get, object[:id]).to_return(body: Oj.dump(object)) @@ -46,7 +48,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234", + id: 'https://foo.bar/@foo/1234', type: 'Video', name: 'Nyan Cat 10 hours remix', attributedTo: ActivityPub::TagManager.instance.uri_for(sender), @@ -54,13 +56,13 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do { type: 'Link', mimeType: 'application/x-bittorrent', - href: "https://foo.bar/12345.torrent", + href: 'https://foo.bar/12345.torrent', }, { type: 'Link', mimeType: 'text/html', - href: "https://foo.bar/watch?v=12345", + href: 'https://foo.bar/watch?v=12345', }, ], } @@ -70,8 +72,8 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do status = sender.statuses.first expect(status).to_not be_nil - expect(status.url).to eq "https://foo.bar/watch?v=12345" - expect(strip_tags(status.text)).to eq "Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345" + expect(status.url).to eq 'https://foo.bar/watch?v=12345' + expect(strip_tags(status.text)).to eq 'Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345' end end @@ -79,7 +81,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234", + id: 'https://foo.bar/@foo/1234', type: 'Audio', name: 'Nyan Cat 10 hours remix', attributedTo: ActivityPub::TagManager.instance.uri_for(sender), @@ -87,13 +89,13 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do { type: 'Link', mimeType: 'application/x-bittorrent', - href: "https://foo.bar/12345.torrent", + href: 'https://foo.bar/12345.torrent', }, { type: 'Link', mimeType: 'text/html', - href: "https://foo.bar/watch?v=12345", + href: 'https://foo.bar/watch?v=12345', }, ], } @@ -103,8 +105,8 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do status = sender.statuses.first expect(status).to_not be_nil - expect(status.url).to eq "https://foo.bar/watch?v=12345" - expect(strip_tags(status.text)).to eq "Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345" + expect(status.url).to eq 'https://foo.bar/watch?v=12345' + expect(strip_tags(status.text)).to eq 'Nyan Cat 10 hours remixhttps://foo.bar/watch?v=12345' end end @@ -112,10 +114,10 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234", + id: 'https://foo.bar/@foo/1234', type: 'Event', name: "Let's change the world", - attributedTo: ActivityPub::TagManager.instance.uri_for(sender) + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), } end @@ -123,7 +125,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do status = sender.statuses.first expect(status).to_not be_nil - expect(status.url).to eq "https://foo.bar/@foo/1234" + expect(status.url).to eq 'https://foo.bar/@foo/1234' expect(strip_tags(status.text)).to eq "Let's change the worldhttps://foo.bar/@foo/1234" end end @@ -132,7 +134,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:note) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://real.address/@foo/1234", + id: 'https://real.address/@foo/1234', type: 'Note', content: 'Lorem ipsum', attributedTo: ActivityPub::TagManager.instance.uri_for(sender), @@ -154,7 +156,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234/create", + id: 'https://foo.bar/@foo/1234/create', type: 'Create', actor: ActivityPub::TagManager.instance.uri_for(sender), object: note, @@ -174,11 +176,11 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234/create", + id: 'https://foo.bar/@foo/1234/create', type: 'Create', actor: ActivityPub::TagManager.instance.uri_for(sender), object: { - id: "https://real.address/@foo/1234", + id: 'https://real.address/@foo/1234', type: 'Note', content: 'Lorem ipsum', attributedTo: ActivityPub::TagManager.instance.uri_for(sender), @@ -208,7 +210,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1234/create", + id: 'https://foo.bar/@foo/1234/create', type: 'Create', actor: ActivityPub::TagManager.instance.uri_for(sender), object: note.merge(updated: '2021-09-08T22:39:25Z'), @@ -224,16 +226,16 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do end end - context 'statuses referencing other statuses' do + context 'with statuses referencing other statuses' do before do stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5 end - context 'using inReplyTo' do + context 'when using inReplyTo' do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1", + id: 'https://foo.bar/@foo/1', type: 'Note', content: 'Lorem ipsum', inReplyTo: 'https://foo.bar/@foo/2', @@ -265,11 +267,11 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do end end - context 'using replies' do + context 'when using replies' do let(:object) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://foo.bar/@foo/1", + id: 'https://foo.bar/@foo/1', type: 'Note', content: 'Lorem ipsum', replies: { @@ -298,7 +300,7 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do first: { type: 'CollectionPage', partOf: "https://foo.bar/@foo/#{i}/replies", - items: ["https://foo.bar/@foo/#{i+1}"], + items: ["https://foo.bar/@foo/#{i + 1}"], }, }, attributedTo: ActivityPub::TagManager.instance.uri_for(sender), diff --git a/spec/services/activitypub/fetch_replies_service_spec.rb b/spec/services/activitypub/fetch_replies_service_spec.rb index fe49b18c19..bf8e296764 100644 --- a/spec/services/activitypub/fetch_replies_service_spec.rb +++ b/spec/services/activitypub/fetch_replies_service_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::FetchRepliesService, type: :service do + subject { described_class.new } + let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account') } let(:status) { Fabricate(:status, account: actor) } let(:collection_uri) { 'http://example.com/replies/1' } @@ -28,8 +32,6 @@ RSpec.describe ActivityPub::FetchRepliesService, type: :service do }.with_indifferent_access end - subject { described_class.new } - describe '#call' do context 'when the payload is a Collection with inlined replies' do context 'when passing the collection itself' do @@ -90,7 +92,7 @@ RSpec.describe ActivityPub::FetchRepliesService, type: :service do type: 'CollectionPage', partOf: collection_uri, items: items, - } + }, }.with_indifferent_access end diff --git a/spec/services/activitypub/process_account_service_spec.rb b/spec/services/activitypub/process_account_service_spec.rb index 2b20d17b1b..c02a0800a3 100644 --- a/spec/services/activitypub/process_account_service_spec.rb +++ b/spec/services/activitypub/process_account_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::ProcessAccountService, type: :service do subject { described_class.new } - context 'property values' do + context 'with property values' do let(:payload) do { id: 'https://foo.test', @@ -12,7 +14,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do attachment: [ { type: 'PropertyValue', name: 'Pronouns', value: 'They/them' }, { type: 'PropertyValue', name: 'Occupation', value: 'Unit test' }, - { type: 'PropertyValue', name: 'non-string', value: ['foo', 'bar'] }, + { type: 'PropertyValue', name: 'non-string', value: %w(foo bar) }, ], }.with_indifferent_access end @@ -31,6 +33,8 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end context 'when account is not suspended' do + subject { described_class.new.call('alice', 'example.com', payload) } + let!(:account) { Fabricate(:account, username: 'alice', domain: 'example.com') } let(:payload) do @@ -46,8 +50,6 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do allow(Admin::SuspensionWorker).to receive(:perform_async) end - subject { described_class.new.call('alice', 'example.com', payload) } - it 'suspends account remotely' do expect(subject.suspended?).to be true expect(subject.suspension_origin_remote?).to be true @@ -60,6 +62,8 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end context 'when account is suspended' do + subject { described_class.new.call('alice', 'example.com', payload) } + let!(:account) { Fabricate(:account, username: 'alice', domain: 'example.com', display_name: '') } let(:payload) do @@ -78,9 +82,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do account.suspend!(origin: suspension_origin) end - subject { described_class.new.call('alice', 'example.com', payload) } - - context 'locally' do + context 'when locally' do let(:suspension_origin) { :local } it 'does not unsuspend it' do @@ -92,7 +94,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end end - context 'remotely' do + context 'when remotely' do let(:suspension_origin) { :remote } it 'unsuspends it' do @@ -110,12 +112,8 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end end - context 'discovering many subdomains in a short timeframe' do - before do - stub_const 'ActivityPub::ProcessAccountService::SUBDOMAINS_RATELIMIT', 5 - end - - let(:subject) do + context 'when discovering many subdomains in a short timeframe' do + subject do 8.times do |i| domain = "test#{i}.testdomain.com" json = { @@ -127,6 +125,10 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end end + before do + stub_const 'ActivityPub::ProcessAccountService::SUBDOMAINS_RATELIMIT', 5 + end + it 'creates at least some accounts' do expect { subject }.to change { Account.remote.count }.by_at_least(2) end @@ -136,11 +138,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end end - context 'accounts referencing other accounts' do - before do - stub_const 'ActivityPub::ProcessAccountService::DISCOVERIES_PER_REQUEST', 5 - end - + context 'when Accounts referencing other accounts' do let(:payload) do { '@context': ['https://www.w3.org/ns/activitystreams'], @@ -153,6 +151,8 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do end before do + stub_const 'ActivityPub::ProcessAccountService::DISCOVERIES_PER_REQUEST', 5 + 8.times do |i| actor_json = { '@context': ['https://www.w3.org/ns/activitystreams'], @@ -172,16 +172,16 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do { type: 'Mention', href: "https://foo.test/users/#{i + 1}", - name: "@user#{i + 1 }", - } + name: "@user#{i + 1}", + }, ], - to: [ 'as:Public', "https://foo.test/users/#{i + 1}" ] + to: ['as:Public', "https://foo.test/users/#{i + 1}"], }.with_indifferent_access featured_json = { '@context': ['https://www.w3.org/ns/activitystreams'], id: "https://foo.test/users/#{i}/featured", type: 'OrderedCollection', - totelItems: 1, + totalItems: 1, orderedItems: [status_json], }.with_indifferent_access webfinger = { diff --git a/spec/services/activitypub/process_collection_service_spec.rb b/spec/services/activitypub/process_collection_service_spec.rb index 093a188a21..02011afea0 100644 --- a/spec/services/activitypub/process_collection_service_spec.rb +++ b/spec/services/activitypub/process_collection_service_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::ProcessCollectionService, type: :service do + subject { described_class.new } + let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account') } let(:payload) do @@ -19,8 +23,6 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do let(:json) { Oj.dump(payload) } - subject { described_class.new } - describe '#call' do context 'when actor is suspended' do before do @@ -39,7 +41,7 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do end it 'does not process payload' do - expect(ActivityPub::Activity).not_to receive(:factory) + expect(ActivityPub::Activity).to_not receive(:factory) subject.call(json, actor) end end @@ -68,8 +70,8 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do let(:forwarder) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/other_account') } it 'does not process payload if no signature exists' do - expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_actor!).and_return(nil) - expect(ActivityPub::Activity).not_to receive(:factory) + allow_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_actor!).and_return(nil) + expect(ActivityPub::Activity).to_not receive(:factory) subject.call(json, forwarder) end @@ -77,7 +79,7 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do it 'processes payload with actor if valid signature exists' do payload['signature'] = { 'type' => 'RsaSignature2017' } - expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_actor!).and_return(actor) + allow_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_actor!).and_return(actor) expect(ActivityPub::Activity).to receive(:factory).with(instance_of(Hash), actor, instance_of(Hash)) subject.call(json, forwarder) @@ -86,8 +88,8 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do it 'does not process payload if invalid signature exists' do payload['signature'] = { 'type' => 'RsaSignature2017' } - expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_actor!).and_return(nil) - expect(ActivityPub::Activity).not_to receive(:factory) + allow_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_actor!).and_return(nil) + expect(ActivityPub::Activity).to_not receive(:factory) subject.call(json, forwarder) end @@ -95,11 +97,21 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do context 'when receiving a fabricated status' do let!(:actor) do Fabricate(:account, - username: 'bob', - domain: 'example.com', - uri: 'https://example.com/users/bob', - public_key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuYyoyfsRkYnXRotMsId\nW3euBDDfiv9oVqOxUVC7bhel8KednIMrMCRWFAkgJhbrlzbIkjVr68o1MP9qLcn7\nCmH/BXHp7yhuFTr4byjdJKpwB+/i2jNEsvDH5jR8WTAeTCe0x/QHg21V3F7dSI5m\nCCZ/1dSIyOXLRTWVlfDlm3rE4ntlCo+US3/7oSWbg/4/4qEnt1HC32kvklgScxua\n4LR5ATdoXa5bFoopPWhul7MJ6NyWCyQyScUuGdlj8EN4kmKQJvphKHrI9fvhgOuG\nTvhTR1S5InA4azSSchY0tXEEw/VNxraeX0KPjbgr6DPcwhPd/m0nhVDq0zVyVBBD\nMwIDAQAB\n-----END PUBLIC KEY-----\n", - private_key: nil) + username: 'bob', + domain: 'example.com', + uri: 'https://example.com/users/bob', + private_key: nil, + public_key: <<~TEXT) + -----BEGIN PUBLIC KEY----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuYyoyfsRkYnXRotMsId + W3euBDDfiv9oVqOxUVC7bhel8KednIMrMCRWFAkgJhbrlzbIkjVr68o1MP9qLcn7 + CmH/BXHp7yhuFTr4byjdJKpwB+/i2jNEsvDH5jR8WTAeTCe0x/QHg21V3F7dSI5m + CCZ/1dSIyOXLRTWVlfDlm3rE4ntlCo+US3/7oSWbg/4/4qEnt1HC32kvklgScxua + 4LR5ATdoXa5bFoopPWhul7MJ6NyWCyQyScUuGdlj8EN4kmKQJvphKHrI9fvhgOuG + TvhTR1S5InA4azSSchY0tXEEw/VNxraeX0KPjbgr6DPcwhPd/m0nhVDq0zVyVBBD + MwIDAQAB + -----END PUBLIC KEY----- + TEXT end let(:payload) do @@ -107,48 +119,55 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do '@context': [ 'https://www.w3.org/ns/activitystreams', nil, - {'object': 'https://www.w3.org/ns/activitystreams#object'} + { object: 'https://www.w3.org/ns/activitystreams#object' }, ], - 'id': 'https://example.com/users/bob/fake-status/activity', - 'type': 'Create', - 'actor': 'https://example.com/users/bob', - 'published': '2022-01-22T15:00:00Z', - 'to': [ - 'https://www.w3.org/ns/activitystreams#Public' + id: 'https://example.com/users/bob/fake-status/activity', + type: 'Create', + actor: 'https://example.com/users/bob', + published: '2022-01-22T15:00:00Z', + to: [ + 'https://www.w3.org/ns/activitystreams#Public', ], - 'cc': [ - 'https://example.com/users/bob/followers' + cc: [ + 'https://example.com/users/bob/followers', ], - 'signature': { - 'type': 'RsaSignature2017', - 'creator': 'https://example.com/users/bob#main-key', - 'created': '2022-03-09T21:57:25Z', - 'signatureValue': 'WculK0LelTQ0MvGwU9TPoq5pFzFfGYRDCJqjZ232/Udj4CHqDTGOSw5UTDLShqBOyycCkbZGrQwXG+dpyDpQLSe1UVPZ5TPQtc/9XtI57WlS2nMNpdvRuxGnnb2btPdesXZ7n3pCxo0zjaXrJMe0mqQh5QJO22mahb4bDwwmfTHgbD3nmkD+fBfGi+UV2qWwqr+jlV4L4JqNkh0gWljF5KTePLRRZCuWiQ/FAt7c67636cdIPf7fR+usjuZltTQyLZKEGuK8VUn2Gkfsx5qns7Vcjvlz1JqlAjyO8HPBbzTTHzUG2nUOIgC3PojCSWv6mNTmRGoLZzOscCAYQA6cKw==' + signature: { + type: 'RsaSignature2017', + creator: 'https://example.com/users/bob#main-key', + created: '2022-03-09T21:57:25Z', + signatureValue: 'WculK0LelTQ0MvGwU9TPoq5pFzFfGYRDCJqjZ232/Udj4' \ + 'CHqDTGOSw5UTDLShqBOyycCkbZGrQwXG+dpyDpQLSe1UV' \ + 'PZ5TPQtc/9XtI57WlS2nMNpdvRuxGnnb2btPdesXZ7n3p' \ + 'Cxo0zjaXrJMe0mqQh5QJO22mahb4bDwwmfTHgbD3nmkD+' \ + 'fBfGi+UV2qWwqr+jlV4L4JqNkh0gWljF5KTePLRRZCuWi' \ + 'Q/FAt7c67636cdIPf7fR+usjuZltTQyLZKEGuK8VUn2Gk' \ + 'fsx5qns7Vcjvlz1JqlAjyO8HPBbzTTHzUG2nUOIgC3Poj' \ + 'CSWv6mNTmRGoLZzOscCAYQA6cKw==', }, '@id': 'https://example.com/users/bob/statuses/107928807471117876/activity', '@type': 'https://www.w3.org/ns/activitystreams#Create', 'https://www.w3.org/ns/activitystreams#actor': { - '@id': 'https://example.com/users/bob' + '@id': 'https://example.com/users/bob', }, 'https://www.w3.org/ns/activitystreams#cc': { - '@id': 'https://example.com/users/bob/followers' + '@id': 'https://example.com/users/bob/followers', }, - 'object': { - 'id': 'https://example.com/users/bob/fake-status', - 'type': 'Note', - 'published': '2022-01-22T15:00:00Z', - 'url': 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=puck-was-here', - 'attributedTo': 'https://example.com/users/bob', - 'to': [ - 'https://www.w3.org/ns/activitystreams#Public' + object: { + id: 'https://example.com/users/bob/fake-status', + type: 'Note', + published: '2022-01-22T15:00:00Z', + url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=puck-was-here', + attributedTo: 'https://example.com/users/bob', + to: [ + 'https://www.w3.org/ns/activitystreams#Public', ], - 'cc': [ - 'https://example.com/users/bob/followers' + cc: [ + 'https://example.com/users/bob/followers', ], - 'sensitive': false, - 'atomUri': 'https://example.com/users/bob/fake-status', - 'conversation': 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation', - 'content': '

puck was here

', + sensitive: false, + atomUri: 'https://example.com/users/bob/fake-status', + conversation: 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation', + content: '

puck was here

', '@id': 'https://example.com/users/bob/statuses/107928807471117876', '@type': 'https://www.w3.org/ns/activitystreams#Note', @@ -156,21 +175,21 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do 'http://ostatus.org#conversation': 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation', 'https://www.w3.org/ns/activitystreams#attachment': [], 'https://www.w3.org/ns/activitystreams#attributedTo': { - '@id': 'https://example.com/users/bob' + '@id': 'https://example.com/users/bob', }, 'https://www.w3.org/ns/activitystreams#cc': { - '@id': 'https://example.com/users/bob/followers' + '@id': 'https://example.com/users/bob/followers', }, 'https://www.w3.org/ns/activitystreams#content': [ '

hello world

', { '@value': '

hello world

', - '@language': 'en' - } + '@language': 'en', + }, ], 'https://www.w3.org/ns/activitystreams#published': { '@type': 'http://www.w3.org/2001/XMLSchema#dateTime', - '@value': '2022-03-09T21:55:07Z' + '@value': '2022-03-09T21:55:07Z', }, 'https://www.w3.org/ns/activitystreams#replies': { '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies', @@ -179,51 +198,51 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do '@type': 'https://www.w3.org/ns/activitystreams#CollectionPage', 'https://www.w3.org/ns/activitystreams#items': [], 'https://www.w3.org/ns/activitystreams#next': { - '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies?only_other_accounts=true&page=true' + '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies?only_other_accounts=true&page=true', }, 'https://www.w3.org/ns/activitystreams#partOf': { - '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies' - } - } + '@id': 'https://example.com/users/bob/statuses/107928807471117876/replies', + }, + }, }, 'https://www.w3.org/ns/activitystreams#sensitive': false, 'https://www.w3.org/ns/activitystreams#tag': [], 'https://www.w3.org/ns/activitystreams#to': { - '@id': 'https://www.w3.org/ns/activitystreams#Public' + '@id': 'https://www.w3.org/ns/activitystreams#Public', }, 'https://www.w3.org/ns/activitystreams#url': { - '@id': 'https://example.com/@bob/107928807471117876' - } + '@id': 'https://example.com/@bob/107928807471117876', + }, }, 'https://www.w3.org/ns/activitystreams#published': { '@type': 'http://www.w3.org/2001/XMLSchema#dateTime', - '@value': '2022-03-09T21:55:07Z' + '@value': '2022-03-09T21:55:07Z', }, 'https://www.w3.org/ns/activitystreams#to': { - '@id': 'https://www.w3.org/ns/activitystreams#Public' - } + '@id': 'https://www.w3.org/ns/activitystreams#Public', + }, } end it 'does not process forged payload' do - expect(ActivityPub::Activity).not_to receive(:factory).with( + expect(ActivityPub::Activity).to_not receive(:factory).with( hash_including( 'object' => hash_including( 'id' => 'https://example.com/users/bob/fake-status' ) ), - anything(), - anything() + anything, + anything ) - expect(ActivityPub::Activity).not_to receive(:factory).with( + expect(ActivityPub::Activity).to_not receive(:factory).with( hash_including( 'object' => hash_including( 'content' => '

puck was here

' ) ), - anything(), - anything() + anything, + anything ) subject.call(json, forwarder) diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb index 750369d57f..9d91f31cc5 100644 --- a/spec/services/activitypub/process_status_update_service_spec.rb +++ b/spec/services/activitypub/process_status_update_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' def poll_option_json(name, votes) @@ -5,21 +7,9 @@ def poll_option_json(name, votes) end RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do + subject { described_class.new } + let!(:status) { Fabricate(:status, text: 'Hello world', account: Fabricate(:account, domain: 'example.com')) } - - let(:alice) { Fabricate(:account) } - let(:bob) { Fabricate(:account) } - - let(:mentions) { [] } - let(:tags) { [] } - let(:media_attachments) { [] } - - before do - mentions.each { |a| Fabricate(:mention, status: status, account: a) } - tags.each { |t| status.tags << t } - media_attachments.each { |m| status.media_attachments << m } - end - let(:payload) do { '@context': 'https://www.w3.org/ns/activitystreams', @@ -34,19 +24,29 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do ], } end - let(:json) { Oj.load(Oj.dump(payload)) } - subject { described_class.new } + let(:alice) { Fabricate(:account) } + let(:bob) { Fabricate(:account) } + + let(:mentions) { [] } + let(:tags) { [] } + let(:media_attachments) { [] } + + before do + mentions.each { |a| Fabricate(:mention, status: status, account: a) } + tags.each { |t| status.tags << t } + media_attachments.each { |m| status.media_attachments << m } + end describe '#call' do it 'updates text' do - subject.call(status, json) + subject.call(status, json, json) expect(status.reload.text).to eq 'Hello universe' end it 'updates content warning' do - subject.call(status, json) + subject.call(status, json, json) expect(status.reload.spoiler_text).to eq 'Show more' end @@ -64,7 +64,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'does not create any edits' do @@ -87,7 +87,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'does not create any edits' do @@ -104,20 +104,19 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end context 'when the status has not been explicitly edited and features a poll' do - let(:account) { Fabricate(:account, domain: 'example.com') } + let(:account) { Fabricate(:account, domain: 'example.com') } let!(:expiration) { 10.days.from_now.utc } let!(:status) do Fabricate(:status, - text: 'Hello world', - account: account, - poll_attributes: { - options: %w(Foo Bar), - account: account, - multiple: false, - hide_totals: false, - expires_at: expiration - } - ) + text: 'Hello world', + account: account, + poll_attributes: { + options: %w(Foo Bar), + account: account, + multiple: false, + hide_totals: false, + expires_at: expiration, + }) end let(:payload) do @@ -135,7 +134,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'does not create any edits' do @@ -156,20 +155,19 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end context 'when the status changes a poll despite being not explicitly marked as updated' do - let(:account) { Fabricate(:account, domain: 'example.com') } + let(:account) { Fabricate(:account, domain: 'example.com') } let!(:expiration) { 10.days.from_now.utc } let!(:status) do Fabricate(:status, - text: 'Hello world', - account: account, - poll_attributes: { - options: %w(Foo Bar), - account: account, - multiple: false, - hide_totals: false, - expires_at: expiration - } - ) + text: 'Hello world', + account: account, + poll_attributes: { + options: %w(Foo Bar), + account: account, + multiple: false, + hide_totals: false, + expires_at: expiration, + }) end let(:payload) do @@ -188,7 +186,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'does not create any edits' do @@ -216,11 +214,11 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end it 'does not create any edits' do - expect { subject.call(status, json) }.not_to change { status.reload.edits.pluck(&:id) } + expect { subject.call(status, json, json) }.to_not(change { status.reload.edits.pluck(&:id) }) end it 'does not update the text, spoiler_text or edited_at' do - expect { subject.call(status, json) }.not_to change { s = status.reload; [s.text, s.spoiler_text, s.edited_at] } + expect { subject.call(status, json, json) }.to_not(change { s = status.reload; [s.text, s.spoiler_text, s.edited_at] }) end end @@ -235,7 +233,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'does not create any edits' do @@ -259,7 +257,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do before do status.update(ordered_media_attachment_ids: nil) - subject.call(status, json) + subject.call(status, json, json) end it 'does not create any edits' do @@ -271,9 +269,9 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally without tags' do + context 'when originally without tags' do before do - subject.call(status, json) + subject.call(status, json, json) end it 'updates tags' do @@ -281,7 +279,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally with tags' do + context 'when originally with tags' do let(:tags) { [Fabricate(:tag, name: 'test'), Fabricate(:tag, name: 'foo')] } let(:payload) do @@ -299,7 +297,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'updates tags' do @@ -307,9 +305,9 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally without mentions' do + context 'when originally without mentions' do before do - subject.call(status, json) + subject.call(status, json, json) end it 'updates mentions' do @@ -317,11 +315,11 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally with mentions' do + context 'when originally with mentions' do let(:mentions) { [alice, bob] } before do - subject.call(status, json) + subject.call(status, json, json) end it 'updates mentions' do @@ -329,10 +327,10 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally without media attachments' do + context 'when originally without media attachments' do before do stub_request(:get, 'https://example.com/foo.png').to_return(body: attachment_fixture('emojo.png')) - subject.call(status, json) + subject.call(status, json, json) end let(:payload) do @@ -344,7 +342,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do updated: '2021-09-08T22:39:25Z', attachment: [ { type: 'Image', mediaType: 'image/png', url: 'https://example.com/foo.png' }, - ] + ], } end @@ -364,7 +362,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally with media attachments' do + context 'when originally with media attachments' do let(:media_attachments) { [Fabricate(:media_attachment, remote_url: 'https://example.com/foo.png'), Fabricate(:media_attachment, remote_url: 'https://example.com/unused.png')] } let(:payload) do @@ -376,13 +374,13 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do updated: '2021-09-08T22:39:25Z', attachment: [ { type: 'Image', mediaType: 'image/png', url: 'https://example.com/foo.png', name: 'A picture' }, - ] + ], } end before do allow(RedownloadMediaWorker).to receive(:perform_async) - subject.call(status, json) + subject.call(status, json, json) end it 'updates the existing media attachment in-place' do @@ -406,15 +404,15 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally with a poll' do + context 'when originally with a poll' do before do poll = Fabricate(:poll, status: status) status.update(preloadable_poll: poll) - subject.call(status, json) + subject.call(status, json, json) end it 'removes poll' do - expect(status.reload.poll).to eq nil + expect(status.reload.poll).to be_nil end it 'records media change in edit' do @@ -422,7 +420,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end end - context 'originally without a poll' do + context 'when originally without a poll' do let(:payload) do { '@context': 'https://www.w3.org/ns/activitystreams', @@ -440,7 +438,7 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end before do - subject.call(status, json) + subject.call(status, json, json) end it 'creates a poll' do @@ -456,12 +454,12 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do end it 'creates edit history' do - subject.call(status, json) + subject.call(status, json, json) expect(status.edits.reload.map(&:text)).to eq ['Hello world', 'Hello universe'] end it 'sets edited timestamp' do - subject.call(status, json) + subject.call(status, json, json) expect(status.reload.edited_at.to_s).to eq '2021-09-08 22:39:25 UTC' end end diff --git a/spec/services/activitypub/synchronize_followers_service_spec.rb b/spec/services/activitypub/synchronize_followers_service_spec.rb index 75dcf204b7..c9a513e24b 100644 --- a/spec/services/activitypub/synchronize_followers_service_spec.rb +++ b/spec/services/activitypub/synchronize_followers_service_spec.rb @@ -1,6 +1,10 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ActivityPub::SynchronizeFollowersService, type: :service do + subject { described_class.new } + let(:actor) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/account', inbox_url: 'http://example.com/inbox') } let(:alice) { Fabricate(:account, username: 'alice') } let(:bob) { Fabricate(:account, username: 'bob') } @@ -25,8 +29,6 @@ RSpec.describe ActivityPub::SynchronizeFollowersService, type: :service do }.with_indifferent_access end - subject { described_class.new } - shared_examples 'synchronizes followers' do before do alice.follow!(actor) @@ -91,7 +93,7 @@ RSpec.describe ActivityPub::SynchronizeFollowersService, type: :service do type: 'CollectionPage', partOf: collection_uri, items: items, - } + }, }.with_indifferent_access end diff --git a/spec/services/after_block_domain_from_account_service_spec.rb b/spec/services/after_block_domain_from_account_service_spec.rb index 006e3f4d28..9bfaa35807 100644 --- a/spec/services/after_block_domain_from_account_service_spec.rb +++ b/spec/services/after_block_domain_from_account_service_spec.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe AfterBlockDomainFromAccountService, type: :service do + subject { described_class.new } + let!(:wolf) { Fabricate(:account, username: 'wolf', domain: 'evil.org', inbox_url: 'https://evil.org/inbox', protocol: :activitypub) } let!(:alice) { Fabricate(:account, username: 'alice') } - subject { AfterBlockDomainFromAccountService.new } - before do stub_jsonld_contexts! allow(ActivityPub::DeliveryWorker).to receive(:perform_async) diff --git a/spec/services/after_block_service_spec.rb b/spec/services/after_block_service_spec.rb index 337766d066..d81bba1d8d 100644 --- a/spec/services/after_block_service_spec.rb +++ b/spec/services/after_block_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe AfterBlockService, type: :service do diff --git a/spec/services/app_sign_up_service_spec.rb b/spec/services/app_sign_up_service_spec.rb index 8ec4d4a7a6..2532304964 100644 --- a/spec/services/app_sign_up_service_spec.rb +++ b/spec/services/app_sign_up_service_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe AppSignUpService, type: :service do + subject { described_class.new } + let(:app) { Fabricate(:application, scopes: 'read write') } let(:good_params) { { username: 'alice', password: '12345678', email: 'good@email.com', agreement: true } } let(:remote_ip) { IPAddr.new('198.0.2.1') } - subject { described_class.new } - describe '#call' do it 'returns nil when registrations are closed' do tmp = Setting.registrations_mode diff --git a/spec/services/authorize_follow_service_spec.rb b/spec/services/authorize_follow_service_spec.rb index 888d694b61..d07645ab6b 100644 --- a/spec/services/authorize_follow_service_spec.rb +++ b/spec/services/authorize_follow_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe AuthorizeFollowService, type: :service do - let(:sender) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { AuthorizeFollowService.new } + let(:sender) { Fabricate(:account, username: 'alice') } describe 'local' do let(:bob) { Fabricate(:account, username: 'bob') } diff --git a/spec/services/backup_service_spec.rb b/spec/services/backup_service_spec.rb new file mode 100644 index 0000000000..806ba18323 --- /dev/null +++ b/spec/services/backup_service_spec.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe BackupService, type: :service do + subject(:service_call) { described_class.new.call(backup) } + + let!(:user) { Fabricate(:user) } + let!(:attachment) { Fabricate(:media_attachment, account: user.account) } + let!(:status) { Fabricate(:status, account: user.account, text: 'Hello', visibility: :public, media_attachments: [attachment]) } + let!(:private_status) { Fabricate(:status, account: user.account, text: 'secret', visibility: :private) } + let!(:favourite) { Fabricate(:favourite, account: user.account) } + let!(:bookmark) { Fabricate(:bookmark, account: user.account) } + let!(:backup) { Fabricate(:backup, user: user) } + + def read_zip_file(backup, filename) + file = Paperclip.io_adapters.for(backup.dump) + Zip::File.open(file) do |zipfile| + entry = zipfile.glob(filename).first + return entry.get_input_stream.read + end + end + + context 'when the user has an avatar and header' do + before do + user.account.update!(avatar: attachment_fixture('avatar.gif')) + user.account.update!(header: attachment_fixture('emojo.png')) + end + + it 'stores them as expected' do + service_call + + json = export_json(:actor) + avatar_path = json.dig('icon', 'url') + header_path = json.dig('image', 'url') + + expect(avatar_path).to_not be_nil + expect(header_path).to_not be_nil + + expect(read_zip_file(backup, avatar_path)).to be_present + expect(read_zip_file(backup, header_path)).to be_present + end + end + + it 'marks the backup as processed and exports files' do + expect { service_call }.to process_backup + + expect_outbox_export + expect_likes_export + expect_bookmarks_export + end + + def process_backup + change(backup, :processed).from(false).to(true) + end + + def expect_outbox_export + json = export_json(:outbox) + + aggregate_failures do + expect(json['@context']).to_not be_nil + expect(json['type']).to eq 'OrderedCollection' + expect(json['totalItems']).to eq 2 + expect(json['orderedItems'][0]['@context']).to be_nil + expect(json['orderedItems'][0]).to include_create_item(status) + expect(json['orderedItems'][1]).to include_create_item(private_status) + end + end + + def expect_likes_export + json = export_json(:likes) + + aggregate_failures do + expect(json['type']).to eq 'OrderedCollection' + expect(json['orderedItems']).to eq [ActivityPub::TagManager.instance.uri_for(favourite.status)] + end + end + + def expect_bookmarks_export + json = export_json(:bookmarks) + + aggregate_failures do + expect(json['type']).to eq 'OrderedCollection' + expect(json['orderedItems']).to eq [ActivityPub::TagManager.instance.uri_for(bookmark.status)] + end + end + + def export_json(type) + Oj.load(read_zip_file(backup, "#{type}.json")) + end + + def include_create_item(status) + include({ + 'type' => 'Create', + 'object' => include({ + 'id' => ActivityPub::TagManager.instance.uri_for(status), + 'content' => "

#{status.text}

", + }), + }) + end +end diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index 920edeb13e..8201c9d51f 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe BatchedRemoveStatusService, type: :service do - subject { BatchedRemoveStatusService.new } + subject { described_class.new } let!(:alice) { Fabricate(:account) } let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') } let!(:jeff) { Fabricate(:account) } let!(:hank) { Fabricate(:account, username: 'hank', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } - let(:status1) { PostStatusService.new.call(alice, text: 'Hello @bob@example.com') } - let(:status2) { PostStatusService.new.call(alice, text: 'Another status') } + let(:status_alice_hello) { PostStatusService.new.call(alice, text: 'Hello @bob@example.com') } + let(:status_alice_other) { PostStatusService.new.call(alice, text: 'Another status') } before do allow(redis).to receive_messages(publish: nil) @@ -20,23 +22,23 @@ RSpec.describe BatchedRemoveStatusService, type: :service do jeff.follow!(alice) hank.follow!(alice) - status1 - status2 + status_alice_hello + status_alice_other - subject.call([status1, status2]) + subject.call([status_alice_hello, status_alice_other]) end it 'removes statuses' do - expect { Status.find(status1.id) }.to raise_error ActiveRecord::RecordNotFound - expect { Status.find(status2.id) }.to raise_error ActiveRecord::RecordNotFound + expect { Status.find(status_alice_hello.id) }.to raise_error ActiveRecord::RecordNotFound + expect { Status.find(status_alice_other.id) }.to raise_error ActiveRecord::RecordNotFound end it 'removes statuses from author\'s home feed' do - expect(HomeFeed.new(alice).get(10)).to_not include([status1.id, status2.id]) + expect(HomeFeed.new(alice).get(10).pluck(:id)).to_not include(status_alice_hello.id, status_alice_other.id) end it 'removes statuses from local follower\'s home feed' do - expect(HomeFeed.new(jeff).get(10)).to_not include([status1.id, status2.id]) + expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(status_alice_hello.id, status_alice_other.id) end it 'notifies streaming API of followers' do diff --git a/spec/services/block_domain_service_spec.rb b/spec/services/block_domain_service_spec.rb index 242b02fff7..36dce9d196 100644 --- a/spec/services/block_domain_service_spec.rb +++ b/spec/services/block_domain_service_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe BlockDomainService, type: :service do - let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') } - let!(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') } - let!(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') } - let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) } - let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) } + subject { described_class.new } - subject { BlockDomainService.new } + let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') } + let!(:bad_status_plain) { Fabricate(:status, account: bad_account, text: 'You suck') } + let!(:bad_status_with_attachment) { Fabricate(:status, account: bad_account, text: 'Hahaha') } + let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status_with_attachment, file: attachment_fixture('attachment.jpg')) } + let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) } describe 'for a suspension' do before do @@ -35,8 +37,8 @@ RSpec.describe BlockDomainService, type: :service do end it 'removes the remote accounts\'s statuses and media attachments' do - expect { bad_status1.reload }.to raise_exception ActiveRecord::RecordNotFound - expect { bad_status2.reload }.to raise_exception ActiveRecord::RecordNotFound + expect { bad_status_plain.reload }.to raise_exception ActiveRecord::RecordNotFound + expect { bad_status_with_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound expect { bad_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound end end @@ -67,9 +69,9 @@ RSpec.describe BlockDomainService, type: :service do end it 'leaves the domains status and attachments, but clears media' do - expect { bad_status1.reload }.not_to raise_error - expect { bad_status2.reload }.not_to raise_error - expect { bad_attachment.reload }.not_to raise_error + expect { bad_status_plain.reload }.to_not raise_error + expect { bad_status_with_attachment.reload }.to_not raise_error + expect { bad_attachment.reload }.to_not raise_error expect(bad_attachment.file.exists?).to be false end end diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb index a53e1f9288..5f7c2e8da0 100644 --- a/spec/services/block_service_spec.rb +++ b/spec/services/block_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe BlockService, type: :service do - let(:sender) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { BlockService.new } + let(:sender) { Fabricate(:account, username: 'alice') } describe 'local' do let(:bob) { Fabricate(:account, username: 'bob') } diff --git a/spec/services/bootstrap_timeline_service_spec.rb b/spec/services/bootstrap_timeline_service_spec.rb index 16f3e9962e..721a0337fd 100644 --- a/spec/services/bootstrap_timeline_service_spec.rb +++ b/spec/services/bootstrap_timeline_service_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe BootstrapTimelineService, type: :service do - subject { BootstrapTimelineService.new } + subject { described_class.new } context 'when the new user has registered from an invite' do - let(:service) { double } + let(:service) { instance_double(FollowService) } let(:autofollow) { false } let(:inviter) { Fabricate(:user, confirmed_at: 2.days.ago) } let(:invite) { Fabricate(:invite, user: inviter, max_uses: nil, expires_at: 1.hour.from_now, autofollow: autofollow) } @@ -32,6 +34,5 @@ RSpec.describe BootstrapTimelineService, type: :service do expect(service).to_not have_received(:call) end end - end end diff --git a/spec/services/bulk_import_row_service_spec.rb b/spec/services/bulk_import_row_service_spec.rb new file mode 100644 index 0000000000..a77acc0732 --- /dev/null +++ b/spec/services/bulk_import_row_service_spec.rb @@ -0,0 +1,173 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe BulkImportRowService do + subject { described_class.new } + + let(:account) { Fabricate(:account) } + let(:import) { Fabricate(:bulk_import, account: account, type: import_type) } + let(:import_row) { Fabricate(:bulk_import_row, bulk_import: import, data: data) } + + describe '#call' do + context 'when importing a follow' do + let(:import_type) { 'following' } + let(:target_account) { Fabricate(:account) } + let(:service_double) { instance_double(FollowService, call: nil) } + let(:data) do + { 'acct' => target_account.acct } + end + + before do + allow(FollowService).to receive(:new).and_return(service_double) + end + + it 'calls FollowService with the expected arguments and returns true' do + expect(subject.call(import_row)).to be true + + expect(service_double).to have_received(:call).with(account, target_account, { reblogs: nil, notify: nil, languages: nil }) + end + end + + context 'when importing a block' do + let(:import_type) { 'blocking' } + let(:target_account) { Fabricate(:account) } + let(:service_double) { instance_double(BlockService, call: nil) } + let(:data) do + { 'acct' => target_account.acct } + end + + before do + allow(BlockService).to receive(:new).and_return(service_double) + end + + it 'calls BlockService with the expected arguments and returns true' do + expect(subject.call(import_row)).to be true + + expect(service_double).to have_received(:call).with(account, target_account) + end + end + + context 'when importing a mute' do + let(:import_type) { 'muting' } + let(:target_account) { Fabricate(:account) } + let(:service_double) { instance_double(MuteService, call: nil) } + let(:data) do + { 'acct' => target_account.acct } + end + + before do + allow(MuteService).to receive(:new).and_return(service_double) + end + + it 'calls MuteService with the expected arguments and returns true' do + expect(subject.call(import_row)).to be true + + expect(service_double).to have_received(:call).with(account, target_account, { notifications: nil }) + end + end + + context 'when importing a bookmark' do + let(:import_type) { 'bookmarks' } + let(:data) do + { 'uri' => ActivityPub::TagManager.instance.uri_for(target_status) } + end + + context 'when the status is public' do + let(:target_status) { Fabricate(:status) } + + it 'bookmarks the status and returns true' do + expect(subject.call(import_row)).to be true + expect(account.bookmarked?(target_status)).to be true + end + end + + context 'when the status is not accessible to the user' do + let(:target_status) { Fabricate(:status, visibility: :direct) } + + it 'does not bookmark the status and returns false' do + expect(subject.call(import_row)).to be false + expect(account.bookmarked?(target_status)).to be false + end + end + end + + context 'when importing a list row' do + let(:import_type) { 'lists' } + let(:target_account) { Fabricate(:account) } + let(:data) do + { 'acct' => target_account.acct, 'list_name' => 'my list' } + end + + shared_examples 'common behavior' do + context 'when the target account is already followed' do + before do + account.follow!(target_account) + end + + it 'returns true' do + expect(subject.call(import_row)).to be true + end + + it 'adds the target account to the list' do + expect { subject.call(import_row) }.to change { ListAccount.joins(:list).exists?(account_id: target_account.id, list: { title: 'my list' }) }.from(false).to(true) + end + end + + context 'when the user already requested to follow the target account' do + before do + account.request_follow!(target_account) + end + + it 'returns true' do + expect(subject.call(import_row)).to be true + end + + it 'adds the target account to the list' do + expect { subject.call(import_row) }.to change { ListAccount.joins(:list).exists?(account_id: target_account.id, list: { title: 'my list' }) }.from(false).to(true) + end + end + + context 'when the target account is neither followed nor requested' do + it 'returns true' do + expect(subject.call(import_row)).to be true + end + + it 'adds the target account to the list' do + expect { subject.call(import_row) }.to change { ListAccount.joins(:list).exists?(account_id: target_account.id, list: { title: 'my list' }) }.from(false).to(true) + end + end + + context 'when the target account is the user themself' do + let(:target_account) { account } + + it 'returns true' do + expect(subject.call(import_row)).to be true + end + + it 'adds the target account to the list' do + expect { subject.call(import_row) }.to change { ListAccount.joins(:list).exists?(account_id: target_account.id, list: { title: 'my list' }) }.from(false).to(true) + end + end + end + + context 'when the list does not exist yet' do + include_examples 'common behavior' + end + + context 'when the list exists' do + before do + Fabricate(:list, account: account, title: 'my list') + end + + include_examples 'common behavior' + + it 'does not create a new list' do + account.follow!(target_account) + + expect { subject.call(import_row) }.to_not(change { List.where(title: 'my list').count }) + end + end + end + end +end diff --git a/spec/services/bulk_import_service_spec.rb b/spec/services/bulk_import_service_spec.rb new file mode 100644 index 0000000000..281b642ea4 --- /dev/null +++ b/spec/services/bulk_import_service_spec.rb @@ -0,0 +1,417 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe BulkImportService do + subject { described_class.new } + + let(:account) { Fabricate(:account) } + let(:import) { Fabricate(:bulk_import, account: account, type: import_type, overwrite: overwrite, state: :in_progress, imported_items: 0, processed_items: 0) } + + before do + import.update(total_items: import.rows.count) + end + + describe '#call' do + around do |example| + Sidekiq::Testing.fake! do + example.run + Sidekiq::Worker.clear_all + end + end + + context 'when importing follows' do + let(:import_type) { 'following' } + let(:overwrite) { false } + + let!(:rows) do + [ + { 'acct' => 'user@foo.bar' }, + { 'acct' => 'unknown@unknown.bar' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.follow!(Fabricate(:account)) + end + + it 'does not immediately change who the account follows' do + expect { subject.call(import) }.to_not(change { account.reload.active_relationships.to_a }) + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) + end + + it 'requests to follow all the listed users once the workers have run' do + subject.call(import) + + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) + allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + + expect(FollowRequest.includes(:target_account).where(account: account).map(&:target_account).map(&:acct)).to contain_exactly('user@foo.bar', 'unknown@unknown.bar') + end + end + + context 'when importing follows with overwrite' do + let(:import_type) { 'following' } + let(:overwrite) { true } + + let!(:followed) { Fabricate(:account, username: 'followed', domain: 'foo.bar', protocol: :activitypub) } + let!(:to_be_unfollowed) { Fabricate(:account, username: 'to_be_unfollowed', domain: 'foo.bar', protocol: :activitypub) } + + let!(:rows) do + [ + { 'acct' => 'followed@foo.bar', 'show_reblogs' => false, 'notify' => true, 'languages' => ['en'] }, + { 'acct' => 'user@foo.bar' }, + { 'acct' => 'unknown@unknown.bar' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.follow!(followed, reblogs: true, notify: false) + account.follow!(to_be_unfollowed) + end + + it 'unfollows user not present on list' do + subject.call(import) + expect(account.following?(to_be_unfollowed)).to be false + end + + it 'updates the existing follow relationship as expected' do + expect { subject.call(import) }.to change { Follow.where(account: account, target_account: followed).pick(:show_reblogs, :notify, :languages) }.from([true, false, nil]).to([false, true, ['en']]) + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id)) + end + + it 'requests to follow all the expected users once the workers have run' do + subject.call(import) + + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) + allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + + expect(FollowRequest.includes(:target_account).where(account: account).map(&:target_account).map(&:acct)).to contain_exactly('user@foo.bar', 'unknown@unknown.bar') + end + end + + context 'when importing blocks' do + let(:import_type) { 'blocking' } + let(:overwrite) { false } + + let!(:rows) do + [ + { 'acct' => 'user@foo.bar' }, + { 'acct' => 'unknown@unknown.bar' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.block!(Fabricate(:account, username: 'already_blocked', domain: 'remote.org')) + end + + it 'does not immediately change who the account blocks' do + expect { subject.call(import) }.to_not(change { account.reload.blocking.to_a }) + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) + end + + it 'blocks all the listed users once the workers have run' do + subject.call(import) + + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) + allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + + expect(account.blocking.map(&:acct)).to contain_exactly('already_blocked@remote.org', 'user@foo.bar', 'unknown@unknown.bar') + end + end + + context 'when importing blocks with overwrite' do + let(:import_type) { 'blocking' } + let(:overwrite) { true } + + let!(:blocked) { Fabricate(:account, username: 'blocked', domain: 'foo.bar', protocol: :activitypub) } + let!(:to_be_unblocked) { Fabricate(:account, username: 'to_be_unblocked', domain: 'foo.bar', protocol: :activitypub) } + + let!(:rows) do + [ + { 'acct' => 'blocked@foo.bar' }, + { 'acct' => 'user@foo.bar' }, + { 'acct' => 'unknown@unknown.bar' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.block!(blocked) + account.block!(to_be_unblocked) + end + + it 'unblocks user not present on list' do + subject.call(import) + expect(account.blocking?(to_be_unblocked)).to be false + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id)) + end + + it 'requests to follow all the expected users once the workers have run' do + subject.call(import) + + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) + allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + + expect(account.blocking.map(&:acct)).to contain_exactly('blocked@foo.bar', 'user@foo.bar', 'unknown@unknown.bar') + end + end + + context 'when importing mutes' do + let(:import_type) { 'muting' } + let(:overwrite) { false } + + let!(:rows) do + [ + { 'acct' => 'user@foo.bar' }, + { 'acct' => 'unknown@unknown.bar' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.mute!(Fabricate(:account, username: 'already_muted', domain: 'remote.org')) + end + + it 'does not immediately change who the account blocks' do + expect { subject.call(import) }.to_not(change { account.reload.muting.to_a }) + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) + end + + it 'mutes all the listed users once the workers have run' do + subject.call(import) + + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) + allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + + expect(account.muting.map(&:acct)).to contain_exactly('already_muted@remote.org', 'user@foo.bar', 'unknown@unknown.bar') + end + end + + context 'when importing mutes with overwrite' do + let(:import_type) { 'muting' } + let(:overwrite) { true } + + let!(:muted) { Fabricate(:account, username: 'muted', domain: 'foo.bar', protocol: :activitypub) } + let!(:to_be_unmuted) { Fabricate(:account, username: 'to_be_unmuted', domain: 'foo.bar', protocol: :activitypub) } + + let!(:rows) do + [ + { 'acct' => 'muted@foo.bar', 'hide_notifications' => true }, + { 'acct' => 'user@foo.bar' }, + { 'acct' => 'unknown@unknown.bar' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.mute!(muted, notifications: false) + account.mute!(to_be_unmuted) + end + + it 'updates the existing mute as expected' do + expect { subject.call(import) }.to change { Mute.where(account: account, target_account: muted).pick(:hide_notifications) }.from(false).to(true) + end + + it 'unblocks user not present on list' do + subject.call(import) + expect(account.muting?(to_be_unmuted)).to be false + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows[1..].map(&:id)) + end + + it 'requests to follow all the expected users once the workers have run' do + subject.call(import) + + resolve_account_service_double = instance_double(ResolveAccountService) + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service_double) + allow(resolve_account_service_double).to receive(:call).with('user@foo.bar', any_args) { Fabricate(:account, username: 'user', domain: 'foo.bar', protocol: :activitypub) } + allow(resolve_account_service_double).to receive(:call).with('unknown@unknown.bar', any_args) { Fabricate(:account, username: 'unknown', domain: 'unknown.bar', protocol: :activitypub) } + + Import::RowWorker.drain + + expect(account.muting.map(&:acct)).to contain_exactly('muted@foo.bar', 'user@foo.bar', 'unknown@unknown.bar') + end + end + + context 'when importing domain blocks' do + let(:import_type) { 'domain_blocking' } + let(:overwrite) { false } + + let!(:rows) do + [ + { 'domain' => 'blocked.com' }, + { 'domain' => 'to_block.com' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.block_domain!('alreadyblocked.com') + account.block_domain!('blocked.com') + end + + it 'blocks all the new domains' do + subject.call(import) + expect(account.domain_blocks.pluck(:domain)).to contain_exactly('alreadyblocked.com', 'blocked.com', 'to_block.com') + end + + it 'marks the import as finished' do + subject.call(import) + expect(import.reload.finished?).to be true + end + end + + context 'when importing domain blocks with overwrite' do + let(:import_type) { 'domain_blocking' } + let(:overwrite) { true } + + let!(:rows) do + [ + { 'domain' => 'blocked.com' }, + { 'domain' => 'to_block.com' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.block_domain!('alreadyblocked.com') + account.block_domain!('blocked.com') + end + + it 'blocks all the new domains' do + subject.call(import) + expect(account.domain_blocks.pluck(:domain)).to contain_exactly('blocked.com', 'to_block.com') + end + + it 'marks the import as finished' do + subject.call(import) + expect(import.reload.finished?).to be true + end + end + + context 'when importing bookmarks' do + let(:import_type) { 'bookmarks' } + let(:overwrite) { false } + + let!(:already_bookmarked) { Fabricate(:status, uri: 'https://already.bookmarked/1') } + let!(:status) { Fabricate(:status, uri: 'https://foo.bar/posts/1') } + let!(:inaccessible_status) { Fabricate(:status, uri: 'https://foo.bar/posts/inaccessible', visibility: :direct) } + let!(:bookmarked) { Fabricate(:status, uri: 'https://foo.bar/posts/already-bookmarked') } + + let!(:rows) do + [ + { 'uri' => status.uri }, + { 'uri' => inaccessible_status.uri }, + { 'uri' => bookmarked.uri }, + { 'uri' => 'https://domain.unknown/foo' }, + { 'uri' => 'https://domain.unknown/private' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.bookmarks.create!(status: already_bookmarked) + account.bookmarks.create!(status: bookmarked) + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) + end + + it 'updates the bookmarks as expected once the workers have run' do + subject.call(import) + + service_double = instance_double(ActivityPub::FetchRemoteStatusService) + allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double) + allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') } + allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) } + + Import::RowWorker.drain + + expect(account.bookmarks.map(&:status).map(&:uri)).to contain_exactly(already_bookmarked.uri, status.uri, bookmarked.uri, 'https://domain.unknown/foo') + end + end + + context 'when importing bookmarks with overwrite' do + let(:import_type) { 'bookmarks' } + let(:overwrite) { true } + + let!(:already_bookmarked) { Fabricate(:status, uri: 'https://already.bookmarked/1') } + let!(:status) { Fabricate(:status, uri: 'https://foo.bar/posts/1') } + let!(:inaccessible_status) { Fabricate(:status, uri: 'https://foo.bar/posts/inaccessible', visibility: :direct) } + let!(:bookmarked) { Fabricate(:status, uri: 'https://foo.bar/posts/already-bookmarked') } + + let!(:rows) do + [ + { 'uri' => status.uri }, + { 'uri' => inaccessible_status.uri }, + { 'uri' => bookmarked.uri }, + { 'uri' => 'https://domain.unknown/foo' }, + { 'uri' => 'https://domain.unknown/private' }, + ].map { |data| import.rows.create!(data: data) } + end + + before do + account.bookmarks.create!(status: already_bookmarked) + account.bookmarks.create!(status: bookmarked) + end + + it 'enqueues workers for the expected rows' do + subject.call(import) + expect(Import::RowWorker.jobs.pluck('args').flatten).to match_array(rows.map(&:id)) + end + + it 'updates the bookmarks as expected once the workers have run' do + subject.call(import) + + service_double = instance_double(ActivityPub::FetchRemoteStatusService) + allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service_double) + allow(service_double).to receive(:call).with('https://domain.unknown/foo') { Fabricate(:status, uri: 'https://domain.unknown/foo') } + allow(service_double).to receive(:call).with('https://domain.unknown/private') { Fabricate(:status, uri: 'https://domain.unknown/private', visibility: :direct) } + + Import::RowWorker.drain + + expect(account.bookmarks.map(&:status).map(&:uri)).to contain_exactly(status.uri, bookmarked.uri, 'https://domain.unknown/foo') + end + end + end +end diff --git a/spec/services/clear_domain_media_service_spec.rb b/spec/services/clear_domain_media_service_spec.rb index 45b92e2c94..9766e62de8 100644 --- a/spec/services/clear_domain_media_service_spec.rb +++ b/spec/services/clear_domain_media_service_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ClearDomainMediaService, type: :service do - let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') } - let!(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') } - let!(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') } - let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) } + subject { described_class.new } - subject { ClearDomainMediaService.new } + let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') } + let!(:bad_status_plain) { Fabricate(:status, account: bad_account, text: 'You suck') } + let!(:bad_status_with_attachment) { Fabricate(:status, account: bad_account, text: 'Hahaha') } + let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status_with_attachment, file: attachment_fixture('attachment.jpg')) } describe 'for a silence with reject media' do before do @@ -14,9 +16,9 @@ RSpec.describe ClearDomainMediaService, type: :service do end it 'leaves the domains status and attachments, but clears media' do - expect { bad_status1.reload }.not_to raise_error - expect { bad_status2.reload }.not_to raise_error - expect { bad_attachment.reload }.not_to raise_error + expect { bad_status_plain.reload }.to_not raise_error + expect { bad_status_with_attachment.reload }.to_not raise_error + expect { bad_attachment.reload }.to_not raise_error expect(bad_attachment.file.exists?).to be false end end diff --git a/spec/services/delete_account_service_spec.rb b/spec/services/delete_account_service_spec.rb index 1fbe4d07c2..68ab491e4e 100644 --- a/spec/services/delete_account_service_spec.rb +++ b/spec/services/delete_account_service_spec.rb @@ -1,7 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe DeleteAccountService, type: :service do shared_examples 'common behavior' do + subject { described_class.new.call(account) } + let!(:status) { Fabricate(:status, account: account) } let!(:mention) { Fabricate(:mention, account: local_follower) } let!(:status_with_mention) { Fabricate(:status, account: account, mentions: [mention]) } @@ -23,8 +27,6 @@ RSpec.describe DeleteAccountService, type: :service do let!(:account_note) { Fabricate(:account_note, account: account) } - subject { described_class.new.call(account) } - it 'deletes associated owned records' do expect { subject }.to change { [ @@ -50,21 +52,21 @@ RSpec.describe DeleteAccountService, type: :service do it 'deletes associated target notifications' do expect { subject }.to change { - [ - 'poll', 'favourite', 'status', 'mention', 'follow' - ].map { |type| Notification.where(type: type).count } + %w( + poll favourite status mention follow + ).map { |type| Notification.where(type: type).count } }.from([1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0]) end end describe '#call on local account' do before do - stub_request(:post, "https://alice.com/inbox").to_return(status: 201) - stub_request(:post, "https://bob.com/inbox").to_return(status: 201) + stub_request(:post, 'https://alice.com/inbox').to_return(status: 201) + stub_request(:post, 'https://bob.com/inbox').to_return(status: 201) end - let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } - let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', domain: 'alice.com', protocol: :activitypub) } + let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', domain: 'bob.com', protocol: :activitypub) } include_examples 'common behavior' do let!(:account) { Fabricate(:account) } @@ -72,25 +74,47 @@ RSpec.describe DeleteAccountService, type: :service do it 'sends a delete actor activity to all known inboxes' do subject - expect(a_request(:post, "https://alice.com/inbox")).to have_been_made.once - expect(a_request(:post, "https://bob.com/inbox")).to have_been_made.once + expect(a_request(:post, 'https://alice.com/inbox')).to have_been_made.once + expect(a_request(:post, 'https://bob.com/inbox')).to have_been_made.once end end end describe '#call on remote account' do before do - stub_request(:post, "https://alice.com/inbox").to_return(status: 201) - stub_request(:post, "https://bob.com/inbox").to_return(status: 201) + stub_request(:post, 'https://alice.com/inbox').to_return(status: 201) + stub_request(:post, 'https://bob.com/inbox').to_return(status: 201) end include_examples 'common behavior' do - let!(:account) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:account) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') } let!(:local_follower) { Fabricate(:account) } - it 'sends a reject follow to follower inboxes' do + it 'sends expected activities to followed and follower inboxes' do subject - expect(a_request(:post, account.inbox_url)).to have_been_made.once + + expect(a_request(:post, account.inbox_url).with( + body: + hash_including({ + 'type' => 'Reject', + 'object' => hash_including({ + 'type' => 'Follow', + 'actor' => account.uri, + 'object' => ActivityPub::TagManager.instance.uri_for(local_follower), + }), + }) + )).to have_been_made.once + + expect(a_request(:post, account.inbox_url).with( + body: hash_including({ + 'type' => 'Undo', + 'object' => hash_including({ + 'type' => 'Follow', + 'actor' => ActivityPub::TagManager.instance.uri_for(local_follower), + 'object' => account.uri, + }), + }) + )).to have_been_made.once end end end diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index 59e15d2301..3b554f9ea3 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -1,16 +1,17 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe FanOutOnWriteService, type: :service do + subject { described_class.new } + let(:last_active_at) { Time.now.utc } + let(:status) { Fabricate(:status, account: alice, visibility: visibility, text: 'Hello @bob #hoge') } let!(:alice) { Fabricate(:user, current_sign_in_at: last_active_at).account } let!(:bob) { Fabricate(:user, current_sign_in_at: last_active_at, account_attributes: { username: 'bob' }).account } let!(:tom) { Fabricate(:user, current_sign_in_at: last_active_at).account } - subject { described_class.new } - - let(:status) { Fabricate(:status, account: alice, visibility: visibility, text: 'Hello @bob #hoge') } - before do bob.follow!(alice) tom.follow!(alice) diff --git a/spec/services/favourite_service_spec.rb b/spec/services/favourite_service_spec.rb index 9781f0d78b..782c235c41 100644 --- a/spec/services/favourite_service_spec.rb +++ b/spec/services/favourite_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe FavouriteService, type: :service do - let(:sender) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { FavouriteService.new } + let(:sender) { Fabricate(:account, username: 'alice') } describe 'local' do let(:bob) { Fabricate(:account) } @@ -23,7 +25,7 @@ RSpec.describe FavouriteService, type: :service do let(:status) { Fabricate(:status, account: bob) } before do - stub_request(:post, "http://example.com/inbox").to_return(status: 200, body: "", headers: {}) + stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {}) subject.call(sender, status) end @@ -32,7 +34,7 @@ RSpec.describe FavouriteService, type: :service do end it 'sends a like activity' do - expect(a_request(:post, "http://example.com/inbox")).to have_been_made.once + expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once end end end diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb index 7a758f910f..f44cbb750c 100644 --- a/spec/services/fetch_link_card_service_spec.rb +++ b/spec/services/fetch_link_card_service_spec.rb @@ -1,107 +1,253 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe FetchLinkCardService, type: :service do subject { described_class.new } + let(:html) { 'Hello world' } + let(:oembed_cache) { nil } + before do - stub_request(:get, 'http://example.xn--fiqs8s/').to_return(request_fixture('idn.txt')) + stub_request(:get, 'http://example.com/html').to_return(headers: { 'Content-Type' => 'text/html' }, body: html) + stub_request(:get, 'http://example.com/not-found').to_return(status: 404, headers: { 'Content-Type' => 'text/html' }, body: html) + stub_request(:get, 'http://example.com/text').to_return(status: 404, headers: { 'Content-Type' => 'text/plain' }, body: 'Hello') + stub_request(:get, 'http://example.com/redirect').to_return(status: 302, headers: { 'Location' => 'http://example.com/html' }) + stub_request(:get, 'http://example.com/redirect-to-404').to_return(status: 302, headers: { 'Location' => 'http://example.com/not-found' }) + stub_request(:get, 'http://example.com/oembed?url=http://example.com/html').to_return(headers: { 'Content-Type' => 'application/json' }, body: '{ "version": "1.0", "type": "link", "title": "oEmbed title" }') + stub_request(:get, 'http://example.com/oembed?format=json&url=http://example.com/html').to_return(headers: { 'Content-Type' => 'application/json' }, body: '{ "version": "1.0", "type": "link", "title": "oEmbed title" }') + + stub_request(:get, 'http://example.xn--fiqs8s') + stub_request(:get, 'http://example.com/日本語') + stub_request(:get, 'http://example.com/test?data=file.gpx%5E1') + stub_request(:get, 'http://example.com/test-') + stub_request(:get, 'http://example.com/sjis').to_return(request_fixture('sjis.txt')) stub_request(:get, 'http://example.com/sjis_with_wrong_charset').to_return(request_fixture('sjis_with_wrong_charset.txt')) stub_request(:get, 'http://example.com/koi8-r').to_return(request_fixture('koi8-r.txt')) - stub_request(:get, 'http://example.com/日本語').to_return(request_fixture('sjis.txt')) - stub_request(:get, 'https://github.com/qbi/WannaCry').to_return(status: 404) - stub_request(:get, 'http://example.com/test?data=file.gpx%5E1').to_return(status: 200) - stub_request(:get, 'http://example.com/test-').to_return(request_fixture('idn.txt')) stub_request(:get, 'http://example.com/windows-1251').to_return(request_fixture('windows-1251.txt')) + Rails.cache.write('oembed_endpoint:example.com', oembed_cache) if oembed_cache + subject.call(status) end - context 'in a local status' do - context do + context 'with a local status' do + context 'with URL of a regular HTML page' do + let(:status) { Fabricate(:status, text: 'http://example.com/html') } + + it 'creates preview card' do + expect(status.preview_card).to_not be_nil + expect(status.preview_card.url).to eq 'http://example.com/html' + expect(status.preview_card.title).to eq 'Hello world' + end + end + + context 'with URL of a page with no title' do + let(:status) { Fabricate(:status, text: 'http://example.com/html') } + let(:html) { '' } + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end + + context 'with a URL of a plain-text page' do + let(:status) { Fabricate(:status, text: 'http://example.com/text') } + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end + + context 'with multiple URLs' do + let(:status) { Fabricate(:status, text: 'ftp://example.com http://example.com/html http://example.com/text') } + + it 'fetches the first valid URL' do + expect(a_request(:get, 'http://example.com/html')).to have_been_made + end + + it 'does not fetch the second valid URL' do + expect(a_request(:get, 'http://example.com/text/')).to_not have_been_made + end + end + + context 'with a redirect URL' do + let(:status) { Fabricate(:status, text: 'http://example.com/redirect') } + + it 'follows redirect' do + expect(a_request(:get, 'http://example.com/redirect')).to have_been_made.once + expect(a_request(:get, 'http://example.com/html')).to have_been_made.once + end + + it 'creates preview card' do + expect(status.preview_card).to_not be_nil + expect(status.preview_card.url).to eq 'http://example.com/html' + expect(status.preview_card.title).to eq 'Hello world' + end + end + + context 'with a broken redirect URL' do + let(:status) { Fabricate(:status, text: 'http://example.com/redirect-to-404') } + + it 'follows redirect' do + expect(a_request(:get, 'http://example.com/redirect-to-404')).to have_been_made.once + expect(a_request(:get, 'http://example.com/not-found')).to have_been_made.once + end + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end + + context 'with a 404 URL' do + let(:status) { Fabricate(:status, text: 'http://example.com/not-found') } + + it 'does not create a preview card' do + expect(status.preview_card).to be_nil + end + end + + context 'with an IDN URL' do let(:status) { Fabricate(:status, text: 'Check out http://example.中国') } - it 'works with IDN URLs' do - expect(a_request(:get, 'http://example.xn--fiqs8s/')).to have_been_made.at_least_once + it 'fetches the URL' do + expect(a_request(:get, 'http://example.xn--fiqs8s/')).to have_been_made.once end end - context do + context 'with a URL of a page in Shift JIS encoding' do let(:status) { Fabricate(:status, text: 'Check out http://example.com/sjis') } - it 'works with SJIS' do - expect(a_request(:get, 'http://example.com/sjis')).to have_been_made.at_least_once - expect(status.preview_cards.first.title).to eq("SJISのページ") + it 'decodes the HTML' do + expect(status.preview_cards.first.title).to eq('SJISのページ') end end - context do + context 'with a URL of a page in Shift JIS encoding labeled as UTF-8' do let(:status) { Fabricate(:status, text: 'Check out http://example.com/sjis_with_wrong_charset') } - it 'works with SJIS even with wrong charset header' do - expect(a_request(:get, 'http://example.com/sjis_with_wrong_charset')).to have_been_made.at_least_once - expect(status.preview_cards.first.title).to eq("SJISのページ") + it 'decodes the HTML despite the wrong charset header' do + expect(status.preview_cards.first.title).to eq('SJISのページ') end end - context do + context 'with a URL of a page in KOI8-R encoding' do let(:status) { Fabricate(:status, text: 'Check out http://example.com/koi8-r') } - it 'works with koi8-r' do - expect(a_request(:get, 'http://example.com/koi8-r')).to have_been_made.at_least_once - expect(status.preview_cards.first.title).to eq("Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.") + it 'decodes the HTML' do + expect(status.preview_cards.first.title).to eq('Московя начинаетъ только въ XVI ст. привлекать внимане иностранцевъ.') end end - context do + context 'with a URL of a page in Windows-1251 encoding' do let(:status) { Fabricate(:status, text: 'Check out http://example.com/windows-1251') } - it 'works with windows-1251' do - expect(a_request(:get, 'http://example.com/windows-1251')).to have_been_made.at_least_once + it 'decodes the HTML' do expect(status.preview_cards.first.title).to eq('сэмпл текст') end end - context do + context 'with a Japanese path URL' do let(:status) { Fabricate(:status, text: 'テストhttp://example.com/日本語') } - it 'works with Japanese path string' do - expect(a_request(:get, 'http://example.com/日本語')).to have_been_made.at_least_once - expect(status.preview_cards.first.title).to eq("SJISのページ") + it 'fetches the URL' do + expect(a_request(:get, 'http://example.com/日本語')).to have_been_made.once end end - context do + context 'with a hyphen-suffixed URL' do let(:status) { Fabricate(:status, text: 'test http://example.com/test-') } - it 'works with a URL ending with a hyphen' do - expect(a_request(:get, 'http://example.com/test-')).to have_been_made.at_least_once + it 'fetches the URL' do + expect(a_request(:get, 'http://example.com/test-')).to have_been_made.once end end - context do + context 'with a caret-suffixed URL' do + let(:status) { Fabricate(:status, text: 'test http://example.com/test?data=file.gpx^1') } + + it 'fetches the URL' do + expect(a_request(:get, 'http://example.com/test?data=file.gpx%5E1')).to have_been_made.once + end + + it 'does not strip the caret before fetching' do + expect(a_request(:get, 'http://example.com/test?data=file.gpx')).to_not have_been_made + end + end + + context 'with a non-isolated URL' do let(:status) { Fabricate(:status, text: 'testhttp://example.com/sjis') } - it 'does not fetch URLs with not isolated from their surroundings' do + it 'does not fetch URLs not isolated from their surroundings' do expect(a_request(:get, 'http://example.com/sjis')).to_not have_been_made end end - context do - let(:status) { Fabricate(:status, text: 'test http://example.com/test?data=file.gpx^1') } + context 'with a URL of a page with oEmbed support' do + let(:html) { 'Hello world' } + let(:status) { Fabricate(:status, text: 'http://example.com/html') } - it 'does fetch URLs with a caret in search params' do - expect(a_request(:get, 'http://example.com/test?data=file.gpx')).to_not have_been_made - expect(a_request(:get, 'http://example.com/test?data=file.gpx%5E1')).to have_been_made.once + it 'fetches the oEmbed URL' do + expect(a_request(:get, 'http://example.com/oembed?url=http://example.com/html')).to have_been_made.once + end + + it 'creates preview card' do + expect(status.preview_card).to_not be_nil + expect(status.preview_card.url).to eq 'http://example.com/html' + expect(status.preview_card.title).to eq 'oEmbed title' + end + + context 'when oEmbed endpoint cache populated' do + let(:oembed_cache) { { endpoint: 'http://example.com/oembed?format=json&url={url}', format: :json } } + + it 'uses the cached oEmbed response' do + expect(a_request(:get, 'http://example.com/oembed?url=http://example.com/html')).to_not have_been_made + expect(a_request(:get, 'http://example.com/oembed?format=json&url=http://example.com/html')).to have_been_made + end + + it 'creates preview card' do + expect(status.preview_card).to_not be_nil + expect(status.preview_card.url).to eq 'http://example.com/html' + expect(status.preview_card.title).to eq 'oEmbed title' + end + end + + # If the original HTML URL for whatever reason (e.g. DOS protection) redirects to + # an error page, we can still use the cached oEmbed but should not use the + # redirect URL on the card. + context 'when oEmbed endpoint cache populated but page returns 404' do + let(:status) { Fabricate(:status, text: 'http://example.com/redirect-to-404') } + let(:oembed_cache) { { endpoint: 'http://example.com/oembed?url=http://example.com/html', format: :json } } + + it 'uses the cached oEmbed response' do + expect(a_request(:get, 'http://example.com/oembed?url=http://example.com/html')).to have_been_made + end + + it 'creates preview card' do + expect(status.preview_card).to_not be_nil + expect(status.preview_card.title).to eq 'oEmbed title' + end + + it 'uses the original URL' do + expect(status.preview_card&.url).to eq 'http://example.com/redirect-to-404' + end end end end - context 'in a remote status' do - let(:status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), text: 'Habt ihr ein paar gute Links zu foo #Wannacry herumfliegen? Ich will mal unter
https://github.com/qbi/WannaCry was sammeln. !security ') } + context 'with a remote status' do + let(:status) do + Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), text: <<-TEXT) + Habt ihr ein paar gute Links zu foo + #Wannacry herumfliegen? + Ich will mal unter
http://example.com/not-found was sammeln. ! + security  + TEXT + end it 'parses out URLs' do - expect(a_request(:get, 'https://github.com/qbi/WannaCry')).to have_been_made.at_least_once + expect(a_request(:get, 'http://example.com/not-found')).to have_been_made.once end it 'ignores URLs to hashtags' do diff --git a/spec/services/fetch_oembed_service_spec.rb b/spec/services/fetch_oembed_service_spec.rb index 88f0113edd..777cbae3fb 100644 --- a/spec/services/fetch_oembed_service_spec.rb +++ b/spec/services/fetch_oembed_service_spec.rb @@ -6,9 +6,9 @@ describe FetchOEmbedService, type: :service do subject { described_class.new } before do - stub_request(:get, "https://host.test/provider.json").to_return(status: 404) - stub_request(:get, "https://host.test/provider.xml").to_return(status: 404) - stub_request(:get, "https://host.test/empty_provider.json").to_return(status: 200) + stub_request(:get, 'https://host.test/provider.json').to_return(status: 404) + stub_request(:get, 'https://host.test/provider.xml').to_return(status: 404) + stub_request(:get, 'https://host.test/empty_provider.json').to_return(status: 200) end describe 'discover_provider' do @@ -18,7 +18,7 @@ describe FetchOEmbedService, type: :service do stub_request(:get, 'https://www.youtube.com/watch?v=IPSbNdBmWKE').to_return( status: 200, headers: { 'Content-Type': 'text/html' }, - body: request_fixture('oembed_youtube.html'), + body: request_fixture('oembed_youtube.html') ) stub_request(:get, 'https://www.youtube.com/oembed?format=json&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DIPSbNdBmWKE').to_return( status: 200, @@ -39,7 +39,7 @@ describe FetchOEmbedService, type: :service do end end - context 'Both of JSON and XML provider are discoverable' do + context 'when both of JSON and XML provider are discoverable' do before do stub_request(:get, 'https://host.test/oembed.html').to_return( status: 200, @@ -62,11 +62,11 @@ describe FetchOEmbedService, type: :service do it 'does not cache OEmbed endpoint' do subject.call('https://host.test/oembed.html', format: :xml) - expect(Rails.cache.exist?('oembed_endpoint:host.test')).to eq false + expect(Rails.cache.exist?('oembed_endpoint:host.test')).to be false end end - context 'JSON provider is discoverable while XML provider is not' do + context 'when JSON provider is discoverable while XML provider is not' do before do stub_request(:get, 'https://host.test/oembed.html').to_return( status: 200, @@ -83,11 +83,11 @@ describe FetchOEmbedService, type: :service do it 'does not cache OEmbed endpoint' do subject.call('https://host.test/oembed.html') - expect(Rails.cache.exist?('oembed_endpoint:host.test')).to eq false + expect(Rails.cache.exist?('oembed_endpoint:host.test')).to be false end end - context 'XML provider is discoverable while JSON provider is not' do + context 'when XML provider is discoverable while JSON provider is not' do before do stub_request(:get, 'https://host.test/oembed.html').to_return( status: 200, @@ -104,11 +104,11 @@ describe FetchOEmbedService, type: :service do it 'does not cache OEmbed endpoint' do subject.call('https://host.test/oembed.html') - expect(Rails.cache.exist?('oembed_endpoint:host.test')).to eq false + expect(Rails.cache.exist?('oembed_endpoint:host.test')).to be false end end - context 'Invalid XML provider is discoverable while JSON provider is not' do + context 'with Invalid XML provider is discoverable while JSON provider is not' do before do stub_request(:get, 'https://host.test/oembed.html').to_return( status: 200, @@ -122,7 +122,7 @@ describe FetchOEmbedService, type: :service do end end - context 'Neither of JSON and XML provider is discoverable' do + context 'with neither of JSON and XML provider is discoverable' do before do stub_request(:get, 'https://host.test/oembed.html').to_return( status: 200, @@ -136,7 +136,7 @@ describe FetchOEmbedService, type: :service do end end - context 'Empty JSON provider is discoverable' do + context 'when empty JSON provider is discoverable' do before do stub_request(:get, 'https://host.test/oembed.html').to_return( status: 200, @@ -151,7 +151,6 @@ describe FetchOEmbedService, type: :service do expect(subject.format).to eq :json end end - end context 'when endpoint is cached' do diff --git a/spec/services/fetch_remote_status_service_spec.rb b/spec/services/fetch_remote_status_service_spec.rb index 4f6ad64967..798740c9b3 100644 --- a/spec/services/fetch_remote_status_service_spec.rb +++ b/spec/services/fetch_remote_status_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe FetchRemoteStatusService, type: :service do @@ -7,15 +9,16 @@ RSpec.describe FetchRemoteStatusService, type: :service do let(:note) do { '@context': 'https://www.w3.org/ns/activitystreams', - id: "https://example.org/@foo/1234", + id: 'https://example.org/@foo/1234', type: 'Note', content: 'Lorem ipsum', attributedTo: ActivityPub::TagManager.instance.uri_for(account), } end - context 'protocol is :activitypub' do + context 'when protocol is :activitypub' do subject { described_class.new.call(note[:id], prefetched_body: prefetched_body) } + let(:prefetched_body) { Oj.dump(note) } before do diff --git a/spec/services/fetch_resource_service_spec.rb b/spec/services/fetch_resource_service_spec.rb index c0c96ab69c..0f1068471f 100644 --- a/spec/services/fetch_resource_service_spec.rb +++ b/spec/services/fetch_resource_service_spec.rb @@ -1,13 +1,16 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe FetchResourceService, type: :service do describe '#call' do - let(:url) { 'http://example.com' } - subject { described_class.new.call(url) } + let(:url) { 'http://example.com' } + context 'with blank url' do let(:url) { '' } + it { is_expected.to be_nil } end @@ -21,7 +24,7 @@ RSpec.describe FetchResourceService, type: :service do context 'when OpenSSL::SSL::SSLError is raised' do before do - request = double() + request = instance_double(Request) allow(Request).to receive(:new).and_return(request) allow(request).to receive(:add_headers) allow(request).to receive(:on_behalf_of) @@ -33,7 +36,7 @@ RSpec.describe FetchResourceService, type: :service do context 'when HTTP::ConnectionError is raised' do before do - request = double() + request = instance_double(Request) allow(Request).to receive(:new).and_return(request) allow(request).to receive(:add_headers) allow(request).to receive(:on_behalf_of) @@ -62,6 +65,7 @@ RSpec.describe FetchResourceService, type: :service do before do stub_request(:get, url).to_return(status: 200, body: body, headers: headers) + stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' }) end it 'signs request' do @@ -72,7 +76,7 @@ RSpec.describe FetchResourceService, type: :service do context 'when content type is application/atom+xml' do let(:content_type) { 'application/atom+xml' } - it { is_expected.to eq nil } + it { is_expected.to be_nil } end context 'when content type is activity+json' do @@ -89,13 +93,8 @@ RSpec.describe FetchResourceService, type: :service do it { is_expected.to eq [1, { prefetched_body: body, id: true }] } end - before do - stub_request(:get, url).to_return(status: 200, body: body, headers: headers) - stub_request(:get, 'http://example.com/foo').to_return(status: 200, body: json, headers: { 'Content-Type' => 'application/activity+json' }) - end - context 'when link header is present' do - let(:headers) { { 'Link' => '; rel="alternate"; type="application/activity+json"', } } + let(:headers) { { 'Link' => '; rel="alternate"; type="application/activity+json"' } } it { is_expected.to eq [1, { prefetched_body: json, id: true }] } end diff --git a/spec/services/follow_service_spec.rb b/spec/services/follow_service_spec.rb index 412c04d76b..c2ad0d7173 100644 --- a/spec/services/follow_service_spec.rb +++ b/spec/services/follow_service_spec.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe FollowService, type: :service do + subject { described_class.new } + let(:sender) { Fabricate(:account, username: 'alice') } - subject { FollowService.new } - - context 'local account' do + context 'when local account' do describe 'locked account' do let(:bob) { Fabricate(:account, locked: true, username: 'bob') } @@ -136,11 +138,11 @@ RSpec.describe FollowService, type: :service do end end - context 'remote ActivityPub account' do + context 'when remote ActivityPub account' do let(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') } before do - stub_request(:post, "http://example.com/inbox").to_return(status: 200, body: "", headers: {}) + stub_request(:post, 'http://example.com/inbox').to_return(status: 200, body: '', headers: {}) subject.call(sender, bob) end diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index e2d182920e..1904ac8dc9 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ImportService, type: :service do @@ -8,16 +10,17 @@ RSpec.describe ImportService, type: :service do let!(:eve) { Fabricate(:account, username: 'eve', domain: 'example.com', locked: false, protocol: :activitypub, inbox_url: 'https://example.com/inbox') } before do - stub_request(:post, "https://example.com/inbox").to_return(status: 200) + stub_request(:post, 'https://example.com/inbox').to_return(status: 200) end - context 'import old-style list of muted users' do - subject { ImportService.new } + context 'when importing old-style list of muted users' do + subject { described_class.new } let(:csv) { attachment_fixture('mute-imports.txt') } describe 'when no accounts are muted' do let(:import) { Import.create(account: account, type: 'muting', data: csv) } + it 'mutes the listed accounts, including notifications' do subject.call(import) expect(account.muting.count).to eq 2 @@ -48,13 +51,14 @@ RSpec.describe ImportService, type: :service do end end - context 'import new-style list of muted users' do - subject { ImportService.new } + context 'when importing new-style list of muted users' do + subject { described_class.new } let(:csv) { attachment_fixture('new-mute-imports.txt') } describe 'when no accounts are muted' do let(:import) { Import.create(account: account, type: 'muting', data: csv) } + it 'mutes the listed accounts, respecting notifications' do subject.call(import) expect(account.muting.count).to eq 2 @@ -88,13 +92,14 @@ RSpec.describe ImportService, type: :service do end end - context 'import old-style list of followed users' do - subject { ImportService.new } + context 'when importing old-style list of followed users' do + subject { described_class.new } let(:csv) { attachment_fixture('mute-imports.txt') } describe 'when no accounts are followed' do let(:import) { Import.create(account: account, type: 'following', data: csv) } + it 'follows the listed accounts, including boosts' do subject.call(import) @@ -129,13 +134,14 @@ RSpec.describe ImportService, type: :service do end end - context 'import new-style list of followed users' do - subject { ImportService.new } + context 'when importing new-style list of followed users' do + subject { described_class.new } let(:csv) { attachment_fixture('new-following-imports.txt') } describe 'when no accounts are followed' do let(:import) { Import.create(account: account, type: 'following', data: csv) } + it 'follows the listed accounts, respecting boosts' do subject.call(import) expect(account.following.count).to eq 1 @@ -175,30 +181,32 @@ RSpec.describe ImportService, type: :service do # Based on the bug report 20571 where UTF-8 encoded domains were rejecting import of their users # # https://github.com/mastodon/mastodon/issues/20571 - context 'utf-8 encoded domains' do - subject { ImportService.new } - - let!(:nare) { Fabricate(:account, username: 'nare', domain: 'թութ.հայ', locked: false, protocol: :activitypub, inbox_url: 'https://թութ.հայ/inbox') } - - # Make sure to not actually go to the remote server - before do - stub_request(:post, "https://թութ.հայ/inbox").to_return(status: 200) - end + context 'with a utf-8 encoded domains' do + subject { described_class.new } + let!(:nare) { Fabricate(:account, username: 'nare', domain: 'թութ.հայ', locked: false, protocol: :activitypub, inbox_url: 'https://թութ.հայ/inbox') } let(:csv) { attachment_fixture('utf8-followers.txt') } let(:import) { Import.create(account: account, type: 'following', data: csv) } + # Make sure to not actually go to the remote server + before do + stub_request(:post, 'https://թութ.հայ/inbox').to_return(status: 200) + end + it 'follows the listed account' do - expect(account.follow_requests.count).to eq 0 + expect(account.follow_requests.count).to eq 0 subject.call(import) expect(account.follow_requests.count).to eq 1 end end - context 'import bookmarks' do - subject { ImportService.new } + context 'when importing bookmarks' do + subject { described_class.new } let(:csv) { attachment_fixture('bookmark-imports.txt') } + let(:local_account) { Fabricate(:account, username: 'foo', domain: '') } + let!(:remote_status) { Fabricate(:status, uri: 'https://example.com/statuses/1312') } + let!(:direct_status) { Fabricate(:status, uri: 'https://example.com/statuses/direct', visibility: :direct) } around(:each) do |example| local_before = Rails.configuration.x.local_domain @@ -210,12 +218,8 @@ RSpec.describe ImportService, type: :service do Rails.configuration.x.local_domain = local_before end - let(:local_account) { Fabricate(:account, username: 'foo', domain: '') } - let!(:remote_status) { Fabricate(:status, uri: 'https://example.com/statuses/1312') } - let!(:direct_status) { Fabricate(:status, uri: 'https://example.com/statuses/direct', visibility: :direct) } - before do - service = double + service = instance_double(ActivityPub::FetchRemoteStatusService) allow(ActivityPub::FetchRemoteStatusService).to receive(:new).and_return(service) allow(service).to receive(:call).with('https://unknown-remote.com/users/bar/statuses/1') do Fabricate(:status, uri: 'https://unknown-remote.com/users/bar/statuses/1') @@ -224,12 +228,13 @@ RSpec.describe ImportService, type: :service do describe 'when no bookmarks are set' do let(:import) { Import.create(account: account, type: 'bookmarks', data: csv) } + it 'adds the toots the user has access to to bookmarks' do local_status = Fabricate(:status, account: local_account, uri: 'https://local.com/users/foo/statuses/42', id: 42, local: true) subject.call(import) expect(account.bookmarks.map(&:status).map(&:id)).to include(local_status.id) expect(account.bookmarks.map(&:status).map(&:id)).to include(remote_status.id) - expect(account.bookmarks.map(&:status).map(&:id)).not_to include(direct_status.id) + expect(account.bookmarks.map(&:status).map(&:id)).to_not include(direct_status.id) expect(account.bookmarks.count).to eq 3 end end diff --git a/spec/services/mute_service_spec.rb b/spec/services/mute_service_spec.rb index 57d8c41dec..50f74ff277 100644 --- a/spec/services/mute_service_spec.rb +++ b/spec/services/mute_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe MuteService, type: :service do diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb index 294c31b044..8fcb586580 100644 --- a/spec/services/notify_service_spec.rb +++ b/spec/services/notify_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe NotifyService, type: :service do @@ -47,22 +49,23 @@ RSpec.describe NotifyService, type: :service do expect { subject }.to_not change(Notification, :count) end - context 'for direct messages' do + context 'with direct messages' do let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct)) } let(:type) { :mention } before do - user.settings.interactions = user.settings.interactions.merge('must_be_following_dm' => enabled) + user.settings.update('interactions.must_be_following_dm': enabled) + user.save end - context 'if recipient is supposed to be following sender' do + context 'when recipient is supposed to be following sender' do let(:enabled) { true } it 'does not notify' do expect { subject }.to_not change(Notification, :count) end - context 'if the message chain is initiated by recipient, but is not direct message' do + context 'when the message chain is initiated by recipient, but is not direct message' do let(:reply_to) { Fabricate(:status, account: recipient) } let!(:mention) { Fabricate(:mention, account: sender, status: reply_to) } let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) } @@ -72,7 +75,7 @@ RSpec.describe NotifyService, type: :service do end end - context 'if the message chain is initiated by recipient, but without a mention to the sender, even if the sender sends multiple messages in a row' do + context 'when the message chain is initiated by recipient, but without a mention to the sender, even if the sender sends multiple messages in a row' do let(:reply_to) { Fabricate(:status, account: recipient) } let!(:mention) { Fabricate(:mention, account: sender, status: reply_to) } let(:dummy_reply) { Fabricate(:status, account: sender, visibility: :direct, thread: reply_to) } @@ -83,7 +86,7 @@ RSpec.describe NotifyService, type: :service do end end - context 'if the message chain is initiated by the recipient with a mention to the sender' do + context 'when the message chain is initiated by the recipient with a mention to the sender' do let(:reply_to) { Fabricate(:status, account: recipient, visibility: :direct) } let!(:mention) { Fabricate(:mention, account: sender, status: reply_to) } let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) } @@ -94,7 +97,7 @@ RSpec.describe NotifyService, type: :service do end end - context 'if recipient is NOT supposed to be following sender' do + context 'when recipient is NOT supposed to be following sender' do let(:enabled) { false } it 'does notify' do @@ -124,7 +127,7 @@ RSpec.describe NotifyService, type: :service do end end - context do + context 'with muted and blocked users' do let(:asshole) { Fabricate(:account, username: 'asshole') } let(:reply_to) { Fabricate(:status, account: asshole) } let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, thread: reply_to)) } @@ -141,7 +144,7 @@ RSpec.describe NotifyService, type: :service do end end - context do + context 'with sender as recipient' do let(:sender) { recipient } it 'does not notify when recipient is the sender' do @@ -153,8 +156,8 @@ RSpec.describe NotifyService, type: :service do before do ActionMailer::Base.deliveries.clear - notification_emails = user.settings.notification_emails - user.settings.notification_emails = notification_emails.merge('follow' => enabled) + user.settings.update('notification_emails.follow': enabled) + user.save end context 'when email notification is enabled' do diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index d21270c793..7d7679c889 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe PostStatusService, type: :service do - subject { PostStatusService.new } + subject { described_class.new } it 'creates a new status' do account = Fabricate(:account) - text = "test status update" + text = 'test status update' status = subject.call(account, text: text) @@ -16,7 +18,7 @@ RSpec.describe PostStatusService, type: :service do it 'creates a new response status' do in_reply_to_status = Fabricate(:status) account = Fabricate(:account) - text = "test status update" + text = 'test status update' status = subject.call(account, text: text, thread: in_reply_to_status) @@ -46,11 +48,11 @@ RSpec.describe PostStatusService, type: :service do expect(status.params['text']).to eq 'Hi future!' expect(status.params['media_ids']).to eq [media.id] expect(media.reload.status).to be_nil - expect(Status.where(text: 'Hi future!').exists?).to be_falsey + expect(Status.where(text: 'Hi future!')).to_not exist end it 'does not change statuses count' do - expect { subject.call(account, text: 'Hi future!', scheduled_at: future, thread: previous_status) }.not_to change { [account.statuses_count, previous_status.replies_count] } + expect { subject.call(account, text: 'Hi future!', scheduled_at: future, thread: previous_status) }.to_not(change { [account.statuses_count, previous_status.replies_count] }) end end @@ -58,7 +60,7 @@ RSpec.describe PostStatusService, type: :service do boosted_status = Fabricate(:status) in_reply_to_status = Fabricate(:status, reblog: boosted_status) account = Fabricate(:account) - text = "test status update" + text = 'test status update' status = subject.call(account, text: text, thread: in_reply_to_status) @@ -75,7 +77,7 @@ RSpec.describe PostStatusService, type: :service do end it 'creates a status with spoiler text' do - spoiler_text = "spoiler text" + spoiler_text = 'spoiler text' status = create_status_with_options(spoiler_text: spoiler_text) @@ -101,14 +103,14 @@ RSpec.describe PostStatusService, type: :service do status = create_status_with_options(visibility: :private) expect(status).to be_persisted - expect(status.visibility).to eq "private" + expect(status.visibility).to eq 'private' end it 'creates a status with limited visibility for silenced users' do status = subject.call(Fabricate(:account, silenced: true), text: 'test', visibility: :public) expect(status).to be_persisted - expect(status.visibility).to eq "unlisted" + expect(status.visibility).to eq 'unlisted' end it 'creates a status for the given application' do @@ -130,24 +132,43 @@ RSpec.describe PostStatusService, type: :service do end it 'processes mentions' do - mention_service = double(:process_mentions_service) + mention_service = instance_double(ProcessMentionsService) allow(mention_service).to receive(:call) allow(ProcessMentionsService).to receive(:new).and_return(mention_service) account = Fabricate(:account) - status = subject.call(account, text: "test status update") + status = subject.call(account, text: 'test status update') expect(ProcessMentionsService).to have_received(:new) - expect(mention_service).to have_received(:call).with(status) + expect(mention_service).to have_received(:call).with(status, save_records: false) + end + + it 'safeguards mentions' do + account = Fabricate(:account) + mentioned_account = Fabricate(:account, username: 'alice') + unexpected_mentioned_account = Fabricate(:account, username: 'bob') + + expect do + subject.call(account, text: '@alice hm, @bob is really annoying lately', allowed_mentions: [mentioned_account.id]) + end.to raise_error(an_instance_of(PostStatusService::UnexpectedMentionsError).and(having_attributes(accounts: [unexpected_mentioned_account]))) + end + + it 'processes duplicate mentions correctly' do + account = Fabricate(:account) + mentioned_account = Fabricate(:account, username: 'alice') + + expect do + subject.call(account, text: '@alice @alice @alice hey @alice') + end.to_not raise_error end it 'processes hashtags' do - hashtags_service = double(:process_hashtags_service) + hashtags_service = instance_double(ProcessHashtagsService) allow(hashtags_service).to receive(:call) allow(ProcessHashtagsService).to receive(:new).and_return(hashtags_service) account = Fabricate(:account) - status = subject.call(account, text: "test status update") + status = subject.call(account, text: 'test status update') expect(ProcessHashtagsService).to have_received(:new) expect(hashtags_service).to have_received(:call).with(status) @@ -159,7 +180,7 @@ RSpec.describe PostStatusService, type: :service do account = Fabricate(:account) - status = subject.call(account, text: "test status update") + status = subject.call(account, text: 'test status update') expect(DistributionWorker).to have_received(:perform_async).with(status.id) expect(ActivityPub::DistributionWorker).to have_received(:perform_async).with(status.id) @@ -169,7 +190,7 @@ RSpec.describe PostStatusService, type: :service do allow(LinkCrawlWorker).to receive(:perform_async) account = Fabricate(:account) - status = subject.call(account, text: "test status update") + status = subject.call(account, text: 'test status update') expect(LinkCrawlWorker).to have_received(:perform_async).with(status.id) end @@ -180,8 +201,8 @@ RSpec.describe PostStatusService, type: :service do status = subject.call( account, - text: "test status update", - media_ids: [media.id], + text: 'test status update', + media_ids: [media.id] ) expect(media.reload.status).to eq status @@ -193,11 +214,11 @@ RSpec.describe PostStatusService, type: :service do status = subject.call( account, - text: "test status update", - media_ids: [media.id], + text: 'test status update', + media_ids: [media.id] ) - expect(media.reload.status).to eq nil + expect(media.reload.status).to be_nil end it 'does not allow attaching more than 4 files' do @@ -206,18 +227,18 @@ RSpec.describe PostStatusService, type: :service do expect do subject.call( account, - text: "test status update", + text: 'test status update', media_ids: [ Fabricate(:media_attachment, account: account), Fabricate(:media_attachment, account: account), Fabricate(:media_attachment, account: account), Fabricate(:media_attachment, account: account), Fabricate(:media_attachment, account: account), - ].map(&:id), + ].map(&:id) ) end.to raise_error( Mastodon::ValidationError, - I18n.t('media_attachments.validations.too_many'), + I18n.t('media_attachments.validations.too_many') ) end @@ -231,15 +252,15 @@ RSpec.describe PostStatusService, type: :service do expect do subject.call( account, - text: "test status update", + text: 'test status update', media_ids: [ video, image, - ].map(&:id), + ].map(&:id) ) end.to raise_error( Mastodon::ValidationError, - I18n.t('media_attachments.validations.images_and_video'), + I18n.t('media_attachments.validations.images_and_video') ) end diff --git a/spec/services/precompute_feed_service_spec.rb b/spec/services/precompute_feed_service_spec.rb index 86b93b5d2f..54e0d94ee0 100644 --- a/spec/services/precompute_feed_service_spec.rb +++ b/spec/services/precompute_feed_service_spec.rb @@ -3,10 +3,11 @@ require 'rails_helper' RSpec.describe PrecomputeFeedService, type: :service do - subject { PrecomputeFeedService.new } + subject { described_class.new } describe 'call' do let(:account) { Fabricate(:account) } + it 'fills a user timeline with statuses' do account = Fabricate(:account) status = Fabricate(:status, account: account) @@ -18,7 +19,7 @@ RSpec.describe PrecomputeFeedService, type: :service do it 'does not raise an error even if it could not find any status' do account = Fabricate(:account) - subject.call(account) + expect { subject.call(account) }.to_not raise_error end it 'filters statuses' do @@ -30,7 +31,7 @@ RSpec.describe PrecomputeFeedService, type: :service do subject.call(account) - expect(redis.zscore(FeedManager.instance.key(:home, account.id), reblog.id)).to eq nil + expect(redis.zscore(FeedManager.instance.key(:home, account.id), reblog.id)).to be_nil end end end diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb index 5b9d17a4c2..0db73c41fa 100644 --- a/spec/services/process_mentions_service_spec.rb +++ b/spec/services/process_mentions_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ProcessMentionsService, type: :service do - let(:account) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { ProcessMentionsService.new } + let(:account) { Fabricate(:account, username: 'alice') } context 'when mentions contain blocked accounts' do let(:non_blocked_account) { Fabricate(:account) } @@ -31,11 +33,11 @@ RSpec.describe ProcessMentionsService, type: :service do end end - context 'resolving a mention to a remote account' do + context 'with resolving a mention to a remote account' do let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct}", visibility: :public) } - context 'ActivityPub' do - context do + context 'with ActivityPub' do + context 'with a valid remote user' do let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } before do @@ -47,9 +49,22 @@ RSpec.describe ProcessMentionsService, type: :service do end end + context 'when mentioning a user several times when not saving records' do + let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } + let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct} @#{remote_user.acct} @#{remote_user.acct}", visibility: :public) } + + before do + subject.call(status, save_records: false) + end + + it 'creates exactly one mention' do + expect(status.mentions.size).to eq 1 + end + end + context 'with an IDN domain' do let!(:remote_user) { Fabricate(:account, username: 'sneak', protocol: :activitypub, domain: 'xn--hresiar-mxa.ch', inbox_url: 'http://example.com/inbox') } - let!(:status) { Fabricate(:status, account: account, text: "Hello @sneak@hæresiar.ch") } + let!(:status) { Fabricate(:status, account: account, text: 'Hello @sneak@hæresiar.ch') } before do subject.call(status) @@ -62,7 +77,7 @@ RSpec.describe ProcessMentionsService, type: :service do context 'with an IDN TLD' do let!(:remote_user) { Fabricate(:account, username: 'foo', protocol: :activitypub, domain: 'xn--y9a3aq.xn--y9a3aq', inbox_url: 'http://example.com/inbox') } - let!(:status) { Fabricate(:status, account: account, text: "Hello @foo@հայ.հայ") } + let!(:status) { Fabricate(:status, account: account, text: 'Hello @foo@հայ.հայ') } before do subject.call(status) @@ -74,12 +89,12 @@ RSpec.describe ProcessMentionsService, type: :service do end end - context 'Temporarily-unreachable ActivityPub user' do + context 'with a Temporarily-unreachable ActivityPub user' do let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox', last_webfingered_at: nil) } before do - stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 404) - stub_request(:get, "https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com").to_return(status: 500) + stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404) + stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:remote_user@example.com').to_return(status: 500) subject.call(status) end diff --git a/spec/services/purge_domain_service_spec.rb b/spec/services/purge_domain_service_spec.rb index 59285f1269..e96618310b 100644 --- a/spec/services/purge_domain_service_spec.rb +++ b/spec/services/purge_domain_service_spec.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe PurgeDomainService, type: :service do - let!(:old_account) { Fabricate(:account, domain: 'obsolete.org') } - let!(:old_status1) { Fabricate(:status, account: old_account) } - let!(:old_status2) { Fabricate(:status, account: old_account) } - let!(:old_attachment) { Fabricate(:media_attachment, account: old_account, status: old_status2, file: attachment_fixture('attachment.jpg')) } + subject { described_class.new } - subject { PurgeDomainService.new } + let!(:old_account) { Fabricate(:account, domain: 'obsolete.org') } + let!(:old_status_plain) { Fabricate(:status, account: old_account) } + let!(:old_status_with_attachment) { Fabricate(:status, account: old_account) } + let!(:old_attachment) { Fabricate(:media_attachment, account: old_account, status: old_status_with_attachment, file: attachment_fixture('attachment.jpg')) } describe 'for a suspension' do before do @@ -15,8 +17,8 @@ RSpec.describe PurgeDomainService, type: :service do it 'removes the remote accounts\'s statuses and media attachments' do expect { old_account.reload }.to raise_exception ActiveRecord::RecordNotFound - expect { old_status1.reload }.to raise_exception ActiveRecord::RecordNotFound - expect { old_status2.reload }.to raise_exception ActiveRecord::RecordNotFound + expect { old_status_plain.reload }.to raise_exception ActiveRecord::RecordNotFound + expect { old_status_with_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound expect { old_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound end diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb index c0ae5eedcc..7b85e37ed8 100644 --- a/spec/services/reblog_service_spec.rb +++ b/spec/services/reblog_service_spec.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ReblogService, type: :service do let(:alice) { Fabricate(:account, username: 'alice') } - context 'creates a reblog with appropriate visibility' do + context 'when creates a reblog with appropriate visibility' do + subject { described_class.new } + let(:visibility) { :public } let(:reblog_visibility) { :public } let(:status) { Fabricate(:status, account: alice, visibility: visibility) } - subject { ReblogService.new } - before do subject.call(alice, status, visibility: reblog_visibility) end @@ -33,10 +35,25 @@ RSpec.describe ReblogService, type: :service do end context 'when the reblogged status is discarded in the meantime' do - let(:status) { Fabricate(:status, account: alice, visibility: :public) } + let(:status) { Fabricate(:status, account: alice, visibility: :public, text: 'discard-status-text') } + # Add a callback to discard the status being reblogged after the + # validations pass but before the database commit is executed. before do - status.discard + Status.class_eval do + before_save :discard_status + def discard_status + Status + .where(id: reblog_of_id) + .where(text: 'discard-status-text') + .update_all(deleted_at: Time.now.utc) # rubocop:disable Rails/SkipsModelValidations + end + end + end + + # Remove race condition simulating `discard_status` callback. + after do + Status._save_callbacks.delete(:discard_status) end it 'raises an exception' do @@ -44,12 +61,12 @@ RSpec.describe ReblogService, type: :service do end end - context 'ActivityPub' do + context 'with ActivityPub' do + subject { described_class.new } + let(:bob) { Fabricate(:account, username: 'bob', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } let(:status) { Fabricate(:status, account: bob) } - subject { ReblogService.new } - before do stub_request(:post, bob.inbox_url) allow(ActivityPub::DistributionWorker).to receive(:perform_async) diff --git a/spec/services/reject_follow_service_spec.rb b/spec/services/reject_follow_service_spec.rb index e14bfa78dc..d28104b2c7 100644 --- a/spec/services/reject_follow_service_spec.rb +++ b/spec/services/reject_follow_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe RejectFollowService, type: :service do - let(:sender) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { RejectFollowService.new } + let(:sender) { Fabricate(:account, username: 'alice') } describe 'local' do let(:bob) { Fabricate(:account) } diff --git a/spec/services/remove_from_follwers_service_spec.rb b/spec/services/remove_from_followers_service_spec.rb similarity index 94% rename from spec/services/remove_from_follwers_service_spec.rb rename to spec/services/remove_from_followers_service_spec.rb index a83f6f49ab..1b29cdcbea 100644 --- a/spec/services/remove_from_follwers_service_spec.rb +++ b/spec/services/remove_from_followers_service_spec.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe RemoveFromFollowersService, type: :service do - let(:bob) { Fabricate(:account, username: 'bob') } + subject { described_class.new } - subject { RemoveFromFollowersService.new } + let(:bob) { Fabricate(:account, username: 'bob') } describe 'local' do let(:sender) { Fabricate(:account, username: 'alice') } - + before do Follow.create(account: sender, target_account: bob) subject.call(bob, sender) diff --git a/spec/services/remove_status_service_spec.rb b/spec/services/remove_status_service_spec.rb index 482068d58f..c19b4fac15 100644 --- a/spec/services/remove_status_service_spec.rb +++ b/spec/services/remove_status_service_spec.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe RemoveStatusService, type: :service do - subject { RemoveStatusService.new } + subject { described_class.new } let!(:alice) { Fabricate(:account) } let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') } @@ -26,40 +28,40 @@ RSpec.describe RemoveStatusService, type: :service do it 'removes status from author\'s home feed' do subject.call(@status) - expect(HomeFeed.new(alice).get(10)).to_not include(@status.id) + expect(HomeFeed.new(alice).get(10).pluck(:id)).to_not include(@status.id) end it 'removes status from local follower\'s home feed' do subject.call(@status) - expect(HomeFeed.new(jeff).get(10)).to_not include(@status.id) + expect(HomeFeed.new(jeff).get(10).pluck(:id)).to_not include(@status.id) end it 'sends Delete activity to followers' do subject.call(@status) expect(a_request(:post, 'http://example.com/inbox').with( - body: hash_including({ - 'type' => 'Delete', - 'object' => { - 'type' => 'Tombstone', - 'id' => ActivityPub::TagManager.instance.uri_for(@status), - 'atomUri' => OStatus::TagManager.instance.uri_for(@status), - }, - }) - )).to have_been_made.once + body: hash_including({ + 'type' => 'Delete', + 'object' => { + 'type' => 'Tombstone', + 'id' => ActivityPub::TagManager.instance.uri_for(@status), + 'atomUri' => OStatus::TagManager.instance.uri_for(@status), + }, + }) + )).to have_been_made.once end it 'sends Delete activity to rebloggers' do subject.call(@status) expect(a_request(:post, 'http://example2.com/inbox').with( - body: hash_including({ - 'type' => 'Delete', - 'object' => { - 'type' => 'Tombstone', - 'id' => ActivityPub::TagManager.instance.uri_for(@status), - 'atomUri' => OStatus::TagManager.instance.uri_for(@status), - }, - }) - )).to have_been_made.once + body: hash_including({ + 'type' => 'Delete', + 'object' => { + 'type' => 'Tombstone', + 'id' => ActivityPub::TagManager.instance.uri_for(@status), + 'atomUri' => OStatus::TagManager.instance.uri_for(@status), + }, + }) + )).to have_been_made.once end it 'remove status from notifications' do @@ -78,14 +80,14 @@ RSpec.describe RemoveStatusService, type: :service do it 'sends Undo activity to followers' do subject.call(@status) expect(a_request(:post, 'http://example.com/inbox').with( - body: hash_including({ - 'type' => 'Undo', - 'object' => hash_including({ - 'type' => 'Announce', - 'object' => ActivityPub::TagManager.instance.uri_for(@original_status), - }), - }) - )).to have_been_made.once + body: hash_including({ + 'type' => 'Undo', + 'object' => hash_including({ + 'type' => 'Announce', + 'object' => ActivityPub::TagManager.instance.uri_for(@original_status), + }), + }) + )).to have_been_made.once end end @@ -98,14 +100,14 @@ RSpec.describe RemoveStatusService, type: :service do it 'sends Undo activity to followers' do subject.call(@status) expect(a_request(:post, 'http://example.com/inbox').with( - body: hash_including({ - 'type' => 'Undo', - 'object' => hash_including({ - 'type' => 'Announce', - 'object' => ActivityPub::TagManager.instance.uri_for(@original_status), - }), - }) - )).to have_been_made.once + body: hash_including({ + 'type' => 'Undo', + 'object' => hash_including({ + 'type' => 'Announce', + 'object' => ActivityPub::TagManager.instance.uri_for(@original_status), + }), + }) + )).to have_been_made.once end end end diff --git a/spec/services/report_service_spec.rb b/spec/services/report_service_spec.rb index 02bc42ac17..d3bcd5d31c 100644 --- a/spec/services/report_service_spec.rb +++ b/spec/services/report_service_spec.rb @@ -1,41 +1,108 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ReportService, type: :service do subject { described_class.new } let(:source_account) { Fabricate(:account) } + let(:target_account) { Fabricate(:account) } - context 'for a remote account' do + context 'with a local account' do + it 'has a uri' do + report = subject.call(source_account, target_account) + expect(report.uri).to_not be_nil + end + end + + context 'with a remote account' do let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') } + let(:forward) { false } before do stub_request(:post, 'http://example.com/inbox').to_return(status: 200) end - it 'sends ActivityPub payload when forward is true' do - subject.call(source_account, remote_account, forward: true) - expect(a_request(:post, 'http://example.com/inbox')).to have_been_made + context 'when forward is true' do + let(:forward) { true } + + it 'sends ActivityPub payload when forward is true' do + subject.call(source_account, remote_account, forward: forward) + expect(a_request(:post, 'http://example.com/inbox')).to have_been_made + end + + it 'has an uri' do + report = subject.call(source_account, remote_account, forward: forward) + expect(report.uri).to_not be_nil + end + + context 'when reporting a reply on a different remote server' do + let(:remote_thread_account) { Fabricate(:account, domain: 'foo.com', protocol: :activitypub, inbox_url: 'http://foo.com/inbox') } + let(:reported_status) { Fabricate(:status, account: remote_account, thread: Fabricate(:status, account: remote_thread_account)) } + + before do + stub_request(:post, 'http://foo.com/inbox').to_return(status: 200) + end + + context 'when forward_to_domains includes both the replied-to domain and the origin domain' do + it 'sends ActivityPub payload to both the author of the replied-to post and the reported user' do + subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward, forward_to_domains: [remote_account.domain, remote_thread_account.domain]) + expect(a_request(:post, 'http://foo.com/inbox')).to have_been_made + expect(a_request(:post, 'http://example.com/inbox')).to have_been_made + end + end + + context 'when forward_to_domains includes only the replied-to domain' do + it 'sends ActivityPub payload only to the author of the replied-to post' do + subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward, forward_to_domains: [remote_thread_account.domain]) + expect(a_request(:post, 'http://foo.com/inbox')).to have_been_made + expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made + end + end + + context 'when forward_to_domains does not include the replied-to domain' do + it 'does not send ActivityPub payload to the author of the replied-to post' do + subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward) + expect(a_request(:post, 'http://foo.com/inbox')).to_not have_been_made + end + end + end + + context 'when reporting a reply on the same remote server as the person being replied-to' do + let(:remote_thread_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') } + let(:reported_status) { Fabricate(:status, account: remote_account, thread: Fabricate(:status, account: remote_thread_account)) } + + context 'when forward_to_domains includes both the replied-to domain and the origin domain' do + it 'sends ActivityPub payload only once' do + subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward, forward_to_domains: [remote_account.domain]) + expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + end + end + + context 'when forward_to_domains does not include the replied-to domain' do + it 'sends ActivityPub payload only once' do + subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward) + expect(a_request(:post, 'http://example.com/inbox')).to have_been_made.once + end + end + end end - it 'does not send anything when forward is false' do - subject.call(source_account, remote_account, forward: false) - expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made - end - - it 'has an uri' do - report = subject.call(source_account, remote_account, forward: true) - expect(report.uri).to_not be_nil + context 'when forward is false' do + it 'does not send anything' do + subject.call(source_account, remote_account, forward: forward) + expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made + end end end context 'when the reported status is a DM' do - let(:target_account) { Fabricate(:account) } - let(:status) { Fabricate(:status, account: target_account, visibility: :direct) } - subject do -> { described_class.new.call(source_account, target_account, status_ids: [status.id]) } end + let(:status) { Fabricate(:status, account: target_account, visibility: :direct) } + context 'when it is addressed to the reporter' do before do status.mentions.create(account: source_account) @@ -85,16 +152,16 @@ RSpec.describe ReportService, type: :service do end context 'when other reports already exist for the same target' do - let!(:target_account) { Fabricate(:account) } - let!(:other_report) { Fabricate(:report, target_account: target_account) } - subject do -> { described_class.new.call(source_account, target_account) } end + let!(:other_report) { Fabricate(:report, target_account: target_account) } + before do ActionMailer::Base.deliveries.clear - source_account.user.settings.notification_emails['report'] = true + source_account.user.settings['notification_emails.report'] = true + source_account.user.save end it 'does not send an e-mail' do diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index 654606beab..f446d0ca6d 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -1,19 +1,21 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe ResolveAccountService, type: :service do subject { described_class.new } before do - stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 404) - stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt')) - stub_request(:get, "https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com").to_return(request_fixture('activitypub-webfinger.txt')) - stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor.txt')) - stub_request(:get, "https://ap.example.com/users/foo.atom").to_return(request_fixture('activitypub-feed.txt')) - stub_request(:get, %r{https://ap.example.com/users/foo/\w+}).to_return(status: 404) + stub_request(:get, 'https://example.com/.well-known/host-meta').to_return(status: 404) + stub_request(:get, 'https://quitter.no/avatar/7477-300-20160211190340.png').to_return(request_fixture('avatar.txt')) + stub_request(:get, 'https://ap.example.com/.well-known/webfinger?resource=acct:foo@ap.example.com').to_return(request_fixture('activitypub-webfinger.txt')) + stub_request(:get, 'https://ap.example.com/users/foo').to_return(request_fixture('activitypub-actor.txt')) + stub_request(:get, 'https://ap.example.com/users/foo.atom').to_return(request_fixture('activitypub-feed.txt')) + stub_request(:get, %r{https://ap\.example\.com/users/foo/\w+}).to_return(status: 404) stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:hoge@example.com').to_return(status: 410) end - context 'using skip_webfinger' do + context 'when using skip_webfinger' do context 'when account is known' do let!(:remote_account) { Fabricate(:account, username: 'foo', domain: 'ap.example.com', protocol: 'activitypub') } @@ -56,8 +58,8 @@ RSpec.describe ResolveAccountService, type: :service do context 'when there is an LRDD endpoint but no resolvable account' do before do - stub_request(:get, "https://quitter.no/.well-known/host-meta").to_return(request_fixture('.host-meta.txt')) - stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:catsrgr8@quitter.no").to_return(status: 404) + stub_request(:get, 'https://quitter.no/.well-known/host-meta').to_return(request_fixture('.host-meta.txt')) + stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:catsrgr8@quitter.no').to_return(status: 404) end it 'returns nil' do @@ -67,7 +69,7 @@ RSpec.describe ResolveAccountService, type: :service do context 'when there is no LRDD endpoint nor resolvable account' do before do - stub_request(:get, "https://example.com/.well-known/webfinger?resource=acct:catsrgr8@example.com").to_return(status: 404) + stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:catsrgr8@example.com').to_return(status: 404) end it 'returns nil' do @@ -76,7 +78,7 @@ RSpec.describe ResolveAccountService, type: :service do end context 'when webfinger returns http gone' do - context 'for a previously known account' do + context 'with a previously known account' do before do Fabricate(:account, username: 'hoge', domain: 'example.com', last_webfingered_at: nil) allow(AccountDeletionWorker).to receive(:perform_async) @@ -92,7 +94,7 @@ RSpec.describe ResolveAccountService, type: :service do end end - context 'for a previously unknown account' do + context 'with a previously unknown account' do it 'returns nil' do expect(subject.call('hoge@example.com')).to be_nil end @@ -108,7 +110,7 @@ RSpec.describe ResolveAccountService, type: :service do it 'returns new remote account' do account = subject.call('Foo@redirected.example.com') - expect(account.activitypub?).to eq true + expect(account.activitypub?).to be true expect(account.acct).to eq 'foo@ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' end @@ -123,7 +125,7 @@ RSpec.describe ResolveAccountService, type: :service do it 'returns new remote account' do account = subject.call('Foo@redirected.example.com') - expect(account.activitypub?).to eq true + expect(account.activitypub?).to be true expect(account.acct).to eq 'foo@ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' end @@ -146,20 +148,20 @@ RSpec.describe ResolveAccountService, type: :service do it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to eq true + expect(account.activitypub?).to be true expect(account.domain).to eq 'ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' end context 'with multiple types' do before do - stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor-individual.txt')) + stub_request(:get, 'https://ap.example.com/users/foo').to_return(request_fixture('activitypub-actor-individual.txt')) end it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to eq true + expect(account.activitypub?).to be true expect(account.domain).to eq 'ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' expect(account.actor_type).to eq 'Person' @@ -174,7 +176,7 @@ RSpec.describe ResolveAccountService, type: :service do it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to eq true + expect(account.activitypub?).to be true expect(account.domain).to eq 'ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' expect(account.uri).to eq 'https://ap.example.com/users/foo' @@ -190,12 +192,12 @@ RSpec.describe ResolveAccountService, type: :service do context 'with an already-known acct: URI changing ActivityPub id' do let!(:old_account) { Fabricate(:account, username: 'foo', domain: 'ap.example.com', uri: 'https://old.example.com/users/foo', last_webfingered_at: nil) } - let!(:status) { Fabricate(:status, account: old_account, text: 'foo') } + let!(:status) { Fabricate(:status, account: old_account, text: 'foo') } it 'returns new remote account' do account = subject.call('foo@ap.example.com') - expect(account.activitypub?).to eq true + expect(account.activitypub?).to be true expect(account.domain).to eq 'ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' expect(account.uri).to eq 'https://ap.example.com/users/foo' @@ -207,11 +209,6 @@ RSpec.describe ResolveAccountService, type: :service do fail_occurred = false return_values = Concurrent::Array.new - # Preload classes that throw circular dependency errors in threads - Account - TagManager - DomainBlock - threads = Array.new(5) do Thread.new do true while wait_for_start diff --git a/spec/services/resolve_url_service_spec.rb b/spec/services/resolve_url_service_spec.rb index ab5b50b765..7991aa6ef1 100644 --- a/spec/services/resolve_url_service_spec.rb +++ b/spec/services/resolve_url_service_spec.rb @@ -8,8 +8,8 @@ describe ResolveURLService, type: :service do describe '#call' do it 'returns nil when there is no resource url' do url = 'http://example.com/missing-resource' - known_account = Fabricate(:account, uri: url) - service = double + known_account = Fabricate(:account, uri: url, domain: 'example.com') + service = instance_double(FetchResourceService) allow(FetchResourceService).to receive(:new).and_return service allow(service).to receive(:response_code).and_return(404) @@ -20,8 +20,8 @@ describe ResolveURLService, type: :service do it 'returns known account on temporary error' do url = 'http://example.com/missing-resource' - known_account = Fabricate(:account, uri: url) - service = double + known_account = Fabricate(:account, uri: url, domain: 'example.com') + service = instance_double(FetchResourceService) allow(FetchResourceService).to receive(:new).and_return service allow(service).to receive(:response_code).and_return(500) @@ -30,7 +30,7 @@ describe ResolveURLService, type: :service do expect(subject.call(url)).to eq known_account end - context 'searching for a remote private status' do + context 'when searching for a remote private status' do let(:account) { Fabricate(:account) } let(:poster) { Fabricate(:account, domain: 'example.com') } let(:url) { 'https://example.com/@foo/42' } @@ -95,7 +95,7 @@ describe ResolveURLService, type: :service do end end - context 'searching for a local private status' do + context 'when searching for a local private status' do let(:account) { Fabricate(:account) } let(:poster) { Fabricate(:account) } let!(:status) { Fabricate(:status, account: poster, visibility: :private) } @@ -127,13 +127,13 @@ describe ResolveURLService, type: :service do end end - context 'searching for a link that redirects to a local public status' do + context 'when searching for a link that redirects to a local public status' do let(:account) { Fabricate(:account) } let(:poster) { Fabricate(:account) } let!(:status) { Fabricate(:status, account: poster, visibility: :public) } let(:url) { 'https://link.to/foobar' } let(:status_url) { ActivityPub::TagManager.instance.url_for(status) } - let(:uri) { ActivityPub::TagManager.instance.uri_for(status) } + let(:uri) { ActivityPub::TagManager.instance.uri_for(status) } before do stub_request(:get, url).to_return(status: 302, headers: { 'Location' => status_url }) diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb index 5b52662ba0..cb69af5f54 100644 --- a/spec/services/search_service_spec.rb +++ b/spec/services/search_service_spec.rb @@ -13,8 +13,8 @@ describe SearchService, type: :service do results = subject.call('', nil, 10) expect(results).to eq(empty_results) - expect(AccountSearchService).not_to have_received(:new) - expect(Tag).not_to have_received(:search_for) + expect(AccountSearchService).to_not have_received(:new) + expect(Tag).to_not have_received(:search_for) end end @@ -23,9 +23,9 @@ describe SearchService, type: :service do @query = 'http://test.host/query' end - context 'that does not find anything' do + context 'when it does not find anything' do it 'returns the empty results' do - service = double(call: nil) + service = instance_double(ResolveURLService, call: nil) allow(ResolveURLService).to receive(:new).and_return(service) results = subject.call(@query, nil, 10, resolve: true) @@ -34,10 +34,10 @@ describe SearchService, type: :service do end end - context 'that finds an account' do + context 'when it finds an account' do it 'includes the account in the results' do account = Account.new - service = double(call: account) + service = instance_double(ResolveURLService, call: account) allow(ResolveURLService).to receive(:new).and_return(service) results = subject.call(@query, nil, 10, resolve: true) @@ -46,10 +46,10 @@ describe SearchService, type: :service do end end - context 'that finds a status' do + context 'when it finds a status' do it 'includes the status in the results' do status = Status.new - service = double(call: status) + service = instance_double(ResolveURLService, call: status) allow(ResolveURLService).to receive(:new).and_return(service) results = subject.call(@query, nil, 10, resolve: true) @@ -60,45 +60,29 @@ describe SearchService, type: :service do end describe 'with a non-url query' do - context 'that matches an account' do + context 'when it matches an account' do it 'includes the account in the results' do query = 'username' account = Account.new - service = double(call: [account]) + service = instance_double(AccountSearchService, call: [account]) allow(AccountSearchService).to receive(:new).and_return(service) results = subject.call(query, nil, 10) - expect(service).to have_received(:call).with(query, nil, limit: 10, offset: 0, resolve: false) + expect(service).to have_received(:call).with(query, nil, limit: 10, offset: 0, resolve: false, start_with_hashtag: false, use_searchable_text: true, following: false) expect(results).to eq empty_results.merge(accounts: [account]) end end - context 'that matches a tag' do + context 'when it matches a tag' do it 'includes the tag in the results' do query = '#tag' tag = Tag.new - allow(Tag).to receive(:search_for).with('tag', 10, 0, exclude_unreviewed: nil).and_return([tag]) + allow(Tag).to receive(:search_for).with('tag', 10, 0, { exclude_unreviewed: nil }).and_return([tag]) results = subject.call(query, nil, 10) expect(Tag).to have_received(:search_for).with('tag', 10, 0, exclude_unreviewed: nil) expect(results).to eq empty_results.merge(hashtags: [tag]) end - it 'does not include tag when starts with @ character' do - query = '@username' - allow(Tag).to receive(:search_for) - - results = subject.call(query, nil, 10) - expect(Tag).not_to have_received(:search_for) - expect(results).to eq empty_results - end - it 'does not include account when starts with # character' do - query = '#tag' - allow(AccountSearchService).to receive(:new) - - results = subject.call(query, nil, 10) - expect(AccountSearchService).to_not have_received(:new) - expect(results).to eq empty_results - end end end end diff --git a/spec/services/software_update_check_service_spec.rb b/spec/services/software_update_check_service_spec.rb new file mode 100644 index 0000000000..c8821348ac --- /dev/null +++ b/spec/services/software_update_check_service_spec.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe SoftwareUpdateCheckService, type: :service do + subject { described_class.new } + + shared_examples 'when the feature is enabled' do + let(:full_update_check_url) { "#{update_check_url}?version=#{Mastodon::Version.to_s.split('+')[0]}" } + + let(:devops_role) { Fabricate(:user_role, name: 'DevOps', permissions: UserRole::FLAGS[:view_devops]) } + let(:owner_user) { Fabricate(:user, role: UserRole.find_by(name: 'Owner')) } + let(:old_devops_user) { Fabricate(:user) } + let(:none_user) { Fabricate(:user, role: devops_role) } + let(:patch_user) { Fabricate(:user, role: devops_role) } + let(:critical_user) { Fabricate(:user, role: devops_role) } + + around do |example| + queue_adapter = ActiveJob::Base.queue_adapter + ActiveJob::Base.queue_adapter = :test + + example.run + + ActiveJob::Base.queue_adapter = queue_adapter + end + + before do + Fabricate(:software_update, version: '3.5.0', type: 'major', urgent: false) + Fabricate(:software_update, version: '42.13.12', type: 'major', urgent: false) + + owner_user.settings.update('notification_emails.software_updates': 'all') + owner_user.save! + + old_devops_user.settings.update('notification_emails.software_updates': 'all') + old_devops_user.save! + + none_user.settings.update('notification_emails.software_updates': 'none') + none_user.save! + + patch_user.settings.update('notification_emails.software_updates': 'patch') + patch_user.save! + + critical_user.settings.update('notification_emails.software_updates': 'critical') + critical_user.save! + end + + context 'when the update server errors out' do + before do + stub_request(:get, full_update_check_url).to_return(status: 404) + end + + it 'deletes outdated update records but keeps valid update records' do + expect { subject.call }.to change { SoftwareUpdate.pluck(:version).sort }.from(['3.5.0', '42.13.12']).to(['42.13.12']) + end + end + + context 'when the server returns new versions' do + let(:server_json) do + { + updatesAvailable: [ + { + version: '4.2.1', + urgent: false, + type: 'patch', + releaseNotes: 'https://github.com/mastodon/mastodon/releases/v4.2.1', + }, + { + version: '4.3.0', + urgent: false, + type: 'minor', + releaseNotes: 'https://github.com/mastodon/mastodon/releases/v4.3.0', + }, + { + version: '5.0.0', + urgent: false, + type: 'minor', + releaseNotes: 'https://github.com/mastodon/mastodon/releases/v5.0.0', + }, + ], + } + end + + before do + stub_request(:get, full_update_check_url).to_return(body: Oj.dump(server_json)) + end + + it 'updates the list of known updates' do + expect { subject.call }.to change { SoftwareUpdate.pluck(:version).sort }.from(['3.5.0', '42.13.12']).to(['4.2.1', '4.3.0', '5.0.0']) + end + + context 'when no update is urgent' do + it 'sends e-mail notifications according to settings', :aggregate_failures do + expect { subject.call }.to have_enqueued_mail(AdminMailer, :new_software_updates) + .with(hash_including(params: { recipient: owner_user.account })).once + .and(have_enqueued_mail(AdminMailer, :new_software_updates).with(hash_including(params: { recipient: patch_user.account })).once) + .and(have_enqueued_mail.at_most(2)) + end + end + + context 'when an update is urgent' do + let(:server_json) do + { + updatesAvailable: [ + { + version: '5.0.0', + urgent: true, + type: 'minor', + releaseNotes: 'https://github.com/mastodon/mastodon/releases/v5.0.0', + }, + ], + } + end + + it 'sends e-mail notifications according to settings', :aggregate_failures do + expect { subject.call }.to have_enqueued_mail(AdminMailer, :new_critical_software_updates) + .with(hash_including(params: { recipient: owner_user.account })).once + .and(have_enqueued_mail(AdminMailer, :new_critical_software_updates).with(hash_including(params: { recipient: patch_user.account })).once) + .and(have_enqueued_mail(AdminMailer, :new_critical_software_updates).with(hash_including(params: { recipient: critical_user.account })).once) + .and(have_enqueued_mail.at_most(3)) + end + end + end + end + + context 'when update checking is disabled' do + around do |example| + ClimateControl.modify UPDATE_CHECK_URL: '' do + example.run + end + end + + before do + Fabricate(:software_update, version: '3.5.0', type: 'major', urgent: false) + end + + it 'deletes outdated update records' do + expect { subject.call }.to change(SoftwareUpdate, :count).from(1).to(0) + end + end + + context 'when using the default update checking API' do + let(:update_check_url) { 'https://api.joinmastodon.org/update-check' } + + it_behaves_like 'when the feature is enabled' + end + + context 'when using a custom update check URL' do + let(:update_check_url) { 'https://api.example.com/update_check' } + + around do |example| + ClimateControl.modify UPDATE_CHECK_URL: 'https://api.example.com/update_check' do + example.run + end + end + + it_behaves_like 'when the feature is enabled' + end +end diff --git a/spec/services/suspend_account_service_spec.rb b/spec/services/suspend_account_service_spec.rb index 126b13986b..edb7050083 100644 --- a/spec/services/suspend_account_service_spec.rb +++ b/spec/services/suspend_account_service_spec.rb @@ -1,15 +1,16 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe SuspendAccountService, type: :service do shared_examples 'common behavior' do + subject { described_class.new.call(account) } + let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account } let!(:list) { Fabricate(:list, account: local_follower) } - subject { described_class.new.call(account) } - before do - allow(FeedManager.instance).to receive(:unmerge_from_home).and_return(nil) - allow(FeedManager.instance).to receive(:unmerge_from_list).and_return(nil) + allow(FeedManager.instance).to receive_messages(unmerge_from_home: nil, unmerge_from_list: nil) local_follower.follow!(account) list.accounts << account @@ -24,7 +25,7 @@ RSpec.describe SuspendAccountService, type: :service do end it 'does not change the “suspended” flag' do - expect { subject }.to_not change { account.suspended? } + expect { subject }.to_not change(account, :suspended?) end end @@ -42,8 +43,8 @@ RSpec.describe SuspendAccountService, type: :service do include_examples 'common behavior' do let!(:account) { Fabricate(:account) } - let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } - let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub, domain: 'alice.com') } + let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') } let!(:report) { Fabricate(:report, account: remote_reporter, target_account: account) } before do diff --git a/spec/services/translate_status_service_spec.rb b/spec/services/translate_status_service_spec.rb new file mode 100644 index 0000000000..5f6418f5d6 --- /dev/null +++ b/spec/services/translate_status_service_spec.rb @@ -0,0 +1,234 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe TranslateStatusService, type: :service do + subject(:service) { described_class.new } + + let(:status) { Fabricate(:status, text: text, spoiler_text: spoiler_text, language: 'en', preloadable_poll: poll, media_attachments: media_attachments) } + let(:text) { 'Hello' } + let(:spoiler_text) { '' } + let(:poll) { nil } + let(:media_attachments) { [] } + + before do + Fabricate(:custom_emoji, shortcode: 'highfive') + end + + describe '#call' do + before do + translation_service = TranslationService.new + allow(translation_service).to receive(:languages).and_return({ 'en' => ['es'] }) + allow(translation_service).to receive(:translate) do |texts| + texts.map do |text| + TranslationService::Translation.new( + text: text.gsub('Hello', 'Hola').gsub('higfive', 'cincoaltos'), + detected_source_language: 'en', + provider: 'Dummy' + ) + end + end + + allow(TranslationService).to receive_messages(configured?: true, configured: translation_service) + end + + it 'returns translated status content' do + expect(service.call(status, 'es').content).to eq '

Hola

' + end + + it 'returns source language' do + expect(service.call(status, 'es').detected_source_language).to eq 'en' + end + + it 'returns translation provider' do + expect(service.call(status, 'es').provider).to eq 'Dummy' + end + + it 'returns original status' do + expect(service.call(status, 'es').status).to eq status + end + + describe 'status has content with custom emoji' do + let(:text) { 'Hello & :highfive:' } + + it 'does not translate shortcode' do + expect(service.call(status, 'es').content).to eq '

Hola & :highfive:

' + end + end + + describe 'status has no spoiler_text' do + it 'returns an empty string' do + expect(service.call(status, 'es').spoiler_text).to eq '' + end + end + + describe 'status has spoiler_text' do + let(:spoiler_text) { 'Hello & Hello!' } + + it 'translates the spoiler text' do + expect(service.call(status, 'es').spoiler_text).to eq 'Hola & Hola!' + end + end + + describe 'status has spoiler_text with custom emoji' do + let(:spoiler_text) { 'Hello :highfive:' } + + it 'does not translate shortcode' do + expect(service.call(status, 'es').spoiler_text).to eq 'Hola :highfive:' + end + end + + describe 'status has spoiler_text with unmatched custom emoji' do + let(:spoiler_text) { 'Hello :Hello:' } + + it 'translates the invalid shortcode' do + expect(service.call(status, 'es').spoiler_text).to eq 'Hola :Hola:' + end + end + + describe 'status has poll' do + let(:poll) { Fabricate(:poll, options: ['Hello 1', 'Hello 2']) } + + it 'translates the poll option title' do + status_translation = service.call(status, 'es') + expect(status_translation.poll_options.size).to eq 2 + expect(status_translation.poll_options.first.title).to eq 'Hola 1' + end + end + + describe 'status has media attachment' do + let(:media_attachments) { [Fabricate(:media_attachment, description: 'Hello & :highfive:')] } + + it 'translates the media attachment description' do + status_translation = service.call(status, 'es') + + media_attachment = status_translation.media_attachments.first + expect(media_attachment.id).to eq media_attachments.first.id + expect(media_attachment.description).to eq 'Hola & :highfive:' + end + end + end + + describe '#source_texts' do + before do + service.instance_variable_set(:@status, status) + end + + describe 'status only has content' do + it 'returns formatted content' do + expect(service.send(:source_texts)).to eq({ content: '

Hello

' }) + end + end + + describe 'status content contains custom emoji' do + let(:status) { Fabricate(:status, text: 'Hello :highfive:') } + + it 'returns formatted content' do + source_texts = service.send(:source_texts) + expect(source_texts[:content]).to eq '

Hello :highfive:

' + end + end + + describe 'status content contains tags' do + let(:status) { Fabricate(:status, text: 'Hello #hola') } + + it 'returns formatted content' do + source_texts = service.send(:source_texts) + expect(source_texts[:content]).to include '

Hello :highfive:' + end + end + + describe 'status has poll' do + let(:poll) { Fabricate(:poll, options: %w(Blue Green)) } + + context 'with source texts from the service' do + let!(:source_texts) { service.send(:source_texts) } + + it 'returns formatted poll options' do + expect(source_texts.size).to eq 3 + expect(source_texts.values).to eq %w(

Hello

Blue Green) + end + + it 'has a first key with content' do + expect(source_texts.keys.first).to eq :content + end + + it 'has the first option in the second key with correct options' do + option1 = source_texts.keys.second + expect(option1).to be_a Poll::Option + expect(option1.id).to eq '0' + expect(option1.title).to eq 'Blue' + end + + it 'has the second option in the third key with correct options' do + option2 = source_texts.keys.third + expect(option2).to be_a Poll::Option + expect(option2.id).to eq '1' + expect(option2.title).to eq 'Green' + end + end + end + + describe 'status has poll with custom emoji' do + let(:poll) { Fabricate(:poll, options: ['Blue', 'Green :highfive:']) } + + it 'returns formatted poll options' do + html = service.send(:source_texts).values.last + expect(html).to eq 'Green :highfive:' + end + end + + describe 'status has media attachments' do + let(:text) { '' } + let(:media_attachments) { [Fabricate(:media_attachment, description: 'Hello :highfive:')] } + + it 'returns media attachments without custom emoji rendering' do + source_texts = service.send(:source_texts) + expect(source_texts.size).to eq 1 + + key, text = source_texts.first + expect(key).to eq media_attachments.first + expect(text).to eq 'Hello :highfive:' + end + end + end + + describe '#wrap_emoji_shortcodes' do + before do + service.instance_variable_set(:@status, status) + end + + describe 'string contains custom emoji' do + let(:text) { ':highfive:' } + + it 'renders the emoji' do + html = service.send(:wrap_emoji_shortcodes, 'Hello :highfive:'.html_safe) + expect(html).to eq 'Hello :highfive:' + end + end + end + + describe '#unwrap_emoji_shortcodes' do + describe 'string contains custom emoji' do + it 'inserts the shortcode' do + fragment = service.send(:unwrap_emoji_shortcodes, '

Hello :highfive:!

') + expect(fragment.to_html).to eq '

Hello :highfive:!

' + end + + it 'preserves other attributes than translate=no' do + fragment = service.send(:unwrap_emoji_shortcodes, '

Hello :highfive:!

') + expect(fragment.to_html).to eq '

Hello :highfive:!

' + end + end + end +end diff --git a/spec/services/unallow_domain_service_spec.rb b/spec/services/unallow_domain_service_spec.rb index b93945b9a2..19d40e7e86 100644 --- a/spec/services/unallow_domain_service_spec.rb +++ b/spec/services/unallow_domain_service_spec.rb @@ -1,18 +1,20 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe UnallowDomainService, type: :service do + subject { described_class.new } + let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') } - let!(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') } - let!(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') } - let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) } + let!(:bad_status_harassment) { Fabricate(:status, account: bad_account, text: 'You suck') } + let!(:bad_status_mean) { Fabricate(:status, account: bad_account, text: 'Hahaha') } + let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status_mean, file: attachment_fixture('attachment.jpg')) } let!(:already_banned_account) { Fabricate(:account, username: 'badguy', domain: 'evil.org', suspended: true, silenced: true) } let!(:domain_allow) { Fabricate(:domain_allow, domain: 'evil.org') } - subject { UnallowDomainService.new } - - context 'in limited federation mode' do + context 'with limited federation mode' do before do - allow(subject).to receive(:whitelist_mode?).and_return(true) + allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(true) end describe '#call' do @@ -29,8 +31,8 @@ RSpec.describe UnallowDomainService, type: :service do end it 'removes the remote accounts\'s statuses and media attachments' do - expect { bad_status1.reload }.to raise_exception ActiveRecord::RecordNotFound - expect { bad_status2.reload }.to raise_exception ActiveRecord::RecordNotFound + expect { bad_status_harassment.reload }.to raise_exception ActiveRecord::RecordNotFound + expect { bad_status_mean.reload }.to raise_exception ActiveRecord::RecordNotFound expect { bad_attachment.reload }.to raise_exception ActiveRecord::RecordNotFound end end @@ -38,7 +40,7 @@ RSpec.describe UnallowDomainService, type: :service do context 'without limited federation mode' do before do - allow(subject).to receive(:whitelist_mode?).and_return(false) + allow(Rails.configuration.x).to receive(:limited_federation_mode).and_return(false) end describe '#call' do @@ -55,8 +57,8 @@ RSpec.describe UnallowDomainService, type: :service do end it 'removes the remote accounts\'s statuses and media attachments' do - expect { bad_status1.reload }.to_not raise_error - expect { bad_status2.reload }.to_not raise_error + expect { bad_status_harassment.reload }.to_not raise_error + expect { bad_status_mean.reload }.to_not raise_error expect { bad_attachment.reload }.to_not raise_error end end diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb index 10448b3403..86632c3938 100644 --- a/spec/services/unblock_service_spec.rb +++ b/spec/services/unblock_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe UnblockService, type: :service do - let(:sender) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { UnblockService.new } + let(:sender) { Fabricate(:account, username: 'alice') } describe 'local' do let(:bob) { Fabricate(:account) } diff --git a/spec/services/unfollow_service_spec.rb b/spec/services/unfollow_service_spec.rb index bb5bef5c91..3e65e610ba 100644 --- a/spec/services/unfollow_service_spec.rb +++ b/spec/services/unfollow_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe UnfollowService, type: :service do - let(:sender) { Fabricate(:account, username: 'alice') } + subject { described_class.new } - subject { UnfollowService.new } + let(:sender) { Fabricate(:account, username: 'alice') } describe 'local' do let(:bob) { Fabricate(:account, username: 'bob') } diff --git a/spec/services/unmute_service_spec.rb b/spec/services/unmute_service_spec.rb deleted file mode 100644 index 8463eb283f..0000000000 --- a/spec/services/unmute_service_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'rails_helper' - -RSpec.describe UnmuteService, type: :service do - subject { UnmuteService.new } -end diff --git a/spec/services/unsuspend_account_service_spec.rb b/spec/services/unsuspend_account_service_spec.rb index 987eb09e23..c555b661ec 100644 --- a/spec/services/unsuspend_account_service_spec.rb +++ b/spec/services/unsuspend_account_service_spec.rb @@ -1,15 +1,16 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe UnsuspendAccountService, type: :service do - shared_examples 'common behavior' do + shared_context 'with common context' do + subject { described_class.new.call(account) } + let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account } let!(:list) { Fabricate(:list, account: local_follower) } - subject { described_class.new.call(account) } - before do - allow(FeedManager.instance).to receive(:merge_into_home).and_return(nil) - allow(FeedManager.instance).to receive(:merge_into_list).and_return(nil) + allow(FeedManager.instance).to receive_messages(merge_into_home: nil, merge_into_list: nil) local_follower.follow!(account) list.accounts << account @@ -31,13 +32,13 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 'does not change the “suspended” flag' do - expect { subject }.to_not change { account.suspended? } + expect { subject }.to_not change(account, :suspended?) end - include_examples 'common behavior' do + include_examples 'with common context' do let!(:account) { Fabricate(:account) } - let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub) } - let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } + let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub, domain: 'alice.com') } + let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') } let!(:report) { Fabricate(:report, account: remote_reporter, target_account: account) } before do @@ -59,9 +60,9 @@ RSpec.describe UnsuspendAccountService, type: :service do end describe 'unsuspending a remote account' do - include_examples 'common behavior' do + include_examples 'with common context' do let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) } - let!(:resolve_account_service) { double } + let!(:resolve_account_service) { instance_double(ResolveAccountService) } before do allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service) @@ -84,7 +85,7 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 'does not change the “suspended” flag' do - expect { subject }.to_not change { account.suspended? } + expect { subject }.to_not change(account, :suspended?) end end @@ -108,7 +109,7 @@ RSpec.describe UnsuspendAccountService, type: :service do end it 'marks account as suspended' do - expect { subject }.to change { account.suspended? }.from(false).to(true) + expect { subject }.to change(account, :suspended?).from(false).to(true) end end diff --git a/spec/services/update_account_service_spec.rb b/spec/services/update_account_service_spec.rb index c2dc791e4d..6318cc95fb 100644 --- a/spec/services/update_account_service_spec.rb +++ b/spec/services/update_account_service_spec.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe UpdateAccountService, type: :service do - subject { UpdateAccountService.new } + subject { described_class.new } describe 'switching form locked to unlocked accounts' do let(:account) { Fabricate(:account, locked: true) } diff --git a/spec/services/update_status_service_spec.rb b/spec/services/update_status_service_spec.rb index 16e981d2be..9c53ebb2fd 100644 --- a/spec/services/update_status_service_spec.rb +++ b/spec/services/update_status_service_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe UpdateStatusService, type: :service do @@ -111,14 +113,16 @@ RSpec.describe UpdateStatusService, type: :service do context 'when poll changes' do let(:account) { Fabricate(:account) } - let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: {options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) } + let!(:status) { Fabricate(:status, text: 'Foo', account: account, poll_attributes: { options: %w(Foo Bar), account: account, multiple: false, hide_totals: false, expires_at: 7.days.from_now }) } let!(:poll) { status.poll } let!(:voter) { Fabricate(:account) } before do status.update(poll: poll) VoteService.new.call(voter, poll, [0]) - subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i }) + Sidekiq::Testing.fake! do + subject.call(status, status.account_id, text: 'Foo', poll: { options: %w(Bar Baz Foo), expires_in: 5.days.to_i }) + end end it 'updates poll' do @@ -136,6 +140,11 @@ RSpec.describe UpdateStatusService, type: :service do it 'saves edit history' do expect(status.edits.pluck(:poll_options)).to eq [%w(Foo Bar), %w(Bar Baz Foo)] end + + it 'requeues expiration notification' do + poll = status.poll.reload + expect(PollExpirationNotifyWorker).to have_enqueued_sidekiq_job(poll.id).at(poll.expires_at + 5.minutes) + end end context 'when mentions in text change' do @@ -153,7 +162,7 @@ RSpec.describe UpdateStatusService, type: :service do end it 'keeps old mentions as silent mentions' do - expect(status.mentions.pluck(:account_id)).to match_array([alice.id, bob.id]) + expect(status.mentions.pluck(:account_id)).to contain_exactly(alice.id, bob.id) end end diff --git a/spec/services/verify_link_service_spec.rb b/spec/services/verify_link_service_spec.rb index 8f65f3a846..415788cb58 100644 --- a/spec/services/verify_link_service_spec.rb +++ b/spec/services/verify_link_service_spec.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require 'rails_helper' RSpec.describe VerifyLinkService, type: :service do subject { described_class.new } - context 'given a local account' do + context 'when given a local account' do let(:account) { Fabricate(:account, username: 'alice') } let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => 'http://example.com') } @@ -127,7 +129,7 @@ RSpec.describe VerifyLinkService, type: :service do end end - context 'given a remote account' do + context 'when given a remote account' do let(:account) { Fabricate(:account, username: 'alice', domain: 'example.com', url: 'https://profile.example.com/alice') } let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => 'example.com') } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0414ba9ed6..b4c20545f5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,18 +1,19 @@ -GC.disable +# frozen_string_literal: true if ENV['DISABLE_SIMPLECOV'] != 'true' require 'simplecov' SimpleCov.start 'rails' do - add_group 'Services', 'app/services' + add_filter 'lib/linter' + add_group 'Policies', 'app/policies' add_group 'Presenters', 'app/presenters' + add_group 'Serializers', 'app/serializers' + add_group 'Services', 'app/services' add_group 'Validators', 'app/validators' end end -gc_counter = -1 - RSpec.configure do |config| - config.example_status_persistence_file_path = "tmp/rspec/examples.txt" + config.example_status_persistence_file_path = 'tmp/rspec/examples.txt' config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end @@ -33,20 +34,7 @@ RSpec.configure do |config| end config.after :suite do - gc_counter = 0 - FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"]) - end - - config.after :each do - gc_counter += 1 - - if gc_counter > 19 - GC.enable - GC.start - GC.disable - - gc_counter = 0 - end + FileUtils.rm_rf(Dir[Rails.root.join('spec', 'test_files')]) end end @@ -60,7 +48,126 @@ end def expect_push_bulk_to_match(klass, matcher) expect(Sidekiq::Client).to receive(:push_bulk).with(hash_including({ - "class" => klass, - "args" => matcher + 'class' => klass, + 'args' => matcher, })) end + +class StreamingServerManager + @running_thread = nil + + def initialize + at_exit { stop } + end + + def start(port: 4020) + return if @running_thread + + queue = Queue.new + + @queue = queue + + @running_thread = Thread.new do + Open3.popen2e( + { + 'REDIS_NAMESPACE' => ENV.fetch('REDIS_NAMESPACE'), + 'DB_NAME' => "#{ENV.fetch('DB_NAME', 'mastodon')}_test#{ENV.fetch('TEST_ENV_NUMBER', '')}", + 'RAILS_ENV' => ENV.fetch('RAILS_ENV', 'test'), + 'NODE_ENV' => ENV.fetch('STREAMING_NODE_ENV', 'development'), + 'PORT' => port.to_s, + }, + 'node index.js', # must not call yarn here, otherwise it will fail because yarn does not send signals to its child process + chdir: Rails.root.join('streaming') + ) do |_stdin, stdout_err, process_thread| + status = :starting + + # Spawn a thread to listen on streaming server output + output_thread = Thread.new do + stdout_err.each_line do |line| + Rails.logger.info "Streaming server: #{line}" + + if status == :starting && line.match('Streaming API now listening on') + status = :started + @queue.enq 'started' + end + end + end + + # And another thread to listen on commands from the main thread + loop do + msg = queue.pop + + case msg + when 'stop' + # we need to properly stop the reading thread + output_thread.kill + + # Then stop the node process + Process.kill('KILL', process_thread.pid) + + # And we stop ourselves + @running_thread.kill + end + end + end + end + + # wait for 10 seconds for the streaming server to start + Timeout.timeout(10) do + loop do + break if @queue.pop == 'started' + end + end + end + + def stop + return unless @running_thread + + @queue.enq 'stop' + + # Wait for the thread to end + @running_thread.join + end +end + +class SearchDataManager + def prepare_test_data + 4.times do |i| + username = "search_test_account_#{i}" + account = Fabricate.create(:account, username: username, indexable: i.even?, discoverable: i.even?, note: "Lover of #{i}.") + 2.times do |j| + Fabricate.create(:status, account: account, text: "#{username}'s #{j} post", visibility: j.even? ? :public : :private) + end + end + + 3.times do |i| + Fabricate.create(:tag, name: "search_test_tag_#{i}") + end + end + + def indexes + [ + AccountsIndex, + PublicStatusesIndex, + StatusesIndex, + TagsIndex, + ] + end + + def populate_indexes + indexes.each do |index_class| + index_class.purge! + index_class.import! + end + end + + def remove_indexes + indexes.each(&:delete!) + end + + def cleanup_test_data + Status.destroy_all + Account.destroy_all + Tag.destroy_all + end +end diff --git a/spec/support/examples/api.rb b/spec/support/examples/api.rb new file mode 100644 index 0000000000..d531860abf --- /dev/null +++ b/spec/support/examples/api.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +shared_examples 'forbidden for wrong scope' do |wrong_scope| + let(:scopes) { wrong_scope } + + it 'returns http forbidden' do + # Some examples have a subject which needs to be called to make a request + subject if request.nil? + + expect(response).to have_http_status(403) + end +end + +shared_examples 'forbidden for wrong role' do |wrong_role| + let(:role) { UserRole.find_by(name: wrong_role) } + + it 'returns http forbidden' do + # Some examples have a subject which needs to be called to make a request + subject if request.nil? + + expect(response).to have_http_status(403) + end +end diff --git a/spec/support/examples/lib/admin/checks.rb b/spec/support/examples/lib/admin/checks.rb new file mode 100644 index 0000000000..b50faa77ba --- /dev/null +++ b/spec/support/examples/lib/admin/checks.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +shared_examples 'a check available to devops users' do + describe 'skip?' do + context 'when user can view devops' do + before { allow(user).to receive(:can?).with(:view_devops).and_return(true) } + + it 'returns false' do + expect(check.skip?).to be false + end + end + + context 'when user cannot view devops' do + before { allow(user).to receive(:can?).with(:view_devops).and_return(false) } + + it 'returns true' do + expect(check.skip?).to be true + end + end + end +end diff --git a/spec/support/examples/lib/settings/scoped_settings.rb b/spec/support/examples/lib/settings/scoped_settings.rb deleted file mode 100644 index 2457dcfbf2..0000000000 --- a/spec/support/examples/lib/settings/scoped_settings.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'ScopedSettings' do - describe '[]' do - it 'inherits default settings' do - expect(Setting.boost_modal).to eq false - expect(Setting.interactions['must_be_follower']).to eq false - - settings = create! - - expect(settings['boost_modal']).to eq false - expect(settings['interactions']['must_be_follower']).to eq false - end - end - - describe 'all_as_records' do - # expecting [] and []= works - - it 'returns records merged with default values except hashes' do - expect(Setting.boost_modal).to eq false - expect(Setting.delete_modal).to eq true - - settings = create! - settings['boost_modal'] = true - - records = settings.all_as_records - - expect(records['boost_modal'].value).to eq true - expect(records['delete_modal'].value).to eq true - end - end - - describe 'missing methods' do - # expecting [] and []= works. - - it 'reads settings' do - expect(Setting.boost_modal).to eq false - settings = create! - expect(settings.boost_modal).to eq false - end - - it 'updates settings' do - settings = fabricate - settings.boost_modal = true - expect(settings['boost_modal']).to eq true - end - end - - it 'can update settings with [] and can read with []=' do - settings = fabricate - - settings['boost_modal'] = true - settings['interactions'] = settings['interactions'].merge('must_be_follower' => true) - - Setting.save! - - expect(settings['boost_modal']).to eq true - expect(settings['interactions']['must_be_follower']).to eq true - - Rails.cache.clear - - expect(settings['boost_modal']).to eq true - expect(settings['interactions']['must_be_follower']).to eq true - end - - xit 'does not mutate defaults via the cache' do - fabricate['interactions']['must_be_follower'] = true - # TODO - # This mutates the global settings default such that future - # instances will inherit the incorrect starting values - - expect(fabricate.settings['interactions']['must_be_follower']).to eq false - end -end diff --git a/spec/support/examples/lib/settings/settings_extended.rb b/spec/support/examples/lib/settings/settings_extended.rb deleted file mode 100644 index 5a9d34bb04..0000000000 --- a/spec/support/examples/lib/settings/settings_extended.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -shared_examples 'Settings-extended' do - describe 'settings' do - def fabricate - super.settings - end - - def create! - super.settings - end - - it_behaves_like 'ScopedSettings' - end -end diff --git a/spec/support/examples/mailers.rb b/spec/support/examples/mailers.rb new file mode 100644 index 0000000000..213e873b4e --- /dev/null +++ b/spec/support/examples/mailers.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +shared_examples 'localized subject' do |*args, **kwrest| + it 'renders subject localized for the locale of the receiver' do + locale = :de + receiver.update!(locale: locale) + expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: locale)) + end + + it 'renders subject localized for the default locale if the locale of the receiver is unavailable' do + receiver.update!(locale: nil) + expect(mail.subject).to eq I18n.t(*args, **kwrest.merge(locale: I18n.default_locale)) + end +end diff --git a/spec/support/examples/models/concerns/account_avatar.rb b/spec/support/examples/models/concerns/account_avatar.rb index 2180f52739..16ebda5641 100644 --- a/spec/support/examples/models/concerns/account_avatar.rb +++ b/spec/support/examples/models/concerns/account_avatar.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true shared_examples 'AccountAvatar' do |fabricator| - describe 'static avatars' do + describe 'static avatars', paperclip_processing: true do describe 'when GIF' do it 'creates a png static style' do account = Fabricate(fabricator, avatar: attachment_fixture('avatar.gif')) @@ -17,7 +17,7 @@ shared_examples 'AccountAvatar' do |fabricator| end end - describe 'base64-encoded files' do + describe 'base64-encoded files', paperclip_processing: true do let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('attachment.jpg').read)}" } let(:account) { Fabricate(fabricator, avatar: base64_attachment) } diff --git a/spec/support/examples/models/concerns/account_header.rb b/spec/support/examples/models/concerns/account_header.rb index 77ee0e6290..d65f54f00f 100644 --- a/spec/support/examples/models/concerns/account_header.rb +++ b/spec/support/examples/models/concerns/account_header.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true shared_examples 'AccountHeader' do |fabricator| - describe 'base64-encoded files' do + describe 'base64-encoded files', paperclip_processing: true do let(:base64_attachment) { "data:image/jpeg;base64,#{Base64.encode64(attachment_fixture('attachment.jpg').read)}" } let(:account) { Fabricate(fabricator, header: base64_attachment) } diff --git a/spec/support/matchers/json/match_json_schema.rb b/spec/support/matchers/json/match_json_schema.rb index 5d9c9a618e..3a275199ef 100644 --- a/spec/support/matchers/json/match_json_schema.rb +++ b/spec/support/matchers/json/match_json_schema.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec::Matchers.define :match_json_schema do |schema| match do |input_json| schema_path = Rails.root.join('spec', 'support', 'schema', "#{schema}.json").to_s diff --git a/spec/support/matchers/model/model_have_error_on_field.rb b/spec/support/matchers/model/model_have_error_on_field.rb index 85bdd82159..0f9c81a475 100644 --- a/spec/support/matchers/model/model_have_error_on_field.rb +++ b/spec/support/matchers/model/model_have_error_on_field.rb @@ -1,10 +1,10 @@ +# frozen_string_literal: true + RSpec::Matchers.define :model_have_error_on_field do |expected| match do |record| - if record.errors.empty? - record.valid? - end + record.valid? if record.errors.empty? - record.errors.has_key?(expected) + record.errors.key?(expected) end failure_message do |record| diff --git a/spec/support/omniauth_mocks.rb b/spec/support/omniauth_mocks.rb new file mode 100644 index 0000000000..9883adec7a --- /dev/null +++ b/spec/support/omniauth_mocks.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +OmniAuth.config.test_mode = true + +def mock_omniauth(provider, data) + OmniAuth.config.mock_auth[provider] = OmniAuth::AuthHash.new(data) +end diff --git a/spec/support/stories/profile_stories.rb b/spec/support/stories/profile_stories.rb index 0c4a14d1c9..2b345ddef1 100644 --- a/spec/support/stories/profile_stories.rb +++ b/spec/support/stories/profile_stories.rb @@ -9,6 +9,8 @@ module ProfileStories email: email, password: password, confirmed_at: confirmed_at, account: Fabricate(:account, username: 'bob') ) + + Web::Setting.where(user: bob).first_or_initialize(user: bob).update!(data: { introductionVersion: 201812160442020 }) if finished_onboarding # rubocop:disable Style/NumericLiterals end def as_a_logged_in_user @@ -20,8 +22,8 @@ module ProfileStories end def with_alice_as_local_user - @alice_bio = '@alice and @bob are fictional characters commonly used as'\ - 'placeholder names in #cryptology, as well as #science and'\ + @alice_bio = '@alice and @bob are fictional characters commonly used as' \ + 'placeholder names in #cryptology, as well as #science and' \ 'engineering 📖 literature. Not affiliated with @pepe.' @alice = Fabricate( @@ -42,4 +44,8 @@ module ProfileStories def password @password ||= 'password' end + + def finished_onboarding + @finished_onboarding || false + end end diff --git a/spec/system/new_statuses_spec.rb b/spec/system/new_statuses_spec.rb new file mode 100644 index 0000000000..6faed6c808 --- /dev/null +++ b/spec/system/new_statuses_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'NewStatuses' do + include ProfileStories + + subject { page } + + let(:email) { 'test@example.com' } + let(:password) { 'password' } + let(:confirmed_at) { Time.zone.now } + let(:finished_onboarding) { true } + + before do + as_a_logged_in_user + visit root_path + end + + it 'can be posted' do + expect(subject).to have_css('div.app-holder') + + status_text = 'This is a new status!' + + within('.compose-form') do + fill_in "What's on your mind?", with: status_text + click_on 'Publish!' + end + + expect(subject).to have_selector('.status__content__text', text: status_text) + end + + it 'can be posted again' do + expect(subject).to have_css('div.app-holder') + + status_text = 'This is a second status!' + + within('.compose-form') do + fill_in "What's on your mind?", with: status_text + click_on 'Publish!' + end + + expect(subject).to have_selector('.status__content__text', text: status_text) + end +end diff --git a/spec/validators/blacklisted_email_validator_spec.rb b/spec/validators/blacklisted_email_validator_spec.rb index 351de07076..bfe2a11a99 100644 --- a/spec/validators/blacklisted_email_validator_spec.rb +++ b/spec/validators/blacklisted_email_validator_spec.rb @@ -4,21 +4,22 @@ require 'rails_helper' RSpec.describe BlacklistedEmailValidator, type: :validator do describe '#validate' do - let(:user) { double(email: 'info@mail.com', sign_up_ip: '1.2.3.4', errors: errors) } - let(:errors) { double(add: nil) } + subject { described_class.new.validate(user); errors } + + let(:user) { instance_double(User, email: 'info@mail.com', sign_up_ip: '1.2.3.4', errors: errors) } + let(:errors) { instance_double(ActiveModel::Errors, add: nil) } before do - allow(user).to receive(:valid_invitation?) { false } - allow_any_instance_of(described_class).to receive(:blocked_email_provider?) { blocked_email } + allow(user).to receive(:valid_invitation?).and_return(false) + allow(EmailDomainBlock).to receive(:block?) { blocked_email } end - subject { described_class.new.validate(user); errors } - context 'when e-mail provider is blocked' do let(:blocked_email) { true } it 'adds error' do - expect(subject).to have_received(:add).with(:email, :blocked) + described_class.new.validate(user) + expect(errors).to have_received(:add).with(:email, :blocked).once end end @@ -26,7 +27,8 @@ RSpec.describe BlacklistedEmailValidator, type: :validator do let(:blocked_email) { false } it 'does not add errors' do - expect(subject).not_to have_received(:add).with(:email, :blocked) + described_class.new.validate(user) + expect(errors).to_not have_received(:add) end context 'when canonical e-mail is blocked' do @@ -37,7 +39,8 @@ RSpec.describe BlacklistedEmailValidator, type: :validator do end it 'adds error' do - expect(subject).to have_received(:add).with(:email, :taken) + described_class.new.validate(user) + expect(errors).to have_received(:add).with(:email, :taken).once end end end diff --git a/spec/validators/disallowed_hashtags_validator_spec.rb b/spec/validators/disallowed_hashtags_validator_spec.rb index 9deec0bb90..7144d28918 100644 --- a/spec/validators/disallowed_hashtags_validator_spec.rb +++ b/spec/validators/disallowed_hashtags_validator_spec.rb @@ -11,19 +11,19 @@ RSpec.describe DisallowedHashtagsValidator, type: :validator do described_class.new.validate(status) end - let(:status) { double(errors: errors, local?: local, reblog?: reblog, text: disallowed_tags.map { |x| '#' + x }.join(' ')) } - let(:errors) { double(add: nil) } + let(:status) { instance_double(Status, errors: errors, local?: local, reblog?: reblog, text: disallowed_tags.map { |x| "##{x}" }.join(' ')) } + let(:errors) { instance_double(ActiveModel::Errors, add: nil) } - context 'for a remote reblog' do + context 'with a remote reblog' do let(:local) { false } let(:reblog) { true } it 'does not add errors' do - expect(errors).not_to have_received(:add).with(:text, any_args) + expect(errors).to_not have_received(:add).with(:text, any_args) end end - context 'for a local original status' do + context 'with a local original status' do let(:local) { true } let(:reblog) { false } @@ -31,7 +31,7 @@ RSpec.describe DisallowedHashtagsValidator, type: :validator do let(:disallowed_tags) { [] } it 'does not add errors' do - expect(errors).not_to have_received(:add).with(:text, any_args) + expect(errors).to_not have_received(:add).with(:text, any_args) end end diff --git a/spec/validators/email_mx_validator_spec.rb b/spec/validators/email_mx_validator_spec.rb index 6640d6058e..876d73c184 100644 --- a/spec/validators/email_mx_validator_spec.rb +++ b/spec/validators/email_mx_validator_spec.rb @@ -4,9 +4,9 @@ require 'rails_helper' describe EmailMxValidator do describe '#validate' do - let(:user) { double(email: 'foo@example.com', sign_up_ip: '1.2.3.4', errors: double(add: nil)) } + let(:user) { instance_double(User, email: 'foo@example.com', sign_up_ip: '1.2.3.4', errors: instance_double(ActiveModel::Errors, add: nil)) } - context 'for an e-mail domain that is explicitly allowed' do + context 'with an e-mail domain that is explicitly allowed' do around do |block| tmp = Rails.configuration.x.email_domains_whitelist Rails.configuration.x.email_domains_whitelist = 'example.com' @@ -15,7 +15,7 @@ describe EmailMxValidator do end it 'does not add errors if there are no DNS records' do - resolver = double + resolver = instance_double(Resolv::DNS) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) @@ -29,7 +29,7 @@ describe EmailMxValidator do end it 'adds no error if there are DNS records for the e-mail domain' do - resolver = double + resolver = instance_double(Resolv::DNS) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([Resolv::DNS::Resource::IN::A.new('192.0.2.42')]) @@ -38,11 +38,27 @@ describe EmailMxValidator do allow(Resolv::DNS).to receive(:open).and_yield(resolver) subject.validate(user) - expect(user.errors).not_to have_received(:add) + expect(user.errors).to_not have_received(:add) + end + + it 'adds an error if the TagManager fails to normalize domain' do + double = instance_double(TagManager) + allow(TagManager).to receive(:instance).and_return(double) + allow(double).to receive(:normalize_domain).with('example.com').and_raise(Addressable::URI::InvalidURIError) + + user = instance_double(User, email: 'foo@example.com', errors: instance_double(ActiveModel::Errors, add: nil)) + subject.validate(user) + expect(user.errors).to have_received(:add) + end + + it 'adds an error if the domain email portion is blank' do + user = instance_double(User, email: 'foo@', errors: instance_double(ActiveModel::Errors, add: nil)) + subject.validate(user) + expect(user.errors).to have_received(:add) end it 'adds an error if the email domain name contains empty labels' do - resolver = double + resolver = instance_double(Resolv::DNS) allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::MX).and_return([]) allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::A).and_return([Resolv::DNS::Resource::IN::A.new('192.0.2.42')]) @@ -50,13 +66,13 @@ describe EmailMxValidator do allow(resolver).to receive(:timeouts=).and_return(nil) allow(Resolv::DNS).to receive(:open).and_yield(resolver) - user = double(email: 'foo@example..com', sign_up_ip: '1.2.3.4', errors: double(add: nil)) + user = instance_double(User, email: 'foo@example..com', sign_up_ip: '1.2.3.4', errors: instance_double(ActiveModel::Errors, add: nil)) subject.validate(user) expect(user.errors).to have_received(:add) end it 'adds an error if there are no DNS records for the e-mail domain' do - resolver = double + resolver = instance_double(Resolv::DNS) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) @@ -69,9 +85,11 @@ describe EmailMxValidator do end it 'adds an error if a MX record does not lead to an IP' do - resolver = double + resolver = instance_double(Resolv::DNS) - allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')]) + allow(resolver).to receive(:getresources) + .with('example.com', Resolv::DNS::Resource::IN::MX) + .and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([]) allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([]) @@ -85,13 +103,15 @@ describe EmailMxValidator do it 'adds an error if the MX record is blacklisted' do EmailDomainBlock.create!(domain: 'mail.example.com') - resolver = double + resolver = instance_double(Resolv::DNS) - allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([double(exchange: 'mail.example.com')]) + allow(resolver).to receive(:getresources) + .with('example.com', Resolv::DNS::Resource::IN::MX) + .and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([]) - allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([double(address: '2.3.4.5')]) - allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([double(address: 'fd00::2')]) + allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5')]) + allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: 'fd00::2')]) allow(resolver).to receive(:timeouts=).and_return(nil) allow(Resolv::DNS).to receive(:open).and_yield(resolver) diff --git a/spec/validators/follow_limit_validator_spec.rb b/spec/validators/follow_limit_validator_spec.rb index cc8fbb6313..86b6511d65 100644 --- a/spec/validators/follow_limit_validator_spec.rb +++ b/spec/validators/follow_limit_validator_spec.rb @@ -12,25 +12,25 @@ RSpec.describe FollowLimitValidator, type: :validator do described_class.new.validate(follow) end - let(:follow) { double(account: account, errors: errors) } - let(:errors) { double(add: nil) } - let(:account) { double(nil?: _nil, local?: local, following_count: 0, followers_count: 0) } + let(:follow) { instance_double(Follow, account: account, errors: errors) } + let(:errors) { instance_double(ActiveModel::Errors, add: nil) } + let(:account) { instance_double(Account, nil?: _nil, local?: local, following_count: 0, followers_count: 0) } let(:_nil) { true } let(:local) { false } - context 'follow.account.nil? || !follow.account.local?' do + context 'with follow.account.nil? || !follow.account.local?' do let(:_nil) { true } it 'not calls errors.add' do - expect(errors).not_to have_received(:add).with(:base, any_args) + expect(errors).to_not have_received(:add).with(:base, any_args) end end - context '!(follow.account.nil? || !follow.account.local?)' do + context 'with !(follow.account.nil? || !follow.account.local?)' do let(:_nil) { false } let(:local) { true } - context 'limit_reached?' do + context 'when limit_reached?' do let(:limit_reached) { true } it 'calls errors.add' do @@ -39,11 +39,11 @@ RSpec.describe FollowLimitValidator, type: :validator do end end - context '!limit_reached?' do + context 'with !limit_reached?' do let(:limit_reached) { false } it 'not calls errors.add' do - expect(errors).not_to have_received(:add).with(:base, any_args) + expect(errors).to_not have_received(:add).with(:base, any_args) end end end diff --git a/spec/validators/language_validator_spec.rb b/spec/validators/language_validator_spec.rb new file mode 100644 index 0000000000..cb693dcd81 --- /dev/null +++ b/spec/validators/language_validator_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe LanguageValidator do + let(:record_class) do + Class.new do + include ActiveModel::Validations + attr_accessor :locale + + validates :locale, language: true + end + end + let(:record) { record_class.new } + + describe '#validate_each' do + context 'with a nil value' do + it 'does not add errors' do + record.locale = nil + + expect(record).to be_valid + expect(record.errors).to be_empty + end + end + + context 'with an array of values' do + it 'does not add errors with array of existing locales' do + record.locale = %w(en fr) + + expect(record).to be_valid + expect(record.errors).to be_empty + end + + it 'adds errors with array having some non-existing locales' do + record.locale = %w(en fr missing) + + expect(record).to_not be_valid + expect(record.errors.first.attribute).to eq(:locale) + expect(record.errors.first.type).to eq(:invalid) + end + end + + context 'with a locale string' do + it 'does not add errors when string is an existing locale' do + record.locale = 'en' + + expect(record).to be_valid + expect(record.errors).to be_empty + end + + it 'adds errors when string is non-existing locale' do + record.locale = 'missing' + + expect(record).to_not be_valid + expect(record.errors.first.attribute).to eq(:locale) + expect(record.errors.first.type).to eq(:invalid) + end + end + end +end diff --git a/spec/validators/note_length_validator_spec.rb b/spec/validators/note_length_validator_spec.rb index 6e9b4e132f..66fccad3ec 100644 --- a/spec/validators/note_length_validator_spec.rb +++ b/spec/validators/note_length_validator_spec.rb @@ -3,31 +3,37 @@ require 'rails_helper' describe NoteLengthValidator do - subject { NoteLengthValidator.new(attributes: { note: true }, maximum: 500) } + subject { described_class.new(attributes: { note: true }, maximum: 500) } describe '#validate' do it 'adds an error when text is over 500 characters' do text = 'a' * 520 - account = double(note: text, errors: double(add: nil)) + account = instance_double(Account, note: text, errors: activemodel_errors) subject.validate_each(account, 'note', text) expect(account.errors).to have_received(:add) end it 'counts URLs as 23 characters flat' do - text = ('a' * 476) + " http://#{'b' * 30}.com/example" - account = double(note: text, errors: double(add: nil)) + text = ('a' * 476) + " http://#{'b' * 30}.com/example" + account = instance_double(Account, note: text, errors: activemodel_errors) subject.validate_each(account, 'note', text) expect(account.errors).to_not have_received(:add) end it 'does not count non-autolinkable URLs as 23 characters flat' do - text = ('a' * 476) + "http://#{'b' * 30}.com/example" - account = double(note: text, errors: double(add: nil)) + text = ('a' * 476) + "http://#{'b' * 30}.com/example" + account = instance_double(Account, note: text, errors: activemodel_errors) subject.validate_each(account, 'note', text) expect(account.errors).to have_received(:add) end + + private + + def activemodel_errors + instance_double(ActiveModel::Errors, add: nil) + end end end diff --git a/spec/validators/poll_validator_spec.rb b/spec/validators/poll_validator_spec.rb index 941b83401f..95feb043db 100644 --- a/spec/validators/poll_validator_spec.rb +++ b/spec/validators/poll_validator_spec.rb @@ -9,19 +9,20 @@ RSpec.describe PollValidator, type: :validator do end let(:validator) { described_class.new } - let(:poll) { double(options: options, expires_at: expires_at, errors: errors) } - let(:errors) { double(add: nil) } + let(:poll) { instance_double(Poll, options: options, expires_at: expires_at, errors: errors) } + let(:errors) { instance_double(ActiveModel::Errors, add: nil) } let(:options) { %w(foo bar) } let(:expires_at) { 1.day.from_now } it 'have no errors' do - expect(errors).not_to have_received(:add) + expect(errors).to_not have_received(:add) end - context 'expires just 5 min ago' do + context 'when expires is just 5 min ago' do let(:expires_at) { 5.minutes.from_now } + it 'not calls errors add' do - expect(errors).not_to have_received(:add) + expect(errors).to_not have_received(:add) end end end diff --git a/spec/validators/status_length_validator_spec.rb b/spec/validators/status_length_validator_spec.rb index db9c728a8b..8535ddd750 100644 --- a/spec/validators/status_length_validator_spec.rb +++ b/spec/validators/status_length_validator_spec.rb @@ -5,38 +5,43 @@ require 'rails_helper' describe StatusLengthValidator do describe '#validate' do it 'does not add errors onto remote statuses' do - status = double(local?: false) + status = instance_double(Status, local?: false) subject.validate(status) - expect(status).not_to receive(:errors) + expect(status).to_not receive(:errors) end it 'does not add errors onto local reblogs' do - status = double(local?: false, reblog?: true) + status = instance_double(Status, local?: false, reblog?: true) subject.validate(status) - expect(status).not_to receive(:errors) + expect(status).to_not receive(:errors) end - it 'adds an error when content warning is over 500 characters' do - status = double(spoiler_text: 'a' * 520, text: '', errors: double(add: nil), local?: true, reblog?: false) + it 'adds an error when content warning is over MAX_CHARS characters' do + chars = StatusLengthValidator::MAX_CHARS + 1 + status = instance_double(Status, spoiler_text: 'a' * chars, text: '', errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to have_received(:add) end - it 'adds an error when text is over 500 characters' do - status = double(spoiler_text: '', text: 'a' * 520, errors: double(add: nil), local?: true, reblog?: false) + it 'adds an error when text is over MAX_CHARS characters' do + chars = StatusLengthValidator::MAX_CHARS + 1 + status = instance_double(Status, spoiler_text: '', text: 'a' * chars, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to have_received(:add) end - it 'adds an error when text and content warning are over 500 characters total' do - status = double(spoiler_text: 'a' * 250, text: 'b' * 251, errors: double(add: nil), local?: true, reblog?: false) + it 'adds an error when text and content warning are over MAX_CHARS characters total' do + chars1 = 20 + chars2 = StatusLengthValidator::MAX_CHARS + 1 - chars1 + status = instance_double(Status, spoiler_text: 'a' * chars1, text: 'b' * chars2, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to have_received(:add) end it 'counts URLs as 23 characters flat' do - text = ('a' * 476) + " http://#{'b' * 30}.com/example" - status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false) + chars = StatusLengthValidator::MAX_CHARS - 1 - 23 + text = ('a' * chars) + " http://#{'b' * 30}.com/example" + status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to_not have_received(:add) @@ -44,7 +49,7 @@ describe StatusLengthValidator do it 'does not count non-autolinkable URLs as 23 characters flat' do text = ('a' * 476) + "http://#{'b' * 30}.com/example" - status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false) + status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to have_received(:add) @@ -52,14 +57,16 @@ describe StatusLengthValidator do it 'does not count overly long URLs as 23 characters flat' do text = "http://example.com/valid?#{'#foo?' * 1000}" - status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false) + status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to have_received(:add) end it 'counts only the front part of remote usernames' do - text = ('a' * 475) + " @alice@#{'b' * 30}.com" - status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false) + username = '@alice' + chars = StatusLengthValidator::MAX_CHARS - 1 - username.length + text = ('a' * chars) + " #{username}@#{'b' * 30}.com" + status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to_not have_received(:add) @@ -67,10 +74,16 @@ describe StatusLengthValidator do it 'does count both parts of remote usernames for overly long domains' do text = "@alice@#{'b' * 500}.com" - status = double(spoiler_text: '', text: text, errors: double(add: nil), local?: true, reblog?: false) + status = instance_double(Status, spoiler_text: '', text: text, errors: activemodel_errors, local?: true, reblog?: false) subject.validate(status) expect(status.errors).to have_received(:add) end end + + private + + def activemodel_errors + instance_double(ActiveModel::Errors, add: nil) + end end diff --git a/spec/validators/status_pin_validator_spec.rb b/spec/validators/status_pin_validator_spec.rb index d5bd0d1b83..e8f8a45434 100644 --- a/spec/validators/status_pin_validator_spec.rb +++ b/spec/validators/status_pin_validator_spec.rb @@ -8,11 +8,11 @@ RSpec.describe StatusPinValidator, type: :validator do subject.validate(pin) end - let(:pin) { double(account: account, errors: errors, status: status, account_id: pin_account_id) } - let(:status) { double(reblog?: reblog, account_id: status_account_id, visibility: visibility, direct_visibility?: visibility == 'direct') } - let(:account) { double(status_pins: status_pins, local?: local) } - let(:status_pins) { double(count: count) } - let(:errors) { double(add: nil) } + let(:pin) { instance_double(StatusPin, account: account, errors: errors, status: status, account_id: pin_account_id) } + let(:status) { instance_double(Status, reblog?: reblog, account_id: status_account_id, visibility: visibility, direct_visibility?: visibility == 'direct') } + let(:account) { instance_double(Account, status_pins: status_pins, local?: local) } + let(:status_pins) { instance_double(Array, count: count) } + let(:errors) { instance_double(ActiveModel::Errors, add: nil) } let(:pin_account_id) { 1 } let(:status_account_id) { 1 } let(:visibility) { 'public' } @@ -20,7 +20,7 @@ RSpec.describe StatusPinValidator, type: :validator do let(:reblog) { false } let(:count) { 0 } - context 'pin.status.reblog?' do + context 'when pin.status.reblog?' do let(:reblog) { true } it 'calls errors.add' do @@ -28,7 +28,7 @@ RSpec.describe StatusPinValidator, type: :validator do end end - context 'pin.account_id != pin.status.account_id' do + context 'when pin.account_id != pin.status.account_id' do let(:pin_account_id) { 1 } let(:status_account_id) { 2 } @@ -37,7 +37,7 @@ RSpec.describe StatusPinValidator, type: :validator do end end - context 'if pin.status.direct_visibility?' do + context 'when pin.status.direct_visibility?' do let(:visibility) { 'direct' } it 'calls errors.add' do @@ -45,7 +45,7 @@ RSpec.describe StatusPinValidator, type: :validator do end end - context 'pin.account.status_pins.count > 4 && pin.account.local?' do + context 'when pin.account.status_pins.count > 4 && pin.account.local?' do let(:count) { 5 } let(:local) { true } diff --git a/spec/validators/unique_username_validator_spec.rb b/spec/validators/unique_username_validator_spec.rb index 6867cbc6ce..0d172c8408 100644 --- a/spec/validators/unique_username_validator_spec.rb +++ b/spec/validators/unique_username_validator_spec.rb @@ -6,7 +6,7 @@ describe UniqueUsernameValidator do describe '#validate' do context 'when local account' do it 'does not add errors if username is nil' do - account = double(username: nil, domain: nil, persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: nil, domain: nil, persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to_not have_received(:add) end @@ -18,14 +18,14 @@ describe UniqueUsernameValidator do it 'adds an error when the username is already used with ignoring cases' do Fabricate(:account, username: 'ABCdef') - account = double(username: 'abcDEF', domain: nil, persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: 'abcDEF', domain: nil, persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to have_received(:add) end it 'does not add errors when same username remote account exists' do Fabricate(:account, username: 'abcdef', domain: 'example.com') - account = double(username: 'abcdef', domain: nil, persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: 'abcdef', domain: nil, persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to_not have_received(:add) end @@ -34,7 +34,7 @@ describe UniqueUsernameValidator do context 'when remote account' do it 'does not add errors if username is nil' do - account = double(username: nil, domain: 'example.com', persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: nil, domain: 'example.com', persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to_not have_received(:add) end @@ -46,23 +46,29 @@ describe UniqueUsernameValidator do it 'adds an error when the username is already used with ignoring cases' do Fabricate(:account, username: 'ABCdef', domain: 'example.com') - account = double(username: 'abcDEF', domain: 'example.com', persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: 'abcDEF', domain: 'example.com', persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to have_received(:add) end it 'adds an error when the domain is already used with ignoring cases' do Fabricate(:account, username: 'ABCdef', domain: 'example.com') - account = double(username: 'ABCdef', domain: 'EXAMPLE.COM', persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: 'ABCdef', domain: 'EXAMPLE.COM', persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to have_received(:add) end it 'does not add errors when account with the same username and another domain exists' do Fabricate(:account, username: 'abcdef', domain: 'example.com') - account = double(username: 'abcdef', domain: 'example2.com', persisted?: false, errors: double(add: nil)) + account = instance_double(Account, username: 'abcdef', domain: 'example2.com', persisted?: false, errors: activemodel_errors) subject.validate(account) expect(account.errors).to_not have_received(:add) end end + + private + + def activemodel_errors + instance_double(ActiveModel::Errors, add: nil) + end end diff --git a/spec/validators/unreserved_username_validator_spec.rb b/spec/validators/unreserved_username_validator_spec.rb index 746b3866c8..6f353eeafd 100644 --- a/spec/validators/unreserved_username_validator_spec.rb +++ b/spec/validators/unreserved_username_validator_spec.rb @@ -10,21 +10,21 @@ RSpec.describe UnreservedUsernameValidator, type: :validator do end let(:validator) { described_class.new } - let(:account) { double(username: username, errors: errors) } - let(:errors ) { double(add: nil) } + let(:account) { instance_double(Account, username: username, errors: errors) } + let(:errors) { instance_double(ActiveModel::Errors, add: nil) } - context '@username.blank?' do - let(:username) { nil } + context 'when @username is blank?' do + let(:username) { nil } it 'not calls errors.add' do - expect(errors).not_to have_received(:add).with(:username, any_args) + expect(errors).to_not have_received(:add).with(:username, any_args) end end - context '!@username.blank?' do - let(:username) { 'f' } + context 'when @username is not blank?' do + let(:username) { 'f' } - context 'reserved_username?' do + context 'with reserved_username?' do let(:reserved_username) { true } it 'calls errors.add' do @@ -32,11 +32,11 @@ RSpec.describe UnreservedUsernameValidator, type: :validator do end end - context '!reserved_username?' do + context 'when username is not reserved' do let(:reserved_username) { false } it 'not calls errors.add' do - expect(errors).not_to have_received(:add).with(:username, any_args) + expect(errors).to_not have_received(:add).with(:username, any_args) end end end diff --git a/spec/validators/url_validator_spec.rb b/spec/validators/url_validator_spec.rb index 85eadeb63a..4f32b7b399 100644 --- a/spec/validators/url_validator_spec.rb +++ b/spec/validators/url_validator_spec.rb @@ -2,32 +2,64 @@ require 'rails_helper' -RSpec.describe URLValidator, type: :validator do - describe '#validate_each' do - before do - allow(validator).to receive(:compliant?).with(value) { compliant } - validator.validate_each(record, attribute, value) +describe URLValidator do + let(:record_class) do + Class.new do + include ActiveModel::Validations + attr_accessor :profile + + validates :profile, url: true end + end + let(:record) { record_class.new } - let(:validator) { described_class.new(attributes: [attribute]) } - let(:record) { double(errors: errors) } - let(:errors) { double(add: nil) } - let(:value) { '' } - let(:attribute) { :foo } + describe '#validate_each' do + context 'with a nil value' do + it 'adds errors' do + record.profile = nil - context 'unless compliant?' do - let(:compliant) { false } - - it 'calls errors.add' do - expect(errors).to have_received(:add).with(attribute, :invalid) + expect(record).to_not be_valid + expect(record.errors.first.attribute).to eq(:profile) + expect(record.errors.first.type).to eq(:invalid) end end - context 'if compliant?' do - let(:compliant) { true } + context 'with an invalid url scheme' do + it 'adds errors' do + record.profile = 'ftp://example.com/page' - it 'not calls errors.add' do - expect(errors).not_to have_received(:add).with(attribute, any_args) + expect(record).to_not be_valid + expect(record.errors.first.attribute).to eq(:profile) + expect(record.errors.first.type).to eq(:invalid) + end + end + + context 'without a hostname' do + it 'adds errors' do + record.profile = 'https:///page' + + expect(record).to_not be_valid + expect(record.errors.first.attribute).to eq(:profile) + expect(record.errors.first.type).to eq(:invalid) + end + end + + context 'with an unparseable value' do + it 'adds errors' do + record.profile = 'https://host:port/page' # non-numeric port string causes invalid uri error + + expect(record).to_not be_valid + expect(record.errors.first.attribute).to eq(:profile) + expect(record.errors.first.type).to eq(:invalid) + end + end + + context 'with a valid url' do + it 'does not add errors' do + record.profile = 'https://example.com/page' + + expect(record).to be_valid + expect(record.errors).to be_empty end end end diff --git a/spec/views/statuses/show.html.haml_spec.rb b/spec/views/statuses/show.html.haml_spec.rb index ca5bb2ae87..354f9d3e63 100644 --- a/spec/views/statuses/show.html.haml_spec.rb +++ b/spec/views/statuses/show.html.haml_spec.rb @@ -4,15 +4,9 @@ require 'rails_helper' describe 'statuses/show.html.haml', without_verify_partial_doubles: true do before do - double(api_oembed_url: '') - allow(view).to receive(:show_landing_strip?).and_return(true) - allow(view).to receive(:site_title).and_return('example site') - allow(view).to receive(:site_hostname).and_return('example.com') - allow(view).to receive(:full_asset_url).and_return('//asset.host/image.svg') + allow(view).to receive_messages(api_oembed_url: '', show_landing_strip?: true, site_title: 'example site', site_hostname: 'example.com', full_asset_url: '//asset.host/image.svg', current_account: nil, single_user_mode?: false) allow(view).to receive(:local_time) allow(view).to receive(:local_time_ago) - allow(view).to receive(:current_account).and_return(nil) - allow(view).to receive(:single_user_mode?).and_return(false) assign(:instance_presenter, InstancePresenter.new) end @@ -29,10 +23,10 @@ describe 'statuses/show.html.haml', without_verify_partial_doubles: true do header_tags = view.content_for(:header_tags) - expect(header_tags).to match(%r{}) - expect(header_tags).to match(%r{}) - expect(header_tags).to match(%r{}) - expect(header_tags).to match(%r{}) + expect(header_tags).to match(//) + expect(header_tags).to match(//) + expect(header_tags).to match(//) + expect(header_tags).to match(%r{}) end it 'has twitter player tag' do @@ -48,7 +42,7 @@ describe 'statuses/show.html.haml', without_verify_partial_doubles: true do header_tags = view.content_for(:header_tags) - expect(header_tags).to match(%r{}) - expect(header_tags).to match(%r{}) + expect(header_tags).to match(%r{}) + expect(header_tags).to match(//) end end diff --git a/spec/workers/activitypub/distribute_poll_update_worker_spec.rb b/spec/workers/activitypub/distribute_poll_update_worker_spec.rb index d68a695b78..0bdbf63903 100644 --- a/spec/workers/activitypub/distribute_poll_update_worker_spec.rb +++ b/spec/workers/activitypub/distribute_poll_update_worker_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' describe ActivityPub::DistributePollUpdateWorker do subject { described_class.new } let(:account) { Fabricate(:account) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } let(:poll) { Fabricate(:poll, account: account) } let!(:status) { Fabricate(:status, account: account, poll: poll) } diff --git a/spec/workers/activitypub/distribution_worker_spec.rb b/spec/workers/activitypub/distribution_worker_spec.rb index 3a5900d9b8..d8803f6b8a 100644 --- a/spec/workers/activitypub/distribution_worker_spec.rb +++ b/spec/workers/activitypub/distribution_worker_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' describe ActivityPub::DistributionWorker do subject { described_class.new } let(:status) { Fabricate(:status) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } describe '#perform' do before do @@ -34,7 +36,7 @@ describe ActivityPub::DistributionWorker do end context 'with direct status' do - let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox')} + let(:mentioned_account) { Fabricate(:account, protocol: :activitypub, inbox_url: 'https://foo.bar/inbox', domain: 'foo.bar') } before do status.update(visibility: :direct) diff --git a/spec/workers/activitypub/fetch_replies_worker_spec.rb b/spec/workers/activitypub/fetch_replies_worker_spec.rb index 91ef3c4b92..ff4d049a26 100644 --- a/spec/workers/activitypub/fetch_replies_worker_spec.rb +++ b/spec/workers/activitypub/fetch_replies_worker_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' describe ActivityPub::FetchRepliesWorker do subject { described_class.new } - let(:account) { Fabricate(:account, uri: 'https://example.com/user/1') } + let(:account) { Fabricate(:account, domain: 'example.com') } let(:status) { Fabricate(:status, account: account) } let(:payload) do diff --git a/spec/workers/activitypub/move_distribution_worker_spec.rb b/spec/workers/activitypub/move_distribution_worker_spec.rb index af8c44cc01..b8601f78cf 100644 --- a/spec/workers/activitypub/move_distribution_worker_spec.rb +++ b/spec/workers/activitypub/move_distribution_worker_spec.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require 'rails_helper' describe ActivityPub::MoveDistributionWorker do subject { described_class.new } - let(:migration) { Fabricate(:account_migration) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } - let(:blocker) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example2.com') } + let(:migration) { Fabricate(:account_migration) } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } + let(:blocker) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example2.com', domain: 'example2.com') } describe '#perform' do before do @@ -15,9 +17,9 @@ describe ActivityPub::MoveDistributionWorker do it 'delivers to followers and known blockers' do expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [ - [kind_of(String), migration.account.id, 'http://example.com'], - [kind_of(String), migration.account.id, 'http://example2.com'] - ]) + [kind_of(String), migration.account.id, 'http://example.com'], + [kind_of(String), migration.account.id, 'http://example2.com'], + ]) subject.perform(migration.id) end end diff --git a/spec/workers/activitypub/processing_worker_spec.rb b/spec/workers/activitypub/processing_worker_spec.rb index b42c0bdbc9..66d1cf4890 100644 --- a/spec/workers/activitypub/processing_worker_spec.rb +++ b/spec/workers/activitypub/processing_worker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe ActivityPub::ProcessingWorker do @@ -7,7 +9,8 @@ describe ActivityPub::ProcessingWorker do describe '#perform' do it 'delegates to ActivityPub::ProcessCollectionService' do - allow(ActivityPub::ProcessCollectionService).to receive(:new).and_return(double(:service, call: nil)) + allow(ActivityPub::ProcessCollectionService).to receive(:new) + .and_return(instance_double(ActivityPub::ProcessCollectionService, call: nil)) subject.perform(account.id, '') expect(ActivityPub::ProcessCollectionService).to have_received(:new) end diff --git a/spec/workers/activitypub/status_update_distribution_worker_spec.rb b/spec/workers/activitypub/status_update_distribution_worker_spec.rb index c014c6790e..c500bac959 100644 --- a/spec/workers/activitypub/status_update_distribution_worker_spec.rb +++ b/spec/workers/activitypub/status_update_distribution_worker_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' describe ActivityPub::StatusUpdateDistributionWorker do subject { described_class.new } let(:status) { Fabricate(:status, text: 'foo') } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } describe '#perform' do before do diff --git a/spec/workers/activitypub/update_distribution_worker_spec.rb b/spec/workers/activitypub/update_distribution_worker_spec.rb index 0e057fd0bc..d0eeda43bf 100644 --- a/spec/workers/activitypub/update_distribution_worker_spec.rb +++ b/spec/workers/activitypub/update_distribution_worker_spec.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + require 'rails_helper' describe ActivityPub::UpdateDistributionWorker do subject { described_class.new } let(:account) { Fabricate(:account) } - let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com') } + let(:follower) { Fabricate(:account, protocol: :activitypub, inbox_url: 'http://example.com', domain: 'example.com') } describe '#perform' do before do diff --git a/spec/workers/add_to_public_statuses_index_worker_spec.rb b/spec/workers/add_to_public_statuses_index_worker_spec.rb new file mode 100644 index 0000000000..fa15072241 --- /dev/null +++ b/spec/workers/add_to_public_statuses_index_worker_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe AddToPublicStatusesIndexWorker do + describe '#perform' do + let(:account) { Fabricate(:account, indexable: indexable) } + let(:account_id) { account.id } + + before do + allow(Account).to receive(:find).with(account_id).and_return(account) unless account.nil? + allow(account).to receive(:add_to_public_statuses_index!) unless account.nil? + end + + context 'when account is indexable' do + let(:indexable) { true } + + it 'adds the account to the public statuses index' do + subject.perform(account_id) + expect(account).to have_received(:add_to_public_statuses_index!) + end + end + + context 'when account is not indexable' do + let(:indexable) { false } + + it 'does not add the account to public statuses index' do + subject.perform(account_id) + expect(account).to_not have_received(:add_to_public_statuses_index!) + end + end + + context 'when account does not exist' do + let(:account) { nil } + let(:account_id) { 999 } + + it 'does not raise an error' do + expect { subject.perform(account_id) }.to_not raise_error + end + end + end +end diff --git a/spec/workers/admin/account_deletion_worker_spec.rb b/spec/workers/admin/account_deletion_worker_spec.rb new file mode 100644 index 0000000000..631cab6648 --- /dev/null +++ b/spec/workers/admin/account_deletion_worker_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::AccountDeletionWorker do + let(:worker) { described_class.new } + + describe 'perform' do + let(:account) { Fabricate(:account) } + let(:service) { instance_double(DeleteAccountService, call: true) } + + it 'calls delete account service' do + allow(DeleteAccountService).to receive(:new).and_return(service) + worker.perform(account.id) + + expect(service).to have_received(:call).with(account, { reserve_email: true, reserve_username: true }) + end + end +end diff --git a/spec/workers/admin/domain_purge_worker_spec.rb b/spec/workers/admin/domain_purge_worker_spec.rb index b67c58b234..861fd71a7f 100644 --- a/spec/workers/admin/domain_purge_worker_spec.rb +++ b/spec/workers/admin/domain_purge_worker_spec.rb @@ -7,7 +7,7 @@ describe Admin::DomainPurgeWorker do describe 'perform' do it 'calls domain purge service for relevant domain block' do - service = double(call: nil) + service = instance_double(PurgeDomainService, call: nil) allow(PurgeDomainService).to receive(:new).and_return(service) result = subject.perform('example.com') diff --git a/spec/workers/bulk_import_worker_spec.rb b/spec/workers/bulk_import_worker_spec.rb new file mode 100644 index 0000000000..91f51fbb42 --- /dev/null +++ b/spec/workers/bulk_import_worker_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe BulkImportWorker do + subject { described_class.new } + + let(:import) { Fabricate(:bulk_import, state: :scheduled) } + + describe '#perform' do + let(:service_double) { instance_double(BulkImportService, call: nil) } + + before do + allow(BulkImportService).to receive(:new).and_return(service_double) + end + + it 'changes the import\'s state as appropriate' do + expect { subject.perform(import.id) }.to change { import.reload.state.to_sym }.from(:scheduled).to(:in_progress) + end + + it 'calls BulkImportService' do + subject.perform(import.id) + expect(service_double).to have_received(:call).with(import) + end + end +end diff --git a/spec/workers/cache_buster_worker_spec.rb b/spec/workers/cache_buster_worker_spec.rb new file mode 100644 index 0000000000..adeb287fa3 --- /dev/null +++ b/spec/workers/cache_buster_worker_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe CacheBusterWorker do + let(:worker) { described_class.new } + + describe 'perform' do + let(:path) { 'https://example.com' } + let(:service) { instance_double(CacheBuster, bust: true) } + + it 'calls the cache buster' do + allow(CacheBuster).to receive(:new).and_return(service) + worker.perform(path) + + expect(service).to have_received(:bust).with(path) + end + end +end diff --git a/spec/workers/domain_block_worker_spec.rb b/spec/workers/domain_block_worker_spec.rb index bd8fc4a620..33c3ca009a 100644 --- a/spec/workers/domain_block_worker_spec.rb +++ b/spec/workers/domain_block_worker_spec.rb @@ -9,7 +9,7 @@ describe DomainBlockWorker do let(:domain_block) { Fabricate(:domain_block) } it 'calls domain block service for relevant domain block' do - service = double(call: nil) + service = instance_double(BlockDomainService, call: nil) allow(BlockDomainService).to receive(:new).and_return(service) result = subject.perform(domain_block.id) @@ -20,7 +20,7 @@ describe DomainBlockWorker do it 'returns true for non-existent domain block' do result = subject.perform('aaa') - expect(result).to eq(true) + expect(result).to be(true) end end end diff --git a/spec/workers/domain_clear_media_worker_spec.rb b/spec/workers/domain_clear_media_worker_spec.rb index 36251b1ec5..21f8f87b2f 100644 --- a/spec/workers/domain_clear_media_worker_spec.rb +++ b/spec/workers/domain_clear_media_worker_spec.rb @@ -9,7 +9,7 @@ describe DomainClearMediaWorker do let(:domain_block) { Fabricate(:domain_block, severity: :silence, reject_media: true) } it 'calls domain clear media service for relevant domain block' do - service = double(call: nil) + service = instance_double(ClearDomainMediaService, call: nil) allow(ClearDomainMediaService).to receive(:new).and_return(service) result = subject.perform(domain_block.id) @@ -20,7 +20,7 @@ describe DomainClearMediaWorker do it 'returns true for non-existent domain block' do result = subject.perform('aaa') - expect(result).to eq(true) + expect(result).to be(true) end end end diff --git a/spec/workers/feed_insert_worker_spec.rb b/spec/workers/feed_insert_worker_spec.rb index fb34970fc3..97c73c5999 100644 --- a/spec/workers/feed_insert_worker_spec.rb +++ b/spec/workers/feed_insert_worker_spec.rb @@ -11,36 +11,36 @@ describe FeedInsertWorker do context 'when there are no records' do it 'skips push with missing status' do - instance = double(push_to_home: nil) + instance = instance_double(FeedManager, push_to_home: nil) allow(FeedManager).to receive(:instance).and_return(instance) result = subject.perform(nil, follower.id) - expect(result).to eq true - expect(instance).not_to have_received(:push_to_home) + expect(result).to be true + expect(instance).to_not have_received(:push_to_home) end it 'skips push with missing account' do - instance = double(push_to_home: nil) + instance = instance_double(FeedManager, push_to_home: nil) allow(FeedManager).to receive(:instance).and_return(instance) result = subject.perform(status.id, nil) - expect(result).to eq true - expect(instance).not_to have_received(:push_to_home) + expect(result).to be true + expect(instance).to_not have_received(:push_to_home) end end context 'when there are real records' do it 'skips the push when there is a filter' do - instance = double(push_to_home: nil, filter?: true) + instance = instance_double(FeedManager, push_to_home: nil, filter?: true) allow(FeedManager).to receive(:instance).and_return(instance) result = subject.perform(status.id, follower.id) expect(result).to be_nil - expect(instance).not_to have_received(:push_to_home) + expect(instance).to_not have_received(:push_to_home) end it 'pushes the status onto the home timeline without filter' do - instance = double(push_to_home: nil, filter?: false) + instance = instance_double(FeedManager, push_to_home: nil, filter?: false) allow(FeedManager).to receive(:instance).and_return(instance) result = subject.perform(status.id, follower.id) diff --git a/spec/workers/import/row_worker_spec.rb b/spec/workers/import/row_worker_spec.rb new file mode 100644 index 0000000000..0a71a838fc --- /dev/null +++ b/spec/workers/import/row_worker_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Import::RowWorker do + subject { described_class.new } + + let(:row) { Fabricate(:bulk_import_row, bulk_import: import) } + + describe '#perform' do + before do + allow(BulkImportRowService).to receive(:new).and_return(service_double) + end + + shared_examples 'clean failure' do + let(:service_double) { instance_double(BulkImportRowService, call: false) } + + it 'calls BulkImportRowService' do + subject.perform(row.id) + expect(service_double).to have_received(:call).with(row) + end + + it 'increases the number of processed items' do + expect { subject.perform(row.id) }.to(change { import.reload.processed_items }.by(+1)) + end + + it 'does not increase the number of imported items' do + expect { subject.perform(row.id) }.to_not(change { import.reload.imported_items }) + end + + it 'does not delete the row' do + subject.perform(row.id) + expect(BulkImportRow.exists?(row.id)).to be true + end + end + + shared_examples 'unclean failure' do + let(:service_double) { instance_double(BulkImportRowService) } + + before do + allow(service_double).to receive(:call) do + raise 'dummy error' + end + end + + it 'raises an error and does not change processed items count' do + expect { subject.perform(row.id) }.to raise_error(StandardError, 'dummy error').and(not_change { import.reload.processed_items }) + end + + it 'does not delete the row' do + expect { subject.perform(row.id) }.to raise_error(StandardError, 'dummy error').and(not_change { BulkImportRow.exists?(row.id) }) + end + end + + shared_examples 'clean success' do + let(:service_double) { instance_double(BulkImportRowService, call: true) } + + it 'calls BulkImportRowService' do + subject.perform(row.id) + expect(service_double).to have_received(:call).with(row) + end + + it 'increases the number of processed items' do + expect { subject.perform(row.id) }.to(change { import.reload.processed_items }.by(+1)) + end + + it 'increases the number of imported items' do + expect { subject.perform(row.id) }.to(change { import.reload.imported_items }.by(+1)) + end + + it 'deletes the row' do + expect { subject.perform(row.id) }.to change { BulkImportRow.exists?(row.id) }.from(true).to(false) + end + end + + context 'when there are multiple rows to process' do + let(:import) { Fabricate(:bulk_import, total_items: 2, processed_items: 0, imported_items: 0, state: :in_progress) } + + context 'with a clean failure' do + include_examples 'clean failure' + + it 'does not mark the import as finished' do + expect { subject.perform(row.id) }.to_not(change { import.reload.state.to_sym }) + end + end + + context 'with an unclean failure' do + include_examples 'unclean failure' + + it 'does not mark the import as finished' do + expect { subject.perform(row.id) }.to raise_error(StandardError).and(not_change { import.reload.state.to_sym }) + end + end + + context 'with a clean success' do + include_examples 'clean success' + + it 'does not mark the import as finished' do + expect { subject.perform(row.id) }.to_not(change { import.reload.state.to_sym }) + end + end + end + + context 'when this is the last row to process' do + let(:import) { Fabricate(:bulk_import, total_items: 2, processed_items: 1, imported_items: 0, state: :in_progress) } + + context 'with a clean failure' do + include_examples 'clean failure' + + it 'marks the import as finished' do + expect { subject.perform(row.id) }.to change { import.reload.state.to_sym }.from(:in_progress).to(:finished) + end + end + + # NOTE: sidekiq retry logic may be a bit too difficult to test, so leaving this blind spot for now + it_behaves_like 'unclean failure' + + context 'with a clean success' do + include_examples 'clean success' + + it 'marks the import as finished' do + expect { subject.perform(row.id) }.to change { import.reload.state.to_sym }.from(:in_progress).to(:finished) + end + end + end + end +end diff --git a/spec/workers/move_worker_spec.rb b/spec/workers/move_worker_spec.rb index 3ca6aaf4de..7577f6e896 100644 --- a/spec/workers/move_worker_spec.rb +++ b/spec/workers/move_worker_spec.rb @@ -3,24 +3,30 @@ require 'rails_helper' describe MoveWorker do - let(:local_follower) { Fabricate(:account) } + subject { described_class.new } + + let(:local_follower) { Fabricate(:account, domain: nil) } let(:blocking_account) { Fabricate(:account) } let(:muting_account) { Fabricate(:account) } - let(:source_account) { Fabricate(:account, protocol: :activitypub, domain: 'example.com') } - let(:target_account) { Fabricate(:account, protocol: :activitypub, domain: 'example.com') } + let(:source_account) { Fabricate(:account, protocol: :activitypub, domain: 'example.com', uri: 'https://example.org/a', inbox_url: 'https://example.org/a/inbox') } + let(:target_account) { Fabricate(:account, protocol: :activitypub, domain: 'example.com', uri: 'https://example.org/b', inbox_url: 'https://example.org/b/inbox') } let(:local_user) { Fabricate(:user) } let(:comment) { 'old note prior to move' } let!(:account_note) { Fabricate(:account_note, account: local_user.account, target_account: source_account, comment: comment) } + let(:list) { Fabricate(:list, account: local_follower) } - let(:block_service) { double } - - subject { described_class.new } + let(:block_service) { instance_double(BlockService) } before do + stub_request(:post, 'https://example.org/a/inbox').to_return(status: 200) + stub_request(:post, 'https://example.org/b/inbox').to_return(status: 200) + local_follower.follow!(source_account) blocking_account.block!(source_account) muting_account.mute!(source_account) + list.accounts << source_account + allow(BlockService).to receive(:new).and_return(block_service) allow(block_service).to receive(:call) end @@ -86,55 +92,100 @@ describe MoveWorker do end end - context 'both accounts are distant' do - describe 'perform' do - it 'calls UnfollowFollowWorker' do - expect_push_bulk_to_match(UnfollowFollowWorker, [[local_follower.id, source_account.id, target_account.id, false]]) - subject.perform(source_account.id, target_account.id) + shared_examples 'lists handling' do + it 'puts the new account on the list' do + subject.perform(source_account.id, target_account.id) + expect(list.accounts.include?(target_account)).to be true + end + + it 'does not create invalid list memberships' do + subject.perform(source_account.id, target_account.id) + expect(ListAccount.all).to all be_valid + end + end + + shared_examples 'common tests' do + include_examples 'user note handling' + include_examples 'block and mute handling' + include_examples 'followers count handling' + include_examples 'lists handling' + + context 'when a local user already follows both source and target' do + before do + local_follower.request_follow!(target_account) end include_examples 'user note handling' include_examples 'block and mute handling' include_examples 'followers count handling' + include_examples 'lists handling' + + context 'when the local user already has the target in a list' do + before do + list.accounts << target_account + end + + include_examples 'lists handling' + end end - end - context 'target account is local' do - let(:target_account) { Fabricate(:account) } - - describe 'perform' do - it 'calls UnfollowFollowWorker' do - expect_push_bulk_to_match(UnfollowFollowWorker, [[local_follower.id, source_account.id, target_account.id, true]]) - subject.perform(source_account.id, target_account.id) + context 'when a local follower already has a pending request to the target' do + before do + local_follower.follow!(target_account) end include_examples 'user note handling' include_examples 'block and mute handling' include_examples 'followers count handling' + include_examples 'lists handling' + + context 'when the local user already has the target in a list' do + before do + list.accounts << target_account + end + + include_examples 'lists handling' + end end end - context 'both target and source accounts are local' do - let(:target_account) { Fabricate(:account) } - let(:source_account) { Fabricate(:account) } + describe '#perform' do + context 'when both accounts are distant' do + it 'calls UnfollowFollowWorker' do + Sidekiq::Testing.fake! do + subject.perform(source_account.id, target_account.id) + expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, false) + Sidekiq::Worker.drain_all + end + end + + include_examples 'common tests' + end + + context 'when target account is local' do + let(:target_account) { Fabricate(:account) } + + it 'calls UnfollowFollowWorker' do + Sidekiq::Testing.fake! do + subject.perform(source_account.id, target_account.id) + expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, true) + Sidekiq::Worker.clear_all + end + end + + include_examples 'common tests' + end + + context 'when both target and source accounts are local' do + let(:target_account) { Fabricate(:account) } + let(:source_account) { Fabricate(:account) } - describe 'perform' do it 'calls makes local followers follow the target account' do subject.perform(source_account.id, target_account.id) expect(local_follower.following?(target_account)).to be true end - include_examples 'user note handling' - include_examples 'block and mute handling' - include_examples 'followers count handling' - - it 'does not fail when a local user is already following both accounts' do - double_follower = Fabricate(:account) - double_follower.follow!(source_account) - double_follower.follow!(target_account) - subject.perform(source_account.id, target_account.id) - expect(local_follower.following?(target_account)).to be true - end + include_examples 'common tests' it 'does not allow the moved account to follow themselves' do source_account.follow!(target_account) diff --git a/spec/workers/poll_expiration_notify_worker_spec.rb b/spec/workers/poll_expiration_notify_worker_spec.rb new file mode 100644 index 0000000000..78cbc1ee40 --- /dev/null +++ b/spec/workers/poll_expiration_notify_worker_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PollExpirationNotifyWorker do + let(:worker) { described_class.new } + let(:account) { Fabricate(:account, domain: remote? ? 'example.com' : nil) } + let(:status) { Fabricate(:status, account: account) } + let(:poll) { Fabricate(:poll, status: status, account: account) } + let(:remote?) { false } + let(:poll_vote) { Fabricate(:poll_vote, poll: poll) } + + describe '#perform' do + around do |example| + Sidekiq::Testing.fake! do + example.run + end + end + + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + + context 'when poll is not expired' do + it 'requeues job' do + worker.perform(poll.id) + expect(described_class.sidekiq_options_hash['lock']).to be :until_executing + expect(described_class).to have_enqueued_sidekiq_job(poll.id).at(poll.expires_at + 5.minutes) + end + end + + context 'when poll is expired' do + before do + poll_vote + + travel_to poll.expires_at + 5.minutes + + worker.perform(poll.id) + end + + context 'when poll is local' do + it 'notifies voters' do + expect(ActivityPub::DistributePollUpdateWorker).to have_enqueued_sidekiq_job(poll.status.id) + end + + it 'notifies owner' do + expect(LocalNotificationWorker).to have_enqueued_sidekiq_job(poll.account.id, poll.id, 'Poll', 'poll') + end + + it 'notifies local voters' do + expect(LocalNotificationWorker).to have_enqueued_sidekiq_job(poll_vote.account.id, poll.id, 'Poll', 'poll') + end + end + + context 'when poll is remote' do + let(:remote?) { true } + + it 'does not notify remote voters' do + expect(ActivityPub::DistributePollUpdateWorker).to_not have_enqueued_sidekiq_job(poll.status.id) + end + + it 'does not notify owner' do + expect(LocalNotificationWorker).to_not have_enqueued_sidekiq_job(poll.account.id, poll.id, 'Poll', 'poll') + end + + it 'notifies local voters' do + expect(LocalNotificationWorker).to have_enqueued_sidekiq_job(poll_vote.account.id, poll.id, 'Poll', 'poll') + end + end + end + end +end diff --git a/spec/workers/post_process_media_worker_spec.rb b/spec/workers/post_process_media_worker_spec.rb new file mode 100644 index 0000000000..33072704bf --- /dev/null +++ b/spec/workers/post_process_media_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PostProcessMediaWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/publish_scheduled_announcement_worker_spec.rb b/spec/workers/publish_scheduled_announcement_worker_spec.rb index 0977bba1ee..2e50d4a50d 100644 --- a/spec/workers/publish_scheduled_announcement_worker_spec.rb +++ b/spec/workers/publish_scheduled_announcement_worker_spec.rb @@ -12,7 +12,7 @@ describe PublishScheduledAnnouncementWorker do describe 'perform' do before do - service = double + service = instance_double(FetchRemoteStatusService) allow(FetchRemoteStatusService).to receive(:new).and_return(service) allow(service).to receive(:call).with('https://domain.com/users/foo/12345') { remote_status.reload } diff --git a/spec/workers/push_conversation_worker_spec.rb b/spec/workers/push_conversation_worker_spec.rb new file mode 100644 index 0000000000..5fbb4c6853 --- /dev/null +++ b/spec/workers/push_conversation_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PushConversationWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/push_encrypted_message_worker_spec.rb b/spec/workers/push_encrypted_message_worker_spec.rb new file mode 100644 index 0000000000..3cd04ce7b4 --- /dev/null +++ b/spec/workers/push_encrypted_message_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PushEncryptedMessageWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/push_update_worker_spec.rb b/spec/workers/push_update_worker_spec.rb new file mode 100644 index 0000000000..c8f94fa82a --- /dev/null +++ b/spec/workers/push_update_worker_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe PushUpdateWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + account_id = nil + status_id = nil + + expect { worker.perform(account_id, status_id) }.to_not raise_error + end + end +end diff --git a/spec/workers/redownload_avatar_worker_spec.rb b/spec/workers/redownload_avatar_worker_spec.rb new file mode 100644 index 0000000000..b44ae9f035 --- /dev/null +++ b/spec/workers/redownload_avatar_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RedownloadAvatarWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/redownload_header_worker_spec.rb b/spec/workers/redownload_header_worker_spec.rb new file mode 100644 index 0000000000..767ae7a5ab --- /dev/null +++ b/spec/workers/redownload_header_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RedownloadHeaderWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/refollow_worker_spec.rb b/spec/workers/refollow_worker_spec.rb index d9c2293b62..5718d4db49 100644 --- a/spec/workers/refollow_worker_spec.rb +++ b/spec/workers/refollow_worker_spec.rb @@ -4,12 +4,13 @@ require 'rails_helper' describe RefollowWorker do subject { described_class.new } + let(:account) { Fabricate(:account, domain: 'example.org', protocol: :activitypub) } let(:alice) { Fabricate(:account, domain: nil, username: 'alice') } let(:bob) { Fabricate(:account, domain: nil, username: 'bob') } describe 'perform' do - let(:service) { double } + let(:service) { instance_double(FollowService) } before do allow(FollowService).to receive(:new).and_return(service) diff --git a/spec/workers/regeneration_worker_spec.rb b/spec/workers/regeneration_worker_spec.rb index c6bdfa0e5e..37b0a04c49 100644 --- a/spec/workers/regeneration_worker_spec.rb +++ b/spec/workers/regeneration_worker_spec.rb @@ -9,7 +9,7 @@ describe RegenerationWorker do let(:account) { Fabricate(:account) } it 'calls the precompute feed service for the account' do - service = double(call: nil) + service = instance_double(PrecomputeFeedService, call: nil) allow(PrecomputeFeedService).to receive(:new).and_return(service) result = subject.perform(account.id) @@ -20,7 +20,7 @@ describe RegenerationWorker do it 'fails when account does not exist' do result = subject.perform('aaa') - expect(result).to eq(true) + expect(result).to be(true) end end end diff --git a/spec/workers/remove_featured_tag_worker_spec.rb b/spec/workers/remove_featured_tag_worker_spec.rb new file mode 100644 index 0000000000..a64bd0605f --- /dev/null +++ b/spec/workers/remove_featured_tag_worker_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RemoveFeaturedTagWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + account_id = nil + featured_tag_id = nil + expect { worker.perform(account_id, featured_tag_id) }.to_not raise_error + end + end +end diff --git a/spec/workers/remove_from_public_statuses_index_worker_spec.rb b/spec/workers/remove_from_public_statuses_index_worker_spec.rb new file mode 100644 index 0000000000..43ff211eaa --- /dev/null +++ b/spec/workers/remove_from_public_statuses_index_worker_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RemoveFromPublicStatusesIndexWorker do + describe '#perform' do + let(:account) { Fabricate(:account, indexable: indexable) } + let(:account_id) { account.id } + + before do + allow(Account).to receive(:find).with(account_id).and_return(account) unless account.nil? + allow(account).to receive(:remove_from_public_statuses_index!) unless account.nil? + end + + context 'when account is not indexable' do + let(:indexable) { false } + + it 'removes the account from public statuses index' do + subject.perform(account_id) + expect(account).to have_received(:remove_from_public_statuses_index!) + end + end + + context 'when account is indexable' do + let(:indexable) { true } + + it 'does not remove the account from public statuses index' do + subject.perform(account_id) + expect(account).to_not have_received(:remove_from_public_statuses_index!) + end + end + + context 'when account does not exist' do + let(:account) { nil } + let(:account_id) { 999 } + + it 'does not raise an error' do + expect { subject.perform(account_id) }.to_not raise_error + end + end + end +end diff --git a/spec/workers/resolve_account_worker_spec.rb b/spec/workers/resolve_account_worker_spec.rb new file mode 100644 index 0000000000..6f3cff099f --- /dev/null +++ b/spec/workers/resolve_account_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ResolveAccountWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb b/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb index 0b0c4dd487..4d9185093a 100644 --- a/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb +++ b/spec/workers/scheduler/accounts_statuses_cleanup_scheduler_spec.rb @@ -1,19 +1,16 @@ +# frozen_string_literal: true + require 'rails_helper' describe Scheduler::AccountsStatusesCleanupScheduler do subject { described_class.new } - let!(:account1) { Fabricate(:account, domain: nil) } - let!(:account2) { Fabricate(:account, domain: nil) } - let!(:account3) { Fabricate(:account, domain: nil) } - let!(:account4) { Fabricate(:account, domain: nil) } - let!(:account5) { Fabricate(:account, domain: nil) } - let!(:remote) { Fabricate(:account) } - - let!(:policy1) { Fabricate(:account_statuses_cleanup_policy, account: account1) } - let!(:policy2) { Fabricate(:account_statuses_cleanup_policy, account: account3) } - let!(:policy3) { Fabricate(:account_statuses_cleanup_policy, account: account4, enabled: false) } - let!(:policy4) { Fabricate(:account_statuses_cleanup_policy, account: account5) } + let!(:account_alice) { Fabricate(:account, domain: nil, username: 'alice') } + let!(:account_bob) { Fabricate(:account, domain: nil, username: 'bob') } + let!(:account_chris) { Fabricate(:account, domain: nil, username: 'chris') } + let!(:account_dave) { Fabricate(:account, domain: nil, username: 'dave') } + let!(:account_erin) { Fabricate(:account, domain: nil, username: 'erin') } + let!(:remote) { Fabricate(:account) } let(:queue_size) { 0 } let(:queue_latency) { 0 } @@ -21,39 +18,18 @@ describe Scheduler::AccountsStatusesCleanupScheduler do [ { 'concurrency' => 2, - 'queues' => ['push', 'default'], + 'queues' => %w(push default), }, ] end before do - queue_stub = double - allow(queue_stub).to receive(:size).and_return(queue_size) - allow(queue_stub).to receive(:latency).and_return(queue_latency) + queue_stub = instance_double(Sidekiq::Queue, size: queue_size, latency: queue_latency) allow(Sidekiq::Queue).to receive(:new).and_return(queue_stub) allow(Sidekiq::ProcessSet).to receive(:new).and_return(process_set_stub) - sidekiq_stats_stub = double + sidekiq_stats_stub = instance_double(Sidekiq::Stats) allow(Sidekiq::Stats).to receive(:new).and_return(sidekiq_stats_stub) - - # Create a bunch of old statuses - 10.times do - Fabricate(:status, account: account1, created_at: 3.years.ago) - Fabricate(:status, account: account2, created_at: 3.years.ago) - Fabricate(:status, account: account3, created_at: 3.years.ago) - Fabricate(:status, account: account4, created_at: 3.years.ago) - Fabricate(:status, account: account5, created_at: 3.years.ago) - Fabricate(:status, account: remote, created_at: 3.years.ago) - end - - # Create a bunch of newer statuses - 5.times do - Fabricate(:status, account: account1, created_at: 3.minutes.ago) - Fabricate(:status, account: account2, created_at: 3.minutes.ago) - Fabricate(:status, account: account3, created_at: 3.minutes.ago) - Fabricate(:status, account: account4, created_at: 3.minutes.ago) - Fabricate(:status, account: remote, created_at: 3.minutes.ago) - end end describe '#under_load?' do @@ -74,18 +50,18 @@ describe Scheduler::AccountsStatusesCleanupScheduler do end describe '#compute_budget' do - context 'on a single thread' do - let(:process_set_stub) { [ { 'concurrency' => 1, 'queues' => ['push', 'default'] } ] } + context 'with a single thread' do + let(:process_set_stub) { [{ 'concurrency' => 1, 'queues' => %w(push default) }] } it 'returns a low value' do expect(subject.compute_budget).to be < 10 end end - context 'on a lot of threads' do + context 'with a lot of threads' do let(:process_set_stub) do [ - { 'concurrency' => 2, 'queues' => ['push', 'default'] }, + { 'concurrency' => 2, 'queues' => %w(push default) }, { 'concurrency' => 2, 'queues' => ['push'] }, { 'concurrency' => 2, 'queues' => ['push'] }, { 'concurrency' => 2, 'queues' => ['push'] }, @@ -99,23 +75,51 @@ describe Scheduler::AccountsStatusesCleanupScheduler do end describe '#perform' do + around do |example| + Timeout.timeout(30) do + example.run + end + end + + before do + # Policies for the accounts + Fabricate(:account_statuses_cleanup_policy, account: account_alice) + Fabricate(:account_statuses_cleanup_policy, account: account_chris) + Fabricate(:account_statuses_cleanup_policy, account: account_dave, enabled: false) + Fabricate(:account_statuses_cleanup_policy, account: account_erin) + + # Create a bunch of old statuses + 4.times do + Fabricate(:status, account: account_alice, created_at: 3.years.ago) + Fabricate(:status, account: account_bob, created_at: 3.years.ago) + Fabricate(:status, account: account_chris, created_at: 3.years.ago) + Fabricate(:status, account: account_dave, created_at: 3.years.ago) + Fabricate(:status, account: account_erin, created_at: 3.years.ago) + Fabricate(:status, account: remote, created_at: 3.years.ago) + end + + # Create a bunch of newer statuses + Fabricate(:status, account: account_alice, created_at: 3.minutes.ago) + Fabricate(:status, account: account_bob, created_at: 3.minutes.ago) + Fabricate(:status, account: account_chris, created_at: 3.minutes.ago) + Fabricate(:status, account: account_dave, created_at: 3.minutes.ago) + Fabricate(:status, account: remote, created_at: 3.minutes.ago) + end + context 'when the budget is lower than the number of toots to delete' do - it 'deletes as many statuses as the given budget' do - expect { subject.perform }.to change { Status.count }.by(-subject.compute_budget) - end + it 'deletes the appropriate statuses' do + expect(Status.count).to be > (subject.compute_budget) # Data check - it 'does not delete from accounts with no cleanup policy' do - expect { subject.perform }.to_not change { account2.statuses.count } - end - - it 'does not delete from accounts with disabled cleanup policies' do - expect { subject.perform }.to_not change { account4.statuses.count } + expect { subject.perform } + .to change(Status, :count).by(-subject.compute_budget) # Cleanable statuses + .and (not_change { account_bob.statuses.count }) # No cleanup policy for account + .and(not_change { account_dave.statuses.count }) # Disabled cleanup policy end it 'eventually deletes every deletable toot given enough runs' do stub_const 'Scheduler::AccountsStatusesCleanupScheduler::MAX_BUDGET', 4 - expect { 10.times { subject.perform } }.to change { Status.count }.by(-30) + expect { 3.times { subject.perform } }.to change(Status, :count).by(-cleanable_statuses_count) end it 'correctly round-trips between users across several runs' do @@ -123,10 +127,10 @@ describe Scheduler::AccountsStatusesCleanupScheduler do stub_const 'Scheduler::AccountsStatusesCleanupScheduler::PER_ACCOUNT_BUDGET', 2 expect { 3.times { subject.perform } } - .to change { Status.count }.by(-3 * 3) - .and change { account1.statuses.count } - .and change { account3.statuses.count } - .and change { account5.statuses.count } + .to change(Status, :count).by(-3 * 3) + .and change { account_alice.statuses.count } + .and change { account_chris.statuses.count } + .and(change { account_erin.statuses.count }) end context 'when given a big budget' do @@ -138,7 +142,7 @@ describe Scheduler::AccountsStatusesCleanupScheduler do it 'correctly handles looping in a single run' do expect(subject.compute_budget).to eq(400) - expect { subject.perform }.to change { Status.count }.by(-30) + expect { subject.perform }.to change(Status, :count).by(-cleanable_statuses_count) end end @@ -152,9 +156,16 @@ describe Scheduler::AccountsStatusesCleanupScheduler do it 'does not get stuck' do expect(subject.compute_budget).to eq(400) - expect { subject.perform }.to_not change { Status.count } + expect { subject.perform }.to_not change(Status, :count) end end + + def cleanable_statuses_count + Status + .where(account_id: [account_alice, account_chris, account_erin]) # Accounts with enabled policies + .where('created_at < ?', 2.weeks.ago) # Policy defaults is 2.weeks + .count + end end end end diff --git a/spec/workers/scheduler/follow_recommendations_scheduler_spec.rb b/spec/workers/scheduler/follow_recommendations_scheduler_spec.rb new file mode 100644 index 0000000000..18d5260e42 --- /dev/null +++ b/spec/workers/scheduler/follow_recommendations_scheduler_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::FollowRecommendationsScheduler do + let!(:target_accounts) do + Fabricate.times(3, :account) do + statuses(count: 6) + end + end + let!(:follower_accounts) do + Fabricate.times(5, :account) do + statuses(count: 6) + end + end + + describe '#perform' do + subject(:scheduled_run) { described_class.new.perform } + + context 'when there are accounts to recommend' do + before do + # Follow the target accounts by follow accounts to make them recommendable + follower_accounts.each do |follower_account| + target_accounts.each do |target_account| + Fabricate(:follow, account: follower_account, target_account: target_account) + end + end + end + + it 'creates recommendations' do + expect { scheduled_run }.to change(FollowRecommendation, :count).from(0).to(target_accounts.size) + expect(redis.zrange('follow_recommendations:en', 0, -1)).to match_array(target_accounts.pluck(:id).map(&:to_s)) + end + end + + context 'when there are no accounts to recommend' do + it 'does not create follow recommendations' do + expect { scheduled_run }.to_not change(FollowRecommendation, :count) + expect(redis.zrange('follow_recommendations:en', 0, -1)).to be_empty + end + end + end +end diff --git a/spec/workers/scheduler/indexing_scheduler_spec.rb b/spec/workers/scheduler/indexing_scheduler_spec.rb new file mode 100644 index 0000000000..568f0fc84d --- /dev/null +++ b/spec/workers/scheduler/indexing_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::IndexingScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/instance_refresh_scheduler_spec.rb b/spec/workers/scheduler/instance_refresh_scheduler_spec.rb new file mode 100644 index 0000000000..8f686a6998 --- /dev/null +++ b/spec/workers/scheduler/instance_refresh_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::InstanceRefreshScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/ip_cleanup_scheduler_spec.rb b/spec/workers/scheduler/ip_cleanup_scheduler_spec.rb new file mode 100644 index 0000000000..50af030117 --- /dev/null +++ b/spec/workers/scheduler/ip_cleanup_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::IpCleanupScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/pghero_scheduler_spec.rb b/spec/workers/scheduler/pghero_scheduler_spec.rb new file mode 100644 index 0000000000..e404e5fe47 --- /dev/null +++ b/spec/workers/scheduler/pghero_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::PgheroScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/scheduled_statuses_scheduler_spec.rb b/spec/workers/scheduler/scheduled_statuses_scheduler_spec.rb new file mode 100644 index 0000000000..13c853c62a --- /dev/null +++ b/spec/workers/scheduler/scheduled_statuses_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::ScheduledStatusesScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/software_update_check_scheduler_spec.rb b/spec/workers/scheduler/software_update_check_scheduler_spec.rb new file mode 100644 index 0000000000..f596c0a1ec --- /dev/null +++ b/spec/workers/scheduler/software_update_check_scheduler_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::SoftwareUpdateCheckScheduler do + subject { described_class.new } + + describe 'perform' do + let(:service_double) { instance_double(SoftwareUpdateCheckService, call: nil) } + + before do + allow(SoftwareUpdateCheckService).to receive(:new).and_return(service_double) + end + + it 'calls SoftwareUpdateCheckService' do + subject.perform + expect(service_double).to have_received(:call) + end + end +end diff --git a/spec/workers/scheduler/suspended_user_cleanup_scheduler_spec.rb b/spec/workers/scheduler/suspended_user_cleanup_scheduler_spec.rb new file mode 100644 index 0000000000..25f0e1fce4 --- /dev/null +++ b/spec/workers/scheduler/suspended_user_cleanup_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::SuspendedUserCleanupScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/trends/refresh_scheduler_spec.rb b/spec/workers/scheduler/trends/refresh_scheduler_spec.rb new file mode 100644 index 0000000000..c0c5f032bf --- /dev/null +++ b/spec/workers/scheduler/trends/refresh_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::Trends::RefreshScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/trends/review_notifications_scheduler_spec.rb b/spec/workers/scheduler/trends/review_notifications_scheduler_spec.rb new file mode 100644 index 0000000000..cc971c24b4 --- /dev/null +++ b/spec/workers/scheduler/trends/review_notifications_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::Trends::ReviewNotificationsScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/scheduler/user_cleanup_scheduler_spec.rb b/spec/workers/scheduler/user_cleanup_scheduler_spec.rb index da99f10f97..9909795008 100644 --- a/spec/workers/scheduler/user_cleanup_scheduler_spec.rb +++ b/spec/workers/scheduler/user_cleanup_scheduler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe Scheduler::UserCleanupScheduler do diff --git a/spec/workers/scheduler/vacuum_scheduler_spec.rb b/spec/workers/scheduler/vacuum_scheduler_spec.rb new file mode 100644 index 0000000000..36ecc93d8e --- /dev/null +++ b/spec/workers/scheduler/vacuum_scheduler_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Scheduler::VacuumScheduler do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform }.to_not raise_error + end + end +end diff --git a/spec/workers/tag_unmerge_worker_spec.rb b/spec/workers/tag_unmerge_worker_spec.rb new file mode 100644 index 0000000000..5d3a12c449 --- /dev/null +++ b/spec/workers/tag_unmerge_worker_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe TagUnmergeWorker do + subject { described_class.new } + + describe 'perform' do + let(:follower) { Fabricate(:account) } + let(:followed) { Fabricate(:account) } + let(:followed_tag) { Fabricate(:tag) } + let(:unchanged_followed_tag) { Fabricate(:tag) } + let(:status_from_followed) { Fabricate(:status, created_at: 2.hours.ago, account: followed) } + let(:tagged_status) { Fabricate(:status, created_at: 1.hour.ago) } + let(:unchanged_tagged_status) { Fabricate(:status) } + + before do + tagged_status.tags << followed_tag + unchanged_tagged_status.tags << followed_tag + unchanged_tagged_status.tags << unchanged_followed_tag + + tag_follow = TagFollow.create_with(rate_limit: false).find_or_create_by!(tag: followed_tag, account: follower) + TagFollow.create_with(rate_limit: false).find_or_create_by!(tag: unchanged_followed_tag, account: follower) + + FeedManager.instance.push_to_home(follower, status_from_followed, update: false) + FeedManager.instance.push_to_home(follower, tagged_status, update: false) + FeedManager.instance.push_to_home(follower, unchanged_tagged_status, update: false) + + tag_follow.destroy! + end + + it 'removes the expected status from the feed' do + expect { subject.perform(followed_tag.id, follower.id) } + .to change { HomeFeed.new(follower).get(10).pluck(:id) } + .from([unchanged_tagged_status.id, tagged_status.id, status_from_followed.id]) + .to([unchanged_tagged_status.id, status_from_followed.id]) + end + end +end diff --git a/spec/workers/unfollow_follow_worker_spec.rb b/spec/workers/unfollow_follow_worker_spec.rb index 5ea4256a9b..8025b88c0c 100644 --- a/spec/workers/unfollow_follow_worker_spec.rb +++ b/spec/workers/unfollow_follow_worker_spec.rb @@ -3,13 +3,13 @@ require 'rails_helper' describe UnfollowFollowWorker do + subject { described_class.new } + let(:local_follower) { Fabricate(:account) } let(:source_account) { Fabricate(:account) } let(:target_account) { Fabricate(:account) } let(:show_reblogs) { true } - subject { described_class.new } - before do local_follower.follow!(source_account, reblogs: show_reblogs) end diff --git a/spec/workers/unpublish_announcement_worker_spec.rb b/spec/workers/unpublish_announcement_worker_spec.rb new file mode 100644 index 0000000000..c742c30bce --- /dev/null +++ b/spec/workers/unpublish_announcement_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe UnpublishAnnouncementWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/verify_account_links_worker_spec.rb b/spec/workers/verify_account_links_worker_spec.rb new file mode 100644 index 0000000000..227591392c --- /dev/null +++ b/spec/workers/verify_account_links_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe VerifyAccountLinksWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error for missing record' do + expect { worker.perform(nil) }.to_not raise_error + end + end +end diff --git a/spec/workers/web/push_notification_worker_spec.rb b/spec/workers/web/push_notification_worker_spec.rb index 5bc24f8886..822ef5257f 100644 --- a/spec/workers/web/push_notification_worker_spec.rb +++ b/spec/workers/web/push_notification_worker_spec.rb @@ -37,7 +37,7 @@ describe Web::PushNotificationWorker do expect(a_request(:post, endpoint).with(headers: { 'Content-Encoding' => 'aesgcm', 'Content-Type' => 'application/octet-stream', - 'Crypto-Key' => 'dh=BAgtUks5d90kFmxGevk9tH7GEmvz9DB0qcEMUsOBgKwMf-TMjsKIIG6LQvGcFAf6jcmAod15VVwmYwGIIxE4VWE;p256ecdsa=' + vapid_public_key.delete('='), + 'Crypto-Key' => "dh=BAgtUks5d90kFmxGevk9tH7GEmvz9DB0qcEMUsOBgKwMf-TMjsKIIG6LQvGcFAf6jcmAod15VVwmYwGIIxE4VWE;p256ecdsa=#{vapid_public_key.delete('=')}", 'Encryption' => 'salt=WJeVM-RY-F9351SVxTFx_g', 'Ttl' => '172800', 'Urgency' => 'normal', diff --git a/spec/workers/webhooks/delivery_worker_spec.rb b/spec/workers/webhooks/delivery_worker_spec.rb new file mode 100644 index 0000000000..daf8a3e285 --- /dev/null +++ b/spec/workers/webhooks/delivery_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Webhooks::DeliveryWorker do + let(:worker) { described_class.new } + + describe 'perform' do + it 'runs without error' do + expect { worker.perform(nil, nil) }.to_not raise_error + end + end +end diff --git a/stderr.log b/stderr.log new file mode 100644 index 0000000000..05898db8b5 --- /dev/null +++ b/stderr.log @@ -0,0 +1,8247 @@ +rails aborted! +ActionView::Template::Error: Webpacker can't find core/common.js in /home/mastodon/live/public/packs/manifest.json. Possible causes: +1. You want to set webpacker.yml value of compile to true for your environment + unless you are using the `webpack -w` or the webpack-dev-server. +2. webpack has not yet re-run to reflect updates. +3. You have misconfigured Webpacker's config/webpacker.yml file. +4. Your webpack configuration is not creating a manifest. +Your manifest contains: +{ + "admin.js": { + "src": "/packs/js/admin-41af99b8579db78a010d.chunk.js", + "integrity": "sha256-ntJmrmyuIxEPCQMqPonSgMOwaXw9VumIQ1VzWPTgrsI=" + }, + "admin.js.map": { + "src": "/packs/js/admin-41af99b8579db78a010d.chunk.js.map", + "integrity": "sha256-Tn0iSqcU3OY94y+ky8gIP0wHmPfjVkvGKJUv4mAgjNA=" + }, + "application.js": { + "src": "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js", + "integrity": "sha256-HDgeyT/1csPW7R56OBxya3CiKp5KvAdo4pn/4CX8Gxw=" + }, + "application.js.map": { + "src": "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js.map", + "integrity": "sha256-OWOQ5vK1As4TbWqADbLSzU0W9yUWaC6ztwn45ee+ow4=" + }, + "arrow-key-navigation.js": { + "src": "/packs/js/arrow-key-navigation-c612b3295983104aa0f0.chunk.js", + "integrity": "sha256-xm0v3gnDtsgfV0fBS6dK0Z49lhrgPAphZBLKP+6/3vc=" + }, + "arrow-key-navigation.js.map": { + "src": "/packs/js/arrow-key-navigation-c612b3295983104aa0f0.chunk.js.map", + "integrity": "sha256-kh2Nlueg4q1XPuH9xzBxtLMizHN556h7/MMmviB5CG0=" + }, + "base_polyfills.js": { + "src": "/packs/js/base_polyfills-9e5acba002b775f8a876.chunk.js", + "integrity": "sha256-y2eTCHt6BD+kvYZigLo6R01y+2tl7KYj6oO95RO6eFw=" + }, + "base_polyfills.js.map": { + "src": "/packs/js/base_polyfills-9e5acba002b775f8a876.chunk.js.map", + "integrity": "sha256-lIHOw3dc6xt6/DsFmt8on8HFxhOpvEMF3IjQVf541zs=" + }, + "common.css": { + "src": "/packs/css/common-a844dc34.css", + "integrity": "sha256-P7jsS35wKfKZ7egDM6otdXk7d8JjmsE5i9R8SD1vD8s=" + }, + "common.css.map": { + "src": "/packs/css/common-a844dc34.css.map", + "integrity": "sha256-Qyj/GZ0pv+z3+NCOntxsGwO9M3J2Q8poPIe4Sfc1lgY=" + }, + "common.js": { + "src": "/packs/js/common-9da33dbc9762ba5fb40c.js", + "integrity": "sha256-yz8q1A5JNj54ijBOSdiiYh9xQmsWlLvDxYav5onKtuQ=" + }, + "common.js.map": { + "src": "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "integrity": "sha256-+J4Uo07Scxl6ucAWPOJkPv1ye1hkeVpPnNz2MHV3ocA=" + }, + "containers/media_container.js": { + "src": "/packs/js/containers/media_container-2afe952129d043ba10ed.chunk.js", + "integrity": "sha256-kB3PN4it0IxWs5+DjPCFSxxdqYWN9i4fT5Yl285CjkU=" + }, + "containers/media_container.js.map": { + "src": "/packs/js/containers/media_container-2afe952129d043ba10ed.chunk.js.map", + "integrity": "sha256-YU76VZoOXrSJPXorQs4CkswA1YVkVWeb/4PmOxoeAV0=" + }, + "contrast.css": { + "src": "/packs/css/contrast-5cabd607.chunk.css", + "integrity": "sha256-EGQklklRlDxmQmTgH5Mj9SoQ9ONWg18XZzKJ6EJrZ0w=" + }, + "contrast.css.map": { + "src": "/packs/css/contrast-5cabd607.chunk.css.map", + "integrity": "sha256-dKva8YMTNM51g4ZfFpap/hMi2KgB3ztHYxYcqA0qmBQ=" + }, + "contrast.js": { + "src": "/packs/js/contrast-393583c54c3047b1a13c.chunk.js", + "integrity": "sha256-HN1BR9k9NLbdPBLrJRmSWhfDcu/v/mcsBYGazK4abBI=" + }, + "contrast.js.map": { + "src": "/packs/js/contrast-393583c54c3047b1a13c.chunk.js.map", + "integrity": "sha256-10ozejR0zZg2fuD/Um2sWN4z8FjwEPAhqvfZI8a0Lws=" + }, + "dark.css": { + "src": "/packs/css/dark-a3b88036.chunk.css", + "integrity": "sha256-q+vj0pe+B8fkLwmMvwkYWQJ+skyHaGB6yy1/4Ofa78g=" + }, + "dark.css.map": { + "src": "/packs/css/dark-a3b88036.chunk.css.map", + "integrity": "sha256-CKkP+P28O6kbL4KnjVCz6fgLrWxNOUnnhIB0Xhny1Zg=" + }, + "dark.js": { + "src": "/packs/js/dark-1e375a968d41797e60af.chunk.js", + "integrity": "sha256-XaXdkRE/GYwUmvVTR2JNzxVZl4E2F+EmI78ddvUeCqE=" + }, + "dark.js.map": { + "src": "/packs/js/dark-1e375a968d41797e60af.chunk.js.map", + "integrity": "sha256-wvgYCF4wIaY1hWtkdrBgRbh8c6KNq+XW4naA/Xh04XE=" + }, + "default.css": { + "src": "/packs/css/default-229799f4.chunk.css", + "integrity": "sha256-XxDgsR1SNLVJd5pPuao6byCJQVDMPtCCakHcpqsdUPc=" + }, + "default.css.map": { + "src": "/packs/css/default-229799f4.chunk.css.map", + "integrity": "sha256-ebkS5CFpQ/JKVYi/3INDeZGZlSSC4fKluCdk56t/QoE=" + }, + "default.js": { + "src": "/packs/js/default-8b7478aae9e7db81c926.chunk.js", + "integrity": "sha256-QFMq9O6piSNhhZLgOdrnmXF8S9GNBoOJ3fo4HfbgJgo=" + }, + "default.js.map": { + "src": "/packs/js/default-8b7478aae9e7db81c926.chunk.js.map", + "integrity": "sha256-uzk84SO6ddlFMyWL89bftycACfqBpk2WyQ9nAv6zR+8=" + }, + "emoji_picker.js": { + "src": "/packs/js/emoji_picker-58d5d6643533880286d8.chunk.js", + "integrity": "sha256-0Q56X7XU3uvVsHM26NeHEjTFEGi08JJxWiGAqX4+9NU=" + }, + "emoji_picker.js.map": { + "src": "/packs/js/emoji_picker-58d5d6643533880286d8.chunk.js.map", + "integrity": "sha256-ioRLeVGfhxvoHhiCjnloAgNoZnz3W142SN+N6Uv/3Vw=" + }, + "entrypoints": { + "admin": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/admin-41af99b8579db78a010d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/admin-41af99b8579db78a010d.chunk.js.map" + ] + } + }, + "application": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js.map" + ] + } + }, + "error": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/error-9aec4316f262805dbab4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/error-9aec4316f262805dbab4.chunk.js.map" + ] + } + }, + "mailer": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/mailer-d3e9e30b.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/mailer-906c1f5c743751870035.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/mailer-d3e9e30b.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/mailer-906c1f5c743751870035.chunk.js.map" + ] + } + }, + "public-path": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js.map" + ] + } + }, + "public": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/public-35500a3113a9d04e88f1.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/public-35500a3113a9d04e88f1.chunk.js.map" + ] + } + }, + "share": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/share-efad16f2e2c4954c4721.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/share-efad16f2e2c4954c4721.chunk.js.map" + ] + } + }, + "two_factor_authentication": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js.map" + ] + } + }, + "locale_af": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js.map" + ] + } + }, + "locale_an": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_an-7042264d7263706588ca.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_an-7042264d7263706588ca.chunk.js.map" + ] + } + }, + "locale_ar": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js.map" + ] + } + }, + "locale_ast": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js.map" + ] + } + }, + "locale_be": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_be-2b73894a107f7474274e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_be-2b73894a107f7474274e.chunk.js.map" + ] + } + }, + "locale_bg": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js.map" + ] + } + }, + "locale_bn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js.map" + ] + } + }, + "locale_br": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js.map" + ] + } + }, + "locale_bs": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js.map" + ] + } + }, + "locale_ca": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js.map" + ] + } + }, + "locale_ckb": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ckb-bac2365515303c579326.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ckb-bac2365515303c579326.chunk.js.map" + ] + } + }, + "locale_co": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js.map" + ] + } + }, + "locale_cs": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js.map" + ] + } + }, + "locale_csb": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js.map" + ] + } + }, + "locale_cy": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js.map" + ] + } + }, + "locale_da": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js.map" + ] + } + }, + "locale_de": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js.map" + ] + } + }, + "locale_el": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js.map" + ] + } + }, + "locale_en-GB": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js.map" + ] + } + }, + "locale_en": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js.map" + ] + } + }, + "locale_eo": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js.map" + ] + } + }, + "locale_es-AR": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js.map" + ] + } + }, + "locale_es-MX": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js.map" + ] + } + }, + "locale_es": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js.map" + ] + } + }, + "locale_et": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_et-9957864e54462b54bd25.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_et-9957864e54462b54bd25.chunk.js.map" + ] + } + }, + "locale_eu": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js.map" + ] + } + }, + "locale_fa": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js.map" + ] + } + }, + "locale_fi": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js.map" + ] + } + }, + "locale_fo": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js.map" + ] + } + }, + "locale_fr-QC": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js.map" + ] + } + }, + "locale_fr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js.map" + ] + } + }, + "locale_fy": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js.map" + ] + } + }, + "locale_ga": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js.map" + ] + } + }, + "locale_gd": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js.map" + ] + } + }, + "locale_gl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js.map" + ] + } + }, + "locale_he": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_he-940c5914bccd89572a87.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_he-940c5914bccd89572a87.chunk.js.map" + ] + } + }, + "locale_hi": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js.map" + ] + } + }, + "locale_hr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js.map" + ] + } + }, + "locale_hu": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js.map" + ] + } + }, + "locale_hy": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js.map" + ] + } + }, + "locale_id": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js.map" + ] + } + }, + "locale_ig": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js.map" + ] + } + }, + "locale_io": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js.map" + ] + } + }, + "locale_is": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js.map" + ] + } + }, + "locale_it": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js.map" + ] + } + }, + "locale_ja": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js.map" + ] + } + }, + "locale_ka": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js.map" + ] + } + }, + "locale_kab": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js.map" + ] + } + }, + "locale_kk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kk-806df7189017998308a3.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kk-806df7189017998308a3.chunk.js.map" + ] + } + }, + "locale_kn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js.map" + ] + } + }, + "locale_ko": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js.map" + ] + } + }, + "locale_ku": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js.map" + ] + } + }, + "locale_kw": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js.map" + ] + } + }, + "locale_la": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js.map" + ] + } + }, + "locale_lt": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js.map" + ] + } + }, + "locale_lv": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js.map" + ] + } + }, + "locale_mk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js.map" + ] + } + }, + "locale_ml": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js.map" + ] + } + }, + "locale_mr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js.map" + ] + } + }, + "locale_ms": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js.map" + ] + } + }, + "locale_my": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js.map" + ] + } + }, + "locale_nl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js.map" + ] + } + }, + "locale_nn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js.map" + ] + } + }, + "locale_no": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js.map" + ] + } + }, + "locale_oc": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js.map" + ] + } + }, + "locale_pa": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js.map" + ] + } + }, + "locale_pl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js.map" + ] + } + }, + "locale_pt-BR": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js.map" + ] + } + }, + "locale_pt-PT": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js.map" + ] + } + }, + "locale_ro": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js.map" + ] + } + }, + "locale_ru": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js.map" + ] + } + }, + "locale_sa": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js.map" + ] + } + }, + "locale_sc": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js.map" + ] + } + }, + "locale_sco": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js.map" + ] + } + }, + "locale_si": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_si-17838170f6bebef2861a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_si-17838170f6bebef2861a.chunk.js.map" + ] + } + }, + "locale_sk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js.map" + ] + } + }, + "locale_sl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js.map" + ] + } + }, + "locale_sq": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js.map" + ] + } + }, + "locale_sr-Latn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js.map" + ] + } + }, + "locale_sr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js.map" + ] + } + }, + "locale_sv": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js.map" + ] + } + }, + "locale_szl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js.map" + ] + } + }, + "locale_ta": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js.map" + ] + } + }, + "locale_tai": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js.map" + ] + } + }, + "locale_te": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js.map" + ] + } + }, + "locale_th": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js.map" + ] + } + }, + "locale_tr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js.map" + ] + } + }, + "locale_tt": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js.map" + ] + } + }, + "locale_ug": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js.map" + ] + } + }, + "locale_uk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js.map" + ] + } + }, + "locale_ur": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js.map" + ] + } + }, + "locale_uz": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_uz-38029008a065795c55b7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_uz-38029008a065795c55b7.chunk.js.map" + ] + } + }, + "locale_vi": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js.map" + ] + } + }, + "locale_zgh": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js.map" + ] + } + }, + "locale_zh-CN": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js.map" + ] + } + }, + "locale_zh-HK": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js.map" + ] + } + }, + "locale_zh-TW": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js.map" + ] + } + }, + "dark": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/dark-a3b88036.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/dark-1e375a968d41797e60af.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/dark-a3b88036.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/dark-1e375a968d41797e60af.chunk.js.map" + ] + } + }, + "contrast": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/contrast-5cabd607.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/contrast-393583c54c3047b1a13c.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/contrast-5cabd607.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/contrast-393583c54c3047b1a13c.chunk.js.map" + ] + } + }, + "mastodon-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/mastodon-light-d9270c4c.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/mastodon-light-d9270c4c.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js.map" + ] + } + }, + "wobbl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-88f067e5.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-88f067e5.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js.map" + ] + } + }, + "wobbl-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-light-aae0a2db.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-light-aae0a2db.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js.map" + ] + } + }, + "modern-dark": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-dark-1cfb4c54.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-dark-1cfb4c54.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js.map" + ] + } + }, + "modern-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-light-1c0258de.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-light-1c0258de.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js.map" + ] + } + }, + "modern-light-wobbl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-light-wobbl-291fe684.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-light-wobbl-291fe684.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js.map" + ] + } + }, + "default": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/default-229799f4.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/default-8b7478aae9e7db81c926.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/default-229799f4.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/default-8b7478aae9e7db81c926.chunk.js.map" + ] + } + }, + "wobbl-old": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-old-41b5a76e.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-old-41b5a76e.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js.map" + ] + } + }, + "wobbl-old-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-old-light-d2f87f38.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-old-light-d2f87f38.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js.map" + ] + } + }, + "modern-dark-wobbl-old": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js.map" + ] + } + }, + "modern-light-wobbl-old": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-light-wobbl-old-50985752.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-light-wobbl-old-50985752.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js.map" + ] + } + } + }, + "error.js": { + "src": "/packs/js/error-9aec4316f262805dbab4.chunk.js", + "integrity": "sha256-h9t4X1Ctr0SuSxvzHAKHvNRPSwxrrY7oebKxIQxySBk=" + }, + "error.js.map": { + "src": "/packs/js/error-9aec4316f262805dbab4.chunk.js.map", + "integrity": "sha256-psF6oQh90Aksct2faHnn75dOrCHWElEs0jeyuzdOPp8=" + }, + "extra_polyfills.js": { + "src": "/packs/js/extra_polyfills-986a5c759c7ce45b20f0.chunk.js", + "integrity": "sha256-IbfbaxmjQpCO96TjxZpwytUa/mDckWLewB3KA2CW0C0=" + }, + "extra_polyfills.js.map": { + "src": "/packs/js/extra_polyfills-986a5c759c7ce45b20f0.chunk.js.map", + "integrity": "sha256-PY8UO/dZvCju1KsxfMJ5z918P4fJfRkSOgfd7iVWzCE=" + }, + "features/about.js": { + "src": "/packs/js/features/about-1780ba5ccec34a6fd8bc.chunk.js", + "integrity": "sha256-GOc4LtB/SlB43XLXfOUJLSDv5ZhOHT9ofr1SpT/RkKc=" + }, + "features/about.js.map": { + "src": "/packs/js/features/about-1780ba5ccec34a6fd8bc.chunk.js.map", + "integrity": "sha256-Yiyme4FMjNsKDMz2Dwzx376SYQzuaPrCGbC6Bs1mD8A=" + }, + "features/account_gallery.js": { + "src": "/packs/js/features/account_gallery-43b9c971f6b5d2fad0ae.chunk.js", + "integrity": "sha256-cojN2LWXi9RVlxiv0w+Cqr04tzZDjL6W9nws7BQRWYA=" + }, + "features/account_gallery.js.map": { + "src": "/packs/js/features/account_gallery-43b9c971f6b5d2fad0ae.chunk.js.map", + "integrity": "sha256-tAiBwyNYx+T7bozkk5lAQhLH4leE4WpijnjF6hX2clI=" + }, + "features/account_timeline.js": { + "src": "/packs/js/features/account_timeline-bd75831a69a631b87bd0.chunk.js", + "integrity": "sha256-FICvdjaT4TOPCOUEubS9eBgEYwKG/Bc2cKORbkN+JlY=" + }, + "features/account_timeline.js.map": { + "src": "/packs/js/features/account_timeline-bd75831a69a631b87bd0.chunk.js.map", + "integrity": "sha256-HVPFzIvJ05spKhZKd5q2ilFSa429O5zV0W+NENh2UIE=" + }, + "features/blocks.js": { + "src": "/packs/js/features/blocks-520befb4cfcc5d3664b7.chunk.js", + "integrity": "sha256-h3/JRMNKljdV2VosjYqWWq8icEHIZ3MlhUKNRYRCC8I=" + }, + "features/blocks.js.map": { + "src": "/packs/js/features/blocks-520befb4cfcc5d3664b7.chunk.js.map", + "integrity": "sha256-AqQB2o3bGyHKlALudU8UQ8SXObCIRhO/N5bRKmDpl8I=" + }, + "features/bookmarked_statuses.js": { + "src": "/packs/js/features/bookmarked_statuses-4f2fd2082497e715db43.chunk.js", + "integrity": "sha256-jmI6y/z+ULcT3lWuNy8x7M3PU5FIv5tTUXiSxM5JPCU=" + }, + "features/bookmarked_statuses.js.map": { + "src": "/packs/js/features/bookmarked_statuses-4f2fd2082497e715db43.chunk.js.map", + "integrity": "sha256-xHRBHocZmyizjGoI7tvqYmTvhZVR18AEYKGneJL6NY4=" + }, + "features/community_timeline.js": { + "src": "/packs/js/features/community_timeline-68ad82d6845040826ad2.chunk.js", + "integrity": "sha256-jv+gzNw8AlMY/JX8bK64u8uf4DtIkyu3xX1OFtFuzx4=" + }, + "features/community_timeline.js.map": { + "src": "/packs/js/features/community_timeline-68ad82d6845040826ad2.chunk.js.map", + "integrity": "sha256-uo0lNTTf0UHSJiukJFvFOczexikwPUGp6XZvzLZOHjQ=" + }, + "features/compose.js": { + "src": "/packs/js/features/compose-42b9ec23ecf1cb253911.chunk.js", + "integrity": "sha256-YB3UEO72JDwiTiTT/jFevc8e37QMlTEfKublUSblzww=" + }, + "features/compose.js.map": { + "src": "/packs/js/features/compose-42b9ec23ecf1cb253911.chunk.js.map", + "integrity": "sha256-4rHUv/3Pdfw5H++FEh1W2z6zQYOLMWs9k24V4Pq4pbA=" + }, + "features/direct_timeline.js": { + "src": "/packs/js/features/direct_timeline-7e13d467a7e34a1c91e8.chunk.js", + "integrity": "sha256-dUCXDUokpyPOAawf8R9Y8k6WfiDS0WRzc6ldO4PmE3c=" + }, + "features/direct_timeline.js.map": { + "src": "/packs/js/features/direct_timeline-7e13d467a7e34a1c91e8.chunk.js.map", + "integrity": "sha256-q/pP26txerzPKBcPt03IEajGHze2XQBIGrsWO2xa+Ow=" + }, + "features/directory.js": { + "src": "/packs/js/features/directory-7e0a4b6e741808cedc7a.chunk.js", + "integrity": "sha256-3yiafpWhsMFOPmYN6ICU4GnR/8I6zZapGiUL2JaXibI=" + }, + "features/directory.js.map": { + "src": "/packs/js/features/directory-7e0a4b6e741808cedc7a.chunk.js.map", + "integrity": "sha256-/awgeVDYw3UBo48wc1s2lfA9JwkNVIV4DlExhzbY2c0=" + }, + "features/domain_blocks.js": { + "src": "/packs/js/features/domain_blocks-08e0f9af26979e7fb010.chunk.js", + "integrity": "sha256-nRKlZm+olWkxsyg15fced2a2Hrz/EgrL1F5COcNkLqw=" + }, + "features/domain_blocks.js.map": { + "src": "/packs/js/features/domain_blocks-08e0f9af26979e7fb010.chunk.js.map", + "integrity": "sha256-v54vgT9BX4eBCqf4SkQd4hLbCxEhBijJ+453F1B9IHE=" + }, + "features/explore.js": { + "src": "/packs/js/features/explore-ebedda7bc800a5976a26.chunk.js", + "integrity": "sha256-KkrLL4KjJ1/nwK1ZBIzviP5dZK9WaHT8TwD2ncH5ugI=" + }, + "features/explore.js.map": { + "src": "/packs/js/features/explore-ebedda7bc800a5976a26.chunk.js.map", + "integrity": "sha256-8lwfc1Y3K++/RpqamsymSaGSwZeIL2PMY786V/PZIMY=" + }, + "features/favourited_statuses.js": { + "src": "/packs/js/features/favourited_statuses-328e07362d25feb2f4aa.chunk.js", + "integrity": "sha256-qgIsFKIuNFqcoRfX8wKeciYT5ZDqZOShCV5NMdGk2z0=" + }, + "features/favourited_statuses.js.map": { + "src": "/packs/js/features/favourited_statuses-328e07362d25feb2f4aa.chunk.js.map", + "integrity": "sha256-1oqKRRDeLzHIlL3u/PZBELMFcQZzlRUjDvcetioF25g=" + }, + "features/favourites.js": { + "src": "/packs/js/features/favourites-1ad8debadf728dd45baa.chunk.js", + "integrity": "sha256-OdsOSwL7Yb8E50tJm5mehZbzqEKnC1A9MSouYqva43Q=" + }, + "features/favourites.js.map": { + "src": "/packs/js/features/favourites-1ad8debadf728dd45baa.chunk.js.map", + "integrity": "sha256-qH4u4yegkprK1kNgAy0pviIHxBIGK75UV+Zo3Ycw/m4=" + }, + "features/follow_recommendations.js": { + "src": "/packs/js/features/follow_recommendations-c33a6a51282ffb98ed74.chunk.js", + "integrity": "sha256-jb1nPq8lPW5iOWbZ2TyjYSxzXr6Ro/0nPlbtY4FFYsU=" + }, + "features/follow_recommendations.js.map": { + "src": "/packs/js/features/follow_recommendations-c33a6a51282ffb98ed74.chunk.js.map", + "integrity": "sha256-Z2kQYh17dXi9l/nqIWDFte1XvfJfMAVnAdQpcg5Mdig=" + }, + "features/follow_requests.js": { + "src": "/packs/js/features/follow_requests-d38d490b8ffaef0b9c1d.chunk.js", + "integrity": "sha256-r2LVVHRVMOwcDr+q6zmlroBo5pJYLPMADpP3NhagpQU=" + }, + "features/follow_requests.js.map": { + "src": "/packs/js/features/follow_requests-d38d490b8ffaef0b9c1d.chunk.js.map", + "integrity": "sha256-1klRMHrS1T/1aNvdj1E+mPDh8mimFkV24apjtT7gph8=" + }, + "features/followed_tags.js": { + "src": "/packs/js/features/followed_tags-40edb1def48ffb16eaad.chunk.js", + "integrity": "sha256-FXJ1K6hnUN/Kg33RKlR2wWJfyT2zNpiIiTFaNREsKS4=" + }, + "features/followed_tags.js.map": { + "src": "/packs/js/features/followed_tags-40edb1def48ffb16eaad.chunk.js.map", + "integrity": "sha256-s9ADcBf1CwjgsNJSRUXadV20mIzUZpDpT/jKVAaXs/Y=" + }, + "features/followers.js": { + "src": "/packs/js/features/followers-da441e6654c2a8725cf9.chunk.js", + "integrity": "sha256-xgQ2szg6cu+lF879A+YvNbA7qmJ//ZWjYtlJmhRxj2U=" + }, + "features/followers.js.map": { + "src": "/packs/js/features/followers-da441e6654c2a8725cf9.chunk.js.map", + "integrity": "sha256-43OmxvB2htNXTK+uFoi8JgoMqsO7qvQC8LLl3UJSV/U=" + }, + "features/following.js": { + "src": "/packs/js/features/following-e3684a6d630329f76e39.chunk.js", + "integrity": "sha256-2awJyRg3GCG5K57dG2AgYa/4yzfG8/5uquFQtMLGEF0=" + }, + "features/following.js.map": { + "src": "/packs/js/features/following-e3684a6d630329f76e39.chunk.js.map", + "integrity": "sha256-3ae2xZSiNHCzBPqHdRmka8+u85PB3YeBRZxc14+r1zw=" + }, + "features/generic_not_found.js": { + "src": "/packs/js/features/generic_not_found-89f2836a6221235141be.chunk.js", + "integrity": "sha256-e9D7skCXophOpTG6HdFvu/7K4/7xWEHjtIBggz9Ep2w=" + }, + "features/generic_not_found.js.map": { + "src": "/packs/js/features/generic_not_found-89f2836a6221235141be.chunk.js.map", + "integrity": "sha256-6MDE5LFvRKSetIjrYWoBIieX4j6lAezLdxysNlBlB9o=" + }, + "features/getting_started.js": { + "src": "/packs/js/features/getting_started-1b714b058a8b2a8d3a62.chunk.js", + "integrity": "sha256-dsYg+PR/1R2PJY/b6H+0Z1bCPHPuXcbLnGmHcoy9lfk=" + }, + "features/getting_started.js.map": { + "src": "/packs/js/features/getting_started-1b714b058a8b2a8d3a62.chunk.js.map", + "integrity": "sha256-dGaJ1xbFzEfeEm24YSEhs6IwL/Cs99mjRgIMZ8oWB44=" + }, + "features/hashtag_timeline.js": { + "src": "/packs/js/features/hashtag_timeline-eeafb06a34c51d00c0fe.chunk.js", + "integrity": "sha256-cxr3cKXFKh2GZTZ9frq4oMrcN3lGdzSUwvywXV+ewFM=" + }, + "features/hashtag_timeline.js.map": { + "src": "/packs/js/features/hashtag_timeline-eeafb06a34c51d00c0fe.chunk.js.map", + "integrity": "sha256-87Z1nZRZH0RY5iEWroV/VFh5UQOsp+ZmUC9sCRQIc4k=" + }, + "features/home_timeline.js": { + "src": "/packs/js/features/home_timeline-929f3815cc493564611a.chunk.js", + "integrity": "sha256-tD2dR6Y7JA/7VoTsYgjMOOVU4z37u5DQkMsydI45uvQ=" + }, + "features/home_timeline.js.map": { + "src": "/packs/js/features/home_timeline-929f3815cc493564611a.chunk.js.map", + "integrity": "sha256-RW7Q9irq3tG1bYzC2XF4FqJxV9yiFoeHsJkB7i6caMM=" + }, + "features/keyboard_shortcuts.js": { + "src": "/packs/js/features/keyboard_shortcuts-83eb9db76d2c748ae986.chunk.js", + "integrity": "sha256-6JrzbtFclxD4tKs9OfThaT8oJMyAapOc2hkHT4KQQ7g=" + }, + "features/keyboard_shortcuts.js.map": { + "src": "/packs/js/features/keyboard_shortcuts-83eb9db76d2c748ae986.chunk.js.map", + "integrity": "sha256-DnTrSlVz2kWspCeevgE+ucqJTr+DceEppa8Ukdg5NQE=" + }, + "features/list_adder.js": { + "src": "/packs/js/features/list_adder-694c55136cb9b44a857c.chunk.js", + "integrity": "sha256-9u2oKtOjK824n715L+SrDLsWpVYpXbRF0UFrJIkO/iM=" + }, + "features/list_adder.js.map": { + "src": "/packs/js/features/list_adder-694c55136cb9b44a857c.chunk.js.map", + "integrity": "sha256-fNZoayKBziG9tDymet/aYa7394N1VjjyH0vUZL2FzNo=" + }, + "features/list_editor.js": { + "src": "/packs/js/features/list_editor-9438254dac1fae33280d.chunk.js", + "integrity": "sha256-UHvkiQNbQrk/6/d3Tn7qF8z63kPVyBiDNNmIxj6yi8s=" + }, + "features/list_editor.js.map": { + "src": "/packs/js/features/list_editor-9438254dac1fae33280d.chunk.js.map", + "integrity": "sha256-0EMMbm/RdSV1ERHtp+OYKXecWE1/54J68YyRXxJo+wU=" + }, + "features/list_timeline.js": { + "src": "/packs/js/features/list_timeline-f796e1b02420e7a919ea.chunk.js", + "integrity": "sha256-7qvKQAdrdcCJO93zvLC6ZN3pKZFWw3uSC/BquE7Jq7I=" + }, + "features/list_timeline.js.map": { + "src": "/packs/js/features/list_timeline-f796e1b02420e7a919ea.chunk.js.map", + "integrity": "sha256-9ExEg86aMLYrQQUOr/auZ3psdRfhYV37YwTx3GCna5M=" + }, + "features/lists.js": { + "src": "/packs/js/features/lists-acaa219c64ce85b1ee60.chunk.js", + "integrity": "sha256-cmbriFBNRMkdUTmvZ4D7BdojybIqKtm+DqJdZ5y8NHA=" + }, + "features/lists.js.map": { + "src": "/packs/js/features/lists-acaa219c64ce85b1ee60.chunk.js.map", + "integrity": "sha256-r+YX3FidnaAi2rrT1LzNRds2TVPLwA32LTNtsVtYDv0=" + }, + "features/mutes.js": { + "src": "/packs/js/features/mutes-f1313ec5af4e39f4dc9c.chunk.js", + "integrity": "sha256-xPNUwkLdfVUqawKE74uOT3wEGp/QWmL6BJP/W2Eke0E=" + }, + "features/mutes.js.map": { + "src": "/packs/js/features/mutes-f1313ec5af4e39f4dc9c.chunk.js.map", + "integrity": "sha256-NK4YJEpjdUgryhZcy2e22b0dB0rp0ZNYVx7sWFVmzgc=" + }, + "features/notifications.js": { + "src": "/packs/js/features/notifications-2c51c8a4a8ccc70a63c0.chunk.js", + "integrity": "sha256-kB/pbIR155eRRtEVDVYkSLXBGioCTLL8uyVKusxPE8Q=" + }, + "features/notifications.js.map": { + "src": "/packs/js/features/notifications-2c51c8a4a8ccc70a63c0.chunk.js.map", + "integrity": "sha256-bZMwQmrdY8ZUMqzbQq9i9q411dRio4Sz1VT9qQvkRHQ=" + }, + "features/pinned_statuses.js": { + "src": "/packs/js/features/pinned_statuses-afc39764d48b37b80ba6.chunk.js", + "integrity": "sha256-l2jVvcI5OI7PdMC8pRd+kwcgF166Z/v65Ehs4kj94FA=" + }, + "features/pinned_statuses.js.map": { + "src": "/packs/js/features/pinned_statuses-afc39764d48b37b80ba6.chunk.js.map", + "integrity": "sha256-babaIJH3mvEIVCBOFbnMYOrcof2ypI03mXecroTM6wk=" + }, + "features/privacy_policy.js": { + "src": "/packs/js/features/privacy_policy-98df21ce8d336a5c909f.chunk.js", + "integrity": "sha256-qlWFdthfeuL4BTYMPaz95uEMBPry2fZzwdXLJaGLxC8=" + }, + "features/privacy_policy.js.map": { + "src": "/packs/js/features/privacy_policy-98df21ce8d336a5c909f.chunk.js.map", + "integrity": "sha256-DhcegLw8YuA8hyTrTMzyntPoJ36CCueI5tQjD8z6+/U=" + }, + "features/public_timeline.js": { + "src": "/packs/js/features/public_timeline-3c694db7db09581f9814.chunk.js", + "integrity": "sha256-kEfDWogw0052Hwsk4qiWYuj5pFat+WFVDmMdg/R39mE=" + }, + "features/public_timeline.js.map": { + "src": "/packs/js/features/public_timeline-3c694db7db09581f9814.chunk.js.map", + "integrity": "sha256-rTlpNO1SnLlgp5eQN1jXFRnSsLOq7nNGFk9WLGcfcXA=" + }, + "features/reblogs.js": { + "src": "/packs/js/features/reblogs-e61e4f722a862d2d1bf3.chunk.js", + "integrity": "sha256-3i1xZsxguhO+gjcxs91o0hKJOOKYM86PrwRArvYWp4Q=" + }, + "features/reblogs.js.map": { + "src": "/packs/js/features/reblogs-e61e4f722a862d2d1bf3.chunk.js.map", + "integrity": "sha256-kFsPnFNZAaGVhEVtysCGXyPvfOXJ273lXH47Cf5fFKc=" + }, + "features/status.js": { + "src": "/packs/js/features/status-b229e1d9012139273e09.chunk.js", + "integrity": "sha256-D5N9sUhZ/rWhAi1cJMEOeNWikDIXDKx4H7TqVLBFG5k=" + }, + "features/status.js.map": { + "src": "/packs/js/features/status-b229e1d9012139273e09.chunk.js.map", + "integrity": "sha256-wZ8uluF2bKCDdsMXuswQBbr8sMxzFfgyeAkGY6qdxhQ=" + }, + "js/1-4f08bea894e3d7ced52a.chunk.js": { + "src": "/packs/js/1-4f08bea894e3d7ced52a.chunk.js", + "integrity": "sha256-W6au4yjVCPby2YZpuzRWaZaUB2ByDrDxaTpGwbyG540=" + }, + "js/1-4f08bea894e3d7ced52a.chunk.js.map": { + "src": "/packs/js/1-4f08bea894e3d7ced52a.chunk.js.map", + "integrity": "sha256-owtIty3jsLF/knrVLfl4P166wXe/ONz91SZqA3k5Fec=" + }, + "js/173-91bb2c0776a21ff5f203.chunk.js": { + "src": "/packs/js/173-91bb2c0776a21ff5f203.chunk.js", + "integrity": "sha256-Nm9RxdRKVGq32UFYV5yb+7K2ikWzBDYyTg/XrUjRIQg=" + }, + "js/173-91bb2c0776a21ff5f203.chunk.js.map": { + "src": "/packs/js/173-91bb2c0776a21ff5f203.chunk.js.map", + "integrity": "sha256-y8KUC8NiFHFS3+zg71VETNXObdZereqlem4sFNSK3aE=" + }, + "js/174-5d5b87c3cf374832f4c6.chunk.js": { + "src": "/packs/js/174-5d5b87c3cf374832f4c6.chunk.js", + "integrity": "sha256-PPMJpNfW8myDvafLzZicuUVc9RWJQBzccu+Rry0nvlU=" + }, + "js/174-5d5b87c3cf374832f4c6.chunk.js.map": { + "src": "/packs/js/174-5d5b87c3cf374832f4c6.chunk.js.map", + "integrity": "sha256-+fr/c4UKYS2JSS8xEjNgxIp/wKCkv+pivvZ53Zz1tQ0=" + }, + "js/175-44abe411af23889c1804.chunk.js": { + "src": "/packs/js/175-44abe411af23889c1804.chunk.js", + "integrity": "sha256-r520lpv8O8RN3V0DOECych6Xxoeez7XphWlS1fDgu3Y=" + }, + "js/175-44abe411af23889c1804.chunk.js.map": { + "src": "/packs/js/175-44abe411af23889c1804.chunk.js.map", + "integrity": "sha256-D0wkWkNfdjnKtI3b7723pIuiWViwA3+4jZp9VhuI+nk=" + }, + "js/2-7904cb94a6d1b97a570c.chunk.js": { + "src": "/packs/js/2-7904cb94a6d1b97a570c.chunk.js", + "integrity": "sha256-aX3q1iy18AG+/w+JT7eUzI0md73PA+zvnQVhNtHqRWc=" + }, + "js/2-7904cb94a6d1b97a570c.chunk.js.map": { + "src": "/packs/js/2-7904cb94a6d1b97a570c.chunk.js.map", + "integrity": "sha256-52FGTK+9me8SOgLDvhK8YA8/mIZdGxIB1/vfse2nrH8=" + }, + "js/3-7e9194f0476ed145bc37.chunk.js": { + "src": "/packs/js/3-7e9194f0476ed145bc37.chunk.js", + "integrity": "sha256-Fm/nlqhYCpByMII2ILlnLR7bXc4BiIhjj5jph8cdVeE=" + }, + "js/3-7e9194f0476ed145bc37.chunk.js.map": { + "src": "/packs/js/3-7e9194f0476ed145bc37.chunk.js.map", + "integrity": "sha256-hnLi4iRuYaPFmYudBS2dKYW5x59qmhufHN3ephGh4Wk=" + }, + "js/4-30ed5e9610faa481148c.chunk.js": { + "src": "/packs/js/4-30ed5e9610faa481148c.chunk.js", + "integrity": "sha256-Hvj2lO4/74ZP0t7RO222lK1+QCtWR4KHOR/AYklrK/0=" + }, + "js/4-30ed5e9610faa481148c.chunk.js.map": { + "src": "/packs/js/4-30ed5e9610faa481148c.chunk.js.map", + "integrity": "sha256-KOv05CDwEcvXl6aTXqfkG0jyfprzpAZmdk4FFT5f/U4=" + }, + "js/5-048aaf12b2f542259d73.chunk.js": { + "src": "/packs/js/5-048aaf12b2f542259d73.chunk.js", + "integrity": "sha256-wix30LF7d/ZfUnsQaNpXoZQMu0r1ndcWJoHOtnncWV4=" + }, + "js/5-048aaf12b2f542259d73.chunk.js.map": { + "src": "/packs/js/5-048aaf12b2f542259d73.chunk.js.map", + "integrity": "sha256-cJ+cveLA+i7dfi+W/fF2WI7sO4Kph7wVTMlLwltFk0w=" + }, + "js/common-9da33dbc9762ba5fb40c.js.LICENSE.txt": { + "src": "/packs/js/common-9da33dbc9762ba5fb40c.js.LICENSE.txt", + "integrity": "sha256-hWo228Md1YZAmYGmNqneO3nDiy30YDNXCW9VfXHNi10=" + }, + "locale_af.js": { + "src": "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js", + "integrity": "sha256-WR6imeagC/fGqDrh3sNFizJCj/XufMNvFDiMeuJYq38=" + }, + "locale_af.js.map": { + "src": "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js.map", + "integrity": "sha256-6OSJijYWu+6ZuviYVvLCCPvoqWoZQGKGe915xOrU7fo=" + }, + "locale_an.js": { + "src": "/packs/js/locale_an-7042264d7263706588ca.chunk.js", + "integrity": "sha256-cAxeY9HS2+KP5+DFRTalgrZ58te3oxYY8e8C/GmgU9k=" + }, + "locale_an.js.map": { + "src": "/packs/js/locale_an-7042264d7263706588ca.chunk.js.map", + "integrity": "sha256-TIqCy6vAeWTun8DHpdsIg/d1iXSHX+nrTbOYoMeeKeo=" + }, + "locale_ar.js": { + "src": "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js", + "integrity": "sha256-Hw/mGiKXwVbjCPBFyeKEshWELXbJ3dZTREHDON6SlbM=" + }, + "locale_ar.js.map": { + "src": "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js.map", + "integrity": "sha256-5KzvXP9MwbDlSQOoBKvK3v7O1BYE2lG0SGWWHdJQNe8=" + }, + "locale_ast.js": { + "src": "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js", + "integrity": "sha256-JUj5MgrxCyYEm5qJpksQ8KkA4HXYogB4ykDT3VB7jsg=" + }, + "locale_ast.js.map": { + "src": "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js.map", + "integrity": "sha256-c71oAoERZwNiAAVmefjYGm2+eYTpIn9A+i4/Al/yzQI=" + }, + "locale_be.js": { + "src": "/packs/js/locale_be-2b73894a107f7474274e.chunk.js", + "integrity": "sha256-2vwj92qeICaX7xdKZlwWZUbb7H7POmu4x7HUFflGHUA=" + }, + "locale_be.js.map": { + "src": "/packs/js/locale_be-2b73894a107f7474274e.chunk.js.map", + "integrity": "sha256-KA1A3nBLys0vAW0FGLvxlw6oG/JoCZN25yl/G3IK3OA=" + }, + "locale_bg.js": { + "src": "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js", + "integrity": "sha256-hhlhzvxCFmntuyqCqQLuyZGEjXNCkxe0yh/T1+448Lo=" + }, + "locale_bg.js.map": { + "src": "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js.map", + "integrity": "sha256-QTTQrVU+O6DlvKzE9/NHzJR1mdfY65v+Jv4u6WTZoRI=" + }, + "locale_bn.js": { + "src": "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js", + "integrity": "sha256-dOY/E8CVwGQ21CzN8ww7YqWcnpSFAuk6UP865s1ugwM=" + }, + "locale_bn.js.map": { + "src": "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js.map", + "integrity": "sha256-nwULTJvuuJ9nUCnzp3PRwpsKRG5AewuTYc9FLrndGco=" + }, + "locale_br.js": { + "src": "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js", + "integrity": "sha256-W73qBtotwAWoe6i8l0LgyyTn7cHSufvN6m0B3qtRoG8=" + }, + "locale_br.js.map": { + "src": "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js.map", + "integrity": "sha256-4O+Rbrui0yZSjO2olJFYWSbnVFOVC0rBaYUUM7AsNcg=" + }, + "locale_bs.js": { + "src": "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js", + "integrity": "sha256-N3Y0DqjCIlkjV/e75wXyXuf+1VwZmf3ti1eWImdZcPM=" + }, + "locale_bs.js.map": { + "src": "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js.map", + "integrity": "sha256-x1D4TDyF46bKKVZT5VihyNJxFuDYBI69auVt9oL8Hn8=" + }, + "locale_ca.js": { + "src": "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js", + "integrity": "sha256-iAcMn2aFTDLSZXZkG1pSZ+LDP0GYB1t0NN6euMjk52A=" + }, + "locale_ca.js.map": { + "src": "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js.map", + "integrity": "sha256-WHzVXq6bXJFtYr1m9RYUy9bXrHjhYQ2nQZUgx64LtgY=" + }, + "locale_ckb.js": { + "src": "/packs/js/locale_ckb-bac2365515303c579326.chunk.js", + "integrity": "sha256-nl2/+tYeeTqnlnM2uaXgGXnsqkLJuDrVHS/I8o+gTeg=" + }, + "locale_ckb.js.map": { + "src": "/packs/js/locale_ckb-bac2365515303c579326.chunk.js.map", + "integrity": "sha256-2VFhqwDHmPVjoAJ5QUQsOJiTZU7hf3ERNxe0BBMztmM=" + }, + "locale_co.js": { + "src": "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js", + "integrity": "sha256-1xTLG/9ZESJSBJVagHoTvPjSQ9/+5ArYUtOzWSmHxlo=" + }, + "locale_co.js.map": { + "src": "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js.map", + "integrity": "sha256-pZbO05d87UrxDKTeyxSmYyldO2o2TUtu7woepeortYE=" + }, + "locale_cs.js": { + "src": "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js", + "integrity": "sha256-dtcupSFSPA1KQkLyC2Qvswz3zJahQtFbLJAT3WC5lKs=" + }, + "locale_cs.js.map": { + "src": "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js.map", + "integrity": "sha256-PWwZGNYeGlpnkrom0nIFKAX0QSclhc2uZKPdjaQaSWA=" + }, + "locale_csb.js": { + "src": "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js", + "integrity": "sha256-J4jWNRkrOloMRSZUXmGZiLV5UVbZTOFmNd2y7zBCygM=" + }, + "locale_csb.js.map": { + "src": "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js.map", + "integrity": "sha256-MIH/2lcke3Jpc2kUbW5qrmydm/uajVrVlgt6MBkts9A=" + }, + "locale_cy.js": { + "src": "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js", + "integrity": "sha256-iTWuSdqhqE867oEfXNN0Dib5a5p5zLDK/t02Zt0/Leo=" + }, + "locale_cy.js.map": { + "src": "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js.map", + "integrity": "sha256-JMIERda8hWQujDYv6Swi4UO4x89969r4y7rJ40fV7kI=" + }, + "locale_da.js": { + "src": "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js", + "integrity": "sha256-cz+s9fp1ipoJ/wI9LRW4npf8vcyN0UVt3O3F91gex6Q=" + }, + "locale_da.js.map": { + "src": "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js.map", + "integrity": "sha256-eiZEPeDlBlSEK8mcC5LhE2sPCk6QhBib9QXbFMHR2f0=" + }, + "locale_de.js": { + "src": "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js", + "integrity": "sha256-zODoZZhLwmOBCHv0OSBpB0DjSscp+/JzG7dIWoh8dIA=" + }, + "locale_de.js.map": { + "src": "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js.map", + "integrity": "sha256-xmyIlEvliCIoiFQoS7uSx7CX09YiBIS/lrY23s9GjGo=" + }, + "locale_el.js": { + "src": "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js", + "integrity": "sha256-z9n58WLCj40IQo16slVtLfK/NKhLLIurr70WReLuI/E=" + }, + "locale_el.js.map": { + "src": "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js.map", + "integrity": "sha256-66Mg9bS70qeSF4AjDhRjZ/3C2PElQ/vKepSBd+Px/E0=" + }, + "locale_en-GB.js": { + "src": "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js", + "integrity": "sha256-SALgj+/GpFcOXNUnpTU5DqDo2ufixeAYKDvbzkCAtZE=" + }, + "locale_en-GB.js.map": { + "src": "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js.map", + "integrity": "sha256-nF9uKaWaheXfvcgQYBOcQ/ajnZDKXouwDzAi/mcDTlk=" + }, + "locale_en.js": { + "src": "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js", + "integrity": "sha256-cT1gYpk/YsvJCEZlFtqKFsblKN2t+5zHKooixAp+TUI=" + }, + "locale_en.js.map": { + "src": "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js.map", + "integrity": "sha256-R6Gj+NXGMEGxTxq4DqUWgzxq9+aPglyaMG1ADIgWT3o=" + }, + "locale_eo.js": { + "src": "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js", + "integrity": "sha256-H3iZ9xIQ1eagIdYH7iBoVuRFgVDAxBj6hiShdZySSYc=" + }, + "locale_eo.js.map": { + "src": "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js.map", + "integrity": "sha256-Ae9mMI4P01MM4QDJf5tSWzcCvB9n+qIyMTHWv+lApk4=" + }, + "locale_es-AR.js": { + "src": "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js", + "integrity": "sha256-gqbdgNdLPcRTageIejS73It5jWU9xW5necdFrAX1WYU=" + }, + "locale_es-AR.js.map": { + "src": "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js.map", + "integrity": "sha256-8KON1RnBdnDUWvXViHepR28l/8HqZNdMlaN8HX81t6o=" + }, + "locale_es-MX.js": { + "src": "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js", + "integrity": "sha256-AiQb14GSBQ0NtoeqdDvPbC7KTKxgAZwYlKMZ3T0peDE=" + }, + "locale_es-MX.js.map": { + "src": "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js.map", + "integrity": "sha256-HLLsGDqLDYnZR4i1EBZiii3Dv7xL7TCee7DlkkwofMw=" + }, + "locale_es.js": { + "src": "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js", + "integrity": "sha256-l1EDProxifZUfo0sSWq46toIIygJYxsNa9MSqoQEHhI=" + }, + "locale_es.js.map": { + "src": "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js.map", + "integrity": "sha256-qSg+GX+ju4hEJrYKs/S3doD+bqK5CNweEh/bQbs9d6Q=" + }, + "locale_et.js": { + "src": "/packs/js/locale_et-9957864e54462b54bd25.chunk.js", + "integrity": "sha256-E6ET/WSdz9LyvaS8yIKJ+vhdCz1CnRwvKRnknE2hrMM=" + }, + "locale_et.js.map": { + "src": "/packs/js/locale_et-9957864e54462b54bd25.chunk.js.map", + "integrity": "sha256-Q7TDj3rWzKKaiNuwpZQ3BnVx7afghd4aEiHuSseF8pE=" + }, + "locale_eu.js": { + "src": "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js", + "integrity": "sha256-ZoVoUf01U07qYF8uhXmOnPwAQqFFzrrkzgZdlgrmNV4=" + }, + "locale_eu.js.map": { + "src": "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js.map", + "integrity": "sha256-Gs5ujTHebd7kPKbldzobEDmLc42YnE4qNfjzNtVBmpw=" + }, + "locale_fa.js": { + "src": "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js", + "integrity": "sha256-zIVyyyumrPfe7LsT/hhALqt46i4I2AeNF1VdC3Vfo2M=" + }, + "locale_fa.js.map": { + "src": "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js.map", + "integrity": "sha256-462Z8TfMtQrbChC1VDKE4NdrdxiTexLOLXansI2WZ+c=" + }, + "locale_fi.js": { + "src": "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js", + "integrity": "sha256-+DDW231rtFLvAmI0sdkuEmKVvdSbGzV+LQ3htlk/NKQ=" + }, + "locale_fi.js.map": { + "src": "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js.map", + "integrity": "sha256-Byf9vSW7/p63+SpFwdVkDAk7yQvKZV9ouNKPIzmEUlM=" + }, + "locale_fo.js": { + "src": "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js", + "integrity": "sha256-gT1g4PAUd4cpKgSF9Zag0n4tywbMN29j/s3+ZnxXyMY=" + }, + "locale_fo.js.map": { + "src": "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js.map", + "integrity": "sha256-GxleTbIpCfE3+GXo0tEPsB9q2K73NDOnP73dPmWHmP0=" + }, + "locale_fr-QC.js": { + "src": "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js", + "integrity": "sha256-///I5zl62oZGmK2ynRp+dzCh0+GMXItPy2dzmEeROKU=" + }, + "locale_fr-QC.js.map": { + "src": "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js.map", + "integrity": "sha256-p0lX1t+NiAXkzBNLpb+3fwgDG5pGgqeGz3yx4tMyE+w=" + }, + "locale_fr.js": { + "src": "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js", + "integrity": "sha256-hDSDncSCcNjzG4MJ9KaVKPEIkiOMp/YOFBPGphs3hGY=" + }, + "locale_fr.js.map": { + "src": "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js.map", + "integrity": "sha256-70OHPL8PIWcGVkRupKigT/u+ydbVa5flkZUtOfCUFro=" + }, + "locale_fy.js": { + "src": "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js", + "integrity": "sha256-Z42P5P67PA6P3FV7oSKXtM/OZa+yGRGNC1Z2eGr+sU8=" + }, + "locale_fy.js.map": { + "src": "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js.map", + "integrity": "sha256-Es6HCxEO7mcdMDFVvjfWKp8Gqlb4X+ugm+f3H+qCbxM=" + }, + "locale_ga.js": { + "src": "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js", + "integrity": "sha256-YNLKbLfg2muzu9T/qa6s1JRum6NPQBLcMXxdDA7Tedk=" + }, + "locale_ga.js.map": { + "src": "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js.map", + "integrity": "sha256-w1uMZHqxD2lkg9xr65z19fumPnnLuMkTUcYsknO9l34=" + }, + "locale_gd.js": { + "src": "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js", + "integrity": "sha256-zROzrkQA0Xe9joJbt6gHyQkg5mKxOdhHA4Afn20IXPM=" + }, + "locale_gd.js.map": { + "src": "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js.map", + "integrity": "sha256-78pscx7tXZJ3mXCgWY3gZy0vWIL8r/pfGvxyqYsor1Q=" + }, + "locale_gl.js": { + "src": "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js", + "integrity": "sha256-oYj5S+SMwtuXuUDAe64jAQAhOZGsO2zhtSGFMd34JU4=" + }, + "locale_gl.js.map": { + "src": "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js.map", + "integrity": "sha256-3H9lSRGbru/3MODU74CWTqYt9qOeSBnlW2Gjq3gkLdI=" + }, + "locale_he.js": { + "src": "/packs/js/locale_he-940c5914bccd89572a87.chunk.js", + "integrity": "sha256-qJJGuBnFhz9aKi+Vpzk53qLoUkX84E6G5f1Z4sIac6s=" + }, + "locale_he.js.map": { + "src": "/packs/js/locale_he-940c5914bccd89572a87.chunk.js.map", + "integrity": "sha256-B6nhxDzy7nhgnc715B+351rt70wLmURUaM/hIxpGFho=" + }, + "locale_hi.js": { + "src": "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js", + "integrity": "sha256-nVi8zJud6mqM0+namCZYZODKkfIpwDMom+qTrKaewsg=" + }, + "locale_hi.js.map": { + "src": "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js.map", + "integrity": "sha256-2i13JQaVXothK19ESqYHEMp6UsxiBXDwiXbX3TNIdtg=" + }, + "locale_hr.js": { + "src": "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js", + "integrity": "sha256-BWOd3SUq/wnXbc6sKn7U5ZCw/TSgtbh5YPdn+V7bZek=" + }, + "locale_hr.js.map": { + "src": "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js.map", + "integrity": "sha256-wKp/7BM243tHBp7xq+xJzJrCKkuDv8PByF/lmdbRRR0=" + }, + "locale_hu.js": { + "src": "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js", + "integrity": "sha256-gJVl/VVtSBLTA6yZqvOxYiDJyV3bTFfZ5tz9Gd0NE+Q=" + }, + "locale_hu.js.map": { + "src": "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js.map", + "integrity": "sha256-ptYfpIkVQsy20P+zVlEZk1avLcRLZ83h22HO5dgLrHc=" + }, + "locale_hy.js": { + "src": "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js", + "integrity": "sha256-mAkZBjgQ7WUIMG7kUDnGgD/k2IwbKgEmU/hUsISIljs=" + }, + "locale_hy.js.map": { + "src": "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js.map", + "integrity": "sha256-uFswh5tMkmtBqFA4P+Em/FgE/eAKJhxouZCFdFik8yU=" + }, + "locale_id.js": { + "src": "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js", + "integrity": "sha256-9AtjWka/o0CuxiaOhPnEq35j/8GzPzhb94+bOjvRqsQ=" + }, + "locale_id.js.map": { + "src": "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js.map", + "integrity": "sha256-uHO+r3+1E69NKt3UT/oM++rA4C6CKDFdYvPka1Lw5ms=" + }, + "locale_ig.js": { + "src": "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js", + "integrity": "sha256-892yjlk32mTQlZRSEoinSvBI6hZHW/yDxDLhvPe8JRo=" + }, + "locale_ig.js.map": { + "src": "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js.map", + "integrity": "sha256-eHEffHKwbFg3k+L2LBjLk5LeELTaqdnmaWe/mfv6mEU=" + }, + "locale_io.js": { + "src": "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js", + "integrity": "sha256-qEqFzG2D6xWeF6FaIEpfSC8yX41jhZEwwlkmQukCKIU=" + }, + "locale_io.js.map": { + "src": "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js.map", + "integrity": "sha256-6wKSxTQMpu2kpR10ZOCkkIz48VSOgDglLnkRdSDCdgc=" + }, + "locale_is.js": { + "src": "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js", + "integrity": "sha256-VZC+bpd5yxqicwxsxWRl04TcIgeRZmKKRBcRITacBM4=" + }, + "locale_is.js.map": { + "src": "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js.map", + "integrity": "sha256-DEWCUNv3AMD3+l/jzgxFRMobwbkqjSK+TJHmWC2YRXo=" + }, + "locale_it.js": { + "src": "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js", + "integrity": "sha256-Xa+ihJQLe3hnNAoshuYAvNcTH2K4aPoBTPAzmQiVUvI=" + }, + "locale_it.js.map": { + "src": "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js.map", + "integrity": "sha256-HVnmjnZOlVQMwlb9WiZMBLRVN4PPACCk356vlb7ypHY=" + }, + "locale_ja.js": { + "src": "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js", + "integrity": "sha256-8XvJlY0fub4UupoXHT6jo7+ASLQp3JupbX5GmUJMDqM=" + }, + "locale_ja.js.map": { + "src": "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js.map", + "integrity": "sha256-VlWSQXEcP15ci/vYYUuQ/K1Vz2kqNkPxN7btUnl1qhI=" + }, + "locale_ka.js": { + "src": "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js", + "integrity": "sha256-q86D1tdb0P3hQYt9RwTrCqUvFFVSs7loEh72LNXWAsQ=" + }, + "locale_ka.js.map": { + "src": "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js.map", + "integrity": "sha256-j5rUU6Aoh2Y6Xu/l2+0XJ2/p4rND5F/wAM/8/6Jh4KU=" + }, + "locale_kab.js": { + "src": "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js", + "integrity": "sha256-kWrUEVGGbXnWkUIcts8AVHtEtWczDqNSZbsvVuqtseE=" + }, + "locale_kab.js.map": { + "src": "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js.map", + "integrity": "sha256-UHKTJekLW0cItmEXKTdEpOeeYPMx2hFSmxz+5phDBfc=" + }, + "locale_kk.js": { + "src": "/packs/js/locale_kk-806df7189017998308a3.chunk.js", + "integrity": "sha256-560YKdh7m3hFb1G68O5mxv4j8uQ400bYQ3B4v4otkS8=" + }, + "locale_kk.js.map": { + "src": "/packs/js/locale_kk-806df7189017998308a3.chunk.js.map", + "integrity": "sha256-DTHcpplTt9+xpZlicWZj95nMH9VXhvXTIK090ABlYcI=" + }, + "locale_kn.js": { + "src": "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js", + "integrity": "sha256-FrZsZa8BtgCfMI07LCVABYravZvDxtjCRPxIc4VK8Aw=" + }, + "locale_kn.js.map": { + "src": "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js.map", + "integrity": "sha256-u+GHLhMc89xc0ySLueaXEeILlfthfCuXWfd/0B99z4A=" + }, + "locale_ko.js": { + "src": "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js", + "integrity": "sha256-+bXL++ooHtepnflO4DyGWwkTBlUPg8bzWC5gzN36XtU=" + }, + "locale_ko.js.map": { + "src": "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js.map", + "integrity": "sha256-7LNkDvPbgP4qml+dbiUuQ4qLxgArM3bwYFdg39pPJ9U=" + }, + "locale_ku.js": { + "src": "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js", + "integrity": "sha256-hU462/kg1/2VQ1Gg3oGgD1W3RRFYoSGXAo1P8vTI2GM=" + }, + "locale_ku.js.map": { + "src": "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js.map", + "integrity": "sha256-t7oIP4/uCs8RiriVKYrVJ0WLsWAuvRLrNXDzXgBRk+8=" + }, + "locale_kw.js": { + "src": "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js", + "integrity": "sha256-WNhO1QGY7JJZHuPCx3OCYFfwLViM9YP+I44MTuUnDBc=" + }, + "locale_kw.js.map": { + "src": "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js.map", + "integrity": "sha256-uyzHkO6x6JzWW05euj34D91o4USpXVVhQOmC+dqDeVc=" + }, + "locale_la.js": { + "src": "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js", + "integrity": "sha256-eSTZPsf4wIuMixsm5u3knQRAHVNqMyojtFd8/QrZU34=" + }, + "locale_la.js.map": { + "src": "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js.map", + "integrity": "sha256-mOWYO0YM5ubqnfaEqcvG1MDFXZ5YOrFqurJauGWJuC4=" + }, + "locale_lt.js": { + "src": "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js", + "integrity": "sha256-LfJeBSBiQjM/e1oACIYpZ/fzbF2ZLimrzZmb+ApDHBE=" + }, + "locale_lt.js.map": { + "src": "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js.map", + "integrity": "sha256-bahnWd6k0cdky+IEhVVK/2anKl+Oeck8Ol3CMN17fJI=" + }, + "locale_lv.js": { + "src": "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js", + "integrity": "sha256-B7bhgmKY26kmabsQ9ZepstxwaAcSpFVPHgxTn0lwJTU=" + }, + "locale_lv.js.map": { + "src": "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js.map", + "integrity": "sha256-kMl+o/yrHG8S6sqhr2gb6n89xU4Ghda19byu/IFBVOw=" + }, + "locale_mk.js": { + "src": "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js", + "integrity": "sha256-P9boDty9aUCVUHPnA5UqhoQQBIJxbVXnGo0mHK2fGiE=" + }, + "locale_mk.js.map": { + "src": "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js.map", + "integrity": "sha256-fcx3Q1Vy8/e9hGPQCOCj/UoqUcBJK/2ZGBDuQYhw10A=" + }, + "locale_ml.js": { + "src": "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js", + "integrity": "sha256-89f1wpr/+YYear+ad39veBD9n//2LG4cI/JcCZnthoI=" + }, + "locale_ml.js.map": { + "src": "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js.map", + "integrity": "sha256-z9dkFEQvtEYc4VAtG/203FUXNjb1OlzoMj/4yEgpz+c=" + }, + "locale_mr.js": { + "src": "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js", + "integrity": "sha256-TlfVKlsbC4OzKOLnxu9mCU/KiEG1/3YxED2o6kblbW4=" + }, + "locale_mr.js.map": { + "src": "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js.map", + "integrity": "sha256-jRbayXpXZBeZDHQhvMtR325FkInsR5inyNomL8Bd29o=" + }, + "locale_ms.js": { + "src": "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js", + "integrity": "sha256-3FMp+t3nQ4KEzIGuvBc87NyUuy+eiGdmRgpDnjOoMPI=" + }, + "locale_ms.js.map": { + "src": "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js.map", + "integrity": "sha256-/Tqid9TrvSHr3G97ne0VeBRDljHVs8ap2aAZ1XpzTh4=" + }, + "locale_my.js": { + "src": "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js", + "integrity": "sha256-BOiX+nljOxQzkmoLl1F+dlJiQfFrkEwxsmBx0QAH2m8=" + }, + "locale_my.js.map": { + "src": "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js.map", + "integrity": "sha256-Q3tc/toGURY/rOkSc91RpX1u+jjM9Na09Ptd+KJZna8=" + }, + "locale_nl.js": { + "src": "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js", + "integrity": "sha256-IDQCNscOpy+9pFVGzy/QmvqaoWGif+KglM9QsA3whkc=" + }, + "locale_nl.js.map": { + "src": "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js.map", + "integrity": "sha256-Oa7kCDbhhfIOpFqXgT44LAe9QPJP3HXAckSsw394ZE4=" + }, + "locale_nn.js": { + "src": "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js", + "integrity": "sha256-BlMkziOCaf0lDfAEDsW1wUiYlBizuCWEDhr+Ay5xdHo=" + }, + "locale_nn.js.map": { + "src": "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js.map", + "integrity": "sha256-4gQbEv0B1K3CCW2UCpUlXv18dyjfMd1w0cGQu8ZeygQ=" + }, + "locale_no.js": { + "src": "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js", + "integrity": "sha256-iFfNt4wPwtzLCM22Avc5RuEMAr8PF8diGvG21D0RskA=" + }, + "locale_no.js.map": { + "src": "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js.map", + "integrity": "sha256-VX3PSv0lkXS1CF8QNgAPZ10kYAFWt57jaau7LbgddvA=" + }, + "locale_oc.js": { + "src": "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js", + "integrity": "sha256-9fckY0qlbxVgc1qbfYdsW8bOM1aG1Eu9yvvztDUkzmA=" + }, + "locale_oc.js.map": { + "src": "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js.map", + "integrity": "sha256-lgQSwSpIjt/sDmizhd4069rr9CyF3enfGOw/AFSPXds=" + }, + "locale_pa.js": { + "src": "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js", + "integrity": "sha256-mJJPHYovfXW8ZzUfgzH/fm4J1h0KX8BfguM8vsM9TMQ=" + }, + "locale_pa.js.map": { + "src": "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js.map", + "integrity": "sha256-3LvIJHduhsGUxFbfSams6PtFSx+L2jXn+rf6nylVaT8=" + }, + "locale_pl.js": { + "src": "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js", + "integrity": "sha256-tl5CGx2K7wW9BEebVIFE/cJ4Bv9frqAz9ADMkpbOuk0=" + }, + "locale_pl.js.map": { + "src": "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js.map", + "integrity": "sha256-Rp+GjHwbYaMIT4Q1pZxG6SX6sfUfIQ71NwqDjLGHx1E=" + }, + "locale_pt-BR.js": { + "src": "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js", + "integrity": "sha256-T8jrBIHo+8mxEwT+1wJc1SmjFrMGX0tbX4+NOjIYvwE=" + }, + "locale_pt-BR.js.map": { + "src": "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js.map", + "integrity": "sha256-b42Q17JRd+POkiGQcahfrC8FpHeLcia4fg/9T08//6Y=" + }, + "locale_pt-PT.js": { + "src": "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js", + "integrity": "sha256-+TYGInWRhhMnS+K3gfiI7iRLoduOmc1jC1GrEUddi7A=" + }, + "locale_pt-PT.js.map": { + "src": "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js.map", + "integrity": "sha256-bqVptGgiycU+P2t/uZArGe4H99SZTIHYJaW+08rhK+s=" + }, + "locale_ro.js": { + "src": "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js", + "integrity": "sha256-h/crkYw5rFBLDmvi+AxxbOQ9l04kNKCLLaLSSmif2Pc=" + }, + "locale_ro.js.map": { + "src": "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js.map", + "integrity": "sha256-zlM5e9ZwBepEibqEqosH7cR7nKrw0qemXKoYb/jpNck=" + }, + "locale_ru.js": { + "src": "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js", + "integrity": "sha256-Oa3e/XJS2HFrf2PdF2gsZZmf5sh/TdKyQg7EowiOTww=" + }, + "locale_ru.js.map": { + "src": "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js.map", + "integrity": "sha256-PhyOBiGLeh5vGq4RJowYo6dzWWSLeXMDxHSJdneCPeo=" + }, + "locale_sa.js": { + "src": "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js", + "integrity": "sha256-aiixeTj8VpByVbfAPAjfT6AnCNMmZD9yR7Ki2fPr7ZU=" + }, + "locale_sa.js.map": { + "src": "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js.map", + "integrity": "sha256-uFxeHda8Kkx/PoAFlNlHBJegnWUrIhMXWYjh2pK2aSg=" + }, + "locale_sc.js": { + "src": "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js", + "integrity": "sha256-OBCXX8dVUe5hIYpEmB0xsVNEzLH2Is0bLf5gcAIuOuQ=" + }, + "locale_sc.js.map": { + "src": "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js.map", + "integrity": "sha256-ExpHmetKDsvfAemzbDSOjLkouKUcuyK/EALyiTd2Bog=" + }, + "locale_sco.js": { + "src": "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js", + "integrity": "sha256-TWifzDAcraaAijIbaDpeUE1cyIuXOuDvSyCAMgJ0x7g=" + }, + "locale_sco.js.map": { + "src": "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js.map", + "integrity": "sha256-rTy9Ok0zV7xseyAIjDNLr4U05Vmmg8Q7FyYooQkFmX4=" + }, + "locale_si.js": { + "src": "/packs/js/locale_si-17838170f6bebef2861a.chunk.js", + "integrity": "sha256-nq24RIfsAUL3rk30LbH4scFK2EvfL/GW3d8s1ymCZLY=" + }, + "locale_si.js.map": { + "src": "/packs/js/locale_si-17838170f6bebef2861a.chunk.js.map", + "integrity": "sha256-xwmNRp/kNjUiC7Y4ZzUneybCB1/aRMjJJ29msh2cIVk=" + }, + "locale_sk.js": { + "src": "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js", + "integrity": "sha256-NOuZYMDVVjd71kWExQ4SUCSDk/BR/WfYGMirUfgHJPY=" + }, + "locale_sk.js.map": { + "src": "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js.map", + "integrity": "sha256-7N3gmMp9ModK9jJr7LyayX1/9GDB3j01gn6MKbbWwrs=" + }, + "locale_sl.js": { + "src": "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js", + "integrity": "sha256-/8Pnzl9y+hA2nKYkHqR9/WKX2gflDYNaKy3TLX/2wk0=" + }, + "locale_sl.js.map": { + "src": "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js.map", + "integrity": "sha256-wcE5LU4zwvlao4dmxmMNNnsQppNla85ChhSjzfpm5dQ=" + }, + "locale_sq.js": { + "src": "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js", + "integrity": "sha256-gu2KIslQV64AqhVGUAD7HJPIOK1csiAGBnutModlj9k=" + }, + "locale_sq.js.map": { + "src": "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js.map", + "integrity": "sha256-i3aOehc94tSSHPEQ8SJ6xIZMMNuyzUKEnMQztI9LVoA=" + }, + "locale_sr-Latn.js": { + "src": "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js", + "integrity": "sha256-bMbUcDIGMSAoEHRwoQvyK0rDjrhsAg6lJBJRCi4tBHU=" + }, + "locale_sr-Latn.js.map": { + "src": "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js.map", + "integrity": "sha256-pH/svEWlQobikQ6A+p0sWmJID1R9zvYUEa4n+Rp6/Pk=" + }, + "locale_sr.js": { + "src": "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js", + "integrity": "sha256-MB7gwcVgbKOnJZUlUckdSWuhyadLXy8j6MHmKpLS4cw=" + }, + "locale_sr.js.map": { + "src": "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js.map", + "integrity": "sha256-Y03TUUpttZ7IwMHNJ86QaUeXs0L1BEBm7QfKU75X280=" + }, + "locale_sv.js": { + "src": "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js", + "integrity": "sha256-ix7gKPkdcOadbRkZU8K5cdAlgHCa1BQbj+Q8QEkqlEI=" + }, + "locale_sv.js.map": { + "src": "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js.map", + "integrity": "sha256-JWUn5UYrO9loA8xX0pyMdIqT6HI+3RpN0UM9UyumlHc=" + }, + "locale_szl.js": { + "src": "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js", + "integrity": "sha256-Z0is22d9hJ2SrKKJSp5eCi2XzMWo1F7J7yYLsas/vGM=" + }, + "locale_szl.js.map": { + "src": "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js.map", + "integrity": "sha256-Xb+G5D17+1I/5zNuxyyG3BiajFrzso6XI5a6PZ83p6U=" + }, + "locale_ta.js": { + "src": "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js", + "integrity": "sha256-ScwN6L82Nd0PKihd3H7r+Fs4VDD0N4tTt1zGQ5eYucE=" + }, + "locale_ta.js.map": { + "src": "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js.map", + "integrity": "sha256-0u2lj3Yh9tvJ8BYQAzOb88pRocgJ2YnliIezQf2RQnQ=" + }, + "locale_tai.js": { + "src": "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js", + "integrity": "sha256-tnFuPdh588UVkjL8dlvBS6ka4sG457ua7rO+Fc+/s30=" + }, + "locale_tai.js.map": { + "src": "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js.map", + "integrity": "sha256-7kBRSZt5KxnhDSgJGh1wILys9J5heEPXbEECCK9i8Ic=" + }, + "locale_te.js": { + "src": "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js", + "integrity": "sha256-tc+YIHM9y5R/AXAxGpgDNnZIjuIYWrXisfy3jQtXDfY=" + }, + "locale_te.js.map": { + "src": "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js.map", + "integrity": "sha256-9S4wEem8RwCZB5bzBqp+9YwrwwThFoMo+Or3KAfUYLY=" + }, + "locale_th.js": { + "src": "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js", + "integrity": "sha256-DGL3f6Bl1+H7r15fpTHtG93W3aLCSjRnughABAQne5M=" + }, + "locale_th.js.map": { + "src": "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js.map", + "integrity": "sha256-MOLXD5Ld9r08b8VX+f/3pDHDBLYOOy6xF4UsC0BoJD8=" + }, + "locale_tr.js": { + "src": "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js", + "integrity": "sha256-khe34YihUoCD0AV5o4pgKqDuV1wIsLTwZC3qkXAbPCE=" + }, + "locale_tr.js.map": { + "src": "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js.map", + "integrity": "sha256-v2V1YGuMsy67fxzo5eWeNp9khvG3+pafxLP8yNhyuW0=" + }, + "locale_tt.js": { + "src": "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js", + "integrity": "sha256-HBgMlgLYcmPhHJtpKuM7uuHveu6n24iINX4PofW9eBg=" + }, + "locale_tt.js.map": { + "src": "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js.map", + "integrity": "sha256-LojEtd1BIATpGV50zAJ+zwUgHcaWTZNj9UuBlakRX+Q=" + }, + "locale_ug.js": { + "src": "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js", + "integrity": "sha256-U4FjPlp7xtbPUADVMb+v9bAgOHQIea8XztEfnJsQfqU=" + }, + "locale_ug.js.map": { + "src": "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js.map", + "integrity": "sha256-JXHgSo9GlYHp2VwKqyTRw60SDp9psuxoQ/SgZz+41/U=" + }, + "locale_uk.js": { + "src": "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js", + "integrity": "sha256-cZ01w/aujHulc0TSP+o1kVguu5dw5ygM1BzjL8pmtEQ=" + }, + "locale_uk.js.map": { + "src": "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js.map", + "integrity": "sha256-2/CIxh87uit5JemQ0YCjQEpzJSbuM0BGECaP8ccPB4Q=" + }, + "locale_ur.js": { + "src": "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js", + "integrity": "sha256-P7YZtTY960t7JmSxuTJhAkrXPD+Ib3pSukiDPuVgP0E=" + }, + "locale_ur.js.map": { + "src": "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js.map", + "integrity": "sha256-y/TEpftUysA9Qs557bLTs3iJD40/yyXOBDcUYJcuiaw=" + }, + "locale_uz.js": { + "src": "/packs/js/locale_uz-38029008a065795c55b7.chunk.js", + "integrity": "sha256-O34b4eo/aXwL97o5gCuE3iBcdCL+YSn7cvcRIuAnLvo=" + }, + "locale_uz.js.map": { + "src": "/packs/js/locale_uz-38029008a065795c55b7.chunk.js.map", + "integrity": "sha256-DxvG+OoAbHu0dMPn/vNP20L5ob4oYObpRarmBJ8WMMY=" + }, + "locale_vi.js": { + "src": "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js", + "integrity": "sha256-lu2/hoL1iWs7CC8qAsNVr3ILBbceSYiuY09naPGxcQ0=" + }, + "locale_vi.js.map": { + "src": "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js.map", + "integrity": "sha256-Ndjild7pxt8RQ2fSssvwVK88sP/25re+3zqejUjG0gw=" + }, + "locale_zgh.js": { + "src": "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js", + "integrity": "sha256-kvZ86IlAa5nRE66v5kCtpPqCmXxHXtnGJmRC0crWjmQ=" + }, + "locale_zgh.js.map": { + "src": "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js.map", + "integrity": "sha256-nZQT7XDevHHB+GjJAuhoR9mqaGa3vCC67Olvadisvzk=" + }, + "locale_zh-CN.js": { + "src": "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js", + "integrity": "sha256-1lvh6SDZsKGCx9N8V1dAuN4qSHfbRv0BoPCwk8xdLg4=" + }, + "locale_zh-CN.js.map": { + "src": "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js.map", + "integrity": "sha256-alGdpSO2wn0KvjdQk7O/lBiX93z/CtWm1uCERqaJkp8=" + }, + "locale_zh-HK.js": { + "src": "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js", + "integrity": "sha256-Mb0uHwkCC9kmxLKtB9ag5GQxDZHLGdoXus1IvHF98pQ=" + }, + "locale_zh-HK.js.map": { + "src": "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js.map", + "integrity": "sha256-ytaPO3bE0FVWRc82OB3W1ZNjJlCoV08BR7Wldfx9W90=" + }, + "locale_zh-TW.js": { + "src": "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js", + "integrity": "sha256-KhuOY48FL2L6L842ITm1x8N/TyoDZAjxhTBf96Xgi/k=" + }, + "locale_zh-TW.js.map": { + "src": "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js.map", + "integrity": "sha256-2UfkY26DE4+tiEEyLSJoWF1UpC+6e+7E+KDiMHEpKo0=" + }, + "mailer.css": { + "src": "/packs/css/mailer-d3e9e30b.chunk.css", + "integrity": "sha256-i3Ojw8PPOO9atNke0FfRzbhAgjsrn5m/f1ErXnnDuA0=" + }, + "mailer.css.map": { + "src": "/packs/css/mailer-d3e9e30b.chunk.css.map", + "integrity": "sha256-6+FY9nxjXldQYGnAEmCxGg01FrMuTcmLaKaIhtyoW94=" + }, + "mailer.js": { + "src": "/packs/js/mailer-906c1f5c743751870035.chunk.js", + "integrity": "sha256-85qJnQADq/qh1h7c1+FKtF7NvTTCsPk6m/jej/WITRI=" + }, + "mailer.js.map": { + "src": "/packs/js/mailer-906c1f5c743751870035.chunk.js.map", + "integrity": "sha256-Df4caWSNiigAIH7OO1QE1t8JgJlRbhNSSQserAjpBXo=" + }, + "mastodon-light.css": { + "src": "/packs/css/mastodon-light-d9270c4c.chunk.css", + "integrity": "sha256-/0cGJMex4hn34b9JaNOhJmitZh0uNTIHLazYi0ZVSEE=" + }, + "mastodon-light.css.map": { + "src": "/packs/css/mastodon-light-d9270c4c.chunk.css.map", + "integrity": "sha256-1h3MEHXH3698sa4GY1gKyJ+O8vUx9a1T8uSg62mO5dU=" + }, + "mastodon-light.js": { + "src": "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js", + "integrity": "sha256-MdjZy+0w8m0cOkUwDnvh5Pc0r5iWlER1d1yI+7uCAAQ=" + }, + "mastodon-light.js.map": { + "src": "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js.map", + "integrity": "sha256-BP5nqoaGvGf/EWv4OSXAn2BhOA1ZaBV0EAmRPUpvKGI=" + }, + "media/fonts/fontawesome-webfont.eot": { + "src": "/packs/media/fonts/fontawesome-webfont-8b43027f.eot", + "integrity": "sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk=" + }, + "media/fonts/fontawesome-webfont.eot?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-8b43027f.eot", + "integrity": "sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk=" + }, + "media/fonts/fontawesome-webfont.svg?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-c1e38fd9.svg", + "integrity": "sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q=" + }, + "media/fonts/fontawesome-webfont.ttf?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-1e59d233.ttf", + "integrity": "sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg=" + }, + "media/fonts/fontawesome-webfont.woff2?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-20fd1704.woff2", + "integrity": "sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4=" + }, + "media/fonts/fontawesome-webfont.woff?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-f691f37e.woff", + "integrity": "sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.svg": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-fe0d118334cccfd145435b2c48cd06e4.svg", + "integrity": "sha256-MEMSbYnngJXxYQ8KRPOQIKxYciWL82Wwd63UDpM8cws=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.ttf": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-7fb73b77e9674adf3bb4e256d12f5c24.ttf", + "integrity": "sha256-/qGM+ZKZ4mABZFu6bET035hNgXtgksEuozod4cbMrNk=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.woff": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-de79497258b00697d7449a8d933a2d77.woff", + "integrity": "sha256-9vQXjjwSHGsQPwRvKmKwO2zyeNGMiRX7BeQ0pbFfpPI=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.woff2": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-ccc9601c8b2933f9a4b9246665afb352.woff2", + "integrity": "sha256-SK8nRVUadeAqAy5ejQE9i7O9HakKf1IYXhmyQHGZ7AY=" + }, + "media/fonts/roboto/roboto-bold-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-5ea71553d6e57da5b5cee78d8480db12.svg", + "integrity": "sha256-W3rX9bPwruYVrf5ZnZQH4vPsemzCewyP0uZClDMbXj0=" + }, + "media/fonts/roboto/roboto-bold-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-099d7f6e4b0fd1955bf58d33f84cbddf.ttf", + "integrity": "sha256-iuwOFV2x3/JXIKfqU379IGD06kKUfOOwI5NzTjxluUE=" + }, + "media/fonts/roboto/roboto-bold-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-c8eca5c3d7f0e3203f2150ef668b11d7.woff", + "integrity": "sha256-TOSP1nSCnMcDrYWavFo+P78JQxLsYBm+OObDOBmKcQg=" + }, + "media/fonts/roboto/roboto-bold-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-2c18fe4b97519d62a0d6aad8ada1004f.woff2", + "integrity": "sha256-BpdFK0bp30mD2AyyHRXGb80eiX4kqPjH0eWBbVVeZXA=" + }, + "media/fonts/roboto/roboto-italic-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-8f90649d463aec7793d71b786b5b3b06.svg", + "integrity": "sha256-VHBU5eAsjpCMAI/RR/uXYh5tjoMVApA0kdSLryewxoU=" + }, + "media/fonts/roboto/roboto-italic-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-73eaf3921695d82f2daba6bc02ffa602.ttf", + "integrity": "sha256-BiuKjMKaxKr6jdFLH93CEzdRxVPYI01U72YhuapMAgY=" + }, + "media/fonts/roboto/roboto-italic-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-5c39c5913ec17aaca7e59635381b9b62.woff", + "integrity": "sha256-SvzA5M9GAAiscee+UsXlpY8QDtCBEmWWWiELNGRdT0E=" + }, + "media/fonts/roboto/roboto-italic-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-dcb8144b63145c7e349a27ebbe24f875.woff2", + "integrity": "sha256-zvNTcwwumq9McCzuOvAXCxFvsFDirdQDTk5YuuOne9Y=" + }, + "media/fonts/roboto/roboto-medium-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-c0d084caf29abb0ed6cc87e92d886d61.svg", + "integrity": "sha256-FbY0mZiI2BKPu709RU14wIgwO9Z1Q7VHMuyDkXbt5Ck=" + }, + "media/fonts/roboto/roboto-medium-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-131f629d199b0a47d72d8489fda5823a.ttf", + "integrity": "sha256-Z0m2dvzqefs0MsfK0YnShEaL+d5V6B/2RqVsQ7AdeCk=" + }, + "media/fonts/roboto/roboto-medium-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-3a01847aadd53eb13f47e0227e8aca9b.woff", + "integrity": "sha256-LxGk4hswt/cygyD4jElXm1Hpux+SaNxjHS4sVxNmMB8=" + }, + "media/fonts/roboto/roboto-medium-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-3ed000c35f7afb8bd4ad7f46da85abbf.woff2", + "integrity": "sha256-CGpPcs+e9DBhvd8tTxkY/fkrcECxuPJA15YELoYA6LI=" + }, + "media/fonts/roboto/roboto-regular-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-a8da5f98faeafb21714583a6e373c397.svg", + "integrity": "sha256-Nh18Hzy0tVuQ/rTuxG5YA3+mUZgvhOrvtz8bzbLg8XA=" + }, + "media/fonts/roboto/roboto-regular-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-00831949e731c8201e1966faf97da0d2.ttf", + "integrity": "sha256-hLUefY7Hl7ubmSzAqTii2MxfRwwnV1RLjEYNioNg4MI=" + }, + "media/fonts/roboto/roboto-regular-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-8ede4fa233d6c99fb3653a767922b22b.woff", + "integrity": "sha256-VIg+si7Ii8+t89xqSTEP/einJc+RBvKO51H4QJavKJU=" + }, + "media/fonts/roboto/roboto-regular-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-e6505d5d85943244ec91d5e3002791f2.woff2", + "integrity": "sha256-EDb9syRt4IKFaMDBY00bhSVEgjkokXRXHchinMyAAdc=" + }, + "media/icons/android-chrome-144x144.png": { + "src": "/packs/media/icons/android-chrome-144x144-ff3110f7772743bdd0c1c47fb7b2d4e0.png", + "integrity": "sha256-gYEMVOji+GRQsFpFXxcQP3oc6IsdUW2OHu3lv8xmROc=" + }, + "media/icons/android-chrome-192x192.png": { + "src": "/packs/media/icons/android-chrome-192x192-eddc1ed540e97b926202b7b857989d60.png", + "integrity": "sha256-dmP8/MOpZHLwRdR05BpCii3mdYv+obNo4UBfGpwdLFM=" + }, + "media/icons/android-chrome-256x256.png": { + "src": "/packs/media/icons/android-chrome-256x256-7b2b43926019259f7c9ddee627d80a0f.png", + "integrity": "sha256-nd/BCLSP6NVJbTyu/aEzu4XQ8pV0hxEUUmzQ/eJLVV0=" + }, + "media/icons/android-chrome-36x36.png": { + "src": "/packs/media/icons/android-chrome-36x36-4c61fdb42936428af85afdbf8c6a45a8.png", + "integrity": "sha256-/WEeWTmVSljVK/uXN+BLcVgkzua+qaQzeEO8zcn8PHw=" + }, + "media/icons/android-chrome-384x384.png": { + "src": "/packs/media/icons/android-chrome-384x384-72068ed50b02828fc505a8d69b321dea.png", + "integrity": "sha256-uk3uWgqnhiieXE70jUQbDOVSkBRfnbLVAWU3BH74Dwo=" + }, + "media/icons/android-chrome-48x48.png": { + "src": "/packs/media/icons/android-chrome-48x48-2027aead76dc906c981043d658a8258d.png", + "integrity": "sha256-qe0TixDJcvnklqip4GHndmf6pjCYQupBLB1bsU3gE98=" + }, + "media/icons/android-chrome-512x512.png": { + "src": "/packs/media/icons/android-chrome-512x512-ccb53c9fcbb5f61bf741cc54998318f0.png", + "integrity": "sha256-4XQHB0u0eYVsi9VpTcxvGPk/Yg9WWksJO6iicrr1XbQ=" + }, + "media/icons/android-chrome-72x72.png": { + "src": "/packs/media/icons/android-chrome-72x72-799d90b81f5b28cea7355a0c0b356381.png", + "integrity": "sha256-4gMGAMaypoBawcwzM21iR9yJSiJDQPrIY1XSV1XsGIA=" + }, + "media/icons/android-chrome-96x96.png": { + "src": "/packs/media/icons/android-chrome-96x96-c2dfcfa1268c56e59edddfe20d818b91.png", + "integrity": "sha256-u1dL/So2/8Ggqnywr3HA8uma0mXKnuim1Y+B3am5xFc=" + }, + "media/icons/apple-touch-icon-1024x1024.png": { + "src": "/packs/media/icons/apple-touch-icon-1024x1024-db6849588b44f525363c37b65ef0ac66.png", + "integrity": "sha256-PUN8ROoYNJbZG13zIBqtCsZPcI4eUjBydDXcliuN3c4=" + }, + "media/icons/apple-touch-icon-114x114.png": { + "src": "/packs/media/icons/apple-touch-icon-114x114-211e68807b8d15707666a8d326d338b1.png", + "integrity": "sha256-mCmH6WAcD8etz6YPYiVnqaX8Wcp6r7151gmpCsTjDpw=" + }, + "media/icons/apple-touch-icon-120x120.png": { + "src": "/packs/media/icons/apple-touch-icon-120x120-4c4e647d758bf1b2f47a53e2165a01d2.png", + "integrity": "sha256-yVCmBDYwpTA0WuRvBTEefo8lZbL0ztMLKzPlGYbW6r8=" + }, + "media/icons/apple-touch-icon-144x144.png": { + "src": "/packs/media/icons/apple-touch-icon-144x144-ff3110f7772743bdd0c1c47fb7b2d4e0.png", + "integrity": "sha256-gYEMVOji+GRQsFpFXxcQP3oc6IsdUW2OHu3lv8xmROc=" + }, + "media/icons/apple-touch-icon-152x152.png": { + "src": "/packs/media/icons/apple-touch-icon-152x152-b12cbb1baaf4a6111d0efd391fd829c9.png", + "integrity": "sha256-MCK5KVDZVd+hp4QcLYCUutFBgEFcqTBnpoCbIzP//qU=" + }, + "media/icons/apple-touch-icon-167x167.png": { + "src": "/packs/media/icons/apple-touch-icon-167x167-6f21a68f6a05a8b5cf25b1729e553728.png", + "integrity": "sha256-iI25wuGAjIoClOt/Kj7qfrltZ3tXRjpuzPRLHOEBjVQ=" + }, + "media/icons/apple-touch-icon-180x180.png": { + "src": "/packs/media/icons/apple-touch-icon-180x180-a75559a0af48064c1b7c71b81f3bf7c6.png", + "integrity": "sha256-QWHa0MggRPM/msNf0ynvu5c6bue/whIQDPYo5feGVj4=" + }, + "media/icons/apple-touch-icon-57x57.png": { + "src": "/packs/media/icons/apple-touch-icon-57x57-c9dca808280860c51d0357f6a3350f4d.png", + "integrity": "sha256-Oa7mtD0a6kJQxHCXQgiTM3G1FlHCOHntGhkG3wtCjZI=" + }, + "media/icons/apple-touch-icon-60x60.png": { + "src": "/packs/media/icons/apple-touch-icon-60x60-bb247db195d9ee9d8c687b2b048508d9.png", + "integrity": "sha256-BHfmmZYMASwVkrQvJS11Guuw5jyxcHxAR1De6n7SIHg=" + }, + "media/icons/apple-touch-icon-72x72.png": { + "src": "/packs/media/icons/apple-touch-icon-72x72-799d90b81f5b28cea7355a0c0b356381.png", + "integrity": "sha256-4gMGAMaypoBawcwzM21iR9yJSiJDQPrIY1XSV1XsGIA=" + }, + "media/icons/apple-touch-icon-76x76.png": { + "src": "/packs/media/icons/apple-touch-icon-76x76-015d73d770413d121873193153ae4ab5.png", + "integrity": "sha256-5GKhEYATGlQe/SvgAqN+0qrVTIdx6T3RmTzczl1AAFg=" + }, + "media/icons/favicon-16x16.png": { + "src": "/packs/media/icons/favicon-16x16-c58fdef40ced38d582d5b8eed9d15c5a.png", + "integrity": "sha256-DK84BauFv9HYCaNZMBWPtRhC0tnuWoCPHelaD+D6SBc=" + }, + "media/icons/favicon-32x32.png": { + "src": "/packs/media/icons/favicon-32x32-249409a6d9f300112c51af514d863112.png", + "integrity": "sha256-Ft+9TR7iUbbKkiWxFmeO2NOjT/9GCy7/eG8E217aWa8=" + }, + "media/icons/favicon-48x48.png": { + "src": "/packs/media/icons/favicon-48x48-c1197e9664ee6476d2715a1c4293bf61.png", + "integrity": "sha256-eUrXLyOyoclFj/+MmZ2j1/Mlwpy3U2gFmt/+9dt9+uY=" + }, + "media/images/app-icon.svg": { + "src": "/packs/media/images/app-icon-0808256a4b7b3a7d337085d90c1b6133.svg", + "integrity": "sha256-aS0mhny+U/jVzXcFnlDu1QlTbC1ogRbkLeObUb+Vbic=" + }, + "media/images/elephant_ui_disappointed.svg": { + "src": "/packs/media/images/elephant_ui_disappointed-83980a5d0868aabbde510765f8a44a84.svg", + "integrity": "sha256-81e7qIL5w5F2rcDC7cUd1yBNSb2YO+FlwZoZllj3WP8=" + }, + "media/images/elephant_ui_greeting.svg": { + "src": "/packs/media/images/elephant_ui_greeting-530b368959aeb035f1ebb16fbc361c71.svg", + "integrity": "sha256-pQWEATvZ7bSOUn+cMAqsrB8OWru4TEyuNpwv6D8/vYQ=" + }, + "media/images/elephant_ui_plane.svg": { + "src": "/packs/media/images/elephant_ui_plane-72f8702db120a51a1cdbc4fb7f5ef59d.svg", + "integrity": "sha256-L6iHdg2PGx2XAypQ+pXu68p9JdSJEfwRrFyUOD2MBOI=" + }, + "media/images/elephant_ui_working.svg": { + "src": "/packs/media/images/elephant_ui_working-8d131ca68f598cb545a64ac0563199d1.svg", + "integrity": "sha256-vF6FuZMs/4pOUYgzmjZB4+dmuOoMpLU5m8uYhJSqsJo=" + }, + "media/images/icons/icon_cached.svg": { + "src": "/packs/media/images/icons/icon_cached-bb4d475764c7c6fe4ffc1e3496af21fb.svg", + "integrity": "sha256-LOkB9M+myiCnwJ+KxgVeJGXGz2GSB6BiOelWYGg2Nkw=" + }, + "media/images/icons/icon_done.svg": { + "src": "/packs/media/images/icons/icon_done-158fdbfc997bfbaecd661b95ac707663.svg", + "integrity": "sha256-DS/OmEIopI5HoMfSOET3iLXpuaaGtUGtVhed32zCBzE=" + }, + "media/images/icons/icon_email.svg": { + "src": "/packs/media/images/icons/icon_email-185c94df8b200b5513adfd2cb2c90cf2.svg", + "integrity": "sha256-QgA+Y4r7cO9jfOlDijSt25vtXGtn+yYGQRHSGv3HeU4=" + }, + "media/images/icons/icon_file_download.svg": { + "src": "/packs/media/images/icons/icon_file_download-99cc9fe7a1a90b340c55e5d3860315bc.svg", + "integrity": "sha256-jU7kyOzTLLxykwQ7xGVUpTMg/ke/BulU6ymRcwByYAw=" + }, + "media/images/icons/icon_flag.svg": { + "src": "/packs/media/images/icons/icon_flag-abc0a5f6874c0737c69c0f47c94f8bdb.svg", + "integrity": "sha256-9taRFfGw66g6s1ls4ERaNEzhlrvCElpGK2MD0LqnX+M=" + }, + "media/images/icons/icon_grade.svg": { + "src": "/packs/media/images/icons/icon_grade-b210a115be8deda342ba1cd816bf4796.svg", + "integrity": "sha256-W3yBkIV2GAA1ldDrrfpfAED/HaptnyI3Lfx1tfJRUmg=" + }, + "media/images/icons/icon_lock_open.svg": { + "src": "/packs/media/images/icons/icon_lock_open-9581ebece5a62933d1562da18b868457.svg", + "integrity": "sha256-eQcmzZQfswpbgjdCQiEKG6nn3A9l4BKYPLZpY/bKlcY=" + }, + "media/images/icons/icon_person_add.svg": { + "src": "/packs/media/images/icons/icon_person_add-d9557536647bdd6fc5a2af1e8e7fd352.svg", + "integrity": "sha256-uQsrgwH0uwn+gL4lUl1TXYkWkfuW0jv0LEXF2MmszWE=" + }, + "media/images/icons/icon_reply.svg": { + "src": "/packs/media/images/icons/icon_reply-e0c983a2e64569176501a9e047f91b7e.svg", + "integrity": "sha256-AiDvy928aX2Ip0YLici4ytEax7N9g48TdlQGIjkrho0=" + }, + "media/images/logo-symbol-icon.svg": { + "src": "/packs/media/images/logo-symbol-icon-de9e68dc49b19eb5cd142d3316f9e95e.svg", + "integrity": "sha256-TLwj1pIKuGNeqywk3EZ+rQKiNKLlA+OqnlHVwIWzKpk=" + }, + "media/images/logo-symbol-wordmark.svg": { + "src": "/packs/media/images/logo-symbol-wordmark-3830557f705aa0d7559b03269c942fe4.svg", + "integrity": "sha256-uYpo5V6HkDA0Uj2yy5ryYw/7XeNfUGxXX7Ot78lS+Nw=" + }, + "media/images/logo.svg": { + "src": "/packs/media/images/logo-d4b5dc90fd3e117d141ae7053b157f58.svg", + "integrity": "sha256-5voQCbqV8dEA/n2hwRhtCjCKPREhk+2wnvB+1kH+6SA=" + }, + "media/images/logo_full.svg": { + "src": "/packs/media/images/logo_full-4f531370f8ab23cd34058f3a7c2464ca.svg", + "integrity": "sha256-Dr5BQ136Hr3m3Ex4mPiU2x68fwxfMZZHwqgfrsIG6+M=" + }, + "media/images/logo_transparent.svg": { + "src": "/packs/media/images/logo_transparent-9aedc3a098e790b61726b33fcd385cb4.svg", + "integrity": "sha256-EijcQYC+f127YynG58/SToZxuEXS3WAd1V+Pl9hhvUo=" + }, + "media/images/mailer/icon_cached.png": { + "src": "/packs/media/images/mailer/icon_cached-d82304cbd965343f5f6a5631d68e8a15.png", + "integrity": "sha256-wVFGwcwrrY9jeuqUBvHmByHpykviOIeJj55b/lmlVoM=" + }, + "media/images/mailer/icon_done.png": { + "src": "/packs/media/images/mailer/icon_done-f49dc0b65c99f2edce1b99ee696f0b8d.png", + "integrity": "sha256-j6kr09zhKoVu9aPqzWR4wRNkNrgLjX658QiGAemgRrk=" + }, + "media/images/mailer/icon_email.png": { + "src": "/packs/media/images/mailer/icon_email-07eaf000249a54dae76b2937a834c3ae.png", + "integrity": "sha256-AHupchKk56cqiDt6GHMtRlkyQmzbRVG91IR2SK22GCI=" + }, + "media/images/mailer/icon_file_download.png": { + "src": "/packs/media/images/mailer/icon_file_download-fb5f9be9fd8e11726c3b3a1d47e72717.png", + "integrity": "sha256-c9dazTq2KmjfgEl8KCEl/Eulifnr2VovgQejnauzNiw=" + }, + "media/images/mailer/icon_flag.png": { + "src": "/packs/media/images/mailer/icon_flag-fb052043db6f17c4f79c21fccff09700.png", + "integrity": "sha256-uBmc1YSPIjLaHAmEUPmJ+D5yNATVijpLf0BAY6vM8+I=" + }, + "media/images/mailer/icon_grade.png": { + "src": "/packs/media/images/mailer/icon_grade-15655c70b6fe2ca2f8547db15929187a.png", + "integrity": "sha256-IaJFveyki3F0GnIRXc/8DpGIMxY21OrI9G5U+f5BbQ4=" + }, + "media/images/mailer/icon_lock_open.png": { + "src": "/packs/media/images/mailer/icon_lock_open-8e5ae4f888e6ea016e3046b607314d02.png", + "integrity": "sha256-n+dr7c8ZOudT8khIOcB/FVlXon2jojVuIfHfo6ivyN4=" + }, + "media/images/mailer/icon_person_add.png": { + "src": "/packs/media/images/mailer/icon_person_add-a9759d23d1662ab87c2f255c8906107b.png", + "integrity": "sha256-bx9vDJOZtQ6s1qFp/vgSAxFYJKvsXaUIEwaJOCjIfm8=" + }, + "media/images/mailer/icon_reply.png": { + "src": "/packs/media/images/mailer/icon_reply-05e7be76b12b1b5529bd003bbe17bcf2.png", + "integrity": "sha256-9EyRKX1qQa9B1pvAWchCNbi5Z+8Z4FNW2sA9O5wpb8c=" + }, + "media/images/mailer/logo.png": { + "src": "/packs/media/images/mailer/logo-50cfb97cbce11d4974c71481a924b69c.png", + "integrity": "sha256-Ae8FX5xzFqoNsNWUYuDljAv1tiiMT0URSZya6xrwubk=" + }, + "media/images/mailer/wordmark.png": { + "src": "/packs/media/images/mailer/wordmark-8a93a992d2c8ac64361a1bc2c1664250.png", + "integrity": "sha256-Y5DvjTdZgUSJSyBfcBU61MKkXu71iTqJOpDz9kOfDwY=" + }, + "media/images/preview.png": { + "src": "/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png", + "integrity": "sha256-uA/RrG49ZVMEbl4uydzExgCwWVludRMd4pYUpBdajBc=" + }, + "media/images/reticle.png": { + "src": "/packs/media/images/reticle-dbff413218a2f5843b32cf2fb9968eb4.png", + "integrity": "sha256-vb5WEHGlvKJhtoRMa8zdOGda7LiS92EkQJ53oGL2ttU=" + }, + "media/images/void.png": { + "src": "/packs/media/images/void-cf1819950446c7563cdb09966c0db01d.png", + "integrity": "sha256-S5oQlKuN5UINWLmsKmAVPZc9KmHsoLRoiIMtNUWROYc=" + }, + "modals/block_modal.js": { + "src": "/packs/js/modals/block_modal-285514f4fd899d40d729.chunk.js", + "integrity": "sha256-tATA1ZOSxR5XqSDgZ2ufDtutnvXL5+sUtbYSSunY/wU=" + }, + "modals/block_modal.js.map": { + "src": "/packs/js/modals/block_modal-285514f4fd899d40d729.chunk.js.map", + "integrity": "sha256-zSbIEBMfUkoRAmzcFxo41BzrsrGTUucnLx44x1zFGgE=" + }, + "modals/closed_registrations_modal.js": { + "src": "/packs/js/modals/closed_registrations_modal-cffa83a84851c036f0e7.chunk.js", + "integrity": "sha256-n66RYrZXCdIcZc0dl03GZ1mBUhhdYXeYesewIW+8dvI=" + }, + "modals/closed_registrations_modal.js.map": { + "src": "/packs/js/modals/closed_registrations_modal-cffa83a84851c036f0e7.chunk.js.map", + "integrity": "sha256-0rdNNc4nKgKjx1v4JC4zbtOz8+TyZnjQxE0PZRugNhc=" + }, + "modals/compare_history_modal.js": { + "src": "/packs/js/modals/compare_history_modal-90b3013107b67285a7da.chunk.js", + "integrity": "sha256-zQ+/ICuZYBmpQ2GkzJxa2qrQd06VYV3G4DwPeEQadio=" + }, + "modals/compare_history_modal.js.map": { + "src": "/packs/js/modals/compare_history_modal-90b3013107b67285a7da.chunk.js.map", + "integrity": "sha256-dFtswiv0X++FFifTB5/LvvcRs8IKKLFO8ElIhqmcDkw=" + }, + "modals/embed_modal.js": { + "src": "/packs/js/modals/embed_modal-b3308de1f266e93b7aaf.chunk.js", + "integrity": "sha256-7hb+VsRzZD/GM+472Gyzltt88Nr+V1aeJ2orBarBz3Y=" + }, + "modals/embed_modal.js.map": { + "src": "/packs/js/modals/embed_modal-b3308de1f266e93b7aaf.chunk.js.map", + "integrity": "sha256-DUXlrT7Yy3rVjyhaVExqOBRAyuYIhoCmV/sbk1DGFZY=" + }, + "modals/filter_modal.js": { + "src": "/packs/js/modals/filter_modal-6ad1eed2cf629d860383.chunk.js", + "integrity": "sha256-I4d5kXs017Qv3BI4bFkdzc9ZjrMocaYQoiDvBMWwrW0=" + }, + "modals/filter_modal.js.map": { + "src": "/packs/js/modals/filter_modal-6ad1eed2cf629d860383.chunk.js.map", + "integrity": "sha256-D67EMgmijKcduY4XLj2Rdh7o4iaVbKObKHqtBCQnYrQ=" + }, + "modals/interaction_modal.js": { + "src": "/packs/js/modals/interaction_modal-facf890aa0ae8f2ac47c.chunk.js", + "integrity": "sha256-ilba2YoU0JLPocESrGSWdC2Tcy1OqKNweCuuL3giZGA=" + }, + "modals/interaction_modal.js.map": { + "src": "/packs/js/modals/interaction_modal-facf890aa0ae8f2ac47c.chunk.js.map", + "integrity": "sha256-QydGrgCMa16qS6ZI2bw+Eg8VoK8NxqgdRJr82eZb90Y=" + }, + "modals/mute_modal.js": { + "src": "/packs/js/modals/mute_modal-44fbd9f138ed444e344d.chunk.js", + "integrity": "sha256-Hf4z6ZHAI9sMfctf1VVy479viJD/X0whNB5GMu3/bMg=" + }, + "modals/mute_modal.js.map": { + "src": "/packs/js/modals/mute_modal-44fbd9f138ed444e344d.chunk.js.map", + "integrity": "sha256-Mv+EEwvcvP2laxRpMTIewrOQAOewSrPvJwyNcvYDJGc=" + }, + "modals/report_modal.js": { + "src": "/packs/js/modals/report_modal-f393be11609ee994a2db.chunk.js", + "integrity": "sha256-lQC1ncu1YAJxlJZ2S2EfAeiDmJ400q81BuEV6gbSzFs=" + }, + "modals/report_modal.js.map": { + "src": "/packs/js/modals/report_modal-f393be11609ee994a2db.chunk.js.map", + "integrity": "sha256-QvQSYcOoEQgicaGII1ZVou8sPBzLF+r3kQnIw9Cg7fs=" + }, + "modals/subscribed_languages_modal.js": { + "src": "/packs/js/modals/subscribed_languages_modal-9e2993dd250cf513f141.chunk.js", + "integrity": "sha256-8bULdwgWdff8D4RZDOtZjgCu/Xa4Co8LwmSw68A7TJI=" + }, + "modals/subscribed_languages_modal.js.map": { + "src": "/packs/js/modals/subscribed_languages_modal-9e2993dd250cf513f141.chunk.js.map", + "integrity": "sha256-D0EPxRTC3AlhgRpi78nuUjBjq84Oqa8e6ylJAD98ov4=" + }, + "modern-dark-wobbl-old.css": { + "src": "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css", + "integrity": "sha256-Ic57GXLi6Q8UG5V1CE6yazZosiL5pZ/rORiLvMOo2Do=" + }, + "modern-dark-wobbl-old.css.map": { + "src": "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css.map", + "integrity": "sha256-ha+7RHuf3N2B9Z8uGHS1dD+rj+U9zIjY3tjpUoPY4z8=" + }, + "modern-dark-wobbl-old.js": { + "src": "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js", + "integrity": "sha256-EDG5zP/PpG7R44tOOP9AKlP79Hzah0DFVnLtG4Lrv1Q=" + }, + "modern-dark-wobbl-old.js.map": { + "src": "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js.map", + "integrity": "sha256-x713hTukta7lDQkXfdphLY1guSaJjeI6edtGMOSPEJw=" + }, + "modern-dark.css": { + "src": "/packs/css/modern-dark-1cfb4c54.chunk.css", + "integrity": "sha256-ZO5+6kPMcC10o5iXdjun9BA+qqmMy5oMAusr/j1L4Qo=" + }, + "modern-dark.css.map": { + "src": "/packs/css/modern-dark-1cfb4c54.chunk.css.map", + "integrity": "sha256-eBuesRNhVWUljmvu1L2MLGsAZ35gmfBFe38nB470+rk=" + }, + "modern-dark.js": { + "src": "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js", + "integrity": "sha256-lfQ5SpgTXhD4/ARsxygt6owXI3EkCP1LvDYn29Nk22o=" + }, + "modern-dark.js.map": { + "src": "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js.map", + "integrity": "sha256-gZaOsNOkj8cPH2H/SBU/fsYrtaGilQpf8Z2/zrEwHIA=" + }, + "modern-light-wobbl-old.css": { + "src": "/packs/css/modern-light-wobbl-old-50985752.chunk.css", + "integrity": "sha256-FKu4HTqRYXlV4VI53VIEQppyYfBeOZO2+JXSJFsf9Ow=" + }, + "modern-light-wobbl-old.css.map": { + "src": "/packs/css/modern-light-wobbl-old-50985752.chunk.css.map", + "integrity": "sha256-p8KWL8O/nRIi1HbeMBXd+6APNjkJLPnh25FYQbvcm5c=" + }, + "modern-light-wobbl-old.js": { + "src": "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js", + "integrity": "sha256-c+B26bZspb1up778EN5lOoRlhEP7Ck9tYMD2CBynGx4=" + }, + "modern-light-wobbl-old.js.map": { + "src": "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js.map", + "integrity": "sha256-qp5Nh8PjdDHagjupVdwI4m4v64kNo2kjm20fyKDnfFQ=" + }, + "modern-light-wobbl.css": { + "src": "/packs/css/modern-light-wobbl-291fe684.chunk.css", + "integrity": "sha256-u0FNCZ866kB1PUmBaoLjU/IbabcZuaz/crhyXbkrz68=" + }, + "modern-light-wobbl.css.map": { + "src": "/packs/css/modern-light-wobbl-291fe684.chunk.css.map", + "integrity": "sha256-S77R1L+1H52KmHabl11nRhCe1y9Q6O6rdyb+1oeleeY=" + }, + "modern-light-wobbl.js": { + "src": "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js", + "integrity": "sha256-ncq1mZHSipDX2gpf0ENaBlhuMkoKFtQws8WbHyX6tK4=" + }, + "modern-light-wobbl.js.map": { + "src": "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js.map", + "integrity": "sha256-Ugj5gnsIEw972ytw7AfyAv/XyZt9C9FTSAZ8ToW0KGY=" + }, + "modern-light.css": { + "src": "/packs/css/modern-light-1c0258de.chunk.css", + "integrity": "sha256-rKaxxKRKcDPfEWnxPOlfFQN/baKgUhM5UwgG8C33JGs=" + }, + "modern-light.css.map": { + "src": "/packs/css/modern-light-1c0258de.chunk.css.map", + "integrity": "sha256-p5oDMWPwl5lnYjLatrfxmVnZZsh7nEvMrB1HYZBaGos=" + }, + "modern-light.js": { + "src": "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js", + "integrity": "sha256-zFT0z3IcGgZ9Ck0+gVLBDNFvcuA7+MDoX1U3dBWj7O4=" + }, + "modern-light.js.map": { + "src": "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js.map", + "integrity": "sha256-X7nuN9Nfj2YQbYSJkB25KonCuwHDZxZu6bEQgTiaLXg=" + }, + "ocr/tesseract-core.wasm.js": { + "src": "/packs/ocr/tesseract-core.wasm-e4db7f953ac7bcf9f67bd39031e42241.js", + "integrity": "sha256-j2marGLlEXTmo0iXTPumIL1lVgn0+RwBP4VSESoKSjY=" + }, + "ocr/worker.min-514c4b0a1fa9a086ca9ab8bfb7df6c9d.js.LICENSE.txt": { + "src": "/packs/ocr/worker.min-514c4b0a1fa9a086ca9ab8bfb7df6c9d.js.LICENSE.txt", + "integrity": "sha256-QoWYHwnDlKd4MX8P4iAeB1ezh+OWVOjZq0YvVoSnUWM=" + }, + "ocr/worker.min.js": { + "src": "/packs/ocr/worker.min-514c4b0a1fa9a086ca9ab8bfb7df6c9d.js", + "integrity": "sha256-hwUPXOFqMNYJvaOu5bjDwhmIIFEEp7M7+Hkrxm2dwWU=" + }, + "public-path.js": { + "src": "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js", + "integrity": "sha256-jAMI72eadFn7TolK0dBykdrbJKs4NVm1tunq8Jr45d8=" + }, + "public-path.js.map": { + "src": "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js.map", + "integrity": "sha256-uTazMmhgfzKf4YJNsntBX+Y+OE5s93qa8xPTsZH4elo=" + }, + "public.js": { + "src": "/packs/js/public-35500a3113a9d04e88f1.chunk.js", + "integrity": "sha256-kTTSpUDFa4593lidSMDSXjVMqCoWu/Hn04kad5VKVvw=" + }, + "public.js.map": { + "src": "/packs/js/public-35500a3113a9d04e88f1.chunk.js.map", + "integrity": "sha256-fnoFVSgpoGc5H+qAK/eswo7I4WO1B7o66p7kezN3uK8=" + }, + "share.js": { + "src": "/packs/js/share-efad16f2e2c4954c4721.chunk.js", + "integrity": "sha256-mVx160SzmlJuVDWXXybFtI/n7AhM669/ZkIpqHDf/zU=" + }, + "share.js.map": { + "src": "/packs/js/share-efad16f2e2c4954c4721.chunk.js.map", + "integrity": "sha256-n4JcNS9vOzTyvcyL6jCGD2gjWyBsoTfInd6RC9vJcUc=" + }, + "sw.js": { + "src": "/packs/sw.js", + "integrity": "sha256-WKzgP5z9lDjfgAwTObADmmil2VZjNW0qtTyCWjWz/3w=" + }, + "sw.js.map": { + "src": "/packs/sw.js.map", + "integrity": "sha256-qUX+GpzGQD63dBr9WzV5KVCCU0731AVR6ZMwe8aDSsE=" + }, + "tesseract.js": { + "src": "/packs/js/tesseract-1135ffb0b9825ec8791c.chunk.js", + "integrity": "sha256-XdWnMHTwhYYMk5SoJcWDj4qIJf+xTdW3vWste1hAdxY=" + }, + "tesseract.js.map": { + "src": "/packs/js/tesseract-1135ffb0b9825ec8791c.chunk.js.map", + "integrity": "sha256-zgN7800XxxAl51ITqnSm0MceJA+8MErDwSpv90KKZGk=" + }, + "two_factor_authentication.js": { + "src": "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js", + "integrity": "sha256-jZwbajnZKuCUZnoWCAqvj2nzbP0ggwQuq2IFFXVQWsI=" + }, + "two_factor_authentication.js.map": { + "src": "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js.map", + "integrity": "sha256-4Pvk4t81YoTmPKvdONNdqUzOVpD+YvKsOS9mxWGi8YU=" + }, + "wobbl-light.css": { + "src": "/packs/css/wobbl-light-aae0a2db.chunk.css", + "integrity": "sha256-iFc0ERGgymcOJrUuq509pxmzt16EvKp0KO5sOI+GWqo=" + }, + "wobbl-light.css.map": { + "src": "/packs/css/wobbl-light-aae0a2db.chunk.css.map", + "integrity": "sha256-6jjeNyVhWX/R0B/Cynndhgt3iIdnBMK+FC0wRdLPBUw=" + }, + "wobbl-light.js": { + "src": "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js", + "integrity": "sha256-T6caY1gIdm/xSrF0jB0kAjwFYTcBHTt2THmY6TMv1V4=" + }, + "wobbl-light.js.map": { + "src": "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js.map", + "integrity": "sha256-Y6XtgD1lgZHZRbCBv5cMMaaI+wjYJEPvqWJo4jOgkTA=" + }, + "wobbl-old-light.css": { + "src": "/packs/css/wobbl-old-light-d2f87f38.chunk.css", + "integrity": "sha256-YT6U10dMY8/fxu4E3HfLthiawVCQ/5RrnA0KYR4iGBo=" + }, + "wobbl-old-light.css.map": { + "src": "/packs/css/wobbl-old-light-d2f87f38.chunk.css.map", + "integrity": "sha256-bCACqV4neCBC2/XEoLGgemPWQdn9UQH2fma+6SfTpMU=" + }, + "wobbl-old-light.js": { + "src": "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js", + "integrity": "sha256-/LyLShmuQnze21vjWH7irG4BNOAgnionOMryvfWbf78=" + }, + "wobbl-old-light.js.map": { + "src": "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js.map", + "integrity": "sha256-c+zynZEmMAICeiTiVdFUL0smuoAVJ1bwVsLLti7nNZk=" + }, + "wobbl-old.css": { + "src": "/packs/css/wobbl-old-41b5a76e.chunk.css", + "integrity": "sha256-6qiqu+KyJt0fS2R8Vc5C7dwrMPlieOOmDgRFYloa67E=" + }, + "wobbl-old.css.map": { + "src": "/packs/css/wobbl-old-41b5a76e.chunk.css.map", + "integrity": "sha256-sA9q8aDLcpvwa+LAbHd6SQCZSVZA70fU31qfIJmb1LM=" + }, + "wobbl-old.js": { + "src": "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js", + "integrity": "sha256-CAYaWEFHpHvk8Cew4eNlsGtKq0S/aqURhYrw0fYfmZg=" + }, + "wobbl-old.js.map": { + "src": "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js.map", + "integrity": "sha256-AS+HRq5qQgPnhUO2mVXquGFXjrhZB7DXENnHlmXJScE=" + }, + "wobbl.css": { + "src": "/packs/css/wobbl-88f067e5.chunk.css", + "integrity": "sha256-sREyL1vRm9S9FhRs4DUtM1t9hb0STo8nKixwXwO5CwA=" + }, + "wobbl.css.map": { + "src": "/packs/css/wobbl-88f067e5.chunk.css.map", + "integrity": "sha256-9IdCSCDlS4NpLCh7gh9VEoxMbir1JeSvZI0SAwb3yjg=" + }, + "wobbl.js": { + "src": "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js", + "integrity": "sha256-JiRac5Sj33oGQ3i4LLxCpe35Ya2HS1AWb3EWsePGXFY=" + }, + "wobbl.js.map": { + "src": "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js.map", + "integrity": "sha256-ANmfOcLOTzqaaGKuDPUz2VHzadEleuR6bhHkY8kJ+FA=" + } +} +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/webpacker-5.4.4/lib/webpacker/manifest.rb:79:in `handle_missing_entry' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/webpacker-5.4.4/lib/webpacker/manifest.rb:49:in `lookup!' +/home/mastodon/live/lib/webpacker/helper_extensions.rb:5:in `javascript_pack_tag' +/home/mastodon/live/app/views/layouts/_theme.html.haml:6:in `_app_views_layouts__theme_html_haml__3180968677926065901_69360' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `public_send' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `_run' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:157:in `block in render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:361:in `instrument_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:155:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/partial_renderer.rb:251:in `block in render_partial_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/partial_renderer.rb:246:in `render_partial_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/object_renderer.rb:31:in `render_partial_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/partial_renderer.rb:237:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/object_renderer.rb:16:in `render_object_with_partial' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:77:in `render_partial_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:27:in `render_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:22:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/helpers/rendering_helper.rb:37:in `block in render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:270:in `in_rendering_context' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/helpers/rendering_helper.rb:33:in `render' +/home/mastodon/live/app/views/layouts/error.html.haml:9:in `_app_views_layouts_error_html_haml__434087765855293748_69340' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `public_send' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `_run' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:157:in `block in render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:361:in `instrument_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:155:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:76:in `block in render_with_layout' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:74:in `render_with_layout' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:59:in `render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:11:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:61:in `render_template_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:29:in `render_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/rendering.rb:117:in `block in _render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:270:in `in_rendering_context' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/rendering.rb:116:in `_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/streaming.rb:216:in `_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/rendering.rb:103:in `render_to_body' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/rendering.rb:158:in `render_to_body' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/renderers.rb:141:in `render_to_body' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/abstract_controller/rendering.rb:45:in `render_to_string' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/rendering.rb:147:in `render_to_string' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/renderer.rb:81:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/rendering.rb:11:in `render' +/home/mastodon/live/lib/tasks/assets.rake:13:in `render_static_page' +/home/mastodon/live/lib/tasks/assets.rake:17:in `block (2 levels) in
' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke' +/home/mastodon/live/lib/tasks/assets.rake:24:in `block in
' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands/rake/rake_command.rb:24:in `block (2 levels) in perform' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands/rake/rake_command.rb:24:in `block in perform' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/rake_module.rb:59:in `with_application' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands/rake/rake_command.rb:18:in `perform' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/command.rb:51:in `invoke' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands.rb:18:in `
' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require' + +Caused by: +Webpacker::Manifest::MissingEntryError: Webpacker can't find core/common.js in /home/mastodon/live/public/packs/manifest.json. Possible causes: +1. You want to set webpacker.yml value of compile to true for your environment + unless you are using the `webpack -w` or the webpack-dev-server. +2. webpack has not yet re-run to reflect updates. +3. You have misconfigured Webpacker's config/webpacker.yml file. +4. Your webpack configuration is not creating a manifest. +Your manifest contains: +{ + "admin.js": { + "src": "/packs/js/admin-41af99b8579db78a010d.chunk.js", + "integrity": "sha256-ntJmrmyuIxEPCQMqPonSgMOwaXw9VumIQ1VzWPTgrsI=" + }, + "admin.js.map": { + "src": "/packs/js/admin-41af99b8579db78a010d.chunk.js.map", + "integrity": "sha256-Tn0iSqcU3OY94y+ky8gIP0wHmPfjVkvGKJUv4mAgjNA=" + }, + "application.js": { + "src": "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js", + "integrity": "sha256-HDgeyT/1csPW7R56OBxya3CiKp5KvAdo4pn/4CX8Gxw=" + }, + "application.js.map": { + "src": "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js.map", + "integrity": "sha256-OWOQ5vK1As4TbWqADbLSzU0W9yUWaC6ztwn45ee+ow4=" + }, + "arrow-key-navigation.js": { + "src": "/packs/js/arrow-key-navigation-c612b3295983104aa0f0.chunk.js", + "integrity": "sha256-xm0v3gnDtsgfV0fBS6dK0Z49lhrgPAphZBLKP+6/3vc=" + }, + "arrow-key-navigation.js.map": { + "src": "/packs/js/arrow-key-navigation-c612b3295983104aa0f0.chunk.js.map", + "integrity": "sha256-kh2Nlueg4q1XPuH9xzBxtLMizHN556h7/MMmviB5CG0=" + }, + "base_polyfills.js": { + "src": "/packs/js/base_polyfills-9e5acba002b775f8a876.chunk.js", + "integrity": "sha256-y2eTCHt6BD+kvYZigLo6R01y+2tl7KYj6oO95RO6eFw=" + }, + "base_polyfills.js.map": { + "src": "/packs/js/base_polyfills-9e5acba002b775f8a876.chunk.js.map", + "integrity": "sha256-lIHOw3dc6xt6/DsFmt8on8HFxhOpvEMF3IjQVf541zs=" + }, + "common.css": { + "src": "/packs/css/common-a844dc34.css", + "integrity": "sha256-P7jsS35wKfKZ7egDM6otdXk7d8JjmsE5i9R8SD1vD8s=" + }, + "common.css.map": { + "src": "/packs/css/common-a844dc34.css.map", + "integrity": "sha256-Qyj/GZ0pv+z3+NCOntxsGwO9M3J2Q8poPIe4Sfc1lgY=" + }, + "common.js": { + "src": "/packs/js/common-9da33dbc9762ba5fb40c.js", + "integrity": "sha256-yz8q1A5JNj54ijBOSdiiYh9xQmsWlLvDxYav5onKtuQ=" + }, + "common.js.map": { + "src": "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "integrity": "sha256-+J4Uo07Scxl6ucAWPOJkPv1ye1hkeVpPnNz2MHV3ocA=" + }, + "containers/media_container.js": { + "src": "/packs/js/containers/media_container-2afe952129d043ba10ed.chunk.js", + "integrity": "sha256-kB3PN4it0IxWs5+DjPCFSxxdqYWN9i4fT5Yl285CjkU=" + }, + "containers/media_container.js.map": { + "src": "/packs/js/containers/media_container-2afe952129d043ba10ed.chunk.js.map", + "integrity": "sha256-YU76VZoOXrSJPXorQs4CkswA1YVkVWeb/4PmOxoeAV0=" + }, + "contrast.css": { + "src": "/packs/css/contrast-5cabd607.chunk.css", + "integrity": "sha256-EGQklklRlDxmQmTgH5Mj9SoQ9ONWg18XZzKJ6EJrZ0w=" + }, + "contrast.css.map": { + "src": "/packs/css/contrast-5cabd607.chunk.css.map", + "integrity": "sha256-dKva8YMTNM51g4ZfFpap/hMi2KgB3ztHYxYcqA0qmBQ=" + }, + "contrast.js": { + "src": "/packs/js/contrast-393583c54c3047b1a13c.chunk.js", + "integrity": "sha256-HN1BR9k9NLbdPBLrJRmSWhfDcu/v/mcsBYGazK4abBI=" + }, + "contrast.js.map": { + "src": "/packs/js/contrast-393583c54c3047b1a13c.chunk.js.map", + "integrity": "sha256-10ozejR0zZg2fuD/Um2sWN4z8FjwEPAhqvfZI8a0Lws=" + }, + "dark.css": { + "src": "/packs/css/dark-a3b88036.chunk.css", + "integrity": "sha256-q+vj0pe+B8fkLwmMvwkYWQJ+skyHaGB6yy1/4Ofa78g=" + }, + "dark.css.map": { + "src": "/packs/css/dark-a3b88036.chunk.css.map", + "integrity": "sha256-CKkP+P28O6kbL4KnjVCz6fgLrWxNOUnnhIB0Xhny1Zg=" + }, + "dark.js": { + "src": "/packs/js/dark-1e375a968d41797e60af.chunk.js", + "integrity": "sha256-XaXdkRE/GYwUmvVTR2JNzxVZl4E2F+EmI78ddvUeCqE=" + }, + "dark.js.map": { + "src": "/packs/js/dark-1e375a968d41797e60af.chunk.js.map", + "integrity": "sha256-wvgYCF4wIaY1hWtkdrBgRbh8c6KNq+XW4naA/Xh04XE=" + }, + "default.css": { + "src": "/packs/css/default-229799f4.chunk.css", + "integrity": "sha256-XxDgsR1SNLVJd5pPuao6byCJQVDMPtCCakHcpqsdUPc=" + }, + "default.css.map": { + "src": "/packs/css/default-229799f4.chunk.css.map", + "integrity": "sha256-ebkS5CFpQ/JKVYi/3INDeZGZlSSC4fKluCdk56t/QoE=" + }, + "default.js": { + "src": "/packs/js/default-8b7478aae9e7db81c926.chunk.js", + "integrity": "sha256-QFMq9O6piSNhhZLgOdrnmXF8S9GNBoOJ3fo4HfbgJgo=" + }, + "default.js.map": { + "src": "/packs/js/default-8b7478aae9e7db81c926.chunk.js.map", + "integrity": "sha256-uzk84SO6ddlFMyWL89bftycACfqBpk2WyQ9nAv6zR+8=" + }, + "emoji_picker.js": { + "src": "/packs/js/emoji_picker-58d5d6643533880286d8.chunk.js", + "integrity": "sha256-0Q56X7XU3uvVsHM26NeHEjTFEGi08JJxWiGAqX4+9NU=" + }, + "emoji_picker.js.map": { + "src": "/packs/js/emoji_picker-58d5d6643533880286d8.chunk.js.map", + "integrity": "sha256-ioRLeVGfhxvoHhiCjnloAgNoZnz3W142SN+N6Uv/3Vw=" + }, + "entrypoints": { + "admin": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/admin-41af99b8579db78a010d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/admin-41af99b8579db78a010d.chunk.js.map" + ] + } + }, + "application": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/application-7fdb18aa157c9d68cd19.chunk.js.map" + ] + } + }, + "error": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/error-9aec4316f262805dbab4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/error-9aec4316f262805dbab4.chunk.js.map" + ] + } + }, + "mailer": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/mailer-d3e9e30b.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/mailer-906c1f5c743751870035.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/mailer-d3e9e30b.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/mailer-906c1f5c743751870035.chunk.js.map" + ] + } + }, + "public-path": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js.map" + ] + } + }, + "public": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/public-35500a3113a9d04e88f1.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/public-35500a3113a9d04e88f1.chunk.js.map" + ] + } + }, + "share": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/share-efad16f2e2c4954c4721.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/share-efad16f2e2c4954c4721.chunk.js.map" + ] + } + }, + "two_factor_authentication": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js.map" + ] + } + }, + "locale_af": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js.map" + ] + } + }, + "locale_an": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_an-7042264d7263706588ca.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_an-7042264d7263706588ca.chunk.js.map" + ] + } + }, + "locale_ar": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js.map" + ] + } + }, + "locale_ast": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js.map" + ] + } + }, + "locale_be": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_be-2b73894a107f7474274e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_be-2b73894a107f7474274e.chunk.js.map" + ] + } + }, + "locale_bg": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js.map" + ] + } + }, + "locale_bn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js.map" + ] + } + }, + "locale_br": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js.map" + ] + } + }, + "locale_bs": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js.map" + ] + } + }, + "locale_ca": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js.map" + ] + } + }, + "locale_ckb": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ckb-bac2365515303c579326.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ckb-bac2365515303c579326.chunk.js.map" + ] + } + }, + "locale_co": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js.map" + ] + } + }, + "locale_cs": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js.map" + ] + } + }, + "locale_csb": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js.map" + ] + } + }, + "locale_cy": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js.map" + ] + } + }, + "locale_da": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js.map" + ] + } + }, + "locale_de": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js.map" + ] + } + }, + "locale_el": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js.map" + ] + } + }, + "locale_en-GB": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js.map" + ] + } + }, + "locale_en": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js.map" + ] + } + }, + "locale_eo": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js.map" + ] + } + }, + "locale_es-AR": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js.map" + ] + } + }, + "locale_es-MX": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js.map" + ] + } + }, + "locale_es": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js.map" + ] + } + }, + "locale_et": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_et-9957864e54462b54bd25.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_et-9957864e54462b54bd25.chunk.js.map" + ] + } + }, + "locale_eu": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js.map" + ] + } + }, + "locale_fa": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js.map" + ] + } + }, + "locale_fi": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js.map" + ] + } + }, + "locale_fo": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js.map" + ] + } + }, + "locale_fr-QC": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js.map" + ] + } + }, + "locale_fr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js.map" + ] + } + }, + "locale_fy": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js.map" + ] + } + }, + "locale_ga": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js.map" + ] + } + }, + "locale_gd": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js.map" + ] + } + }, + "locale_gl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js.map" + ] + } + }, + "locale_he": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_he-940c5914bccd89572a87.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_he-940c5914bccd89572a87.chunk.js.map" + ] + } + }, + "locale_hi": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js.map" + ] + } + }, + "locale_hr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js.map" + ] + } + }, + "locale_hu": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js.map" + ] + } + }, + "locale_hy": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js.map" + ] + } + }, + "locale_id": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js.map" + ] + } + }, + "locale_ig": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js.map" + ] + } + }, + "locale_io": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js.map" + ] + } + }, + "locale_is": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js.map" + ] + } + }, + "locale_it": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js.map" + ] + } + }, + "locale_ja": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js.map" + ] + } + }, + "locale_ka": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js.map" + ] + } + }, + "locale_kab": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js.map" + ] + } + }, + "locale_kk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kk-806df7189017998308a3.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kk-806df7189017998308a3.chunk.js.map" + ] + } + }, + "locale_kn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js.map" + ] + } + }, + "locale_ko": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js.map" + ] + } + }, + "locale_ku": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js.map" + ] + } + }, + "locale_kw": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js.map" + ] + } + }, + "locale_la": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js.map" + ] + } + }, + "locale_lt": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js.map" + ] + } + }, + "locale_lv": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js.map" + ] + } + }, + "locale_mk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js.map" + ] + } + }, + "locale_ml": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js.map" + ] + } + }, + "locale_mr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js.map" + ] + } + }, + "locale_ms": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js.map" + ] + } + }, + "locale_my": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js.map" + ] + } + }, + "locale_nl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js.map" + ] + } + }, + "locale_nn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js.map" + ] + } + }, + "locale_no": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js.map" + ] + } + }, + "locale_oc": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js.map" + ] + } + }, + "locale_pa": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js.map" + ] + } + }, + "locale_pl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js.map" + ] + } + }, + "locale_pt-BR": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js.map" + ] + } + }, + "locale_pt-PT": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js.map" + ] + } + }, + "locale_ro": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js.map" + ] + } + }, + "locale_ru": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js.map" + ] + } + }, + "locale_sa": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js.map" + ] + } + }, + "locale_sc": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js.map" + ] + } + }, + "locale_sco": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js.map" + ] + } + }, + "locale_si": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_si-17838170f6bebef2861a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_si-17838170f6bebef2861a.chunk.js.map" + ] + } + }, + "locale_sk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js.map" + ] + } + }, + "locale_sl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js.map" + ] + } + }, + "locale_sq": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js.map" + ] + } + }, + "locale_sr-Latn": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js.map" + ] + } + }, + "locale_sr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js.map" + ] + } + }, + "locale_sv": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js.map" + ] + } + }, + "locale_szl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js.map" + ] + } + }, + "locale_ta": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js.map" + ] + } + }, + "locale_tai": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js.map" + ] + } + }, + "locale_te": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js.map" + ] + } + }, + "locale_th": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js.map" + ] + } + }, + "locale_tr": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js.map" + ] + } + }, + "locale_tt": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js.map" + ] + } + }, + "locale_ug": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js.map" + ] + } + }, + "locale_uk": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js.map" + ] + } + }, + "locale_ur": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js.map" + ] + } + }, + "locale_uz": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_uz-38029008a065795c55b7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_uz-38029008a065795c55b7.chunk.js.map" + ] + } + }, + "locale_vi": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js.map" + ] + } + }, + "locale_zgh": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js.map" + ] + } + }, + "locale_zh-CN": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js.map" + ] + } + }, + "locale_zh-HK": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js.map" + ] + } + }, + "locale_zh-TW": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js.map" + ] + } + }, + "dark": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/dark-a3b88036.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/dark-1e375a968d41797e60af.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/dark-a3b88036.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/dark-1e375a968d41797e60af.chunk.js.map" + ] + } + }, + "contrast": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/contrast-5cabd607.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/contrast-393583c54c3047b1a13c.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/contrast-5cabd607.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/contrast-393583c54c3047b1a13c.chunk.js.map" + ] + } + }, + "mastodon-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/mastodon-light-d9270c4c.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/mastodon-light-d9270c4c.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js.map" + ] + } + }, + "wobbl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-88f067e5.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-88f067e5.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js.map" + ] + } + }, + "wobbl-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-light-aae0a2db.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-light-aae0a2db.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js.map" + ] + } + }, + "modern-dark": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-dark-1cfb4c54.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-dark-1cfb4c54.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js.map" + ] + } + }, + "modern-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-light-1c0258de.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-light-1c0258de.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js.map" + ] + } + }, + "modern-light-wobbl": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-light-wobbl-291fe684.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-light-wobbl-291fe684.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js.map" + ] + } + }, + "default": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/default-229799f4.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/default-8b7478aae9e7db81c926.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/default-229799f4.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/default-8b7478aae9e7db81c926.chunk.js.map" + ] + } + }, + "wobbl-old": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-old-41b5a76e.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-old-41b5a76e.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js.map" + ] + } + }, + "wobbl-old-light": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/wobbl-old-light-d2f87f38.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/wobbl-old-light-d2f87f38.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js.map" + ] + } + }, + "modern-dark-wobbl-old": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js.map" + ] + } + }, + "modern-light-wobbl-old": { + "assets": { + "css": [ + "/packs/css/common-a844dc34.css", + "/packs/css/modern-light-wobbl-old-50985752.chunk.css" + ], + "js": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js", + "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js" + ], + "css.map": [ + "/packs/css/common-a844dc34.css.map", + "/packs/css/modern-light-wobbl-old-50985752.chunk.css.map" + ], + "js.map": [ + "/packs/js/common-9da33dbc9762ba5fb40c.js.map", + "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js.map" + ] + } + } + }, + "error.js": { + "src": "/packs/js/error-9aec4316f262805dbab4.chunk.js", + "integrity": "sha256-h9t4X1Ctr0SuSxvzHAKHvNRPSwxrrY7oebKxIQxySBk=" + }, + "error.js.map": { + "src": "/packs/js/error-9aec4316f262805dbab4.chunk.js.map", + "integrity": "sha256-psF6oQh90Aksct2faHnn75dOrCHWElEs0jeyuzdOPp8=" + }, + "extra_polyfills.js": { + "src": "/packs/js/extra_polyfills-986a5c759c7ce45b20f0.chunk.js", + "integrity": "sha256-IbfbaxmjQpCO96TjxZpwytUa/mDckWLewB3KA2CW0C0=" + }, + "extra_polyfills.js.map": { + "src": "/packs/js/extra_polyfills-986a5c759c7ce45b20f0.chunk.js.map", + "integrity": "sha256-PY8UO/dZvCju1KsxfMJ5z918P4fJfRkSOgfd7iVWzCE=" + }, + "features/about.js": { + "src": "/packs/js/features/about-1780ba5ccec34a6fd8bc.chunk.js", + "integrity": "sha256-GOc4LtB/SlB43XLXfOUJLSDv5ZhOHT9ofr1SpT/RkKc=" + }, + "features/about.js.map": { + "src": "/packs/js/features/about-1780ba5ccec34a6fd8bc.chunk.js.map", + "integrity": "sha256-Yiyme4FMjNsKDMz2Dwzx376SYQzuaPrCGbC6Bs1mD8A=" + }, + "features/account_gallery.js": { + "src": "/packs/js/features/account_gallery-43b9c971f6b5d2fad0ae.chunk.js", + "integrity": "sha256-cojN2LWXi9RVlxiv0w+Cqr04tzZDjL6W9nws7BQRWYA=" + }, + "features/account_gallery.js.map": { + "src": "/packs/js/features/account_gallery-43b9c971f6b5d2fad0ae.chunk.js.map", + "integrity": "sha256-tAiBwyNYx+T7bozkk5lAQhLH4leE4WpijnjF6hX2clI=" + }, + "features/account_timeline.js": { + "src": "/packs/js/features/account_timeline-bd75831a69a631b87bd0.chunk.js", + "integrity": "sha256-FICvdjaT4TOPCOUEubS9eBgEYwKG/Bc2cKORbkN+JlY=" + }, + "features/account_timeline.js.map": { + "src": "/packs/js/features/account_timeline-bd75831a69a631b87bd0.chunk.js.map", + "integrity": "sha256-HVPFzIvJ05spKhZKd5q2ilFSa429O5zV0W+NENh2UIE=" + }, + "features/blocks.js": { + "src": "/packs/js/features/blocks-520befb4cfcc5d3664b7.chunk.js", + "integrity": "sha256-h3/JRMNKljdV2VosjYqWWq8icEHIZ3MlhUKNRYRCC8I=" + }, + "features/blocks.js.map": { + "src": "/packs/js/features/blocks-520befb4cfcc5d3664b7.chunk.js.map", + "integrity": "sha256-AqQB2o3bGyHKlALudU8UQ8SXObCIRhO/N5bRKmDpl8I=" + }, + "features/bookmarked_statuses.js": { + "src": "/packs/js/features/bookmarked_statuses-4f2fd2082497e715db43.chunk.js", + "integrity": "sha256-jmI6y/z+ULcT3lWuNy8x7M3PU5FIv5tTUXiSxM5JPCU=" + }, + "features/bookmarked_statuses.js.map": { + "src": "/packs/js/features/bookmarked_statuses-4f2fd2082497e715db43.chunk.js.map", + "integrity": "sha256-xHRBHocZmyizjGoI7tvqYmTvhZVR18AEYKGneJL6NY4=" + }, + "features/community_timeline.js": { + "src": "/packs/js/features/community_timeline-68ad82d6845040826ad2.chunk.js", + "integrity": "sha256-jv+gzNw8AlMY/JX8bK64u8uf4DtIkyu3xX1OFtFuzx4=" + }, + "features/community_timeline.js.map": { + "src": "/packs/js/features/community_timeline-68ad82d6845040826ad2.chunk.js.map", + "integrity": "sha256-uo0lNTTf0UHSJiukJFvFOczexikwPUGp6XZvzLZOHjQ=" + }, + "features/compose.js": { + "src": "/packs/js/features/compose-42b9ec23ecf1cb253911.chunk.js", + "integrity": "sha256-YB3UEO72JDwiTiTT/jFevc8e37QMlTEfKublUSblzww=" + }, + "features/compose.js.map": { + "src": "/packs/js/features/compose-42b9ec23ecf1cb253911.chunk.js.map", + "integrity": "sha256-4rHUv/3Pdfw5H++FEh1W2z6zQYOLMWs9k24V4Pq4pbA=" + }, + "features/direct_timeline.js": { + "src": "/packs/js/features/direct_timeline-7e13d467a7e34a1c91e8.chunk.js", + "integrity": "sha256-dUCXDUokpyPOAawf8R9Y8k6WfiDS0WRzc6ldO4PmE3c=" + }, + "features/direct_timeline.js.map": { + "src": "/packs/js/features/direct_timeline-7e13d467a7e34a1c91e8.chunk.js.map", + "integrity": "sha256-q/pP26txerzPKBcPt03IEajGHze2XQBIGrsWO2xa+Ow=" + }, + "features/directory.js": { + "src": "/packs/js/features/directory-7e0a4b6e741808cedc7a.chunk.js", + "integrity": "sha256-3yiafpWhsMFOPmYN6ICU4GnR/8I6zZapGiUL2JaXibI=" + }, + "features/directory.js.map": { + "src": "/packs/js/features/directory-7e0a4b6e741808cedc7a.chunk.js.map", + "integrity": "sha256-/awgeVDYw3UBo48wc1s2lfA9JwkNVIV4DlExhzbY2c0=" + }, + "features/domain_blocks.js": { + "src": "/packs/js/features/domain_blocks-08e0f9af26979e7fb010.chunk.js", + "integrity": "sha256-nRKlZm+olWkxsyg15fced2a2Hrz/EgrL1F5COcNkLqw=" + }, + "features/domain_blocks.js.map": { + "src": "/packs/js/features/domain_blocks-08e0f9af26979e7fb010.chunk.js.map", + "integrity": "sha256-v54vgT9BX4eBCqf4SkQd4hLbCxEhBijJ+453F1B9IHE=" + }, + "features/explore.js": { + "src": "/packs/js/features/explore-ebedda7bc800a5976a26.chunk.js", + "integrity": "sha256-KkrLL4KjJ1/nwK1ZBIzviP5dZK9WaHT8TwD2ncH5ugI=" + }, + "features/explore.js.map": { + "src": "/packs/js/features/explore-ebedda7bc800a5976a26.chunk.js.map", + "integrity": "sha256-8lwfc1Y3K++/RpqamsymSaGSwZeIL2PMY786V/PZIMY=" + }, + "features/favourited_statuses.js": { + "src": "/packs/js/features/favourited_statuses-328e07362d25feb2f4aa.chunk.js", + "integrity": "sha256-qgIsFKIuNFqcoRfX8wKeciYT5ZDqZOShCV5NMdGk2z0=" + }, + "features/favourited_statuses.js.map": { + "src": "/packs/js/features/favourited_statuses-328e07362d25feb2f4aa.chunk.js.map", + "integrity": "sha256-1oqKRRDeLzHIlL3u/PZBELMFcQZzlRUjDvcetioF25g=" + }, + "features/favourites.js": { + "src": "/packs/js/features/favourites-1ad8debadf728dd45baa.chunk.js", + "integrity": "sha256-OdsOSwL7Yb8E50tJm5mehZbzqEKnC1A9MSouYqva43Q=" + }, + "features/favourites.js.map": { + "src": "/packs/js/features/favourites-1ad8debadf728dd45baa.chunk.js.map", + "integrity": "sha256-qH4u4yegkprK1kNgAy0pviIHxBIGK75UV+Zo3Ycw/m4=" + }, + "features/follow_recommendations.js": { + "src": "/packs/js/features/follow_recommendations-c33a6a51282ffb98ed74.chunk.js", + "integrity": "sha256-jb1nPq8lPW5iOWbZ2TyjYSxzXr6Ro/0nPlbtY4FFYsU=" + }, + "features/follow_recommendations.js.map": { + "src": "/packs/js/features/follow_recommendations-c33a6a51282ffb98ed74.chunk.js.map", + "integrity": "sha256-Z2kQYh17dXi9l/nqIWDFte1XvfJfMAVnAdQpcg5Mdig=" + }, + "features/follow_requests.js": { + "src": "/packs/js/features/follow_requests-d38d490b8ffaef0b9c1d.chunk.js", + "integrity": "sha256-r2LVVHRVMOwcDr+q6zmlroBo5pJYLPMADpP3NhagpQU=" + }, + "features/follow_requests.js.map": { + "src": "/packs/js/features/follow_requests-d38d490b8ffaef0b9c1d.chunk.js.map", + "integrity": "sha256-1klRMHrS1T/1aNvdj1E+mPDh8mimFkV24apjtT7gph8=" + }, + "features/followed_tags.js": { + "src": "/packs/js/features/followed_tags-40edb1def48ffb16eaad.chunk.js", + "integrity": "sha256-FXJ1K6hnUN/Kg33RKlR2wWJfyT2zNpiIiTFaNREsKS4=" + }, + "features/followed_tags.js.map": { + "src": "/packs/js/features/followed_tags-40edb1def48ffb16eaad.chunk.js.map", + "integrity": "sha256-s9ADcBf1CwjgsNJSRUXadV20mIzUZpDpT/jKVAaXs/Y=" + }, + "features/followers.js": { + "src": "/packs/js/features/followers-da441e6654c2a8725cf9.chunk.js", + "integrity": "sha256-xgQ2szg6cu+lF879A+YvNbA7qmJ//ZWjYtlJmhRxj2U=" + }, + "features/followers.js.map": { + "src": "/packs/js/features/followers-da441e6654c2a8725cf9.chunk.js.map", + "integrity": "sha256-43OmxvB2htNXTK+uFoi8JgoMqsO7qvQC8LLl3UJSV/U=" + }, + "features/following.js": { + "src": "/packs/js/features/following-e3684a6d630329f76e39.chunk.js", + "integrity": "sha256-2awJyRg3GCG5K57dG2AgYa/4yzfG8/5uquFQtMLGEF0=" + }, + "features/following.js.map": { + "src": "/packs/js/features/following-e3684a6d630329f76e39.chunk.js.map", + "integrity": "sha256-3ae2xZSiNHCzBPqHdRmka8+u85PB3YeBRZxc14+r1zw=" + }, + "features/generic_not_found.js": { + "src": "/packs/js/features/generic_not_found-89f2836a6221235141be.chunk.js", + "integrity": "sha256-e9D7skCXophOpTG6HdFvu/7K4/7xWEHjtIBggz9Ep2w=" + }, + "features/generic_not_found.js.map": { + "src": "/packs/js/features/generic_not_found-89f2836a6221235141be.chunk.js.map", + "integrity": "sha256-6MDE5LFvRKSetIjrYWoBIieX4j6lAezLdxysNlBlB9o=" + }, + "features/getting_started.js": { + "src": "/packs/js/features/getting_started-1b714b058a8b2a8d3a62.chunk.js", + "integrity": "sha256-dsYg+PR/1R2PJY/b6H+0Z1bCPHPuXcbLnGmHcoy9lfk=" + }, + "features/getting_started.js.map": { + "src": "/packs/js/features/getting_started-1b714b058a8b2a8d3a62.chunk.js.map", + "integrity": "sha256-dGaJ1xbFzEfeEm24YSEhs6IwL/Cs99mjRgIMZ8oWB44=" + }, + "features/hashtag_timeline.js": { + "src": "/packs/js/features/hashtag_timeline-eeafb06a34c51d00c0fe.chunk.js", + "integrity": "sha256-cxr3cKXFKh2GZTZ9frq4oMrcN3lGdzSUwvywXV+ewFM=" + }, + "features/hashtag_timeline.js.map": { + "src": "/packs/js/features/hashtag_timeline-eeafb06a34c51d00c0fe.chunk.js.map", + "integrity": "sha256-87Z1nZRZH0RY5iEWroV/VFh5UQOsp+ZmUC9sCRQIc4k=" + }, + "features/home_timeline.js": { + "src": "/packs/js/features/home_timeline-929f3815cc493564611a.chunk.js", + "integrity": "sha256-tD2dR6Y7JA/7VoTsYgjMOOVU4z37u5DQkMsydI45uvQ=" + }, + "features/home_timeline.js.map": { + "src": "/packs/js/features/home_timeline-929f3815cc493564611a.chunk.js.map", + "integrity": "sha256-RW7Q9irq3tG1bYzC2XF4FqJxV9yiFoeHsJkB7i6caMM=" + }, + "features/keyboard_shortcuts.js": { + "src": "/packs/js/features/keyboard_shortcuts-83eb9db76d2c748ae986.chunk.js", + "integrity": "sha256-6JrzbtFclxD4tKs9OfThaT8oJMyAapOc2hkHT4KQQ7g=" + }, + "features/keyboard_shortcuts.js.map": { + "src": "/packs/js/features/keyboard_shortcuts-83eb9db76d2c748ae986.chunk.js.map", + "integrity": "sha256-DnTrSlVz2kWspCeevgE+ucqJTr+DceEppa8Ukdg5NQE=" + }, + "features/list_adder.js": { + "src": "/packs/js/features/list_adder-694c55136cb9b44a857c.chunk.js", + "integrity": "sha256-9u2oKtOjK824n715L+SrDLsWpVYpXbRF0UFrJIkO/iM=" + }, + "features/list_adder.js.map": { + "src": "/packs/js/features/list_adder-694c55136cb9b44a857c.chunk.js.map", + "integrity": "sha256-fNZoayKBziG9tDymet/aYa7394N1VjjyH0vUZL2FzNo=" + }, + "features/list_editor.js": { + "src": "/packs/js/features/list_editor-9438254dac1fae33280d.chunk.js", + "integrity": "sha256-UHvkiQNbQrk/6/d3Tn7qF8z63kPVyBiDNNmIxj6yi8s=" + }, + "features/list_editor.js.map": { + "src": "/packs/js/features/list_editor-9438254dac1fae33280d.chunk.js.map", + "integrity": "sha256-0EMMbm/RdSV1ERHtp+OYKXecWE1/54J68YyRXxJo+wU=" + }, + "features/list_timeline.js": { + "src": "/packs/js/features/list_timeline-f796e1b02420e7a919ea.chunk.js", + "integrity": "sha256-7qvKQAdrdcCJO93zvLC6ZN3pKZFWw3uSC/BquE7Jq7I=" + }, + "features/list_timeline.js.map": { + "src": "/packs/js/features/list_timeline-f796e1b02420e7a919ea.chunk.js.map", + "integrity": "sha256-9ExEg86aMLYrQQUOr/auZ3psdRfhYV37YwTx3GCna5M=" + }, + "features/lists.js": { + "src": "/packs/js/features/lists-acaa219c64ce85b1ee60.chunk.js", + "integrity": "sha256-cmbriFBNRMkdUTmvZ4D7BdojybIqKtm+DqJdZ5y8NHA=" + }, + "features/lists.js.map": { + "src": "/packs/js/features/lists-acaa219c64ce85b1ee60.chunk.js.map", + "integrity": "sha256-r+YX3FidnaAi2rrT1LzNRds2TVPLwA32LTNtsVtYDv0=" + }, + "features/mutes.js": { + "src": "/packs/js/features/mutes-f1313ec5af4e39f4dc9c.chunk.js", + "integrity": "sha256-xPNUwkLdfVUqawKE74uOT3wEGp/QWmL6BJP/W2Eke0E=" + }, + "features/mutes.js.map": { + "src": "/packs/js/features/mutes-f1313ec5af4e39f4dc9c.chunk.js.map", + "integrity": "sha256-NK4YJEpjdUgryhZcy2e22b0dB0rp0ZNYVx7sWFVmzgc=" + }, + "features/notifications.js": { + "src": "/packs/js/features/notifications-2c51c8a4a8ccc70a63c0.chunk.js", + "integrity": "sha256-kB/pbIR155eRRtEVDVYkSLXBGioCTLL8uyVKusxPE8Q=" + }, + "features/notifications.js.map": { + "src": "/packs/js/features/notifications-2c51c8a4a8ccc70a63c0.chunk.js.map", + "integrity": "sha256-bZMwQmrdY8ZUMqzbQq9i9q411dRio4Sz1VT9qQvkRHQ=" + }, + "features/pinned_statuses.js": { + "src": "/packs/js/features/pinned_statuses-afc39764d48b37b80ba6.chunk.js", + "integrity": "sha256-l2jVvcI5OI7PdMC8pRd+kwcgF166Z/v65Ehs4kj94FA=" + }, + "features/pinned_statuses.js.map": { + "src": "/packs/js/features/pinned_statuses-afc39764d48b37b80ba6.chunk.js.map", + "integrity": "sha256-babaIJH3mvEIVCBOFbnMYOrcof2ypI03mXecroTM6wk=" + }, + "features/privacy_policy.js": { + "src": "/packs/js/features/privacy_policy-98df21ce8d336a5c909f.chunk.js", + "integrity": "sha256-qlWFdthfeuL4BTYMPaz95uEMBPry2fZzwdXLJaGLxC8=" + }, + "features/privacy_policy.js.map": { + "src": "/packs/js/features/privacy_policy-98df21ce8d336a5c909f.chunk.js.map", + "integrity": "sha256-DhcegLw8YuA8hyTrTMzyntPoJ36CCueI5tQjD8z6+/U=" + }, + "features/public_timeline.js": { + "src": "/packs/js/features/public_timeline-3c694db7db09581f9814.chunk.js", + "integrity": "sha256-kEfDWogw0052Hwsk4qiWYuj5pFat+WFVDmMdg/R39mE=" + }, + "features/public_timeline.js.map": { + "src": "/packs/js/features/public_timeline-3c694db7db09581f9814.chunk.js.map", + "integrity": "sha256-rTlpNO1SnLlgp5eQN1jXFRnSsLOq7nNGFk9WLGcfcXA=" + }, + "features/reblogs.js": { + "src": "/packs/js/features/reblogs-e61e4f722a862d2d1bf3.chunk.js", + "integrity": "sha256-3i1xZsxguhO+gjcxs91o0hKJOOKYM86PrwRArvYWp4Q=" + }, + "features/reblogs.js.map": { + "src": "/packs/js/features/reblogs-e61e4f722a862d2d1bf3.chunk.js.map", + "integrity": "sha256-kFsPnFNZAaGVhEVtysCGXyPvfOXJ273lXH47Cf5fFKc=" + }, + "features/status.js": { + "src": "/packs/js/features/status-b229e1d9012139273e09.chunk.js", + "integrity": "sha256-D5N9sUhZ/rWhAi1cJMEOeNWikDIXDKx4H7TqVLBFG5k=" + }, + "features/status.js.map": { + "src": "/packs/js/features/status-b229e1d9012139273e09.chunk.js.map", + "integrity": "sha256-wZ8uluF2bKCDdsMXuswQBbr8sMxzFfgyeAkGY6qdxhQ=" + }, + "js/1-4f08bea894e3d7ced52a.chunk.js": { + "src": "/packs/js/1-4f08bea894e3d7ced52a.chunk.js", + "integrity": "sha256-W6au4yjVCPby2YZpuzRWaZaUB2ByDrDxaTpGwbyG540=" + }, + "js/1-4f08bea894e3d7ced52a.chunk.js.map": { + "src": "/packs/js/1-4f08bea894e3d7ced52a.chunk.js.map", + "integrity": "sha256-owtIty3jsLF/knrVLfl4P166wXe/ONz91SZqA3k5Fec=" + }, + "js/173-91bb2c0776a21ff5f203.chunk.js": { + "src": "/packs/js/173-91bb2c0776a21ff5f203.chunk.js", + "integrity": "sha256-Nm9RxdRKVGq32UFYV5yb+7K2ikWzBDYyTg/XrUjRIQg=" + }, + "js/173-91bb2c0776a21ff5f203.chunk.js.map": { + "src": "/packs/js/173-91bb2c0776a21ff5f203.chunk.js.map", + "integrity": "sha256-y8KUC8NiFHFS3+zg71VETNXObdZereqlem4sFNSK3aE=" + }, + "js/174-5d5b87c3cf374832f4c6.chunk.js": { + "src": "/packs/js/174-5d5b87c3cf374832f4c6.chunk.js", + "integrity": "sha256-PPMJpNfW8myDvafLzZicuUVc9RWJQBzccu+Rry0nvlU=" + }, + "js/174-5d5b87c3cf374832f4c6.chunk.js.map": { + "src": "/packs/js/174-5d5b87c3cf374832f4c6.chunk.js.map", + "integrity": "sha256-+fr/c4UKYS2JSS8xEjNgxIp/wKCkv+pivvZ53Zz1tQ0=" + }, + "js/175-44abe411af23889c1804.chunk.js": { + "src": "/packs/js/175-44abe411af23889c1804.chunk.js", + "integrity": "sha256-r520lpv8O8RN3V0DOECych6Xxoeez7XphWlS1fDgu3Y=" + }, + "js/175-44abe411af23889c1804.chunk.js.map": { + "src": "/packs/js/175-44abe411af23889c1804.chunk.js.map", + "integrity": "sha256-D0wkWkNfdjnKtI3b7723pIuiWViwA3+4jZp9VhuI+nk=" + }, + "js/2-7904cb94a6d1b97a570c.chunk.js": { + "src": "/packs/js/2-7904cb94a6d1b97a570c.chunk.js", + "integrity": "sha256-aX3q1iy18AG+/w+JT7eUzI0md73PA+zvnQVhNtHqRWc=" + }, + "js/2-7904cb94a6d1b97a570c.chunk.js.map": { + "src": "/packs/js/2-7904cb94a6d1b97a570c.chunk.js.map", + "integrity": "sha256-52FGTK+9me8SOgLDvhK8YA8/mIZdGxIB1/vfse2nrH8=" + }, + "js/3-7e9194f0476ed145bc37.chunk.js": { + "src": "/packs/js/3-7e9194f0476ed145bc37.chunk.js", + "integrity": "sha256-Fm/nlqhYCpByMII2ILlnLR7bXc4BiIhjj5jph8cdVeE=" + }, + "js/3-7e9194f0476ed145bc37.chunk.js.map": { + "src": "/packs/js/3-7e9194f0476ed145bc37.chunk.js.map", + "integrity": "sha256-hnLi4iRuYaPFmYudBS2dKYW5x59qmhufHN3ephGh4Wk=" + }, + "js/4-30ed5e9610faa481148c.chunk.js": { + "src": "/packs/js/4-30ed5e9610faa481148c.chunk.js", + "integrity": "sha256-Hvj2lO4/74ZP0t7RO222lK1+QCtWR4KHOR/AYklrK/0=" + }, + "js/4-30ed5e9610faa481148c.chunk.js.map": { + "src": "/packs/js/4-30ed5e9610faa481148c.chunk.js.map", + "integrity": "sha256-KOv05CDwEcvXl6aTXqfkG0jyfprzpAZmdk4FFT5f/U4=" + }, + "js/5-048aaf12b2f542259d73.chunk.js": { + "src": "/packs/js/5-048aaf12b2f542259d73.chunk.js", + "integrity": "sha256-wix30LF7d/ZfUnsQaNpXoZQMu0r1ndcWJoHOtnncWV4=" + }, + "js/5-048aaf12b2f542259d73.chunk.js.map": { + "src": "/packs/js/5-048aaf12b2f542259d73.chunk.js.map", + "integrity": "sha256-cJ+cveLA+i7dfi+W/fF2WI7sO4Kph7wVTMlLwltFk0w=" + }, + "js/common-9da33dbc9762ba5fb40c.js.LICENSE.txt": { + "src": "/packs/js/common-9da33dbc9762ba5fb40c.js.LICENSE.txt", + "integrity": "sha256-hWo228Md1YZAmYGmNqneO3nDiy30YDNXCW9VfXHNi10=" + }, + "locale_af.js": { + "src": "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js", + "integrity": "sha256-WR6imeagC/fGqDrh3sNFizJCj/XufMNvFDiMeuJYq38=" + }, + "locale_af.js.map": { + "src": "/packs/js/locale_af-e17e859f1a8ec0b25300.chunk.js.map", + "integrity": "sha256-6OSJijYWu+6ZuviYVvLCCPvoqWoZQGKGe915xOrU7fo=" + }, + "locale_an.js": { + "src": "/packs/js/locale_an-7042264d7263706588ca.chunk.js", + "integrity": "sha256-cAxeY9HS2+KP5+DFRTalgrZ58te3oxYY8e8C/GmgU9k=" + }, + "locale_an.js.map": { + "src": "/packs/js/locale_an-7042264d7263706588ca.chunk.js.map", + "integrity": "sha256-TIqCy6vAeWTun8DHpdsIg/d1iXSHX+nrTbOYoMeeKeo=" + }, + "locale_ar.js": { + "src": "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js", + "integrity": "sha256-Hw/mGiKXwVbjCPBFyeKEshWELXbJ3dZTREHDON6SlbM=" + }, + "locale_ar.js.map": { + "src": "/packs/js/locale_ar-1da106fc18da5fd7f5cf.chunk.js.map", + "integrity": "sha256-5KzvXP9MwbDlSQOoBKvK3v7O1BYE2lG0SGWWHdJQNe8=" + }, + "locale_ast.js": { + "src": "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js", + "integrity": "sha256-JUj5MgrxCyYEm5qJpksQ8KkA4HXYogB4ykDT3VB7jsg=" + }, + "locale_ast.js.map": { + "src": "/packs/js/locale_ast-0c628628ab2864822ee4.chunk.js.map", + "integrity": "sha256-c71oAoERZwNiAAVmefjYGm2+eYTpIn9A+i4/Al/yzQI=" + }, + "locale_be.js": { + "src": "/packs/js/locale_be-2b73894a107f7474274e.chunk.js", + "integrity": "sha256-2vwj92qeICaX7xdKZlwWZUbb7H7POmu4x7HUFflGHUA=" + }, + "locale_be.js.map": { + "src": "/packs/js/locale_be-2b73894a107f7474274e.chunk.js.map", + "integrity": "sha256-KA1A3nBLys0vAW0FGLvxlw6oG/JoCZN25yl/G3IK3OA=" + }, + "locale_bg.js": { + "src": "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js", + "integrity": "sha256-hhlhzvxCFmntuyqCqQLuyZGEjXNCkxe0yh/T1+448Lo=" + }, + "locale_bg.js.map": { + "src": "/packs/js/locale_bg-6ee3a74a46eceac1a250.chunk.js.map", + "integrity": "sha256-QTTQrVU+O6DlvKzE9/NHzJR1mdfY65v+Jv4u6WTZoRI=" + }, + "locale_bn.js": { + "src": "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js", + "integrity": "sha256-dOY/E8CVwGQ21CzN8ww7YqWcnpSFAuk6UP865s1ugwM=" + }, + "locale_bn.js.map": { + "src": "/packs/js/locale_bn-ae68c98c0afc4bfc4b2e.chunk.js.map", + "integrity": "sha256-nwULTJvuuJ9nUCnzp3PRwpsKRG5AewuTYc9FLrndGco=" + }, + "locale_br.js": { + "src": "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js", + "integrity": "sha256-W73qBtotwAWoe6i8l0LgyyTn7cHSufvN6m0B3qtRoG8=" + }, + "locale_br.js.map": { + "src": "/packs/js/locale_br-4f876ba533be3e727f6d.chunk.js.map", + "integrity": "sha256-4O+Rbrui0yZSjO2olJFYWSbnVFOVC0rBaYUUM7AsNcg=" + }, + "locale_bs.js": { + "src": "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js", + "integrity": "sha256-N3Y0DqjCIlkjV/e75wXyXuf+1VwZmf3ti1eWImdZcPM=" + }, + "locale_bs.js.map": { + "src": "/packs/js/locale_bs-177c72486175e64f5d08.chunk.js.map", + "integrity": "sha256-x1D4TDyF46bKKVZT5VihyNJxFuDYBI69auVt9oL8Hn8=" + }, + "locale_ca.js": { + "src": "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js", + "integrity": "sha256-iAcMn2aFTDLSZXZkG1pSZ+LDP0GYB1t0NN6euMjk52A=" + }, + "locale_ca.js.map": { + "src": "/packs/js/locale_ca-90e39a48130142e3e483.chunk.js.map", + "integrity": "sha256-WHzVXq6bXJFtYr1m9RYUy9bXrHjhYQ2nQZUgx64LtgY=" + }, + "locale_ckb.js": { + "src": "/packs/js/locale_ckb-bac2365515303c579326.chunk.js", + "integrity": "sha256-nl2/+tYeeTqnlnM2uaXgGXnsqkLJuDrVHS/I8o+gTeg=" + }, + "locale_ckb.js.map": { + "src": "/packs/js/locale_ckb-bac2365515303c579326.chunk.js.map", + "integrity": "sha256-2VFhqwDHmPVjoAJ5QUQsOJiTZU7hf3ERNxe0BBMztmM=" + }, + "locale_co.js": { + "src": "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js", + "integrity": "sha256-1xTLG/9ZESJSBJVagHoTvPjSQ9/+5ArYUtOzWSmHxlo=" + }, + "locale_co.js.map": { + "src": "/packs/js/locale_co-460970a25e28394ef7ce.chunk.js.map", + "integrity": "sha256-pZbO05d87UrxDKTeyxSmYyldO2o2TUtu7woepeortYE=" + }, + "locale_cs.js": { + "src": "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js", + "integrity": "sha256-dtcupSFSPA1KQkLyC2Qvswz3zJahQtFbLJAT3WC5lKs=" + }, + "locale_cs.js.map": { + "src": "/packs/js/locale_cs-5d59c8dcd842835bf754.chunk.js.map", + "integrity": "sha256-PWwZGNYeGlpnkrom0nIFKAX0QSclhc2uZKPdjaQaSWA=" + }, + "locale_csb.js": { + "src": "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js", + "integrity": "sha256-J4jWNRkrOloMRSZUXmGZiLV5UVbZTOFmNd2y7zBCygM=" + }, + "locale_csb.js.map": { + "src": "/packs/js/locale_csb-2a739084b880f71206a2.chunk.js.map", + "integrity": "sha256-MIH/2lcke3Jpc2kUbW5qrmydm/uajVrVlgt6MBkts9A=" + }, + "locale_cy.js": { + "src": "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js", + "integrity": "sha256-iTWuSdqhqE867oEfXNN0Dib5a5p5zLDK/t02Zt0/Leo=" + }, + "locale_cy.js.map": { + "src": "/packs/js/locale_cy-38cc5184af285ba71bb6.chunk.js.map", + "integrity": "sha256-JMIERda8hWQujDYv6Swi4UO4x89969r4y7rJ40fV7kI=" + }, + "locale_da.js": { + "src": "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js", + "integrity": "sha256-cz+s9fp1ipoJ/wI9LRW4npf8vcyN0UVt3O3F91gex6Q=" + }, + "locale_da.js.map": { + "src": "/packs/js/locale_da-e7d17b053e28a2231bd5.chunk.js.map", + "integrity": "sha256-eiZEPeDlBlSEK8mcC5LhE2sPCk6QhBib9QXbFMHR2f0=" + }, + "locale_de.js": { + "src": "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js", + "integrity": "sha256-zODoZZhLwmOBCHv0OSBpB0DjSscp+/JzG7dIWoh8dIA=" + }, + "locale_de.js.map": { + "src": "/packs/js/locale_de-f9095dd5d861aee7c39f.chunk.js.map", + "integrity": "sha256-xmyIlEvliCIoiFQoS7uSx7CX09YiBIS/lrY23s9GjGo=" + }, + "locale_el.js": { + "src": "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js", + "integrity": "sha256-z9n58WLCj40IQo16slVtLfK/NKhLLIurr70WReLuI/E=" + }, + "locale_el.js.map": { + "src": "/packs/js/locale_el-edbc55fe9652661d16bb.chunk.js.map", + "integrity": "sha256-66Mg9bS70qeSF4AjDhRjZ/3C2PElQ/vKepSBd+Px/E0=" + }, + "locale_en-GB.js": { + "src": "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js", + "integrity": "sha256-SALgj+/GpFcOXNUnpTU5DqDo2ufixeAYKDvbzkCAtZE=" + }, + "locale_en-GB.js.map": { + "src": "/packs/js/locale_en-GB-66f1ae018b2aabc910f8.chunk.js.map", + "integrity": "sha256-nF9uKaWaheXfvcgQYBOcQ/ajnZDKXouwDzAi/mcDTlk=" + }, + "locale_en.js": { + "src": "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js", + "integrity": "sha256-cT1gYpk/YsvJCEZlFtqKFsblKN2t+5zHKooixAp+TUI=" + }, + "locale_en.js.map": { + "src": "/packs/js/locale_en-3a1b6a629390d09dfacc.chunk.js.map", + "integrity": "sha256-R6Gj+NXGMEGxTxq4DqUWgzxq9+aPglyaMG1ADIgWT3o=" + }, + "locale_eo.js": { + "src": "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js", + "integrity": "sha256-H3iZ9xIQ1eagIdYH7iBoVuRFgVDAxBj6hiShdZySSYc=" + }, + "locale_eo.js.map": { + "src": "/packs/js/locale_eo-fac46eca25cf22ec45cf.chunk.js.map", + "integrity": "sha256-Ae9mMI4P01MM4QDJf5tSWzcCvB9n+qIyMTHWv+lApk4=" + }, + "locale_es-AR.js": { + "src": "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js", + "integrity": "sha256-gqbdgNdLPcRTageIejS73It5jWU9xW5necdFrAX1WYU=" + }, + "locale_es-AR.js.map": { + "src": "/packs/js/locale_es-AR-d3b9b6ce47daeffb06f7.chunk.js.map", + "integrity": "sha256-8KON1RnBdnDUWvXViHepR28l/8HqZNdMlaN8HX81t6o=" + }, + "locale_es-MX.js": { + "src": "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js", + "integrity": "sha256-AiQb14GSBQ0NtoeqdDvPbC7KTKxgAZwYlKMZ3T0peDE=" + }, + "locale_es-MX.js.map": { + "src": "/packs/js/locale_es-MX-f2d22ad3a63f61da7142.chunk.js.map", + "integrity": "sha256-HLLsGDqLDYnZR4i1EBZiii3Dv7xL7TCee7DlkkwofMw=" + }, + "locale_es.js": { + "src": "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js", + "integrity": "sha256-l1EDProxifZUfo0sSWq46toIIygJYxsNa9MSqoQEHhI=" + }, + "locale_es.js.map": { + "src": "/packs/js/locale_es-5d9ad503ecde09f3c9f4.chunk.js.map", + "integrity": "sha256-qSg+GX+ju4hEJrYKs/S3doD+bqK5CNweEh/bQbs9d6Q=" + }, + "locale_et.js": { + "src": "/packs/js/locale_et-9957864e54462b54bd25.chunk.js", + "integrity": "sha256-E6ET/WSdz9LyvaS8yIKJ+vhdCz1CnRwvKRnknE2hrMM=" + }, + "locale_et.js.map": { + "src": "/packs/js/locale_et-9957864e54462b54bd25.chunk.js.map", + "integrity": "sha256-Q7TDj3rWzKKaiNuwpZQ3BnVx7afghd4aEiHuSseF8pE=" + }, + "locale_eu.js": { + "src": "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js", + "integrity": "sha256-ZoVoUf01U07qYF8uhXmOnPwAQqFFzrrkzgZdlgrmNV4=" + }, + "locale_eu.js.map": { + "src": "/packs/js/locale_eu-13784c9b52ca102cfbc2.chunk.js.map", + "integrity": "sha256-Gs5ujTHebd7kPKbldzobEDmLc42YnE4qNfjzNtVBmpw=" + }, + "locale_fa.js": { + "src": "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js", + "integrity": "sha256-zIVyyyumrPfe7LsT/hhALqt46i4I2AeNF1VdC3Vfo2M=" + }, + "locale_fa.js.map": { + "src": "/packs/js/locale_fa-dbfa497ba9931ec984d0.chunk.js.map", + "integrity": "sha256-462Z8TfMtQrbChC1VDKE4NdrdxiTexLOLXansI2WZ+c=" + }, + "locale_fi.js": { + "src": "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js", + "integrity": "sha256-+DDW231rtFLvAmI0sdkuEmKVvdSbGzV+LQ3htlk/NKQ=" + }, + "locale_fi.js.map": { + "src": "/packs/js/locale_fi-7874c3cf663f9e8ae73b.chunk.js.map", + "integrity": "sha256-Byf9vSW7/p63+SpFwdVkDAk7yQvKZV9ouNKPIzmEUlM=" + }, + "locale_fo.js": { + "src": "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js", + "integrity": "sha256-gT1g4PAUd4cpKgSF9Zag0n4tywbMN29j/s3+ZnxXyMY=" + }, + "locale_fo.js.map": { + "src": "/packs/js/locale_fo-09b9595a2b40c5588882.chunk.js.map", + "integrity": "sha256-GxleTbIpCfE3+GXo0tEPsB9q2K73NDOnP73dPmWHmP0=" + }, + "locale_fr-QC.js": { + "src": "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js", + "integrity": "sha256-///I5zl62oZGmK2ynRp+dzCh0+GMXItPy2dzmEeROKU=" + }, + "locale_fr-QC.js.map": { + "src": "/packs/js/locale_fr-QC-b4aad9abb0bcca611977.chunk.js.map", + "integrity": "sha256-p0lX1t+NiAXkzBNLpb+3fwgDG5pGgqeGz3yx4tMyE+w=" + }, + "locale_fr.js": { + "src": "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js", + "integrity": "sha256-hDSDncSCcNjzG4MJ9KaVKPEIkiOMp/YOFBPGphs3hGY=" + }, + "locale_fr.js.map": { + "src": "/packs/js/locale_fr-1986d9b703e0cb0a86e7.chunk.js.map", + "integrity": "sha256-70OHPL8PIWcGVkRupKigT/u+ydbVa5flkZUtOfCUFro=" + }, + "locale_fy.js": { + "src": "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js", + "integrity": "sha256-Z42P5P67PA6P3FV7oSKXtM/OZa+yGRGNC1Z2eGr+sU8=" + }, + "locale_fy.js.map": { + "src": "/packs/js/locale_fy-2746d87041d2e9509489.chunk.js.map", + "integrity": "sha256-Es6HCxEO7mcdMDFVvjfWKp8Gqlb4X+ugm+f3H+qCbxM=" + }, + "locale_ga.js": { + "src": "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js", + "integrity": "sha256-YNLKbLfg2muzu9T/qa6s1JRum6NPQBLcMXxdDA7Tedk=" + }, + "locale_ga.js.map": { + "src": "/packs/js/locale_ga-8ad993633f5fef580f38.chunk.js.map", + "integrity": "sha256-w1uMZHqxD2lkg9xr65z19fumPnnLuMkTUcYsknO9l34=" + }, + "locale_gd.js": { + "src": "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js", + "integrity": "sha256-zROzrkQA0Xe9joJbt6gHyQkg5mKxOdhHA4Afn20IXPM=" + }, + "locale_gd.js.map": { + "src": "/packs/js/locale_gd-2a88db839f75ac81d29a.chunk.js.map", + "integrity": "sha256-78pscx7tXZJ3mXCgWY3gZy0vWIL8r/pfGvxyqYsor1Q=" + }, + "locale_gl.js": { + "src": "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js", + "integrity": "sha256-oYj5S+SMwtuXuUDAe64jAQAhOZGsO2zhtSGFMd34JU4=" + }, + "locale_gl.js.map": { + "src": "/packs/js/locale_gl-d47f165ca404e333cf96.chunk.js.map", + "integrity": "sha256-3H9lSRGbru/3MODU74CWTqYt9qOeSBnlW2Gjq3gkLdI=" + }, + "locale_he.js": { + "src": "/packs/js/locale_he-940c5914bccd89572a87.chunk.js", + "integrity": "sha256-qJJGuBnFhz9aKi+Vpzk53qLoUkX84E6G5f1Z4sIac6s=" + }, + "locale_he.js.map": { + "src": "/packs/js/locale_he-940c5914bccd89572a87.chunk.js.map", + "integrity": "sha256-B6nhxDzy7nhgnc715B+351rt70wLmURUaM/hIxpGFho=" + }, + "locale_hi.js": { + "src": "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js", + "integrity": "sha256-nVi8zJud6mqM0+namCZYZODKkfIpwDMom+qTrKaewsg=" + }, + "locale_hi.js.map": { + "src": "/packs/js/locale_hi-f99ada1f9f8dbd8fc430.chunk.js.map", + "integrity": "sha256-2i13JQaVXothK19ESqYHEMp6UsxiBXDwiXbX3TNIdtg=" + }, + "locale_hr.js": { + "src": "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js", + "integrity": "sha256-BWOd3SUq/wnXbc6sKn7U5ZCw/TSgtbh5YPdn+V7bZek=" + }, + "locale_hr.js.map": { + "src": "/packs/js/locale_hr-bba3073a13bbbb7d61f0.chunk.js.map", + "integrity": "sha256-wKp/7BM243tHBp7xq+xJzJrCKkuDv8PByF/lmdbRRR0=" + }, + "locale_hu.js": { + "src": "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js", + "integrity": "sha256-gJVl/VVtSBLTA6yZqvOxYiDJyV3bTFfZ5tz9Gd0NE+Q=" + }, + "locale_hu.js.map": { + "src": "/packs/js/locale_hu-5cd8f082d94dd1a2af42.chunk.js.map", + "integrity": "sha256-ptYfpIkVQsy20P+zVlEZk1avLcRLZ83h22HO5dgLrHc=" + }, + "locale_hy.js": { + "src": "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js", + "integrity": "sha256-mAkZBjgQ7WUIMG7kUDnGgD/k2IwbKgEmU/hUsISIljs=" + }, + "locale_hy.js.map": { + "src": "/packs/js/locale_hy-2dd9487107e4867cbf6a.chunk.js.map", + "integrity": "sha256-uFswh5tMkmtBqFA4P+Em/FgE/eAKJhxouZCFdFik8yU=" + }, + "locale_id.js": { + "src": "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js", + "integrity": "sha256-9AtjWka/o0CuxiaOhPnEq35j/8GzPzhb94+bOjvRqsQ=" + }, + "locale_id.js.map": { + "src": "/packs/js/locale_id-12707db198fc2c6c20a4.chunk.js.map", + "integrity": "sha256-uHO+r3+1E69NKt3UT/oM++rA4C6CKDFdYvPka1Lw5ms=" + }, + "locale_ig.js": { + "src": "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js", + "integrity": "sha256-892yjlk32mTQlZRSEoinSvBI6hZHW/yDxDLhvPe8JRo=" + }, + "locale_ig.js.map": { + "src": "/packs/js/locale_ig-ff3d79d9206c0a735199.chunk.js.map", + "integrity": "sha256-eHEffHKwbFg3k+L2LBjLk5LeELTaqdnmaWe/mfv6mEU=" + }, + "locale_io.js": { + "src": "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js", + "integrity": "sha256-qEqFzG2D6xWeF6FaIEpfSC8yX41jhZEwwlkmQukCKIU=" + }, + "locale_io.js.map": { + "src": "/packs/js/locale_io-2befc8b1f63a30ce47a4.chunk.js.map", + "integrity": "sha256-6wKSxTQMpu2kpR10ZOCkkIz48VSOgDglLnkRdSDCdgc=" + }, + "locale_is.js": { + "src": "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js", + "integrity": "sha256-VZC+bpd5yxqicwxsxWRl04TcIgeRZmKKRBcRITacBM4=" + }, + "locale_is.js.map": { + "src": "/packs/js/locale_is-7d4eb585c6da3c491a64.chunk.js.map", + "integrity": "sha256-DEWCUNv3AMD3+l/jzgxFRMobwbkqjSK+TJHmWC2YRXo=" + }, + "locale_it.js": { + "src": "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js", + "integrity": "sha256-Xa+ihJQLe3hnNAoshuYAvNcTH2K4aPoBTPAzmQiVUvI=" + }, + "locale_it.js.map": { + "src": "/packs/js/locale_it-3dda38a1cf30149fee3e.chunk.js.map", + "integrity": "sha256-HVnmjnZOlVQMwlb9WiZMBLRVN4PPACCk356vlb7ypHY=" + }, + "locale_ja.js": { + "src": "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js", + "integrity": "sha256-8XvJlY0fub4UupoXHT6jo7+ASLQp3JupbX5GmUJMDqM=" + }, + "locale_ja.js.map": { + "src": "/packs/js/locale_ja-6311beb2cc2f57e4dea4.chunk.js.map", + "integrity": "sha256-VlWSQXEcP15ci/vYYUuQ/K1Vz2kqNkPxN7btUnl1qhI=" + }, + "locale_ka.js": { + "src": "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js", + "integrity": "sha256-q86D1tdb0P3hQYt9RwTrCqUvFFVSs7loEh72LNXWAsQ=" + }, + "locale_ka.js.map": { + "src": "/packs/js/locale_ka-63b70748a220d9e9efec.chunk.js.map", + "integrity": "sha256-j5rUU6Aoh2Y6Xu/l2+0XJ2/p4rND5F/wAM/8/6Jh4KU=" + }, + "locale_kab.js": { + "src": "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js", + "integrity": "sha256-kWrUEVGGbXnWkUIcts8AVHtEtWczDqNSZbsvVuqtseE=" + }, + "locale_kab.js.map": { + "src": "/packs/js/locale_kab-667b3b79ea82e6fb6068.chunk.js.map", + "integrity": "sha256-UHKTJekLW0cItmEXKTdEpOeeYPMx2hFSmxz+5phDBfc=" + }, + "locale_kk.js": { + "src": "/packs/js/locale_kk-806df7189017998308a3.chunk.js", + "integrity": "sha256-560YKdh7m3hFb1G68O5mxv4j8uQ400bYQ3B4v4otkS8=" + }, + "locale_kk.js.map": { + "src": "/packs/js/locale_kk-806df7189017998308a3.chunk.js.map", + "integrity": "sha256-DTHcpplTt9+xpZlicWZj95nMH9VXhvXTIK090ABlYcI=" + }, + "locale_kn.js": { + "src": "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js", + "integrity": "sha256-FrZsZa8BtgCfMI07LCVABYravZvDxtjCRPxIc4VK8Aw=" + }, + "locale_kn.js.map": { + "src": "/packs/js/locale_kn-3043d47752c1d69b015d.chunk.js.map", + "integrity": "sha256-u+GHLhMc89xc0ySLueaXEeILlfthfCuXWfd/0B99z4A=" + }, + "locale_ko.js": { + "src": "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js", + "integrity": "sha256-+bXL++ooHtepnflO4DyGWwkTBlUPg8bzWC5gzN36XtU=" + }, + "locale_ko.js.map": { + "src": "/packs/js/locale_ko-99a4ef0ca445141a26d3.chunk.js.map", + "integrity": "sha256-7LNkDvPbgP4qml+dbiUuQ4qLxgArM3bwYFdg39pPJ9U=" + }, + "locale_ku.js": { + "src": "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js", + "integrity": "sha256-hU462/kg1/2VQ1Gg3oGgD1W3RRFYoSGXAo1P8vTI2GM=" + }, + "locale_ku.js.map": { + "src": "/packs/js/locale_ku-ca2530b20ddbe1a2b924.chunk.js.map", + "integrity": "sha256-t7oIP4/uCs8RiriVKYrVJ0WLsWAuvRLrNXDzXgBRk+8=" + }, + "locale_kw.js": { + "src": "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js", + "integrity": "sha256-WNhO1QGY7JJZHuPCx3OCYFfwLViM9YP+I44MTuUnDBc=" + }, + "locale_kw.js.map": { + "src": "/packs/js/locale_kw-622a455bad2cf1bb0630.chunk.js.map", + "integrity": "sha256-uyzHkO6x6JzWW05euj34D91o4USpXVVhQOmC+dqDeVc=" + }, + "locale_la.js": { + "src": "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js", + "integrity": "sha256-eSTZPsf4wIuMixsm5u3knQRAHVNqMyojtFd8/QrZU34=" + }, + "locale_la.js.map": { + "src": "/packs/js/locale_la-540797de7b49f2bddaa8.chunk.js.map", + "integrity": "sha256-mOWYO0YM5ubqnfaEqcvG1MDFXZ5YOrFqurJauGWJuC4=" + }, + "locale_lt.js": { + "src": "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js", + "integrity": "sha256-LfJeBSBiQjM/e1oACIYpZ/fzbF2ZLimrzZmb+ApDHBE=" + }, + "locale_lt.js.map": { + "src": "/packs/js/locale_lt-502ddf8aae5bb8183260.chunk.js.map", + "integrity": "sha256-bahnWd6k0cdky+IEhVVK/2anKl+Oeck8Ol3CMN17fJI=" + }, + "locale_lv.js": { + "src": "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js", + "integrity": "sha256-B7bhgmKY26kmabsQ9ZepstxwaAcSpFVPHgxTn0lwJTU=" + }, + "locale_lv.js.map": { + "src": "/packs/js/locale_lv-d1096c0f54345c6088fc.chunk.js.map", + "integrity": "sha256-kMl+o/yrHG8S6sqhr2gb6n89xU4Ghda19byu/IFBVOw=" + }, + "locale_mk.js": { + "src": "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js", + "integrity": "sha256-P9boDty9aUCVUHPnA5UqhoQQBIJxbVXnGo0mHK2fGiE=" + }, + "locale_mk.js.map": { + "src": "/packs/js/locale_mk-5ddafa16d22f86041a9a.chunk.js.map", + "integrity": "sha256-fcx3Q1Vy8/e9hGPQCOCj/UoqUcBJK/2ZGBDuQYhw10A=" + }, + "locale_ml.js": { + "src": "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js", + "integrity": "sha256-89f1wpr/+YYear+ad39veBD9n//2LG4cI/JcCZnthoI=" + }, + "locale_ml.js.map": { + "src": "/packs/js/locale_ml-20cd60c82ab5c3407132.chunk.js.map", + "integrity": "sha256-z9dkFEQvtEYc4VAtG/203FUXNjb1OlzoMj/4yEgpz+c=" + }, + "locale_mr.js": { + "src": "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js", + "integrity": "sha256-TlfVKlsbC4OzKOLnxu9mCU/KiEG1/3YxED2o6kblbW4=" + }, + "locale_mr.js.map": { + "src": "/packs/js/locale_mr-cca595ea1a8116127575.chunk.js.map", + "integrity": "sha256-jRbayXpXZBeZDHQhvMtR325FkInsR5inyNomL8Bd29o=" + }, + "locale_ms.js": { + "src": "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js", + "integrity": "sha256-3FMp+t3nQ4KEzIGuvBc87NyUuy+eiGdmRgpDnjOoMPI=" + }, + "locale_ms.js.map": { + "src": "/packs/js/locale_ms-3037ef4e73365defbc31.chunk.js.map", + "integrity": "sha256-/Tqid9TrvSHr3G97ne0VeBRDljHVs8ap2aAZ1XpzTh4=" + }, + "locale_my.js": { + "src": "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js", + "integrity": "sha256-BOiX+nljOxQzkmoLl1F+dlJiQfFrkEwxsmBx0QAH2m8=" + }, + "locale_my.js.map": { + "src": "/packs/js/locale_my-a0930e2a8a4c6aebe25d.chunk.js.map", + "integrity": "sha256-Q3tc/toGURY/rOkSc91RpX1u+jjM9Na09Ptd+KJZna8=" + }, + "locale_nl.js": { + "src": "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js", + "integrity": "sha256-IDQCNscOpy+9pFVGzy/QmvqaoWGif+KglM9QsA3whkc=" + }, + "locale_nl.js.map": { + "src": "/packs/js/locale_nl-de9a210a27b9b5db6468.chunk.js.map", + "integrity": "sha256-Oa7kCDbhhfIOpFqXgT44LAe9QPJP3HXAckSsw394ZE4=" + }, + "locale_nn.js": { + "src": "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js", + "integrity": "sha256-BlMkziOCaf0lDfAEDsW1wUiYlBizuCWEDhr+Ay5xdHo=" + }, + "locale_nn.js.map": { + "src": "/packs/js/locale_nn-1b9204cb296f6e7260be.chunk.js.map", + "integrity": "sha256-4gQbEv0B1K3CCW2UCpUlXv18dyjfMd1w0cGQu8ZeygQ=" + }, + "locale_no.js": { + "src": "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js", + "integrity": "sha256-iFfNt4wPwtzLCM22Avc5RuEMAr8PF8diGvG21D0RskA=" + }, + "locale_no.js.map": { + "src": "/packs/js/locale_no-b878a05bb8d46438025f.chunk.js.map", + "integrity": "sha256-VX3PSv0lkXS1CF8QNgAPZ10kYAFWt57jaau7LbgddvA=" + }, + "locale_oc.js": { + "src": "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js", + "integrity": "sha256-9fckY0qlbxVgc1qbfYdsW8bOM1aG1Eu9yvvztDUkzmA=" + }, + "locale_oc.js.map": { + "src": "/packs/js/locale_oc-c40573d3f0f0bc035ce9.chunk.js.map", + "integrity": "sha256-lgQSwSpIjt/sDmizhd4069rr9CyF3enfGOw/AFSPXds=" + }, + "locale_pa.js": { + "src": "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js", + "integrity": "sha256-mJJPHYovfXW8ZzUfgzH/fm4J1h0KX8BfguM8vsM9TMQ=" + }, + "locale_pa.js.map": { + "src": "/packs/js/locale_pa-45b4ce945531b2f0cd5c.chunk.js.map", + "integrity": "sha256-3LvIJHduhsGUxFbfSams6PtFSx+L2jXn+rf6nylVaT8=" + }, + "locale_pl.js": { + "src": "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js", + "integrity": "sha256-tl5CGx2K7wW9BEebVIFE/cJ4Bv9frqAz9ADMkpbOuk0=" + }, + "locale_pl.js.map": { + "src": "/packs/js/locale_pl-e0907aed14495d5a9d01.chunk.js.map", + "integrity": "sha256-Rp+GjHwbYaMIT4Q1pZxG6SX6sfUfIQ71NwqDjLGHx1E=" + }, + "locale_pt-BR.js": { + "src": "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js", + "integrity": "sha256-T8jrBIHo+8mxEwT+1wJc1SmjFrMGX0tbX4+NOjIYvwE=" + }, + "locale_pt-BR.js.map": { + "src": "/packs/js/locale_pt-BR-c5868c2635d2c15381cd.chunk.js.map", + "integrity": "sha256-b42Q17JRd+POkiGQcahfrC8FpHeLcia4fg/9T08//6Y=" + }, + "locale_pt-PT.js": { + "src": "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js", + "integrity": "sha256-+TYGInWRhhMnS+K3gfiI7iRLoduOmc1jC1GrEUddi7A=" + }, + "locale_pt-PT.js.map": { + "src": "/packs/js/locale_pt-PT-9f8d239897fdbff5163b.chunk.js.map", + "integrity": "sha256-bqVptGgiycU+P2t/uZArGe4H99SZTIHYJaW+08rhK+s=" + }, + "locale_ro.js": { + "src": "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js", + "integrity": "sha256-h/crkYw5rFBLDmvi+AxxbOQ9l04kNKCLLaLSSmif2Pc=" + }, + "locale_ro.js.map": { + "src": "/packs/js/locale_ro-6970b84da3b996e9349b.chunk.js.map", + "integrity": "sha256-zlM5e9ZwBepEibqEqosH7cR7nKrw0qemXKoYb/jpNck=" + }, + "locale_ru.js": { + "src": "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js", + "integrity": "sha256-Oa3e/XJS2HFrf2PdF2gsZZmf5sh/TdKyQg7EowiOTww=" + }, + "locale_ru.js.map": { + "src": "/packs/js/locale_ru-d73dd26da7075791741f.chunk.js.map", + "integrity": "sha256-PhyOBiGLeh5vGq4RJowYo6dzWWSLeXMDxHSJdneCPeo=" + }, + "locale_sa.js": { + "src": "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js", + "integrity": "sha256-aiixeTj8VpByVbfAPAjfT6AnCNMmZD9yR7Ki2fPr7ZU=" + }, + "locale_sa.js.map": { + "src": "/packs/js/locale_sa-489e282c0c6ff6dd4e2f.chunk.js.map", + "integrity": "sha256-uFxeHda8Kkx/PoAFlNlHBJegnWUrIhMXWYjh2pK2aSg=" + }, + "locale_sc.js": { + "src": "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js", + "integrity": "sha256-OBCXX8dVUe5hIYpEmB0xsVNEzLH2Is0bLf5gcAIuOuQ=" + }, + "locale_sc.js.map": { + "src": "/packs/js/locale_sc-f449449c4646bd6e21c7.chunk.js.map", + "integrity": "sha256-ExpHmetKDsvfAemzbDSOjLkouKUcuyK/EALyiTd2Bog=" + }, + "locale_sco.js": { + "src": "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js", + "integrity": "sha256-TWifzDAcraaAijIbaDpeUE1cyIuXOuDvSyCAMgJ0x7g=" + }, + "locale_sco.js.map": { + "src": "/packs/js/locale_sco-e6ffa60a95cce30ce8e7.chunk.js.map", + "integrity": "sha256-rTy9Ok0zV7xseyAIjDNLr4U05Vmmg8Q7FyYooQkFmX4=" + }, + "locale_si.js": { + "src": "/packs/js/locale_si-17838170f6bebef2861a.chunk.js", + "integrity": "sha256-nq24RIfsAUL3rk30LbH4scFK2EvfL/GW3d8s1ymCZLY=" + }, + "locale_si.js.map": { + "src": "/packs/js/locale_si-17838170f6bebef2861a.chunk.js.map", + "integrity": "sha256-xwmNRp/kNjUiC7Y4ZzUneybCB1/aRMjJJ29msh2cIVk=" + }, + "locale_sk.js": { + "src": "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js", + "integrity": "sha256-NOuZYMDVVjd71kWExQ4SUCSDk/BR/WfYGMirUfgHJPY=" + }, + "locale_sk.js.map": { + "src": "/packs/js/locale_sk-256f439213248dd5e2ae.chunk.js.map", + "integrity": "sha256-7N3gmMp9ModK9jJr7LyayX1/9GDB3j01gn6MKbbWwrs=" + }, + "locale_sl.js": { + "src": "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js", + "integrity": "sha256-/8Pnzl9y+hA2nKYkHqR9/WKX2gflDYNaKy3TLX/2wk0=" + }, + "locale_sl.js.map": { + "src": "/packs/js/locale_sl-b9643142ab5b4eda9add.chunk.js.map", + "integrity": "sha256-wcE5LU4zwvlao4dmxmMNNnsQppNla85ChhSjzfpm5dQ=" + }, + "locale_sq.js": { + "src": "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js", + "integrity": "sha256-gu2KIslQV64AqhVGUAD7HJPIOK1csiAGBnutModlj9k=" + }, + "locale_sq.js.map": { + "src": "/packs/js/locale_sq-9c3ef3bbac65a331ba30.chunk.js.map", + "integrity": "sha256-i3aOehc94tSSHPEQ8SJ6xIZMMNuyzUKEnMQztI9LVoA=" + }, + "locale_sr-Latn.js": { + "src": "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js", + "integrity": "sha256-bMbUcDIGMSAoEHRwoQvyK0rDjrhsAg6lJBJRCi4tBHU=" + }, + "locale_sr-Latn.js.map": { + "src": "/packs/js/locale_sr-Latn-289d42a505feb334f879.chunk.js.map", + "integrity": "sha256-pH/svEWlQobikQ6A+p0sWmJID1R9zvYUEa4n+Rp6/Pk=" + }, + "locale_sr.js": { + "src": "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js", + "integrity": "sha256-MB7gwcVgbKOnJZUlUckdSWuhyadLXy8j6MHmKpLS4cw=" + }, + "locale_sr.js.map": { + "src": "/packs/js/locale_sr-11dd609028dfeb029bee.chunk.js.map", + "integrity": "sha256-Y03TUUpttZ7IwMHNJ86QaUeXs0L1BEBm7QfKU75X280=" + }, + "locale_sv.js": { + "src": "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js", + "integrity": "sha256-ix7gKPkdcOadbRkZU8K5cdAlgHCa1BQbj+Q8QEkqlEI=" + }, + "locale_sv.js.map": { + "src": "/packs/js/locale_sv-487faa54ab8e9a4b97b1.chunk.js.map", + "integrity": "sha256-JWUn5UYrO9loA8xX0pyMdIqT6HI+3RpN0UM9UyumlHc=" + }, + "locale_szl.js": { + "src": "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js", + "integrity": "sha256-Z0is22d9hJ2SrKKJSp5eCi2XzMWo1F7J7yYLsas/vGM=" + }, + "locale_szl.js.map": { + "src": "/packs/js/locale_szl-b1f873216c7e9518dd7e.chunk.js.map", + "integrity": "sha256-Xb+G5D17+1I/5zNuxyyG3BiajFrzso6XI5a6PZ83p6U=" + }, + "locale_ta.js": { + "src": "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js", + "integrity": "sha256-ScwN6L82Nd0PKihd3H7r+Fs4VDD0N4tTt1zGQ5eYucE=" + }, + "locale_ta.js.map": { + "src": "/packs/js/locale_ta-635db71fd9232cc33747.chunk.js.map", + "integrity": "sha256-0u2lj3Yh9tvJ8BYQAzOb88pRocgJ2YnliIezQf2RQnQ=" + }, + "locale_tai.js": { + "src": "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js", + "integrity": "sha256-tnFuPdh588UVkjL8dlvBS6ka4sG457ua7rO+Fc+/s30=" + }, + "locale_tai.js.map": { + "src": "/packs/js/locale_tai-66ec01423765120d41d9.chunk.js.map", + "integrity": "sha256-7kBRSZt5KxnhDSgJGh1wILys9J5heEPXbEECCK9i8Ic=" + }, + "locale_te.js": { + "src": "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js", + "integrity": "sha256-tc+YIHM9y5R/AXAxGpgDNnZIjuIYWrXisfy3jQtXDfY=" + }, + "locale_te.js.map": { + "src": "/packs/js/locale_te-15e5fb1e2660ae6c9dc0.chunk.js.map", + "integrity": "sha256-9S4wEem8RwCZB5bzBqp+9YwrwwThFoMo+Or3KAfUYLY=" + }, + "locale_th.js": { + "src": "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js", + "integrity": "sha256-DGL3f6Bl1+H7r15fpTHtG93W3aLCSjRnughABAQne5M=" + }, + "locale_th.js.map": { + "src": "/packs/js/locale_th-33920587174bc6ed98a7.chunk.js.map", + "integrity": "sha256-MOLXD5Ld9r08b8VX+f/3pDHDBLYOOy6xF4UsC0BoJD8=" + }, + "locale_tr.js": { + "src": "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js", + "integrity": "sha256-khe34YihUoCD0AV5o4pgKqDuV1wIsLTwZC3qkXAbPCE=" + }, + "locale_tr.js.map": { + "src": "/packs/js/locale_tr-79afb025a585ec9124dc.chunk.js.map", + "integrity": "sha256-v2V1YGuMsy67fxzo5eWeNp9khvG3+pafxLP8yNhyuW0=" + }, + "locale_tt.js": { + "src": "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js", + "integrity": "sha256-HBgMlgLYcmPhHJtpKuM7uuHveu6n24iINX4PofW9eBg=" + }, + "locale_tt.js.map": { + "src": "/packs/js/locale_tt-41c60ab8bad077ef6387.chunk.js.map", + "integrity": "sha256-LojEtd1BIATpGV50zAJ+zwUgHcaWTZNj9UuBlakRX+Q=" + }, + "locale_ug.js": { + "src": "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js", + "integrity": "sha256-U4FjPlp7xtbPUADVMb+v9bAgOHQIea8XztEfnJsQfqU=" + }, + "locale_ug.js.map": { + "src": "/packs/js/locale_ug-9417a8218d5840abcf41.chunk.js.map", + "integrity": "sha256-JXHgSo9GlYHp2VwKqyTRw60SDp9psuxoQ/SgZz+41/U=" + }, + "locale_uk.js": { + "src": "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js", + "integrity": "sha256-cZ01w/aujHulc0TSP+o1kVguu5dw5ygM1BzjL8pmtEQ=" + }, + "locale_uk.js.map": { + "src": "/packs/js/locale_uk-35d8d5b96d0247cda8ae.chunk.js.map", + "integrity": "sha256-2/CIxh87uit5JemQ0YCjQEpzJSbuM0BGECaP8ccPB4Q=" + }, + "locale_ur.js": { + "src": "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js", + "integrity": "sha256-P7YZtTY960t7JmSxuTJhAkrXPD+Ib3pSukiDPuVgP0E=" + }, + "locale_ur.js.map": { + "src": "/packs/js/locale_ur-7aae6d47dd0572b29025.chunk.js.map", + "integrity": "sha256-y/TEpftUysA9Qs557bLTs3iJD40/yyXOBDcUYJcuiaw=" + }, + "locale_uz.js": { + "src": "/packs/js/locale_uz-38029008a065795c55b7.chunk.js", + "integrity": "sha256-O34b4eo/aXwL97o5gCuE3iBcdCL+YSn7cvcRIuAnLvo=" + }, + "locale_uz.js.map": { + "src": "/packs/js/locale_uz-38029008a065795c55b7.chunk.js.map", + "integrity": "sha256-DxvG+OoAbHu0dMPn/vNP20L5ob4oYObpRarmBJ8WMMY=" + }, + "locale_vi.js": { + "src": "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js", + "integrity": "sha256-lu2/hoL1iWs7CC8qAsNVr3ILBbceSYiuY09naPGxcQ0=" + }, + "locale_vi.js.map": { + "src": "/packs/js/locale_vi-bafdab4e21a4b9d91951.chunk.js.map", + "integrity": "sha256-Ndjild7pxt8RQ2fSssvwVK88sP/25re+3zqejUjG0gw=" + }, + "locale_zgh.js": { + "src": "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js", + "integrity": "sha256-kvZ86IlAa5nRE66v5kCtpPqCmXxHXtnGJmRC0crWjmQ=" + }, + "locale_zgh.js.map": { + "src": "/packs/js/locale_zgh-00c9940396f7e9eea03f.chunk.js.map", + "integrity": "sha256-nZQT7XDevHHB+GjJAuhoR9mqaGa3vCC67Olvadisvzk=" + }, + "locale_zh-CN.js": { + "src": "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js", + "integrity": "sha256-1lvh6SDZsKGCx9N8V1dAuN4qSHfbRv0BoPCwk8xdLg4=" + }, + "locale_zh-CN.js.map": { + "src": "/packs/js/locale_zh-CN-04a07c41100957bed4d7.chunk.js.map", + "integrity": "sha256-alGdpSO2wn0KvjdQk7O/lBiX93z/CtWm1uCERqaJkp8=" + }, + "locale_zh-HK.js": { + "src": "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js", + "integrity": "sha256-Mb0uHwkCC9kmxLKtB9ag5GQxDZHLGdoXus1IvHF98pQ=" + }, + "locale_zh-HK.js.map": { + "src": "/packs/js/locale_zh-HK-95e90384869e2801caf7.chunk.js.map", + "integrity": "sha256-ytaPO3bE0FVWRc82OB3W1ZNjJlCoV08BR7Wldfx9W90=" + }, + "locale_zh-TW.js": { + "src": "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js", + "integrity": "sha256-KhuOY48FL2L6L842ITm1x8N/TyoDZAjxhTBf96Xgi/k=" + }, + "locale_zh-TW.js.map": { + "src": "/packs/js/locale_zh-TW-abf88413ea0d7766a45a.chunk.js.map", + "integrity": "sha256-2UfkY26DE4+tiEEyLSJoWF1UpC+6e+7E+KDiMHEpKo0=" + }, + "mailer.css": { + "src": "/packs/css/mailer-d3e9e30b.chunk.css", + "integrity": "sha256-i3Ojw8PPOO9atNke0FfRzbhAgjsrn5m/f1ErXnnDuA0=" + }, + "mailer.css.map": { + "src": "/packs/css/mailer-d3e9e30b.chunk.css.map", + "integrity": "sha256-6+FY9nxjXldQYGnAEmCxGg01FrMuTcmLaKaIhtyoW94=" + }, + "mailer.js": { + "src": "/packs/js/mailer-906c1f5c743751870035.chunk.js", + "integrity": "sha256-85qJnQADq/qh1h7c1+FKtF7NvTTCsPk6m/jej/WITRI=" + }, + "mailer.js.map": { + "src": "/packs/js/mailer-906c1f5c743751870035.chunk.js.map", + "integrity": "sha256-Df4caWSNiigAIH7OO1QE1t8JgJlRbhNSSQserAjpBXo=" + }, + "mastodon-light.css": { + "src": "/packs/css/mastodon-light-d9270c4c.chunk.css", + "integrity": "sha256-/0cGJMex4hn34b9JaNOhJmitZh0uNTIHLazYi0ZVSEE=" + }, + "mastodon-light.css.map": { + "src": "/packs/css/mastodon-light-d9270c4c.chunk.css.map", + "integrity": "sha256-1h3MEHXH3698sa4GY1gKyJ+O8vUx9a1T8uSg62mO5dU=" + }, + "mastodon-light.js": { + "src": "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js", + "integrity": "sha256-MdjZy+0w8m0cOkUwDnvh5Pc0r5iWlER1d1yI+7uCAAQ=" + }, + "mastodon-light.js.map": { + "src": "/packs/js/mastodon-light-627790bb4db0c95b5ec9.chunk.js.map", + "integrity": "sha256-BP5nqoaGvGf/EWv4OSXAn2BhOA1ZaBV0EAmRPUpvKGI=" + }, + "media/fonts/fontawesome-webfont.eot": { + "src": "/packs/media/fonts/fontawesome-webfont-8b43027f.eot", + "integrity": "sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk=" + }, + "media/fonts/fontawesome-webfont.eot?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-8b43027f.eot", + "integrity": "sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk=" + }, + "media/fonts/fontawesome-webfont.svg?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-c1e38fd9.svg", + "integrity": "sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q=" + }, + "media/fonts/fontawesome-webfont.ttf?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-1e59d233.ttf", + "integrity": "sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg=" + }, + "media/fonts/fontawesome-webfont.woff2?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-20fd1704.woff2", + "integrity": "sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4=" + }, + "media/fonts/fontawesome-webfont.woff?v=4.7.0": { + "src": "/packs/media/fonts/fontawesome-webfont-f691f37e.woff", + "integrity": "sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.svg": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-fe0d118334cccfd145435b2c48cd06e4.svg", + "integrity": "sha256-MEMSbYnngJXxYQ8KRPOQIKxYciWL82Wwd63UDpM8cws=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.ttf": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-7fb73b77e9674adf3bb4e256d12f5c24.ttf", + "integrity": "sha256-/qGM+ZKZ4mABZFu6bET035hNgXtgksEuozod4cbMrNk=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.woff": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-de79497258b00697d7449a8d933a2d77.woff", + "integrity": "sha256-9vQXjjwSHGsQPwRvKmKwO2zyeNGMiRX7BeQ0pbFfpPI=" + }, + "media/fonts/roboto-mono/robotomono-regular-webfont.woff2": { + "src": "/packs/media/fonts/roboto-mono/robotomono-regular-webfont-ccc9601c8b2933f9a4b9246665afb352.woff2", + "integrity": "sha256-SK8nRVUadeAqAy5ejQE9i7O9HakKf1IYXhmyQHGZ7AY=" + }, + "media/fonts/roboto/roboto-bold-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-5ea71553d6e57da5b5cee78d8480db12.svg", + "integrity": "sha256-W3rX9bPwruYVrf5ZnZQH4vPsemzCewyP0uZClDMbXj0=" + }, + "media/fonts/roboto/roboto-bold-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-099d7f6e4b0fd1955bf58d33f84cbddf.ttf", + "integrity": "sha256-iuwOFV2x3/JXIKfqU379IGD06kKUfOOwI5NzTjxluUE=" + }, + "media/fonts/roboto/roboto-bold-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-c8eca5c3d7f0e3203f2150ef668b11d7.woff", + "integrity": "sha256-TOSP1nSCnMcDrYWavFo+P78JQxLsYBm+OObDOBmKcQg=" + }, + "media/fonts/roboto/roboto-bold-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-bold-webfont-2c18fe4b97519d62a0d6aad8ada1004f.woff2", + "integrity": "sha256-BpdFK0bp30mD2AyyHRXGb80eiX4kqPjH0eWBbVVeZXA=" + }, + "media/fonts/roboto/roboto-italic-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-8f90649d463aec7793d71b786b5b3b06.svg", + "integrity": "sha256-VHBU5eAsjpCMAI/RR/uXYh5tjoMVApA0kdSLryewxoU=" + }, + "media/fonts/roboto/roboto-italic-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-73eaf3921695d82f2daba6bc02ffa602.ttf", + "integrity": "sha256-BiuKjMKaxKr6jdFLH93CEzdRxVPYI01U72YhuapMAgY=" + }, + "media/fonts/roboto/roboto-italic-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-5c39c5913ec17aaca7e59635381b9b62.woff", + "integrity": "sha256-SvzA5M9GAAiscee+UsXlpY8QDtCBEmWWWiELNGRdT0E=" + }, + "media/fonts/roboto/roboto-italic-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-italic-webfont-dcb8144b63145c7e349a27ebbe24f875.woff2", + "integrity": "sha256-zvNTcwwumq9McCzuOvAXCxFvsFDirdQDTk5YuuOne9Y=" + }, + "media/fonts/roboto/roboto-medium-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-c0d084caf29abb0ed6cc87e92d886d61.svg", + "integrity": "sha256-FbY0mZiI2BKPu709RU14wIgwO9Z1Q7VHMuyDkXbt5Ck=" + }, + "media/fonts/roboto/roboto-medium-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-131f629d199b0a47d72d8489fda5823a.ttf", + "integrity": "sha256-Z0m2dvzqefs0MsfK0YnShEaL+d5V6B/2RqVsQ7AdeCk=" + }, + "media/fonts/roboto/roboto-medium-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-3a01847aadd53eb13f47e0227e8aca9b.woff", + "integrity": "sha256-LxGk4hswt/cygyD4jElXm1Hpux+SaNxjHS4sVxNmMB8=" + }, + "media/fonts/roboto/roboto-medium-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-medium-webfont-3ed000c35f7afb8bd4ad7f46da85abbf.woff2", + "integrity": "sha256-CGpPcs+e9DBhvd8tTxkY/fkrcECxuPJA15YELoYA6LI=" + }, + "media/fonts/roboto/roboto-regular-webfont.svg": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-a8da5f98faeafb21714583a6e373c397.svg", + "integrity": "sha256-Nh18Hzy0tVuQ/rTuxG5YA3+mUZgvhOrvtz8bzbLg8XA=" + }, + "media/fonts/roboto/roboto-regular-webfont.ttf": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-00831949e731c8201e1966faf97da0d2.ttf", + "integrity": "sha256-hLUefY7Hl7ubmSzAqTii2MxfRwwnV1RLjEYNioNg4MI=" + }, + "media/fonts/roboto/roboto-regular-webfont.woff": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-8ede4fa233d6c99fb3653a767922b22b.woff", + "integrity": "sha256-VIg+si7Ii8+t89xqSTEP/einJc+RBvKO51H4QJavKJU=" + }, + "media/fonts/roboto/roboto-regular-webfont.woff2": { + "src": "/packs/media/fonts/roboto/roboto-regular-webfont-e6505d5d85943244ec91d5e3002791f2.woff2", + "integrity": "sha256-EDb9syRt4IKFaMDBY00bhSVEgjkokXRXHchinMyAAdc=" + }, + "media/icons/android-chrome-144x144.png": { + "src": "/packs/media/icons/android-chrome-144x144-ff3110f7772743bdd0c1c47fb7b2d4e0.png", + "integrity": "sha256-gYEMVOji+GRQsFpFXxcQP3oc6IsdUW2OHu3lv8xmROc=" + }, + "media/icons/android-chrome-192x192.png": { + "src": "/packs/media/icons/android-chrome-192x192-eddc1ed540e97b926202b7b857989d60.png", + "integrity": "sha256-dmP8/MOpZHLwRdR05BpCii3mdYv+obNo4UBfGpwdLFM=" + }, + "media/icons/android-chrome-256x256.png": { + "src": "/packs/media/icons/android-chrome-256x256-7b2b43926019259f7c9ddee627d80a0f.png", + "integrity": "sha256-nd/BCLSP6NVJbTyu/aEzu4XQ8pV0hxEUUmzQ/eJLVV0=" + }, + "media/icons/android-chrome-36x36.png": { + "src": "/packs/media/icons/android-chrome-36x36-4c61fdb42936428af85afdbf8c6a45a8.png", + "integrity": "sha256-/WEeWTmVSljVK/uXN+BLcVgkzua+qaQzeEO8zcn8PHw=" + }, + "media/icons/android-chrome-384x384.png": { + "src": "/packs/media/icons/android-chrome-384x384-72068ed50b02828fc505a8d69b321dea.png", + "integrity": "sha256-uk3uWgqnhiieXE70jUQbDOVSkBRfnbLVAWU3BH74Dwo=" + }, + "media/icons/android-chrome-48x48.png": { + "src": "/packs/media/icons/android-chrome-48x48-2027aead76dc906c981043d658a8258d.png", + "integrity": "sha256-qe0TixDJcvnklqip4GHndmf6pjCYQupBLB1bsU3gE98=" + }, + "media/icons/android-chrome-512x512.png": { + "src": "/packs/media/icons/android-chrome-512x512-ccb53c9fcbb5f61bf741cc54998318f0.png", + "integrity": "sha256-4XQHB0u0eYVsi9VpTcxvGPk/Yg9WWksJO6iicrr1XbQ=" + }, + "media/icons/android-chrome-72x72.png": { + "src": "/packs/media/icons/android-chrome-72x72-799d90b81f5b28cea7355a0c0b356381.png", + "integrity": "sha256-4gMGAMaypoBawcwzM21iR9yJSiJDQPrIY1XSV1XsGIA=" + }, + "media/icons/android-chrome-96x96.png": { + "src": "/packs/media/icons/android-chrome-96x96-c2dfcfa1268c56e59edddfe20d818b91.png", + "integrity": "sha256-u1dL/So2/8Ggqnywr3HA8uma0mXKnuim1Y+B3am5xFc=" + }, + "media/icons/apple-touch-icon-1024x1024.png": { + "src": "/packs/media/icons/apple-touch-icon-1024x1024-db6849588b44f525363c37b65ef0ac66.png", + "integrity": "sha256-PUN8ROoYNJbZG13zIBqtCsZPcI4eUjBydDXcliuN3c4=" + }, + "media/icons/apple-touch-icon-114x114.png": { + "src": "/packs/media/icons/apple-touch-icon-114x114-211e68807b8d15707666a8d326d338b1.png", + "integrity": "sha256-mCmH6WAcD8etz6YPYiVnqaX8Wcp6r7151gmpCsTjDpw=" + }, + "media/icons/apple-touch-icon-120x120.png": { + "src": "/packs/media/icons/apple-touch-icon-120x120-4c4e647d758bf1b2f47a53e2165a01d2.png", + "integrity": "sha256-yVCmBDYwpTA0WuRvBTEefo8lZbL0ztMLKzPlGYbW6r8=" + }, + "media/icons/apple-touch-icon-144x144.png": { + "src": "/packs/media/icons/apple-touch-icon-144x144-ff3110f7772743bdd0c1c47fb7b2d4e0.png", + "integrity": "sha256-gYEMVOji+GRQsFpFXxcQP3oc6IsdUW2OHu3lv8xmROc=" + }, + "media/icons/apple-touch-icon-152x152.png": { + "src": "/packs/media/icons/apple-touch-icon-152x152-b12cbb1baaf4a6111d0efd391fd829c9.png", + "integrity": "sha256-MCK5KVDZVd+hp4QcLYCUutFBgEFcqTBnpoCbIzP//qU=" + }, + "media/icons/apple-touch-icon-167x167.png": { + "src": "/packs/media/icons/apple-touch-icon-167x167-6f21a68f6a05a8b5cf25b1729e553728.png", + "integrity": "sha256-iI25wuGAjIoClOt/Kj7qfrltZ3tXRjpuzPRLHOEBjVQ=" + }, + "media/icons/apple-touch-icon-180x180.png": { + "src": "/packs/media/icons/apple-touch-icon-180x180-a75559a0af48064c1b7c71b81f3bf7c6.png", + "integrity": "sha256-QWHa0MggRPM/msNf0ynvu5c6bue/whIQDPYo5feGVj4=" + }, + "media/icons/apple-touch-icon-57x57.png": { + "src": "/packs/media/icons/apple-touch-icon-57x57-c9dca808280860c51d0357f6a3350f4d.png", + "integrity": "sha256-Oa7mtD0a6kJQxHCXQgiTM3G1FlHCOHntGhkG3wtCjZI=" + }, + "media/icons/apple-touch-icon-60x60.png": { + "src": "/packs/media/icons/apple-touch-icon-60x60-bb247db195d9ee9d8c687b2b048508d9.png", + "integrity": "sha256-BHfmmZYMASwVkrQvJS11Guuw5jyxcHxAR1De6n7SIHg=" + }, + "media/icons/apple-touch-icon-72x72.png": { + "src": "/packs/media/icons/apple-touch-icon-72x72-799d90b81f5b28cea7355a0c0b356381.png", + "integrity": "sha256-4gMGAMaypoBawcwzM21iR9yJSiJDQPrIY1XSV1XsGIA=" + }, + "media/icons/apple-touch-icon-76x76.png": { + "src": "/packs/media/icons/apple-touch-icon-76x76-015d73d770413d121873193153ae4ab5.png", + "integrity": "sha256-5GKhEYATGlQe/SvgAqN+0qrVTIdx6T3RmTzczl1AAFg=" + }, + "media/icons/favicon-16x16.png": { + "src": "/packs/media/icons/favicon-16x16-c58fdef40ced38d582d5b8eed9d15c5a.png", + "integrity": "sha256-DK84BauFv9HYCaNZMBWPtRhC0tnuWoCPHelaD+D6SBc=" + }, + "media/icons/favicon-32x32.png": { + "src": "/packs/media/icons/favicon-32x32-249409a6d9f300112c51af514d863112.png", + "integrity": "sha256-Ft+9TR7iUbbKkiWxFmeO2NOjT/9GCy7/eG8E217aWa8=" + }, + "media/icons/favicon-48x48.png": { + "src": "/packs/media/icons/favicon-48x48-c1197e9664ee6476d2715a1c4293bf61.png", + "integrity": "sha256-eUrXLyOyoclFj/+MmZ2j1/Mlwpy3U2gFmt/+9dt9+uY=" + }, + "media/images/app-icon.svg": { + "src": "/packs/media/images/app-icon-0808256a4b7b3a7d337085d90c1b6133.svg", + "integrity": "sha256-aS0mhny+U/jVzXcFnlDu1QlTbC1ogRbkLeObUb+Vbic=" + }, + "media/images/elephant_ui_disappointed.svg": { + "src": "/packs/media/images/elephant_ui_disappointed-83980a5d0868aabbde510765f8a44a84.svg", + "integrity": "sha256-81e7qIL5w5F2rcDC7cUd1yBNSb2YO+FlwZoZllj3WP8=" + }, + "media/images/elephant_ui_greeting.svg": { + "src": "/packs/media/images/elephant_ui_greeting-530b368959aeb035f1ebb16fbc361c71.svg", + "integrity": "sha256-pQWEATvZ7bSOUn+cMAqsrB8OWru4TEyuNpwv6D8/vYQ=" + }, + "media/images/elephant_ui_plane.svg": { + "src": "/packs/media/images/elephant_ui_plane-72f8702db120a51a1cdbc4fb7f5ef59d.svg", + "integrity": "sha256-L6iHdg2PGx2XAypQ+pXu68p9JdSJEfwRrFyUOD2MBOI=" + }, + "media/images/elephant_ui_working.svg": { + "src": "/packs/media/images/elephant_ui_working-8d131ca68f598cb545a64ac0563199d1.svg", + "integrity": "sha256-vF6FuZMs/4pOUYgzmjZB4+dmuOoMpLU5m8uYhJSqsJo=" + }, + "media/images/icons/icon_cached.svg": { + "src": "/packs/media/images/icons/icon_cached-bb4d475764c7c6fe4ffc1e3496af21fb.svg", + "integrity": "sha256-LOkB9M+myiCnwJ+KxgVeJGXGz2GSB6BiOelWYGg2Nkw=" + }, + "media/images/icons/icon_done.svg": { + "src": "/packs/media/images/icons/icon_done-158fdbfc997bfbaecd661b95ac707663.svg", + "integrity": "sha256-DS/OmEIopI5HoMfSOET3iLXpuaaGtUGtVhed32zCBzE=" + }, + "media/images/icons/icon_email.svg": { + "src": "/packs/media/images/icons/icon_email-185c94df8b200b5513adfd2cb2c90cf2.svg", + "integrity": "sha256-QgA+Y4r7cO9jfOlDijSt25vtXGtn+yYGQRHSGv3HeU4=" + }, + "media/images/icons/icon_file_download.svg": { + "src": "/packs/media/images/icons/icon_file_download-99cc9fe7a1a90b340c55e5d3860315bc.svg", + "integrity": "sha256-jU7kyOzTLLxykwQ7xGVUpTMg/ke/BulU6ymRcwByYAw=" + }, + "media/images/icons/icon_flag.svg": { + "src": "/packs/media/images/icons/icon_flag-abc0a5f6874c0737c69c0f47c94f8bdb.svg", + "integrity": "sha256-9taRFfGw66g6s1ls4ERaNEzhlrvCElpGK2MD0LqnX+M=" + }, + "media/images/icons/icon_grade.svg": { + "src": "/packs/media/images/icons/icon_grade-b210a115be8deda342ba1cd816bf4796.svg", + "integrity": "sha256-W3yBkIV2GAA1ldDrrfpfAED/HaptnyI3Lfx1tfJRUmg=" + }, + "media/images/icons/icon_lock_open.svg": { + "src": "/packs/media/images/icons/icon_lock_open-9581ebece5a62933d1562da18b868457.svg", + "integrity": "sha256-eQcmzZQfswpbgjdCQiEKG6nn3A9l4BKYPLZpY/bKlcY=" + }, + "media/images/icons/icon_person_add.svg": { + "src": "/packs/media/images/icons/icon_person_add-d9557536647bdd6fc5a2af1e8e7fd352.svg", + "integrity": "sha256-uQsrgwH0uwn+gL4lUl1TXYkWkfuW0jv0LEXF2MmszWE=" + }, + "media/images/icons/icon_reply.svg": { + "src": "/packs/media/images/icons/icon_reply-e0c983a2e64569176501a9e047f91b7e.svg", + "integrity": "sha256-AiDvy928aX2Ip0YLici4ytEax7N9g48TdlQGIjkrho0=" + }, + "media/images/logo-symbol-icon.svg": { + "src": "/packs/media/images/logo-symbol-icon-de9e68dc49b19eb5cd142d3316f9e95e.svg", + "integrity": "sha256-TLwj1pIKuGNeqywk3EZ+rQKiNKLlA+OqnlHVwIWzKpk=" + }, + "media/images/logo-symbol-wordmark.svg": { + "src": "/packs/media/images/logo-symbol-wordmark-3830557f705aa0d7559b03269c942fe4.svg", + "integrity": "sha256-uYpo5V6HkDA0Uj2yy5ryYw/7XeNfUGxXX7Ot78lS+Nw=" + }, + "media/images/logo.svg": { + "src": "/packs/media/images/logo-d4b5dc90fd3e117d141ae7053b157f58.svg", + "integrity": "sha256-5voQCbqV8dEA/n2hwRhtCjCKPREhk+2wnvB+1kH+6SA=" + }, + "media/images/logo_full.svg": { + "src": "/packs/media/images/logo_full-4f531370f8ab23cd34058f3a7c2464ca.svg", + "integrity": "sha256-Dr5BQ136Hr3m3Ex4mPiU2x68fwxfMZZHwqgfrsIG6+M=" + }, + "media/images/logo_transparent.svg": { + "src": "/packs/media/images/logo_transparent-9aedc3a098e790b61726b33fcd385cb4.svg", + "integrity": "sha256-EijcQYC+f127YynG58/SToZxuEXS3WAd1V+Pl9hhvUo=" + }, + "media/images/mailer/icon_cached.png": { + "src": "/packs/media/images/mailer/icon_cached-d82304cbd965343f5f6a5631d68e8a15.png", + "integrity": "sha256-wVFGwcwrrY9jeuqUBvHmByHpykviOIeJj55b/lmlVoM=" + }, + "media/images/mailer/icon_done.png": { + "src": "/packs/media/images/mailer/icon_done-f49dc0b65c99f2edce1b99ee696f0b8d.png", + "integrity": "sha256-j6kr09zhKoVu9aPqzWR4wRNkNrgLjX658QiGAemgRrk=" + }, + "media/images/mailer/icon_email.png": { + "src": "/packs/media/images/mailer/icon_email-07eaf000249a54dae76b2937a834c3ae.png", + "integrity": "sha256-AHupchKk56cqiDt6GHMtRlkyQmzbRVG91IR2SK22GCI=" + }, + "media/images/mailer/icon_file_download.png": { + "src": "/packs/media/images/mailer/icon_file_download-fb5f9be9fd8e11726c3b3a1d47e72717.png", + "integrity": "sha256-c9dazTq2KmjfgEl8KCEl/Eulifnr2VovgQejnauzNiw=" + }, + "media/images/mailer/icon_flag.png": { + "src": "/packs/media/images/mailer/icon_flag-fb052043db6f17c4f79c21fccff09700.png", + "integrity": "sha256-uBmc1YSPIjLaHAmEUPmJ+D5yNATVijpLf0BAY6vM8+I=" + }, + "media/images/mailer/icon_grade.png": { + "src": "/packs/media/images/mailer/icon_grade-15655c70b6fe2ca2f8547db15929187a.png", + "integrity": "sha256-IaJFveyki3F0GnIRXc/8DpGIMxY21OrI9G5U+f5BbQ4=" + }, + "media/images/mailer/icon_lock_open.png": { + "src": "/packs/media/images/mailer/icon_lock_open-8e5ae4f888e6ea016e3046b607314d02.png", + "integrity": "sha256-n+dr7c8ZOudT8khIOcB/FVlXon2jojVuIfHfo6ivyN4=" + }, + "media/images/mailer/icon_person_add.png": { + "src": "/packs/media/images/mailer/icon_person_add-a9759d23d1662ab87c2f255c8906107b.png", + "integrity": "sha256-bx9vDJOZtQ6s1qFp/vgSAxFYJKvsXaUIEwaJOCjIfm8=" + }, + "media/images/mailer/icon_reply.png": { + "src": "/packs/media/images/mailer/icon_reply-05e7be76b12b1b5529bd003bbe17bcf2.png", + "integrity": "sha256-9EyRKX1qQa9B1pvAWchCNbi5Z+8Z4FNW2sA9O5wpb8c=" + }, + "media/images/mailer/logo.png": { + "src": "/packs/media/images/mailer/logo-50cfb97cbce11d4974c71481a924b69c.png", + "integrity": "sha256-Ae8FX5xzFqoNsNWUYuDljAv1tiiMT0URSZya6xrwubk=" + }, + "media/images/mailer/wordmark.png": { + "src": "/packs/media/images/mailer/wordmark-8a93a992d2c8ac64361a1bc2c1664250.png", + "integrity": "sha256-Y5DvjTdZgUSJSyBfcBU61MKkXu71iTqJOpDz9kOfDwY=" + }, + "media/images/preview.png": { + "src": "/packs/media/images/preview-6399aebd96ccf025654e2977454f168f.png", + "integrity": "sha256-uA/RrG49ZVMEbl4uydzExgCwWVludRMd4pYUpBdajBc=" + }, + "media/images/reticle.png": { + "src": "/packs/media/images/reticle-dbff413218a2f5843b32cf2fb9968eb4.png", + "integrity": "sha256-vb5WEHGlvKJhtoRMa8zdOGda7LiS92EkQJ53oGL2ttU=" + }, + "media/images/void.png": { + "src": "/packs/media/images/void-cf1819950446c7563cdb09966c0db01d.png", + "integrity": "sha256-S5oQlKuN5UINWLmsKmAVPZc9KmHsoLRoiIMtNUWROYc=" + }, + "modals/block_modal.js": { + "src": "/packs/js/modals/block_modal-285514f4fd899d40d729.chunk.js", + "integrity": "sha256-tATA1ZOSxR5XqSDgZ2ufDtutnvXL5+sUtbYSSunY/wU=" + }, + "modals/block_modal.js.map": { + "src": "/packs/js/modals/block_modal-285514f4fd899d40d729.chunk.js.map", + "integrity": "sha256-zSbIEBMfUkoRAmzcFxo41BzrsrGTUucnLx44x1zFGgE=" + }, + "modals/closed_registrations_modal.js": { + "src": "/packs/js/modals/closed_registrations_modal-cffa83a84851c036f0e7.chunk.js", + "integrity": "sha256-n66RYrZXCdIcZc0dl03GZ1mBUhhdYXeYesewIW+8dvI=" + }, + "modals/closed_registrations_modal.js.map": { + "src": "/packs/js/modals/closed_registrations_modal-cffa83a84851c036f0e7.chunk.js.map", + "integrity": "sha256-0rdNNc4nKgKjx1v4JC4zbtOz8+TyZnjQxE0PZRugNhc=" + }, + "modals/compare_history_modal.js": { + "src": "/packs/js/modals/compare_history_modal-90b3013107b67285a7da.chunk.js", + "integrity": "sha256-zQ+/ICuZYBmpQ2GkzJxa2qrQd06VYV3G4DwPeEQadio=" + }, + "modals/compare_history_modal.js.map": { + "src": "/packs/js/modals/compare_history_modal-90b3013107b67285a7da.chunk.js.map", + "integrity": "sha256-dFtswiv0X++FFifTB5/LvvcRs8IKKLFO8ElIhqmcDkw=" + }, + "modals/embed_modal.js": { + "src": "/packs/js/modals/embed_modal-b3308de1f266e93b7aaf.chunk.js", + "integrity": "sha256-7hb+VsRzZD/GM+472Gyzltt88Nr+V1aeJ2orBarBz3Y=" + }, + "modals/embed_modal.js.map": { + "src": "/packs/js/modals/embed_modal-b3308de1f266e93b7aaf.chunk.js.map", + "integrity": "sha256-DUXlrT7Yy3rVjyhaVExqOBRAyuYIhoCmV/sbk1DGFZY=" + }, + "modals/filter_modal.js": { + "src": "/packs/js/modals/filter_modal-6ad1eed2cf629d860383.chunk.js", + "integrity": "sha256-I4d5kXs017Qv3BI4bFkdzc9ZjrMocaYQoiDvBMWwrW0=" + }, + "modals/filter_modal.js.map": { + "src": "/packs/js/modals/filter_modal-6ad1eed2cf629d860383.chunk.js.map", + "integrity": "sha256-D67EMgmijKcduY4XLj2Rdh7o4iaVbKObKHqtBCQnYrQ=" + }, + "modals/interaction_modal.js": { + "src": "/packs/js/modals/interaction_modal-facf890aa0ae8f2ac47c.chunk.js", + "integrity": "sha256-ilba2YoU0JLPocESrGSWdC2Tcy1OqKNweCuuL3giZGA=" + }, + "modals/interaction_modal.js.map": { + "src": "/packs/js/modals/interaction_modal-facf890aa0ae8f2ac47c.chunk.js.map", + "integrity": "sha256-QydGrgCMa16qS6ZI2bw+Eg8VoK8NxqgdRJr82eZb90Y=" + }, + "modals/mute_modal.js": { + "src": "/packs/js/modals/mute_modal-44fbd9f138ed444e344d.chunk.js", + "integrity": "sha256-Hf4z6ZHAI9sMfctf1VVy479viJD/X0whNB5GMu3/bMg=" + }, + "modals/mute_modal.js.map": { + "src": "/packs/js/modals/mute_modal-44fbd9f138ed444e344d.chunk.js.map", + "integrity": "sha256-Mv+EEwvcvP2laxRpMTIewrOQAOewSrPvJwyNcvYDJGc=" + }, + "modals/report_modal.js": { + "src": "/packs/js/modals/report_modal-f393be11609ee994a2db.chunk.js", + "integrity": "sha256-lQC1ncu1YAJxlJZ2S2EfAeiDmJ400q81BuEV6gbSzFs=" + }, + "modals/report_modal.js.map": { + "src": "/packs/js/modals/report_modal-f393be11609ee994a2db.chunk.js.map", + "integrity": "sha256-QvQSYcOoEQgicaGII1ZVou8sPBzLF+r3kQnIw9Cg7fs=" + }, + "modals/subscribed_languages_modal.js": { + "src": "/packs/js/modals/subscribed_languages_modal-9e2993dd250cf513f141.chunk.js", + "integrity": "sha256-8bULdwgWdff8D4RZDOtZjgCu/Xa4Co8LwmSw68A7TJI=" + }, + "modals/subscribed_languages_modal.js.map": { + "src": "/packs/js/modals/subscribed_languages_modal-9e2993dd250cf513f141.chunk.js.map", + "integrity": "sha256-D0EPxRTC3AlhgRpi78nuUjBjq84Oqa8e6ylJAD98ov4=" + }, + "modern-dark-wobbl-old.css": { + "src": "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css", + "integrity": "sha256-Ic57GXLi6Q8UG5V1CE6yazZosiL5pZ/rORiLvMOo2Do=" + }, + "modern-dark-wobbl-old.css.map": { + "src": "/packs/css/modern-dark-wobbl-old-04b62fd3.chunk.css.map", + "integrity": "sha256-ha+7RHuf3N2B9Z8uGHS1dD+rj+U9zIjY3tjpUoPY4z8=" + }, + "modern-dark-wobbl-old.js": { + "src": "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js", + "integrity": "sha256-EDG5zP/PpG7R44tOOP9AKlP79Hzah0DFVnLtG4Lrv1Q=" + }, + "modern-dark-wobbl-old.js.map": { + "src": "/packs/js/modern-dark-wobbl-old-4e938192994fd64d3225.chunk.js.map", + "integrity": "sha256-x713hTukta7lDQkXfdphLY1guSaJjeI6edtGMOSPEJw=" + }, + "modern-dark.css": { + "src": "/packs/css/modern-dark-1cfb4c54.chunk.css", + "integrity": "sha256-ZO5+6kPMcC10o5iXdjun9BA+qqmMy5oMAusr/j1L4Qo=" + }, + "modern-dark.css.map": { + "src": "/packs/css/modern-dark-1cfb4c54.chunk.css.map", + "integrity": "sha256-eBuesRNhVWUljmvu1L2MLGsAZ35gmfBFe38nB470+rk=" + }, + "modern-dark.js": { + "src": "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js", + "integrity": "sha256-lfQ5SpgTXhD4/ARsxygt6owXI3EkCP1LvDYn29Nk22o=" + }, + "modern-dark.js.map": { + "src": "/packs/js/modern-dark-05ffeadf0ba337f78ce5.chunk.js.map", + "integrity": "sha256-gZaOsNOkj8cPH2H/SBU/fsYrtaGilQpf8Z2/zrEwHIA=" + }, + "modern-light-wobbl-old.css": { + "src": "/packs/css/modern-light-wobbl-old-50985752.chunk.css", + "integrity": "sha256-FKu4HTqRYXlV4VI53VIEQppyYfBeOZO2+JXSJFsf9Ow=" + }, + "modern-light-wobbl-old.css.map": { + "src": "/packs/css/modern-light-wobbl-old-50985752.chunk.css.map", + "integrity": "sha256-p8KWL8O/nRIi1HbeMBXd+6APNjkJLPnh25FYQbvcm5c=" + }, + "modern-light-wobbl-old.js": { + "src": "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js", + "integrity": "sha256-c+B26bZspb1up778EN5lOoRlhEP7Ck9tYMD2CBynGx4=" + }, + "modern-light-wobbl-old.js.map": { + "src": "/packs/js/modern-light-wobbl-old-55f71d8cd6804f322af3.chunk.js.map", + "integrity": "sha256-qp5Nh8PjdDHagjupVdwI4m4v64kNo2kjm20fyKDnfFQ=" + }, + "modern-light-wobbl.css": { + "src": "/packs/css/modern-light-wobbl-291fe684.chunk.css", + "integrity": "sha256-u0FNCZ866kB1PUmBaoLjU/IbabcZuaz/crhyXbkrz68=" + }, + "modern-light-wobbl.css.map": { + "src": "/packs/css/modern-light-wobbl-291fe684.chunk.css.map", + "integrity": "sha256-S77R1L+1H52KmHabl11nRhCe1y9Q6O6rdyb+1oeleeY=" + }, + "modern-light-wobbl.js": { + "src": "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js", + "integrity": "sha256-ncq1mZHSipDX2gpf0ENaBlhuMkoKFtQws8WbHyX6tK4=" + }, + "modern-light-wobbl.js.map": { + "src": "/packs/js/modern-light-wobbl-657a1d2027ddde7e9de2.chunk.js.map", + "integrity": "sha256-Ugj5gnsIEw972ytw7AfyAv/XyZt9C9FTSAZ8ToW0KGY=" + }, + "modern-light.css": { + "src": "/packs/css/modern-light-1c0258de.chunk.css", + "integrity": "sha256-rKaxxKRKcDPfEWnxPOlfFQN/baKgUhM5UwgG8C33JGs=" + }, + "modern-light.css.map": { + "src": "/packs/css/modern-light-1c0258de.chunk.css.map", + "integrity": "sha256-p5oDMWPwl5lnYjLatrfxmVnZZsh7nEvMrB1HYZBaGos=" + }, + "modern-light.js": { + "src": "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js", + "integrity": "sha256-zFT0z3IcGgZ9Ck0+gVLBDNFvcuA7+MDoX1U3dBWj7O4=" + }, + "modern-light.js.map": { + "src": "/packs/js/modern-light-f53ce20d37e18c90f347.chunk.js.map", + "integrity": "sha256-X7nuN9Nfj2YQbYSJkB25KonCuwHDZxZu6bEQgTiaLXg=" + }, + "ocr/tesseract-core.wasm.js": { + "src": "/packs/ocr/tesseract-core.wasm-e4db7f953ac7bcf9f67bd39031e42241.js", + "integrity": "sha256-j2marGLlEXTmo0iXTPumIL1lVgn0+RwBP4VSESoKSjY=" + }, + "ocr/worker.min-514c4b0a1fa9a086ca9ab8bfb7df6c9d.js.LICENSE.txt": { + "src": "/packs/ocr/worker.min-514c4b0a1fa9a086ca9ab8bfb7df6c9d.js.LICENSE.txt", + "integrity": "sha256-QoWYHwnDlKd4MX8P4iAeB1ezh+OWVOjZq0YvVoSnUWM=" + }, + "ocr/worker.min.js": { + "src": "/packs/ocr/worker.min-514c4b0a1fa9a086ca9ab8bfb7df6c9d.js", + "integrity": "sha256-hwUPXOFqMNYJvaOu5bjDwhmIIFEEp7M7+Hkrxm2dwWU=" + }, + "public-path.js": { + "src": "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js", + "integrity": "sha256-jAMI72eadFn7TolK0dBykdrbJKs4NVm1tunq8Jr45d8=" + }, + "public-path.js.map": { + "src": "/packs/js/public-path-a74ca554ddafba4a7b4a.chunk.js.map", + "integrity": "sha256-uTazMmhgfzKf4YJNsntBX+Y+OE5s93qa8xPTsZH4elo=" + }, + "public.js": { + "src": "/packs/js/public-35500a3113a9d04e88f1.chunk.js", + "integrity": "sha256-kTTSpUDFa4593lidSMDSXjVMqCoWu/Hn04kad5VKVvw=" + }, + "public.js.map": { + "src": "/packs/js/public-35500a3113a9d04e88f1.chunk.js.map", + "integrity": "sha256-fnoFVSgpoGc5H+qAK/eswo7I4WO1B7o66p7kezN3uK8=" + }, + "share.js": { + "src": "/packs/js/share-efad16f2e2c4954c4721.chunk.js", + "integrity": "sha256-mVx160SzmlJuVDWXXybFtI/n7AhM669/ZkIpqHDf/zU=" + }, + "share.js.map": { + "src": "/packs/js/share-efad16f2e2c4954c4721.chunk.js.map", + "integrity": "sha256-n4JcNS9vOzTyvcyL6jCGD2gjWyBsoTfInd6RC9vJcUc=" + }, + "sw.js": { + "src": "/packs/sw.js", + "integrity": "sha256-WKzgP5z9lDjfgAwTObADmmil2VZjNW0qtTyCWjWz/3w=" + }, + "sw.js.map": { + "src": "/packs/sw.js.map", + "integrity": "sha256-qUX+GpzGQD63dBr9WzV5KVCCU0731AVR6ZMwe8aDSsE=" + }, + "tesseract.js": { + "src": "/packs/js/tesseract-1135ffb0b9825ec8791c.chunk.js", + "integrity": "sha256-XdWnMHTwhYYMk5SoJcWDj4qIJf+xTdW3vWste1hAdxY=" + }, + "tesseract.js.map": { + "src": "/packs/js/tesseract-1135ffb0b9825ec8791c.chunk.js.map", + "integrity": "sha256-zgN7800XxxAl51ITqnSm0MceJA+8MErDwSpv90KKZGk=" + }, + "two_factor_authentication.js": { + "src": "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js", + "integrity": "sha256-jZwbajnZKuCUZnoWCAqvj2nzbP0ggwQuq2IFFXVQWsI=" + }, + "two_factor_authentication.js.map": { + "src": "/packs/js/two_factor_authentication-0b882fb4d79f0ddb3377.chunk.js.map", + "integrity": "sha256-4Pvk4t81YoTmPKvdONNdqUzOVpD+YvKsOS9mxWGi8YU=" + }, + "wobbl-light.css": { + "src": "/packs/css/wobbl-light-aae0a2db.chunk.css", + "integrity": "sha256-iFc0ERGgymcOJrUuq509pxmzt16EvKp0KO5sOI+GWqo=" + }, + "wobbl-light.css.map": { + "src": "/packs/css/wobbl-light-aae0a2db.chunk.css.map", + "integrity": "sha256-6jjeNyVhWX/R0B/Cynndhgt3iIdnBMK+FC0wRdLPBUw=" + }, + "wobbl-light.js": { + "src": "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js", + "integrity": "sha256-T6caY1gIdm/xSrF0jB0kAjwFYTcBHTt2THmY6TMv1V4=" + }, + "wobbl-light.js.map": { + "src": "/packs/js/wobbl-light-0d3aad295e04b652883c.chunk.js.map", + "integrity": "sha256-Y6XtgD1lgZHZRbCBv5cMMaaI+wjYJEPvqWJo4jOgkTA=" + }, + "wobbl-old-light.css": { + "src": "/packs/css/wobbl-old-light-d2f87f38.chunk.css", + "integrity": "sha256-YT6U10dMY8/fxu4E3HfLthiawVCQ/5RrnA0KYR4iGBo=" + }, + "wobbl-old-light.css.map": { + "src": "/packs/css/wobbl-old-light-d2f87f38.chunk.css.map", + "integrity": "sha256-bCACqV4neCBC2/XEoLGgemPWQdn9UQH2fma+6SfTpMU=" + }, + "wobbl-old-light.js": { + "src": "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js", + "integrity": "sha256-/LyLShmuQnze21vjWH7irG4BNOAgnionOMryvfWbf78=" + }, + "wobbl-old-light.js.map": { + "src": "/packs/js/wobbl-old-light-356bc6d0a63e0be3e2e0.chunk.js.map", + "integrity": "sha256-c+zynZEmMAICeiTiVdFUL0smuoAVJ1bwVsLLti7nNZk=" + }, + "wobbl-old.css": { + "src": "/packs/css/wobbl-old-41b5a76e.chunk.css", + "integrity": "sha256-6qiqu+KyJt0fS2R8Vc5C7dwrMPlieOOmDgRFYloa67E=" + }, + "wobbl-old.css.map": { + "src": "/packs/css/wobbl-old-41b5a76e.chunk.css.map", + "integrity": "sha256-sA9q8aDLcpvwa+LAbHd6SQCZSVZA70fU31qfIJmb1LM=" + }, + "wobbl-old.js": { + "src": "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js", + "integrity": "sha256-CAYaWEFHpHvk8Cew4eNlsGtKq0S/aqURhYrw0fYfmZg=" + }, + "wobbl-old.js.map": { + "src": "/packs/js/wobbl-old-b1c6aefc0e2e6d926817.chunk.js.map", + "integrity": "sha256-AS+HRq5qQgPnhUO2mVXquGFXjrhZB7DXENnHlmXJScE=" + }, + "wobbl.css": { + "src": "/packs/css/wobbl-88f067e5.chunk.css", + "integrity": "sha256-sREyL1vRm9S9FhRs4DUtM1t9hb0STo8nKixwXwO5CwA=" + }, + "wobbl.css.map": { + "src": "/packs/css/wobbl-88f067e5.chunk.css.map", + "integrity": "sha256-9IdCSCDlS4NpLCh7gh9VEoxMbir1JeSvZI0SAwb3yjg=" + }, + "wobbl.js": { + "src": "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js", + "integrity": "sha256-JiRac5Sj33oGQ3i4LLxCpe35Ya2HS1AWb3EWsePGXFY=" + }, + "wobbl.js.map": { + "src": "/packs/js/wobbl-1538317b62791a7f9d66.chunk.js.map", + "integrity": "sha256-ANmfOcLOTzqaaGKuDPUz2VHzadEleuR6bhHkY8kJ+FA=" + } +} +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/webpacker-5.4.4/lib/webpacker/manifest.rb:79:in `handle_missing_entry' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/webpacker-5.4.4/lib/webpacker/manifest.rb:49:in `lookup!' +/home/mastodon/live/lib/webpacker/helper_extensions.rb:5:in `javascript_pack_tag' +/home/mastodon/live/app/views/layouts/_theme.html.haml:6:in `_app_views_layouts__theme_html_haml__3180968677926065901_69360' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `public_send' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `_run' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:157:in `block in render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:361:in `instrument_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:155:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/partial_renderer.rb:251:in `block in render_partial_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/partial_renderer.rb:246:in `render_partial_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/object_renderer.rb:31:in `render_partial_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/partial_renderer.rb:237:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/object_renderer.rb:16:in `render_object_with_partial' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:77:in `render_partial_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:27:in `render_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:22:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/helpers/rendering_helper.rb:37:in `block in render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:270:in `in_rendering_context' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/helpers/rendering_helper.rb:33:in `render' +/home/mastodon/live/app/views/layouts/error.html.haml:9:in `_app_views_layouts_error_html_haml__434087765855293748_69340' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `public_send' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:244:in `_run' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:157:in `block in render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:361:in `instrument_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/template.rb:155:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:76:in `block in render_with_layout' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/activesupport-7.0.6/lib/active_support/notifications.rb:208:in `instrument' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:74:in `render_with_layout' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:59:in `render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/template_renderer.rb:11:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:61:in `render_template_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/renderer/renderer.rb:29:in `render_to_object' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/rendering.rb:117:in `block in _render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/base.rb:270:in `in_rendering_context' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/rendering.rb:116:in `_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/streaming.rb:216:in `_render_template' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionview-7.0.6/lib/action_view/rendering.rb:103:in `render_to_body' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/rendering.rb:158:in `render_to_body' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/renderers.rb:141:in `render_to_body' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/abstract_controller/rendering.rb:45:in `render_to_string' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/rendering.rb:147:in `render_to_string' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/renderer.rb:81:in `render' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.6/lib/action_controller/metal/rendering.rb:11:in `render' +/home/mastodon/live/lib/tasks/assets.rake:13:in `render_static_page' +/home/mastodon/live/lib/tasks/assets.rake:17:in `block (2 levels) in
' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke' +/home/mastodon/live/lib/tasks/assets.rake:24:in `block in
' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `block in execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `each' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:281:in `execute' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:219:in `block in invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands/rake/rake_command.rb:24:in `block (2 levels) in perform' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands/rake/rake_command.rb:24:in `block in perform' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/lib/rake/rake_module.rb:59:in `with_application' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands/rake/rake_command.rb:18:in `perform' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/command.rb:51:in `invoke' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/railties-7.0.6/lib/rails/commands.rb:18:in `
' +/home/mastodon/live/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require' +Tasks: TOP => assets:generate_static_pages +(See full trace by running task with --trace) diff --git a/streaming/index.js b/streaming/index.js index ffb570c5b9..d1bd74d33d 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -1,96 +1,39 @@ // @ts-check -const os = require('os'); -const throng = require('throng'); +const fs = require('fs'); +const http = require('http'); +const url = require('url'); + const dotenv = require('dotenv'); const express = require('express'); -const http = require('http'); -const redis = require('redis'); -const pg = require('pg'); -const log = require('npmlog'); -const url = require('url'); -const uuid = require('uuid'); -const fs = require('fs'); -const WebSocket = require('ws'); +const Redis = require('ioredis'); const { JSDOM } = require('jsdom'); +const log = require('npmlog'); +const pg = require('pg'); +const dbUrlToConfig = require('pg-connection-string').parse; +const metrics = require('prom-client'); +const uuid = require('uuid'); +const WebSocket = require('ws'); -const env = process.env.NODE_ENV || 'development'; -const alwaysRequireAuth = process.env.LIMITED_FEDERATION_MODE === 'true' || process.env.WHITELIST_MODE === 'true' || process.env.AUTHORIZED_FETCH === 'true'; +const environment = process.env.NODE_ENV || 'development'; dotenv.config({ - path: env === 'production' ? '.env.production' : '.env', + path: environment === 'production' ? '.env.production' : '.env', }); log.level = process.env.LOG_LEVEL || 'verbose'; /** - * @param {string} dbUrl - * @return {Object.} + * @param {Object.} config */ -const dbUrlToConfig = (dbUrl) => { - if (!dbUrl) { - return {}; - } - - const params = url.parse(dbUrl, true); - const config = {}; - - if (params.auth) { - [config.user, config.password] = params.auth.split(':'); - } - - if (params.hostname) { - config.host = params.hostname; - } - - if (params.port) { - config.port = params.port; - } - - if (params.pathname) { - config.database = params.pathname.split('/')[1]; - } - - const ssl = params.query && params.query.ssl; - - if (ssl && ssl === 'true' || ssl === '1') { - config.ssl = true; - } - - return config; -}; - -/** - * @param {Object.} defaultConfig - * @param {string} redisUrl - */ -const redisUrlToClient = async (defaultConfig, redisUrl) => { - const config = defaultConfig; - - let client; - - if (!redisUrl) { - client = redis.createClient(config); - } else if (redisUrl.startsWith('unix://')) { - client = redis.createClient(Object.assign(config, { - socket: { - path: redisUrl.slice(7), - }, - })); - } else { - client = redis.createClient(Object.assign(config, { - url: redisUrl, - })); - } - +const createRedisClient = async (config) => { + const { redisParams, redisUrl } = config; + const client = new Redis(redisUrl, redisParams); client.on('error', (err) => log.error('Redis Client Error!', err)); - await client.connect(); return client; }; -const numWorkers = +process.env.STREAMING_CLUSTER_NUM || (env === 'development' ? 1 : Math.max(os.cpus().length - 1, 1)); - /** * Attempts to safely parse a string as JSON, used when both receiving a message * from redis and when receiving a message from a client over a websocket @@ -122,74 +65,234 @@ const parseJSON = (json, req) => { } }; -const startMaster = () => { - if (!process.env.SOCKET && process.env.PORT && isNaN(+process.env.PORT)) { - log.warn('UNIX domain socket is now supported by using SOCKET. Please migrate from PORT hack.'); - } - - log.warn(`Starting streaming API server master with ${numWorkers} workers`); -}; - -const startWorker = async (workerId) => { - log.warn(`Starting worker ${workerId}`); - +/** + * @param {Object.} env the `process.env` value to read configuration from + * @returns {Object.} the configuration for the PostgreSQL connection + */ +const pgConfigFromEnv = (env) => { const pgConfigs = { development: { - user: process.env.DB_USER || pg.defaults.user, - password: process.env.DB_PASS || pg.defaults.password, - database: process.env.DB_NAME || 'mastodon_development', - host: process.env.DB_HOST || pg.defaults.host, - port: process.env.DB_PORT || pg.defaults.port, + user: env.DB_USER || pg.defaults.user, + password: env.DB_PASS || pg.defaults.password, + database: env.DB_NAME || 'mastodon_development', + host: env.DB_HOST || pg.defaults.host, + port: env.DB_PORT || pg.defaults.port, }, production: { - user: process.env.DB_USER || 'mastodon', - password: process.env.DB_PASS || '', - database: process.env.DB_NAME || 'mastodon_production', - host: process.env.DB_HOST || 'localhost', - port: process.env.DB_PORT || 5432, + user: env.DB_USER || 'mastodon', + password: env.DB_PASS || '', + database: env.DB_NAME || 'mastodon_production', + host: env.DB_HOST || 'localhost', + port: env.DB_PORT || 5432, }, }; + if (!!process.env.DB_SSLMODE && process.env.DB_SSLMODE !== 'disable') { + pgConfigs.development.ssl = true; + pgConfigs.production.ssl = {ca: fs.readFileSync("ca-certificate.crt") }; + } + + let baseConfig; + + if (env.DATABASE_URL) { + baseConfig = dbUrlToConfig(env.DATABASE_URL); + + // Support overriding the database password in the connection URL + if (!baseConfig.password && env.DB_PASS) { + baseConfig.password = env.DB_PASS; + } + } else { + baseConfig = pgConfigs[environment]; + + if (env.DB_SSLMODE) { + switch(env.DB_SSLMODE) { + case 'disable': + case '': + baseConfig.ssl = false; + break; + case 'no-verify': + baseConfig.ssl = { rejectUnauthorized: false }; + break; + default: + baseConfig.ssl = { rejectUnauthorized: false }; + break; + } + } + } + + return { + ...baseConfig, + max: env.DB_POOL || 10, + connectionTimeoutMillis: 15000, + application_name: '', + }; +}; + +/** + * @param {Object.} env the `process.env` value to read configuration from + * @returns {Object.} configuration for the Redis connection + */ +const redisConfigFromEnv = (env) => { + // ioredis *can* transparently add prefixes for us, but it doesn't *in some cases*, + // which means we can't use it. But this is something that should be looked into. + const redisPrefix = env.REDIS_NAMESPACE ? `${env.REDIS_NAMESPACE}:` : ''; + + const redisParams = { + host: env.REDIS_HOST || '127.0.0.1', + port: env.REDIS_PORT || 6379, + db: env.REDIS_DB || 0, + password: env.REDIS_PASSWORD || undefined, + }; + + // redisParams.path takes precedence over host and port. + if (env.REDIS_URL && env.REDIS_URL.startsWith('unix://')) { + redisParams.path = env.REDIS_URL.slice(7); + } + + return { + redisParams, + redisPrefix, + redisUrl: env.REDIS_URL, + }; +}; + +const PUBLIC_CHANNELS = [ + 'public', + 'public:media', + 'public:local', + 'public:local:media', + 'public:remote', + 'public:remote:media', + 'hashtag', + 'hashtag:local', +]; + +// Used for priming the counters/gauges for the various metrics that are +// per-channel +const CHANNEL_NAMES = [ + 'system', + 'user', + 'user:notification', + 'list', + 'direct', + ...PUBLIC_CHANNELS +]; + +const startServer = async () => { const app = express(); app.set('trust proxy', process.env.TRUSTED_PROXY_IP ? process.env.TRUSTED_PROXY_IP.split(/(?:\s*,\s*|\s+)/) : 'loopback,uniquelocal'); - const pgPool = new pg.Pool(Object.assign(pgConfigs[env], dbUrlToConfig(process.env.DATABASE_URL), { - max: process.env.DB_POOL || 10, - connectionTimeoutMillis: 15000, - ssl: !!process.env.DB_SSLMODE && process.env.DB_SSLMODE !== 'disable', - })); - + const pgPool = new pg.Pool(pgConfigFromEnv(process.env)); const server = http.createServer(app); - const redisNamespace = process.env.REDIS_NAMESPACE || null; - - const redisParams = { - socket: { - host: process.env.REDIS_HOST || '127.0.0.1', - port: process.env.REDIS_PORT || 6379, - }, - database: process.env.REDIS_DB || 0, - password: process.env.REDIS_PASSWORD || undefined, - }; - - if (redisNamespace) { - redisParams.namespace = redisNamespace; - } - - const redisPrefix = redisNamespace ? `${redisNamespace}:` : ''; /** * @type {Object.): void>>} */ const subs = {}; - const redisSubscribeClient = await redisUrlToClient(redisParams, process.env.REDIS_URL); - const redisClient = await redisUrlToClient(redisParams, process.env.REDIS_URL); + const redisConfig = redisConfigFromEnv(process.env); + const redisSubscribeClient = await createRedisClient(redisConfig); + const redisClient = await createRedisClient(redisConfig); + const { redisPrefix } = redisConfig; + + // Collect metrics from Node.js + metrics.collectDefaultMetrics(); + + new metrics.Gauge({ + name: 'pg_pool_total_connections', + help: 'The total number of clients existing within the pool', + collect() { + this.set(pgPool.totalCount); + }, + }); + + new metrics.Gauge({ + name: 'pg_pool_idle_connections', + help: 'The number of clients which are not checked out but are currently idle in the pool', + collect() { + this.set(pgPool.idleCount); + }, + }); + + new metrics.Gauge({ + name: 'pg_pool_waiting_queries', + help: 'The number of queued requests waiting on a client when all clients are checked out', + collect() { + this.set(pgPool.waitingCount); + }, + }); + + const connectedClients = new metrics.Gauge({ + name: 'connected_clients', + help: 'The number of clients connected to the streaming server', + labelNames: ['type'], + }); + + const connectedChannels = new metrics.Gauge({ + name: 'connected_channels', + help: 'The number of channels the streaming server is streaming to', + labelNames: [ 'type', 'channel' ] + }); + + const redisSubscriptions = new metrics.Gauge({ + name: 'redis_subscriptions', + help: 'The number of Redis channels the streaming server is subscribed to', + }); + + const redisMessagesReceived = new metrics.Counter({ + name: 'redis_messages_received_total', + help: 'The total number of messages the streaming server has received from redis subscriptions' + }); + + const messagesSent = new metrics.Counter({ + name: 'messages_sent_total', + help: 'The total number of messages the streaming server sent to clients per connection type', + labelNames: [ 'type' ] + }); + + // Prime the gauges so we don't loose metrics between restarts: + redisSubscriptions.set(0); + connectedClients.set({ type: 'websocket' }, 0); + connectedClients.set({ type: 'eventsource' }, 0); + + // For each channel, initialize the gauges at zero; There's only a finite set of channels available + CHANNEL_NAMES.forEach(( channel ) => { + connectedChannels.set({ type: 'websocket', channel }, 0); + connectedChannels.set({ type: 'eventsource', channel }, 0); + }); + + // Prime the counters so that we don't loose metrics between restarts. + // Unfortunately counters don't support the set() API, so instead I'm using + // inc(0) to achieve the same result. + redisMessagesReceived.inc(0); + messagesSent.inc({ type: 'websocket' }, 0); + messagesSent.inc({ type: 'eventsource' }, 0); + + // When checking metrics in the browser, the favicon is requested this + // prevents the request from falling through to the API Router, which would + // error for this endpoint: + app.get('/favicon.ico', (req, res) => res.status(404).end()); + + app.get('/api/v1/streaming/health', (req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('OK'); + }); + + app.get('/metrics', async (req, res) => { + try { + res.set('Content-Type', metrics.register.contentType); + res.end(await metrics.register.metrics()); + } catch (ex) { + log.error(ex); + res.status(500).end(); + } + }); /** * @param {string[]} channels - * @return {function(): void} + * @returns {function(): void} */ const subscriptionHeartbeat = channels => { const interval = 6 * 60; @@ -208,13 +311,15 @@ const startWorker = async (workerId) => { }; /** - * @param {string} message * @param {string} channel + * @param {string} message */ - const onRedisMessage = (message, channel) => { + const onRedisMessage = (channel, message) => { + redisMessagesReceived.inc(); + const callbacks = subs[channel]; - log.silly(`New message on channel ${channel}`); + log.silly(`New message on channel ${redisPrefix}${channel}`); if (!callbacks) { return; @@ -225,10 +330,17 @@ const startWorker = async (workerId) => { callbacks.forEach(callback => callback(json)); }; + redisSubscribeClient.on("message", onRedisMessage); + + /** + * @callback SubscriptionListener + * @param {ReturnType} json of the message + * @returns void + */ /** * @param {string} channel - * @param {function(string): void} callback + * @param {SubscriptionListener} callback */ const subscribe = (channel, callback) => { log.silly(`Adding listener for ${channel}`); @@ -237,7 +349,14 @@ const startWorker = async (workerId) => { if (subs[channel].length === 0) { log.verbose(`Subscribe ${channel}`); - redisSubscribeClient.subscribe(channel, onRedisMessage); + redisSubscribeClient.subscribe(channel, (err, count) => { + if (err) { + log.error(`Error subscribing to ${channel}`); + } + else { + redisSubscriptions.set(count); + } + }); } subs[channel].push(callback); @@ -245,7 +364,7 @@ const startWorker = async (workerId) => { /** * @param {string} channel - * @param {function(Object): void} callback + * @param {SubscriptionListener} callback */ const unsubscribe = (channel, callback) => { log.silly(`Removing listener for ${channel}`); @@ -258,7 +377,14 @@ const startWorker = async (workerId) => { if (subs[channel].length === 0) { log.verbose(`Unsubscribe ${channel}`); - redisSubscribeClient.unsubscribe(channel); + redisSubscribeClient.unsubscribe(channel, (err, count) => { + if (err) { + log.error(`Error unsubscribing to ${channel}`); + } + else { + redisSubscriptions.set(count); + } + }); delete subs[channel]; } }; @@ -277,7 +403,7 @@ const startWorker = async (workerId) => { /** * @param {any} value - * @return {boolean} + * @returns {boolean} */ const isTruthy = value => value && !FALSE_VALUES.includes(value); @@ -285,7 +411,7 @@ const startWorker = async (workerId) => { /** * @param {any} req * @param {any} res - * @param {function(Error=): void} + * @param {function(Error=): void} next */ const allowCrossDomain = (req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); @@ -298,7 +424,7 @@ const startWorker = async (workerId) => { /** * @param {any} req * @param {any} res - * @param {function(Error=): void} + * @param {function(Error=): void} next */ const setRequestId = (req, res, next) => { req.requestId = uuid.v4(); @@ -310,7 +436,7 @@ const startWorker = async (workerId) => { /** * @param {any} req * @param {any} res - * @param {function(Error=): void} + * @param {function(Error=): void} next */ const setRemoteAddress = (req, res, next) => { req.remoteAddress = req.connection.remoteAddress; @@ -321,7 +447,7 @@ const startWorker = async (workerId) => { /** * @param {any} req * @param {string[]} necessaryScopes - * @return {boolean} + * @returns {boolean} */ const isInScope = (req, necessaryScopes) => req.scopes.some(scope => necessaryScopes.includes(scope)); @@ -329,7 +455,7 @@ const startWorker = async (workerId) => { /** * @param {string} token * @param {any} req - * @return {Promise.} + * @returns {Promise.} */ const accountFromToken = (token, req) => new Promise((resolve, reject) => { pgPool.connect((err, client, done) => { @@ -367,25 +493,19 @@ const startWorker = async (workerId) => { /** * @param {any} req - * @param {boolean=} required - * @return {Promise.} + * @returns {Promise.} */ - const accountFromRequest = (req, required = true) => new Promise((resolve, reject) => { + 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']; if (!authorization && !accessToken) { - if (required) { - const err = new Error('Missing access token'); - err.status = 401; + const err = new Error('Missing access token'); + err.status = 401; - reject(err); - return; - } else { - resolve(); - return; - } + reject(err); + return; } const token = authorization ? authorization.replace(/^Bearer /, '') : accessToken; @@ -425,21 +545,10 @@ const startWorker = async (workerId) => { } }; - const PUBLIC_CHANNELS = [ - 'public', - 'public:media', - 'public:local', - 'public:local:media', - 'public:remote', - 'public:remote:media', - 'hashtag', - 'hashtag:local', - ]; - /** * @param {any} req - * @param {string} channelName - * @return {Promise.} + * @param {string|undefined} channelName + * @returns {Promise.} */ const checkScopes = (req, channelName) => new Promise((resolve, reject) => { log.silly(req.requestId, `Checking OAuth scopes for ${channelName}`); @@ -488,7 +597,7 @@ const startWorker = async (workerId) => { // variables. OAuth scope checks are moved to the point of subscription // to a specific stream. - accountFromRequest(info.req, alwaysRequireAuth).then(() => { + accountFromRequest(info.req).then(() => { callback(true, undefined, undefined); }).catch(err => { log.error(info.req.requestId, err.toString()); @@ -541,10 +650,14 @@ const startWorker = async (workerId) => { res.on('close', () => { unsubscribe(`${redisPrefix}${accessTokenChannelId}`, listener); unsubscribe(`${redisPrefix}${systemChannelId}`, listener); + + connectedChannels.labels({ type: 'eventsource', channel: 'system' }).dec(2); }); subscribe(`${redisPrefix}${accessTokenChannelId}`, listener); subscribe(`${redisPrefix}${systemChannelId}`, listener); + + connectedChannels.labels({ type: 'eventsource', channel: 'system' }).inc(2); }; /** @@ -558,7 +671,19 @@ const startWorker = async (workerId) => { return; } - accountFromRequest(req, alwaysRequireAuth).then(() => checkScopes(req, channelNameFromPath(req))).then(() => { + const channelName = channelNameFromPath(req); + + // If no channelName can be found for the request, then we should terminate + // the connection, as there's nothing to stream back + if (!channelName) { + const err = new Error('Unknown channel requested'); + err.status = 400; + + next(err); + return; + } + + accountFromRequest(req).then(() => checkScopes(req, channelName)).then(() => { subscribeHttpToSystemChannel(req, res); }).then(() => { next(); @@ -588,14 +713,14 @@ const startWorker = async (workerId) => { /** * @param {array} arr * @param {number=} shift - * @return {string} + * @returns {string} */ const placeholders = (arr, shift = 0) => arr.map((_, i) => `$${i + 1 + shift}`).join(', '); /** * @param {string} listId * @param {any} req - * @return {Promise.} + * @returns {Promise.} */ const authorizeListAccess = (listId, req) => new Promise((resolve, reject) => { const { accountId } = req; @@ -623,51 +748,76 @@ const startWorker = async (workerId) => { * @param {string[]} ids * @param {any} req * @param {function(string, string): void} output - * @param {function(string[], function(string): void): void} attachCloseHandler + * @param {undefined | function(string[], SubscriptionListener): void} attachCloseHandler + * @param {'websocket' | 'eventsource'} destinationType * @param {boolean=} needsFiltering - * @returns {function(object): void} + * @param {boolean=} allowLocalOnly + * @returns {SubscriptionListener} */ - const streamFrom = (ids, req, output, attachCloseHandler, needsFiltering = false) => { + const streamFrom = (ids, req, output, attachCloseHandler, destinationType, needsFiltering = false, allowLocalOnly = false) => { const accountId = req.accountId || req.remoteAddress; log.verbose(req.requestId, `Starting stream from ${ids.join(', ')} for ${accountId}`); - // Currently message is of type string, soon it'll be Record + const transmit = (event, payload) => { + // TODO: Replace "string"-based delete payloads with object payloads: + const encodedPayload = typeof payload === 'object' ? JSON.stringify(payload) : payload; + + messagesSent.labels({ type: destinationType }).inc(1); + + log.silly(req.requestId, `Transmitting for ${accountId}: ${event} ${encodedPayload}`); + output(event, encodedPayload); + }; + + // The listener used to process each message off the redis subscription, + // message here is an object with an `event` and `payload` property. Some + // events also include a queued_at value, but this is being removed shortly. + /** @type {SubscriptionListener} */ const listener = message => { - const { event, payload, queued_at } = message; + const { event, payload } = message; - const transmit = () => { - const now = new Date().getTime(); - const delta = now - queued_at; - const encodedPayload = typeof payload === 'object' ? JSON.stringify(payload) : payload; - - log.silly(req.requestId, `Transmitting for ${accountId}: ${event} ${encodedPayload} Delay: ${delta}ms`); - output(event, encodedPayload); - }; - - // Only messages that may require filtering are statuses, since notifications - // are already personalized and deletes do not matter - if (!needsFiltering || event !== 'update') { - transmit(); + // Only send local-only statuses to logged-in users + if ((event === 'update' || event === 'status.update') && payload.local_only && !(req.accountId && allowLocalOnly)) { + log.silly(req.requestId, `Message ${payload.id} filtered because it was local-only`); return; } - const unpackedPayload = payload; - const targetAccountIds = [unpackedPayload.account.id].concat(unpackedPayload.mentions.map(item => item.id)); - const accountDomain = unpackedPayload.account.acct.split('@')[1]; + // Streaming only needs to apply filtering to some channels and only to + // some events. This is because majority of the filtering happens on the + // Ruby on Rails side when producing the event for streaming. + // + // The only events that require filtering from the streaming server are + // `update` and `status.update`, all other events are transmitted to the + // client as soon as they're received (pass-through). + // + // The channels that need filtering are determined in the function + // `channelNameToIds` defined below: + if (!needsFiltering || (event !== 'update' && event !== 'status.update')) { + transmit(event, payload); + return; + } - if (Array.isArray(req.chosenLanguages) && unpackedPayload.language !== null && req.chosenLanguages.indexOf(unpackedPayload.language) === -1) { - log.silly(req.requestId, `Message ${unpackedPayload.id} filtered by language (${unpackedPayload.language})`); + // The rest of the logic from here on in this function is to handle + // filtering of statuses: + + // Filter based on language: + if (Array.isArray(req.chosenLanguages) && payload.language !== null && req.chosenLanguages.indexOf(payload.language) === -1) { + log.silly(req.requestId, `Message ${payload.id} filtered by language (${payload.language})`); return; } // When the account is not logged in, it is not necessary to confirm the block or mute if (!req.accountId) { - transmit(); + transmit(event, payload); return; } - pgPool.connect((err, client, done) => { + // Filter based on domain blocks, blocks, mutes, or custom filters: + const targetAccountIds = [payload.account.id].concat(payload.mentions.map(item => item.id)); + const accountDomain = payload.account.acct.split('@')[1]; + + // TODO: Move this logic out of the message handling loop + pgPool.connect((err, client, releasePgConnection) => { if (err) { log.error(err); return; @@ -682,40 +832,57 @@ const startWorker = async (workerId) => { SELECT 1 FROM mutes WHERE account_id = $1 - AND target_account_id IN (${placeholders(targetAccountIds, 2)})`, [req.accountId, unpackedPayload.account.id].concat(targetAccountIds)), + AND target_account_id IN (${placeholders(targetAccountIds, 2)})`, [req.accountId, payload.account.id].concat(targetAccountIds)), ]; if (accountDomain) { queries.push(client.query('SELECT 1 FROM account_domain_blocks WHERE account_id = $1 AND domain = $2', [req.accountId, accountDomain])); } - if (!unpackedPayload.filtered && !req.cachedFilters) { + if (!payload.filtered && !req.cachedFilters) { 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])); } Promise.all(queries).then(values => { - done(); + releasePgConnection(); + // Handling blocks & mutes and domain blocks: If one of those applies, + // then we don't transmit the payload of the event to the client if (values[0].rows.length > 0 || (accountDomain && values[1].rows.length > 0)) { return; } - if (!unpackedPayload.filtered && !req.cachedFilters) { + // If the payload already contains the `filtered` property, it means + // that filtering has been applied on the ruby on rails side, as + // such, we don't need to construct or apply the filters in streaming: + if (Object.prototype.hasOwnProperty.call(payload, "filtered")) { + transmit(event, payload); + return; + } + + // Handling for constructing the custom filters and caching them on the request + // TODO: Move this logic out of the message handling lifecycle + if (!req.cachedFilters) { const filterRows = values[accountDomain ? 2 : 1].rows; - req.cachedFilters = filterRows.reduce((cache, row) => { - if (cache[row.id]) { - cache[row.id].keywords.push([row.keyword, row.whole_word]); + req.cachedFilters = filterRows.reduce((cache, filter) => { + if (cache[filter.id]) { + cache[filter.id].keywords.push([filter.keyword, filter.whole_word]); } else { - cache[row.id] = { - keywords: [[row.keyword, row.whole_word]], - expires_at: row.expires_at, - repr: { - id: row.id, - title: row.title, - context: row.context, - expires_at: row.expires_at, - filter_action: ['warn', 'hide'][row.filter_action], + cache[filter.id] = { + keywords: [[filter.keyword, filter.whole_word]], + expires_at: filter.expires_at, + filter: { + id: filter.id, + title: filter.title, + context: filter.context, + expires_at: filter.expires_at, + // filter.filter_action is the value from the + // custom_filters.action database column, it is an integer + // representing a value in an enum defined by Ruby on Rails: + // + // enum { warn: 0, hide: 1 } + filter_action: ['warn', 'hide'][filter.filter_action], }, }; } @@ -723,6 +890,10 @@ const startWorker = async (workerId) => { return cache; }, {}); + // Construct the regular expressions for the custom filters: This + // 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 Object.keys(req.cachedFilters).forEach((key) => { req.cachedFilters[key].regexp = new RegExp(req.cachedFilters[key].keywords.map(([keyword, whole_word]) => { let expr = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); @@ -742,31 +913,58 @@ const startWorker = async (workerId) => { }); } - // Check filters - if (req.cachedFilters && !unpackedPayload.filtered) { - const status = unpackedPayload; - const searchContent = ([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 searchIndex = JSDOM.fragment(searchContent).textContent; + // Apply cachedFilters against the payload, constructing a + // `filter_results` array of FilterResult entities + if (req.cachedFilters) { + const status = payload; + // TODO: Calculate searchableContent in Ruby on Rails: + 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(); - payload.filtered = []; - Object.values(req.cachedFilters).forEach((cachedFilter) => { - if ((cachedFilter.expires_at === null || cachedFilter.expires_at > now)) { - const keyword_matches = searchIndex.match(cachedFilter.regexp); - if (keyword_matches) { - payload.filtered.push({ - filter: cachedFilter.repr, - keyword_matches, - }); - } + 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) { + return results; } - }); - } - transmit(); + // Just in-case JSDOM fails to find textContent in searchableContent + if (!searchableTextContent) { + return results; + } + + const keyword_matches = searchableTextContent.match(cachedFilter.regexp); + if (keyword_matches) { + // results is an Array of FilterResult; status_matches is always + // null as we only are only applying the keyword-based custom + // filters, not the status-based custom filters. + // https://docs.joinmastodon.org/entities/FilterResult/ + results.push({ + filter: cachedFilter.filter, + keyword_matches, + status_matches: null + }); + } + + return results; + }, []); + + // Send the payload + the FilterResults as the `filtered` property + // to the streaming connection. To reach this code, the `event` must + // have been either `update` or `status.update`, meaning the + // `payload` is a Status entity, which has a `filtered` property: + // + // filtered: https://docs.joinmastodon.org/entities/Status/#filtered + transmit(event, { + ...payload, + filtered: filter_results + }); + } else { + transmit(event, payload); + } }).catch(err => { log.error(err); - done(); + releasePgConnection(); }); }); }; @@ -775,7 +973,7 @@ const startWorker = async (workerId) => { subscribe(`${redisPrefix}${id}`, listener); }); - if (attachCloseHandler) { + if (typeof attachCloseHandler === 'function') { attachCloseHandler(ids.map(id => `${redisPrefix}${id}`), listener); } @@ -785,11 +983,20 @@ const startWorker = async (workerId) => { /** * @param {any} req * @param {any} res - * @return {function(string, string): void} + * @returns {function(string, string): void} */ const streamToHttp = (req, res) => { const accountId = req.accountId || req.remoteAddress; + const channelName = channelNameFromPath(req); + + connectedClients.labels({ type: 'eventsource' }).inc(); + + // In theory we'll always have a channel name, but channelNameFromPath can return undefined: + if (typeof channelName === 'string') { + connectedChannels.labels({ type: 'eventsource', channel: channelName }).inc(); + } + res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-store'); res.setHeader('Transfer-Encoding', 'chunked'); @@ -800,6 +1007,14 @@ const startWorker = async (workerId) => { req.on('close', () => { log.verbose(req.requestId, `Ending stream for ${accountId}`); + // We decrement these counters here instead of in streamHttpEnd as in that + // method we don't have knowledge of the channel names + connectedClients.labels({ type: 'eventsource' }).dec(); + // In theory we'll always have a channel name, but channelNameFromPath can return undefined: + if (typeof channelName === 'string') { + connectedChannels.labels({ type: 'eventsource', channel: channelName }).dec(); + } + clearInterval(heartbeat); }); @@ -812,12 +1027,13 @@ const startWorker = async (workerId) => { /** * @param {any} req * @param {function(): void} [closeHandler] - * @return {function(string[]): void} + * @returns {function(string[], SubscriptionListener): void} */ - const streamHttpEnd = (req, closeHandler = undefined) => (ids) => { + + const streamHttpEnd = (req, closeHandler = undefined) => (ids, listener) => { req.on('close', () => { ids.forEach(id => { - unsubscribe(id); + unsubscribe(id, listener); }); if (closeHandler) { @@ -830,7 +1046,7 @@ const startWorker = async (workerId) => { * @param {any} req * @param {any} ws * @param {string[]} streamName - * @return {function(string, string): void} + * @returns {function(string, string): void} */ const streamToWs = (req, ws, streamName) => (event, payload) => { if (ws.readyState !== ws.OPEN) { @@ -838,7 +1054,11 @@ const startWorker = async (workerId) => { return; } - ws.send(JSON.stringify({ stream: streamName, event, payload })); + ws.send(JSON.stringify({ stream: streamName, event, payload }), (err) => { + if (err) { + log.error(req.requestId, `Failed to send to websocket: ${err}`); + } + }); }; /** @@ -849,45 +1069,23 @@ const startWorker = async (workerId) => { res.end(JSON.stringify({ error: 'Not found' })); }; - app.use(setRequestId); - app.use(setRemoteAddress); - app.use(allowCrossDomain); + const api = express.Router(); - app.get('/api/v1/streaming/health', (req, res) => { - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('OK'); - }); + app.use(api); - app.get('/metrics', (req, res) => server.getConnections((err, count) => { - res.writeHeader(200, { 'Content-Type': 'application/openmetrics-text; version=1.0.0; charset=utf-8' }); - res.write('# TYPE connected_clients gauge\n'); - res.write('# HELP connected_clients The number of clients connected to the streaming server\n'); - res.write(`connected_clients ${count}.0\n`); - res.write('# TYPE connected_channels gauge\n'); - res.write('# HELP connected_channels The number of Redis channels the streaming server is subscribed to\n'); - res.write(`connected_channels ${Object.keys(subs).length}.0\n`); - res.write('# TYPE pg_pool_total_connections gauge\n'); - res.write('# HELP pg_pool_total_connections The total number of clients existing within the pool\n'); - res.write(`pg_pool_total_connections ${pgPool.totalCount}.0\n`); - res.write('# TYPE pg_pool_idle_connections gauge\n'); - res.write('# HELP pg_pool_idle_connections The number of clients which are not checked out but are currently idle in the pool\n'); - res.write(`pg_pool_idle_connections ${pgPool.idleCount}.0\n`); - res.write('# TYPE pg_pool_waiting_queries gauge\n'); - res.write('# HELP pg_pool_waiting_queries The number of queued requests waiting on a client when all clients are checked out\n'); - res.write(`pg_pool_waiting_queries ${pgPool.waitingCount}.0\n`); - res.write('# EOF\n'); - res.end(); - })); + api.use(setRequestId); + api.use(setRemoteAddress); + api.use(allowCrossDomain); - app.use(authenticationMiddleware); - app.use(errorMiddleware); + api.use(authenticationMiddleware); + api.use(errorMiddleware); - app.get('/api/v1/streaming/*', (req, res) => { + api.get('/api/v1/streaming/*', (req, res) => { channelNameToIds(req, channelNameFromPath(req), req.query).then(({ channelIds, options }) => { const onSend = streamToHttp(req, res); const onEnd = streamHttpEnd(req, subscriptionHeartbeat(channelIds)); - streamFrom(channelIds, req, onSend, onEnd, options.needsFiltering); + streamFrom(channelIds, req, onSend, onEnd, 'eventsource', options.needsFiltering, options.allowLocalOnly); }).catch(err => { log.verbose(req.requestId, 'Subscription error:', err.toString()); httpNotFound(res); @@ -905,7 +1103,7 @@ const startWorker = async (workerId) => { /** * @param {any} req - * @return {string[]} + * @returns {string[]} */ const channelsForUserStream = req => { const arr = [`timeline:${req.accountId}`]; @@ -930,7 +1128,7 @@ const startWorker = async (workerId) => { /** * @param {string} str - * @return {string} + * @returns {string} */ const foldToASCII = str => { const regex = new RegExp(NON_ASCII_CHARS.split('').join('|'), 'g'); @@ -943,7 +1141,7 @@ const startWorker = async (workerId) => { /** * @param {string} str - * @return {string} + * @returns {string} */ const normalizeHashtag = str => { return foldToASCII(str.normalize('NFKC').toLowerCase()).replace(/[^\p{L}\p{N}_\u00b7\u200c]/gu, ''); @@ -953,70 +1151,84 @@ const startWorker = async (workerId) => { * @param {any} req * @param {string} name * @param {StreamParams} params - * @return {Promise.<{ channelIds: string[], options: { needsFiltering: boolean } }>} + * @returns {Promise.<{ channelIds: string[], options: { needsFiltering: boolean } }>} */ const channelNameToIds = (req, name, params) => new Promise((resolve, reject) => { switch (name) { case 'user': resolve({ channelIds: channelsForUserStream(req), - options: { needsFiltering: false }, + options: { needsFiltering: false, allowLocalOnly: true }, }); break; case 'user:notification': resolve({ channelIds: [`timeline:${req.accountId}:notifications`], - options: { needsFiltering: false }, + options: { needsFiltering: false, allowLocalOnly: true }, }); break; case 'public': resolve({ channelIds: ['timeline:public'], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: isTruthy(params.allow_local_only) }, + }); + + break; + case 'public:allow_local_only': + resolve({ + channelIds: ['timeline:public'], + options: { needsFiltering: true, allowLocalOnly: true }, }); break; case 'public:local': resolve({ channelIds: ['timeline:public:local'], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: true }, }); break; case 'public:remote': resolve({ channelIds: ['timeline:public:remote'], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: false }, }); break; case 'public:media': resolve({ channelIds: ['timeline:public:media'], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: isTruthy(params.allow_local_only) }, + }); + + break; + case 'public:allow_local_only:media': + resolve({ + channelIds: ['timeline:public:media'], + options: { needsFiltering: true, allowLocalOnly: true }, }); break; case 'public:local:media': resolve({ channelIds: ['timeline:public:local:media'], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: true }, }); break; case 'public:remote:media': resolve({ channelIds: ['timeline:public:remote:media'], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: false }, }); break; case 'direct': resolve({ channelIds: [`timeline:direct:${req.accountId}`], - options: { needsFiltering: false }, + options: { needsFiltering: false, allowLocalOnly: true }, }); break; @@ -1026,7 +1238,7 @@ const startWorker = async (workerId) => { } else { resolve({ channelIds: [`timeline:hashtag:${normalizeHashtag(params.tag)}`], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: true }, }); } @@ -1037,7 +1249,7 @@ const startWorker = async (workerId) => { } else { resolve({ channelIds: [`timeline:hashtag:${normalizeHashtag(params.tag)}:local`], - options: { needsFiltering: true }, + options: { needsFiltering: true, allowLocalOnly: true }, }); } @@ -1046,7 +1258,7 @@ const startWorker = async (workerId) => { authorizeListAccess(params.list, req).then(() => { resolve({ channelIds: [`timeline:list:${params.list}`], - options: { needsFiltering: false }, + options: { needsFiltering: false, allowLocalOnly: true }, }); }).catch(() => { reject('Not authorized to stream this list'); @@ -1061,7 +1273,7 @@ const startWorker = async (workerId) => { /** * @param {string} channelName * @param {StreamParams} params - * @return {string[]} + * @returns {string[]} */ const streamNameFromChannelName = (channelName, params) => { if (channelName === 'list') { @@ -1077,15 +1289,16 @@ const startWorker = async (workerId) => { * @typedef WebSocketSession * @property {any} socket * @property {any} request - * @property {Object.} subscriptions + * @property {Object.} subscriptions */ /** * @param {WebSocketSession} session * @param {string} channelName * @param {StreamParams} params + * @returns {void} */ - const subscribeWebsocketToChannel = ({ socket, request, subscriptions }, channelName, params) => + const subscribeWebsocketToChannel = ({ socket, request, subscriptions }, channelName, params) => { checkScopes(request, channelName).then(() => channelNameToIds(request, channelName, params)).then(({ channelIds, options, @@ -1096,9 +1309,12 @@ const startWorker = async (workerId) => { const onSend = streamToWs(request, socket, streamNameFromChannelName(channelName, params)); const stopHeartbeat = subscriptionHeartbeat(channelIds); - const listener = streamFrom(channelIds, request, onSend, undefined, options.needsFiltering); + const listener = streamFrom(channelIds, request, onSend, undefined, 'websocket', options.needsFiltering, options.allowLocalOnly); + + connectedChannels.labels({ type: 'websocket', channel: channelName }).inc(); subscriptions[channelIds.join(';')] = { + channelName, listener, stopHeartbeat, }; @@ -1106,35 +1322,47 @@ const startWorker = async (workerId) => { log.verbose(request.requestId, 'Subscription error:', err.toString()); socket.send(JSON.stringify({ error: err.toString() })); }); + }; + + + const removeSubscription = (subscriptions, channelIds, request) => { + log.verbose(request.requestId, `Ending stream from ${channelIds.join(', ')} for ${request.accountId}`); + + const subscription = subscriptions[channelIds.join(';')]; + + if (!subscription) { + return; + } + + channelIds.forEach(channelId => { + unsubscribe(`${redisPrefix}${channelId}`, subscription.listener); + }); + + connectedChannels.labels({ type: 'websocket', channel: subscription.channelName }).dec(); + subscription.stopHeartbeat(); + + delete subscriptions[channelIds.join(';')]; + }; /** * @param {WebSocketSession} session * @param {string} channelName * @param {StreamParams} params + * @returns {void} */ - const unsubscribeWebsocketFromChannel = ({ socket, request, subscriptions }, channelName, params) => + const unsubscribeWebsocketFromChannel = ({ socket, request, subscriptions }, channelName, params) => { channelNameToIds(request, channelName, params).then(({ channelIds }) => { - log.verbose(request.requestId, `Ending stream from ${channelIds.join(', ')} for ${request.accountId}`); - - const subscription = subscriptions[channelIds.join(';')]; - - if (!subscription) { - return; - } - - const { listener, stopHeartbeat } = subscription; - - channelIds.forEach(channelId => { - unsubscribe(`${redisPrefix}${channelId}`, listener); - }); - - stopHeartbeat(); - - delete subscriptions[channelIds.join(';')]; + removeSubscription(subscriptions, channelIds, request); }).catch(err => { - log.verbose(request.requestId, 'Unsubscription error:', err); - socket.send(JSON.stringify({ error: err.toString() })); + log.verbose(request.requestId, 'Unsubscribe error:', err); + + // If we have a socket that is alive and open still, send the error back to the client: + // FIXME: In other parts of the code ws === socket + if (socket.isAlive && socket.readyState === socket.OPEN) { + socket.send(JSON.stringify({ error: "Error unsubscribing from channel" })); + } }); + }; /** * @param {WebSocketSession} session @@ -1155,21 +1383,25 @@ const startWorker = async (workerId) => { subscribe(`${redisPrefix}${systemChannelId}`, listener); subscriptions[accessTokenChannelId] = { + channelName: 'system', listener, stopHeartbeat: () => { }, }; subscriptions[systemChannelId] = { + channelName: 'system', listener, stopHeartbeat: () => { }, }; + + connectedChannels.labels({ type: 'websocket', channel: 'system' }).inc(2); }; /** * @param {string|string[]} arrayOrString - * @return {string} + * @returns {string} */ const firstParam = arrayOrString => { if (Array.isArray(arrayOrString)) { @@ -1180,13 +1412,17 @@ const startWorker = async (workerId) => { }; wss.on('connection', (ws, req) => { - const location = url.parse(req.url, true); + // Note: url.parse could throw, which would terminate the connection, so we + // increment the connected clients metric straight away when we establish + // the connection, without waiting: + connectedClients.labels({ type: 'websocket' }).inc(); + // Setup request properties: req.requestId = uuid.v4(); req.remoteAddress = ws._socket.remoteAddress; + // Setup connection keep-alive state: ws.isAlive = true; - ws.on('pong', () => { ws.isAlive = true; }); @@ -1200,26 +1436,31 @@ const startWorker = async (workerId) => { subscriptions: {}, }; - const onEnd = () => { - const keys = Object.keys(session.subscriptions); + ws.on('close', function onWebsocketClose() { + const subscriptions = Object.keys(session.subscriptions); - keys.forEach(channelIds => { - const { listener, stopHeartbeat } = session.subscriptions[channelIds]; - - channelIds.split(';').forEach(channelId => { - unsubscribe(`${redisPrefix}${channelId}`, listener); - }); - - stopHeartbeat(); + subscriptions.forEach(channelIds => { + removeSubscription(session.subscriptions, channelIds.split(';'), req); }); - }; - ws.on('close', onEnd); - ws.on('error', onEnd); + // Decrement the metrics for connected clients: + connectedClients.labels({ type: 'websocket' }).dec(); + + // ensure garbage collection: + session.socket = null; + session.request = null; + session.subscriptions = {}; + }); + + // Note: immediately after the `error` event is emitted, the `close` event + // is emitted. As such, all we need to do is log the error here. + ws.on('error', (err) => { + log.error('websocket', err.toString()); + }); ws.on('message', (data, isBinary) => { if (isBinary) { - log.warn('socket', 'Received binary data, closing connection'); + log.warn('websocket', 'Received binary data, closing connection'); ws.close(1003, 'The mastodon streaming server does not support binary messages'); return; } @@ -1242,7 +1483,10 @@ const startWorker = async (workerId) => { subscribeWebsocketToSystemChannel(session); - if (location.query.stream) { + // Parse the URL for the connection arguments (if supplied), url.parse can throw: + const location = req.url && url.parse(req.url, true); + + if (location && location.query.stream) { subscribeWebsocketToChannel(session, firstParam(location.query.stream), location.query); } }); @@ -1260,11 +1504,10 @@ const startWorker = async (workerId) => { }, 30000); attachServerWithConfig(server, address => { - log.warn(`Worker ${workerId} now listening on ${address}`); + log.warn(`Streaming API now listening on ${address}`); }); const onExit = () => { - log.warn(`Worker ${workerId} exiting`); server.close(); process.exit(0); }; @@ -1302,34 +1545,4 @@ const attachServerWithConfig = (server, onSuccess) => { } }; -/** - * @param {function(Error=): void} onSuccess - */ -const onPortAvailable = onSuccess => { - const testServer = http.createServer(); - - testServer.once('error', err => { - onSuccess(err); - }); - - testServer.once('listening', () => { - testServer.once('close', () => onSuccess()); - testServer.close(); - }); - - attachServerWithConfig(testServer); -}; - -onPortAvailable(err => { - if (err) { - log.error('Could not start server, the port or socket is in use'); - return; - } - - throng({ - workers: numWorkers, - lifetime: Infinity, - start: startWorker, - master: startMaster, - }); -}); +startServer(); diff --git a/stylelint.config.js b/stylelint.config.js index 0f8267a81f..308d606f6e 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -2,27 +2,48 @@ module.exports = { extends: ['stylelint-config-standard-scss'], ignoreFiles: [ 'app/javascript/styles/mastodon/reset.scss', + 'app/javascript/flavours/glitch/styles/reset.scss', + 'app/javascript/flavours/glitch/styles/modern/modern.css', + 'app/javascript/styles/win95.scss', + 'coverage/**/*', 'node_modules/**/*', + 'public/assets/**/*', + 'public/packs/**/*', + 'public/packs-test/**/*', 'vendor/**/*', ], + reportDescriptionlessDisables: true, + reportInvalidScopeDisables: true, + reportNeedlessDisables: true, rules: { 'at-rule-empty-line-before': null, 'color-function-notation': null, 'color-hex-length': null, 'declaration-block-no-redundant-longhand-properties': null, - 'max-line-length': null, 'no-descending-specificity': null, 'no-duplicate-selectors': null, 'number-max-precision': 8, - 'property-no-unknown': null, 'property-no-vendor-prefix': null, 'selector-class-pattern': null, 'selector-id-pattern': null, - 'string-quotes': null, 'value-keyword-case': null, 'value-no-vendor-prefix': null, 'scss/dollar-variable-empty-line-before': null, 'scss/no-global-function-names': null, }, + overrides: [ + { + 'files': ['app/javascript/styles/mailer.scss'], + rules: { + 'property-no-unknown': [ + true, + { + ignoreProperties: [ + '/^mso-/', + ] }, + ], + }, + }, + ], }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..70d65496a3 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "target": "esnext", + "module": "CommonJS", + "moduleResolution": "node", + "allowJs": true, + "noEmit": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "baseUrl": "./", + "paths": { + "locales": ["app/javascript/locales"], + "styles/*": ["app/javascript/styles/*"], + "packs/public-path": ["app/javascript/packs/public-path"], + "flavours/glitch": ["app/javascript/flavours/glitch"], + "flavours/glitch/*": ["app/javascript/flavours/glitch/*"], + "mastodon": ["app/javascript/mastodon"], + "mastodon/*": ["app/javascript/mastodon/*"] + } + }, + "include": [ + "app/javascript/mastodon", + "app/javascript/packs", + "app/javascript/types", + "app/javascript/flavours/glitch", + "app/javascript/core" + ] +} diff --git a/yarn.lock b/yarn.lock index 3fd6d129bd..2f87cf5884 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,342 +3,323 @@ "@adobe/css-tools@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd" - integrity sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g== + version "4.2.0" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.2.0.tgz#e1a84fca468f4b337816fcb7f0964beb620ba855" + integrity sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA== -"@ampproject/remapping@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" - integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/trace-mapping" "^0.3.0" + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" "@apideck/better-ajv-errors@^0.3.1": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.3.tgz#ab0b1e981e1749bf59736cf7ebe25cfc9f949c15" - integrity sha512-9o+HO2MbJhJHjDYZaDxJmSDckvDpiuItEsrIShV0DXeCshXWRHhqYyU/PKHMkuClOmFnZhRd6wzv4vpDu/dRKg== + version "0.3.6" + resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz#957d4c28e886a64a8141f7522783be65733ff097" + integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== dependencies: json-schema "^0.4.0" jsonpointer "^5.0.0" leven "^3.1.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" - integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== -"@babel/compat-data@^7.20.5": - version "7.20.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" - integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== - -"@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.20.12", "@babel/core@^7.7.2": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" - integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== +"@babel/core@^7.10.4", "@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.22.1": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helpers" "^7.20.7" - "@babel/parser" "^7.20.7" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.12" - "@babel/types" "^7.20.7" + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.8" + "@babel/types" "^7.22.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" - semver "^6.3.0" + semver "^6.3.1" -"@babel/eslint-parser@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" - integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ== +"@babel/generator@^7.22.5": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.7.tgz#a6b8152d5a621893f2c9dacf9a4e286d520633d5" + integrity sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ== dependencies: - "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" - eslint-visitor-keys "^2.1.0" - semver "^6.3.0" - -"@babel/generator@^7.20.7", "@babel/generator@^7.7.2": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" - integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== - dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.22.5" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.6.tgz#f14d640ed1ee9246fb33b8255f08353acfe70e6a" - integrity sha512-KT10c1oWEpmrIRYnthbzHgoOf6B+Xd6a5yhdbNtdhtG7aO1or5HViuf1TQR36xY/QprXA5nvxO6nAjhJ4y38jw== +"@babel/generator@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" + integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" -"@babel/helper-builder-react-jsx@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.18.6.tgz#b3a302c0eb4949e5356b400cb752a91e93bf9b79" - integrity sha512-2ndBVP5f9zwHWQeBr5EgqTAvFhPDViMW969bbJzRhKUUylnC39CdFZdVmqk+UtkxIpwm/efPgm3SzXUSlJnjAw== +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" - integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz#a3f4758efdd0190d8927fcffd261755937c71878" + integrity sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw== dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" + "@babel/types" "^7.22.5" + +"@babel/helper-builder-react-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.22.5.tgz#9b325d4558fb51b0bb51e4837a2bf8f707029e97" + integrity sha512-GYZBuAC9Vl4jnPun18TeNGyqkKWQ+3AtZHbgnrdT//0yCV+qcFyXj0X+9DJyD2jYi0C+55gRcUAhE35sk2Mm9g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" lru-cache "^5.1.1" - semver "^6.3.0" + semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.12": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz#4349b928e79be05ed2d1643b20b99bb87c503819" - integrity sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz#c36ea240bb3348f942f08b0fbe28d6d979fab236" + integrity sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" - integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.1.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== +"@babel/helper-define-polyfill-provider@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz#af1429c4a83ac316a6a8c2cc8ff45cb5d2998d3a" + integrity sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" + "@babel/types" "^7.22.5" -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== +"@babel/helper-member-expression-to-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz#0a7c56117cad3372fbf8d2fb4bf8f8d64a1e76b2" + integrity sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz#a6f26e919582275a93c3aa6594756d71b0bb7f05" - integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw== +"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.22.5" -"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.11": - version "7.20.11" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" - integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.10" - "@babel/types" "^7.20.7" + "@babel/types" "^7.22.5" -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== - -"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" + integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.19.1", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" - integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/types" "^7.22.5" -"@babel/helper-simple-access@^7.19.4", "@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== dependencies: - "@babel/types" "^7.20.2" + "@babel/types" "^7.22.5" -"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" - integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== +"@babel/helper-split-export-declaration@^7.22.5", "@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.22.5" -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helper-wrap-function@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz#189937248c45b0182c1dcf32f3444ca153944cb9" + integrity sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q== dependencies: - "@babel/types" "^7.20.0" + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== dependencies: - "@babel/types" "^7.18.6" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.6" + "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helper-wrap-function@^7.18.9": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.10.tgz#a7fcd3ab9b1be4c9b52cf7d7fdc1e88c2ce93396" - integrity sha512-95NLBP59VWdfK2lyLKe6eTMq9xg+yWKzxzxbJ1wcYNi1Auz200+83fMDADjRxBvc2QQor5zja2yTQzXGhk2GtQ== +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== dependencies: - "@babel/helper-function-name" "^7.18.9" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/helpers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce" - integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA== - dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" + "@babel/helper-validator-identifier" "^7.22.5" chalk "^2.0.0" js-tokens "^4.0.0" "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" - integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" + integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== +"@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz#87245a21cd69a73b0b81bcda98d443d6df08f05e" + integrity sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" - integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz#fef09f9499b1f1c930da8a0c419db42167d792ca" + integrity sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.5" -"@babel/plugin-proposal-async-generator-functions@^7.20.1": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9" - integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.18.6": +"@babel/plugin-proposal-class-properties@^7.14.5": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== @@ -346,121 +327,23 @@ "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" - integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== +"@babel/plugin-proposal-object-rest-spread@^7.14.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-proposal-decorators@^7.20.13": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz#b6bea3b18e88443688fa7ed2cc06d2c60da9f4a7" - integrity sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.20.12" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.19.0" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" - integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d" - integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ== - dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" + "@babel/compat-data" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.7" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.1" + "@babel/plugin-transform-parameters" "^7.20.7" -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== -"@babel/plugin-proposal-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" - integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" - integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== @@ -496,13 +379,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" - integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== - dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -517,14 +393,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== +"@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -538,12 +421,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.18.6", "@babel/plugin-syntax-jsx@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== +"@babel/plugin-syntax-jsx@7", "@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -601,348 +484,492 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" - integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== +"@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-arrow-functions@^7.18.6": +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" - integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" - integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== +"@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== +"@babel/plugin-transform-async-generator-functions@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz#053e76c0a903b72b573cb1ab7d6882174d460a1b" + integrity sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-block-scoping@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz#f59b1767e6385c663fd0bce655db6ca9c8b236ed" - integrity sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ== +"@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" -"@babel/plugin-transform-classes@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2" - integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g== +"@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.19.1" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-block-scoping@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz#8bfc793b3a4b2742c0983fadc1480d843ecea31b" + integrity sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-class-static-block@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz#3e40c46f048403472d6f4183116d5e46b1bff5ba" + integrity sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-transform-classes@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" - integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== +"@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" -"@babel/plugin-transform-destructuring@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792" - integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw== +"@babel/plugin-transform-destructuring@^7.14.7", "@babel/plugin-transform-destructuring@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz#d3aca7438f6c26c78cdd0b0ba920a336001b27cc" + integrity sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== +"@babel/plugin-transform-dotall-regex@^7.22.5", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-dynamic-import@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz#d6908a8916a810468c4edff73b5b75bda6ad393e" + integrity sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== +"@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-export-namespace-from@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz#57c41cb1d0613d22f548fddd8b288eedb9973a5b" + integrity sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-for-of@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz#ab1b8a200a8f990137aff9a084f8de4099ab173f" + integrity sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-amd@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz#aca391801ae55d19c4d8d2ebfeaa33df5f2a2cbd" - integrity sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg== +"@babel/plugin-transform-json-strings@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz#14b64352fdf7e1f737eed68de1a1468bd2a77ec0" + integrity sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A== dependencies: - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-modules-commonjs@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz#25b32feef24df8038fc1ec56038917eacb0b730c" - integrity sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ== +"@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== dependencies: - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-simple-access" "^7.19.4" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-systemjs@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" - integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== +"@babel/plugin-transform-logical-assignment-operators@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz#66ae5f068fd5a9a5dc570df16f56c2a8462a9d6c" + integrity sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" - integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== +"@babel/plugin-transform-modules-amd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz#4e045f55dcf98afd00f85691a68fc0780704f526" + integrity sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-modules-commonjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz#7d9875908d19b8c0536085af7b053fd5bd651bfa" + integrity sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-modules-systemjs@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz#18c31410b5e579a0092638f95c896c2a98a5d496" + integrity sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" -"@babel/plugin-transform-parameters@^7.20.1": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz#7b3468d70c3c5b62e46be0a47b6045d8590fb748" - integrity sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA== +"@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-display-name@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" - integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== +"@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-inline-elements@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.18.6.tgz#d0676948eb5a11d547de6add7e8a2c522ec708f5" - integrity sha512-uo3yD1EXhDxmk1Y/CeFDdHS5t22IOUBooLPFOrrjfpYmDM9Vg61xbIaWeWkbYQ7Aq0zMf30/FfKoQgFwyqw6Bg== +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.3", "@babel/plugin-transform-nullish-coalescing-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz#f8872c65776e0b552e0849d7596cddd416c3e381" + integrity sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA== dependencies: - "@babel/helper-builder-react-jsx" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-react-jsx-development@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" - integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== +"@babel/plugin-transform-numeric-separator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz#57226a2ed9e512b9b446517ab6fa2d17abb83f58" + integrity sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g== dependencies: - "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.6.tgz#2721e96d31df96e3b7ad48ff446995d26bc028ff" - integrity sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw== +"@babel/plugin-transform-object-rest-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz#9686dc3447df4753b0b2a2fae7e8bc33cdc1f2e1" + integrity sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/types" "^7.18.6" + "@babel/compat-data" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.5" -"@babel/plugin-transform-react-pure-annotations@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" - integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== +"@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" - integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== +"@babel/plugin-transform-optional-catch-binding@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz#842080be3076703be0eaf32ead6ac8174edee333" + integrity sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - regenerator-transform "^0.15.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-optional-chaining@^7.22.5", "@babel/plugin-transform-optional-chaining@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz#4bacfe37001fe1901117672875e931d439811564" + integrity sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-runtime@^7.19.6": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz#9d2a9dbf4e12644d6f46e5e75bfbf02b5d6e9194" - integrity sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw== +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz#c3542dd3c39b42c8069936e48717a8d179d63a18" + integrity sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-spread@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" - integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== +"@babel/plugin-transform-private-property-in-object@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz#07a77f28cbb251546a43d175a1dda4cf3ef83e32" + integrity sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== +"@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/plugin-transform-react-display-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" + integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/plugin-transform-react-inline-elements@^7.21.0": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.22.5.tgz#f158486764de87f84706f5e9c98506df3015d9a4" + integrity sha512-m+OHS1E33wsWyv37bQXNzY/AB7vMTR1BYGG/KW+HGHdKeQS03sUAweNdGaDh8wKmAqh6ZbRRtFjPbhyYFToSbQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-builder-react-jsx" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-react-jsx" "^7.22.5" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@babel/plugin-transform-react-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz#932c291eb6dd1153359e2a90cb5e557dcf068416" + integrity sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" - integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== +"@babel/plugin-transform-react-pure-annotations@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" + integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.20.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.14.5", "@babel/plugin-transform-regenerator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz#cd8a68b228a5f75fa01420e8cc2fc400f0fc32aa" + integrity sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.1" + +"@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-runtime@^7.15.0", "@babel/plugin-transform-runtime@^7.22.4": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz#a87b11e170cbbfb018e6a2bf91f5c6e533b9e027" + integrity sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + semver "^6.3.1" + +"@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typescript@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz#5c0f7adfc1b5f38c4dbc8f79b1f0f8074134bd7d" + integrity sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" + +"@babel/plugin-transform-unicode-escapes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz#ce0c248522b1cb22c7c992d88301a5ead70e806c" + integrity sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.22.4": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.9.tgz#57f17108eb5dfd4c5c25a44c1977eba1df310ac7" + integrity sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.5" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-assertions" "^7.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -952,45 +979,62 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.20.2" - "@babel/plugin-transform-classes" "^7.20.2" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.20.2" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.19.6" - "@babel/plugin-transform-modules-commonjs" "^7.19.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.6" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.20.1" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.7" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.22.5" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.5" + "@babel/plugin-transform-classes" "^7.22.6" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.22.5" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.5" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.5" + "@babel/plugin-transform-for-of" "^7.22.5" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.5" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.5" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-modules-systemjs" "^7.22.5" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.5" + "@babel/plugin-transform-numeric-separator" "^7.22.5" + "@babel/plugin-transform-object-rest-spread" "^7.22.5" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.6" + "@babel/plugin-transform-parameters" "^7.22.5" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.5" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.5" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.5" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" + "@babel/types" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + core-js-compat "^3.31.0" + semver "^6.3.1" "@babel/preset-modules@^0.1.5": version "0.1.5" @@ -1003,25 +1047,33 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" - integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== +"@babel/preset-react@^7.22.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.5.tgz#c4d6058fbf80bccad02dd8c313a9aaa67e3c3dd6" + integrity sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-react-display-name" "^7.18.6" - "@babel/plugin-transform-react-jsx" "^7.18.6" - "@babel/plugin-transform-react-jsx-development" "^7.18.6" - "@babel/plugin-transform-react-pure-annotations" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-transform-react-display-name" "^7.22.5" + "@babel/plugin-transform-react-jsx" "^7.22.5" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.22.5" -"@babel/runtime-corejs3@^7.10.2": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.10.3.tgz#931ed6941d3954924a7aa967ee440e60c507b91a" - integrity sha512-HA7RPj5xvJxQl429r5Cxr2trJwOfPjKiqhCXcdQPSqO2G0RHPZpXu4fkYmBaTKCp2c/jRaMK9GB/lN+7zvvFPw== +"@babel/preset-typescript@^7.21.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz#16367d8b01d640e9a507577ed4ee54e0101e51c8" + integrity sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ== dependencies: - core-js-pure "^3.0.0" - regenerator-runtime "^0.13.4" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.22.5" + "@babel/plugin-transform-typescript" "^7.22.5" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@7.0.0": version "7.0.0" @@ -1030,45 +1082,61 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.15.4", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" - integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.15.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.22.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== dependencies: regenerator-runtime "^0.13.11" -"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== +"@babel/template@^7.22.5", "@babel/template@^7.3.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" -"@babel/traverse@^7.18.10", "@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.2": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5" - integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ== +"@babel/traverse@7", "@babel/traverse@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" + integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" - integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.12.11", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1076,102 +1144,153 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@csstools/selector-specificity@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" - integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== -"@emotion/babel-plugin@^11.7.1": - version "11.9.2" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.9.2.tgz#723b6d394c89fb2ef782229d92ba95a740576e95" - integrity sha512-Pr/7HGH6H6yKgnVFNEj2MVlreu3ADqftqjqwUvDy/OJzKFgxKeTQ+eeUf20FOTuHVkDON2iNa25rAXVYtWJCjw== +"@csstools/css-parser-algorithms@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.0.tgz#0cc3a656dc2d638370ecf6f98358973bfbd00141" + integrity sha512-dTKSIHHWc0zPvcS5cqGP+/TPFUJB0ekJ9dGKvMAFoNuBFhDPBt9OMGNZiIA5vTiNdGHHBeScYPXIGBMnVOahsA== + +"@csstools/css-tokenizer@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz#07ae11a0a06365d7ec686549db7b729bc036528e" + integrity sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA== + +"@csstools/media-query-list-parser@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.2.tgz#6ef642b728d30c1009bfbba3211c7e4c11302728" + integrity sha512-M8cFGGwl866o6++vIY7j1AKuq9v57cf+dGepScwCcbut9ypJNr4Cj+LLTWligYUZ0uyhEoJDKt5lvyBfh2L3ZQ== + +"@csstools/selector-specificity@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz#798622546b63847e82389e473fd67f2707d82247" + integrity sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g== + +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/plugin-syntax-jsx" "^7.12.13" - "@babel/runtime" "^7.13.10" - "@emotion/hash" "^0.8.0" - "@emotion/memoize" "^0.7.5" - "@emotion/serialize" "^1.0.2" - babel-plugin-macros "^2.6.1" + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" find-root "^1.1.0" source-map "^0.5.7" - stylis "4.0.13" + stylis "4.2.0" -"@emotion/cache@^11.4.0", "@emotion/cache@^11.7.1": - version "11.7.1" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539" - integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A== +"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== dependencies: - "@emotion/memoize" "^0.7.4" - "@emotion/sheet" "^1.1.0" - "@emotion/utils" "^1.0.0" - "@emotion/weak-memoize" "^0.2.5" - stylis "4.0.13" + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" -"@emotion/hash@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" - integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== -"@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" - integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== "@emotion/react@^11.8.1": - version "11.9.0" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.9.0.tgz#b6d42b1db3bd7511e7a7c4151dc8bc82e14593b8" - integrity sha512-lBVSF5d0ceKtfKCDQJveNAtkC7ayxpVlgOohLgXqRwqWr9bOf4TZAFFyIcNngnV6xK6X4x2ZeXq7vliHkoVkxQ== + version "11.11.1" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" + integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== dependencies: - "@babel/runtime" "^7.13.10" - "@emotion/babel-plugin" "^11.7.1" - "@emotion/cache" "^11.7.1" - "@emotion/serialize" "^1.0.3" - "@emotion/utils" "^1.1.0" - "@emotion/weak-memoize" "^0.2.5" + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.0.2", "@emotion/serialize@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.3.tgz#99e2060c26c6292469fb30db41f4690e1c8fea63" - integrity sha512-2mSSvgLfyV3q+iVh3YWgNlUc2a9ZlDU7DjuP5MjK3AXRR0dYigCrP99aeFtaB2L/hjfEZdSThn5dsZ0ufqbvsA== +"@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== dependencies: - "@emotion/hash" "^0.8.0" - "@emotion/memoize" "^0.7.4" - "@emotion/unitless" "^0.7.5" - "@emotion/utils" "^1.0.0" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" csstype "^3.0.2" -"@emotion/sheet@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.1.0.tgz#56d99c41f0a1cda2726a05aa6a20afd4c63e58d2" - integrity sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g== +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== -"@emotion/unitless@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== -"@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.1.0.tgz#86b0b297f3f1a0f2bdb08eeac9a2f49afd40d0cf" - integrity sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ== +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== -"@emotion/weak-memoize@^0.2.5": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" - integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== -"@eslint/eslintrc@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e" - integrity sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA== +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + +"@es-joy/jsdoccomment@~0.39.4": + version "0.39.4" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz#6b8a62e9b3077027837728818d3c4389a898b392" + integrity sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg== + dependencies: + comment-parser "1.3.1" + esquery "^1.5.0" + jsdoc-type-pratt-parser "~4.0.0" + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.3.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.4.0" + espree "^9.5.2" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1179,44 +1298,139 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@floating-ui/core@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.0.1.tgz#00e64d74e911602c8533957af0cce5af6b2e93c8" - integrity sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA== +"@eslint/js@8.42.0": + version "8.42.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.42.0.tgz#484a1d638de2911e6f5a30c12f49c7e4a3270fb6" + integrity sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw== + +"@floating-ui/core@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.3.1.tgz#4d795b649cc3b1cbb760d191c80dcb4353c9a366" + integrity sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g== "@floating-ui/dom@^1.0.1": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.0.2.tgz#c5184c52c6f50abd11052d71204f4be2d9245237" - integrity sha512-5X9WSvZ8/fjy3gDu8yx9HAA4KG1lazUN2P4/VnaXLxTO9Dz53HI1oYoh1OlhqFNlHgGDiwFX5WhFCc2ljbW3yA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.4.5.tgz#336dfb9870c98b471ff5802002982e489b8bd1c5" + integrity sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw== dependencies: - "@floating-ui/core" "^1.0.1" + "@floating-ui/core" "^1.3.1" -"@formatjs/intl-unified-numberformat@^3.3.3": - version "3.3.6" - resolved "https://registry.yarnpkg.com/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-3.3.6.tgz#ab69818f7568894023cb31fdb5b5c7eed62c6537" - integrity sha512-VQYswh9Pxf4kN6FQvKprAQwSJrF93eJstCDPM1HIt3c3O6NqPFWNWhZ91PLTppOV11rLYsFK11ZxiGbnLNiPTg== +"@formatjs/cli@^6.1.1": + version "6.1.3" + resolved "https://registry.yarnpkg.com/@formatjs/cli/-/cli-6.1.3.tgz#b4b95259398e222ec6c06cf5f23f76d987f53e96" + integrity sha512-PdTXZTY8LqxwmvFqdifn89gjXnPUpGtGyFs0BnoeLuOuxZFSnBfIs5WQCVMaJnr1+0vNNlXyT0VAIAwjRpf6BA== + +"@formatjs/ecma402-abstract@1.17.0": + version "1.17.0" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz#2ce191a3bde4c65c6684e03fa247062a4a294b9e" + integrity sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ== dependencies: - "@formatjs/intl-utils" "^2.2.5" + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" -"@formatjs/intl-utils@^2.2.5": - version "2.2.5" - resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.5.tgz#eaafd94df3d102ee13e54e80f992a33868a6b1e8" - integrity sha512-p7gcmazKROteL4IECCp03Qrs790fZ8tbemUAjQu0+K0AaAlK49rI1SIFFq3LzDUAqXIshV95JJhRe/yXxkal5g== +"@formatjs/fast-memoize@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" + integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA== + dependencies: + tslib "^2.4.0" + +"@formatjs/icu-messageformat-parser@2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.6.0.tgz#b0d58ce8c8f472969c96b5cd0b3ad5522d3a02b7" + integrity sha512-yT6at0qc0DANw9qM/TU8RZaCtfDXtj4pZM/IC2WnVU80yAcliS3KVDiuUt4jSQAeFL9JS5bc2hARnFmjPdA6qw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/icu-skeleton-parser" "1.6.0" + tslib "^2.4.0" + +"@formatjs/icu-skeleton-parser@1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.0.tgz#0728be8b6b3656f1a4b8e6e5b0e02dffffc23c6c" + integrity sha512-eMmxNpoX/J1IPUjPGSZwo0Wh+7CEvdEMddP2Jxg1gQJXfGfht/FdW2D5XDFj3VMbOTUQlDIdZJY7uC6O6gjPoA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + tslib "^2.4.0" + +"@formatjs/intl-displaynames@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.5.0.tgz#32737088e7d943fb3e22140e64bb634e0ba05fcf" + integrity sha512-sg/nR8ILEdUl+2sWu6jc1nQ5s04yucGlH1RVfatW8TSJ5uG3Yy3vgigi8NNC/BuhcncUNPWqSpTCSI1hA+rhiw== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" + +"@formatjs/intl-listformat@7.4.0": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.4.0.tgz#fa8ac535d82fc716f052f2fd60eeaa7331362357" + integrity sha512-ifupb+balZUAF/Oh3QyGRqPRWGSKwWoMPR0cYZEG7r61SimD+m38oFQqVx/3Fp7LfQFF11m7IS+MlxOo2sKINA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" + +"@formatjs/intl-localematcher@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.0.tgz#63bbc37a7c3545a1bf1686072e51d9a3aed98d6b" + integrity sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw== + dependencies: + tslib "^2.4.0" + +"@formatjs/intl-pluralrules@^5.2.2": + version "5.2.4" + resolved "https://registry.yarnpkg.com/@formatjs/intl-pluralrules/-/intl-pluralrules-5.2.4.tgz#b417aa503186c2cbb4715f47114ed65211b4ada9" + integrity sha512-6meo376d8I4zikRFSUxATLnqzGwezmc57SmToP4z1/NQwTHXGe0yIG/ABPbO3QMx7IUkofH/ROP3A4DhtPTpnA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/intl-localematcher" "0.4.0" + tslib "^2.4.0" + +"@formatjs/intl@2.9.0": + version "2.9.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.9.0.tgz#e1335572af3ca8a53e136a78e866f1851a9718c2" + integrity sha512-Ym0trUoC/VO6wQu4YHa0H1VR2tEixFRmwZgADkDLm7nD+vv1Ob+/88mUAoT0pwvirFqYKgUKEwp1tFepqyqvVA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/intl-displaynames" "6.5.0" + "@formatjs/intl-listformat" "7.4.0" + intl-messageformat "10.5.0" + tslib "^2.4.0" + +"@formatjs/ts-transformer@3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@formatjs/ts-transformer/-/ts-transformer-3.13.3.tgz#249f5b5df70c51e651280732536d5504078297ff" + integrity sha512-W6+huH4dLYx8eZfZue6fcreNzLZHoPboreqJSkickYCKIOicI35zC0Txb4xCT6kau/DXAKTpNEln3V2NgX6Igg== + dependencies: + "@formatjs/icu-messageformat-parser" "2.6.0" + "@types/json-stable-stringify" "^1.0.32" + "@types/node" "14 || 16 || 17" + chalk "^4.0.0" + json-stable-stringify "^1.0.1" + tslib "^2.4.0" + typescript "^4.7 || 5" "@gamestdio/websocket@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@gamestdio/websocket/-/websocket-0.3.2.tgz#321ba0976ee30fd14e51dbf8faa85ce7b325f76a" integrity sha512-J3n5SKim+ZoLbe44hRGI/VYAwSMCeIJuBy+FfP6EZaujEpNchPRFcIsVQLWAwpU1bP2Ji63rC+rEUOd1vjUB6Q== -"@github/webauthn-json@^0.5.7": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@github/webauthn-json/-/webauthn-json-0.5.7.tgz#143bc67f6e0f75f8d188e565741507bb08c31214" - integrity sha512-SUYsttDxFSvWvvJssJpwzjmRCqYfdfqC9VCmAHQYfdKCVelyJteCHo9/lK1CB72mx/jrl6cFNY08aua4J2jIyg== +"@gar/promisify@^1.0.1": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== +"@github/webauthn-json@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@github/webauthn-json/-/webauthn-json-2.1.1.tgz#648e63fc28050917d2882cc2b27817a88cb420fc" + integrity sha512-XrftRn4z75SnaJOmZQbt7Mk+IIjqVHw+glDGOxuHwXkZBZh/MBoRS7MHjSZMDaLhT4RjN2VqiEU7EOYleuJWSQ== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -1232,6 +1446,18 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1244,113 +1470,113 @@ resolve-from "^5.0.0" "@istanbuljs/schema@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" - integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.1.tgz#cbc31d73f6329f693b3d34b365124de797704fff" - integrity sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ== +"@jest/console@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.5.0.tgz#593a6c5c0d3f75689835f1b3b4688c4f8544cb57" + integrity sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.4.1" - jest-util "^29.4.1" + jest-message-util "^29.5.0" + jest-util "^29.5.0" slash "^3.0.0" -"@jest/core@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.1.tgz#91371179b5959951e211dfaeea4277a01dcca14f" - integrity sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA== +"@jest/core@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.5.0.tgz#76674b96904484e8214614d17261cc491e5f1f03" + integrity sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ== dependencies: - "@jest/console" "^29.4.1" - "@jest/reporters" "^29.4.1" - "@jest/test-result" "^29.4.1" - "@jest/transform" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/console" "^29.5.0" + "@jest/reporters" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.4.0" - jest-config "^29.4.1" - jest-haste-map "^29.4.1" - jest-message-util "^29.4.1" - jest-regex-util "^29.2.0" - jest-resolve "^29.4.1" - jest-resolve-dependencies "^29.4.1" - jest-runner "^29.4.1" - jest-runtime "^29.4.1" - jest-snapshot "^29.4.1" - jest-util "^29.4.1" - jest-validate "^29.4.1" - jest-watcher "^29.4.1" + jest-changed-files "^29.5.0" + jest-config "^29.5.0" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-resolve-dependencies "^29.5.0" + jest-runner "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" + jest-watcher "^29.5.0" micromatch "^4.0.4" - pretty-format "^29.4.1" + pretty-format "^29.5.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.1.tgz#52d232a85cdc995b407a940c89c86568f5a88ffe" - integrity sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg== +"@jest/environment@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" + integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== dependencies: - "@jest/fake-timers" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-mock "^29.4.1" + jest-mock "^29.5.0" -"@jest/expect-utils@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.1.tgz#105b9f3e2c48101f09cae2f0a4d79a1b3a419cbb" - integrity sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ== +"@jest/expect-utils@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" + integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== dependencies: - jest-get-type "^29.2.0" + jest-get-type "^29.4.3" -"@jest/expect@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.1.tgz#3338fa20f547bb6e550c4be37d6f82711cc13c38" - integrity sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw== +"@jest/expect@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.5.0.tgz#80952f5316b23c483fbca4363ce822af79c38fba" + integrity sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g== dependencies: - expect "^29.4.1" - jest-snapshot "^29.4.1" + expect "^29.5.0" + jest-snapshot "^29.5.0" -"@jest/fake-timers@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.1.tgz#7b673131e8ea2a2045858f08241cace5d518b42b" - integrity sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw== +"@jest/fake-timers@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" + integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.4.1" - jest-mock "^29.4.1" - jest-util "^29.4.1" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-util "^29.5.0" -"@jest/globals@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.1.tgz#3cd78c5567ab0249f09fbd81bf9f37a7328f4713" - integrity sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA== +"@jest/globals@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.5.0.tgz#6166c0bfc374c58268677539d0c181f9c1833298" + integrity sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ== dependencies: - "@jest/environment" "^29.4.1" - "@jest/expect" "^29.4.1" - "@jest/types" "^29.4.1" - jest-mock "^29.4.1" + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/types" "^29.5.0" + jest-mock "^29.5.0" -"@jest/reporters@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.1.tgz#50d509c08575c75e3cd2176d72ec3786419d5e04" - integrity sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg== +"@jest/reporters@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.5.0.tgz#985dfd91290cd78ddae4914ba7921bcbabe8ac9b" + integrity sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.4.1" - "@jest/test-result" "^29.4.1" - "@jest/transform" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/console" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" @@ -1363,188 +1589,132 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.4.1" - jest-util "^29.4.1" - jest-worker "^29.4.1" + jest-message-util "^29.5.0" + jest-util "^29.5.0" + jest-worker "^29.5.0" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^29.4.0": - version "29.4.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.0.tgz#0d6ad358f295cc1deca0b643e6b4c86ebd539f17" - integrity sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ== +"@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== dependencies: "@sinclair/typebox" "^0.25.16" -"@jest/source-map@^29.2.0": - version "29.2.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" - integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== +"@jest/source-map@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== dependencies: "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.1.tgz#997f19695e13b34779ceb3c288a416bd26c3238d" - integrity sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ== +"@jest/test-result@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.5.0.tgz#7c856a6ca84f45cc36926a4e9c6b57f1973f1408" + integrity sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ== dependencies: - "@jest/console" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/console" "^29.5.0" + "@jest/types" "^29.5.0" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz#f7a006ec7058b194a10cf833c88282ef86d578fd" - integrity sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w== +"@jest/test-sequencer@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz#34d7d82d3081abd523dbddc038a3ddcb9f6d3cc4" + integrity sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ== dependencies: - "@jest/test-result" "^29.4.1" + "@jest/test-result" "^29.5.0" graceful-fs "^4.2.9" - jest-haste-map "^29.4.1" + jest-haste-map "^29.5.0" slash "^3.0.0" -"@jest/transform@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.1.tgz#e4f517841bb795c7dcdee1ba896275e2c2d26d4a" - integrity sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg== +"@jest/transform@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.5.0.tgz#cf9c872d0965f0cbd32f1458aa44a2b1988b00f9" + integrity sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@jridgewell/trace-mapping" "^0.3.15" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.4.1" - jest-regex-util "^29.2.0" - jest-util "^29.4.1" + jest-haste-map "^29.5.0" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" - write-file-atomic "^5.0.0" + write-file-atomic "^4.0.2" -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== +"@jest/types@^29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" + integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - -"@jest/types@^27.0.2": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@jest/types@^29.4.1": - version "29.4.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.1.tgz#f9f83d0916f50696661da72766132729dcb82ecb" - integrity sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA== - dependencies: - "@jest/schemas" "^29.4.0" + "@jest/schemas" "^29.4.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" "@types/yargs" "^17.0.8" chalk "^4.0.0" -<<<<<<< Updated upstream -======= -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - ->>>>>>> Stashed changes -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72" - integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg== +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.10" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186" - integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg== - -"@jridgewell/trace-mapping@^0.3.0", "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== +"@jridgewell/source-map@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" + integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" -"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": - version "5.1.1-v1" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" - integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== dependencies: - eslint-scope "5.1.1" + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" -"@node-redis/bloom@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@node-redis/bloom/-/bloom-1.0.1.tgz#144474a0b7dc4a4b91badea2cfa9538ce0a1854e" - integrity sha512-mXEBvEIgF4tUzdIN89LiYsbi6//EdpFA7L8M+DHCvePXg+bfHWi+ct5VI6nHUFQE5+ohm/9wmgihCH3HSkeKsw== - -"@node-redis/client@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@node-redis/client/-/client-1.0.5.tgz#ebac5e2bbf12214042a37621604973a954ede755" - integrity sha512-ESZ3bd1f+od62h4MaBLKum+klVJfA4wAeLHcVQBkoXa1l0viFesOWnakLQqKg+UyrlJhZmXJWtu0Y9v7iTMrig== - dependencies: - cluster-key-slot "1.1.0" - generic-pool "3.8.2" - redis-parser "3.0.0" - yallist "4.0.0" - -"@node-redis/graph@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@node-redis/graph/-/graph-1.0.0.tgz#baf8eaac4a400f86ea04d65ec3d65715fd7951ab" - integrity sha512-mRSo8jEGC0cf+Rm7q8mWMKKKqkn6EAnA9IA2S3JvUv/gaWW/73vil7GLNwion2ihTptAm05I9LkepzfIXUKX5g== - -"@node-redis/json@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@node-redis/json/-/json-1.0.2.tgz#8ad2d0f026698dc1a4238cc3d1eb099a3bee5ab8" - integrity sha512-qVRgn8WfG46QQ08CghSbY4VhHFgaTY71WjpwRBGEuqGPfWwfRcIf3OqSpR7Q/45X+v3xd8mvYjywqh0wqJ8T+g== - -"@node-redis/search@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@node-redis/search/-/search-1.0.5.tgz#96050007eb7c50a7e47080320b4f12aca8cf94c4" - integrity sha512-MCOL8iCKq4v+3HgEQv8zGlSkZyXSXtERgrAJ4TSryIG/eLFy84b57KmNNa/V7M1Q2Wd2hgn2nPCGNcQtk1R1OQ== - -"@node-redis/time-series@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@node-redis/time-series/-/time-series-1.0.2.tgz#5dd3638374edd85ebe0aa6b0e87addc88fb9df69" - integrity sha512-HGQ8YooJ8Mx7l28tD7XjtB3ImLEjlUxG1wC1PAjxu6hPJqjPshUZxAICzDqDjtIbhDTf48WXXUcx8TQJB1XTKA== +"@nicolo-ribaudo/semver-v6@^6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz#ea6d23ade78a325f7a52750aab1526b02b628c29" + integrity sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1567,32 +1737,146 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + "@npmcli/move-file@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464" - integrity sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw== + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== dependencies: mkdirp "^1.0.4" + rimraf "^3.0.2" -"@polka/url@^1.0.0-next.9": - version "1.0.0-next.11" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" - integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@pkgr/utils@^2.3.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.1.tgz#adf291d0357834c410ce80af16e711b56c7b1cd3" + integrity sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.2.12" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.5.0" + +"@polka/url@^1.0.0-next.20": + version "1.0.0-next.21" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" + integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== "@popperjs/core@^2.11.6": - version "2.11.6" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" - integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@rails/ujs@^6.1.7": - version "6.1.7" - resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.1.7.tgz#b09dc5b2105dd267e8374c47e4490240451dc7f6" - integrity sha512-0e7WQ4LE/+LEfW2zfAw9ppsB6A8RmxbdAUPAF++UT80epY+7emuQDkKXmaK0a9lp6An50RvzezI0cIQjp1A58w== +"@rails/ujs@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-7.0.6.tgz#fd8937c92335f3da9495e07292511ad5f7547a6a" + integrity sha512-s5v3AC6AywOIFMz0RIMW83Xc8FPIvKMkP3ZHFlM4ISNkhdUwP9HdhVtxxo6z3dIhe9vI0Our2A8kN/QpUV02Qg== + +"@rails/webpacker@5.4.4": + version "5.4.4" + resolved "https://registry.yarnpkg.com/@rails/webpacker/-/webpacker-5.4.4.tgz#971a41b987c096c908ce4088accd57c1a9a7e2f7" + integrity sha512-hp9myb2MChYFPfE5Fd/3gF4q2m4wpxC+WWCkxcg6My3HYCptWuqMVXRwrBZ5EJHYiL/WRyMLvVNWwlFV47xhUw== + dependencies: + "@babel/core" "^7.15.0" + "@babel/plugin-proposal-class-properties" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.14.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.14.7" + "@babel/plugin-transform-regenerator" "^7.14.5" + "@babel/plugin-transform-runtime" "^7.15.0" + "@babel/preset-env" "^7.15.0" + "@babel/runtime" "^7.15.3" + babel-loader "^8.2.2" + babel-plugin-dynamic-import-node "^2.3.3" + babel-plugin-macros "^2.8.0" + case-sensitive-paths-webpack-plugin "^2.4.0" + compression-webpack-plugin "^4.0.1" + core-js "^3.16.2" + css-loader "^3.6.0" + file-loader "^6.2.0" + flatted "^3.2.2" + glob "^7.1.7" + js-yaml "^3.14.1" + mini-css-extract-plugin "^0.9.0" + optimize-css-assets-webpack-plugin "^5.0.8" + path-complete-extname "^1.0.0" + pnp-webpack-plugin "^1.7.0" + postcss-flexbugs-fixes "^4.2.1" + postcss-import "^12.0.1" + postcss-loader "^3.0.0" + postcss-preset-env "^6.7.0" + postcss-safe-parser "^4.0.2" + regenerator-runtime "^0.13.9" + sass "^1.38.0" + sass-loader "10.1.1" + style-loader "^1.3.0" + terser-webpack-plugin "^4.2.3" + webpack "^4.46.0" + webpack-assets-manifest "^3.1.1" + webpack-cli "^3.3.12" + webpack-sources "^1.4.3" + +"@redis/bloom@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.2.0.tgz#d3fd6d3c0af3ef92f26767b56414a370c7b63b71" + integrity sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg== + +"@redis/client@1.5.8": + version "1.5.8" + resolved "https://registry.yarnpkg.com/@redis/client/-/client-1.5.8.tgz#a375ba7861825bd0d2dc512282b8bff7b98dbcb1" + integrity sha512-xzElwHIO6rBAqzPeVnCzgvrnBEcFL1P0w8P65VNLRkdVW8rOE58f52hdj0BDgmsdOm4f1EoXPZtH4Fh7M/qUpw== + dependencies: + cluster-key-slot "1.1.2" + generic-pool "3.9.0" + yallist "4.0.0" + +"@redis/graph@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redis/graph/-/graph-1.1.0.tgz#cc2b82e5141a29ada2cce7d267a6b74baa6dd519" + integrity sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg== + +"@redis/json@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@redis/json/-/json-1.0.4.tgz#f372b5f93324e6ffb7f16aadcbcb4e5c3d39bda1" + integrity sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw== + +"@redis/search@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@redis/search/-/search-1.1.3.tgz#b5a6837522ce9028267fe6f50762a8bcfd2e998b" + integrity sha512-4Dg1JjvCevdiCBTZqjhKkGoC5/BcB7k9j99kdMnaXFXg8x4eyOIVg9487CMv7/BUVkFLZCaIh8ead9mU15DNng== + +"@redis/time-series@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.4.tgz#af85eb080f6934580e4d3b58046026b6c2b18717" + integrity sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng== + +"@reduxjs/toolkit@^1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.9.5.tgz#d3987849c24189ca483baa7aa59386c8e52077c4" + integrity sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ== + dependencies: + immer "^9.0.21" + redux "^4.2.1" + redux-thunk "^2.4.2" + reselect "^4.1.8" "@restart/hooks@^0.4.7": - version "0.4.7" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.7.tgz#d79ca6472c01ce04389fc73d4a79af1b5e33cd39" - integrity sha512-ZbjlEHcG+FQtpDPHd7i4FzNNvJf2enAwZfJbpM8CW7BhmOAbsHpZe3tsHwfQUrBuyrxWqPYp2x5UMnilWcY22A== + version "0.4.9" + resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.9.tgz#ad858fb39d99e252cccce19416adc18fc3f18fcb" + integrity sha512-3BekqcwB6Umeya+16XPooARn4qEPW6vNvwYnlofIYe6h9qG1/VeD7UvShCWx11eFz5ELYmwIEshz+MkPX3wjcQ== dependencies: dequal "^2.0.2" @@ -1634,23 +1918,23 @@ picomatch "^2.2.2" "@sinclair/typebox@^0.25.16": - version "0.25.21" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272" - integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g== + version "0.25.24" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" + integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== -"@sinonjs/commons@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" - integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== dependencies: type-detect "4.0.8" "@sinonjs/fake-timers@^10.0.2": - version "10.0.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" - integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== + version "10.2.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.2.0.tgz#b3e322a34c5f26e3184e7f6115695f299c1b1194" + integrity sha512-OPwQlEdg40HAj5KNF8WW6q2KG4Z+cBCZb3m4ninfTZKaBmbIJodviQsDBoYMPHkOyJJMHnOJo5j2+LKDOhOACg== dependencies: - "@sinonjs/commons" "^2.0.0" + "@sinonjs/commons" "^3.0.0" "@surma/rollup-plugin-off-main-thread@^2.2.3": version "2.2.3" @@ -1662,18 +1946,18 @@ magic-string "^0.25.0" string.prototype.matchall "^4.0.6" -"@testing-library/dom@^8.0.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.1.0.tgz#f8358b1883844ea569ba76b7e94582168df5370d" - integrity sha512-kmW9alndr19qd6DABzQ978zKQ+J65gU2Rzkl8hriIetPnwpesRaK4//jEQyYh8fEALmGhomD/LBQqt+o+DL95Q== +"@testing-library/dom@^9.0.0": + version "9.3.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.3.1.tgz#8094f560e9389fb973fe957af41bf766937a9ee9" + integrity sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w== dependencies: "@babel/code-frame" "^7.10.4" "@babel/runtime" "^7.12.5" - "@types/aria-query" "^4.2.0" - aria-query "^4.2.2" + "@types/aria-query" "^5.0.1" + aria-query "5.1.3" chalk "^4.1.0" - dom-accessibility-api "^0.5.6" - lz-string "^1.4.4" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" pretty-format "^27.0.2" "@testing-library/jest-dom@^5.16.5": @@ -1691,90 +1975,156 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react@^12.1.5": - version "12.1.5" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.5.tgz#bb248f72f02a5ac9d949dea07279095fa577963b" - integrity sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg== +"@testing-library/react@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.0.0.tgz#59030392a6792450b9ab8e67aea5f3cc18d6347c" + integrity sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg== dependencies: "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^8.0.0" - "@types/react-dom" "<18.0.0" + "@testing-library/dom" "^9.0.0" + "@types/react-dom" "^18.0.0" "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/aria-query@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" - integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== -"@types/babel__core@^7.1.12", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.3": - version "7.1.18" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" - integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== +"@types/aria-query@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.1.tgz#3286741fb8f1e1580ac28784add4c7a1d49bdfbc" + integrity sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q== + +"@types/babel__core@*", "@types/babel__core@^7.1.12", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7", "@types/babel__core@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.1" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" - integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== dependencies: "@babel/types" "^7.0.0" +"@types/babel__helper-plugin-utils@^7.10.0": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@types/babel__helper-plugin-utils/-/babel__helper-plugin-utils-7.10.0.tgz#dcd2416f9c189d5837ab2a276368cf67134efe78" + integrity sha512-60YtHzhQ9HAkToHVV+TB4VLzBn9lrfgrsOjiJMtbv/c1jPdekBxaByd6DMsGBzROXWoIL6U3lEFvvbu69RkUoA== + dependencies: + "@types/babel__core" "*" + "@types/babel__template@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" - integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.13.tgz#1874914be974a492e1b4cb00585cabb274e8ba18" - integrity sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ== +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6", "@types/babel__traverse@^7.1.7": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/emoji-mart@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@types/emoji-mart/-/emoji-mart-3.0.9.tgz#2f7ef5d9ec194f28029c46c81a5fc1e5b0efa73c" + integrity sha512-qdBo/2Y8MXaJ/2spKjDZocuq79GpnOhkwMHnK2GnVFa8WYFgfA+ei6sil3aeWQPCreOKIx9ogPpR5+7MaOqYAA== + dependencies: + "@types/react" "*" + +"@types/escape-html@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/escape-html/-/escape-html-1.0.2.tgz#072b7b13784fb3cee9c2450c22f36405983f5e3c" + integrity sha512-gaBLT8pdcexFztLSPRtriHeXY/Kn4907uOCZ4Q3lncFBkheAWOuNt53ypsF8szgxbEJ513UeBzcf4utN0EzEwA== + +"@types/eslint@7 || 8": + version "8.40.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.40.2.tgz#2833bc112d809677864a4b0e7d1de4f04d7dac2d" + integrity sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/events@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/express-serve-static-core@^4.17.33": + version "4.17.35" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz#c95dd4424f0d32e525d23812aa8ab8e4d3906c4f" + integrity sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@^4.17.17": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" "@types/glob@^7.1.1": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" - integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: - "@types/events" "*" "@types/minimatch" "*" "@types/node" "*" "@types/graceful-fs@^4.1.3": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" -"@types/hoist-non-react-statics@^3.3.0": +"@types/history@^4.7.11": + version "4.7.11" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" + integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== + +"@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -1782,10 +2132,22 @@ "@types/react" "*" hoist-non-react-statics "^3.3.0" +"@types/http-link-header@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/http-link-header/-/http-link-header-1.0.3.tgz#899adf1d8d2036074514f3dbd148fb901ceff920" + integrity sha512-y8HkoD/vyid+5MrJ3aas0FvU3/BVBGcyG9kgxL0Zn4JwstA8CglFPnrR0RuzOjRCXwqzL5uxWC2IO7Ub0rMU2A== + dependencies: + "@types/node" "*" + +"@types/intl@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/intl/-/intl-1.2.0.tgz#1245511f13064402087979f498764611a3c758fc" + integrity sha512-BP+KwmOvD9AR5aoxnbyyPr3fAtpjEI/bVImHsotmpuC43+z0NAmjJ9cQbX7vPCq8XcvCeAVc8E3KSQPYNaPsUQ== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" - integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== "@types/istanbul-lib-report@*": version "3.0.0" @@ -1794,129 +2156,272 @@ dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" - integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== - dependencies: - "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" - "@types/istanbul-reports@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" - integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*": - version "26.0.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.3.tgz#79534e0e94857171c0edc596db0ebe7cb7863251" - integrity sha512-v89ga1clpVL/Y1+YI0eIu1VMW+KU7Xl8PhylVtDKVWaSUHBHYPLXMQGBdrpHewaKoTvlXkksbYqPgz8b4cmRZg== +"@types/jest@*", "@types/jest@^29.5.2": + version "29.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.2.tgz#86b4afc86e3a8f3005b297ed8a72494f89e6395b" + integrity sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg== dependencies: - jest-diff "^25.2.1" - pretty-format "^25.2.1" + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/js-yaml@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.5.tgz#738dd390a6ecc5442f35e7f03fa1431353f7e138" + integrity sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA== "@types/jsdom@^20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.0.tgz#4414fb629465167f8b7b3804b9e067bdd99f1791" - integrity sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA== + version "20.0.1" + resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" + integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ== dependencies: "@types/node" "*" "@types/tough-cookie" "*" parse5 "^7.0.0" -"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" - integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/json-schema@*", "@types/json-schema@^7.0.11", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/json-stable-stringify@^1.0.32": + version "1.0.34" + resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.34.tgz#c0fb25e4d957e0ee2e497c1f553d7f8bb668fd75" + integrity sha512-s2cfwagOQAS8o06TcwKfr9Wx11dNGbH2E9vJz1cqV+a/LOyhWNLUNd6JSRYNzvB4d29UuJX2M0Dj9vE1T8fRXw== "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/lodash@^4.14.195": + version "4.14.195" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632" + integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== "@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== -"@types/minimist@^1.2.0": +"@types/minimist@^1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== "@types/node@*": - version "14.11.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.1.tgz#56af902ad157e763f9ba63d671c39cda3193c835" - integrity sha512-oTQgnd0hblfLsJ6BvJzzSL+Inogp3lq9fGgqRkMB/ziKMgEUaFl801OncOzUmalfzt14N0oPHMK47ipl+wbTIw== + version "20.3.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe" + integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg== + +"@types/node@14 || 16 || 17": + version "17.0.45" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" + integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== +"@types/npmlog@^4.1.4": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.4.tgz#30eb872153c7ead3e8688c476054ddca004115f6" + integrity sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ== + +"@types/object-assign@^4.0.30": + version "4.0.30" + resolved "https://registry.yarnpkg.com/@types/object-assign/-/object-assign-4.0.30.tgz#8949371d5a99f4381ee0f1df0a9b7a187e07e652" + integrity sha512-HhE8gFfLj321pa6OE59QmOdL5NgIOhkdYn7MWnZTOcHOms8XFzNgr9+A0/GbN0XEX9wTM58yg4YXKhGr69QIUw== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== -"@types/prettier@^2.1.5": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" - integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== +"@types/pg@^8.6.6": + version "8.10.2" + resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.10.2.tgz#7814d1ca02c8071f4d0864c1b17c589b061dba43" + integrity sha512-MKFs9P6nJ+LAeHLU3V0cODEOgyThJ3OAnmOlsZsxux6sfQs3HRXR5bBn7xG5DjckEFhTAxsXi7k7cd0pCMxpJw== + dependencies: + "@types/node" "*" + pg-protocol "*" + pg-types "^4.0.1" -"@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== +"@types/picomatch@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" + integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== + +"@types/prettier@^2.1.5": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + +"@types/prop-types@*", "@types/prop-types@^15.7.5": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/punycode@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/punycode/-/punycode-2.1.0.tgz#89e4f3d09b3f92e87a80505af19be7e0c31d4e83" + integrity sha512-PG5aLpW6PJOeV2fHRslP4IOMWn+G+Uq8CfnyJ+PDS8ndCbU+soO+fB3NKCKo0p/Jh2Y4aPaiQZsrOXFdzpcA6g== "@types/q@^1.5.1": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" - integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== + version "1.5.5" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" + integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== -"@types/react-dom@<18.0.0": - version "17.0.15" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.15.tgz#f2c8efde11521a4b7991e076cb9c70ba3bb0d156" - integrity sha512-Tr9VU9DvNoHDWlmecmcsE5ZZiUkYx+nKBzum4Oxe1K0yJVyBlfbq7H3eXjxXqJczBKqPGq3EgfTru4MgKb9+Yw== - dependencies: - "@types/react" "^17" +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== -"@types/react-redux@^7.1.20": - version "7.1.20" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.20.tgz#42f0e61ababb621e12c66c96dda94c58423bd7df" - integrity sha512-q42es4c8iIeTgcnB+yJgRTTzftv3eYYvCZOh1Ckn2eX/3o5TdsQYKUWpLoLuGlcY/p+VAhV9IOEZJcWk/vfkXw== +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/react-dom@^18.0.0", "@types/react-dom@^18.2.4": + version "18.2.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.5.tgz#5c5f13548bda23cd98f50ca4a59107238bfe18f3" + integrity sha512-sRQsOS/sCLnpQhR4DSKGTtWFE3FZjpQa86KPVbhUqdYMRZ9FEFcfAytKhR/vUG2rH1oFbOOej6cuD7MFSobDRQ== + dependencies: + "@types/react" "*" + +"@types/react-helmet@^6.1.6": + version "6.1.6" + resolved "https://registry.yarnpkg.com/@types/react-helmet/-/react-helmet-6.1.6.tgz#7d1afd8cbf099616894e8240e9ef70e3c6d7506d" + integrity sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A== + dependencies: + "@types/react" "*" + +"@types/react-immutable-proptypes@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#c045fb48ba28c34c9d759abc3a51a04b5321b77a" + integrity sha512-NRH4W4mgymzyM2gnAG+i2VoOdWIBOQlJlSyAgnFiBTdJ0l8IVeyCtdWP8g6Lra59sUBj2XUO/+DkfmrRAxj6UA== + dependencies: + "@types/prop-types" "*" + immutable "^3.8.2" + +"@types/react-motion@^0.0.34": + version "0.0.34" + resolved "https://registry.yarnpkg.com/@types/react-motion/-/react-motion-0.0.34.tgz#789ff2063e2f7fbb6085d291135c442e8b35291a" + integrity sha512-/rFI22Vg4Xzb47hXtS06WkzUGRu+Vb3yDleuxiqzGj0JbXYXQUCgwSa2ZU12K7ubKi4C8xsdIN3xt4Z4fjSdPw== + dependencies: + "@types/react" "*" + +"@types/react-overlays@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/react-overlays/-/react-overlays-3.1.0.tgz#2efefa5407562c5aeb34a03336d070a0f74c6274" + integrity sha512-NzZZHFLj7M7+I+p5rDdVHtm6AeVYQPShVxALiLYhR9leJSX8XujPsYuY+vh7/mzFjv6XR7PxHBAdlFGNaN6QDQ== + dependencies: + react-overlays "*" + +"@types/react-router-dom@^5.3.3": + version "5.3.3" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "5.1.20" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" + integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + +"@types/react-select@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-5.0.1.tgz#04fc85edd34a72675a0ab56ad4c30428aab0e444" + integrity sha512-h5Im0AP0dr4AVeHtrcvQrLV+gmPa7SA0AGdxl2jOhtwiE6KgXBFSogWw8az32/nusE6AQHlCOHQWjP1S/+oMWA== + dependencies: + react-select "*" + +"@types/react-sparklines@^1.7.2": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@types/react-sparklines/-/react-sparklines-1.7.2.tgz#c14e80623abd3669a10f18d13f6fb9fbdc322f70" + integrity sha512-N1GwO7Ri5C5fE8+CxhiDntuSw1qYdGytBuedKrCxWpaojXm4WnfygbdBdc5sXGX7feMxDXBy9MNhxoUTwrMl4A== + dependencies: + "@types/react" "*" + +"@types/react-swipeable-views@^0.13.1": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@types/react-swipeable-views/-/react-swipeable-views-0.13.2.tgz#c37cc8978ae60ab0dff209ef3eb1f77185aef330" + integrity sha512-FiszBm9M0JicAgzO/IwDqpfHQRUEjPZA88UexYsVD6qHJBf5LrbGjR5Mw4+yZbf8ZxJneNqOsZbe4WGjOYG7iQ== + dependencies: + "@types/react" "*" + +"@types/react-test-renderer@^18.0.0": + version "18.0.0" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz#7b7f69ca98821ea5501b21ba24ea7b6139da2243" + integrity sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ== + dependencies: + "@types/react" "*" + +"@types/react-textarea-autosize@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@types/react-textarea-autosize/-/react-textarea-autosize-8.0.0.tgz#f68f388552aaa608328b3e352d9a23ad7e0f72e4" + integrity sha512-KVqk+/+RMQB3ZDpk7ZTpYHauU3Ue+Y0f09POvGaEpaGb+izzbpoM47tkDGlbF37iT7JYZ8QFwLzqiOPYbQaztA== + dependencies: + react-textarea-autosize "*" + +"@types/react-toggle@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/react-toggle/-/react-toggle-4.0.3.tgz#8db98ac8d2c5e8c03c2d3a42027555c1cd2289da" + integrity sha512-57QdMWeeQdRjM2/p+udgYerxUbSkmeUIW18kwUttcci6GHkgxoqCsDZfRtsCsAHcvvM5VBQdtDUEgLWo2e87mA== dependencies: - "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" - hoist-non-react-statics "^3.3.0" - redux "^4.0.0" "@types/react-transition-group@^4.4.0": - version "4.4.3" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.3.tgz#b0994da0a7023d67dbb4a8910a62112bc00d5688" - integrity sha512-fUx5muOWSYP8Bw2BUQ9M9RK9+W1XBK/7FLJ8PTQpnpTEkn0ccyMffyEQvan4C3h53gHdx7KE5Qrxi/LnUGQtdg== + version "4.4.6" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.6.tgz#18187bcda5281f8e10dfc48f0943e2fdf4f75e2e" + integrity sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^17": - version "17.0.44" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.44.tgz#c3714bd34dd551ab20b8015d9d0dbec812a51ec7" - integrity sha512-Ye0nlw09GeMp2Suh8qoOv0odfgCoowfM/9MG6WeRD60Gq9wS90bdkdRtYbRkNhXOpG4H+YXGvj4wOWhAC0LJ1g== +"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@>=16.9.11", "@types/react@^18.0.26", "@types/react@^18.2.7": + version "18.2.12" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.12.tgz#95d584338610b78bb9ba0415e3180fb03debdf97" + integrity sha512-ndmBMLCgn38v3SntMeoJaIrO6tGHYKMEBohCUmw8HoLLQdRMOIGXfeYaBTLe2lsFaSB3MOK1VXscYFnmLtTSmw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" -"@types/react@>=16.9.11": - version "18.0.26" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.26.tgz#8ad59fc01fef8eaf5c74f4ea392621749f0b7917" - integrity sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug== +"@types/redux-immutable@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/redux-immutable/-/redux-immutable-4.0.3.tgz#db92a281aa9a55a7b63bc1f20a233790305a1f06" + integrity sha512-wXUApt9ib9MGUqoHUMbQmQhqCkvykMHBW3z/P7DISMigFGpGRQ0kkbv7we0XNiv5sYEtEiZzNCEDm+W6ei04DA== dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" + immutable "^4.0.0-rc.1" + redux "^4.0.0" + +"@types/requestidlecallback@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@types/requestidlecallback/-/requestidlecallback-0.3.5.tgz#132529751a4717fe7dc55fef5e930336f229543c" + integrity sha512-Uh49VrVTPfU0y/qIvXXYuRmd/sKLfVgQWZU1t8FWH22AIJyQbCei1aSmXdMDAijwGUFhBDpJmksiHEDsfiE/cg== "@types/resolve@1.17.1": version "1.17.1" @@ -1926,24 +2431,50 @@ "@types/node" "*" "@types/scheduler@*": - version "0.16.1" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" - integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== -"@types/schema-utils@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/schema-utils/-/schema-utils-1.0.0.tgz#295d36f01e2cb8bc3207ca1d9a68e210db6b40cb" - integrity sha512-YesPanU1+WCigC/Aj1Mga8UCOjHIfMNHZ3zzDsUY7lI8GlKnh/Kv2QwJOQ+jNQ36Ru7IfzSedlG14hppYaN13A== +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.1" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" + integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/tapable@^1": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" + integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== "@types/testing-library__jest-dom@^5.9.1": - version "5.9.1" - resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.1.tgz#aba5ee062b7880f69c212ef769389f30752806e5" - integrity sha512-yYn5EKHO3MPEMSOrcAb1dLWY+68CG29LiXKsWmmpVHqoP5+ZRiAVLyUHvPNrO2dABDdUGZvavMsaGpWNjM6N2g== + version "5.14.6" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.6.tgz#4887f6e1af11215428ab02777873bcede98a53b0" + integrity sha512-FkHXCb+ikSoUP4Y4rOslzTdX5sqYwMxfefKh1GmZ8ce1GOkEHntSp6b5cGadmNfp5e4BMEWOMx+WSKd5/MqlDA== dependencies: "@types/jest" "*" @@ -1953,40 +2484,178 @@ integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== "@types/trusted-types@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" - integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== + +"@types/uglify-js@*": + version "3.17.1" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.1.tgz#e0ffcef756476410e5bce2cb01384ed878a195b5" + integrity sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g== + dependencies: + source-map "^0.6.1" + +"@types/use-sync-external-store@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" + integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== + +"@types/uuid@^9.0.0": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.2.tgz#ede1d1b1e451548d44919dc226253e32a6952c4b" + integrity sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ== "@types/warning@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" integrity sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA== +"@types/webpack-sources@*": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b" + integrity sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + +"@types/webpack@^4.41.33": + version "4.41.33" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.33.tgz#16164845a5be6a306bcbe554a8e67f9cac215ffc" + integrity sha512-PPajH64Ft2vWevkerISMtnZ8rTs4YmRbs+23c402J0INmxDKCrhZNvwZYtzx96gY2wAtXdrK1BS2fiC8MlLr3g== + dependencies: + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + anymatch "^3.0.0" + source-map "^0.6.0" + "@types/yargs-parser@*": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" - integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== -"@types/yargs@^15.0.0": - version "15.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.5.tgz#947e9a6561483bdee9adffc983e91a6902af8b79" - integrity sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w== +"@types/yargs@^17.0.24", "@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: "@types/yargs-parser" "*" -"@types/yargs@^16.0.0": - version "16.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.3.tgz#4b6d35bb8e680510a7dc2308518a80ee1ef27e01" - integrity sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ== +"@typescript-eslint/eslint-plugin@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz#19ff4f1cab8d6f8c2c1825150f7a840bc5d9bdc4" + integrity sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A== dependencies: - "@types/yargs-parser" "*" + "@eslint-community/regexpp" "^4.5.0" + "@typescript-eslint/scope-manager" "6.0.0" + "@typescript-eslint/type-utils" "6.0.0" + "@typescript-eslint/utils" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" + debug "^4.3.4" + grapheme-splitter "^1.0.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + natural-compare-lite "^1.4.0" + semver "^7.5.0" + ts-api-utils "^1.0.1" -"@types/yargs@^17.0.8": - version "17.0.10" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a" - integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== +"@typescript-eslint/parser@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.0.0.tgz#46b2600fd1f67e62fc00a28093a75f41bf7effc4" + integrity sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg== dependencies: - "@types/yargs-parser" "*" + "@typescript-eslint/scope-manager" "6.0.0" + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/typescript-estree" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz#8ede47a37cb2b7ed82d329000437abd1113b5e11" + integrity sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg== + dependencies: + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" + +"@typescript-eslint/type-utils@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz#0478d8a94f05e51da2877cc0500f1b3c27ac7e18" + integrity sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ== + dependencies: + "@typescript-eslint/typescript-estree" "6.0.0" + "@typescript-eslint/utils" "6.0.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@5.59.0": + version "5.59.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.0.tgz#3fcdac7dbf923ec5251545acdd9f1d42d7c4fe32" + integrity sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA== + +"@typescript-eslint/types@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.0.0.tgz#19795f515f8decbec749c448b0b5fc76d82445a1" + integrity sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg== + +"@typescript-eslint/typescript-estree@5.59.0": + version "5.59.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.0.tgz#8869156ee1dcfc5a95be3ed0e2809969ea28e965" + integrity sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg== + dependencies: + "@typescript-eslint/types" "5.59.0" + "@typescript-eslint/visitor-keys" "5.59.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/typescript-estree@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz#1e09aab7320e404fb9f83027ea568ac24e372f81" + integrity sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ== + dependencies: + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.0" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.0.0.tgz#27a16d0d8f2719274a39417b9782f7daa3802db0" + integrity sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ== + dependencies: + "@eslint-community/eslint-utils" "^4.3.0" + "@types/json-schema" "^7.0.11" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "6.0.0" + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/typescript-estree" "6.0.0" + eslint-scope "^5.1.1" + semver "^7.5.0" + +"@typescript-eslint/visitor-keys@5.59.0": + version "5.59.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.0.tgz#a59913f2bf0baeb61b5cfcb6135d3926c3854365" + integrity sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA== + dependencies: + "@typescript-eslint/types" "5.59.0" + eslint-visitor-keys "^3.3.0" + +"@typescript-eslint/visitor-keys@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz#0b49026049fbd096d2c00c5e784866bc69532a31" + integrity sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA== + dependencies: + "@typescript-eslint/types" "6.0.0" + eslint-visitor-keys "^3.4.1" "@webassemblyjs/ast@1.9.0": version "1.9.0" @@ -2187,16 +2856,11 @@ acorn-walk@^8.0.0, acorn-walk@^8.0.2: integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== acorn@^6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" - integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^8.0.4, acorn@^8.1.0, acorn@^8.5.0, acorn@^8.8.1: - version "8.8.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== - -acorn@^8.8.0: +acorn@^8.0.4, acorn@^8.1.0, acorn@^8.8.0, acorn@^8.8.1, acorn@^8.8.2: version "8.8.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== @@ -2237,9 +2901,9 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5: uri-js "^4.2.2" ajv@^8.0.1, ajv@^8.6.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -2249,19 +2913,19 @@ ajv@^8.0.1, ajv@^8.6.0: alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + integrity sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ== ansi-colors@^3.0.0: version "3.2.4" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== -ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - type-fest "^0.11.0" + type-fest "^0.21.3" ansi-html-community@0.0.8: version "0.0.8" @@ -2271,18 +2935,23 @@ ansi-html-community@0.0.8: ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== -ansi-regex@^5.0.0, ansi-regex@^5.0.1: +ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -2291,11 +2960,10 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: - "@types/color-name" "^1.1.1" color-convert "^2.0.1" ansi-styles@^5.0.0: @@ -2303,6 +2971,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.0.0, ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -2311,19 +2984,29 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3, anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" -"aproba@^1.0.3 || ^2.0.0", aproba@^1.1.1: +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +are-docs-informative@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" + integrity sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig== + are-we-there-yet@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-4.0.0.tgz#3ff397dc14f08b52dd8b2a64d3cee154ab8760d2" @@ -2344,25 +3027,24 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - -aria-query@^5.0.0, aria-query@^5.1.3: +aria-query@5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== dependencies: deep-equal "^2.0.5" +aria-query@^5.0.0, aria-query@^5.1.3: + version "5.2.1" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.2.1.tgz#bc285d9d654d1df121bcd0c134880d415ca67c15" + integrity sha512-7uFg4b+lETFgdaJyETnILsXgnnzVnkHcgRbwbPwevm5x/LmUlt3MjczMRe1zg824iBgXZNRPTBftNYyRSKLp2g== + dependencies: + dequal "^2.0.3" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== arr-flatten@^1.1.0: version "1.1.0" @@ -2372,12 +3054,20 @@ arr-flatten@^1.1.0: arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== array-flatten@^2.1.0: version "2.1.2" @@ -2398,7 +3088,7 @@ array-includes@^3.1.5, array-includes@^3.1.6: array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== dependencies: array-uniq "^1.0.1" @@ -2410,12 +3100,12 @@ array-union@^2.1.0: array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== array.prototype.flat@^1.3.1: version "1.3.1" @@ -2437,6 +3127,17 @@ array.prototype.flatmap@^1.3.1: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" +array.prototype.reduce@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" + integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + array.prototype.tosorted@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" @@ -2448,6 +3149,18 @@ array.prototype.tosorted@^1.1.1: es-shim-unscopables "^1.0.0" get-intrinsic "^1.1.3" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -2479,12 +3192,12 @@ assert@^1.1.1: assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== astral-regex@^2.0.0: version "2.0.0" @@ -2492,16 +3205,23 @@ astral-regex@^2.0.0: integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" + integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== -async@^2.6.2: +async-mutex@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.0.tgz#ae8048cd4d04ace94347507504b3cf15e631c25f" + integrity sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA== + dependencies: + tslib "^2.4.0" + +async@^2.6.4: version "2.6.4" resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== @@ -2509,14 +3229,14 @@ async@^2.6.2: lodash "^4.17.14" async@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" - integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== at-least-node@^1.0.0: version "1.0.0" @@ -2528,7 +3248,24 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^9.8.8: +atrament@0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/atrament/-/atrament-0.2.4.tgz#6f78196edfcd194e568b7c0b9c88201ec371ac66" + integrity sha512-hSA9VwW6COMwvRhSEO4uZweZ91YGOdHqwvslNyrJZG+8mzc4qx/qMsDZBuAeXFeWZO/QKtRjIXguOUy1aNMl3A== + +autoprefixer@^10.4.14: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +autoprefixer@^9.6.1: version "9.8.8" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== @@ -2547,40 +3284,40 @@ available-typed-arrays@^1.0.5: integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== axe-core@^4.6.2: - version "4.6.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.3.tgz#fc0db6fdb65cc7a80ccf85286d91d64ababa3ece" - integrity sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg== + version "4.7.2" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.2.tgz#040a7342b20765cb18bb50b628394c21bccc17a0" + integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== -axios@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.2.tgz#7ac517f0fa3ec46e0e636223fd973713a09c72b3" - integrity sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw== +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" proxy-from-env "^1.1.0" axobject-query@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" - integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== + version "3.2.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" + integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== dependencies: - deep-equal "^2.0.5" + dequal "^2.0.3" -babel-jest@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.1.tgz#01fa167e27470b35c2d4a1b841d9586b1764da19" - integrity sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg== +babel-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.5.0.tgz#3fe3ddb109198e78b1c88f9ebdecd5e4fc2f50a5" + integrity sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q== dependencies: - "@jest/transform" "^29.4.1" + "@jest/transform" "^29.5.0" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.4.0" + babel-preset-jest "^29.5.0" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" -babel-loader@^8.3.0: +babel-loader@^8.2.2, babel-loader@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== @@ -2590,6 +3327,30 @@ babel-loader@^8.3.0: make-dir "^3.1.0" schema-utils "^2.6.5" +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-formatjs@^10.5.1: + version "10.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-formatjs/-/babel-plugin-formatjs-10.5.3.tgz#718e47f4f3aad663ad4f901274aedd7be0a86380" + integrity sha512-PBeryWyN2HY2VUGNFPQS6+DPNQ/I9zDZ97y38i1+LzIpIyTHBePECq/ehEABE73PvvF2irFiN7TCYBrQQw5+lA== + dependencies: + "@babel/core" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "7" + "@babel/traverse" "7" + "@babel/types" "^7.12.11" + "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/ts-transformer" "3.13.3" + "@types/babel__core" "^7.1.7" + "@types/babel__helper-plugin-utils" "^7.10.0" + "@types/babel__traverse" "^7.1.7" + tslib "^2.4.0" + babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -2601,10 +3362,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^29.4.0: - version "29.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz#3fd3dfcedf645932df6d0c9fc3d9a704dd860248" - integrity sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg== +babel-plugin-jest-hoist@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" + integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -2622,7 +3383,7 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" -babel-plugin-macros@^2.6.1: +babel-plugin-macros@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== @@ -2631,7 +3392,7 @@ babel-plugin-macros@^2.6.1: cosmiconfig "^6.0.0" resolve "^1.12.0" -babel-plugin-macros@^3.0.1: +babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== @@ -2640,29 +3401,29 @@ babel-plugin-macros@^3.0.1: cosmiconfig "^7.0.0" resolve "^1.19.0" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz#9f9a0e1cd9d645cc246a5e094db5c3aa913ccd2b" + integrity sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.1" + "@nicolo-ribaudo/semver-v6" "^6.3.3" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz#d406c5738d298cd9c66f64a94cf8d5904ce4cc5e" + integrity sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.4.1" + core-js-compat "^3.31.0" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz#ace7a5eced6dff7d5060c335c52064778216afd3" + integrity sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.1" babel-plugin-preval@^5.1.0: version "5.1.0" @@ -2674,28 +3435,15 @@ babel-plugin-preval@^5.1.0: babel-plugin-macros "^3.0.1" require-from-string "^2.0.2" -babel-plugin-react-intl@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-react-intl/-/babel-plugin-react-intl-6.2.0.tgz#ac51ca757f318938792fc91e1747515e9225386a" - integrity sha512-ajGpa14mLzyDgdOS75DRlQ0aEL+q7iSCB77613YUPOZbxnAvfB0wg+gLngbd/43eKRw7a4y+IzO3P8kDHl40nA== - dependencies: - "@babel/core" "^7.7.2" - "@babel/helper-plugin-utils" "^7.0.0" - "@types/babel__core" "^7.1.3" - "@types/schema-utils" "^1.0.0" - fs-extra "^8.1.0" - intl-messageformat-parser "^4.1.1" - schema-utils "^2.2.0" - babel-plugin-transform-react-remove-prop-types@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== babel-preset-current-node-syntax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.0.tgz#cf5feef29551253471cfa82fc8e0f5063df07a77" - integrity sha512-mGkvkpocWJes1CmMKtgGUwCeeq0pOhALyymozzDWYomHTbDLwueDYG6p4TK1YOeYHCzBzYPsWkgTto10JubI1Q== + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" @@ -2710,18 +3458,18 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^29.4.0: - version "29.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz#c2b03c548b02dea0a18ae21d5759c136f9251ee4" - integrity sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA== +babel-preset-jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" + integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== dependencies: - babel-plugin-jest-hoist "^29.4.0" + babel-plugin-jest-hoist "^29.5.0" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== balanced-match@^2.0.0: version "2.0.0" @@ -2749,7 +3497,12 @@ base@^0.11.1: batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== big.js@^5.2.2: version "5.2.2" @@ -2762,9 +3515,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bindings@^1.5.0: version "1.5.0" @@ -2778,25 +3531,30 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -blurhash@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-2.0.4.tgz#60642a823b50acaaf3732ddb6c7dfd721bdfef2a" - integrity sha512-r/As72u2FbucLoK5NTegM/GucxJc3d8GvHc4ngo13IO/nt2HU4gONxNLq1XPN6EM/V8Y9URIa7PcSz2RZu553A== +blueimp-load-image@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/blueimp-load-image/-/blueimp-load-image-3.0.0.tgz#d71c39440a7d2f1a83e3e86a625e329116a51705" + integrity sha512-Q9rFbd4ZUNvzSFmRXx9MoG0RwWwJeMjjEUbG7WIOJgUg22Jgkow0wL5b35B6qwiBscxACW9OHdrP5s2vQ3x8DQ== + +blurhash@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-2.0.5.tgz#efde729fc14a2f03571a6aa91b49cba80d1abe4b" + integrity sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w== bmp-js@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" - integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= + integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.1.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" - integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== body-parser@1.20.1: version "1.20.1" @@ -2819,7 +3577,7 @@ body-parser@1.20.1: bonjour@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= + integrity sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg== dependencies: array-flatten "^2.1.0" deep-equal "^1.0.1" @@ -2831,7 +3589,14 @@ bonjour@^3.5.0: boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" brace-expansion@^1.1.7: version "1.1.11" @@ -2874,7 +3639,7 @@ braces@^3.0.2, braces@~3.0.2: brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" @@ -2908,11 +3673,11 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: @@ -2937,15 +3702,25 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.21.3, browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.0.0, browserslist@^4.21.4, browserslist@^4.21.5: + version "4.21.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.8.tgz#db2498e1f4b80ed199c076248a094935860b6017" + integrity sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001502" + electron-to-chromium "^1.4.428" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" + +browserslist@^4.12.0, browserslist@^4.21.9, browserslist@^4.6.4: + version "4.21.9" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" + integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== + dependencies: + caniuse-lite "^1.0.30001503" + electron-to-chromium "^1.4.431" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" bser@2.1.1: version "2.1.1" @@ -2972,7 +3747,7 @@ buffer-writer@2.0.0: buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== buffer@^4.3.0: version "4.9.2" @@ -2998,7 +3773,7 @@ bufferutil@^4.0.7: dependencies: node-gyp-build "^4.3.0" -builtin-modules@^3.1.0: +builtin-modules@^3.1.0, builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== @@ -3006,12 +3781,19 @@ builtin-modules@^3.1.0: builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== bytes@3.1.2: version "3.1.2" @@ -3040,10 +3822,11 @@ cacache@^12.0.2: y18n "^4.0.0" cacache@^15.0.5: - version "15.0.5" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" - integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== + version "15.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== dependencies: + "@npmcli/fs" "^1.0.0" "@npmcli/move-file" "^1.0.1" chownr "^2.0.0" fs-minipass "^2.0.0" @@ -3058,7 +3841,7 @@ cacache@^15.0.5: p-map "^4.0.0" promise-inflight "^1.0.1" rimraf "^3.0.2" - ssri "^8.0.0" + ssri "^8.0.1" tar "^6.0.2" unique-filename "^1.1.1" @@ -3088,45 +3871,46 @@ call-bind@^1.0.0, call-bind@^1.0.2: caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + integrity sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ== dependencies: callsites "^2.0.0" caller-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + integrity sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A== dependencies: caller-callsite "^2.0.0" callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + integrity sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ== callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== +camelcase-keys@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-7.0.2.tgz#d048d8c69448745bb0de6fc4c1c52a30dfbe7252" + integrity sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg== dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" + camelcase "^6.3.0" + map-obj "^4.1.0" + quick-lru "^5.1.1" + type-fest "^1.2.1" camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== +camelcase@^6.2.0, camelcase@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-api@^3.0.0: version "3.0.0" @@ -3138,12 +3922,32 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001400: - version "1.0.30001414" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz" - integrity sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001464: + version "1.0.30001503" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz#88b6ff1b2cf735f1f3361dc1a15b59f0561aa398" + integrity sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw== -chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001503: + version "1.0.30001516" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz#621b1be7d85a8843ee7d210fd9d87b52e3daab3a" + integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== + +caniuse-lite@^1.0.30001502: + version "1.0.30001515" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz#418aefeed9d024cd3129bfae0ccc782d4cb8f12b" + integrity sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA== + +case-sensitive-paths-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + +chalk@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" + integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + +chalk@^2.0, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3174,19 +3978,19 @@ char-regex@^1.0.2: integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== "chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: - anymatch "~3.1.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.5.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.3.1" + fsevents "~2.3.2" chokidar@^2.1.8: version "2.1.8" @@ -3218,16 +4022,14 @@ chownr@^2.0.0: integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" - integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -3238,9 +4040,9 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: safe-buffer "^5.0.1" cjs-module-lexer@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" - integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== class-utils@^0.3.5: version "0.3.6" @@ -3262,6 +4064,29 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -3289,15 +4114,15 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -cluster-key-slot@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" - integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== +cluster-key-slot@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== coa@^2.0.2: version "2.0.2" @@ -3321,17 +4146,17 @@ collect-v8-coverage@^1.0.0: collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== dependencies: map-visit "^1.0.0" object-visit "^1.0.0" -color-blend@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/color-blend/-/color-blend-3.0.1.tgz#3882ed1190ca18760ffe11570d8537960171172b" - integrity sha512-KueDvNiKHAvVeApic0SxHZLyy4x3NELfTLzMHRpRRLi+9e2kWhpeWvtuH3Sjb92mOJYEUhRjb8z7lr4OqDv17Q== +color-blend@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/color-blend/-/color-blend-4.0.0.tgz#e9950e9fa5d6e552ff8bb107c39f7e83a0c1a3bb" + integrity sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw== -color-convert@^1.9.0, color-convert@^1.9.1: +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -3348,17 +4173,17 @@ color-convert@^2.0.1: color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312" - integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA== +color-string@^1.6.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -3369,18 +4194,28 @@ color-support@^1.1.3: integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== color@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== dependencies: - color-convert "^1.9.1" - color-string "^1.5.2" + color-convert "^1.9.3" + color-string "^1.6.0" -colord@^2.9.3: +colord@^2.9.1, colord@^2.9.3: version "2.9.3" resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== +colorette@^2.0.19: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -3388,6 +4223,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -3398,6 +4238,11 @@ commander@^7.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +comment-parser@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b" + integrity sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA== + common-tags@^1.8.0: version "1.8.2" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" @@ -3406,7 +4251,7 @@ common-tags@^1.8.0: commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== component-emitter@^1.2.1: version "1.3.0" @@ -3420,6 +4265,17 @@ compressible@~2.0.16: dependencies: mime-db ">= 1.43.0 < 2" +compression-webpack-plugin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-4.0.1.tgz#33eda97f1170dd38c5556771de10f34245aa0274" + integrity sha512-0mg6PgwTsUe5LEcUrOu3ob32vraDx2VdbMGAT1PARcOV+UJWDYZFdkSo6RbHoGQ061mmmkC7XpRKOlvwm/gzJQ== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + schema-utils "^2.7.0" + serialize-javascript "^4.0.0" + webpack-sources "^1.4.3" + compression-webpack-plugin@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/compression-webpack-plugin/-/compression-webpack-plugin-6.1.1.tgz#ae8e4b2ffdb7396bb776e66918d751a20d8ccf0e" @@ -3447,7 +4303,7 @@ compression@^1.7.4: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^1.5.0: version "1.6.2" @@ -3472,12 +4328,12 @@ console-browserify@^1.1.0: console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== content-disposition@0.5.4: version "0.5.4" @@ -3487,16 +4343,14 @@ content-disposition@0.5.4: safe-buffer "5.2.1" content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== convert-source-map@^2.0.0: version "2.0.0" @@ -3506,7 +4360,7 @@ convert-source-map@^2.0.0: cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== cookie@0.5.0: version "0.5.0" @@ -3528,29 +4382,29 @@ copy-concurrently@^1.0.0: copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -core-js-compat@^3.25.1: - version "3.25.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.2.tgz#7875573586809909c69e03ef310810c1969ee138" - integrity sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ== +core-js-compat@^3.31.0: + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.1.tgz#5084ad1a46858df50ff89ace152441a63ba7aae0" + integrity sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA== dependencies: - browserslist "^4.21.4" - -core-js-pure@^3.0.0: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" - integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== + browserslist "^4.21.9" core-js@^2.5.0: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== +core-js@^3.16.2, core-js@^3.30.2: + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.31.1.tgz#f2b0eea9be9da0def2c5fece71064a7e5d687653" + integrity sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ== + core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^5.0.0: version "5.2.1" @@ -3573,7 +4427,7 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -cosmiconfig@^7.0.0, cosmiconfig@^7.1.0: +cosmiconfig@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== @@ -3584,6 +4438,16 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.1.0: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd" + integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -3633,7 +4497,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3664,10 +4528,17 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== +css-blank-pseudo@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" + integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== + dependencies: + postcss "^7.0.5" + css-color-names@0.0.4, css-color-names@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + integrity sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q== css-declaration-sorter@^4.0.1: version "4.0.1" @@ -3677,11 +4548,43 @@ css-declaration-sorter@^4.0.1: postcss "^7.0.1" timsort "^0.3.0" +css-declaration-sorter@^6.3.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz#630618adc21724484b3e9505bce812def44000ad" + integrity sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew== + css-functions-list@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.1.0.tgz#cf5b09f835ad91a00e5959bcfc627cd498e1321b" integrity sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w== +css-has-pseudo@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" + integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^5.0.0-rc.4" + +css-loader@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + css-loader@^5.2.7: version "5.2.7" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" @@ -3698,6 +4601,13 @@ css-loader@^5.2.7: schema-utils "^3.0.0" semver "^7.3.5" +css-prefers-color-scheme@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" + integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== + dependencies: + postcss "^7.0.5" + css-select-base-adapter@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" @@ -3713,6 +4623,17 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" @@ -3721,23 +4642,54 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-tree@1.0.0-alpha.39: - version "1.0.0-alpha.39" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" - integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== +css-tree@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== dependencies: - mdn-data "2.0.6" + mdn-data "2.0.14" source-map "^0.6.1" +css-tree@^2.2.1, css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + css-what@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" - integrity sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg== + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== css.escape@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" - integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + +cssdb@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" + integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== + +cssesc@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" + integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== cssesc@^3.0.0: version "3.0.0" @@ -3780,15 +4732,50 @@ cssnano-preset-default@^4.0.8: postcss-svgo "^4.0.3" postcss-unique-selectors "^4.0.1" +cssnano-preset-default@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz#2a93247140d214ddb9f46bc6a3562fa9177fe301" + integrity sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ== + dependencies: + css-declaration-sorter "^6.3.1" + cssnano-utils "^4.0.0" + postcss-calc "^9.0.0" + postcss-colormin "^6.0.0" + postcss-convert-values "^6.0.0" + postcss-discard-comments "^6.0.0" + postcss-discard-duplicates "^6.0.0" + postcss-discard-empty "^6.0.0" + postcss-discard-overridden "^6.0.0" + postcss-merge-longhand "^6.0.0" + postcss-merge-rules "^6.0.1" + postcss-minify-font-values "^6.0.0" + postcss-minify-gradients "^6.0.0" + postcss-minify-params "^6.0.0" + postcss-minify-selectors "^6.0.0" + postcss-normalize-charset "^6.0.0" + postcss-normalize-display-values "^6.0.0" + postcss-normalize-positions "^6.0.0" + postcss-normalize-repeat-style "^6.0.0" + postcss-normalize-string "^6.0.0" + postcss-normalize-timing-functions "^6.0.0" + postcss-normalize-unicode "^6.0.0" + postcss-normalize-url "^6.0.0" + postcss-normalize-whitespace "^6.0.0" + postcss-ordered-values "^6.0.0" + postcss-reduce-initial "^6.0.0" + postcss-reduce-transforms "^6.0.0" + postcss-svgo "^6.0.0" + postcss-unique-selectors "^6.0.0" + cssnano-util-get-arguments@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" - integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + integrity sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw== cssnano-util-get-match@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" - integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + integrity sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw== cssnano-util-raw-cache@^4.0.1: version "4.0.1" @@ -3802,7 +4789,12 @@ cssnano-util-same-parent@^4.0.0: resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== -cssnano@^4.1.11: +cssnano-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-4.0.0.tgz#d1da885ec04003ab19505ff0e62e029708d36b08" + integrity sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw== + +cssnano@^4.1.10: version "4.1.11" resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.11.tgz#c7b5f5b81da269cb1fd982cb960c1200910c9a99" integrity sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g== @@ -3812,12 +4804,27 @@ cssnano@^4.1.11: is-resolvable "^1.0.0" postcss "^7.0.0" -csso@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" - integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== +cssnano@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-6.0.1.tgz#87c38c4cd47049c735ab756d7e77ac3ca855c008" + integrity sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg== dependencies: - css-tree "1.0.0-alpha.39" + cssnano-preset-default "^6.0.1" + lilconfig "^2.1.0" + +csso@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + +csso@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" cssom@^0.5.0: version "0.5.0" @@ -3836,28 +4843,22 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^2.6.7: - version "2.6.13" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f" - integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A== +cssstyle@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-3.0.0.tgz#17ca9c87d26eac764bb8cfd00583cff21ce0277a" + integrity sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg== + dependencies: + rrweb-cssom "^0.6.0" csstype@^3.0.2: - version "3.0.6" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef" - integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" + version "1.0.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" + integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== damerau-levenshtein@^1.0.8: version "1.0.8" @@ -3873,6 +4874,15 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" +data-urls@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-4.0.0.tgz#333a454eca6f9a5b7b0f1013ff89074c3f522dd4" + integrity sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g== + dependencies: + abab "^2.0.6" + whatwg-mimetype "^3.0.0" + whatwg-url "^12.0.0" + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -3887,7 +4897,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" -debug@^3.1.1, debug@^3.2.6, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -3895,9 +4905,9 @@ debug@^3.1.1, debug@^3.2.6, debug@^3.2.7: ms "^2.1.1" decamelize-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" + integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== dependencies: decamelize "^1.1.0" map-obj "^1.0.0" @@ -3905,12 +4915,17 @@ decamelize-keys@^1.1.0: decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -decimal.js@^10.4.2: - version "10.4.2" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" - integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA== +decamelize@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.1.tgz#db11a92e58c741ef339fb0a2868d8a06a9a7b1e9" + integrity sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA== + +decimal.js@^10.4.2, decimal.js@^10.4.3: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== decode-uri-component@^0.2.0: version "0.2.2" @@ -3920,7 +4935,7 @@ decode-uri-component@^0.2.0: dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-equal@^1.0.1: version "1.1.1" @@ -3935,15 +4950,16 @@ deep-equal@^1.0.1: regexp.prototype.flags "^1.2.0" deep-equal@^2.0.5: - version "2.2.0" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6" - integrity sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw== + version "2.2.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.1.tgz#c72ab22f3a7d3503a4ca87dde976fe9978816739" + integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== dependencies: + array-buffer-byte-length "^1.0.0" call-bind "^1.0.2" - es-get-iterator "^1.1.2" - get-intrinsic "^1.1.3" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.0" is-arguments "^1.1.1" - is-array-buffer "^3.0.1" + is-array-buffer "^3.0.2" is-date-object "^1.0.5" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" @@ -3951,21 +4967,39 @@ deep-equal@^2.0.5: object-is "^1.1.5" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.0" side-channel "^1.0.4" which-boxed-primitive "^1.0.2" which-collection "^1.0.1" which-typed-array "^1.1.9" deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.0, deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" default-gateway@^4.2.0: version "4.2.0" @@ -3975,10 +5009,15 @@ default-gateway@^4.2.0: execa "^1.0.0" ip-regex "^2.1.0" -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== dependencies: has-property-descriptors "^1.0.0" object-keys "^1.1.1" @@ -3986,14 +5025,14 @@ define-properties@^1.1.3, define-properties@^1.1.4: define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== dependencies: is-descriptor "^1.0.0" @@ -4021,12 +5060,12 @@ del@^4.1.1: delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== depd@2.0.0: version "2.0.0" @@ -4036,17 +5075,17 @@ depd@2.0.0: depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -dequal@^2.0.2: +dequal@^2.0.2, dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" @@ -4059,7 +5098,7 @@ destroy@1.2.0: detect-file@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== detect-it@^4.0.1: version "4.0.1" @@ -4072,9 +5111,9 @@ detect-newline@^3.0.0: integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== detect-passive-events@^2.0.3: version "2.0.3" @@ -4083,15 +5122,10 @@ detect-passive-events@^2.0.3: dependencies: detect-it "^4.0.1" -diff-sequences@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" - integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== - -diff-sequences@^29.3.1: - version "29.3.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" - integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== +diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== diffie-hellman@^5.0.0: version "5.0.3" @@ -4112,7 +5146,7 @@ dir-glob@^3.0.1: dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== dns-packet@^1.3.1: version "1.3.4" @@ -4125,7 +5159,7 @@ dns-packet@^1.3.1: dns-txt@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= + integrity sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ== dependencies: buffer-indexof "^1.0.0" @@ -4143,10 +5177,10 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-accessibility-api@^0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.6.tgz#3f5d43b52c7a3bd68b5fb63fa47b4e4c1fdf65a9" - integrity sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw== +dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== dom-helpers@^3.4.0: version "3.4.0" @@ -4155,15 +5189,7 @@ dom-helpers@^3.4.0: dependencies: "@babel/runtime" "^7.1.2" -dom-helpers@^5.0.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821" - integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw== - dependencies: - "@babel/runtime" "^7.6.3" - csstype "^2.6.7" - -dom-helpers@^5.2.0: +dom-helpers@^5.0.1, dom-helpers@^5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== @@ -4179,6 +5205,15 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -4189,10 +5224,10 @@ domelementtype@1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== -domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== +domelementtype@^2.0.1, domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== domexception@^4.0.0: version "4.0.0" @@ -4201,6 +5236,13 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" @@ -4209,6 +5251,15 @@ domutils@^1.7.0: dom-serializer "0" domelementtype "1" +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dot-prop@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -4217,9 +5268,9 @@ dot-prop@^5.2.0: is-obj "^2.0.0" dotenv@^16.0.3: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== duplexer@^0.1.2: version "0.1.2" @@ -4236,22 +5287,32 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^3.1.6: - version "3.1.8" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" - integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.251: - version "1.4.254" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.254.tgz#c6203583890abf88dfc0be046cd72d3b48f8beb6" - integrity sha512-Sh/7YsHqQYkA6ZHuHMy24e6TE4eX6KZVsZb9E/DvU1nQRIrH4BflO/4k+83tfdYvDl+MObvlqHPRICzEdC9c6Q== +electron-to-chromium@^1.4.428: + version "1.4.457" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.457.tgz#3fdc7b4f97d628ac6b51e8b4b385befb362fe343" + integrity sha512-/g3UyNDmDd6ebeWapmAoiyy+Sy2HyJ+/X8KyvNeHfKRFfHaA2W8oF5fxD5F3tjBDcjpwo0iek6YNgxNXDBoEtA== + +electron-to-chromium@^1.4.431: + version "1.4.461" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.461.tgz#6b14af66042732bf883ab63a4d82cac8f35eb252" + integrity sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ== elliptic@^6.5.3: version "6.5.4" @@ -4280,6 +5341,11 @@ emittery@^0.13.1: intersection-observer "^0.12.0" prop-types "^15.6.0" +emoji-regex@10.2.1, emoji-regex@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f" + integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA== + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -4303,7 +5369,7 @@ emojis-list@^3.0.0: encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" @@ -4321,20 +5387,28 @@ enhanced-resolve@^4.1.1, enhanced-resolve@^4.5.0: memory-fs "^0.5.0" tapable "^1.0.0" -entities@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" - integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== +enhanced-resolve@^5.12.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" -entities@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" - integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -4346,43 +5420,103 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" error-stack-parser@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" - integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== dependencies: - stackframe "^1.1.1" + stackframe "^1.3.4" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.4: - version "1.20.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" - integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== +es-abstract@^1.17.2, es-abstract@^1.21.2: + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" + available-typed-arrays "^1.0.5" call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" has "^1.0.3" has-property-descriptors "^1.0.0" + has-proto "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" is-callable "^1.2.7" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" + is-typed-array "^1.1.10" is-weakref "^1.0.2" - object-inspect "^1.12.2" + object-inspect "^1.12.3" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.10" + +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.21.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" + integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + dependencies: + array-buffer-byte-length "^1.0.0" + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.2.0" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.10" + is-weakref "^1.0.2" + object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.4.3" safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" -es-get-iterator@^1.1.2: +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== @@ -4397,6 +5531,15 @@ es-get-iterator@^1.1.2: isarray "^2.0.5" stop-iteration-iterator "^1.0.0" +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + es-shim-unscopables@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" @@ -4413,32 +5556,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -4447,12 +5564,12 @@ escalade@^3.1.1: escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: version "2.0.0" @@ -4476,6 +5593,11 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" + integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + eslint-import-resolver-node@^0.3.7: version "0.3.7" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" @@ -4485,13 +5607,44 @@ eslint-import-resolver-node@^0.3.7: is-core-module "^2.11.0" resolve "^1.22.1" +eslint-import-resolver-typescript@^3.5.5: + version "3.5.5" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz#0a9034ae7ed94b254a360fbea89187b60ea7456d" + integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== + dependencies: + debug "^4.3.4" + enhanced-resolve "^5.12.0" + eslint-module-utils "^2.7.4" + get-tsconfig "^4.5.0" + globby "^13.1.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + synckit "^0.8.5" + eslint-module-utils@^2.7.4: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" +eslint-plugin-formatjs@^4.10.1: + version "4.10.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-formatjs/-/eslint-plugin-formatjs-4.10.3.tgz#65882730aebee3c8b6eec06381a4b0a18c0d33bd" + integrity sha512-EHKuEMCmWhAiMdCc8oZU8qBAvnvHPUiJuhGxPqA+GX2Nb7GBsGm2o616KYnSSffDisK+v0E9TDCrS8oJ0QLgcw== + dependencies: + "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/ts-transformer" "3.13.3" + "@types/eslint" "7 || 8" + "@types/picomatch" "^2.3.0" + "@typescript-eslint/typescript-estree" "5.59.0" + emoji-regex "^10.2.1" + magic-string "^0.30.0" + picomatch "^2.3.1" + tslib "2.5.0" + typescript "^4.7 || 5" + unicode-emoji-utils "^1.1.1" + eslint-plugin-import@~2.27.5: version "2.27.5" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" @@ -4513,6 +5666,21 @@ eslint-plugin-import@~2.27.5: semver "^6.3.0" tsconfig-paths "^3.14.1" +eslint-plugin-jsdoc@^46.1.0: + version "46.2.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.2.6.tgz#f25590d371859f20691d65b5dcd4cbe370d65564" + integrity sha512-zIaK3zbSrKuH12bP+SPybPgcHSM6MFzh3HFeaODzmsF1N8C1l8dzJ22cW1aq4g0+nayU1VMjmNf7hg0dpShLrA== + dependencies: + "@es-joy/jsdoccomment" "~0.39.4" + are-docs-informative "^0.0.2" + comment-parser "1.3.1" + debug "^4.3.4" + escape-string-regexp "^4.0.0" + esquery "^1.5.0" + is-builtin-module "^3.2.1" + semver "^7.5.1" + spdx-expression-parse "^3.0.1" + eslint-plugin-jsx-a11y@~6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" @@ -4535,11 +5703,24 @@ eslint-plugin-jsx-a11y@~6.7.1: object.fromentries "^2.0.6" semver "^6.3.0" +eslint-plugin-prettier@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a" + integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.8.5" + eslint-plugin-promise@~6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + eslint-plugin-react@~7.32.2: version "7.32.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" @@ -4561,14 +5742,6 @@ eslint-plugin-react@~7.32.2: semver "^6.3.0" string.prototype.matchall "^4.0.8" -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -4577,38 +5750,37 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.41.0: + version "8.42.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.42.0.tgz#7bebdc3a55f9ed7167251fe7259f75219cade291" + integrity sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A== dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint@^8.33.0: - version "8.33.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.33.0.tgz#02f110f32998cb598c6461f24f4d306e41ca33d7" - integrity sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA== - dependencies: - "@eslint/eslintrc" "^1.4.1" - "@humanwhocodes/config-array" "^0.11.8" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.3" + "@eslint/js" "8.42.0" + "@humanwhocodes/config-array" "^0.11.10" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" @@ -4617,24 +5789,22 @@ eslint@^8.33.0: debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.4.0" - esquery "^1.4.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.5.2" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" find-up "^5.0.0" glob-parent "^6.0.2" globals "^13.19.0" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" - js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -4642,29 +5812,28 @@ eslint@^8.33.0: minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.1" - regexpp "^3.2.0" strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.4.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" - integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== +espree@^9.5.2: + version "9.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== dependencies: acorn "^8.8.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.2, esquery@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -4698,7 +5867,7 @@ esutils@^2.0.2: etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== event-target-shim@^5.0.0: version "5.0.1" @@ -4715,12 +5884,10 @@ events@^3.0.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -eventsource@^1.0.7: - version "1.1.1" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.1.tgz#4544a35a57d7120fba4fa4c86cb4023b2c09df2f" - integrity sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA== - dependencies: - original "^1.0.0" +eventsource@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" + integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -4758,6 +5925,21 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^7.0.0, execa@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + exif-js@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/exif-js/-/exif-js-2.3.0.tgz#9d10819bf571f873813e7640241255ab9ce1a814" @@ -4766,12 +5948,12 @@ exif-js@^2.3.0: exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -4784,20 +5966,20 @@ expand-brackets@^2.1.4: expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== dependencies: homedir-polyfill "^1.0.1" -expect@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.1.tgz#58cfeea9cbf479b64ed081fd1e074ac8beb5a1fe" - integrity sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A== +expect@^29.0.0, expect@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" + integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== dependencies: - "@jest/expect-utils" "^29.4.1" - jest-get-type "^29.2.0" - jest-matcher-utils "^29.4.1" - jest-message-util "^29.4.1" - jest-util "^29.4.1" + "@jest/expect-utils" "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" express@^4.17.1, express@^4.18.2: version "4.18.2" @@ -4836,24 +6018,17 @@ express@^4.17.1, express@^4.18.2: utils-merge "1.0.1" vary "~1.1.2" -ext@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" - integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== - dependencies: - type "^2.0.0" - extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" @@ -4877,7 +6052,12 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.12, fast-glob@^3.2.9: +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -4888,6 +6068,17 @@ fast-glob@^3.2.12, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" + integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -4896,7 +6087,7 @@ fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastest-levenshtein@^1.0.16: version "1.0.16" @@ -4904,23 +6095,28 @@ fastest-levenshtein@^1.0.16: integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" -faye-websocket@^0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== +favico.js@^0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/favico.js/-/favico.js-0.3.10.tgz#80586e27a117f24a8d51c18a99bdc714d4339301" + integrity sha1-gFhuJ6EX8kqNUcGKmb3HFNQzkwE= + +faye-websocket@^0.11.3, faye-websocket@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== dependencies: websocket-driver ">=0.5.1" fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" @@ -4954,7 +6150,7 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== @@ -4964,7 +6160,7 @@ filelist@^1.0.1: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -5001,9 +6197,9 @@ find-cache-dir@^2.1.0: pkg-dir "^3.0.0" find-cache-dir@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== dependencies: commondir "^1.0.1" make-dir "^3.0.2" @@ -5055,10 +6251,15 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" -flatted@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" - integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== +flatted@^3.1.0, flatted@^3.2.2: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== flush-write-stream@^1.0.0: version "1.1.1" @@ -5076,7 +6277,7 @@ follow-redirects@^1.0.0, follow-redirects@^1.15.0: font-awesome@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" - integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM= + integrity sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg== for-each@^0.3.3: version "0.3.3" @@ -5088,7 +6289,15 @@ for-each@^0.3.3: for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" form-data@^4.0.0: version "4.0.0" @@ -5104,35 +6313,31 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== dependencies: inherits "^2.0.1" readable-stream "^2.0.0" -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -5153,7 +6358,7 @@ fs-minipass@^2.0.0: fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== dependencies: graceful-fs "^4.1.2" iferr "^0.1.5" @@ -5163,7 +6368,7 @@ fs-write-stream-atomic@^1.0.8: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^1.2.7: version "1.2.13" @@ -5173,7 +6378,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: +fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -5193,34 +6398,34 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functions-have-names@^1.2.2: +functions-have-names@^1.2.2, functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -fuzzysort@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/fuzzysort/-/fuzzysort-1.9.0.tgz#d36d27949eae22340bb6f7ba30ea6751b92a181c" - integrity sha512-MOxCT0qLTwLqmEwc7UtU045RKef7mc8Qz8eR4r2bLNEq9dy/c3ZKMEFp6IEst69otkQdFZ4FfgH2dmZD+ddX1g== +fuzzysort@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/fuzzysort/-/fuzzysort-2.0.4.tgz#a21d1ce8947eaf2797dc3b7c28c36db9d1165f84" + integrity sha512-Api1mJL+Ad7W7vnDZnWq5pGaXJjyencT+iKGia2PlHUcSsSzWwIQ3S1isiMpwpavjYtGd2FzhUIhnnhOULZgDw== gauge@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.0.tgz#e270ca9d97dae84abf64e5277ef1ebddc7dd1e2f" - integrity sha512-0s5T5eciEG7Q3ugkxAkFtaDhrrhXsCRivA5y8C9WMHWuI8UlMOJg7+Iwf7Mccii+Dfs3H5jHepU0joPVyQU0Lw== + version "5.0.1" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.1.tgz#1efc801b8ff076b86ef3e9a7a280a975df572112" + integrity sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ== dependencies: aproba "^1.0.3 || ^2.0.0" color-support "^1.1.3" console-control-strings "^1.1.0" has-unicode "^2.0.1" - signal-exit "^3.0.7" + signal-exit "^4.0.1" string-width "^4.2.3" strip-ansi "^6.0.1" wide-align "^1.1.5" -generic-pool@3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.8.2.tgz#aab4f280adb522fdfbdc5e5b64d718d3683f04e9" - integrity sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg== +generic-pool@3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4" + integrity sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" @@ -5232,13 +6437,14 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" has "^1.0.3" + has-proto "^1.0.1" has-symbols "^1.0.3" get-own-enumerable-property-symbols@^3.0.0: @@ -5258,7 +6464,7 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" -get-stream@^6.0.0: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -5271,20 +6477,27 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-tsconfig@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.6.0.tgz#e977690993a42f3e320e932427502a40f7af6d05" + integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== + dependencies: + resolve-pkg-maps "^1.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -5298,29 +6511,29 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" -glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob@^10.2.5, glob@^10.2.6: + version "10.3.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.3.tgz#8360a4ffdd6ed90df84aa8d52f21f452e86a123b" + integrity sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.0.3" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^3.1.1" once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -5340,7 +6553,7 @@ global-modules@^2.0.0: global-prefix@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== dependencies: expand-tilde "^2.0.2" homedir-polyfill "^1.0.1" @@ -5369,6 +6582,13 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -5381,10 +6601,21 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +globby@^13.1.3: + version "13.1.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.4.tgz#2f91c116066bcec152465ba36e5caa4a13c01317" + integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== dependencies: array-union "^1.0.1" glob "^7.0.3" @@ -5404,16 +6635,21 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: - version "4.2.9" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" - integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== grapheme-splitter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + gzip-size@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" @@ -5431,7 +6667,7 @@ hard-rejection@^2.1.0: resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== -has-bigints@^1.0.2: +has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== @@ -5439,7 +6675,7 @@ has-bigints@^1.0.2: has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" @@ -5453,6 +6689,11 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -5468,12 +6709,12 @@ has-tostringtag@^1.0.0: has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -5482,7 +6723,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -5491,12 +6732,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -5545,7 +6786,7 @@ history@^4.10.1, history@^4.7.2: hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== dependencies: hash.js "^1.0.3" minimalistic-assert "^1.0.0" @@ -5570,11 +6811,6 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - hosted-git-info@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" @@ -5585,7 +6821,7 @@ hosted-git-info@^4.0.1: hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== dependencies: inherits "^2.0.1" obuf "^1.0.0" @@ -5595,12 +6831,12 @@ hpack.js@^2.1.6: hsl-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" - integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + integrity sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A== hsla-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" - integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + integrity sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA== html-encoding-sniffer@^3.0.0: version "3.0.0" @@ -5610,24 +6846,24 @@ html-encoding-sniffer@^3.0.0: whatwg-encoding "^2.0.0" html-entities@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.3.1.tgz#fb9a1a4b5b14c5daba82d3e34c6ae4fe701a0e44" - integrity sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-tags@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" - integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg== +html-tags@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== http-errors@2.0.0: version "2.0.0" @@ -5643,22 +6879,22 @@ http-errors@2.0.0: http-errors@~1.6.2: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== dependencies: depd "~1.1.2" inherits "2.0.3" setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-link-header@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.1.0.tgz#a1ca87efdbcb7778d8d0d4525de1e6964ec1f129" - integrity sha512-pj6N1yxOz/ANO8HHsWGg/OoIL1kmRYvQnXQ7PIRpgp+15AnEsRH8fmIJE6D1OdWG2Bov+BJHVla1fFXxg1JbbA== +http-link-header@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.1.1.tgz#f0e6971b0ed86e858d2077066ecb7ba4f2e50de9" + integrity sha512-mW3N/rTYpCn99s1do0zx6nzFZSwLH9HGfUM4ZqLWJ16ylmYaC2v5eYGqrNTQlByx8AzUgGI+V/32gXPugs1+Sw== http-parser-js@>=0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" - integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== http-proxy-agent@^5.0.0: version "5.0.0" @@ -5691,7 +6927,7 @@ http-proxy@^1.17.0: https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== https-proxy-agent@^5.0.1: version "5.0.1" @@ -5706,6 +6942,16 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +husky@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" + integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5720,6 +6966,13 @@ iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" @@ -5731,9 +6984,9 @@ idb-keyval@^3.2.0: integrity sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ== idb@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.2.tgz#7a067e20dd16539938e456814b7d714ba8db3892" - integrity sha512-jjKrT1EnyZewQ/gCBb/eyiYrhGzws2FeY92Yx8qT9S9GeQAmo4JFVIiWRIfKW/6Ob9A+UDAOW9j9jn58fy2HIg== + version "7.1.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" @@ -5743,29 +6996,39 @@ ieee754@^1.1.4, ieee754@^1.2.1: iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== -ignore@^5.2.0, ignore@^5.2.1: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== -immutable@^4.0.0, immutable@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.4.tgz#83260d50889526b4b531a5e293709a77f7c55a2a" - integrity sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w== +immer@^9.0.21: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + +immutable@^3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg== + +immutable@^4.0.0, immutable@^4.0.0-rc.1, immutable@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.1.tgz#17988b356097ab0719e2f741d56f3ec6c317f9dc" + integrity sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A== import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" - integrity sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk= + integrity sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg== dependencies: import-from "^2.1.0" import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + integrity sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg== dependencies: caller-path "^2.0.0" resolve-from "^3.0.0" @@ -5781,7 +7044,7 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: import-from@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - integrity sha1-M1238qev/VOqpHHUuAId7ja387E= + integrity sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w== dependencies: resolve-from "^3.0.0" @@ -5799,9 +7062,9 @@ import-local@^2.0.0: resolve-cwd "^2.0.0" import-local@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" - integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" @@ -5819,17 +7082,22 @@ imports-loader@^1.2.0: imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== +indent-string@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-5.0.0.tgz#4fd2980fccaf8622d14c64d694f4cf33c81951a5" + integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== + indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + integrity sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA== infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" @@ -5839,7 +7107,7 @@ infer-owner@^1.0.3, infer-owner@^1.0.4: inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" @@ -5852,17 +7120,17 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + integrity sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA== inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== ini@^1.3.4, ini@^1.3.5: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" - integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== internal-ip@^4.3.0: version "4.3.0" @@ -5872,21 +7140,12 @@ internal-ip@^4.3.0: default-gateway "^4.2.0" ipaddr.js "^1.9.0" -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== +internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -internal-slot@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3" - integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== - dependencies: - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.0" has "^1.0.3" side-channel "^1.0.4" @@ -5900,48 +7159,17 @@ intersection-observer@^0.12.0: resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.12.2.tgz#4a45349cc0cd91916682b1f44c28d7ec737dc375" integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg== -intl-format-cache@^2.0.5: - version "2.2.9" - resolved "https://registry.yarnpkg.com/intl-format-cache/-/intl-format-cache-2.2.9.tgz#fb560de20c549cda20b569cf1ffb6dc62b5b93b4" - integrity sha512-Zv/u8wRpekckv0cLkwpVdABYST4hZNTDaX7reFetrYTJwxExR2VyTqQm+l0WmL0Qo8Mjb9Tf33qnfj0T7pjxdQ== - -intl-messageformat-parser@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075" - integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU= - -intl-messageformat-parser@^4.1.1: - version "4.1.4" - resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-4.1.4.tgz#98f3415e6990d44bebf2e0ad8e4cfbacf3ef5ed3" - integrity sha512-zV4kBUD1yhxSyaXm6bGhmP4HFH9Gh4pRQwNn+xq5P+B1dT8mpaAfU75nfUn4HgddIB6pyFnzM5MQjO55UpJwkQ== +intl-messageformat@10.5.0, intl-messageformat@^10.3.5: + version "10.5.0" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.0.tgz#86d11b15913ac954075b25253f5e669359f89538" + integrity sha512-AvojYuOaRb6r2veOKfTVpxH9TrmjSdc5iR9R5RgBwrDZYSmAAFVT+QLbW3C4V7Qsg0OguMp67Q/EoUkxZzXRGw== dependencies: - "@formatjs/intl-unified-numberformat" "^3.3.3" + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.6.0" + tslib "^2.4.0" -intl-messageformat@^2.0.0, intl-messageformat@^2.1.0, intl-messageformat@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc" - integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw= - dependencies: - intl-messageformat-parser "1.4.0" - -intl-relativeformat@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-2.2.0.tgz#6aca95d019ec8d30b6c5653b6629f9983ea5b6c5" - integrity sha512-4bV/7kSKaPEmu6ArxXf9xjv1ny74Zkwuey8Pm01NH4zggPP7JHwg2STk8Y3JdspCKRDriwIyLRfEXnj2ZLr4Bw== - dependencies: - intl-messageformat "^2.0.0" - -intl-relativeformat@^6.4.3: - version "6.4.3" - resolved "https://registry.yarnpkg.com/intl-relativeformat/-/intl-relativeformat-6.4.3.tgz#cb5559e1e257cc2e763583502012a354bb777efe" - integrity sha512-VxZXZfhuX/zBVfxzE/J6kPUpsyWKYjqtZ3jVGZwr6wzK5BOLVpe1vSlwCQX56w5UjlpL63fS8Nxq0kgTyf1gJA== - -intl@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" - integrity sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94= - -invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -5951,12 +7179,12 @@ invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.4: ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + version "1.1.8" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== ipaddr.js@1.9.1, ipaddr.js@^1.9.0: version "1.9.1" @@ -5966,7 +7194,7 @@ ipaddr.js@1.9.1, ipaddr.js@^1.9.0: is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" - integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + integrity sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg== is-absolute-url@^3.0.3: version "3.0.3" @@ -5976,7 +7204,7 @@ is-absolute-url@^3.0.3: is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== dependencies: kind-of "^3.0.2" @@ -5987,12 +7215,7 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - -is-arguments@^1.1.1: +is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -6000,19 +7223,19 @@ is-arguments@^1.1.1: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-array-buffer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" - integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== dependencies: call-bind "^1.0.2" - get-intrinsic "^1.1.3" + get-intrinsic "^1.2.0" is-typed-array "^1.1.10" is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-arrayish@^0.3.1: version "0.3.2" @@ -6020,14 +7243,16 @@ is-arrayish@^0.3.1: integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== is-bigint@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" - integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== dependencies: binary-extensions "^1.0.0" @@ -6039,11 +7264,19 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" - integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-builtin-module@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" @@ -6053,7 +7286,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: is-color-stop@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" - integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + integrity sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA== dependencies: css-color-names "^0.0.4" hex-color-regex "^1.1.0" @@ -6063,16 +7296,16 @@ is-color-stop@^1.0.0: rgba-regex "^1.0.0" is-core-module@^2.11.0, is-core-module@^2.5.0, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== dependencies: has "^1.0.3" is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== dependencies: kind-of "^3.0.2" @@ -6083,12 +7316,7 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-date-object@^1.0.5: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -6116,17 +7344,27 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== + +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== is-electron@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.0.tgz#8943084f09e8b731b3a7a0298a7b5d56f6b7eef0" - integrity sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q== + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.2.tgz#3778902a2044d76de98036f5dc58089ac4d80bb9" + integrity sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== is-extendable@^1.0.1: version "1.0.1" @@ -6138,18 +7376,23 @@ is-extendable@^1.0.1: is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + is-generator-fn@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" @@ -6158,7 +7401,7 @@ is-generator-fn@^2.0.0: is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== dependencies: is-extglob "^2.1.0" @@ -6169,6 +7412,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -6177,15 +7427,7 @@ is-map@^2.0.1, is-map@^2.0.2: is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= - -is-nan@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== is-negative-zero@^2.0.2: version "2.0.2" @@ -6193,14 +7435,16 @@ is-negative-zero@^2.0.2: integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" - integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== dependencies: kind-of "^3.0.2" @@ -6212,7 +7456,7 @@ is-number@^7.0.0: is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== is-obj@^2.0.0: version "2.0.0" @@ -6243,7 +7487,7 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^1.1.0: +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== @@ -6276,7 +7520,7 @@ is-regex@^1.0.4, is-regex@^1.1.4: is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== is-resolvable@^1.0.0: version "1.1.0" @@ -6298,12 +7542,17 @@ is-shared-array-buffer@^1.0.2: is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" @@ -6319,7 +7568,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10: +is-typed-array@^1.1.10, is-typed-array@^1.1.9: version "1.1.10" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== @@ -6363,17 +7612,24 @@ is-windows@^1.0.1, is-windows@^1.0.2: is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isarray@^2.0.5: version "2.0.5" @@ -6383,19 +7639,19 @@ isarray@^2.0.5: isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" @@ -6403,9 +7659,9 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" - integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -6423,339 +7679,333 @@ istanbul-lib-report@^3.0.0: supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" - integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.3.tgz#4bcae3103b94518117930d51283690960b50d3c2" - integrity sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg== + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^2.0.3: + version "2.2.1" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6" + integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" -jest-changed-files@^29.4.0: - version "29.4.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.0.tgz#ac2498bcd394228f7eddcadcf928b3583bf2779d" - integrity sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w== +jest-changed-files@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" + integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== dependencies: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.1.tgz#ff1b63eb04c3b111cefea9489e8dbadd23ce49bd" - integrity sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA== +jest-circus@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.5.0.tgz#b5926989449e75bff0d59944bae083c9d7fb7317" + integrity sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA== dependencies: - "@jest/environment" "^29.4.1" - "@jest/expect" "^29.4.1" - "@jest/test-result" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/environment" "^29.5.0" + "@jest/expect" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^29.4.1" - jest-matcher-utils "^29.4.1" - jest-message-util "^29.4.1" - jest-runtime "^29.4.1" - jest-snapshot "^29.4.1" - jest-util "^29.4.1" + jest-each "^29.5.0" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-runtime "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" p-limit "^3.1.0" - pretty-format "^29.4.1" + pretty-format "^29.5.0" + pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.1.tgz#7abef96944f300feb9b76f68b1eb2d68774fe553" - integrity sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ== +jest-cli@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.5.0.tgz#b34c20a6d35968f3ee47a7437ff8e53e086b4a67" + integrity sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw== dependencies: - "@jest/core" "^29.4.1" - "@jest/test-result" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/core" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.4.1" - jest-util "^29.4.1" - jest-validate "^29.4.1" + jest-config "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.1.tgz#e62670c6c980ec21d75941806ec4d0c0c6402728" - integrity sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg== +jest-config@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.5.0.tgz#3cc972faec8c8aaea9ae158c694541b79f3748da" + integrity sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.4.1" - "@jest/types" "^29.4.1" - babel-jest "^29.4.1" + "@jest/test-sequencer" "^29.5.0" + "@jest/types" "^29.5.0" + babel-jest "^29.5.0" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.4.1" - jest-environment-node "^29.4.1" - jest-get-type "^29.2.0" - jest-regex-util "^29.2.0" - jest-resolve "^29.4.1" - jest-runner "^29.4.1" - jest-util "^29.4.1" - jest-validate "^29.4.1" + jest-circus "^29.5.0" + jest-environment-node "^29.5.0" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-runner "^29.5.0" + jest-util "^29.5.0" + jest-validate "^29.5.0" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.4.1" + pretty-format "^29.5.0" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^25.2.1: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" - integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== - dependencies: - chalk "^3.0.0" - diff-sequences "^25.2.6" - jest-get-type "^25.2.6" - pretty-format "^25.5.0" - -jest-diff@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.1.tgz#9a6dc715037e1fa7a8a44554e7d272088c4029bd" - integrity sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw== +jest-diff@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" + integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== dependencies: chalk "^4.0.0" - diff-sequences "^29.3.1" - jest-get-type "^29.2.0" - pretty-format "^29.4.1" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-docblock@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" - integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== dependencies: detect-newline "^3.0.0" -jest-each@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.1.tgz#05ce9979e7486dbd0f5d41895f49ccfdd0afce01" - integrity sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ== +jest-each@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.5.0.tgz#fc6e7014f83eac68e22b7195598de8554c2e5c06" + integrity sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" chalk "^4.0.0" - jest-get-type "^29.2.0" - jest-util "^29.4.1" - pretty-format "^29.4.1" + jest-get-type "^29.4.3" + jest-util "^29.5.0" + pretty-format "^29.5.0" -jest-environment-jsdom@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.4.1.tgz#34d491244ddd6fe3d666da603b576bd0ae6aef78" - integrity sha512-+KfYmRTl5CBHQst9hIz77TiiriHYvuWoLjMT855gx2AMxhHxpk1vtKvag1DQfyWCPVTWV/AG7SIqVh5WI1O/uw== +jest-environment-jsdom@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.5.0.tgz#cfe86ebaf1453f3297b5ff3470fbe94739c960cb" + integrity sha512-/KG8yEK4aN8ak56yFVdqFDzKNHgF4BAymCx2LbPNPsUshUlfAl0eX402Xm1pt+eoG9SLZEUVifqXtX8SK74KCw== dependencies: - "@jest/environment" "^29.4.1" - "@jest/fake-timers" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/jsdom" "^20.0.0" "@types/node" "*" - jest-mock "^29.4.1" - jest-util "^29.4.1" + jest-mock "^29.5.0" + jest-util "^29.5.0" jsdom "^20.0.0" -jest-environment-node@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.1.tgz#22550b7d0f8f0b16228639c9f88ca04bbf3c1974" - integrity sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg== +jest-environment-node@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" + integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== dependencies: - "@jest/environment" "^29.4.1" - "@jest/fake-timers" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-mock "^29.4.1" - jest-util "^29.4.1" + jest-mock "^29.5.0" + jest-util "^29.5.0" -jest-get-type@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" - integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== +jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== -jest-get-type@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" - integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== - -jest-haste-map@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.1.tgz#b0579dc82d94b40ed9041af56ad25c2f80bedaeb" - integrity sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w== +jest-haste-map@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.5.0.tgz#69bd67dc9012d6e2723f20a945099e972b2e94de" + integrity sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^29.2.0" - jest-util "^29.4.1" - jest-worker "^29.4.1" + jest-regex-util "^29.4.3" + jest-util "^29.5.0" + jest-worker "^29.5.0" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz#632186c546e084da2b490b7496fee1a1c9929637" - integrity sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ== +jest-leak-detector@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz#cf4bdea9615c72bac4a3a7ba7e7930f9c0610c8c" + integrity sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow== dependencies: - jest-get-type "^29.2.0" - pretty-format "^29.4.1" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-matcher-utils@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz#73d834e305909c3b43285fbc76f78bf0ad7e1954" - integrity sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA== +jest-matcher-utils@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" + integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== dependencies: chalk "^4.0.0" - jest-diff "^29.4.1" - jest-get-type "^29.2.0" - pretty-format "^29.4.1" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + pretty-format "^29.5.0" -jest-message-util@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.1.tgz#522623aa1df9a36ebfdffb06495c7d9d19e8a845" - integrity sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ== +jest-message-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" + integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.4.1" + pretty-format "^29.5.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.1.tgz#a218a2abf45c99c501d4665207748a6b9e29afbd" - integrity sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ== +jest-mock@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" + integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@types/node" "*" - jest-util "^29.4.1" + jest-util "^29.5.0" jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== -jest-regex-util@^29.2.0: - version "29.2.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" - integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== -jest-resolve-dependencies@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz#02420a2e055da105e5fca8218c471d8b9553c904" - integrity sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg== +jest-resolve-dependencies@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz#f0ea29955996f49788bf70996052aa98e7befee4" + integrity sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg== dependencies: - jest-regex-util "^29.2.0" - jest-snapshot "^29.4.1" + jest-regex-util "^29.4.3" + jest-snapshot "^29.5.0" -jest-resolve@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.1.tgz#4c6bf71a07b8f0b79c5fdf4f2a2cf47317694c5e" - integrity sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ== +jest-resolve@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.5.0.tgz#b053cc95ad1d5f6327f0ac8aae9f98795475ecdc" + integrity sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.4.1" + jest-haste-map "^29.5.0" jest-pnp-resolver "^1.2.2" - jest-util "^29.4.1" - jest-validate "^29.4.1" + jest-util "^29.5.0" + jest-validate "^29.5.0" resolve "^1.20.0" resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.1.tgz#57460d9ebb0eea2e27eeddca1816cf8537469661" - integrity sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg== +jest-runner@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.5.0.tgz#6a57c282eb0ef749778d444c1d758c6a7693b6f8" + integrity sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ== dependencies: - "@jest/console" "^29.4.1" - "@jest/environment" "^29.4.1" - "@jest/test-result" "^29.4.1" - "@jest/transform" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/console" "^29.5.0" + "@jest/environment" "^29.5.0" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.2.0" - jest-environment-node "^29.4.1" - jest-haste-map "^29.4.1" - jest-leak-detector "^29.4.1" - jest-message-util "^29.4.1" - jest-resolve "^29.4.1" - jest-runtime "^29.4.1" - jest-util "^29.4.1" - jest-watcher "^29.4.1" - jest-worker "^29.4.1" + jest-docblock "^29.4.3" + jest-environment-node "^29.5.0" + jest-haste-map "^29.5.0" + jest-leak-detector "^29.5.0" + jest-message-util "^29.5.0" + jest-resolve "^29.5.0" + jest-runtime "^29.5.0" + jest-util "^29.5.0" + jest-watcher "^29.5.0" + jest-worker "^29.5.0" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.1.tgz#9a50f9c69d3a391690897c01b0bfa8dc5dd45808" - integrity sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA== +jest-runtime@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.5.0.tgz#c83f943ee0c1da7eb91fa181b0811ebd59b03420" + integrity sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw== dependencies: - "@jest/environment" "^29.4.1" - "@jest/fake-timers" "^29.4.1" - "@jest/globals" "^29.4.1" - "@jest/source-map" "^29.2.0" - "@jest/test-result" "^29.4.1" - "@jest/transform" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/environment" "^29.5.0" + "@jest/fake-timers" "^29.5.0" + "@jest/globals" "^29.5.0" + "@jest/source-map" "^29.4.3" + "@jest/test-result" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.4.1" - jest-message-util "^29.4.1" - jest-mock "^29.4.1" - jest-regex-util "^29.2.0" - jest-resolve "^29.4.1" - jest-snapshot "^29.4.1" - jest-util "^29.4.1" - semver "^7.3.5" + jest-haste-map "^29.5.0" + jest-message-util "^29.5.0" + jest-mock "^29.5.0" + jest-regex-util "^29.4.3" + jest-resolve "^29.5.0" + jest-snapshot "^29.5.0" + jest-util "^29.5.0" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.1.tgz#5692210b3690c94f19317913d4082b123bd83dd9" - integrity sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA== +jest-snapshot@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.5.0.tgz#c9c1ce0331e5b63cd444e2f95a55a73b84b1e8ce" + integrity sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" @@ -6763,61 +8013,60 @@ jest-snapshot@^29.4.1: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.4.1" - "@jest/transform" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/expect-utils" "^29.5.0" + "@jest/transform" "^29.5.0" + "@jest/types" "^29.5.0" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.4.1" + expect "^29.5.0" graceful-fs "^4.2.9" - jest-diff "^29.4.1" - jest-get-type "^29.2.0" - jest-haste-map "^29.4.1" - jest-matcher-utils "^29.4.1" - jest-message-util "^29.4.1" - jest-util "^29.4.1" + jest-diff "^29.5.0" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.5.0" + jest-message-util "^29.5.0" + jest-util "^29.5.0" natural-compare "^1.4.0" - pretty-format "^29.4.1" + pretty-format "^29.5.0" semver "^7.3.5" -jest-util@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.1.tgz#2eeed98ff4563b441b5a656ed1a786e3abc3e4c4" - integrity sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ== +jest-util@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" + integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.1.tgz#0d5174510415083ec329d4f981bf6779211f17e9" - integrity sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw== +jest-validate@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.5.0.tgz#8e5a8f36178d40e47138dc00866a5f3bd9916ffc" + integrity sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ== dependencies: - "@jest/types" "^29.4.1" + "@jest/types" "^29.5.0" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.2.0" + jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^29.4.1" + pretty-format "^29.5.0" -jest-watcher@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.1.tgz#6e3e2486918bd778849d4d6e67fd77b814f3e6ed" - integrity sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw== +jest-watcher@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.5.0.tgz#cf7f0f949828ba65ddbbb45c743a382a4d911363" + integrity sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA== dependencies: - "@jest/test-result" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/test-result" "^29.5.0" + "@jest/types" "^29.5.0" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.4.1" + jest-util "^29.5.0" string-length "^4.0.1" jest-worker@^26.2.1, jest-worker@^26.5.0: @@ -6829,37 +8078,48 @@ jest-worker@^26.2.1, jest-worker@^26.5.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jest-worker@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.1.tgz#7cb4a99a38975679600305650f86f4807460aab1" - integrity sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ== +jest-worker@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.5.0.tgz#bdaefb06811bd3384d93f009755014d8acb4615d" + integrity sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA== dependencies: "@types/node" "*" - jest-util "^29.4.1" + jest-util "^29.5.0" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.1.tgz#bb34baca8e05901b49c02c62f1183a6182ea1785" - integrity sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg== +jest@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.5.0.tgz#f75157622f5ce7ad53028f2f8888ab53e1f1f24e" + integrity sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ== dependencies: - "@jest/core" "^29.4.1" - "@jest/types" "^29.4.1" + "@jest/core" "^29.5.0" + "@jest/types" "^29.5.0" import-local "^3.0.2" - jest-cli "^29.4.1" + jest-cli "^29.5.0" -js-sdsl@^4.1.4: - version "4.3.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" - integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== +jpeg-autorotate@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/jpeg-autorotate/-/jpeg-autorotate-7.1.1.tgz#c57905c6afd3b54373a6a1d0249ed6e07f7b043b" + integrity sha512-ewTZTG/QWOM0D5h/yKcQ3QgyrnQYsr3qmcS+bqoAwgQAY1KBa31aJ+q+FlElaxo/rSYqfF1ixf+8EIgluBkgTg== + dependencies: + colors "^1.4.0" + glob "^7.1.6" + jpeg-js "^0.4.2" + piexifjs "^1.0.6" + yargs-parser "^20.2.1" + +jpeg-js@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa" + integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: +js-yaml@^3.13.1, js-yaml@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -6874,6 +8134,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsdoc-type-pratt-parser@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114" + integrity sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ== + jsdom@^20.0.0: version "20.0.3" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" @@ -6906,27 +8171,24 @@ jsdom@^20.0.0: ws "^8.11.0" xml-name-validator "^4.0.0" -jsdom@^21.1.0: - version "21.1.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-21.1.0.tgz#d56ba4a84ed478260d83bd53dc181775f2d8e6ef" - integrity sha512-m0lzlP7qOtthD918nenK3hdItSd2I+V3W9IrBcB36sqDwG+KnUs66IF5GY7laGWUnlM9vTsD0W1QwSEBYWWcJg== +jsdom@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-22.1.0.tgz#0fca6d1a37fbeb7f4aac93d1090d782c56b611c8" + integrity sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw== dependencies: abab "^2.0.6" - acorn "^8.8.1" - acorn-globals "^7.0.0" - cssom "^0.5.0" - cssstyle "^2.3.0" - data-urls "^3.0.2" - decimal.js "^10.4.2" + cssstyle "^3.0.0" + data-urls "^4.0.0" + decimal.js "^10.4.3" domexception "^4.0.0" - escodegen "^2.0.0" form-data "^4.0.0" html-encoding-sniffer "^3.0.0" http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.1" is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.2" - parse5 "^7.1.1" + nwsapi "^2.2.4" + parse5 "^7.1.2" + rrweb-cssom "^0.6.0" saxes "^6.0.0" symbol-tree "^3.2.4" tough-cookie "^4.1.2" @@ -6934,8 +8196,8 @@ jsdom@^21.1.0: webidl-conversions "^7.0.0" whatwg-encoding "^2.0.0" whatwg-mimetype "^3.0.0" - whatwg-url "^11.0.0" - ws "^8.11.0" + whatwg-url "^12.0.1" + ws "^8.13.0" xml-name-validator "^4.0.0" jsesc@^2.5.1: @@ -6946,7 +8208,7 @@ jsesc@^2.5.1: jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" @@ -6976,21 +8238,16 @@ json-schema@^0.4.0: json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz#e06f23128e0bbe342dc996ed5a19e28b57b580e0" + integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== dependencies: - jsonify "~0.0.0" + jsonify "^0.0.1" -json3@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - -json5@^1.0.1: +json5@^1.0.1, json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== @@ -7002,13 +8259,6 @@ json5@^2.1.2, json5@^2.2.0, json5@^2.2.2: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -7018,15 +8268,15 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== jsonpointer@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" - integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: version "3.3.3" @@ -7037,9 +8287,9 @@ jsonpointer@^5.0.0: object.assign "^4.1.3" keycode@^2.1.7: - version "2.2.0" - resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04" - integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ= + version "2.2.1" + resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.1.tgz#09c23b2be0611d26117ea2501c2c391a01f39eff" + integrity sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg== killable@^1.0.1: version "1.0.1" @@ -7057,19 +8307,19 @@ kleur@^3.0.3: integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== klona@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" - integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== -known-css-properties@^0.26.0: - version "0.26.0" - resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.26.0.tgz#008295115abddc045a9f4ed7e2a84dc8b3a77649" - integrity sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg== +known-css-properties@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.27.0.tgz#82a9358dda5fe7f7bd12b5e7142c0a205393c0c5" + integrity sha512-uMCj6+hZYDoffuvAJjFAPz56E9uoowFHmTkqRtRq5WyC5Q6Cu/fTZKNQpX/RbzChBYLLl3lo8CjFZBAZXq9qFg== language-subtag-registry@~0.3.2: - version "0.3.20" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz#a00a37121894f224f763268e431c55556b0c0755" - integrity sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg== + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== language-tags@=1.0.5: version "1.0.5" @@ -7078,6 +8328,14 @@ language-tags@=1.0.5: dependencies: language-subtag-registry "~0.3.2" +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -7094,15 +8352,53 @@ levn@^0.4.1: levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" +lilconfig@2.1.0, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lint-staged@^13.2.2: + version "13.2.2" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.2.2.tgz#5e711d3139c234f73402177be2f8dd312e6508ca" + integrity sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA== + dependencies: + chalk "5.2.0" + cli-truncate "^3.1.0" + commander "^10.0.0" + debug "^4.3.4" + execa "^7.0.0" + lilconfig "2.1.0" + listr2 "^5.0.7" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-inspect "^1.12.3" + pidtree "^0.6.0" + string-argv "^0.3.1" + yaml "^2.2.2" + +listr2@^5.0.7: + version "5.0.8" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" + integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.19" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.8.0" + through "^2.3.8" + wrap-ansi "^7.0.0" loader-runner@^2.4.0: version "2.4.0" @@ -7119,9 +8415,9 @@ loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: json5 "^1.0.1" loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -7159,42 +8455,37 @@ lockfile@^1.0: lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= - -lodash.defaults@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.get@^4.0: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== lodash.has@^4.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" - integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI= + integrity sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g== lodash.isboolean@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== lodash.isobject@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" - integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0= + integrity sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA== lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== lodash.merge@^4.6.2: version "4.6.2" @@ -7204,27 +8495,37 @@ lodash.merge@^4.6.2: lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + loglevel@^1.6.8: - version "1.7.0" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.0.tgz#728166855a740d59d38db01cf46f042caa041bb0" - integrity sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ== + version "1.8.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.1.tgz#5c621f83d5b48c54ae93b6156353f555963377b4" + integrity sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" @@ -7247,10 +8548,15 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lz-string@^1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" - integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" + integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== + +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== magic-string@^0.25.0, magic-string@^0.25.7: version "0.25.9" @@ -7259,6 +8565,13 @@ magic-string@^0.25.0, magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.8" +magic-string@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.0.tgz#fd58a4748c5c4547338a424e90fa5dd17f4de529" + integrity sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.13" + make-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -7284,14 +8597,14 @@ makeerror@1.0.12: map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== -map-obj@^4.0.0: +map-obj@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== @@ -7299,14 +8612,14 @@ map-obj@^4.0.0: map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== dependencies: object-visit "^1.0.0" mark-loader@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/mark-loader/-/mark-loader-0.1.6.tgz#0abb477dca7421d70e20128ff6489f5cae8676d5" - integrity sha1-CrtHfcp0IdcOIBKP9kifXK6GdtU= + integrity sha512-eEhrlUX2D44vADzgo2xKTyWTf3vyiGTApvxtOKHx8+CVepdzNXaMZS7cg+LlaigsIACpTEudChSHGE6noDGy/A== marky@^1.2.5: version "1.2.5" @@ -7327,20 +8640,30 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== -mdn-data@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" - integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memoize-one@^6.0.0: version "6.0.0" @@ -7350,7 +8673,7 @@ memoize-one@^6.0.0: memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== dependencies: errno "^0.1.3" readable-stream "^2.0.1" @@ -7363,28 +8686,28 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -meow@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364" - integrity sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ== +meow@^10.1.5: + version "10.1.5" + resolved "https://registry.yarnpkg.com/meow/-/meow-10.1.5.tgz#be52a1d87b5f5698602b0f32875ee5940904aa7f" + integrity sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw== dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize "^1.2.0" + "@types/minimist" "^1.2.2" + camelcase-keys "^7.0.0" + decamelize "^5.0.0" decamelize-keys "^1.1.0" hard-rejection "^2.1.0" minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" + normalize-package-data "^3.0.2" + read-pkg-up "^8.0.0" + redent "^4.0.0" + trim-newlines "^4.0.2" + type-fest "^1.2.2" + yargs-parser "^20.2.9" merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== merge-stream@^2.0.0: version "2.0.0" @@ -7399,7 +8722,7 @@ merge2@^1.3.0, merge2@^1.4.1: methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" @@ -7453,21 +8776,36 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.3.1, mime@^2.4.4: - version "2.4.7" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74" - integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA== +mime@^2.4.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -min-indent@^1.0.0: +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +mini-css-extract-plugin@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" + integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A== + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + schema-utils "^1.0.0" + webpack-sources "^1.1.0" + mini-css-extract-plugin@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8" @@ -7485,9 +8823,9 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7495,9 +8833,16 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: brace-expansion "^1.1.7" minimatch@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== dependencies: brace-expansion "^2.0.1" @@ -7510,10 +8855,10 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minipass-collect@^1.0.2: version "1.0.2" @@ -7537,12 +8882,22 @@ minipass-pipeline@^1.2.2: minipass "^3.0.0" minipass@^3.0.0, minipass@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== dependencies: yallist "^4.0.0" +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.2.tgz#58a82b7d81c7010da5bd4b2c0c85ac4b4ec5131e" + integrity sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA== + minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -7575,22 +8930,22 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== +mkdirp@^0.5, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.6, mkdirp@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: - minimist "^1.2.5" + minimist "^1.2.6" mkdirp@^1.0, mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.3.tgz#b083ff37be046fd3d6552468c1f0ff44c1545d1f" - integrity sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw== +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== mousetrap@^1.5.2: version "1.6.5" @@ -7600,7 +8955,7 @@ mousetrap@^1.5.2: move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== dependencies: aproba "^1.1.1" copy-concurrently "^1.0.0" @@ -7609,10 +8964,15 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" +mrmime@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" + integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== ms@2.1.2: version "2.1.2" @@ -7627,7 +8987,7 @@ ms@2.1.3, ms@^2.1.1: multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= + integrity sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ== multicast-dns@^6.0.1: version "6.2.3" @@ -7638,14 +8998,14 @@ multicast-dns@^6.0.1: thunky "^1.0.2" nan@^2.12.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + version "2.17.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== nanomatch@^1.2.9: version "1.2.13" @@ -7664,10 +9024,15 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.3: version "0.6.3" @@ -7679,20 +9044,15 @@ neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== node-fetch@^2.6.0: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + version "2.6.11" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" + integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== dependencies: whatwg-url "^5.0.0" @@ -7702,14 +9062,14 @@ node-forge@^0.10.0: integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-gyp-build@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" - integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + version "4.6.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== node-libs-browser@^2.2.1: version "2.2.1" @@ -7740,22 +9100,12 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.12: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^3.0.0: +normalize-package-data@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== @@ -7768,7 +9118,7 @@ normalize-package-data@^3.0.0: normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== dependencies: remove-trailing-separator "^1.0.1" @@ -7780,7 +9130,17 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: normalize-range@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +normalize-url@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ== + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" normalize-url@^3.0.0: version "3.3.0" @@ -7790,7 +9150,7 @@ normalize-url@^3.0.0: npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== dependencies: path-key "^2.0.0" @@ -7801,6 +9161,13 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + npmlog@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-7.0.1.tgz#7372151a01ccb095c47d8bf1d0771a4ff1f53ac8" @@ -7818,44 +9185,43 @@ nth-check@^1.0.2: dependencies: boolbase "~1.0.0" +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== -nwsapi@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== +nwsapi@^2.2.2, nwsapi@^2.2.4: + version "2.2.5" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.5.tgz#a52744c61b3889dd44b0a158687add39b8d935e2" + integrity sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ== -object-assign@^4.0.1, object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== -object-is@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.3.tgz#2e3b9e65560137455ee3bd62aec4d90a2ea1cc81" - integrity sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - -object-is@^1.1.5: +object-is@^1.0.1, object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -7871,11 +9237,11 @@ object-keys@^1.1.1: object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== dependencies: isobject "^3.0.0" -object.assign@^4.1.3, object.assign@^4.1.4: +object.assign@^4.1.0, object.assign@^4.1.3, object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -7904,12 +9270,15 @@ object.fromentries@^2.0.6: es-abstract "^1.20.4" object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + version "2.1.6" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz#5e5c384dd209fa4efffead39e3a0512770ccc312" + integrity sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ== dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + array.prototype.reduce "^1.0.5" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.21.2" + safe-array-concat "^1.0.0" object.hasown@^1.1.2: version "1.1.2" @@ -7922,7 +9291,7 @@ object.hasown@^1.1.2: object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== dependencies: isobject "^3.0.1" @@ -7935,7 +9304,7 @@ object.values@^1.1.0, object.values@^1.1.6: define-properties "^1.1.4" es-abstract "^1.20.4" -obuf@^1.0.0, obuf@^1.1.2: +obuf@^1.0.0, obuf@^1.1.2, obuf@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== @@ -7955,17 +9324,34 @@ on-headers@~1.0.2: once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -onetime@^5.1.2: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + opencollective-postinstall@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" @@ -7983,6 +9369,14 @@ opn@^5.5.0: dependencies: is-wsl "^1.1.0" +optimize-css-assets-webpack-plugin@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.8.tgz#cbccdcf5a6ef61d4f8cc78cf083a67446e5f402a" + integrity sha512-mgFS1JdOtEGzD8l+EuISqL57cKO+We9GcoiQEmdCWRqqck+FGNmYJtx9qfAPzEz+lRrlThWMuGDaRkI/yWNx/Q== + dependencies: + cssnano "^4.1.10" + last-call-webpack-plugin "^3.0.0" + optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -8007,22 +9401,15 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -original@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== - dependencies: - url-parse "^1.4.3" - os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" @@ -8123,7 +9510,7 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" @@ -8141,12 +9528,12 @@ parse-json@^5.0.0, parse-json@^5.2.0: parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== -parse5@^7.0.0, parse5@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.1.tgz#4649f940ccfb95d8754f37f73078ea20afe0c746" - integrity sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg== +parse5@^7.0.0, parse5@^7.1.1, parse5@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== dependencies: entities "^4.4.0" @@ -8158,7 +9545,7 @@ parseurl@~1.3.2, parseurl@~1.3.3: pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== path-browserify@0.0.1: version "0.0.1" @@ -8173,12 +9560,12 @@ path-complete-extname@^1.0.0: path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" @@ -8188,37 +9575,50 @@ path-exists@^4.0.0: path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== path-to-regexp@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" - integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== dependencies: isarray "0.0.1" @@ -8228,9 +9628,9 @@ path-type@^4.0.0: integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -8241,32 +9641,42 @@ pbkdf2@^3.0.3: performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= + integrity sha512-YHk5ez1hmMR5LOkb9iJkLKqoBlL7WD5M8ljC75ZfzXriuBIVNuecaXuU7e+hOwyqf24Wxhh7Vxgt7Hnw9288Tg== performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -pg-connection-string@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10" - integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ== +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + +pg-connection-string@^2.6.0, pg-connection-string@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.1.tgz#78c23c21a35dd116f48e12e23c0965e8d9e2cbfb" + integrity sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg== pg-int8@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== -pg-pool@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.2.2.tgz#a560e433443ed4ad946b84d774b3f22452694dff" - integrity sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA== +pg-numeric@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" + integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== -pg-protocol@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.4.0.tgz#43a71a92f6fe3ac559952555aa3335c8cb4908be" - integrity sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA== +pg-pool@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7" + integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== + +pg-protocol@*, pg-protocol@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" + integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== pg-types@^2.1.0: version "2.2.0" @@ -8279,25 +9689,40 @@ pg-types@^2.1.0: postgres-date "~1.0.4" postgres-interval "^1.1.0" +pg-types@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-4.0.1.tgz#31857e89d00a6c66b06a14e907c3deec03889542" + integrity sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g== + dependencies: + pg-int8 "1.0.1" + pg-numeric "1.0.2" + postgres-array "~3.0.1" + postgres-bytea "~3.0.0" + postgres-date "~2.0.1" + postgres-interval "^3.0.0" + postgres-range "^1.1.1" + pg@^8.5.0: - version "8.5.1" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.5.1.tgz#34dcb15f6db4a29c702bf5031ef2e1e25a06a120" - integrity sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw== + version "8.11.1" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.1.tgz#297e0eb240306b1e9e4f55af8a3bae76ae4810b1" + integrity sha512-utdq2obft07MxaDg0zBJI+l/M3mBRfIpEN3iSemsz0G5F2/VXx+XzqF4oxrbIZXQxt2AZzIUzyVg/YM6xOP/WQ== dependencies: buffer-writer "2.0.0" packet-reader "1.0.0" - pg-connection-string "^2.4.0" - pg-pool "^3.2.2" - pg-protocol "^1.4.0" + pg-connection-string "^2.6.1" + pg-pool "^3.6.1" + pg-protocol "^1.6.0" pg-types "^2.1.0" pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" pgpass@1.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.4.tgz#85eb93a83800b20f8057a2b029bf05abaf94ea9c" - integrity sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w== + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== dependencies: - split2 "^3.1.1" + split2 "^4.1.0" picocolors@^0.2.1: version "0.2.1" @@ -8314,10 +9739,20 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatc resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.0.0: +pidtree@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + +piexifjs@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/piexifjs/-/piexifjs-1.0.6.tgz#883811d73f447218d0d06e9ed7866d04533e59e0" + integrity sha512-0wVyH0cKohzBQ5Gi2V1BuxYpxWfxF3cSqfFXfPIpl5tl9XLS5z4ogqhUCD20AbHi0h9aJkqXNJnkVev6gwh2ag== + +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== pify@^4.0.1: version "4.0.1" @@ -8327,19 +9762,19 @@ pify@^4.0.1: pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== pirates@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" - integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pkg-dir@^3.0.0: version "3.0.0" @@ -8355,29 +9790,94 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -portfinder@^1.0.26: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== +pnp-webpack-plugin@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9" + integrity sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg== dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" + ts-pnp "^1.1.6" + +portfinder@^1.0.26: + version "1.0.32" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" + integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== + dependencies: + async "^2.6.4" + debug "^3.2.7" + mkdirp "^0.5.6" posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + +postcss-attribute-case-insensitive@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" + integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^6.0.2" postcss-calc@^7.0.1: - version "7.0.4" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.4.tgz#5e177ddb417341e6d4a193c5d9fd8ada79094f8b" - integrity sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw== + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.5.tgz#f8a6e99f12e619c2ebc23cf6c486fdc15860933e" + integrity sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg== dependencies: postcss "^7.0.27" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.0.2" +postcss-calc@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-9.0.1.tgz#a744fd592438a93d6de0f1434c572670361eb6c6" + integrity sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ== + dependencies: + postcss-selector-parser "^6.0.11" + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" + integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-gray@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" + integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-color-hex-alpha@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" + integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== + dependencies: + postcss "^7.0.14" + postcss-values-parser "^2.0.1" + +postcss-color-mod-function@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" + integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-color-rebeccapurple@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" + integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + postcss-colormin@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" @@ -8389,6 +9889,16 @@ postcss-colormin@^4.0.3: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-colormin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.0.0.tgz#d4250652e952e1c0aca70c66942da93d3cdeaafe" + integrity sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + postcss-convert-values@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" @@ -8397,6 +9907,45 @@ postcss-convert-values@^4.0.1: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-convert-values@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-6.0.0.tgz#ec94a954957e5c3f78f0e8f65dfcda95280b8996" + integrity sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + +postcss-custom-media@^7.0.8: + version "7.0.8" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" + integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== + dependencies: + postcss "^7.0.14" + +postcss-custom-properties@^8.0.11: + version "8.0.11" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" + integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== + dependencies: + postcss "^7.0.17" + postcss-values-parser "^2.0.1" + +postcss-custom-selectors@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" + integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + +postcss-dir-pseudo-class@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" + integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + postcss-discard-comments@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" @@ -8404,6 +9953,11 @@ postcss-discard-comments@^4.0.2: dependencies: postcss "^7.0.0" +postcss-discard-comments@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.0.tgz#9ca335e8b68919f301b24ba47dde226a42e535fe" + integrity sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw== + postcss-discard-duplicates@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" @@ -8411,6 +9965,11 @@ postcss-discard-duplicates@^4.0.2: dependencies: postcss "^7.0.0" +postcss-discard-duplicates@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.0.tgz#c26177a6c33070922e67e9a92c0fd23d443d1355" + integrity sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA== + postcss-discard-empty@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" @@ -8418,6 +9977,11 @@ postcss-discard-empty@^4.0.1: dependencies: postcss "^7.0.0" +postcss-discard-empty@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-6.0.0.tgz#06c1c4fce09e22d2a99e667c8550eb8a3a1b9aee" + integrity sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ== + postcss-discard-overridden@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" @@ -8425,6 +9989,96 @@ postcss-discard-overridden@^4.0.1: dependencies: postcss "^7.0.0" +postcss-discard-overridden@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-6.0.0.tgz#49c5262db14e975e349692d9024442de7cd8e234" + integrity sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw== + +postcss-double-position-gradients@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" + integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== + dependencies: + postcss "^7.0.5" + postcss-values-parser "^2.0.0" + +postcss-env-function@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" + integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-flexbugs-fixes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== + dependencies: + postcss "^7.0.26" + +postcss-focus-visible@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" + integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== + dependencies: + postcss "^7.0.2" + +postcss-focus-within@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" + integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== + dependencies: + postcss "^7.0.2" + +postcss-font-variant@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" + integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== + dependencies: + postcss "^7.0.2" + +postcss-gap-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" + integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== + dependencies: + postcss "^7.0.2" + +postcss-image-set-function@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" + integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-import@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" + integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== + dependencies: + postcss "^7.0.1" + postcss-value-parser "^3.2.3" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" + integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== + dependencies: + postcss "^7.0.2" + +postcss-lab-function@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" + integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + postcss-load-config@^2.0.0: version "2.1.2" resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.1.2.tgz#c5ea504f2c4aef33c7359a34de3573772ad7502a" @@ -8443,10 +10097,35 @@ postcss-loader@^3.0.0: postcss-load-config "^2.0.0" schema-utils "^1.0.0" +postcss-loader@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" + integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.4" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + semver "^7.3.4" + +postcss-logical@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" + integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== + dependencies: + postcss "^7.0.2" + +postcss-media-minmax@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" + integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== + dependencies: + postcss "^7.0.2" + postcss-media-query-parser@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" - integrity sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ= + integrity sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig== postcss-merge-longhand@^4.0.11: version "4.0.11" @@ -8458,6 +10137,14 @@ postcss-merge-longhand@^4.0.11: postcss-value-parser "^3.0.0" stylehacks "^4.0.0" +postcss-merge-longhand@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz#6f627b27db939bce316eaa97e22400267e798d69" + integrity sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^6.0.0" + postcss-merge-rules@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" @@ -8470,6 +10157,16 @@ postcss-merge-rules@^4.0.3: postcss-selector-parser "^3.0.0" vendors "^1.0.0" +postcss-merge-rules@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-6.0.1.tgz#39f165746404e646c0f5c510222ccde4824a86aa" + integrity sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + cssnano-utils "^4.0.0" + postcss-selector-parser "^6.0.5" + postcss-minify-font-values@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" @@ -8478,6 +10175,13 @@ postcss-minify-font-values@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-minify-font-values@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-6.0.0.tgz#68d4a028f9fa5f61701974724b2cc9445d8e6070" + integrity sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA== + dependencies: + postcss-value-parser "^4.2.0" + postcss-minify-gradients@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" @@ -8488,6 +10192,15 @@ postcss-minify-gradients@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-minify-gradients@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-6.0.0.tgz#22b5c88cc63091dadbad34e31ff958404d51d679" + integrity sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA== + dependencies: + colord "^2.9.1" + cssnano-utils "^4.0.0" + postcss-value-parser "^4.2.0" + postcss-minify-params@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" @@ -8500,6 +10213,15 @@ postcss-minify-params@^4.0.2: postcss-value-parser "^3.0.0" uniqs "^2.0.0" +postcss-minify-params@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-6.0.0.tgz#2b3a85a9e3b990d7a16866f430f5fd1d5961b539" + integrity sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ== + dependencies: + browserslist "^4.21.4" + cssnano-utils "^4.0.0" + postcss-value-parser "^4.2.0" + postcss-minify-selectors@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" @@ -8510,20 +10232,52 @@ postcss-minify-selectors@^4.0.2: postcss "^7.0.0" postcss-selector-parser "^3.0.0" +postcss-minify-selectors@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-6.0.0.tgz#5046c5e8680a586e5a0cad52cc9aa36d6be5bda2" + integrity sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + postcss-modules-extract-imports@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-modules-local-by-default@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-modules-scope@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" @@ -8531,6 +10285,14 @@ postcss-modules-scope@^3.0.0: dependencies: postcss-selector-parser "^6.0.4" +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + postcss-modules-values@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" @@ -8538,6 +10300,13 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" +postcss-nesting@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" + integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== + dependencies: + postcss "^7.0.2" + postcss-normalize-charset@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" @@ -8545,6 +10314,11 @@ postcss-normalize-charset@^4.0.1: dependencies: postcss "^7.0.0" +postcss-normalize-charset@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.0.tgz#36cc12457259064969fb96f84df491652a4b0975" + integrity sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ== + postcss-normalize-display-values@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" @@ -8554,6 +10328,13 @@ postcss-normalize-display-values@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-display-values@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.0.tgz#8d2961415078644d8c6bbbdaf9a2fdd60f546cd4" + integrity sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-positions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" @@ -8564,6 +10345,13 @@ postcss-normalize-positions@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-positions@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-6.0.0.tgz#25b96df99a69f8925f730eaee0be74416865e301" + integrity sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-repeat-style@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" @@ -8574,6 +10362,13 @@ postcss-normalize-repeat-style@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-repeat-style@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.0.tgz#ddf30ad8762feb5b1eb97f39f251acd7b8353299" + integrity sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-string@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" @@ -8583,6 +10378,13 @@ postcss-normalize-string@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-string@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-6.0.0.tgz#948282647a51e409d69dde7910f0ac2ff97cb5d8" + integrity sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-timing-functions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" @@ -8592,6 +10394,13 @@ postcss-normalize-timing-functions@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-timing-functions@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.0.tgz#5f13e650b8c43351989fc5de694525cc2539841c" + integrity sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-unicode@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" @@ -8601,6 +10410,14 @@ postcss-normalize-unicode@^4.0.1: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-unicode@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.0.tgz#741b3310f874616bdcf07764f5503695d3604730" + integrity sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + postcss-normalize-url@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" @@ -8611,6 +10428,13 @@ postcss-normalize-url@^4.0.1: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-url@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-6.0.0.tgz#d0a31e962a16401fb7deb7754b397a323fb650b4" + integrity sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw== + dependencies: + postcss-value-parser "^4.2.0" + postcss-normalize-whitespace@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" @@ -8619,6 +10443,13 @@ postcss-normalize-whitespace@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-normalize-whitespace@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.0.tgz#accb961caa42e25ca4179b60855b79b1f7129d4d" + integrity sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw== + dependencies: + postcss-value-parser "^4.2.0" + postcss-ordered-values@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" @@ -8628,6 +10459,87 @@ postcss-ordered-values@^4.1.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-ordered-values@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.0.tgz#374704cdff25560d44061d17ba3c6308837a3218" + integrity sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg== + dependencies: + cssnano-utils "^4.0.0" + postcss-value-parser "^4.2.0" + +postcss-overflow-shorthand@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" + integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== + dependencies: + postcss "^7.0.2" + +postcss-page-break@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" + integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== + dependencies: + postcss "^7.0.2" + +postcss-place@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" + integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== + dependencies: + postcss "^7.0.2" + postcss-values-parser "^2.0.0" + +postcss-preset-env@^6.7.0: + version "6.7.1" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.1.tgz#26563d2e9395d626a45a836450844540694bfcef" + integrity sha512-rlRkgX9t0v2On33n7TK8pnkcYOATGQSv48J2RS8GsXhqtg+xk6AummHP88Y5mJo0TLJelBjePvSjScTNkj3+qw== + dependencies: + autoprefixer "^9.6.1" + browserslist "^4.6.4" + caniuse-lite "^1.0.30000981" + css-blank-pseudo "^0.1.4" + css-has-pseudo "^0.10.0" + css-prefers-color-scheme "^3.1.1" + cssdb "^4.4.0" + postcss "^7.0.17" + postcss-attribute-case-insensitive "^4.0.1" + postcss-color-functional-notation "^2.0.1" + postcss-color-gray "^5.0.0" + postcss-color-hex-alpha "^5.0.3" + postcss-color-mod-function "^3.0.3" + postcss-color-rebeccapurple "^4.0.1" + postcss-custom-media "^7.0.8" + postcss-custom-properties "^8.0.11" + postcss-custom-selectors "^5.1.2" + postcss-dir-pseudo-class "^5.0.0" + postcss-double-position-gradients "^1.0.0" + postcss-env-function "^2.0.2" + postcss-focus-visible "^4.0.0" + postcss-focus-within "^3.0.0" + postcss-font-variant "^4.0.0" + postcss-gap-properties "^2.0.0" + postcss-image-set-function "^3.0.1" + postcss-initial "^3.0.0" + postcss-lab-function "^2.0.1" + postcss-logical "^3.0.0" + postcss-media-minmax "^4.0.0" + postcss-nesting "^7.0.0" + postcss-overflow-shorthand "^2.0.0" + postcss-page-break "^2.0.0" + postcss-place "^4.0.1" + postcss-pseudo-class-any-link "^6.0.0" + postcss-replace-overflow-wrap "^3.0.0" + postcss-selector-matches "^4.0.0" + postcss-selector-not "^4.0.0" + +postcss-pseudo-class-any-link@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" + integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== + dependencies: + postcss "^7.0.2" + postcss-selector-parser "^5.0.0-rc.3" + postcss-reduce-initial@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" @@ -8638,6 +10550,14 @@ postcss-reduce-initial@^4.0.3: has "^1.0.0" postcss "^7.0.0" +postcss-reduce-initial@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz#7d16e83e60e27e2fa42f56ec0b426f1da332eca7" + integrity sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + postcss-reduce-transforms@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" @@ -8648,21 +10568,58 @@ postcss-reduce-transforms@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" +postcss-reduce-transforms@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.0.tgz#28ff2601a6d9b96a2f039b3501526e1f4d584a46" + integrity sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-replace-overflow-wrap@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" + integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== + dependencies: + postcss "^7.0.2" + postcss-resolve-nested-selector@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" - integrity sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4= + integrity sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw== + +postcss-safe-parser@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz#a6d4e48f0f37d9f7c11b2a581bf00f8ba4870b96" + integrity sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g== + dependencies: + postcss "^7.0.26" postcss-safe-parser@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1" integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ== -postcss-scss@^4.0.2, postcss-scss@^4.0.6: +postcss-scss@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.6.tgz#5d62a574b950a6ae12f2aa89b60d63d9e4432bfd" integrity sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ== +postcss-selector-matches@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" + integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + +postcss-selector-not@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" + integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== + dependencies: + balanced-match "^1.0.0" + postcss "^7.0.2" + postcss-selector-parser@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" @@ -8672,10 +10629,19 @@ postcss-selector-parser@^3.0.0: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.6: - version "6.0.11" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" - integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== +postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" + integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + dependencies: + cssesc "^2.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.13, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -8689,6 +10655,14 @@ postcss-svgo@^4.0.3: postcss-value-parser "^3.0.0" svgo "^1.0.0" +postcss-svgo@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-6.0.0.tgz#7b18742d38d4505a0455bbe70d52b49f00eaf69d" + integrity sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^3.0.2" + postcss-unique-selectors@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" @@ -8698,7 +10672,14 @@ postcss-unique-selectors@^4.0.1: postcss "^7.0.0" uniqs "^2.0.0" -postcss-value-parser@^3.0.0: +postcss-unique-selectors@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-6.0.0.tgz#c94e9b0f7bffb1203894e42294b5a1b3fb34fbe1" + integrity sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw== + dependencies: + postcss-selector-parser "^6.0.5" + +postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== @@ -8708,21 +10689,29 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.32: - version "7.0.32" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" - integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== +postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" + integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" -postcss@^8.2.15, postcss@^8.4.19, postcss@^8.4.21: - version "8.4.21" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" - integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== dependencies: - nanoid "^3.3.4" + picocolors "^0.2.1" + source-map "^0.6.1" + +postcss@^8.2.15, postcss@^8.4.24: + version "8.4.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.27.tgz#234d7e4b72e34ba5a92c29636734349e0d9c3057" + integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ== + dependencies: + nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -8731,16 +10720,33 @@ postgres-array@~2.0.0: resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== +postgres-array@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98" + integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog== + postgres-bytea@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" - integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-bytea@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089" + integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw== + dependencies: + obuf "~1.1.2" postgres-date@~1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== +postgres-date@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-2.0.1.tgz#638b62e5c33764c292d37b08f5257ecb09231457" + integrity sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw== + postgres-interval@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" @@ -8748,6 +10754,16 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +postgres-interval@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a" + integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw== + +postgres-range@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.3.tgz#9ccd7b01ca2789eb3c2e0888b3184225fa859f76" + integrity sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g== + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -8756,44 +10772,45 @@ prelude-ls@^1.2.1: prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -prettier@^2.8.3: - version "2.8.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632" - integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw== +prepend-http@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae" + integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== -pretty-format@^25.2.1, pretty-format@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" - integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== - dependencies: - "@jest/types" "^25.5.0" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" - pretty-format@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.2.tgz#9283ff8c4f581b186b2d4da461617143dca478a4" - integrity sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig== + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: - "@jest/types" "^27.0.2" - ansi-regex "^5.0.0" + ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^29.4.1: - version "29.4.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c" - integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg== +pretty-format@^29.0.0, pretty-format@^29.5.0: + version "29.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" + integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== dependencies: - "@jest/schemas" "^29.4.0" + "@jest/schemas" "^29.4.3" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -8805,29 +10822,20 @@ process-nextick-args@~2.0.0: process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= - -promise.prototype.finally@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.4.tgz#4e756a154e4db27fae24c6b18703495c31da3927" - integrity sha512-nNc3YbgMfLzqtqvO/q5DP6RR0SiHI9pUPGzyDf1q+usTwCN2kjvAnJkBb7bHe3o+fFSBPpsGMoYtaSi+LTNqng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== prompts@^2.0.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" - integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" - sisteransi "^1.0.4" + sisteransi "^1.0.5" prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" @@ -8854,12 +10862,12 @@ proxy-from-env@^1.1.0: prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== psl@^1.1.33: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== public-encrypt@^4.0.0: version "4.0.3" @@ -8898,25 +10906,25 @@ pumpify@^1.3.3: inherits "^2.0.3" pump "^2.0.0" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= - -punycode@1.4.1, punycode@^1.2.4: +punycode@1.4.1, punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +pure-rand@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" + integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== qs@6.11.0: version "6.11.0" @@ -8925,15 +10933,25 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@^6.11.0: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q== + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= - -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== querystringify@^2.1.1: version "2.2.0" @@ -8945,12 +10963,12 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -raf@^3.1.0, raf@^3.4.1: +raf@^3.1.0: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== @@ -8987,15 +11005,13 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -react-dom@^16.14.0: - version "16.14.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" - integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.19.1" + scheduler "^0.23.0" react-event-listener@^0.6.0: version "0.6.6" @@ -9007,9 +11023,9 @@ react-event-listener@^0.6.0: warning "^4.0.1" react-fast-compare@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" - integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== react-helmet@^6.1.0: version "6.1.0" @@ -9024,7 +11040,7 @@ react-helmet@^6.1.0: react-hotkeys@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-1.1.4.tgz#a0712aa2e0c03a759fd7885808598497a4dace72" - integrity sha1-oHEqouDAOnWf14hYCFmEl6TaznI= + integrity sha512-TI7YEZXl3ChOfq9MO5LohWA809hxs4pbLAPodPdFrvunLa7uk9TlMKpftnChMlAcbiqDrOGAhnGWZCMbNnd65A== dependencies: lodash.isboolean "^3.0.3" lodash.isequal "^4.5.0" @@ -9044,42 +11060,37 @@ react-immutable-pure-component@^2.2.2: resolved "https://registry.yarnpkg.com/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz#3014d3e20cd5a7a4db73b81f1f1464f4d351684b" integrity sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A== -react-intl-translations-manager@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/react-intl-translations-manager/-/react-intl-translations-manager-5.0.3.tgz#aee010ecf35975673e033ca5d7d3f4147894324d" - integrity sha512-EfBeugnOGFcdUbQyY9TqBMbuauQ8wm73ZqFr0UqCljhbXl7YDHQcVzclWFRkVmlUffzxitLQFhAZEVVeRNQSwA== +react-intl@^6.4.2: + version "6.4.4" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.4.4.tgz#14b45ce046bfbb60c0e6d392d8ddc30e9ead5a4f" + integrity sha512-/C9Sl/5//ohfkNG6AWlJuf4BhTXsbzyk93K62A4zRhSPANyOGpKZ+fWhN+TLfFd5YjDUHy+exU/09y0w1bO4Xw== dependencies: - chalk "^2.3.2" - glob "^7.1.2" - json-stable-stringify "^1.0.1" - mkdirp "^0.5.1" + "@formatjs/ecma402-abstract" "1.17.0" + "@formatjs/icu-messageformat-parser" "2.6.0" + "@formatjs/intl" "2.9.0" + "@formatjs/intl-displaynames" "6.5.0" + "@formatjs/intl-listformat" "7.4.0" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/react" "16 || 17 || 18" + hoist-non-react-statics "^3.3.2" + intl-messageformat "10.5.0" + tslib "^2.4.0" -react-intl@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.9.0.tgz#c97c5d17d4718f1575fdbd5a769f96018a3b1843" - integrity sha512-27jnDlb/d2A7mSJwrbOBnUgD+rPep+abmoJE511Tf8BnoONIAUehy/U1zZCHGO17mnOwMWxqN4qC0nW11cD6rA== - dependencies: - hoist-non-react-statics "^3.3.0" - intl-format-cache "^2.0.5" - intl-messageformat "^2.1.0" - intl-relativeformat "^2.1.0" - invariant "^2.1.1" +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0, react-is@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.6: +react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^17.0.1, react-is@^17.0.2: +react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" - integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== - react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" @@ -9101,7 +11112,7 @@ react-notification@^6.8.5: dependencies: prop-types "^15.6.2" -react-overlays@^5.2.1: +react-overlays@*, react-overlays@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-5.2.1.tgz#49dc007321adb6784e1f212403f0fb37a74ab86b" integrity sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA== @@ -9123,17 +11134,17 @@ react-redux-loading-bar@^5.0.4: prop-types "^15.7.2" react-lifecycles-compat "^3.0.4" -react-redux@^7.2.9: - version "7.2.9" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d" - integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ== +react-redux@^8.0.4: + version "8.1.1" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.1.1.tgz#8e740f3fd864a4cd0de5ba9cdc8ad39cc9e7c81a" + integrity sha512-5W0QaKtEhj+3bC0Nj0NkqkhIv8gLADH/2kYFMTHxCVqQILiWzLv6MaLuV5wJU3BQEdHKzTfcvPN0WMS6SC1oyA== dependencies: - "@babel/runtime" "^7.15.4" - "@types/react-redux" "^7.1.20" + "@babel/runtime" "^7.12.1" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/use-sync-external-store" "^0.0.3" hoist-non-react-statics "^3.3.2" - loose-envify "^1.4.0" - prop-types "^15.7.2" - react-is "^17.0.2" + react-is "^18.0.0" + use-sync-external-store "^1.0.0" react-router-dom@^4.1.1: version "4.3.1" @@ -9168,10 +11179,10 @@ react-router@^4.3.1: prop-types "^15.6.1" warning "^4.0.1" -react-select@^5.7.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.7.0.tgz#82921b38f1fcf1471a0b62304da01f2896cd8ce6" - integrity sha512-lJGiMxCa3cqnUr2Jjtg9YHsaytiZqeNOKeibv6WF5zbK/fPegZ1hg3y/9P1RZVLhqBTs0PfqQLKuAACednYGhQ== +react-select@*, react-select@^5.7.3: + version "5.7.4" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.7.4.tgz#d8cad96e7bc9d6c8e2709bdda8f4363c5dd7ea7d" + integrity sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ== dependencies: "@babel/runtime" "^7.12.0" "@emotion/cache" "^11.4.0" @@ -9183,6 +11194,14 @@ react-select@^5.7.0: react-transition-group "^4.3.0" use-isomorphic-layout-effect "^1.1.2" +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== + dependencies: + object-assign "^4.1.1" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" + react-side-effect@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a" @@ -9226,22 +11245,21 @@ react-swipeable-views@^0.14.0: react-swipeable-views-utils "^0.14.0" warning "^4.0.1" -react-test-renderer@^16.14.0: - version "16.14.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae" - integrity sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg== +react-test-renderer@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.2.0.tgz#1dd912bd908ff26da5b9fca4fd1c489b9523d37e" + integrity sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA== dependencies: - object-assign "^4.1.1" - prop-types "^15.6.2" - react-is "^16.8.6" - scheduler "^0.19.1" + react-is "^18.2.0" + react-shallow-renderer "^16.15.0" + scheduler "^0.23.0" -react-textarea-autosize@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz#4d0244d6a50caa897806b8c44abc0540a69bfc8c" - integrity sha512-YrTFaEHLgJsi8sJVYHBzYn+mkP3prGkmP2DKb/tm0t7CLJY5t1Rxix8070LAKb0wby7bl/lf2EeHkuMihMZMwQ== +react-textarea-autosize@*, react-textarea-autosize@^8.4.1: + version "8.5.2" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.5.2.tgz#6421df2b5b50b9ca8c5e96fd31be688ea7fa2f9d" + integrity sha512-uOkyjkEl0ByEK21eCJMHDGBAAd/BoFQBawYK5XItjAmCTeSbjxghd8qnt7nzsLYzidjnoObu6M26xts0YGKsGg== dependencies: - "@babel/runtime" "^7.10.2" + "@babel/runtime" "^7.20.13" use-composed-ref "^1.3.0" use-latest "^1.2.1" @@ -9253,47 +11271,52 @@ react-toggle@^4.1.3: classnames "^2.2.5" react-transition-group@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683" - integrity sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw== + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== dependencies: "@babel/runtime" "^7.5.5" dom-helpers "^5.0.1" loose-envify "^1.4.0" prop-types "^15.6.2" -react@^16.14.0: - version "16.14.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" - integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" + pify "^2.3.0" -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== +read-pkg-up@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-8.0.0.tgz#72f595b65e66110f43b052dd9af4de6b10534670" + integrity sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ== + dependencies: + find-up "^5.0.0" + read-pkg "^6.0.0" + type-fest "^1.0.1" + +read-pkg@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-6.0.0.tgz#a67a7d6a1c2b0c3cd6aa2ea521f40c458a4a504c" + integrity sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q== dependencies: "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" + normalize-package-data "^3.0.2" + parse-json "^5.2.0" + type-fest "^1.0.1" "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -9303,19 +11326,19 @@ read-pkg@^5.2.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.0, readable-stream@^3.0.6, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== +readable-stream@^3.0.6, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" readable-stream@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.2.0.tgz#a7ef523d3b39e4962b0db1a1af22777b10eeca46" - integrity sha512-gJrBHsaI3lgBoGMW/jHZsQ/o/TIWiu5ENCJG1BB7fuCKzpFM8GaS2UoBVt9NO+oI+3FcrBNbUkl3ilDe09aY4A== + version "4.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.4.0.tgz#55ce132d60a988c460d75c631e9ccf6a7229b468" + integrity sha512-kDMOq0qLtxV9f/SQv522h8cxZBqNZXuXNyjyezmfAAuribMyVXziljpQ/uQhfE1XLg2/TLTW2DsnoE4VAi/krg== dependencies: abort-controller "^3.0.0" buffer "^6.0.3" @@ -9331,10 +11354,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" @@ -9346,34 +11369,30 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -redis-errors@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" - integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= - -redis-parser@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" - integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= +redent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-4.0.0.tgz#0c0ba7caabb24257ab3bb7a4fd95dd1d5c5681f9" + integrity sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag== dependencies: - redis-errors "^1.0.0" + indent-string "^5.0.0" + strip-indent "^4.0.0" -"redis@^4.0.6 <4.1.0": - version "4.0.6" - resolved "https://registry.yarnpkg.com/redis/-/redis-4.0.6.tgz#a2ded4d9f4f4bad148e54781051618fc684cd858" - integrity sha512-IaPAxgF5dV0jx+A9l6yd6R9/PAChZIoAskDVRzUODeLDNhsMlq7OLLTmu0AwAr0xjrJ1bibW5xdpRwqIQ8Q0Xg== +redis@^4.6.5: + version "4.6.7" + resolved "https://registry.yarnpkg.com/redis/-/redis-4.6.7.tgz#c73123ad0b572776223f172ec78185adb72a6b57" + integrity sha512-KrkuNJNpCwRm5vFJh0tteMxW8SaUzkm5fBH7eL5hd/D0fAkzvapxbfGPP/r+4JAXdQuX7nebsBkBqA2RHB7Usw== dependencies: - "@node-redis/bloom" "1.0.1" - "@node-redis/client" "1.0.5" - "@node-redis/graph" "1.0.0" - "@node-redis/json" "1.0.2" - "@node-redis/search" "1.0.5" - "@node-redis/time-series" "1.0.2" + "@redis/bloom" "1.2.0" + "@redis/client" "1.5.8" + "@redis/graph" "1.1.0" + "@redis/json" "1.0.4" + "@redis/search" "1.1.3" + "@redis/time-series" "1.0.4" redux-immutable@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/redux-immutable/-/redux-immutable-4.0.0.tgz#3a1a32df66366462b63691f0e1dc35e472bbc9f3" - integrity sha1-Ohoy32Y2ZGK2NpHw4dw15HK7yfM= + integrity sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg== redux-thunk@^2.4.2: version "2.4.2" @@ -9387,10 +11406,10 @@ redux@^4.0.0, redux@^4.2.1: dependencies: "@babel/runtime" "^7.9.2" -regenerate-unicode-properties@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" - integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== dependencies: regenerate "^1.4.2" @@ -9404,15 +11423,15 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: +regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.9: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== dependencies: "@babel/runtime" "^7.8.4" @@ -9424,68 +11443,58 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regexpu-core@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" - integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== +regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== dependencies: + "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" - regenerate-unicode-properties "^10.0.1" - regjsgen "^0.6.0" - regjsparser "^0.8.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" -regjsgen@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" - integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== - -regjsparser@^0.8.2: - version "0.8.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" - integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== dependencies: jsesc "~0.5.0" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== requestidlecallback@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/requestidlecallback/-/requestidlecallback-0.3.0.tgz#6fb74e0733f90df3faa4838f9f6a2a5f9b742ac5" - integrity sha1-b7dOBzP5DfP6pIOPn2oqX5t0KsU= + integrity sha512-TWHFkT7S9p7IxLC5A1hYmAYQx2Eb9w1skrXmQ+dS1URyvR8tenMLl4lHbqEOUnpEYxNKpkVMXUgknVpBZWXXfQ== require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" @@ -9500,22 +11509,22 @@ require-main-filename@^2.0.0: require-package-name@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" - integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk= + integrity sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q== requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -reselect@^4.1.7: - version "4.1.7" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.7.tgz#56480d9ff3d3188970ee2b76527bd94a95567a42" - integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A== +reselect@^4.1.8: + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + integrity sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg== dependencies: resolve-from "^3.0.0" @@ -9529,7 +11538,7 @@ resolve-cwd@^3.0.0: resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== dependencies: expand-tilde "^2.0.0" global-modules "^1.0.0" @@ -9537,7 +11546,7 @@ resolve-dir@^1.0.0, resolve-dir@^1.0.1: resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= + integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== resolve-from@^4.0.0: version "4.0.0" @@ -9554,22 +11563,27 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== resolve.exports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e" - integrity sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.1.7, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.11.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -9582,6 +11596,14 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -9590,22 +11612,27 @@ ret@~0.1.10: retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + rgb-regex@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" - integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + integrity sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w== rgba-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" - integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + integrity sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg== rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" @@ -9621,10 +11648,12 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.1.2.tgz#20dfbc98083bdfaa28b01183162885ef213dbf7c" - integrity sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ== +rimraf@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.1.tgz#0881323ab94ad45fec7c0221f27ea1a142f3f0d0" + integrity sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg== + dependencies: + glob "^10.2.5" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" @@ -9645,12 +11674,24 @@ rollup-plugin-terser@^7.0.0: terser "^5.0.0" rollup@^2.43.1: - version "2.72.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.72.1.tgz#861c94790537b10008f0ca0fbc60e631aabdd045" - integrity sha512-NTc5UGy/NWFGpSqF1lFY8z9Adri6uhyMLI6LvPAXdBKoPRFhIIiBUpt+Qg2awixqO3xvzSijjhnb4+QEZwJmxA== + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== optionalDependencies: fsevents "~2.3.2" +rrweb-cssom@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz#ed298055b97cbddcdeb278f904857629dec5e0e1" + integrity sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw== + +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -9661,16 +11702,33 @@ run-parallel@^1.1.9: run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== dependencies: aproba "^1.1.1" +rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-array-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.0.tgz#2064223cba3c08d2ee05148eedbc563cd6d84060" + integrity sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9687,7 +11745,7 @@ safe-regex-test@^1.0.0: safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== dependencies: ret "~0.1.10" @@ -9696,10 +11754,10 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-loader@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.2.0.tgz#3d64c1590f911013b3fa48a0b22a83d5e1494716" - integrity sha512-kUceLzC1gIHz0zNJPpqRsJyisWatGYNFRmv2CKZK2/ngMJgLqxTbXwe/hJ85luyvZkgqU3VlJ33UVF2T/0g6mw== +sass-loader@10.1.1: + version "10.1.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" + integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw== dependencies: klona "^2.0.4" loader-utils "^2.0.0" @@ -9707,10 +11765,30 @@ sass-loader@^10.2.0: schema-utils "^3.0.0" semver "^7.3.2" -sass@^1.58.0: - version "1.58.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.58.0.tgz#ee8aea3ad5ea5c485c26b3096e2df6087d0bb1cc" - integrity sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg== +sass-loader@^10.2.0: + version "10.4.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.4.1.tgz#bea4e173ddf512c9d7f53e9ec686186146807cbf" + integrity sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ== + dependencies: + klona "^2.0.4" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + semver "^7.3.2" + +sass@^1.38.0: + version "1.63.6" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.63.6.tgz#481610e612902e0c31c46b46cf2dad66943283ea" + integrity sha512-MJuxGMHzaOW7ipp+1KdELtqKbfAWbH7OLIdoSMnVe3EXPMTmxTmlaZDCTsgIpPCs3w99lLo9/zDKkOrJuT5byw== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +sass@^1.62.1: + version "1.64.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.64.1.tgz#6a46f6d68e0fa5ad90aa59ce025673ddaa8441cf" + integrity sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -9728,13 +11806,12 @@ saxes@^6.0.0: dependencies: xmlchars "^2.2.0" -scheduler@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" - integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" schema-utils@^1.0.0: version "1.0.0" @@ -9745,7 +11822,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.2.0, schema-utils@^2.6.5: +schema-utils@^2.6.5, schema-utils@^2.7.0: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -9755,11 +11832,11 @@ schema-utils@^2.2.0, schema-utils@^2.6.5: ajv-keywords "^3.5.2" schema-utils@^3.0, schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: - "@types/json-schema" "^7.0.6" + "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" @@ -9774,29 +11851,46 @@ scroll-behavior@^0.9.1: select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== selfsigned@^1.10.8: - version "1.10.8" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" - integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w== + version "1.10.14" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.14.tgz#ee51d84d9dcecc61e07e4aba34f229ab525c1574" + integrity sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA== dependencies: node-forge "^0.10.0" -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: +semver@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: +semver@^5.6.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.1: + version "7.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" + integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + dependencies: + lru-cache "^6.0.0" + +semver@^7.5.0: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -9819,11 +11913,6 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" - integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== - serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" @@ -9841,7 +11930,7 @@ serialize-javascript@^5.0.1: serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== dependencies: accepts "~1.3.4" batch "0.6.1" @@ -9864,7 +11953,7 @@ serve-static@1.15.0: set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" @@ -9879,7 +11968,7 @@ set-value@^2.0.0, set-value@^2.0.1: setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== setprototypeof@1.1.0: version "1.1.0" @@ -9914,7 +12003,7 @@ shallow-equal@^1.2.1: shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== dependencies: shebang-regex "^1.0.0" @@ -9928,7 +12017,7 @@ shebang-command@^2.0.0: shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== shebang-regex@^3.0.0: version "3.0.0" @@ -9949,23 +12038,28 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967" + integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q== + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== dependencies: is-arrayish "^0.3.1" sirv@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.10.tgz#3e591f5a9ae2520f50d5830f5fae38d97e7be194" - integrity sha512-H5EZCoZaggEUQy8ocKsF7WAToGuZhjJlLvM3XOef46CbdIgbNeQ1p32N1PCuCjkVYwrAVOSMacN6CXXgIzuspg== + version "1.0.19" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" + integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== dependencies: - "@polka/url" "^1.0.0-next.9" - mime "^2.3.1" + "@polka/url" "^1.0.0-next.20" + mrmime "^1.0.0" totalist "^1.0.0" -sisteransi@^1.0.4: +sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== @@ -9975,6 +12069,20 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -9984,6 +12092,14 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -10015,32 +12131,38 @@ snapdragon@^0.8.1: use "^3.1.0" sockjs-client@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add" - integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q== + version "1.6.1" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.6.1.tgz#350b8eda42d6d52ddc030c39943364c11dcad806" + integrity sha512-2g0tjOR+fRs0amxENLi/q5TiJTqY+WXFOzb5UwXndlK6TO3U/mirZznpx6w34HVMoc3g7cY24yC/ZMIYnDlfkw== dependencies: - debug "^3.2.6" - eventsource "^1.0.7" - faye-websocket "^0.11.3" + debug "^3.2.7" + eventsource "^2.0.2" + faye-websocket "^0.11.4" inherits "^2.0.4" - json3 "^3.3.3" - url-parse "^1.4.7" + url-parse "^1.5.10" sockjs@^0.3.21: - version "0.3.21" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" - integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== dependencies: faye-websocket "^0.11.3" - uuid "^3.4.0" + uuid "^8.3.2" websocket-driver "^0.7.4" +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -10073,26 +12195,31 @@ source-map-support@~0.5.12, source-map-support@~0.5.20: source-map "^0.6.0" source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.8.0-beta.0, source-map@~0.8.0-beta.0: +source-map@^0.7.3: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +source-map@^0.8.0-beta.0: version "0.8.0-beta.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== @@ -10105,9 +12232,9 @@ sourcemap-codec@^1.4.8: integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -10117,7 +12244,7 @@ spdx-exceptions@^2.1.0: resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== -spdx-expression-parse@^3.0.0: +spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== @@ -10126,9 +12253,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== spdy-transport@^3.0.0: version "3.0.0" @@ -10160,17 +12287,15 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -split2@^3.1.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== ssri@^6.0.1: version "6.0.2" @@ -10179,10 +12304,10 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" - integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA== +ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== dependencies: minipass "^3.1.1" @@ -10192,31 +12317,31 @@ stable@^0.1.8: integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== stack-generator@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" - integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + version "2.0.10" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.10.tgz#8ae171e985ed62287d4f1ed55a1633b3fb53bb4d" + integrity sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ== dependencies: - stackframe "^1.1.1" + stackframe "^1.3.4" stack-utils@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" - integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" -stackframe@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" - integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== stacktrace-gps@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" - integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz#0c40b24a9b119b20da4525c398795338966a2fb0" + integrity sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ== dependencies: source-map "0.5.6" - stackframe "^1.1.1" + stackframe "^1.3.4" stacktrace-js@^2.0.2: version "2.0.2" @@ -10230,7 +12355,7 @@ stacktrace-js@^2.0.2: static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -10243,7 +12368,7 @@ statuses@2.0.1: "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== stop-iteration-iterator@^1.0.0: version "1.0.0" @@ -10284,15 +12409,26 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + +string-argv@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== + string-length@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" - integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + name string-width-cjs version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -10310,6 +12446,15 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" @@ -10324,25 +12469,41 @@ string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: regexp.prototype.flags "^1.4.3" side-channel "^1.0.4" -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" - es-abstract "^1.19.5" + es-abstract "^1.20.4" -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== dependencies: call-bind "^1.0.2" define-properties "^1.1.4" - es-abstract "^1.19.5" + es-abstract "^1.20.4" -string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@~1.1.1: +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== @@ -10365,10 +12526,18 @@ stringz@^2.1.0: dependencies: char-regex "^1.0.2" +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + name strip-ansi-cjs + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== dependencies: ansi-regex "^2.0.0" @@ -10379,17 +12548,17 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: - ansi-regex "^5.0.1" + ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: version "4.0.0" @@ -10404,13 +12573,18 @@ strip-comments@^2.0.1: strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -10418,15 +12592,30 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-loader@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.7.0" + style-search@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" - integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI= + integrity sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg== stylehacks@^4.0.0: version "4.0.3" @@ -10437,99 +12626,108 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -stylelint-config-recommended-scss@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-8.0.0.tgz#1c1e93e619fe2275d4c1067928d92e0614f7d64f" - integrity sha512-BxjxEzRaZoQb7Iinc3p92GS6zRdRAkIuEu2ZFLTxJK2e1AIcCb5B5MXY9KOXdGTnYFZ+KKx6R4Fv9zU6CtMYPQ== +stylehacks@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-6.0.0.tgz#9fdd7c217660dae0f62e14d51c89f6c01b3cb738" + integrity sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw== dependencies: - postcss-scss "^4.0.2" - stylelint-config-recommended "^9.0.0" - stylelint-scss "^4.0.0" + browserslist "^4.21.4" + postcss-selector-parser "^6.0.4" -stylelint-config-recommended@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz#1c9e07536a8cd875405f8ecef7314916d94e7e40" - integrity sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ== - -stylelint-config-standard-scss@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-6.1.0.tgz#a6cddd2a9430578b92fc89726a59474d5548a444" - integrity sha512-iZ2B5kQT2G3rUzx+437cEpdcnFOQkwnwqXuY8Z0QUwIHQVE8mnYChGAquyKFUKZRZ0pRnrciARlPaR1RBtPb0Q== +stylelint-config-recommended-scss@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-12.0.0.tgz#9d9e82c46012649f11bfebcbc788f58e61860f33" + integrity sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA== dependencies: - stylelint-config-recommended-scss "^8.0.0" - stylelint-config-standard "^29.0.0" + postcss-scss "^4.0.6" + stylelint-config-recommended "^12.0.0" + stylelint-scss "^5.0.0" -stylelint-config-standard@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz#4cc0e0f05512a39bb8b8e97853247d3a95d66fa2" - integrity sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg== - dependencies: - stylelint-config-recommended "^9.0.0" +stylelint-config-recommended@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-12.0.0.tgz#d0993232fca017065fd5acfcb52dd8a188784ef4" + integrity sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ== -stylelint-scss@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.2.0.tgz#e25fd390ee38a7e89fcfaec2a8f9dce2ec6ddee8" - integrity sha512-HHHMVKJJ5RM9pPIbgJ/XA67h9H0407G68Rm69H4fzFbFkyDMcTV1Byep3qdze5+fJ3c0U7mJrbj6S0Fg072uZA== +stylelint-config-standard-scss@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-10.0.0.tgz#159a54a01b80649bf0143fa7ba086b676a1a749e" + integrity sha512-bChBEo1p3xUVWh/wenJI+josoMk21f2yuLDGzGjmKYcALfl2u3DFltY+n4UHswYiXghqXaA8mRh+bFy/q1hQlg== + dependencies: + stylelint-config-recommended-scss "^12.0.0" + stylelint-config-standard "^33.0.0" + +stylelint-config-standard@^33.0.0: + version "33.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-33.0.0.tgz#1f7bb299153a53874073e93829e37a475842f0f9" + integrity sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg== + dependencies: + stylelint-config-recommended "^12.0.0" + +stylelint-scss@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-5.0.1.tgz#b33a6580b5734eace083cfc2cc3021225e28547f" + integrity sha512-n87iCRZrr2J7//I/QFsDXxFLnHKw633U4qvWZ+mOW6KDAp/HLj06H+6+f9zOuTYy+MdGdTuCSDROCpQIhw5fvQ== dependencies: - lodash "^4.17.21" postcss-media-query-parser "^0.2.3" postcss-resolve-nested-selector "^0.1.1" - postcss-selector-parser "^6.0.6" - postcss-value-parser "^4.1.0" + postcss-selector-parser "^6.0.13" + postcss-value-parser "^4.2.0" -stylelint@^14.16.1: - version "14.16.1" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.16.1.tgz#b911063530619a1bbe44c2b875fd8181ebdc742d" - integrity sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A== +stylelint@^15.10.1: + version "15.10.1" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-15.10.1.tgz#93f189958687e330c106b010cbec0c41dcae506d" + integrity sha512-CYkzYrCFfA/gnOR+u9kJ1PpzwG10WLVnoxHDuBA/JiwGqdM9+yx9+ou6SE/y9YHtfv1mcLo06fdadHTOx4gBZQ== dependencies: - "@csstools/selector-specificity" "^2.0.2" + "@csstools/css-parser-algorithms" "^2.3.0" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/media-query-list-parser" "^2.1.2" + "@csstools/selector-specificity" "^3.0.0" balanced-match "^2.0.0" colord "^2.9.3" - cosmiconfig "^7.1.0" + cosmiconfig "^8.2.0" css-functions-list "^3.1.0" + css-tree "^2.3.1" debug "^4.3.4" - fast-glob "^3.2.12" + fast-glob "^3.3.0" fastest-levenshtein "^1.0.16" file-entry-cache "^6.0.1" global-modules "^2.0.0" globby "^11.1.0" globjoin "^0.1.4" - html-tags "^3.2.0" - ignore "^5.2.1" + html-tags "^3.3.1" + ignore "^5.2.4" import-lazy "^4.0.0" imurmurhash "^0.1.4" is-plain-object "^5.0.0" - known-css-properties "^0.26.0" + known-css-properties "^0.27.0" mathml-tag-names "^2.1.3" - meow "^9.0.0" + meow "^10.1.5" micromatch "^4.0.5" normalize-path "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.19" - postcss-media-query-parser "^0.2.3" + postcss "^8.4.24" postcss-resolve-nested-selector "^0.1.1" postcss-safe-parser "^6.0.0" - postcss-selector-parser "^6.0.11" + postcss-selector-parser "^6.0.13" postcss-value-parser "^4.2.0" resolve-from "^5.0.0" string-width "^4.2.3" strip-ansi "^6.0.1" style-search "^0.1.0" - supports-hyperlinks "^2.3.0" + supports-hyperlinks "^3.0.0" svg-tags "^1.0.0" table "^6.8.1" - v8-compile-cache "^2.3.0" - write-file-atomic "^4.0.2" + write-file-atomic "^5.0.1" -stylis@4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" - integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== substring-trie@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/substring-trie/-/substring-trie-1.0.2.tgz#7b42592391628b4f2cb17365c6cce4257c7b7af5" - integrity sha1-e0JZI5Fii08ssXNlxszkJXx7evU= + integrity sha512-klL9Z/pqyq1JZE1kAa9hxI3i0J2f6XQonARUOEO3qwdtI9I46qVFX10gwdfQBCkM2yKIKj29eZFtufTN4D6GLg== supports-color@^5.3.0: version "5.5.0" @@ -10559,10 +12757,10 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== +supports-hyperlinks@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz#c711352a5c89070779b4dad54c05a2f14b15c94b" + integrity sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA== dependencies: has-flag "^4.0.0" supports-color "^7.0.0" @@ -10575,7 +12773,7 @@ supports-preserve-symlinks-flag@^1.0.0: svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" - integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= + integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA== svgo@^1.0.0: version "1.3.2" @@ -10596,11 +12794,31 @@ svgo@^1.0.0: unquote "~1.1.1" util.promisify "~1.0.0" +svgo@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.0.2.tgz#5e99eeea42c68ee0dc46aa16da093838c262fe0a" + integrity sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^5.1.0" + css-tree "^2.2.1" + csso "^5.0.5" + picocolors "^1.0.0" + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + table@^6.8.1: version "6.8.1" resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" @@ -10617,14 +12835,19 @@ tapable@^1.0, tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + tar@^6.0.2: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + version "6.1.15" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^3.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -10645,15 +12868,15 @@ tempy@^0.6.0: unique-string "^2.0.0" terser-webpack-plugin@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" - integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== dependencies: cacache "^12.0.2" find-cache-dir "^2.1.0" is-wsl "^1.1.0" schema-utils "^1.0.0" - serialize-javascript "^2.1.2" + serialize-javascript "^4.0.0" source-map "^0.6.1" terser "^4.1.2" webpack-sources "^1.4.0" @@ -10684,13 +12907,13 @@ terser@^4.1.2: source-map-support "~0.5.12" terser@^5.0.0, terser@^5.3.4: - version "5.13.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" - integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== + version "5.18.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.0.tgz#dc811fb8e3481a875d545bda247c8730ee4dc76b" + integrity sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA== dependencies: - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" - source-map "~0.8.0-beta.0" source-map-support "~0.5.20" tesseract.js-core@^2.2.0: @@ -10698,16 +12921,18 @@ tesseract.js-core@^2.2.0: resolved "https://registry.yarnpkg.com/tesseract.js-core/-/tesseract.js-core-2.2.0.tgz#6ef78051272a381969fac3e45a226e85022cffef" integrity sha512-a8L+OJTbUipBsEDsJhDPlnLB0TY1MkTZqw5dqUwmiDSjUzwvU7HWLg/2+WDRulKUi4LE+7PnHlaBlW0k+V0U0w== -tesseract.js@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-2.1.1.tgz#5c50fc95542ce8d834cb952bfb75a8fc85f1441d" - integrity sha512-utg0A8UzT1KwBvZf+UMGmM8LU6izeol6yIem0Z44+7Qqd/YWgRVQ99XOG18ApTOXX48lGE++PDwlcZYkv0ygRQ== +tesseract.js@^2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-2.1.5.tgz#2f757ff059f249721096fe9f94029c349650902c" + integrity sha512-7CIS3SWr7TXpeaH9+HS7iUtVbCfPFYOO3p6rkRAkdtsOtrbz6496x59na6SCbFAIaZulQxy8BjwSu3qL3AoDRg== dependencies: + blueimp-load-image "^3.0.0" bmp-js "^0.1.0" file-type "^12.4.1" idb-keyval "^3.2.0" is-electron "^2.2.0" is-url "^1.2.4" + jpeg-autorotate "^7.1.1" node-fetch "^2.6.0" opencollective-postinstall "^2.0.2" regenerator-runtime "^0.13.3" @@ -10727,14 +12952,7 @@ test-exclude@^6.0.0: text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throng@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/throng/-/throng-4.0.0.tgz#983c6ba1993b58eae859998aa687ffe88df84c17" - integrity sha1-mDxroZk7WOroWZmKpof/6I34TBc= - dependencies: - lodash.defaults "^4.0.1" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== through2@^2.0.0: version "2.0.5" @@ -10744,38 +12962,48 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" timsort@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A== tiny-invariant@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" - integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== tiny-queue@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046" - integrity sha1-JaZ/LG4lOyypQZd7XvdELvl6YEY= + integrity sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A== tiny-warning@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -10784,24 +13012,24 @@ tmpl@1.0.5: to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -10834,9 +13062,9 @@ totalist@^1.0.0: integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== tough-cookie@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -10846,7 +13074,7 @@ tough-cookie@^4.1.2: tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== dependencies: punycode "^2.1.0" @@ -10857,35 +13085,69 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" +tr46@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-4.1.1.tgz#281a758dcc82aeb4fe38c7dfe4d11a395aac8469" + integrity sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw== + dependencies: + punycode "^2.3.0" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== +trim-newlines@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.1.1.tgz#28c88deb50ed10c7ba6dc2474421904a00139125" + integrity sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ== + +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== dependencies: "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^1.0.2" minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^1.9.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +tslib@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" + integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== twemoji-parser@^11.0.2: version "11.0.2" @@ -10912,7 +13174,7 @@ type-check@^0.4.0, type-check@~0.4.0: type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: prelude-ls "~1.1.2" @@ -10921,35 +13183,25 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== - type-fest@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== -type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.0.1, type-fest@^1.2.1, type-fest@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== type-is@~1.6.18: version "1.6.18" @@ -10959,20 +13211,54 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" -type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" - integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +"typescript@^4.7 || 5", typescript@^5.0.4: + version "5.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" + integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== unbox-primitive@^1.0.2: version "1.0.2" @@ -10999,6 +13285,13 @@ unicode-canonical-property-names-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== +unicode-emoji-utils@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unicode-emoji-utils/-/unicode-emoji-utils-1.1.2.tgz#e15c6522d98380f4b145ea9126be59c01dabc297" + integrity sha512-b0fe4T08DjwayBPvKtG+tKyNMwx/Qdc50EZJhOJlGDwqU24DaxNrHMT8Kl75hVmLabrXC6TQ+CuMEVV163z1eQ== + dependencies: + emoji-regex "10.2.1" + unicode-match-property-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" @@ -11007,15 +13300,15 @@ unicode-match-property-ecmascript@^2.0.0: unicode-canonical-property-names-ecmascript "^2.0.0" unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" - integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== unicode-property-aliases-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" - integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== union-value@^1.0.0: version "1.0.1" @@ -11030,12 +13323,12 @@ union-value@^1.0.0: uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + integrity sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA== uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + integrity sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ== unique-filename@^1.1.1: version "1.1.1" @@ -11058,11 +13351,6 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - universalify@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" @@ -11076,47 +13364,52 @@ universalify@^2.0.0: unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unquote@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== dependencies: has-value "^0.3.1" isobject "^3.0.0" +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + upath@^1.1.1, upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" - integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== dependencies: escalade "^3.1.1" picocolors "^1.0.0" uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== -url-parse@^1.4.3, url-parse@^1.4.7, url-parse@^1.5.3: +url-parse@^1.5.10, url-parse@^1.5.3: version "1.5.10" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== @@ -11125,12 +13418,12 @@ url-parse@^1.4.3, url-parse@^1.4.7, url-parse@^1.5.3: requires-port "^1.0.0" url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + version "0.11.1" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.1.tgz#26f90f615427eca1b9f4d6a28288c147e2302a32" + integrity sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA== dependencies: - punycode "1.3.2" - querystring "0.2.0" + punycode "^1.4.1" + qs "^6.11.0" use-composed-ref@^1.3.0: version "1.3.0" @@ -11149,22 +13442,27 @@ use-latest@^1.2.1: dependencies: use-isomorphic-layout-effect "^1.1.1" +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -utf-8-validate@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-6.0.2.tgz#2d80529963e4cc55ac5a1ca9dafdaa990d5ea16b" - integrity sha512-yd7PQEOW+EgecUzSD7XUXTyq/vREGXk7t7fzGfOvwOAr0Z64h5rfGrmkNk8+ddVmf/FrkjPPhVyYBa7fuSPVTg== +utf-8-validate@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-6.0.3.tgz#7d8c936d854e86b24d1d655f138ee27d2636d777" + integrity sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA== dependencies: node-gyp-build "^4.3.0" util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util.promisify@~1.0.0: version "1.0.1" @@ -11179,7 +13477,7 @@ util.promisify@~1.0.0: util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + integrity sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ== dependencies: inherits "2.0.1" @@ -11193,27 +13491,32 @@ util@^0.11.0: utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^3.3.2, uuid@^3.4.0: +uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.3.1: +uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.1.1, v8-compile-cache@^2.3.0: +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + +v8-compile-cache@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== v8-to-istanbul@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" @@ -11235,7 +13538,7 @@ value-equal@^1.0.1: vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== vendors@^1.0.0: version "1.0.4" @@ -11264,7 +13567,7 @@ walker@^1.0.8: warning@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" - integrity sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w= + integrity sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ== dependencies: loose-envify "^1.0.0" @@ -11275,23 +13578,23 @@ warning@^4.0.1, warning@^4.0.3: dependencies: loose-envify "^1.0.0" -watchpack-chokidar2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" - integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" watchpack@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.4.tgz#6e9da53b3c80bb2d6508188f5b200410866cd30b" - integrity sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg== + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" neo-async "^2.5.0" optionalDependencies: chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.0" + watchpack-chokidar2 "^2.0.1" wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" @@ -11303,7 +13606,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webidl-conversions@^4.0.2: version "4.0.2" @@ -11315,6 +13618,19 @@ webidl-conversions@^7.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== +webpack-assets-manifest@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/webpack-assets-manifest/-/webpack-assets-manifest-3.1.1.tgz#39bbc3bf2ee57fcd8ba07cda51c9ba4a3c6ae1de" + integrity sha512-JV9V2QKc5wEWQptdIjvXDUL1ucbPLH2f27toAY3SNdGZp+xSaStAgpoMcvMZmqtFrBc9a5pTS1058vxyMPOzRQ== + dependencies: + chalk "^2.0" + lodash.get "^4.0" + lodash.has "^4.0" + mkdirp "^0.5" + schema-utils "^1.0.0" + tapable "^1.0.0" + webpack-sources "^1.0.0" + webpack-assets-manifest@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/webpack-assets-manifest/-/webpack-assets-manifest-4.0.6.tgz#cb8cfd2d2d8d129228cea645c832448380c21ae0" @@ -11330,11 +13646,12 @@ webpack-assets-manifest@^4.0.6: tapable "^1.0" webpack-sources "^1.0" -webpack-bundle-analyzer@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz#33c1c485a7fcae8627c547b5c3328b46de733c66" - integrity sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg== +webpack-bundle-analyzer@^4.8.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.0.tgz#fc093c4ab174fd3dcbd1c30b763f56d10141209d" + integrity sha512-+bXGmO1LyiNx0i9enBu3H8mv42sj/BJWhZNFwjz92tVnBa9J3JMGo2an2IXlEleoDOPn/Hofl5hr/xCpObUDtw== dependencies: + "@discoveryjs/json-ext" "0.5.7" acorn "^8.0.4" acorn-walk "^8.0.0" chalk "^4.1.0" @@ -11363,9 +13680,9 @@ webpack-cli@^3.3.12: yargs "^13.3.2" webpack-dev-middleware@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== dependencies: memory-fs "^0.4.1" mime "^2.4.4" @@ -11373,7 +13690,7 @@ webpack-dev-middleware@^3.7.2: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-server@^3.11.3: +webpack-dev-server@^3: version "3.11.3" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.3.tgz#8c86b9d2812bf135d3c9bce6f07b718e30f7c3d3" integrity sha512-3x31rjbEQWKMNzacUZRE6wXvUFuGpH7vr0lIEbYpMAG9BOxi0928QU1BBswOAP3kg3H1O4hiS+sq4YyAn6ANnA== @@ -11420,15 +13737,15 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" -webpack-merge@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== +webpack-merge@^5.9.0: + version "5.9.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826" + integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== dependencies: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^1.0, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.0, webpack-sources@^1.0.0, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -11499,10 +13816,18 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" +whatwg-url@^12.0.0, whatwg-url@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-12.0.1.tgz#fd7bcc71192e7c3a2a97b9a8d6b094853ed8773c" + integrity sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ== + dependencies: + tr46 "^4.1.1" + webidl-conversions "^7.0.0" + whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -11538,9 +13863,20 @@ which-collection@^1.0.1: is-weakset "^2.0.1" which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== + +which-typed-array@^1.1.10: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" which-typed-array@^1.1.9: version "1.1.9" @@ -11581,34 +13917,34 @@ wide-align@^1.1.5: string-width "^1.0.2 || 2 || 3 || 4" wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -workbox-background-sync@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz#3141afba3cc8aa2ae14c24d0f6811374ba8ff6a9" - integrity sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g== +workbox-background-sync@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-7.0.0.tgz#2b84b96ca35fec976e3bd2794b70e4acec46b3a5" + integrity sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA== dependencies: idb "^7.0.1" - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-broadcast-update@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz#8441cff5417cd41f384ba7633ca960a7ffe40f66" - integrity sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw== +workbox-broadcast-update@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-7.0.0.tgz#7f611ca1a94ba8ac0aa40fa171c9713e0f937d22" + integrity sha512-oUuh4jzZrLySOo0tC0WoKiSg90bVAcnE98uW7F8GFiSOXnhogfNDGZelPJa+6KpGBO5+Qelv04Hqx2UD+BJqNQ== dependencies: - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-build@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.5.4.tgz#7d06d31eb28a878817e1c991c05c5b93409f0389" - integrity sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA== +workbox-build@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-7.0.0.tgz#02ab5ef2991b3369b8b9395703f08912212769b4" + integrity sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg== dependencies: "@apideck/better-ajv-errors" "^0.3.1" "@babel/core" "^7.11.1" @@ -11632,132 +13968,132 @@ workbox-build@6.5.4: strip-comments "^2.0.1" tempy "^0.6.0" upath "^1.2.0" - workbox-background-sync "6.5.4" - workbox-broadcast-update "6.5.4" - workbox-cacheable-response "6.5.4" - workbox-core "6.5.4" - workbox-expiration "6.5.4" - workbox-google-analytics "6.5.4" - workbox-navigation-preload "6.5.4" - workbox-precaching "6.5.4" - workbox-range-requests "6.5.4" - workbox-recipes "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" - workbox-streams "6.5.4" - workbox-sw "6.5.4" - workbox-window "6.5.4" + workbox-background-sync "7.0.0" + workbox-broadcast-update "7.0.0" + workbox-cacheable-response "7.0.0" + workbox-core "7.0.0" + workbox-expiration "7.0.0" + workbox-google-analytics "7.0.0" + workbox-navigation-preload "7.0.0" + workbox-precaching "7.0.0" + workbox-range-requests "7.0.0" + workbox-recipes "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" + workbox-streams "7.0.0" + workbox-sw "7.0.0" + workbox-window "7.0.0" -workbox-cacheable-response@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz#a5c6ec0c6e2b6f037379198d4ef07d098f7cf137" - integrity sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug== +workbox-cacheable-response@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-7.0.0.tgz#ee27c036728189eed69d25a135013053277482d2" + integrity sha512-0lrtyGHn/LH8kKAJVOQfSu3/80WDc9Ma8ng0p2i/5HuUndGttH+mGMSvOskjOdFImLs2XZIimErp7tSOPmu/6g== dependencies: - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-core@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.5.4.tgz#df48bf44cd58bb1d1726c49b883fb1dffa24c9ba" - integrity sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q== +workbox-core@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-7.0.0.tgz#dec114ec923cc2adc967dd9be1b8a0bed50a3545" + integrity sha512-81JkAAZtfVP8darBpfRTovHg8DGAVrKFgHpOArZbdFd78VqHr5Iw65f2guwjE2NlCFbPFDoez3D3/6ZvhI/rwQ== -workbox-expiration@6.5.4, workbox-expiration@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.5.4.tgz#501056f81e87e1d296c76570bb483ce5e29b4539" - integrity sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ== +workbox-expiration@7.0.0, workbox-expiration@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-7.0.0.tgz#3d90bcf2a7577241de950f89784f6546b66c2baa" + integrity sha512-MLK+fogW+pC3IWU9SFE+FRStvDVutwJMR5if1g7oBJx3qwmO69BNoJQVaMXq41R0gg3MzxVfwOGKx3i9P6sOLQ== dependencies: idb "^7.0.1" - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-google-analytics@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz#c74327f80dfa4c1954cbba93cd7ea640fe7ece7d" - integrity sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg== +workbox-google-analytics@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-7.0.0.tgz#603b2c4244af1e85de0fb26287d4e17d3293452a" + integrity sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg== dependencies: - workbox-background-sync "6.5.4" - workbox-core "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" + workbox-background-sync "7.0.0" + workbox-core "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" -workbox-navigation-preload@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz#ede56dd5f6fc9e860a7e45b2c1a8f87c1c793212" - integrity sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng== +workbox-navigation-preload@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-7.0.0.tgz#4913878dbbd97057181d57baa18d2bbdde085c6c" + integrity sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA== dependencies: - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-precaching@6.5.4, workbox-precaching@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.5.4.tgz#740e3561df92c6726ab5f7471e6aac89582cab72" - integrity sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg== +workbox-precaching@7.0.0, workbox-precaching@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-7.0.0.tgz#3979ba8033aadf3144b70e9fe631d870d5fbaa03" + integrity sha512-EC0vol623LJqTJo1mkhD9DZmMP604vHqni3EohhQVwhJlTgyKyOkMrZNy5/QHfOby+39xqC01gv4LjOm4HSfnA== dependencies: - workbox-core "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" + workbox-core "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" -workbox-range-requests@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz#86b3d482e090433dab38d36ae031b2bb0bd74399" - integrity sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg== +workbox-range-requests@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-7.0.0.tgz#97511901e043df27c1aa422adcc999a7751f52ed" + integrity sha512-SxAzoVl9j/zRU9OT5+IQs7pbJBOUOlriB8Gn9YMvi38BNZRbM+RvkujHMo8FOe9IWrqqwYgDFBfv6sk76I1yaQ== dependencies: - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-recipes@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.5.4.tgz#cca809ee63b98b158b2702dcfb741b5cc3e24acb" - integrity sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA== +workbox-recipes@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-7.0.0.tgz#1a6a01c8c2dfe5a41eef0fed3fe517e8a45c6514" + integrity sha512-DntcK9wuG3rYQOONWC0PejxYYIDHyWWZB/ueTbOUDQgefaeIj1kJ7pdP3LZV2lfrj8XXXBWt+JDRSw1lLLOnww== dependencies: - workbox-cacheable-response "6.5.4" - workbox-core "6.5.4" - workbox-expiration "6.5.4" - workbox-precaching "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" + workbox-cacheable-response "7.0.0" + workbox-core "7.0.0" + workbox-expiration "7.0.0" + workbox-precaching "7.0.0" + workbox-routing "7.0.0" + workbox-strategies "7.0.0" -workbox-routing@6.5.4, workbox-routing@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.5.4.tgz#6a7fbbd23f4ac801038d9a0298bc907ee26fe3da" - integrity sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg== +workbox-routing@7.0.0, workbox-routing@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-7.0.0.tgz#6668438a06554f60645aedc77244a4fe3a91e302" + integrity sha512-8YxLr3xvqidnbVeGyRGkaV4YdlKkn5qZ1LfEePW3dq+ydE73hUUJJuLmGEykW3fMX8x8mNdL0XrWgotcuZjIvA== dependencies: - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-strategies@6.5.4, workbox-strategies@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.5.4.tgz#4edda035b3c010fc7f6152918370699334cd204d" - integrity sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw== +workbox-strategies@7.0.0, workbox-strategies@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-7.0.0.tgz#dcba32b3f3074476019049cc490fe1a60ea73382" + integrity sha512-dg3qJU7tR/Gcd/XXOOo7x9QoCI9nk74JopaJaYAQ+ugLi57gPsXycVdBnYbayVj34m6Y8ppPwIuecrzkpBVwbA== dependencies: - workbox-core "6.5.4" + workbox-core "7.0.0" -workbox-streams@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.5.4.tgz#1cb3c168a6101df7b5269d0353c19e36668d7d69" - integrity sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg== +workbox-streams@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-7.0.0.tgz#36722aecd04785f88b6f709e541c094fc658c0f9" + integrity sha512-moVsh+5to//l6IERWceYKGiftc+prNnqOp2sgALJJFbnNVpTXzKISlTIsrWY+ogMqt+x1oMazIdHj25kBSq/HQ== dependencies: - workbox-core "6.5.4" - workbox-routing "6.5.4" + workbox-core "7.0.0" + workbox-routing "7.0.0" -workbox-sw@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.5.4.tgz#d93e9c67924dd153a61367a4656ff4d2ae2ed736" - integrity sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA== +workbox-sw@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-7.0.0.tgz#7350126411e3de1409f7ec243df8d06bb5b08b86" + integrity sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA== -workbox-webpack-plugin@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz#baf2d3f4b8f435f3469887cf4fba2b7fac3d0fd7" - integrity sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg== +workbox-webpack-plugin@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-7.0.0.tgz#6c61661a2cacde1239192a5877a041a2943d1a55" + integrity sha512-R1ZzCHPfzeJjLK2/TpKUhxSQ3fFDCxlWxgRhhSjMQLz3G2MlBnyw/XeYb34e7SGgSv0qG22zEhMIzjMNqNeKbw== dependencies: fast-json-stable-stringify "^2.1.0" pretty-bytes "^5.4.1" upath "^1.2.0" webpack-sources "^1.4.3" - workbox-build "6.5.4" + workbox-build "7.0.0" -workbox-window@6.5.4, workbox-window@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.5.4.tgz#d991bc0a94dff3c2dbb6b84558cff155ca878e91" - integrity sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug== +workbox-window@7.0.0, workbox-window@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-7.0.0.tgz#a683ab33c896e4f16786794eac7978fc98a25d08" + integrity sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA== dependencies: "@types/trusted-types" "^2.0.2" - workbox-core "6.5.4" + workbox-core "7.0.0" worker-farm@^1.7.0: version "1.7.0" @@ -11766,6 +14102,16 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + name wrap-ansi-cjs + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" @@ -11775,19 +14121,28 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^4.0.2: version "4.0.2" @@ -11797,30 +14152,30 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -write-file-atomic@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.0.tgz#54303f117e109bf3d540261125c8ea5a7320fab0" - integrity sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w== +write-file-atomic@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== dependencies: imurmurhash "^0.1.4" - signal-exit "^3.0.7" + signal-exit "^4.0.1" ws@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + version "6.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" + integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== dependencies: async-limiter "~1.0.0" ws@^7.3.1: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.11.0, ws@^8.12.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8" - integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig== +ws@^8.11.0, ws@^8.12.1, ws@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== xml-name-validator@^4.0.0: version "4.0.0" @@ -11843,9 +14198,9 @@ y18n@^4.0.0: integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== y18n@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@4.0.0, yallist@^4.0.0: version "4.0.0" @@ -11862,6 +14217,11 @@ yaml@^1.10.0, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.2.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" + integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -11870,7 +14230,7 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.3: +yargs-parser@^20.2.1, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== @@ -11896,10 +14256,10 @@ yargs@^13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" -yargs@^17.3.1, yargs@^17.6.2: - version "17.6.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== +yargs@^17.3.1, yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" escalade "^3.1.1" @@ -11917,4 +14277,4 @@ yocto-queue@^0.1.0: zlibjs@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/zlibjs/-/zlibjs-0.3.1.tgz#50197edb28a1c42ca659cc8b4e6a9ddd6d444554" - integrity sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ= + integrity sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==