From 67ebd61f1180e63fcc671c583e7251e1e09755d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Dec 2020 05:12:11 +0100 Subject: [PATCH 1/9] Bump node-notifier from 8.0.0 to 8.0.1 (#15404) Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/mikaelbr/node-notifier/releases) - [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md) - [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 653d67133..4aa8f6380 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7303,9 +7303,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-notifier@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.0.tgz#a7eee2d51da6d0f7ff5094bc7108c911240c1620" - integrity sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA== + version "8.0.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1" + integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA== dependencies: growly "^1.3.0" is-wsl "^2.2.0" @@ -9551,9 +9551,11 @@ semver@^6.0.0, semver@^6.3.0: integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.2.1, semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== + dependencies: + lru-cache "^6.0.0" send@0.17.1: version "0.17.1" @@ -10845,9 +10847,9 @@ uuid@^3.3.2, uuid@^3.4.0: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== uuid@^8.3.0, uuid@^8.3.1: - version "8.3.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" - integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== + 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.0.3, v8-compile-cache@^2.1.1: version "2.2.0" From 9915d11c0d7a15b6775af8e78fcc4d836368f88d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 22 Dec 2020 17:13:55 +0100 Subject: [PATCH 2/9] Fix unnecessary queries when batch-removing statuses, 100x faster (#15387) --- app/models/favourite.rb | 2 +- app/models/status.rb | 12 +- app/services/batched_remove_status_service.rb | 91 +++++++------ app/services/delete_account_service.rb | 128 ++++++++++++++---- config/initializers/chewy.rb | 5 + lib/chewy/strategy/custom_sidekiq.rb | 25 +--- .../batched_remove_status_service_spec.rb | 5 + 7 files changed, 168 insertions(+), 100 deletions(-) diff --git a/app/models/favourite.rb b/app/models/favourite.rb index bf0ec4449..35028b7dd 100644 --- a/app/models/favourite.rb +++ b/app/models/favourite.rb @@ -36,7 +36,7 @@ class Favourite < ApplicationRecord end def decrement_cache_counters - return if association(:status).loaded? && (status.marked_for_destruction? || status.marked_for_mass_destruction?) + return if association(:status).loaded? && status.marked_for_destruction? status&.decrement_count!(:favourites_count) end end diff --git a/app/models/status.rb b/app/models/status.rb index 96d90e1c2..b426f9d5b 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -228,14 +228,6 @@ class Status < ApplicationRecord @emojis = CustomEmoji.from_text(fields.join(' '), account.domain) end - def mark_for_mass_destruction! - @marked_for_mass_destruction = true - end - - def marked_for_mass_destruction? - @marked_for_mass_destruction - end - def replies_count status_stat&.replies_count || 0 end @@ -430,7 +422,7 @@ class Status < ApplicationRecord end def decrement_counter_caches - return if direct_visibility? || marked_for_mass_destruction? + return if direct_visibility? account&.decrement_count!(:statuses_count) reblog&.decrement_count!(:reblogs_count) if reblog? @@ -440,7 +432,7 @@ class Status < ApplicationRecord def unlink_from_conversations return unless direct_visibility? - mentioned_accounts = mentions.includes(:account).map(&:account) + mentioned_accounts = (association(:mentions).loaded? ? mentions : mentions.includes(:account)).map(&:account) inbox_owners = mentioned_accounts.select(&:local?) + (account.local? ? [account] : []) inbox_owners.each do |inbox_owner| diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index 28e5468b3..63ab89f2d 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -3,29 +3,45 @@ class BatchedRemoveStatusService < BaseService include Redisable - # Delete given statuses and reblogs of them - # Remove statuses from home feeds - # Push delete events to streaming API for home feeds and public feeds - # @param [Enumerable] statuses A preferably batched array of statuses + # Delete multiple statuses and reblogs of them as efficiently as possible + # @param [Enumerable] statuses An array of statuses # @param [Hash] options - # @option [Boolean] :skip_side_effects + # @option [Boolean] :skip_side_effects Do not modify feeds and send updates to streaming API def call(statuses, **options) - statuses = Status.where(id: statuses.map(&:id)).includes(:account).flat_map { |status| [status] + status.reblogs.includes(:account).to_a } + ActiveRecord::Associations::Preloader.new.preload(statuses, options[:skip_side_effects] ? :reblogs : [:account, reblogs: :account]) - @mentions = statuses.each_with_object({}) { |s, h| h[s.id] = s.active_mentions.includes(:account).to_a } - @tags = statuses.each_with_object({}) { |s, h| h[s.id] = s.tags.pluck(:name) } + statuses_and_reblogs = statuses.flat_map { |status| [status] + status.reblogs } - @json_payloads = statuses.each_with_object({}) { |s, h| h[s.id] = Oj.dump(event: :delete, payload: s.id.to_s) } + # The conversations for direct visibility statuses also need + # to be manually updated. This part is not efficient but we + # rely on direct visibility statuses being relatively rare. + statuses_with_account_conversations = statuses.select(&:direct_visibility?) - statuses.each do |status| - status.mark_for_mass_destruction! - status.destroy + ActiveRecord::Associations::Preloader.new.preload(statuses_with_account_conversations, [mentions: :account]) + + statuses_with_account_conversations.each do |status| + status.send(:unlink_from_conversations) end + # We do not batch all deletes into one to avoid having a long-running + # transaction lock the database, but we use the delete method instead + # of destroy to avoid all callbacks. We rely on foreign keys to + # cascade the delete faster without loading the associations. + statuses_and_reblogs.each(&:delete) + + # Since we skipped all callbacks, we also need to manually + # deindex the statuses + Chewy.strategy.current.update(StatusesIndex, statuses_and_reblogs) + return if options[:skip_side_effects] + ActiveRecord::Associations::Preloader.new.preload(statuses_and_reblogs, :tags) + + @tags = statuses_and_reblogs.each_with_object({}) { |s, h| h[s.id] = s.tags.map { |tag| tag.name.mb_chars.downcase } } + @json_payloads = statuses_and_reblogs.each_with_object({}) { |s, h| h[s.id] = Oj.dump(event: :delete, payload: s.id.to_s) } + # Batch by source account - statuses.group_by(&:account_id).each_value do |account_statuses| + statuses_and_reblogs.group_by(&:account_id).each_value do |account_statuses| account = account_statuses.first.account next unless account @@ -35,27 +51,31 @@ class BatchedRemoveStatusService < BaseService end # Cannot be batched - statuses.each do |status| - unpush_from_public_timelines(status) + redis.pipelined do + statuses_and_reblogs.each do |status| + unpush_from_public_timelines(status) + end end end private def unpush_from_home_timelines(account, statuses) - recipients = account.followers_for_local_distribution.to_a - - recipients << account if account.local? - - recipients.each do |follower| + account.followers_for_local_distribution.includes(:user).find_each do |follower| statuses.each do |status| FeedManager.instance.unpush_from_home(follower, status) end end + + return unless account.local? + + statuses.each do |status| + FeedManager.instance.unpush_from_home(account, status) + end end def unpush_from_list_timelines(account, statuses) - account.lists_for_local_distribution.select(:id, :account_id).each do |list| + account.lists_for_local_distribution.select(:id, :account_id).includes(account: :user).find_each do |list| statuses.each do |status| FeedManager.instance.unpush_from_list(list, status) end @@ -67,26 +87,17 @@ class BatchedRemoveStatusService < BaseService payload = @json_payloads[status.id] - redis.pipelined do - redis.publish('timeline:public', payload) - if status.local? - redis.publish('timeline:public:local', payload) - else - redis.publish('timeline:public:remote', payload) - end - if status.media_attachments.any? - redis.publish('timeline:public:media', payload) - if status.local? - redis.publish('timeline:public:local:media', payload) - else - redis.publish('timeline:public:remote:media', payload) - end - end + redis.publish('timeline:public', payload) + redis.publish(status.local? ? 'timeline:public:local' : 'timeline:public:remote', payload) - @tags[status.id].each do |hashtag| - redis.publish("timeline:hashtag:#{hashtag.mb_chars.downcase}", payload) - redis.publish("timeline:hashtag:#{hashtag.mb_chars.downcase}:local", payload) if status.local? - end + if status.media_attachments.any? + redis.publish('timeline:public:media', payload) + redis.publish(status.local? ? 'timeline:public:local:media' : 'timeline:public:remote:media', payload) + end + + @tags[status.id].each do |hashtag| + redis.publish("timeline:hashtag:#{hashtag}", payload) + redis.publish("timeline:hashtag:#{hashtag}:local", payload) if status.local? end end end diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb index fa834e775..5123a4697 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -6,15 +6,21 @@ class DeleteAccountService < BaseService ASSOCIATIONS_ON_SUSPEND = %w( account_pins active_relationships + aliases block_relationships blocked_by_relationships + bookmarks conversation_mutes conversations custom_filters + devices domain_blocks favourites + featured_tags follow_requests + identity_proofs list_accounts + migrations mute_relationships muted_by_relationships notifications @@ -25,6 +31,29 @@ class DeleteAccountService < BaseService status_pins ).freeze + # The following associations have no important side-effects + # in callbacks and all of their own associations are secured + # by foreign keys, making them safe to delete without loading + # into memory + ASSOCIATIONS_WITHOUT_SIDE_EFFECTS = %w( + account_pins + aliases + conversation_mutes + conversations + custom_filters + devices + domain_blocks + featured_tags + follow_requests + identity_proofs + migrations + mute_relationships + muted_by_relationships + notifications + scheduled_statuses + status_pins + ) + ASSOCIATIONS_ON_DESTROY = %w( reports targeted_moderation_notes @@ -55,19 +84,25 @@ class DeleteAccountService < BaseService @options[:skip_activitypub] = true if @options[:skip_side_effects] - reject_follows! - undo_follows! - purge_user! - purge_profile! + distribute_activities! purge_content! fulfill_deletion_request! end private - def reject_follows! - return if @account.local? || !@account.activitypub? || @options[:skip_activitypub] + def distribute_activities! + return if skip_activitypub? + if @account.local? + delete_actor! + elsif @account.activitypub? + reject_follows! + undo_follows! + end + end + + def reject_follows! # When deleting a remote account, the account obviously doesn't # actually become deleted on its origin server, i.e. unlike a # locally deleted account it continues to have access to its home @@ -81,8 +116,6 @@ class DeleteAccountService < BaseService end def undo_follows! - return if @account.local? || !@account.activitypub? || @options[:skip_activitypub] - # When deleting a remote account, the account obviously doesn't # actually become deleted on its origin server, but following relationships # are severed on our end. Therefore, make the remote server aware that the @@ -97,7 +130,7 @@ class DeleteAccountService < BaseService def purge_user! return if !@account.local? || @account.user.nil? - if @options[:reserve_email] + if keep_user_record? @account.user.disable! @account.user.invites.where(uses: 0).destroy_all else @@ -106,34 +139,52 @@ class DeleteAccountService < BaseService end def purge_content! - distribute_delete_actor! if @account.local? && !@options[:skip_side_effects] + purge_user! + purge_profile! + purge_statuses! + purge_media_attachments! + purge_polls! + purge_generated_notifications! + purge_other_associations! + @account.destroy unless keep_account_record? + end + + def purge_statuses! @account.statuses.reorder(nil).find_in_batches do |statuses| - statuses.reject! { |status| reported_status_ids.include?(status.id) } if @options[:reserve_username] - BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:skip_side_effects]) - end + statuses.reject! { |status| reported_status_ids.include?(status.id) } if keep_account_record? + BatchedRemoveStatusService.new.call(statuses, skip_side_effects: skip_side_effects?) + end + end + + def purge_media_attachments! @account.media_attachments.reorder(nil).find_each do |media_attachment| - next if @options[:reserve_username] && reported_status_ids.include?(media_attachment.status_id) + next if keep_account_record? && reported_status_ids.include?(media_attachment.status_id) media_attachment.destroy end + end + def purge_polls! @account.polls.reorder(nil).find_each do |poll| - next if @options[:reserve_username] && reported_status_ids.include?(poll.status_id) + next if keep_account_record? && reported_status_ids.include?(poll.status_id) - # We can safely delete the poll rather than destroy it, as any non-reported - # status should have been deleted already, as long as we take care of - # notifications. - Notification.where(poll: poll).delete_all poll.delete end + end + def purge_generated_notifications! + # By deleting polls and statuses without callbacks, we've left behind + # polymorphically associated notifications generated by this account + + Notification.where(from_account: @account).in_batches.delete_all + end + + def purge_other_associations! associations_for_destruction.each do |association_name| - destroy_all(@account.public_send(association_name)) + purge_association(association_name) end - - @account.destroy unless @options[:reserve_username] end def purge_profile! @@ -141,7 +192,7 @@ class DeleteAccountService < BaseService # there is no point wasting time updating # its values first - return unless @options[:reserve_username] + return unless keep_account_record? @account.silenced_at = nil @account.suspended_at = @options[:suspended_at] || Time.now.utc @@ -156,6 +207,7 @@ class DeleteAccountService < BaseService @account.followers_count = 0 @account.following_count = 0 @account.moved_to_account = nil + @account.also_known_as = [] @account.trust_level = :untrusted @account.avatar.destroy @account.header.destroy @@ -166,11 +218,17 @@ class DeleteAccountService < BaseService @account.deletion_request&.destroy end - def destroy_all(association) - association.in_batches.destroy_all + def purge_association(association_name) + association = @account.public_send(association_name) + + if ASSOCIATIONS_WITHOUT_SIDE_EFFECTS.include?(association_name) + association.in_batches.delete_all + else + association.in_batches.destroy_all + end end - def distribute_delete_actor! + def delete_actor! ActivityPub::DeliveryWorker.push_bulk(delivery_inboxes) do |inbox_url| [delete_actor_json, @account.id, inbox_url] end @@ -197,10 +255,26 @@ class DeleteAccountService < BaseService end def associations_for_destruction - if @options[:reserve_username] + if keep_account_record? ASSOCIATIONS_ON_SUSPEND else ASSOCIATIONS_ON_SUSPEND + ASSOCIATIONS_ON_DESTROY end end + + def keep_user_record? + @options[:reserve_email] + end + + def keep_account_record? + @options[:reserve_username] + end + + def skip_side_effects? + @options[:skip_side_effects] + end + + def skip_activitypub? + @options[:skip_activitypub] + end end diff --git a/config/initializers/chewy.rb b/config/initializers/chewy.rb index 8f54abf77..9fc9b2f1a 100644 --- a/config/initializers/chewy.rb +++ b/config/initializers/chewy.rb @@ -12,6 +12,10 @@ Chewy.settings = { sidekiq: { queue: 'pull' }, } +# We use our own async strategy even outside the request-response +# cycle, which takes care of checking if ElasticSearch is enabled +# or not. However, mind that for the Rails console, the :urgent +# strategy is set automatically with no way to override it. Chewy.root_strategy = :custom_sidekiq Chewy.request_strategy = :custom_sidekiq Chewy.use_after_commit_callbacks = false @@ -37,6 +41,7 @@ Elasticsearch::Transport::Client.prepend Module.new { super arguments end } + Elasticsearch::API::Indices::IndicesClient.prepend Module.new { def create(arguments = {}) arguments[:include_type_name] = true diff --git a/lib/chewy/strategy/custom_sidekiq.rb b/lib/chewy/strategy/custom_sidekiq.rb index 3e54326ba..794ae4ed4 100644 --- a/lib/chewy/strategy/custom_sidekiq.rb +++ b/lib/chewy/strategy/custom_sidekiq.rb @@ -2,29 +2,10 @@ module Chewy class Strategy - class CustomSidekiq < Base - class Worker - include ::Sidekiq::Worker - - sidekiq_options queue: 'pull' - - def perform(type, ids, options = {}) - options[:refresh] = !Chewy.disable_refresh_async if Chewy.disable_refresh_async - type.constantize.import!(ids, options) - end + class CustomSidekiq < Sidekiq + def update(_type, _objects, _options = {}) + super if Chewy.enabled? end - - def update(type, objects, _options = {}) - return unless Chewy.enabled? - - ids = type.root.id ? Array.wrap(objects) : type.adapter.identify(objects) - - return if ids.empty? - - Worker.perform_async(type.name, ids) - end - - def leave; end end end end diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index f84256f18..239859f06 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -26,6 +26,11 @@ RSpec.describe BatchedRemoveStatusService, type: :service do subject.call([status1, status2]) 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 + end + it 'removes statuses from author\'s home feed' do expect(HomeFeed.new(alice).get(10)).to_not include([status1.id, status2.id]) end From 1cf2c3a810bba937c7702c342a3ff37c3d37391a Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 22 Dec 2020 17:14:32 +0100 Subject: [PATCH 3/9] Fix external user creation failing when invite request text is required (#15405) * Fix external user creation failing when invite request text is required Also fixes tootctl-based user creation. * Add test about invites when invite request text is otherwise required Co-authored-by: Claire --- app/models/user.rb | 12 ++++++++++-- lib/mastodon/accounts_cli.rb | 2 +- lib/tasks/mastodon.rake | 2 +- .../auth/registrations_controller_spec.rb | 5 ++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index dd96bbf8c..f8c8a6ab5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -83,7 +83,7 @@ class User < ApplicationRecord has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? && !Setting.require_invite_text } - validates :invite_request, presence: true, on: :create, if: -> { Setting.require_invite_text && !invited? } + validates :invite_request, presence: true, on: :create, if: :invite_text_required? validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale? validates_with BlacklistedEmailValidator, on: :create @@ -128,7 +128,7 @@ class User < ApplicationRecord to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code, :sign_in_token_attempt - attr_writer :external + attr_writer :external, :bypass_invite_request_check def confirmed? confirmed_at.present? @@ -429,6 +429,10 @@ class User < ApplicationRecord !!@external end + def bypass_invite_request_check? + @bypass_invite_request_check + end + def sanitize_languages return if chosen_languages.nil? chosen_languages.reject!(&:blank?) @@ -466,4 +470,8 @@ class User < ApplicationRecord def validate_email_dns? email_changed? && !(Rails.env.test? || Rails.env.development?) end + + def invite_text_required? + Setting.require_invite_text && !invited? && !external? && !bypass_invite_request_check? + end end diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb index 5275f04cf..cdd1db995 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/accounts_cli.rb @@ -77,7 +77,7 @@ module Mastodon def create(username) account = Account.new(username: username) password = SecureRandom.hex - user = User.new(email: options[:email], password: password, agreement: true, approved: true, admin: options[:role] == 'admin', moderator: options[:role] == 'moderator', confirmed_at: options[:confirmed] ? Time.now.utc : nil) + user = User.new(email: options[:email], password: password, agreement: true, approved: true, admin: options[:role] == 'admin', moderator: options[:role] == 'moderator', 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) diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 9e80989ef..2ad1e778b 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -412,7 +412,7 @@ namespace :mastodon do password = SecureRandom.hex(16) - user = User.new(admin: true, email: email, password: password, confirmed_at: Time.now.utc, account_attributes: { username: username }) + user = User.new(admin: true, email: email, password: password, confirmed_at: Time.now.utc, account_attributes: { username: username }, bypass_invite_request_check: true) user.save(validate: false) prompt.ok "You can login with the password: #{password}" diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index c701a3b8b..ccf304a93 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -195,16 +195,19 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end end - context 'approval-based registrations with valid invite' do + context 'approval-based registrations with valid invite and required invite text' do around do |example| registrations_mode = Setting.registrations_mode + require_invite_text = Setting.require_invite_text example.run + Setting.require_invite_text = require_invite_text 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' } } From f18349640b686a3c3866711bfcd1d14edd5bc41a Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 22 Dec 2020 20:24:55 +0100 Subject: [PATCH 4/9] Fix batch order warnings in BatchedRemoveStatusService (#15409) Co-authored-by: Claire --- app/services/batched_remove_status_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index 63ab89f2d..3ec000110 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -61,7 +61,7 @@ class BatchedRemoveStatusService < BaseService private def unpush_from_home_timelines(account, statuses) - account.followers_for_local_distribution.includes(:user).find_each do |follower| + account.followers_for_local_distribution.includes(:user).reorder(nil).find_each do |follower| statuses.each do |status| FeedManager.instance.unpush_from_home(follower, status) end @@ -75,7 +75,7 @@ class BatchedRemoveStatusService < BaseService end def unpush_from_list_timelines(account, statuses) - account.lists_for_local_distribution.select(:id, :account_id).includes(account: :user).find_each do |list| + account.lists_for_local_distribution.select(:id, :account_id).includes(account: :user).reorder(nil).find_each do |list| statuses.each do |status| FeedManager.instance.unpush_from_list(list, status) end From 3249d35bdcd9a495af3277dfb4b2129d7ef80f15 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 22 Dec 2020 23:57:46 +0100 Subject: [PATCH 5/9] Improve account deletion performances further (#15407) * Delete status records by batches of 50 * Do not precompute values that are only used once * Do not generate redis events for removal of public toots older than two weeks * Filter reported toots a priori for polls and status deletion * Do not process reblogs when cleaning up public timelines As in Mastodon proper, reblogs don't appear in public TLs * Clean the deleted account's own feed in one go * Refactor Account#clean_feed_manager and List#clean_feed_manager * Delete instead of destroy a few more associations * Fix preloading Co-authored-by: Claire --- app/lib/feed_manager.rb | 30 +++++++++++++++++++ app/models/account.rb | 13 +------- app/models/list.rb | 13 +------- app/services/batched_remove_status_service.rb | 24 +++++---------- app/services/delete_account_service.rb | 20 ++++++++----- .../scheduler/feed_cleanup_scheduler.rb | 30 ++----------------- .../batched_remove_status_service_spec.rb | 4 --- 7 files changed, 53 insertions(+), 81 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 5e01ef67a..f0ad3e21f 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -230,6 +230,36 @@ class FeedManager end end + # Completely clear multiple feeds at once + # @param [Symbol] type + # @param [Array] ids + # @return [void] + def clean_feeds!(type, ids) + reblogged_id_sets = {} + + redis.pipelined do + ids.each do |feed_id| + redis.del(key(type, feed_id)) + reblog_key = key(type, feed_id, 'reblogs') + # We collect a future for this: we don't block while getting + # it, but we can iterate over it later. + reblogged_id_sets[feed_id] = redis.zrange(reblog_key, 0, -1) + redis.del(reblog_key) + end + end + + # Remove all of the reblog tracking keys we just removed the + # references to. + redis.pipelined do + reblogged_id_sets.each do |feed_id, future| + future.value.each do |reblogged_id| + reblog_set_key = key(type, feed_id, "reblogs:#{reblogged_id}") + redis.del(reblog_set_key) + end + end + end + end + private # Trim a feed to maximum size by removing older items diff --git a/app/models/account.rb b/app/models/account.rb index 80eb92a71..e6cf03fa8 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -578,17 +578,6 @@ class Account < ApplicationRecord end def clean_feed_manager - reblog_key = FeedManager.instance.key(:home, id, 'reblogs') - reblogged_id_set = Redis.current.zrange(reblog_key, 0, -1) - - Redis.current.pipelined do - Redis.current.del(FeedManager.instance.key(:home, id)) - Redis.current.del(reblog_key) - - reblogged_id_set.each do |reblogged_id| - reblog_set_key = FeedManager.instance.key(:home, id, "reblogs:#{reblogged_id}") - Redis.current.del(reblog_set_key) - end - end + FeedManager.instance.clean_feeds!(:home, [id]) end end diff --git a/app/models/list.rb b/app/models/list.rb index 655d55ff6..cdc6ebdb3 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -34,17 +34,6 @@ class List < ApplicationRecord private def clean_feed_manager - reblog_key = FeedManager.instance.key(:list, id, 'reblogs') - reblogged_id_set = Redis.current.zrange(reblog_key, 0, -1) - - Redis.current.pipelined do - Redis.current.del(FeedManager.instance.key(:list, id)) - Redis.current.del(reblog_key) - - reblogged_id_set.each do |reblogged_id| - reblog_set_key = FeedManager.instance.key(:list, id, "reblogs:#{reblogged_id}") - Redis.current.del(reblog_set_key) - end - end + FeedManager.instance.clean_feeds!(:list, [id]) end end diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index 3ec000110..61617d958 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -8,7 +8,7 @@ class BatchedRemoveStatusService < BaseService # @param [Hash] options # @option [Boolean] :skip_side_effects Do not modify feeds and send updates to streaming API def call(statuses, **options) - ActiveRecord::Associations::Preloader.new.preload(statuses, options[:skip_side_effects] ? :reblogs : [:account, reblogs: :account]) + ActiveRecord::Associations::Preloader.new.preload(statuses, options[:skip_side_effects] ? :reblogs : [:account, :tags, reblogs: :account]) statuses_and_reblogs = statuses.flat_map { |status| [status] + status.reblogs } @@ -27,7 +27,7 @@ class BatchedRemoveStatusService < BaseService # transaction lock the database, but we use the delete method instead # of destroy to avoid all callbacks. We rely on foreign keys to # cascade the delete faster without loading the associations. - statuses_and_reblogs.each(&:delete) + statuses_and_reblogs.each_slice(50) { |slice| Status.where(id: slice.map(&:id)).delete_all } # Since we skipped all callbacks, we also need to manually # deindex the statuses @@ -35,11 +35,6 @@ class BatchedRemoveStatusService < BaseService return if options[:skip_side_effects] - ActiveRecord::Associations::Preloader.new.preload(statuses_and_reblogs, :tags) - - @tags = statuses_and_reblogs.each_with_object({}) { |s, h| h[s.id] = s.tags.map { |tag| tag.name.mb_chars.downcase } } - @json_payloads = statuses_and_reblogs.each_with_object({}) { |s, h| h[s.id] = Oj.dump(event: :delete, payload: s.id.to_s) } - # Batch by source account statuses_and_reblogs.group_by(&:account_id).each_value do |account_statuses| account = account_statuses.first.account @@ -51,8 +46,9 @@ class BatchedRemoveStatusService < BaseService end # Cannot be batched + @status_id_cutoff = Mastodon::Snowflake.id_at(2.weeks.ago) redis.pipelined do - statuses_and_reblogs.each do |status| + statuses.each do |status| unpush_from_public_timelines(status) end end @@ -66,12 +62,6 @@ class BatchedRemoveStatusService < BaseService FeedManager.instance.unpush_from_home(follower, status) end end - - return unless account.local? - - statuses.each do |status| - FeedManager.instance.unpush_from_home(account, status) - end end def unpush_from_list_timelines(account, statuses) @@ -83,9 +73,9 @@ class BatchedRemoveStatusService < BaseService end def unpush_from_public_timelines(status) - return unless status.public_visibility? + return unless status.public_visibility? && status.id > @status_id_cutoff - payload = @json_payloads[status.id] + payload = Oj.dump(event: :delete, payload: status.id.to_s) redis.publish('timeline:public', payload) redis.publish(status.local? ? 'timeline:public:local' : 'timeline:public:remote', payload) @@ -95,7 +85,7 @@ class BatchedRemoveStatusService < BaseService redis.publish(status.local? ? 'timeline:public:local:media' : 'timeline:public:remote:media', payload) end - @tags[status.id].each do |hashtag| + status.tags.map { |tag| tag.name.mb_chars.downcase }.each do |hashtag| redis.publish("timeline:hashtag:#{hashtag}", payload) redis.publish("timeline:hashtag:#{hashtag}:local", payload) if status.local? end diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb index 5123a4697..58f6ef2ab 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -46,10 +46,12 @@ class DeleteAccountService < BaseService featured_tags follow_requests identity_proofs + list_accounts migrations mute_relationships muted_by_relationships notifications + owned_lists scheduled_statuses status_pins ) @@ -145,15 +147,14 @@ class DeleteAccountService < BaseService purge_media_attachments! purge_polls! purge_generated_notifications! + purge_feeds! purge_other_associations! @account.destroy unless keep_account_record? end def purge_statuses! - @account.statuses.reorder(nil).find_in_batches do |statuses| - statuses.reject! { |status| reported_status_ids.include?(status.id) } if keep_account_record? - + @account.statuses.reorder(nil).where.not(id: reported_status_ids).in_batches do |statuses| BatchedRemoveStatusService.new.call(statuses, skip_side_effects: skip_side_effects?) end end @@ -167,11 +168,7 @@ class DeleteAccountService < BaseService end def purge_polls! - @account.polls.reorder(nil).find_each do |poll| - next if keep_account_record? && reported_status_ids.include?(poll.status_id) - - poll.delete - end + @account.polls.reorder(nil).where.not(status_id: reported_status_ids).in_batches.delete_all end def purge_generated_notifications! @@ -187,6 +184,13 @@ class DeleteAccountService < BaseService end end + def purge_feeds! + return unless @account.local? + + FeedManager.instance.clean_feeds!(:home, [@account.id]) + FeedManager.instance.clean_feeds!(:list, @account.owned_lists.pluck(:id)) + end + def purge_profile! # If the account is going to be destroyed # there is no point wasting time updating diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb index 458fe6193..42b29f4ec 100644 --- a/app/workers/scheduler/feed_cleanup_scheduler.rb +++ b/app/workers/scheduler/feed_cleanup_scheduler.rb @@ -14,37 +14,11 @@ class Scheduler::FeedCleanupScheduler private def clean_home_feeds! - clean_feeds!(inactive_account_ids, :home) + feed_manager.clean_feeds!(:home, inactive_account_ids) end def clean_list_feeds! - clean_feeds!(inactive_list_ids, :list) - end - - def clean_feeds!(ids, type) - reblogged_id_sets = {} - - redis.pipelined do - ids.each do |feed_id| - redis.del(feed_manager.key(type, feed_id)) - reblog_key = feed_manager.key(type, feed_id, 'reblogs') - # We collect a future for this: we don't block while getting - # it, but we can iterate over it later. - reblogged_id_sets[feed_id] = redis.zrange(reblog_key, 0, -1) - redis.del(reblog_key) - end - end - - # Remove all of the reblog tracking keys we just removed the - # references to. - redis.pipelined do - reblogged_id_sets.each do |feed_id, future| - future.value.each do |reblogged_id| - reblog_set_key = feed_manager.key(type, feed_id, "reblogs:#{reblogged_id}") - redis.del(reblog_set_key) - end - end - end + feed_manager.clean_feeds!(:list, inactive_list_ids) end def inactive_account_ids diff --git a/spec/services/batched_remove_status_service_spec.rb b/spec/services/batched_remove_status_service_spec.rb index 239859f06..c1f54a6fd 100644 --- a/spec/services/batched_remove_status_service_spec.rb +++ b/spec/services/batched_remove_status_service_spec.rb @@ -43,10 +43,6 @@ RSpec.describe BatchedRemoveStatusService, type: :service do expect(Redis.current).to have_received(:publish).with("timeline:#{jeff.id}", any_args).at_least(:once) end - it 'notifies streaming API of author' do - expect(Redis.current).to have_received(:publish).with("timeline:#{alice.id}", any_args).at_least(:once) - end - it 'notifies streaming API of public timeline' do expect(Redis.current).to have_received(:publish).with('timeline:public', any_args).at_least(:once) end From 2ab3e91eaf6c386f3933d79007ca87215397f06c Mon Sep 17 00:00:00 2001 From: ThibG Date: Wed, 23 Dec 2020 00:04:52 +0100 Subject: [PATCH 6/9] Fix BatchedRemoveStatusService not working without ES in rails console (#15408) Not a huge deal but may cause surprising failures in custom scripts and development. Co-authored-by: Claire --- app/services/batched_remove_status_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index 61617d958..5000062e4 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -31,7 +31,7 @@ class BatchedRemoveStatusService < BaseService # Since we skipped all callbacks, we also need to manually # deindex the statuses - Chewy.strategy.current.update(StatusesIndex, statuses_and_reblogs) + Chewy.strategy.current.update(StatusesIndex, statuses_and_reblogs) if Chewy.enabled? return if options[:skip_side_effects] From 62e42bd15be081596773d2b29009e437ebf27d8b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 23 Dec 2020 00:10:58 +0100 Subject: [PATCH 7/9] New Crowdin updates (#15369) * New translations doorkeeper.en.yml (Esperanto) [ci skip] * New translations doorkeeper.en.yml (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.yml (Greek) [ci skip] * New translations doorkeeper.en.yml (Standard Moroccan Tamazight) [ci skip] * New translations en.json (Romanian) [ci skip] * New translations en.yml (Icelandic) [ci skip] * New translations en.json (Esperanto) [ci skip] * New translations en.json (Thai) [ci skip] * New translations simple_form.en.yml (Thai) [ci skip] * New translations en.yml (Thai) [ci skip] * New translations simple_form.en.yml (Galician) [ci skip] * New translations simple_form.en.yml (Romanian) [ci skip] * New translations en.yml (Tatar) [ci skip] * New translations en.json (Tatar) [ci skip] * New translations en.yml (Standard Moroccan Tamazight) [ci skip] * New translations en.json (Standard Moroccan Tamazight) [ci skip] * New translations doorkeeper.en.yml (Sardinian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations doorkeeper.en.yml (Romanian) [ci skip] * New translations doorkeeper.en.yml (Chinese Traditional, Hong Kong) [ci skip] * New translations en.json (Bulgarian) [ci skip] * New translations simple_form.en.yml (Catalan) [ci skip] * New translations en.yml (Catalan) [ci skip] * New translations doorkeeper.en.yml (Bulgarian) [ci skip] * New translations simple_form.en.yml (Bulgarian) [ci skip] * New translations en.yml (Bulgarian) [ci skip] * New translations doorkeeper.en.yml (Arabic) [ci skip] * New translations en.yml (French) [ci skip] * New translations simple_form.en.yml (Arabic) [ci skip] * New translations en.yml (Arabic) [ci skip] * New translations en.json (Arabic) [ci skip] * New translations doorkeeper.en.yml (Spanish) [ci skip] * New translations simple_form.en.yml (Spanish) [ci skip] * New translations en.yml (Spanish) [ci skip] * New translations doorkeeper.en.yml (French) [ci skip] * New translations doorkeeper.en.yml (Sorani (Kurdish)) [ci skip] * New translations doorkeeper.en.yml (Vietnamese) [ci skip] * New translations en.yml (Czech) [ci skip] * New translations simple_form.en.yml (Greek) [ci skip] * New translations simple_form.en.yml (Dutch) [ci skip] * New translations en.yml (Dutch) [ci skip] * New translations en.json (Dutch) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.json (Armenian) [ci skip] * New translations en.json (German) [ci skip] * New translations en.yml (Chinese Simplified) [ci skip] * New translations en.json (Czech) [ci skip] * New translations en.json (Spanish) [ci skip] * New translations simple_form.en.yml (French) [ci skip] * New translations en.yml (Corsican) [ci skip] * New translations en.yml (Japanese) [ci skip] * New translations en.json (Swedish) [ci skip] * New translations simple_form.en.yml (Chinese Simplified) [ci skip] * New translations en.json (Kabyle) [ci skip] * New translations en.yml (Occitan) [ci skip] * New translations simple_form.en.yml (Sardinian) [ci skip] * New translations en.yml (Sardinian) [ci skip] * New translations en.json (Sardinian) [ci skip] * New translations simple_form.en.yml (Sorani (Kurdish)) [ci skip] * New translations en.yml (Sorani (Kurdish)) [ci skip] * New translations en.json (Sorani (Kurdish)) [ci skip] * New translations simple_form.en.yml (Chinese Traditional, Hong Kong) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.yml (Chinese Traditional, Hong Kong) [ci skip] * New translations simple_form.en.yml (Esperanto) [ci skip] * New translations en.yml (Esperanto) [ci skip] * New translations simple_form.en.yml (Chinese Traditional) [ci skip] * New translations en.yml (Chinese Traditional) [ci skip] * New translations doorkeeper.en.yml (Catalan) [ci skip] * New translations simple_form.en.yml (Czech) [ci skip] * New translations doorkeeper.en.yml (Norwegian) [ci skip] * New translations simple_form.en.yml (Norwegian) [ci skip] * New translations en.yml (Norwegian) [ci skip] * New translations en.json (Norwegian) [ci skip] * New translations doorkeeper.en.yml (Dutch) [ci skip] * New translations en.yml (Macedonian) [ci skip] * New translations simple_form.en.yml (Polish) [ci skip] * New translations en.json (Macedonian) [ci skip] * New translations en.yml (Lithuanian) [ci skip] * New translations en.json (Lithuanian) [ci skip] * New translations doorkeeper.en.yml (Korean) [ci skip] * New translations simple_form.en.yml (Korean) [ci skip] * New translations en.yml (Polish) [ci skip] * New translations doorkeeper.en.yml (Polish) [ci skip] * New translations doorkeeper.en.yml (Georgian) [ci skip] * New translations en.yml (Slovak) [ci skip] * New translations doorkeeper.en.yml (Slovenian) [ci skip] * New translations simple_form.en.yml (Slovenian) [ci skip] * New translations en.yml (Slovenian) [ci skip] * New translations en.json (Slovenian) [ci skip] * New translations doorkeeper.en.yml (Slovak) [ci skip] * New translations simple_form.en.yml (Slovak) [ci skip] * New translations en.json (Slovak) [ci skip] * New translations doorkeeper.en.yml (Russian) [ci skip] * New translations simple_form.en.yml (Russian) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations doorkeeper.en.yml (Portuguese) [ci skip] * New translations simple_form.en.yml (Portuguese) [ci skip] * New translations en.yml (Portuguese) [ci skip] * New translations en.yml (Korean) [ci skip] * New translations simple_form.en.yml (Georgian) [ci skip] * New translations doorkeeper.en.yml (Czech) [ci skip] * New translations doorkeeper.en.yml (Greek) [ci skip] * New translations en.yml (Finnish) [ci skip] * New translations en.json (Finnish) [ci skip] * New translations doorkeeper.en.yml (Basque) [ci skip] * New translations simple_form.en.yml (Basque) [ci skip] * New translations en.yml (Basque) [ci skip] * New translations en.json (Basque) [ci skip] * New translations en.json (Greek) [ci skip] * New translations doorkeeper.en.yml (Finnish) [ci skip] * New translations doorkeeper.en.yml (German) [ci skip] * New translations simple_form.en.yml (German) [ci skip] * New translations en.yml (German) [ci skip] * New translations doorkeeper.en.yml (Danish) [ci skip] * New translations simple_form.en.yml (Danish) [ci skip] * New translations en.yml (Danish) [ci skip] * New translations en.json (Danish) [ci skip] * New translations simple_form.en.yml (Finnish) [ci skip] * New translations en.json (Hebrew) [ci skip] * New translations en.yml (Georgian) [ci skip] * New translations en.json (Georgian) [ci skip] * New translations doorkeeper.en.yml (Japanese) [ci skip] * New translations simple_form.en.yml (Japanese) [ci skip] * New translations doorkeeper.en.yml (Italian) [ci skip] * New translations simple_form.en.yml (Italian) [ci skip] * New translations en.yml (Italian) [ci skip] * New translations doorkeeper.en.yml (Armenian) [ci skip] * New translations en.yml (Hebrew) [ci skip] * New translations simple_form.en.yml (Armenian) [ci skip] * New translations doorkeeper.en.yml (Hungarian) [ci skip] * New translations simple_form.en.yml (Hungarian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations doorkeeper.en.yml (Hebrew) [ci skip] * New translations simple_form.en.yml (Hebrew) [ci skip] * New translations simple_form.en.yml (Vietnamese) [ci skip] * New translations en.json (Turkish) [ci skip] * New translations en.yml (French) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.yml (Spanish, Argentina) [ci skip] * New translations en.json (French) [ci skip] * New translations en.yml (Vietnamese) [ci skip] * New translations en.json (French) [ci skip] * New translations en.yml (Galician) [ci skip] * New translations en.yml (Galician) [ci skip] * New translations en.yml (Catalan) [ci skip] * New translations en.yml (Occitan) [ci skip] * New translations en.json (Occitan) [ci skip] * New translations en.yml (Polish) [ci skip] * New translations en.yml (Greek) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.json (German) [ci skip] * New translations en.json (German) [ci skip] * New translations en.yml (Spanish) [ci skip] * New translations en.yml (German) [ci skip] * New translations devise.en.yml (German) [ci skip] * New translations en.yml (Icelandic) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Italian) [ci skip] * New translations en.yml (Portuguese) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.json (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations simple_form.en.yml (Armenian) [ci skip] * New translations simple_form.en.yml (Armenian) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.yml (Korean) [ci skip] * New translations en.yml (Korean) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.yml (Chinese Simplified) [ci skip] * New translations en.yml (Chinese Simplified) [ci skip] * New translations en.json (Chinese Simplified) [ci skip] * New translations en.json (Chinese Simplified) [ci skip] * New translations en.json (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations en.yml (Occitan) [ci skip] * New translations simple_form.en.yml (Occitan) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Vietnamese) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations simple_form.en.yml (Malayalam) [ci skip] * New translations en.json (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations devise.en.yml (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations devise.en.yml (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations devise.en.yml (Chinese Traditional) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations devise.en.yml (Chinese Traditional) [ci skip] * New translations en.json (Dutch) [ci skip] * New translations en.yml (Dutch) [ci skip] * New translations en.yml (Dutch) [ci skip] * New translations simple_form.en.yml (Dutch) [ci skip] * New translations en.yml (Dutch) [ci skip] * New translations simple_form.en.yml (Dutch) [ci skip] * New translations en.yml (Dutch) [ci skip] * New translations en.yml (Chinese Traditional) [ci skip] * New translations en.yml (Chinese Traditional) [ci skip] * New translations en.yml (Chinese Traditional) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations en.yml (Malayalam) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.yml (Indonesian) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations activerecord.en.yml (Kabyle) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Malayalam) [ci skip] * New translations en.json (Croatian) [ci skip] * New translations en.json (Croatian) [ci skip] * New translations en.json (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.yml (Armenian) [ci skip] * New translations en.json (Esperanto) [ci skip] * New translations en.json (Esperanto) [ci skip] * i18n-tasks normalize * yarn manage:translations --- app/javascript/mastodon/locales/de.json | 12 +- app/javascript/mastodon/locales/eo.json | 10 +- app/javascript/mastodon/locales/fr.json | 2 +- app/javascript/mastodon/locales/hr.json | 20 +- app/javascript/mastodon/locales/hy.json | 10 +- app/javascript/mastodon/locales/ml.json | 264 ++++++++++----------- app/javascript/mastodon/locales/nl.json | 12 +- app/javascript/mastodon/locales/oc.json | 12 +- app/javascript/mastodon/locales/tr.json | 4 +- app/javascript/mastodon/locales/vi.json | 2 +- app/javascript/mastodon/locales/zh-CN.json | 22 +- app/javascript/mastodon/locales/zh-TW.json | 256 ++++++++++---------- config/locales/activerecord.kab.yml | 2 +- config/locales/ca.yml | 1 + config/locales/de.yml | 5 + config/locales/devise.zh-TW.yml | 30 +-- config/locales/el.yml | 1 + config/locales/es-AR.yml | 1 + config/locales/es.yml | 1 + config/locales/fr.yml | 1 + config/locales/gl.yml | 5 + config/locales/hu.yml | 41 ++-- config/locales/hy.yml | 48 +++- config/locales/id.yml | 1 + config/locales/is.yml | 1 + config/locales/it.yml | 1 + config/locales/ko.yml | 4 + config/locales/ml.yml | 89 ++++++- config/locales/nl.yml | 21 ++ config/locales/oc.yml | 10 + config/locales/pl.yml | 1 + config/locales/pt-PT.yml | 1 + config/locales/simple_form.hy.yml | 2 + config/locales/simple_form.ml.yml | 4 + config/locales/simple_form.nl.yml | 3 +- config/locales/simple_form.oc.yml | 1 + config/locales/sq.yml | 1 + config/locales/vi.yml | 1 + config/locales/zh-CN.yml | 8 +- config/locales/zh-TW.yml | 28 +++ 40 files changed, 587 insertions(+), 352 deletions(-) diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index c2bb08596..1c1773029 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -149,7 +149,7 @@ "emoji_button.search_results": "Suchergebnisse", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Reisen und Orte", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Konto gesperrt", "empty_column.account_timeline": "Keine Beiträge!", "empty_column.account_unavailable": "Konto nicht verfügbar", "empty_column.blocks": "Du hast keine Profile blockiert.", @@ -266,9 +266,9 @@ "lists.edit.submit": "Titel ändern", "lists.new.create": "Liste hinzufügen", "lists.new.title_placeholder": "Neuer Titel der Liste", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.followed": "Jeder gefolgte Benutzer", + "lists.replies_policy.list": "Mitglieder der Liste", + "lists.replies_policy.none": "Niemand", "lists.replies_policy.title": "Antworten anzeigen für:", "lists.search": "Suche nach Leuten denen du folgst", "lists.subheading": "Deine Listen", @@ -334,12 +334,12 @@ "notifications.filter.mentions": "Erwähnungen", "notifications.filter.polls": "Ergebnisse der Umfrage", "notifications.filter.statuses": "Updates von Personen, denen du folgst", - "notifications.grant_permission": "Grant permission.", + "notifications.grant_permission": "Zugriff gewährt.", "notifications.group": "{count} Benachrichtigungen", "notifications.mark_as_read": "Alle Benachrichtigungen als gelesen markieren", "notifications.permission_denied": "Desktop-Benachrichtigungen können nicht aktiviert werden, da die Berechtigung verweigert wurde.", "notifications.permission_denied_alert": "Desktop-Benachrichtigungen können nicht aktiviert werden, da die Browser-Berechtigung zuvor verweigert wurde", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.permission_required": "Desktop-Benachrichtigungen sind nicht verfügbar, da die erforderliche Berechtigung nicht erteilt wurde.", "notifications_permission_banner.enable": "Aktiviere Desktop-Benachrichtigungen", "notifications_permission_banner.how_to_control": "Um Benachrichtigungen zu erhalten, wenn Mastodon nicht geöffnet ist, aktiviere die Desktop-Benachrichtigungen. Du kannst genau bestimmen, welche Arten von Interaktionen Desktop-Benachrichtigungen über die {icon} -Taste erzeugen, sobald diese aktiviert sind.", "notifications_permission_banner.title": "Verpasse nie etwas", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 57e3208fb..5cff6c5af 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -353,13 +353,13 @@ "poll_button.add_poll": "Aldoni balotenketon", "poll_button.remove_poll": "Forigi balotenketon", "privacy.change": "Agordi mesaĝan privatecon", - "privacy.direct.long": "Afiŝi nur al menciitaj uzantoj", + "privacy.direct.long": "Videbla nur al menciitaj uzantoj", "privacy.direct.short": "Rekta", - "privacy.private.long": "Afiŝi nur al sekvantoj", - "privacy.private.short": "Nur por sekvantoj", - "privacy.public.long": "Afiŝi en publikaj tempolinioj", + "privacy.private.long": "Videbla nur al viaj sekvantoj", + "privacy.private.short": "Nur al sekvantoj", + "privacy.public.long": "Videbla al ĉiuj, afiŝita en publikaj tempolinioj", "privacy.public.short": "Publika", - "privacy.unlisted.long": "Ne afiŝi en publikaj tempolinioj", + "privacy.unlisted.long": "Videbla al ĉiuj, sed ne en publikaj tempolinioj", "privacy.unlisted.short": "Nelistigita", "refresh": "Refreŝigu", "regeneration_indicator.label": "Ŝargado…", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 0ea82acbc..214f3aeea 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -438,7 +438,7 @@ "tabs_bar.local_timeline": "Fil public local", "tabs_bar.notifications": "Notifications", "tabs_bar.search": "Chercher", - "time_remaining.days": "{number, plural, one {# day} other {# days}} restants", + "time_remaining.days": "{number, plural, one {# jour} other {# jours}} restant·s", "time_remaining.hours": "{number, plural, one {# heure} other {# heures}} restantes", "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} restantes", "time_remaining.moments": "Encore quelques instants", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index 0b4ce2235..f1b78eda4 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -134,7 +134,7 @@ "directory.new_arrivals": "New arrivals", "directory.recently_active": "Nedavno aktivni", "embed.instructions": "Embed this status on your website by copying the code below.", - "embed.preview": "Here is what it will look like:", + "embed.preview": "Evo kako će izgledati:", "emoji_button.activity": "Aktivnost", "emoji_button.custom": "Prilagođeno", "emoji_button.flags": "Zastave", @@ -149,7 +149,7 @@ "emoji_button.search_results": "Rezultati pretraživanja", "emoji_button.symbols": "Simboli", "emoji_button.travel": "Putovanje i mjesta", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Račun je suspendiran", "empty_column.account_timeline": "Ovdje nema tootova!", "empty_column.account_unavailable": "Profil nije dostupan", "empty_column.blocks": "Još niste blokirali nikoga.", @@ -165,7 +165,7 @@ "empty_column.home.public_timeline": "javnu vremensku crtu", "empty_column.list": "Na ovoj listi još nema ničega. Kada članovi ove liste objave nove tootove, oni će se pojaviti ovdje.", "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", - "empty_column.mutes": "You haven't muted any users yet.", + "empty_column.mutes": "Niste utišali nijednog korisnika.", "empty_column.notifications": "Još nemate obavijesti. Komunicirajte s drugima kako biste započeli razgovor.", "empty_column.public": "Ovdje nema ništa! Napišite nešto javno ili ručno pratite korisnike s drugi poslužitelja da biste ovo popunili", "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.", @@ -266,9 +266,9 @@ "lists.edit.submit": "Promijeni naslov", "lists.new.create": "Dodaj listu", "lists.new.title_placeholder": "Naziv nove liste", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.followed": "Bilo koji praćeni korisnik", + "lists.replies_policy.list": "Članovi liste", + "lists.replies_policy.none": "Nitko", "lists.replies_policy.title": "Show replies to:", "lists.search": "Traži među praćenim ljudima", "lists.subheading": "Vaše liste", @@ -277,10 +277,10 @@ "media_gallery.toggle_visible": "Sakrij {number, plural, one {sliku} other {slike}}", "missing_indicator.label": "Nije pronađeno", "missing_indicator.sublabel": "This resource could not be found", - "mute_modal.duration": "Duration", + "mute_modal.duration": "Trajanje", "mute_modal.hide_notifications": "Hide notifications from this user?", "mute_modal.indefinite": "Indefinite", - "navigation_bar.apps": "Mobile apps", + "navigation_bar.apps": "Mobilne aplikacije", "navigation_bar.blocks": "Blokirani korisnici", "navigation_bar.bookmarks": "Bookmarks", "navigation_bar.community_timeline": "Lokalna vremenska crta", @@ -336,7 +336,7 @@ "notifications.filter.statuses": "Updates from people you follow", "notifications.grant_permission": "Grant permission.", "notifications.group": "{count} obavijesti", - "notifications.mark_as_read": "Mark every notification as read", + "notifications.mark_as_read": "Označi sve obavijesti kao pročitane", "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", @@ -384,7 +384,7 @@ "search_popout.tips.status": "toot", "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", "search_popout.tips.user": "korisnik", - "search_results.accounts": "People", + "search_results.accounts": "Ljudi", "search_results.hashtags": "Hashtags", "search_results.statuses": "Toots", "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 91377d7c5..4d9d0b63e 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -128,7 +128,7 @@ "conversation.delete": "Ջնջել խօսակցութիւնը", "conversation.mark_as_read": "Նշել որպէս ընթերցուած", "conversation.open": "Դիտել խօսակցութիւնը", - "conversation.with": "{names}֊երի հետ", + "conversation.with": "{names}-ի հետ", "directory.federated": "Յայտնի դաշնեզերքից", "directory.local": "{domain} տիրոյթից միայն", "directory.new_arrivals": "Նորեկներ", @@ -268,7 +268,7 @@ "lists.new.title_placeholder": "Նոր ցանկի վերնագիր", "lists.replies_policy.followed": "Any followed user", "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.none": "Ոչ ոք", "lists.replies_policy.title": "Show replies to:", "lists.search": "Փնտրել քո հետեւած մարդկանց մեջ", "lists.subheading": "Քո ցանկերը", @@ -334,7 +334,7 @@ "notifications.filter.mentions": "Նշումները", "notifications.filter.polls": "Հարցման արդիւնքները", "notifications.filter.statuses": "Updates from people you follow", - "notifications.grant_permission": "Grant permission.", + "notifications.grant_permission": "Թոյլատրել։", "notifications.group": "{count} ծանուցում", "notifications.mark_as_read": "Համարել բոլոր ծանուցումները ընթերցած", "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", @@ -343,7 +343,7 @@ "notifications_permission_banner.enable": "Միացնել դիտարկչից ծանուցումները", "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", "notifications_permission_banner.title": "Never miss a thing", - "picture_in_picture.restore": "Put it back", + "picture_in_picture.restore": "Հետ բերել", "poll.closed": "Փակ", "poll.refresh": "Թարմացնել", "poll.total_people": "{count, plural, one {# հոգի} other {# հոգի}}", @@ -470,7 +470,7 @@ "upload_modal.detect_text": "Հայտնբերել տեքստը նկարից", "upload_modal.edit_media": "Խմբագրել մեդիան", "upload_modal.hint": "Սեղմէք եւ տեղաշարժէք նախադիտման շրջանակը՝ որ ընտրէք մանրապատկերում միշտ տեսանելի կէտը։", - "upload_modal.preparing_ocr": "Preparing OCR…", + "upload_modal.preparing_ocr": "Գրաճանաչման նախապատրաստում…", "upload_modal.preview_label": "Նախադիտում ({ratio})", "upload_progress.label": "Վերբեռնվում է…", "video.close": "Փակել տեսագրութիւնը", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index 9d7b913f9..97b4ec401 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -2,17 +2,17 @@ "account.account_note_header": "കുറിപ്പ്", "account.add_or_remove_from_list": "പട്ടികയിൽ ചേർക്കുകയോ അല്ലെങ്കിൽ മാറ്റുകയോ ചെയ്യുക", "account.badges.bot": "റോബോട്ട്", - "account.badges.group": "കൂട്ടം", - "account.block": "@{name} നെ ബ്ലോക്ക് ചെയ്യുക", + "account.badges.group": "ഗ്രൂപ്പ്", + "account.block": "@{name} -നെ തടയുക", "account.block_domain": "{domain} ൽ നിന്നുള്ള എല്ലാം മറയ്കുക", "account.blocked": "തടഞ്ഞു", "account.browse_more_on_origin_server": "യഥാർത്ഥ പ്രൊഫൈലിലേക്ക് പോവുക", "account.cancel_follow_request": "പിന്തുടരാനുള്ള അപേക്ഷ നിരസിക്കുക", "account.direct": "@{name} ന് നേരിട്ട് മെസേജ് അയക്കുക", - "account.disable_notifications": "Stop notifying me when @{name} posts", + "account.disable_notifications": "@{name} പോസ്റ്റുചെയ്യുന്നത് എന്നെ അറിയിക്കുന്നത് നിർത്തുക", "account.domain_blocked": "മേഖല മറയ്ക്കപ്പെട്ടിരിക്കുന്നു", "account.edit_profile": "പ്രൊഫൈൽ തിരുത്തുക", - "account.enable_notifications": "Notify me when @{name} posts", + "account.enable_notifications": "@{name} പോസ്റ്റ് ചെയ്യുമ്പോൾ എന്നെ അറിയിക്കുക", "account.endorse": "പ്രൊഫൈലിൽ പ്രകടമാക്കുക", "account.follow": "പിന്തുടരുക", "account.followers": "പിന്തുടരുന്നവർ", @@ -67,7 +67,7 @@ "column.domain_blocks": "മറയ്ക്കപ്പെട്ട മേഖലകൾ", "column.favourites": "പ്രിയപ്പെട്ടവ", "column.follow_requests": "പിന്തുടരാനുള്ള അഭ്യർത്ഥനകൾ", - "column.home": "ഭവനം", + "column.home": "ഹോം", "column.lists": "പട്ടികകൾ", "column.mutes": "നിശബ്ദമാക്കപ്പെട്ട ഉപയോക്താക്കൾ", "column.notifications": "അറിയിപ്പുകൾ", @@ -105,17 +105,17 @@ "compose_form.spoiler.unmarked": "എഴുത്ത് മറയ്ക്കപ്പെട്ടിട്ടില്ല", "compose_form.spoiler_placeholder": "നിങ്ങളുടെ മുന്നറിയിപ്പ് ഇവിടെ എഴുതുക", "confirmation_modal.cancel": "റദ്ദാക്കുക", - "confirmations.block.block_and_report": "Block & Report", + "confirmations.block.block_and_report": "തടയുകയും റിപ്പോർട്ടും ചെയ്യുക", "confirmations.block.confirm": "തടയുക", - "confirmations.block.message": "Are you sure you want to block {name}?", + "confirmations.block.message": "{name} തടയാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുണ്ടോ?", "confirmations.delete.confirm": "മായ്ക്കുക", - "confirmations.delete.message": "Are you sure you want to delete this status?", + "confirmations.delete.message": "ഈ ടൂട്ട് ഇല്ലാതാക്കണം എന്ന് നിങ്ങൾക്ക് ഉറപ്പാണോ?", "confirmations.delete_list.confirm": "മായ്ക്കുക", - "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", - "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.delete_list.message": "ഈ പട്ടിക എന്നെന്നേക്കുമായി നീക്കം ചെയ്യാൻ നിങ്ങൾ ആഗ്രഹിക്കുന്നുണ്ടോ?", + "confirmations.domain_block.confirm": "മുഴുവൻ ഡൊമെയ്‌നും തടയുക", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", "confirmations.logout.confirm": "പുറത്തുകടക്കുക", - "confirmations.logout.message": "Are you sure you want to log out?", + "confirmations.logout.message": "നിങ്ങൾക്ക് ലോഗ് ഔട്ട് ചെയ്യണമെന്ന് ഉറപ്പാണോ?", "confirmations.mute.confirm": "നിശ്ശബ്ദമാക്കുക", "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", "confirmations.mute.message": "Are you sure you want to mute {name}?", @@ -133,7 +133,7 @@ "directory.local": "{domain} ൽ നിന്ന് മാത്രം", "directory.new_arrivals": "പുതിയ വരവുകൾ", "directory.recently_active": "അടുത്തിടെയായി സജീവമായ", - "embed.instructions": "Embed this status on your website by copying the code below.", + "embed.instructions": "ചുവടെയുള്ള കോഡ് പകർത്തിക്കൊണ്ട് നിങ്ങളുടെ വെബ്‌സൈറ്റിൽ ഈ ടൂട്ട് ഉൾച്ചേർക്കുക.", "embed.preview": "ഇത് ഇങ്ങനെ കാണപ്പെടും:", "emoji_button.activity": "പ്രവര്‍ത്തനം", "emoji_button.custom": "സ്വന്തമായ ഭേദഗതി", @@ -141,7 +141,7 @@ "emoji_button.food": "ഭക്ഷണവും പാനീയവും", "emoji_button.label": "ഇമോജി ചേർക്കുക", "emoji_button.nature": "പ്രകൃതി", - "emoji_button.not_found": "എമോജി പാടില്ല (╯°□°)╯︵ ┻━┻", + "emoji_button.not_found": "ഇമോജി പാടില്ല (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "വസ്തുക്കൾ", "emoji_button.people": "ആളുകൾ", "emoji_button.recent": "അടിക്കടി ഉപയോഗിക്കുന്നവ", @@ -149,7 +149,7 @@ "emoji_button.search_results": "തിരച്ചിൽ ഫലങ്ങൾ", "emoji_button.symbols": "ചിഹ്നങ്ങൾ", "emoji_button.travel": "യാത്രയും സ്ഥലങ്ങളും", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "അക്കൗണ്ട് താൽക്കാലികമായി നിർത്തിവച്ചു", "empty_column.account_timeline": "ഇവിടെ ടൂട്ടുകൾ ഇല്ല!", "empty_column.account_unavailable": "പ്രൊഫൈൽ ലഭ്യമല്ല", "empty_column.blocks": "നിങ്ങൾ ഇതുവരെ ഒരു ഉപയോക്താക്കളെയും തടഞ്ഞിട്ടില്ല.", @@ -160,7 +160,7 @@ "empty_column.favourited_statuses": "നിങ്ങൾക്ക് ഇത് വരെ ഒരു പ്രിയപ്പെട്ട ടൂട്ടും ഇല്ല. നിങ്ങൾ അങ്ങനെ ഒന്ന് പ്രിയപ്പെടുന്ന പക്ഷം അതിവിടെ കാണപ്പെടുന്നതാണ്.", "empty_column.favourites": "ഇതുവരെ ആരും ഈ ടൂട്ട് പ്രിയപ്പെട്ടതായി അടയാളപ്പെടുത്തിയിട്ടില്ല. ആരെങ്കിലും അങ്ങനെ ചെയ്യുന്നപക്ഷം അതിവിടെ കാണപ്പെടുന്നതാണ്.", "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", - "empty_column.hashtag": "There is nothing in this hashtag yet.", + "empty_column.hashtag": "ഈ ഹാഷ്‌ടാഗിൽ ഇതുവരെ ഒന്നുമില്ല.", "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", "empty_column.home.public_timeline": "പൊതു സമയരേഖ", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", @@ -179,7 +179,7 @@ "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.", "generic.saved": "സംരക്ഷിച്ചു", "getting_started.developers": "വികസിപ്പിക്കുന്നവർ", - "getting_started.directory": "രൂപരേഖ നാമഗൃഹസൂചി", + "getting_started.directory": "പ്രൊഫൈൽ ഡയറക്ടറി", "getting_started.documentation": "രേഖാ സമാഹരണം", "getting_started.heading": "തുടക്കം കുറിക്കുക", "getting_started.invite": "ആളുകളെ ക്ഷണിക്കുക", @@ -190,7 +190,7 @@ "hashtag.column_header.tag_mode.any": "അല്ലെങ്കിൽ {additional}", "hashtag.column_header.tag_mode.none": "{additional} ഇല്ലാതെ", "hashtag.column_settings.select.no_options_message": "ഒരു സൂചനയും കണ്ടെത്തിയില്ല", - "hashtag.column_settings.select.placeholder": "ചർച്ചാവിഷയങ്ങൾ എഴുതുക…", + "hashtag.column_settings.select.placeholder": "ഹാഷ്ടാഗുകൾ എഴുതുക…", "hashtag.column_settings.tag_mode.all": "ഇവയെല്ലാം", "hashtag.column_settings.tag_mode.any": "ഇവയിലേതെങ്കിലും", "hashtag.column_settings.tag_mode.none": "ഇതിലൊന്നുമല്ല", @@ -206,7 +206,7 @@ "introduction.federation.action": "അടുത്തത്", "introduction.federation.federated.headline": "സംയുക്തമാക്കിയ", "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", - "introduction.federation.home.headline": "ഭവനം", + "introduction.federation.home.headline": "ഹോം", "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.local.headline": "പ്രാദേശികം", "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", @@ -233,17 +233,17 @@ "keyboard_shortcuts.favourites": "to open favourites list", "keyboard_shortcuts.federated": "to open federated timeline", "keyboard_shortcuts.heading": "കീബോർഡ് എളുപ്പവഴികൾ", - "keyboard_shortcuts.home": "to open home timeline", + "keyboard_shortcuts.home": "ഹോം ടൈംലൈൻ തുറക്കുന്നതിന്", "keyboard_shortcuts.hotkey": "Hotkey", "keyboard_shortcuts.legend": "to display this legend", - "keyboard_shortcuts.local": "to open local timeline", + "keyboard_shortcuts.local": "പ്രാദേശിക സമയരേഖ തുറക്കാൻ", "keyboard_shortcuts.mention": "to mention author", "keyboard_shortcuts.muted": "to open muted users list", - "keyboard_shortcuts.my_profile": "to open your profile", + "keyboard_shortcuts.my_profile": "നിങ്ങളുടെ പ്രൊഫൈൽ തുറക്കാൻ", "keyboard_shortcuts.notifications": "to open notifications column", - "keyboard_shortcuts.open_media": "to open media", + "keyboard_shortcuts.open_media": "മീഡിയ തുറക്കാൻ", "keyboard_shortcuts.pinned": "to open pinned toots list", - "keyboard_shortcuts.profile": "to open author's profile", + "keyboard_shortcuts.profile": "രചയിതാവിന്റെ പ്രൊഫൈൽ തുറക്കുന്നതിന്", "keyboard_shortcuts.reply": "മറുപടി അയക്കാൻ", "keyboard_shortcuts.requests": "to open follow requests list", "keyboard_shortcuts.search": "to focus search", @@ -268,7 +268,7 @@ "lists.new.title_placeholder": "New list title", "lists.replies_policy.followed": "Any followed user", "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.none": "ആരുമില്ല", "lists.replies_policy.title": "Show replies to:", "lists.search": "Search among people you follow", "lists.subheading": "എന്റെ പട്ടികകൾ", @@ -277,208 +277,208 @@ "media_gallery.toggle_visible": "Hide {number, plural, one {image} other {images}}", "missing_indicator.label": "കാണാനില്ല", "missing_indicator.sublabel": "This resource could not be found", - "mute_modal.duration": "Duration", + "mute_modal.duration": "കാലാവധി", "mute_modal.hide_notifications": "Hide notifications from this user?", - "mute_modal.indefinite": "Indefinite", - "navigation_bar.apps": "Mobile apps", - "navigation_bar.blocks": "Blocked users", - "navigation_bar.bookmarks": "അടയാളങ്ങൾ", - "navigation_bar.community_timeline": "Local timeline", + "mute_modal.indefinite": "അനിശ്ചിതകാല", + "navigation_bar.apps": "മൊബൈൽ ആപ്പുകൾ", + "navigation_bar.blocks": "തടയപ്പെട്ട ഉപയോക്താക്കൾ", + "navigation_bar.bookmarks": "ബുക്ക്മാർക്കുകൾ", + "navigation_bar.community_timeline": "പ്രാദേശിക സമയരേഖ", "navigation_bar.compose": "പുതിയ ടൂട്ട് എഴുതുക", - "navigation_bar.direct": "Direct messages", - "navigation_bar.discover": "Discover", + "navigation_bar.direct": "നേരിട്ടുള്ള സന്ദേശങ്ങൾ", + "navigation_bar.discover": "കണ്ടെത്തുക", "navigation_bar.domain_blocks": "Hidden domains", - "navigation_bar.edit_profile": "Edit profile", - "navigation_bar.favourites": "Favourites", + "navigation_bar.edit_profile": "പ്രൊഫൈൽ തിരുത്തുക", + "navigation_bar.favourites": "പ്രിയപ്പെട്ടവ", "navigation_bar.filters": "Muted words", - "navigation_bar.follow_requests": "Follow requests", + "navigation_bar.follow_requests": "പിന്തുടരാനുള്ള അഭ്യർത്ഥനകൾ", "navigation_bar.follows_and_followers": "Follows and followers", - "navigation_bar.info": "About this server", + "navigation_bar.info": "ഈ സെർവറിനെക്കുറിച്ച്", "navigation_bar.keyboard_shortcuts": "Hotkeys", - "navigation_bar.lists": "Lists", - "navigation_bar.logout": "Logout", - "navigation_bar.mutes": "Muted users", + "navigation_bar.lists": "ലിസ്റ്റുകൾ", + "navigation_bar.logout": "ലോഗൗട്ട്", + "navigation_bar.mutes": "നിശബ്ദമാക്കപ്പെട്ട ഉപയോക്താക്കൾ", "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", - "navigation_bar.preferences": "Preferences", + "navigation_bar.preferences": "ക്രമീകരണങ്ങൾ", "navigation_bar.public_timeline": "Federated timeline", - "navigation_bar.security": "Security", + "navigation_bar.security": "സുരക്ഷ", "notification.favourite": "{name} favourited your status", - "notification.follow": "{name} followed you", + "notification.follow": "{name} നിങ്ങളെ പിന്തുടർന്നു", "notification.follow_request": "{name} has requested to follow you", "notification.mention": "{name} mentioned you", - "notification.own_poll": "Your poll has ended", + "notification.own_poll": "നിങ്ങളുടെ പോൾ അവസാനിച്ചു", "notification.poll": "A poll you have voted in has ended", - "notification.reblog": "{name} boosted your status", - "notification.status": "{name} just posted", - "notifications.clear": "Clear notifications", + "notification.reblog": "{name} നിങ്ങളുടെ പോസ്റ്റ് ബൂസ്റ്റ് ചെയ്തു", + "notification.status": "{name} ഇപ്പോൾ പോസ്റ്റുചെയ്‌തു", + "notifications.clear": "അറിയിപ്പ് മായ്ക്കുക", "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", - "notifications.column_settings.alert": "Desktop notifications", - "notifications.column_settings.favourite": "Favourites:", - "notifications.column_settings.filter_bar.advanced": "Display all categories", + "notifications.column_settings.alert": "ഡെസ്ക്ടോപ്പ് അറിയിപ്പുകൾ", + "notifications.column_settings.favourite": "പ്രിയപ്പെട്ടവ:", + "notifications.column_settings.filter_bar.advanced": "എല്ലാ വിഭാഗങ്ങളും പ്രദർശിപ്പിക്കുക", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.show": "കാണിക്കുക", "notifications.column_settings.follow": "New followers:", - "notifications.column_settings.follow_request": "New follow requests:", + "notifications.column_settings.follow_request": "പുതിയ പിന്തുടരൽ അഭ്യർത്ഥനകൾ:", "notifications.column_settings.mention": "Mentions:", - "notifications.column_settings.poll": "Poll results:", + "notifications.column_settings.poll": "പോൾ ഫലങ്ങൾ:", "notifications.column_settings.push": "Push notifications", - "notifications.column_settings.reblog": "Boosts:", + "notifications.column_settings.reblog": "ബൂസ്റ്റുകൾ:", "notifications.column_settings.show": "Show in column", - "notifications.column_settings.sound": "Play sound", - "notifications.column_settings.status": "New toots:", - "notifications.filter.all": "All", - "notifications.filter.boosts": "Boosts", - "notifications.filter.favourites": "Favourites", - "notifications.filter.follows": "Follows", + "notifications.column_settings.sound": "ശബ്ദം പ്ലേ ചെയ്യുക", + "notifications.column_settings.status": "പുതിയ ടൂട്ടുകൾ:", + "notifications.filter.all": "എല്ലാം", + "notifications.filter.boosts": "ബൂസ്റ്റുകൾ", + "notifications.filter.favourites": "പ്രിയപ്പെട്ടവ", + "notifications.filter.follows": "പിന്തുടരുന്നു", "notifications.filter.mentions": "Mentions", - "notifications.filter.polls": "Poll results", - "notifications.filter.statuses": "Updates from people you follow", - "notifications.grant_permission": "Grant permission.", - "notifications.group": "{count} notifications", - "notifications.mark_as_read": "Mark every notification as read", + "notifications.filter.polls": "പോൾ ഫലങ്ങൾ", + "notifications.filter.statuses": "നിങ്ങൾ പിന്തുടരുന്ന ആളുകളിൽ നിന്നുള്ള അപ്‌ഡേറ്റുകൾ", + "notifications.grant_permission": "അനുമതി നൽകുക.", + "notifications.group": "{count} അറിയിപ്പുകൾ", + "notifications.mark_as_read": "എല്ലാ അറിയിപ്പുകളും വായിച്ചതായി അടയാളപ്പെടുത്തുക", "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", - "notifications_permission_banner.enable": "Enable desktop notifications", + "notifications_permission_banner.enable": "ഡെസ്ക്ടോപ്പ് അറിയിപ്പുകൾ പ്രാപ്തമാക്കുക", "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", "notifications_permission_banner.title": "Never miss a thing", - "picture_in_picture.restore": "Put it back", - "poll.closed": "Closed", - "poll.refresh": "Refresh", + "picture_in_picture.restore": "തിരികെ വയ്ക്കുക", + "poll.closed": "അടച്ചു", + "poll.refresh": "പുതുക്കുക", "poll.total_people": "{count, plural, one {# person} other {# people}}", "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", - "poll.vote": "Vote", + "poll.vote": "വോട്ട് ചെയ്യുക", "poll.voted": "You voted for this answer", - "poll_button.add_poll": "Add a poll", - "poll_button.remove_poll": "Remove poll", + "poll_button.add_poll": "ഒരു പോൾ ചേർക്കുക", + "poll_button.remove_poll": "പോൾ നീക്കംചെയ്യുക", "privacy.change": "Adjust status privacy", "privacy.direct.long": "Post to mentioned users only", - "privacy.direct.short": "Direct", + "privacy.direct.short": "നേരിട്ട്", "privacy.private.long": "Post to followers only", "privacy.private.short": "Followers-only", "privacy.public.long": "Post to public timelines", "privacy.public.short": "Public", "privacy.unlisted.long": "Do not show in public timelines", "privacy.unlisted.short": "Unlisted", - "refresh": "Refresh", - "regeneration_indicator.label": "Loading…", - "regeneration_indicator.sublabel": "Your home feed is being prepared!", + "refresh": "പുതുക്കുക", + "regeneration_indicator.label": "ലഭ്യമാക്കുന്നു…", + "regeneration_indicator.sublabel": "നിങ്ങളുടെ ഹോം ഫീഡ് തയാറാക്കുന്നു!", "relative_time.days": "{number}d", "relative_time.hours": "{number}h", - "relative_time.just_now": "now", + "relative_time.just_now": "ഇപ്പോൾ", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", - "relative_time.today": "today", - "reply_indicator.cancel": "Cancel", + "relative_time.today": "ഇന്ന്", + "reply_indicator.cancel": "റദ്ദാക്കുക", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", - "report.placeholder": "Additional comments", - "report.submit": "Submit", + "report.placeholder": "കൂടുതൽ അഭിപ്രായങ്ങൾ", + "report.submit": "സമർപ്പിക്കുക", "report.target": "Report {target}", - "search.placeholder": "Search", + "search.placeholder": "തിരയുക", "search_popout.search_format": "Advanced search format", "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", - "search_popout.tips.hashtag": "hashtag", - "search_popout.tips.status": "status", + "search_popout.tips.hashtag": "ഹാഷ്ടാഗ്", + "search_popout.tips.status": "ടൂട്ട്", "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", - "search_popout.tips.user": "user", - "search_results.accounts": "People", - "search_results.hashtags": "Hashtags", - "search_results.statuses": "Toots", + "search_popout.tips.user": "ഉപയോക്താവ്", + "search_results.accounts": "ആളുകൾ", + "search_results.hashtags": "ഹാഷ്ടാഗുകൾ", + "search_results.statuses": "ടൂട്ടുകൾ", "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", "search_results.total": "{count, number} {count, plural, one {result} other {results}}", "status.admin_account": "Open moderation interface for @{name}", "status.admin_status": "Open this status in the moderation interface", - "status.block": "Block @{name}", - "status.bookmark": "Bookmark", + "status.block": "@{name} -നെ തടയുക", + "status.bookmark": "ബുക്ക്മാർക്ക്", "status.cancel_reblog_private": "Unboost", - "status.cannot_reblog": "This post cannot be boosted", - "status.copy": "Copy link to status", + "status.cannot_reblog": "ഈ പോസ്റ്റ് ബൂസ്റ്ചെയ്യാൻ കഴിയില്ല", + "status.copy": "ടൂട്ടിലേക്ക് ലിങ്ക് പകർത്തുക", "status.delete": "മായ്ക്കുക", "status.detailed_status": "വിശദമായ സംഭാഷണ കാഴ്‌ച", "status.direct": "@{name} ന് നേരിട്ട് മെസേജ് അയക്കുക", "status.embed": "ഉൾച്ചേർക്കുക", "status.favourite": "പ്രിയപ്പെട്ടത്", - "status.filtered": "Filtered", + "status.filtered": "ഫിൽട്ടർ ചെയ്‌തു", "status.load_more": "കൂടുതൽ ലോഡു ചെയ്യുക", - "status.media_hidden": "Media hidden", + "status.media_hidden": "മീഡിയ മറച്ചു", "status.mention": "@{name} സൂചിപ്പിക്കുക", - "status.more": "More", - "status.mute": "Mute @{name}", + "status.more": "കൂടുതൽ", + "status.mute": "@{name}-നെ നിശ്ശബ്ദമാക്കുക", "status.mute_conversation": "Mute conversation", "status.open": "Expand this status", "status.pin": "Pin on profile", "status.pinned": "Pinned toot", - "status.read_more": "Read more", - "status.reblog": "Boost", + "status.read_more": "കൂടുതൽ വായിക്കുക", + "status.reblog": "ബൂസ്റ്റ്", "status.reblog_private": "Boost with original visibility", - "status.reblogged_by": "{name} boosted", + "status.reblogged_by": "{name} ബൂസ്റ്റ് ചെയ്തു", "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", - "status.redraft": "Delete & re-draft", - "status.remove_bookmark": "Remove bookmark", - "status.reply": "Reply", + "status.redraft": "ഇല്ലാതാക്കുക & വീണ്ടും ഡ്രാഫ്റ്റ് ചെയ്യുക", + "status.remove_bookmark": "ബുക്ക്മാർക്ക് നീക്കംചെയ്യുക", + "status.reply": "മറുപടി", "status.replyAll": "Reply to thread", "status.report": "Report @{name}", "status.sensitive_warning": "Sensitive content", - "status.share": "Share", - "status.show_less": "Show less", + "status.share": "പങ്കിടുക", + "status.show_less": "കുറച്ച് കാണിക്കുക", "status.show_less_all": "Show less for all", - "status.show_more": "Show more", - "status.show_more_all": "Show more for all", + "status.show_more": "കൂടുതകൽ കാണിക്കുക", + "status.show_more_all": "എല്ലാവർക്കുമായി കൂടുതൽ കാണിക്കുക", "status.show_thread": "Show thread", - "status.uncached_media_warning": "Not available", + "status.uncached_media_warning": "ലഭ്യമല്ല", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", - "suggestions.header": "You might be interested in…", - "tabs_bar.federated_timeline": "Federated", - "tabs_bar.home": "Home", - "tabs_bar.local_timeline": "Local", - "tabs_bar.notifications": "Notifications", - "tabs_bar.search": "Search", + "suggestions.header": "നിങ്ങൾക്ക് താൽപ്പര്യമുണ്ടാകാം…", + "tabs_bar.federated_timeline": "സംയുക്തമാക്കിയ", + "tabs_bar.home": "ഹോം", + "tabs_bar.local_timeline": "പ്രാദേശികം", + "tabs_bar.notifications": "അറിയിപ്പുകൾ", + "tabs_bar.search": "തിരയുക", "time_remaining.days": "{number, plural, one {# day} other {# days}} left", "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left", "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left", "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.", - "timeline_hint.resources.followers": "Followers", - "timeline_hint.resources.follows": "Follows", - "timeline_hint.resources.statuses": "Older toots", + "timeline_hint.resources.followers": "പിന്തുടരുന്നവർ", + "timeline_hint.resources.follows": "പിന്തുടരുന്നു", + "timeline_hint.resources.statuses": "പഴയ ടൂട്ടുകൾ", "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} talking", - "trends.trending_now": "Trending now", + "trends.trending_now": "ഇപ്പോൾ ട്രെൻഡിംഗ്", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "units.short.billion": "{count}B", - "units.short.million": "{count}M", + "units.short.million": "{count}ദശലക്ഷം", "units.short.thousand": "{count}K", - "upload_area.title": "Drag & drop to upload", - "upload_button.label": "Add images, a video or an audio file", - "upload_error.limit": "File upload limit exceeded.", + "upload_area.title": "അപ്‌ലോഡുചെയ്യാൻ വലിച്ചിടുക", + "upload_button.label": "ഇമേജുകൾ, ഒരു വീഡിയോ അല്ലെങ്കിൽ ഓഡിയോ ഫയൽ ചേർക്കുക", + "upload_error.limit": "ഫയൽ അപ്‌ലോഡ് പരിധി കവിഞ്ഞു.", "upload_error.poll": "File upload not allowed with polls.", - "upload_form.audio_description": "Describe for people with hearing loss", - "upload_form.description": "Describe for the visually impaired", - "upload_form.edit": "Edit", - "upload_form.thumbnail": "Change thumbnail", - "upload_form.undo": "Delete", + "upload_form.audio_description": "കേൾവിശക്തി ഇല്ലാത്തവർക്ക് വേണ്ടി വിവരണം നൽകൂ", + "upload_form.description": "കാഴ്ചശക്തി ഇല്ലാത്തവർക്ക് വേണ്ടി വിവരണം നൽകൂ", + "upload_form.edit": "തിരുത്തുക", + "upload_form.thumbnail": "ലഘുചിത്രം മാറ്റുക", + "upload_form.undo": "ഇല്ലാതാക്കുക", "upload_form.video_description": "Describe for people with hearing loss or visual impairment", "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.choose_image": "Choose image", + "upload_modal.apply": "പ്രയോഗിക്കുക", + "upload_modal.choose_image": "ചിത്രം തിരഞ്ഞെടുക്കുക", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", + "upload_modal.edit_media": "മീഡിയ തിരുത്തുക", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", "upload_modal.preparing_ocr": "Preparing OCR…", "upload_modal.preview_label": "Preview ({ratio})", "upload_progress.label": "Uploading…", - "video.close": "Close video", - "video.download": "Download file", + "video.close": "വീഡിയോ അടയ്ക്കുക", + "video.download": "ഫയൽ ഡൌൺലോഡ് ചെയ്യുക", "video.exit_fullscreen": "Exit full screen", "video.expand": "Expand video", - "video.fullscreen": "Full screen", - "video.hide": "Hide video", + "video.fullscreen": "പൂർണ്ണ സ്ക്രീൻ", + "video.hide": "വീഡിയോ മറയ്ക്കുക", "video.mute": "Mute sound", "video.pause": "Pause", "video.play": "Play", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index c910a28ab..e19f0b6d3 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -149,7 +149,7 @@ "emoji_button.search_results": "Zoekresultaten", "emoji_button.symbols": "Symbolen", "emoji_button.travel": "Reizen en plekken", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Account opgeschort", "empty_column.account_timeline": "Hier zijn geen toots!", "empty_column.account_unavailable": "Profiel is niet beschikbaar", "empty_column.blocks": "Jij hebt nog geen enkele gebruiker geblokkeerd.", @@ -266,9 +266,9 @@ "lists.edit.submit": "Titel veranderen", "lists.new.create": "Lijst toevoegen", "lists.new.title_placeholder": "Naam nieuwe lijst", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.followed": "Elke gevolgde gebruiker", + "lists.replies_policy.list": "Leden van de lijst", + "lists.replies_policy.none": "Niemand", "lists.replies_policy.title": "Toon reacties aan:", "lists.search": "Zoek naar mensen die je volgt", "lists.subheading": "Jouw lijsten", @@ -334,12 +334,12 @@ "notifications.filter.mentions": "Vermeldingen", "notifications.filter.polls": "Pollresultaten", "notifications.filter.statuses": "Updates van mensen die je volgt", - "notifications.grant_permission": "Grant permission.", + "notifications.grant_permission": "Toestemming geven.", "notifications.group": "{count} meldingen", "notifications.mark_as_read": "Markeer elke melding als gelezen", "notifications.permission_denied": "Desktopmeldingen zijn niet beschikbaar omdat een eerdere browsertoestemming werd geweigerd", "notifications.permission_denied_alert": "Desktopmeldingen kunnen niet worden ingeschakeld, omdat een eerdere browsertoestemming werd geweigerd", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.permission_required": "Desktopmeldingen zijn niet beschikbaar omdat de benodigde toestemming niet is verleend.", "notifications_permission_banner.enable": "Desktopmeldingen inschakelen", "notifications_permission_banner.how_to_control": "Om meldingen te ontvangen wanneer Mastodon niet open is. Je kunt precies bepalen welke soort interacties wel of geen desktopmeldingen geven via de bovenstaande {icon} knop.", "notifications_permission_banner.title": "Mis nooit meer iets", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index ba41f83d6..f56d337d3 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -149,7 +149,7 @@ "emoji_button.search_results": "Resultats de recèrca", "emoji_button.symbols": "Simbòls", "emoji_button.travel": "Viatges & lòcs", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Compte suspendut", "empty_column.account_timeline": "Cap de tuts aquí !", "empty_column.account_unavailable": "Perfil pas disponible", "empty_column.blocks": "Avètz pas blocat degun pel moment.", @@ -266,9 +266,9 @@ "lists.edit.submit": "Cambiar lo títol", "lists.new.create": "Ajustar una lista", "lists.new.title_placeholder": "Títol de la nòva lista", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.followed": "Quin seguidor que siá", + "lists.replies_policy.list": "Membres de la lista", + "lists.replies_policy.none": "Degun", "lists.replies_policy.title": "Mostrar las responsas a :", "lists.search": "Cercar demest lo mond que seguètz", "lists.subheading": "Vòstras listas", @@ -334,12 +334,12 @@ "notifications.filter.mentions": "Mencions", "notifications.filter.polls": "Resultats del sondatge", "notifications.filter.statuses": "Mesas a jorn del monde que seguissètz", - "notifications.grant_permission": "Grant permission.", + "notifications.grant_permission": "Acordar l’autorizacion.", "notifications.group": "{count} notificacions", "notifications.mark_as_read": "Marcar totas las notificacions coma legidas", "notifications.permission_denied": "Las notificacion burèu son pas disponiblas a causa del refús de las demandas d’autorizacion navigador", "notifications.permission_denied_alert": "Las notificacions burèu son pas activada, per çò que las autorizacions son estadas refusada abans", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.permission_required": "Las notificacions de burèu son pas indisponiblas perque las permissions requeridas son pas estadas acordadas.", "notifications_permission_banner.enable": "Activar las notificacions burèu", "notifications_permission_banner.how_to_control": "Per recebre las notificacions de Mastodon quand es pas dobèrt, activatz las notificacions de burèu. Podètz precisar quin tipe de notificacion generarà una notificacion de burèu via lo boton {icon} dessús un còp activadas.", "notifications_permission_banner.title": "Manquetz pas jamai res", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 76407efce..1d56d169c 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -149,7 +149,7 @@ "emoji_button.search_results": "Arama sonuçları", "emoji_button.symbols": "Semboller", "emoji_button.travel": "Seyahat ve Yerler", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "Hesap askıya alındı", "empty_column.account_timeline": "Burada hiç toot yok!", "empty_column.account_unavailable": "Profil kullanılamıyor", "empty_column.blocks": "Henüz bir kullanıcıyı engellemediniz.", @@ -267,7 +267,7 @@ "lists.new.create": "Liste ekle", "lists.new.title_placeholder": "Yeni liste başlığı", "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", + "lists.replies_policy.list": "Listenin üyeleri", "lists.replies_policy.none": "No one", "lists.replies_policy.title": "Yanıtları göster:", "lists.search": "Takip ettiğiniz kişiler arasından arayın", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 4814dda91..14c74830b 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -179,7 +179,7 @@ "follow_requests.unlocked_explanation": "Mặc dù tài khoản của bạn đang ở chế độ công khai, quản trị viên của {domain} vẫn tin rằng bạn sẽ muốn xem lại yêu cầu theo dõi từ những người khác.", "generic.saved": "Đã lưu", "getting_started.developers": "Nhà phát triển", - "getting_started.directory": "Cộng đồng", + "getting_started.directory": "Mạng lưới", "getting_started.documentation": "Tài liệu", "getting_started.heading": "Quản lý", "getting_started.invite": "Mời bạn bè", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index f6af15198..6c746bf96 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -133,7 +133,7 @@ "directory.local": "仅来自 {domain}", "directory.new_arrivals": "新来者", "directory.recently_active": "最近活跃", - "embed.instructions": "要在你的网站上嵌入这条嘟文,请复制以下代码。", + "embed.instructions": "要在你的网站上嵌入此嘟文,请复制以下代码。", "embed.preview": "它会像这样显示出来:", "emoji_button.activity": "活动", "emoji_button.custom": "自定义", @@ -149,7 +149,7 @@ "emoji_button.search_results": "搜索结果", "emoji_button.symbols": "符号", "emoji_button.travel": "旅行和地点", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "账户被封禁", "empty_column.account_timeline": "这里没有嘟文!", "empty_column.account_unavailable": "个人资料不可用", "empty_column.blocks": "你目前没有屏蔽任何用户。", @@ -163,7 +163,7 @@ "empty_column.hashtag": "这个话题标签下暂时没有内容。", "empty_column.home": "你还没有关注任何用户。快看看{public},向其他人问个好吧。", "empty_column.home.public_timeline": "公共时间轴", - "empty_column.list": "这个列表中暂时没有内容。列表中用户所发送的的新嘟文将会在这里显示。", + "empty_column.list": "此列表中暂时没有内容。列表中用户所发送的的新嘟文将会在这里显示。", "empty_column.lists": "你还没有创建过列表。你创建的列表会在这里显示。", "empty_column.mutes": "你没有隐藏任何用户。", "empty_column.notifications": "你还没有收到过任何通知,快和其他用户互动吧。", @@ -266,9 +266,9 @@ "lists.edit.submit": "更改标题", "lists.new.create": "新建列表", "lists.new.title_placeholder": "新列表的标题", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", + "lists.replies_policy.followed": "任何被关注的用户", + "lists.replies_policy.list": "列表成员", + "lists.replies_policy.none": "没有人", "lists.replies_policy.title": "显示回复给:", "lists.search": "搜索你关注的人", "lists.subheading": "你的列表", @@ -334,12 +334,12 @@ "notifications.filter.mentions": "提及", "notifications.filter.polls": "投票结果", "notifications.filter.statuses": "你关注的人的动态", - "notifications.grant_permission": "Grant permission.", + "notifications.grant_permission": "授予权限", "notifications.group": "{count} 条通知", "notifications.mark_as_read": "将所有通知标为已读", "notifications.permission_denied": "由于权限被拒绝,无法启用桌面通知。", "notifications.permission_denied_alert": "由于在此之前浏览器权限请求就已被拒绝,所以启用桌面通知失败", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.permission_required": "所需权限未被授予,所以桌面通知不可用", "notifications_permission_banner.enable": "启用桌面通知", "notifications_permission_banner.how_to_control": "启用桌面通知以在 Mastodon 未打开时接收通知。您可以通过交互通过上面的 {icon} 按钮来精细控制可以发送桌面通知的交互类型。", "notifications_permission_banner.title": "精彩不容错过", @@ -403,7 +403,7 @@ "status.favourite": "喜欢", "status.filtered": "已过滤", "status.load_more": "加载更多", - "status.media_hidden": "隐藏媒体内容", + "status.media_hidden": "已隐藏的媒体内容", "status.mention": "提及 @{name}", "status.more": "更多", "status.mute": "隐藏 @{name}", @@ -429,7 +429,7 @@ "status.show_more_all": "显示所有内容", "status.show_thread": "显示全部对话", "status.uncached_media_warning": "暂不可用", - "status.unmute_conversation": "不再隐藏此对话", + "status.unmute_conversation": "将此对话解除静音", "status.unpin": "在个人资料页面取消置顶", "suggestions.dismiss": "关闭建议", "suggestions.header": "您可能会感兴趣…", @@ -454,7 +454,7 @@ "units.short.million": "{count}M", "units.short.thousand": "{count}K", "upload_area.title": "将文件拖放到此处开始上传", - "upload_button.label": "上传媒体文件", + "upload_button.label": "上传图片、视频或音频", "upload_error.limit": "文件大小超过限制。", "upload_error.poll": "投票中不允许上传文件。", "upload_form.audio_description": "为听障人士添加文字描述", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 46cfc4359..cc996e91b 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -4,27 +4,27 @@ "account.badges.bot": "機器人", "account.badges.group": "群組", "account.block": "封鎖 @{name}", - "account.block_domain": "隱藏來自 {domain} 的所有內容", + "account.block_domain": "封鎖來自 {domain} 網域的所有內容", "account.blocked": "已封鎖", - "account.browse_more_on_origin_server": "在該服務器的個人檔案頁上瀏覽更多", + "account.browse_more_on_origin_server": "在該伺服器的個人檔案頁上瀏覽更多", "account.cancel_follow_request": "取消關注請求", "account.direct": "傳私訊給 @{name}", - "account.disable_notifications": "當 @{name} 嘟文時不要再通知我", - "account.domain_blocked": "已隱藏網域", + "account.disable_notifications": "取消來自 @{name} 嘟文的通知", + "account.domain_blocked": "已封鎖網域", "account.edit_profile": "編輯個人資料", "account.enable_notifications": "當 @{name} 嘟文時通知我", "account.endorse": "在個人資料推薦對方", "account.follow": "關注", "account.followers": "關注者", - "account.followers.empty": "尚沒有人關注這位使用者。", + "account.followers.empty": "尚未有人關注這位使用者。", "account.followers_counter": "被 {count, plural,one {{counter} 人}other {{counter} 人}}關注", "account.following_counter": "正在關注 {count, plural,one {{counter}}other {{counter} 人}}", - "account.follows.empty": "這位使用者尚未關注任何使用者。", - "account.follows_you": "關注了你", - "account.hide_reblogs": "隱藏來自 @{name} 的轉推", - "account.last_status": "上次活躍", + "account.follows.empty": "這位使用者尚未關注任何人。", + "account.follows_you": "關注了您", + "account.hide_reblogs": "隱藏來自 @{name} 的轉嘟", + "account.last_status": "上次活躍時間", "account.link_verified_on": "已在 {date} 檢查此連結的擁有者權限", - "account.locked_info": "這隻帳戶的隱私狀態被設成鎖定。該擁有者會手動審核能關注這隻帳號的人。", + "account.locked_info": "此帳號的隱私狀態被設為鎖定。該擁有者會手動審核能關注此帳號的人。", "account.media": "媒體", "account.mention": "提及 @{name}", "account.moved_to": "{name} 已遷移至:", @@ -40,13 +40,13 @@ "account.show_reblogs": "顯示來自 @{name} 的嘟文", "account.statuses_counter": "{count, plural,one {{counter} 則}other {{counter} 則}}嘟文", "account.unblock": "取消封鎖 @{name}", - "account.unblock_domain": "取消隱藏 {domain}", + "account.unblock_domain": "取消封鎖域名 {domain}", "account.unendorse": "不再於個人資料頁面推薦對方", "account.unfollow": "取消關注", "account.unmute": "取消靜音 @{name}", "account.unmute_notifications": "重新接收來自 @{name} 的通知", "account_note.placeholder": "按此添加備注", - "alert.rate_limited.message": "請在 {retry_time, time, medium} 過後重試", + "alert.rate_limited.message": "請在 {retry_time, time, medium} 後重試", "alert.rate_limited.title": "已限速", "alert.unexpected.message": "發生了非預期的錯誤。", "alert.unexpected.title": "哎呀!", @@ -59,17 +59,17 @@ "bundle_modal_error.close": "關閉", "bundle_modal_error.message": "載入此元件時發生錯誤。", "bundle_modal_error.retry": "重試", - "column.blocks": "封鎖的使用者", + "column.blocks": "已封鎖的使用者", "column.bookmarks": "書籤", "column.community": "本機時間軸", "column.direct": "私訊", "column.directory": "瀏覽個人資料", - "column.domain_blocks": "隱藏的網域", - "column.favourites": "讚美集", + "column.domain_blocks": "已封鎖的網域", + "column.favourites": "收藏", "column.follow_requests": "關注請求", - "column.home": "主頁", + "column.home": "首頁", "column.lists": "名單", - "column.mutes": "被靜音的使用者", + "column.mutes": "已靜音的使用者", "column.notifications": "通知", "column.pins": "釘選的嘟文", "column.public": "聯邦時間軸", @@ -81,116 +81,116 @@ "column_header.show_settings": "顯示設定", "column_header.unpin": "取消釘選", "column_subheading.settings": "設定", - "community.column_settings.local_only": "只有本地", + "community.column_settings.local_only": "只有本機", "community.column_settings.media_only": "只有媒體", "community.column_settings.remote_only": "只有遠端", "compose_form.direct_message_warning": "這條嘟文只有被提及的使用者才看得到。", "compose_form.direct_message_warning_learn_more": "了解更多", - "compose_form.hashtag_warning": "由於這則嘟文被設定成「不公開」,所以它將不會被列在任何主題標籤下。只有公開的嘟文才能藉主題標籤找到。", + "compose_form.hashtag_warning": "由於這則嘟文設定為「不公開」,它將不會被列於任何主題標籤下。只有公開的嘟文才能藉由主題標籤找到。", "compose_form.lock_disclaimer": "您的帳戶尚未{locked}。任何人都能關注您並看到您設定成只有關注者能看的嘟文。", "compose_form.lock_disclaimer.lock": "上鎖", - "compose_form.placeholder": "您正在想些什麼?", - "compose_form.poll.add_option": "新增選擇", + "compose_form.placeholder": "正在想些什麼嗎?", + "compose_form.poll.add_option": "新增選項", "compose_form.poll.duration": "投票期限", - "compose_form.poll.option_placeholder": "第 {number} 個選擇", - "compose_form.poll.remove_option": "移除此選擇", + "compose_form.poll.option_placeholder": "第 {number} 個選項", + "compose_form.poll.remove_option": "移除此選項", "compose_form.poll.switch_to_multiple": "變更投票為允許多個選項", "compose_form.poll.switch_to_single": "變更投票為允許單一選項", "compose_form.publish": "嘟出去", "compose_form.publish_loud": "{publish}!", "compose_form.sensitive.hide": "標記媒體為敏感內容", "compose_form.sensitive.marked": "此媒體被標記為敏感內容", - "compose_form.sensitive.unmarked": "此媒體未標記為敏感內容", + "compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容", "compose_form.spoiler.marked": "正文已隱藏到警告之後", "compose_form.spoiler.unmarked": "正文未被隱藏", "compose_form.spoiler_placeholder": "請在此處寫入警告訊息", "confirmation_modal.cancel": "取消", "confirmations.block.block_and_report": "封鎖並檢舉", "confirmations.block.confirm": "封鎖", - "confirmations.block.message": "確定封鎖 {name} ?", + "confirmations.block.message": "確定要封鎖 {name} 嗎?", "confirmations.delete.confirm": "刪除", - "confirmations.delete.message": "你確定要刪除這條嘟文?", + "confirmations.delete.message": "您確定要刪除這則嘟文?", "confirmations.delete_list.confirm": "刪除", "confirmations.delete_list.message": "確定永久刪除此名單?", - "confirmations.domain_block.confirm": "隱藏整個網域", - "confirmations.domain_block.message": "真的非常確定封鎖整個 {domain} 嗎?大部分情況下,你只需要封鎖或靜音少數特定的人就能滿足需求了。你將不能在任何公開的時間軸及通知中看到那個網域的內容。你來自該網域的關注者也會被移除。", + "confirmations.domain_block.confirm": "隱藏整個域名", + "confirmations.domain_block.message": "真的非常確定封鎖整個 {domain} 網域嗎?大部分情況下,您只需要封鎖或靜音少數特定的帳號就能滿足需求了。您將不能在任何公開的時間軸及通知中看到此網域的內容。您來自該網域的關注者也將被移除。", "confirmations.logout.confirm": "登出", "confirmations.logout.message": "確定要登出嗎?", "confirmations.mute.confirm": "靜音", - "confirmations.mute.explanation": "這將會隱藏來自他們的貼文與通知,但是他們還是可以查閱你的貼文與關注你。", + "confirmations.mute.explanation": "這將會隱藏來自他們的貼文與通知,但是他們還是可以查閱你的貼文與關注您。", "confirmations.mute.message": "確定靜音 {name} ?", "confirmations.redraft.confirm": "刪除並重新編輯", - "confirmations.redraft.message": "確定刪掉這則嘟文並重新編輯嗎?將會失去這則嘟文的轉嘟及贊美,且回覆這則的嘟文將會變成獨立的嘟文。", + "confirmations.redraft.message": "確定刪掉這則嘟文並重新編輯嗎?將會失去這則嘟文的轉嘟及收藏,且回覆這則的嘟文將會變成獨立的嘟文。", "confirmations.reply.confirm": "回覆", "confirmations.reply.message": "現在回覆將蓋掉您目前正在撰寫的訊息。是否仍要回覆?", "confirmations.unfollow.confirm": "取消關注", - "confirmations.unfollow.message": "真的要取消關注 {name} 嗎?", + "confirmations.unfollow.message": "確定要取消關注 {name} 嗎?", "conversation.delete": "刪除對話", - "conversation.mark_as_read": "標為已讀", + "conversation.mark_as_read": "標記為已讀", "conversation.open": "檢視對話", "conversation.with": "與 {names}", "directory.federated": "來自已知聯邦宇宙", - "directory.local": "僅來自 {domain}", + "directory.local": "僅來自 {domain} 網域", "directory.new_arrivals": "新人", "directory.recently_active": "最近活躍", - "embed.instructions": "要嵌入此嘟文,請將以下程式碼貼進你的網站。", - "embed.preview": "他會顯示成這樣:", + "embed.instructions": "要在您的網站嵌入此嘟文,請複製以下程式碼。", + "embed.preview": "它將顯示成這樣:", "emoji_button.activity": "活動", "emoji_button.custom": "自訂", - "emoji_button.flags": "旗標", - "emoji_button.food": "飲食", + "emoji_button.flags": "旗幟", + "emoji_button.food": "食物 & 飲料", "emoji_button.label": "插入表情符號", - "emoji_button.nature": "大自然", + "emoji_button.nature": "自然", "emoji_button.not_found": "啊就沒這表情符號吼!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "物件", - "emoji_button.people": "使用者", + "emoji_button.people": "人物", "emoji_button.recent": "最常使用", "emoji_button.search": "搜尋…", "emoji_button.search_results": "搜尋結果", "emoji_button.symbols": "符號", "emoji_button.travel": "旅遊與地點", - "empty_column.account_suspended": "Account suspended", + "empty_column.account_suspended": "帳號被暫停", "empty_column.account_timeline": "這裡還沒有嘟文!", "empty_column.account_unavailable": "無法取得個人資料", - "empty_column.blocks": "你還沒有封鎖任何使用者。", - "empty_column.bookmarked_statuses": "你還沒建立任何書籤。這裡將會顯示你建立的書籤。", - "empty_column.community": "本地時間軸是空的。快公開嘟些文搶頭香啊!", + "empty_column.blocks": "您還沒有封鎖任何使用者。", + "empty_column.bookmarked_statuses": "您還沒建立任何書籤。當您建立書簽時,它將於此顯示。", + "empty_column.community": "本機時間軸是空的。快公開嘟些文搶頭香啊!", "empty_column.direct": "您還沒有任何私訊。當您私訊別人或收到私訊時,它將於此顯示。", - "empty_column.domain_blocks": "尚未隱藏任何網域。", - "empty_column.favourited_statuses": "你還沒讚美过任何嘟文。這裡將會顯示你讚美过的嘟文。", - "empty_column.favourites": "還沒人讚美這則嘟文。當有人點讚後,他們將於此列出。", + "empty_column.domain_blocks": "尚未封鎖任何網域。", + "empty_column.favourited_statuses": "您還沒收藏過任何嘟文。當您收藏嘟文時,它將於此顯示。", + "empty_column.favourites": "還沒有人收藏過這則嘟文。當有人收藏嘟文時,它將於此顯示。", "empty_column.follow_requests": "您尚未收到任何關注請求。這裡將會顯示收到的關注請求。", "empty_column.hashtag": "這個主題標籤下什麼也沒有。", "empty_column.home": "您的首頁時間軸是空的!前往 {public} 或使用搜尋功能來認識其他人。", "empty_column.home.public_timeline": "公開時間軸", "empty_column.list": "這份名單還沒有東西。當此名單的成員嘟出了新的嘟文時,它們就會顯示於此。", - "empty_column.lists": "你還沒有建立任何名單。這裡將會顯示你所建立的名單。", - "empty_column.mutes": "你尚未靜音任何使用者。", + "empty_column.lists": "您還沒有建立任何名單。這裡將會顯示您所建立的名單。", + "empty_column.mutes": "您尚未靜音任何使用者。", "empty_column.notifications": "您尚未收到任何通知,和別人互動開啟對話吧。", "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或著自己關注其他伺服器的使用者後就會有嘟文出現了", - "error.unexpected_crash.explanation": "由於發生系統故障或瀏覽器相容性問題,故無法正常顯示頁面。", + "error.unexpected_crash.explanation": "由於發生系統故障或瀏覽器相容性問題,無法正常顯示此頁面。", "error.unexpected_crash.explanation_addons": "此頁面無法被正常顯示,這可能是由瀏覽器附加元件或網頁自動翻譯工具造成的。", - "error.unexpected_crash.next_steps": "請嘗試重新整理頁面。如果狀況沒有進展,你可以使用不同的瀏覽器或 Mastodon 應用程式來檢視。", - "error.unexpected_crash.next_steps_addons": "請嘗試重新整理頁面。如果狀況沒有進展,您可以嘗試使用不同的瀏覽器或 Mastodon 應用程式來檢視。", - "errors.unexpected_crash.copy_stacktrace": "複製到剪貼簿", - "errors.unexpected_crash.report_issue": "舉報問題", + "error.unexpected_crash.next_steps": "請嘗試重新整理頁面。如果狀況沒有改善,您可以使用不同的瀏覽器或應用程式來檢視來使用 Mastodon。", + "error.unexpected_crash.next_steps_addons": "請嘗試關閉他們然後重新整理頁面。如果狀況沒有改善,您可以使用不同的瀏覽器或應用程式來檢視來使用 Mastodon。", + "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 到剪貼簿", + "errors.unexpected_crash.report_issue": "回報問題", "follow_request.authorize": "授權", "follow_request.reject": "拒絕", - "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的員工認為可能想要自己審核這些帳號的追蹤請求。", + "follow_requests.unlocked_explanation": "即便您的帳號未被鎖定,{domain} 的員工認為您可能想要自己審核這些帳號的追蹤請求。", "generic.saved": "已儲存", "getting_started.developers": "開發者", "getting_started.directory": "個人資料目錄", "getting_started.documentation": "文件", "getting_started.heading": "開始使用", "getting_started.invite": "邀請使用者", - "getting_started.open_source_notice": "Mastodon 是開源軟體。你可以在 GitHub {github} 上貢獻或是回報問題。", - "getting_started.security": "安全性", + "getting_started.open_source_notice": "Mastodon 是開源軟體。您可以在 GitHub {github} 上貢獻或是回報問題。", + "getting_started.security": "帳號安全性設定", "getting_started.terms": "服務條款", - "hashtag.column_header.tag_mode.all": "以及{additional}", - "hashtag.column_header.tag_mode.any": "或是{additional}", - "hashtag.column_header.tag_mode.none": "而無需{additional}", + "hashtag.column_header.tag_mode.all": "以及 {additional}", + "hashtag.column_header.tag_mode.any": "或是 {additional}", + "hashtag.column_header.tag_mode.none": "而無需 {additional}", "hashtag.column_settings.select.no_options_message": "找不到建議", - "hashtag.column_settings.select.placeholder": "輸入主題標籤…", + "hashtag.column_settings.select.placeholder": "請輸入主題標籤…", "hashtag.column_settings.tag_mode.all": "全部", "hashtag.column_settings.tag_mode.any": "任一", "hashtag.column_settings.tag_mode.none": "全不", @@ -204,38 +204,38 @@ "intervals.full.hours": "{number, plural, one {# 小時} other {# 小時}}", "intervals.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}", "introduction.federation.action": "下一步", - "introduction.federation.federated.headline": "站台聯盟", - "introduction.federation.federated.text": "來自聯盟宇宙中其他站台的公開嘟文將會在站點聯盟時間軸中顯示。", + "introduction.federation.federated.headline": "聯邦", + "introduction.federation.federated.text": "來自聯盟宇宙中其他伺服器的公開嘟文將會在聯邦時間軸中顯示。", "introduction.federation.home.headline": "首頁", "introduction.federation.home.text": "你關注使用者的嘟文將會在首頁動態中顯示。你可以關注任何伺服器上的任何人!", "introduction.federation.local.headline": "本機", "introduction.federation.local.text": "跟您同伺服器之使用者所發的公開嘟文將會顯示在本機時間軸中。", "introduction.interactions.action": "完成教學!", - "introduction.interactions.favourite.headline": "讚美", - "introduction.interactions.favourite.text": "您能儲存嘟文供稍候觀看,或者讚美嘟文,讓作者知道您喜歡這則嘟文。", + "introduction.interactions.favourite.headline": "收藏", + "introduction.interactions.favourite.text": "您能儲存嘟文供稍候觀看,或者收藏嘟文,讓作者知道您喜歡這則嘟文。", "introduction.interactions.reblog.headline": "轉嘟", "introduction.interactions.reblog.text": "您能藉由轉嘟他人嘟文來分享給您的關注者。", "introduction.interactions.reply.headline": "回覆", "introduction.interactions.reply.text": "您能回覆其他人或自己的嘟文,這麼做會把這些回覆串成一串對話。", "introduction.welcome.action": "開始旅程吧!", "introduction.welcome.headline": "第一步", - "introduction.welcome.text": "歡迎來到聯盟宇宙!等等你就可以廣播訊息及跨越各種各式各樣的伺服器與朋友聊天。但這台伺服器,{domain},非常特別 - 它寄管了你的個人資料,所以請記住它的名字。", + "introduction.welcome.text": "歡迎來到聯盟宇宙!稍候您就可以廣播訊息及跨越各種各式各樣的伺服器與朋友聊天。但這台伺服器,{domain},非常特別 - 它承載了您的個人資料,所以請記住它的名字。", "keyboard_shortcuts.back": "返回上一頁", "keyboard_shortcuts.blocked": "開啟「封鎖使用者」名單", "keyboard_shortcuts.boost": "轉嘟", "keyboard_shortcuts.column": "將焦點放在其中一欄的嘟文", "keyboard_shortcuts.compose": "將焦點移至撰寫文字區塊", - "keyboard_shortcuts.description": "描述", + "keyboard_shortcuts.description": "說明", "keyboard_shortcuts.direct": "開啟私訊欄", - "keyboard_shortcuts.down": "往下移動名單項目", + "keyboard_shortcuts.down": "在名單中往下移動", "keyboard_shortcuts.enter": "檢視嘟文", - "keyboard_shortcuts.favourite": "讚美", - "keyboard_shortcuts.favourites": "開啟讚美者名錄", - "keyboard_shortcuts.federated": "開啟站點聯盟時間軸", + "keyboard_shortcuts.favourite": "加到收藏", + "keyboard_shortcuts.favourites": "開啟收藏名單", + "keyboard_shortcuts.federated": "開啟聯邦時間軸", "keyboard_shortcuts.heading": "鍵盤快速鍵", "keyboard_shortcuts.home": "開啟首頁時間軸", "keyboard_shortcuts.hotkey": "快速鍵", - "keyboard_shortcuts.legend": "顯示此列表", + "keyboard_shortcuts.legend": "顯示此圖例", "keyboard_shortcuts.local": "開啟本機時間軸", "keyboard_shortcuts.mention": "提及作者", "keyboard_shortcuts.muted": "開啟靜音使用者名單", @@ -244,7 +244,7 @@ "keyboard_shortcuts.open_media": "開啟媒體", "keyboard_shortcuts.pinned": "開啟釘選的嘟文名單", "keyboard_shortcuts.profile": "開啟作者的個人資料頁面", - "keyboard_shortcuts.reply": "回覆", + "keyboard_shortcuts.reply": "回應嘟文", "keyboard_shortcuts.requests": "開啟關注請求名單", "keyboard_shortcuts.search": "將焦點移至搜尋框", "keyboard_shortcuts.spoilers": "顯示或隱藏被折疊的正文", @@ -253,7 +253,7 @@ "keyboard_shortcuts.toggle_sensitivity": "顯示 / 隱藏媒體", "keyboard_shortcuts.toot": "開始發出新嘟文", "keyboard_shortcuts.unfocus": "取消輸入文字區塊 / 搜尋的焦點", - "keyboard_shortcuts.up": "往上移動名單項目", + "keyboard_shortcuts.up": "在名單中往上移動", "lightbox.close": "關閉", "lightbox.compress": "折疊圖片檢視框", "lightbox.expand": "展開圖片檢視框", @@ -266,13 +266,13 @@ "lists.edit.submit": "變更標題", "lists.new.create": "新增名單", "lists.new.title_placeholder": "新名單標題", - "lists.replies_policy.followed": "Any followed user", - "lists.replies_policy.list": "Members of the list", - "lists.replies_policy.none": "No one", - "lists.replies_policy.title": "顯示回覆", + "lists.replies_policy.followed": "任何跟隨的使用者", + "lists.replies_policy.list": "列表成員", + "lists.replies_policy.none": "沒有人", + "lists.replies_policy.title": "顯示回覆:", "lists.search": "搜尋您關注的使用者", "lists.subheading": "您的名單", - "load_pending": "{count, plural, other {# 個新項目}}", + "load_pending": "{count, plural, one {# 個新項目} other {# 個新項目}}", "loading_indicator.label": "讀取中...", "media_gallery.toggle_visible": "切換可見性", "missing_indicator.label": "找不到", @@ -289,7 +289,7 @@ "navigation_bar.discover": "探索", "navigation_bar.domain_blocks": "隱藏的網域", "navigation_bar.edit_profile": "編輯個人資料", - "navigation_bar.favourites": "讚美集", + "navigation_bar.favourites": "收藏", "navigation_bar.filters": "靜音詞彙", "navigation_bar.follow_requests": "關注請求", "navigation_bar.follows_and_followers": "關注及關注者", @@ -303,45 +303,45 @@ "navigation_bar.preferences": "偏好設定", "navigation_bar.public_timeline": "聯邦時間軸", "navigation_bar.security": "安全性", - "notification.favourite": "{name} 讚美了你的嘟文", - "notification.follow": "{name} 關注了你", - "notification.follow_request": "{name} 要求關注你", - "notification.mention": "{name} 提到了你", + "notification.favourite": "{name} 把您的嘟文加入了最愛", + "notification.follow": "{name} 關注了您", + "notification.follow_request": "{name} 要求關注您", + "notification.mention": "{name} 提到了您", "notification.own_poll": "您的投票已結束", - "notification.poll": "您投過的投票已經結束", - "notification.reblog": "{name}轉嘟了你的嘟文", + "notification.poll": "您曾投過的投票已經結束", + "notification.reblog": "{name} 轉嘟了您的嘟文", "notification.status": "{name} 剛剛嘟文", "notifications.clear": "清除通知", - "notifications.clear_confirmation": "確定要永久清除你的通知嗎?", + "notifications.clear_confirmation": "確定要永久清除您的通知嗎?", "notifications.column_settings.alert": "桌面通知", - "notifications.column_settings.favourite": "被讚美:", + "notifications.column_settings.favourite": "最愛:", "notifications.column_settings.filter_bar.advanced": "顯示所有分類", "notifications.column_settings.filter_bar.category": "快速過濾欄", "notifications.column_settings.filter_bar.show": "顯示", "notifications.column_settings.follow": "新關注者:", - "notifications.column_settings.follow_request": "新的關注請求:", + "notifications.column_settings.follow_request": "新的關注請求:", "notifications.column_settings.mention": "提及:", "notifications.column_settings.poll": "投票結果:", - "notifications.column_settings.push": "推送通知", + "notifications.column_settings.push": "推播通知", "notifications.column_settings.reblog": "轉嘟:", "notifications.column_settings.show": "在欄位中顯示", - "notifications.column_settings.sound": "播放音效", - "notifications.column_settings.status": "新嘟文:", + "notifications.column_settings.sound": "播放聲音", + "notifications.column_settings.status": "新嘟文:", "notifications.filter.all": "全部", "notifications.filter.boosts": "轉嘟", - "notifications.filter.favourites": "讚美集", + "notifications.filter.favourites": "最愛", "notifications.filter.follows": "關注的使用者", "notifications.filter.mentions": "提及", "notifications.filter.polls": "投票結果", "notifications.filter.statuses": "已跟隨使用者的最新動態", - "notifications.grant_permission": "Grant permission.", + "notifications.grant_permission": "授予權限", "notifications.group": "{count} 條通知", "notifications.mark_as_read": "將所有通知都標記為已讀", "notifications.permission_denied": "由於之前拒絕了瀏覽器請求,因此桌面通知不可用", "notifications.permission_denied_alert": "因為之前瀏覽器權限被拒絕,無法啟用桌面通知", - "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", + "notifications.permission_required": "因為尚未授予所需的權限,所以桌面通知不可用。", "notifications_permission_banner.enable": "啟用桌面通知", - "notifications_permission_banner.how_to_control": "啟用桌面通知以在 Mastodon 沒有開啟的時候接收通知。在已經啟用桌面通知的時候,你可以透過上面的 {icon} 按鈕準確的控制哪些類型的互動會產生桌面通知。", + "notifications_permission_banner.how_to_control": "啟用桌面通知以在 Mastodon 沒有開啟的時候接收通知。在已經啟用桌面通知的時候,您可以透過上面的 {icon} 按鈕準確的控制哪些類型的互動會產生桌面通知。", "notifications_permission_banner.title": "不要錯過任何東西!", "picture_in_picture.restore": "還原", "poll.closed": "已關閉", @@ -349,37 +349,37 @@ "poll.total_people": "{count, plural, one {# 個投票} other {# 個投票}}", "poll.total_votes": "{count, plural, one {# 個投票} other {# 個投票}}", "poll.vote": "投票", - "poll.voted": "你已對此問題投票", + "poll.voted": "您已對此問題投票", "poll_button.add_poll": "建立投票", "poll_button.remove_poll": "移除投票", - "privacy.change": "調整隱私狀態", - "privacy.direct.long": "只有被提到的使用者能看到", + "privacy.change": "調整嘟文隱私狀態", + "privacy.direct.long": "只有被提及的使用者能看到", "privacy.direct.short": "私訊", - "privacy.private.long": "只有關注你的使用者能看到", + "privacy.private.long": "只有關注您的使用者能看到", "privacy.private.short": "僅關注者", - "privacy.public.long": "嘟到公開時間軸", + "privacy.public.long": "公開,且顯示於公開時間軸", "privacy.public.short": "公開", "privacy.unlisted.long": "公開,但不會顯示在公開時間軸", "privacy.unlisted.short": "不公開", "refresh": "重新整理", "regeneration_indicator.label": "載入中…", - "regeneration_indicator.sublabel": "你的主頁時間軸正在準備中!", + "regeneration_indicator.sublabel": "您的主頁時間軸正在準備中!", "relative_time.days": "{number} 天", - "relative_time.hours": "{number} 小時", + "relative_time.hours": "{number}小時前", "relative_time.just_now": "剛剛", - "relative_time.minutes": "{number} 分", + "relative_time.minutes": "{number} 分前", "relative_time.seconds": "{number} 秒", "relative_time.today": "今天", "reply_indicator.cancel": "取消", "report.forward": "轉寄到 {target}", - "report.forward_hint": "這個帳戶屬於其他站點。要像該站點發送匿名的檢舉訊息嗎?", - "report.hint": "這項訊息會發送到您伺服器的管理員。你可以提供檢舉這個帳戶的理由:", - "report.placeholder": "更多訊息", + "report.forward_hint": "這個帳戶屬於其他伺服器。要像該伺服器發送匿名的檢舉訊息嗎?", + "report.hint": "這項訊息會發送到您伺服器的管理員。您可以提供檢舉這個帳戶的理由:", + "report.placeholder": "其他備註", "report.submit": "送出", "report.target": "檢舉 {target}", "search.placeholder": "搜尋", "search_popout.search_format": "進階搜尋格式", - "search_popout.tips.full_text": "輸入簡單的文字,搜尋由你撰寫、贊美、轉嘟或提你的嘟文,以及與關鍵詞匹配的使用者名稱、帳戶名稱和標籤。", + "search_popout.tips.full_text": "輸入簡單的文字,搜尋由您撰寫、收藏、轉嘟或提您的嘟文,以及與關鍵詞匹配的使用者名稱、帳戶顯示名稱和主題標籤。", "search_popout.tips.hashtag": "主題標籤", "search_popout.tips.status": "嘟文", "search_popout.tips.text": "輸入簡單的文字,搜尋符合的使用者名稱,帳戶名稱與標籤", @@ -394,32 +394,32 @@ "status.block": "封鎖 @{name}", "status.bookmark": "書籤", "status.cancel_reblog_private": "取消轉嘟", - "status.cannot_reblog": "這篇嘟文無法被轉嘟", + "status.cannot_reblog": "這則嘟文無法被轉嘟", "status.copy": "複製嘟文連結", "status.delete": "刪除", - "status.detailed_status": "對話的詳細內容", + "status.detailed_status": "詳細的對話內容", "status.direct": "發送私訊給 @{name}", - "status.embed": "嵌入", - "status.favourite": "讚美", + "status.embed": "內嵌", + "status.favourite": "最愛", "status.filtered": "已過濾", "status.load_more": "載入更多", "status.media_hidden": "隱藏媒體內容", - "status.mention": "提到 @{name}", + "status.mention": "提及 @{name}", "status.more": "更多", "status.mute": "靜音 @{name}", "status.mute_conversation": "靜音對話", - "status.open": "展開嘟文", + "status.open": "展開此嘟文", "status.pin": "釘選到個人資料頁", "status.pinned": "釘選的嘟文", "status.read_more": "閱讀更多", "status.reblog": "轉嘟", "status.reblog_private": "轉嘟給原有關注者", "status.reblogged_by": "{name} 轉嘟了", - "status.reblogs.empty": "還沒有人轉嘟。如果有,會顯示在這裡。", + "status.reblogs.empty": "還沒有人轉嘟過這則嘟文。當有人轉嘟時,它將於此顯示。", "status.redraft": "刪除 & 編輯", "status.remove_bookmark": "移除書籤", "status.reply": "回覆", - "status.replyAll": "回覆所有人", + "status.replyAll": "回覆討論串", "status.report": "檢舉 @{name}", "status.sensitive_warning": "敏感內容", "status.share": "分享", @@ -430,15 +430,15 @@ "status.show_thread": "顯示討論串", "status.uncached_media_warning": "無法使用", "status.unmute_conversation": "解除此對話的靜音", - "status.unpin": "解除置頂", + "status.unpin": "從個人頁面解除釘選", "suggestions.dismiss": "關閉建議", "suggestions.header": "您可能對這些東西有興趣…", - "tabs_bar.federated_timeline": "其他站點", - "tabs_bar.home": "主頁", - "tabs_bar.local_timeline": "本站", + "tabs_bar.federated_timeline": "聯邦宇宙", + "tabs_bar.home": "首頁", + "tabs_bar.local_timeline": "本機", "tabs_bar.notifications": "通知", "tabs_bar.search": "搜尋", - "time_remaining.days": "剩餘{number, plural, one {# 天數} other {# 天數}}", + "time_remaining.days": "剩餘{number, plural, one {# 天} other {# 天}}", "time_remaining.hours": "剩餘{number, plural, one {# 小時} other {# 小時}}", "time_remaining.minutes": "剩餘{number, plural, one {# 分鐘} other {# 分鐘}}", "time_remaining.moments": "剩餘時間", @@ -449,27 +449,27 @@ "timeline_hint.resources.statuses": "更早的嘟文", "trends.counter_by_accounts": "{count, plural,one {{counter} 人}other {{counter} 人}}正在討論", "trends.trending_now": "目前趨勢", - "ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。", + "ui.beforeunload": "如果離開 Mastodon,您的草稿將會不見。", "units.short.billion": "{count}B", "units.short.million": "{count}M", "units.short.thousand": "{count}K", "upload_area.title": "拖放來上傳", - "upload_button.label": "上傳媒體檔案 (JPEG, PNG, GIF, WebM, MP4, MOV)", + "upload_button.label": "上傳圖像、影片、或音樂檔案", "upload_error.limit": "已達到檔案上傳限制。", - "upload_error.poll": "不允許在投票上傳檔案。", - "upload_form.audio_description": "簡單描述內容給聽障人士", + "upload_error.poll": "不允許在投票中上傳檔案。", + "upload_form.audio_description": "描述內容給聽障人士", "upload_form.description": "為視障人士增加文字說明", "upload_form.edit": "編輯", "upload_form.thumbnail": "更改預覽圖", "upload_form.undo": "刪除", - "upload_form.video_description": "簡單描述給聽障或視障人士", + "upload_form.video_description": "描述給聽障或視障人士", "upload_modal.analyzing_picture": "正在分析圖片…", "upload_modal.apply": "套用", "upload_modal.choose_image": "選擇圖片", - "upload_modal.description_placeholder": "A quick brown fox 跳過那隻懶狗", - "upload_modal.detect_text": "從圖片偵測文字", + "upload_modal.description_placeholder": "我能吞下玻璃而不傷身體", + "upload_modal.detect_text": "從圖片中偵測文字", "upload_modal.edit_media": "編輯媒體", - "upload_modal.hint": "點擊或拖曳圓圈以選擇預覽縮圖。", + "upload_modal.hint": "於預覽中點擊或拖曳圓圈以選擇將於所有縮圖中顯示的焦點。", "upload_modal.preparing_ocr": "準備 OCR 中……", "upload_modal.preview_label": "預覽 ({ratio})", "upload_progress.label": "上傳中...", diff --git a/config/locales/activerecord.kab.yml b/config/locales/activerecord.kab.yml index 24e2760da..d6b3c40e4 100644 --- a/config/locales/activerecord.kab.yml +++ b/config/locales/activerecord.kab.yml @@ -3,7 +3,7 @@ kab: activerecord: attributes: poll: - expires_at: Azemz n tagara + expires_at: Azemz n taggara options: Tifranin errors: models: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 439249d1b..ee3c554b4 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -566,6 +566,7 @@ ca: domain_blocks_rationale: title: Mostra el raonament enable_bootstrap_timeline_accounts: + desc_html: Fer que els nous usuaris segueixin automàticament als comptes configurats i la seva línia de temps no arrenqui buida title: Activa els seguiments per defecte per els usuaris nous hero: desc_html: Es mostra en pàgina frontal. Recomanat al menys 600x100px. Si no es configura es mostrarà el del servidor diff --git a/config/locales/de.yml b/config/locales/de.yml index c2013ab8b..34d03f808 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -402,6 +402,8 @@ de: silence: Stummschaltung suspend: Sperre title: Neue Domain-Blockade + obfuscate: Domainname verschleiern + obfuscate_hint: Den Domainnamen in der Liste teilweise verschleiern, wenn die Liste der Domänenbeschränkungen aktiviert ist private_comment: Privater Kommentar private_comment_hint: Kommentar zu dieser Domain-Beschränkung für die interne Nutzung durch die Moderatoren. public_comment: Öffentlicher Kommentar @@ -564,6 +566,7 @@ de: domain_blocks_rationale: title: Rationale anzeigen enable_bootstrap_timeline_accounts: + desc_html: Neue Benutzer automatisch den konfigurierten Konten folgen lassen, sodass ihr Home-Feed nicht leer startet title: Aktiviere die Option "Konten, denen Neu-Angemeldete automatisch folgen" hero: desc_html: Wird auf der Startseite angezeigt. Mindestens 600x100px sind empfohlen. Wenn es nicht gesetzt wurde, wird das Server-Thumbnail dafür verwendet @@ -921,6 +924,8 @@ de: status: Verifizierungsstatus view_proof: Zeige Nachweis imports: + errors: + over_rows_processing_limit: enthält mehr als %{count} Zeilen modes: merge: Zusammenführen merge_long: Behalte existierende Datensätze und füge neue hinzu diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml index 6f652f421..f7b087824 100644 --- a/config/locales/devise.zh-TW.yml +++ b/config/locales/devise.zh-TW.yml @@ -21,18 +21,18 @@ zh-TW: action: 驗證電子信箱位址 action_with_app: 確認並返回 %{app} explanation: 您已經在 %{host} 上以此電子信箱位址建立了一支帳戶。您距離啟用它只剩一點之遙了。若這不是您,請忽略此信件。 - explanation_when_pending: 您使用此電子信箱位址申請了 %{host} 的邀請。當您確認電子信箱後我們將審核您的申請,而直到核准前您都無法登入。當您的申請遭拒絕,您的資料將被移除而不必做後續動作。如果這不是您,請忽略此信件。 + explanation_when_pending: 您使用此電子信箱位址申請了 %{host} 的邀請。當您確認電子信箱後我們將審核您的申請。您可以登入以改變您的細節或刪除您的帳號,但直到您的帳號被核准之前,您無法操作大部分的功能。若您的申請遭拒絕,您的資料將被移除而不必做後續動作。如果這不是您,請忽略此信件。 extra_html: 同時也請看看伺服器規則服務條款。 subject: Mastodon:%{instance} 確認說明 title: 驗證電子信箱位址 email_changed: explanation: 您帳戶的電子信箱位址將變更為: - extra: 若您未變更電子信箱,那麼很有可能是某人取得了你帳戶的存取權限。請立刻變更密碼,或當帳戶被鎖定時,請聯絡伺服器的管理員。 + extra: 若您未變更電子信箱,那麼很有可能是某人取得了您帳戶的存取權限。請立刻變更密碼,或當帳戶被鎖定時,請聯絡伺服器的管理員。 subject: Mastodon:已變更電子信箱 title: 新電子信箱位址 password_change: explanation: 您帳戶的密碼已變更。 - extra: 如果您未變更密碼,那麼很有可能是某人取得了帳戶的存取權限。請立刻變更密碼,或若帳戶被鎖定時,請聯絡伺服器的管理員。 + extra: 若您未變更密碼,那麼很有可能是某人取得了您帳戶的存取權限。請立刻變更密碼,或若帳戶被鎖定時,請聯絡伺服器的管理員。 subject: Mastodon:已變更密碼 title: 密碼已變更 reconfirmation_instructions: @@ -43,7 +43,7 @@ zh-TW: reset_password_instructions: action: 變更密碼 explanation: 您已請求帳戶的新密碼。 - extra: 若您並未請求,請忽略此信件。您的密碼在存取上方連結並建立新連結前不會變更。 + extra: 若您並未請求,請忽略此信件。您的密碼在存取上方連結並建立新密碼前不會變更。 subject: Mastodon:重設密碼指引 title: 重設密碼 two_factor_disabled: @@ -63,27 +63,27 @@ zh-TW: webauthn_credential: added: explanation: 下面的安全密鑰已經新增至您的帳戶 - subject: 'Mastodon: 新安全密鑰' + subject: Mastodon:新安全密鑰 title: 已新增新安全密鑰 deleted: - explanation: 下面的安全密鑰已經從您的帳戶中移除 - subject: 'Mastodon: 安全密鑰已移除' + explanation: 以下的安全密鑰已經從您的帳戶中移除 + subject: Mastodon:安全密鑰已移除 title: 您的一支安全密鑰已經被移除 webauthn_disabled: explanation: 您的帳戶並沒有啟用安全密鑰認證方式。只能以 TOTP app 產生地成對 token 登入。 - subject: 'Mastodon: 安全密鑰認證方式已關閉' + subject: Mastodon:安全密鑰認證方式已關閉 title: 已關閉安全密鑰 webauthn_enabled: - explanation: 安全密鑰認證已在您的帳戶中啟用。您可以使用安全密鑰登入了。 - subject: 'Mastodon: 以啟用安全密鑰認證' - title: 已開啟安全密鑰 + explanation: 您的帳戶已啟用安全密鑰認證。您可以使用安全密鑰登入了。 + subject: Mastodon:已啟用安全密鑰認證 + title: 已啟用安全密鑰 omniauth_callbacks: failure: 無法透過 %{kind} 認證是否為您,因為「%{reason}」。 success: 成功透過 %{kind} 帳戶登入。 passwords: no_token: 您必須透過密碼重設信件才能存取此頁面。若確實如此,請確定輸入的網址是完整的。 - send_instructions: 若電子信箱位址存在於資料庫,幾分鐘後您將在信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 - send_paranoid_instructions: 若電子信箱位址存在於資料庫,幾分鐘後您將在信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 + send_instructions: 若電子信箱位址存在於我們的資料庫,幾分鐘後您將在信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 + send_paranoid_instructions: 若電子信箱位址存在於我們的資料庫,幾分鐘後您將在信箱中收到密碼復原連結。若未收到請檢查垃圾郵件資料夾。 updated: 您的密碼已成功變更,現在已經登入。 updated_not_active: 您的密碼已成功變更。 registrations: @@ -93,14 +93,14 @@ zh-TW: signed_up_but_locked: 您已註冊成功,但由於您的帳戶已被鎖定,我們無法讓您登入。 signed_up_but_pending: 包含確認連結的訊息已寄到您的電子信箱。按下此連結後我們將審核您的申請。核准後將通知您。 signed_up_but_unconfirmed: 包含確認連結的訊息已寄到您的電子信箱。請前往連結以啟用帳號。若未收到請檢查垃圾郵件資料夾。 - update_needs_confirmation: 已更新您的帳號,但仍需驗證您的新信箱。請檢查電子信箱並前往確認連結來確認新信箱位址。若未收到請檢查垃圾郵件資料夾。 + update_needs_confirmation: 已成功更新您的帳號,但仍需驗證您的新信箱。請檢查電子信箱並前往確認連結來確認新信箱位址。若未收到請檢查垃圾郵件資料夾。 updated: 您的帳戶已成功更新。 sessions: already_signed_out: 已成功登出。 signed_in: 已成功登入。 signed_out: 已成功登出。 unlocks: - send_instructions: 幾分鐘後您將收到確認信件。若未收到此信件,請檢查垃圾郵件資料夾。 + send_instructions: 幾分鐘後您將收到解鎖帳號的指引信件。若未收到請檢查垃圾郵件資料夾。 send_paranoid_instructions: 若此帳號存在,您將在幾分鐘後收到解鎖指引信件。若未收到請檢查垃圾郵件資料夾。 unlocked: 已解鎖您的帳戶,請登入繼續。 errors: diff --git a/config/locales/el.yml b/config/locales/el.yml index 837d6f416..5442d38b8 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -557,6 +557,7 @@ el: domain_blocks_rationale: title: Εμφάνιση σκεπτικού enable_bootstrap_timeline_accounts: + desc_html: Οι νέοι χρήστες να ακολουθούν τους προρυθμισμένουνς λογαριασμούς ώστε η αρχική ροή τους να μην είναι άδεια title: Προεπιλογή παρακολούθησης για τους νέους χρήστες hero: desc_html: Εμφανίζεται στην μπροστινή σελίδα. Συνίσταται τουλάχιστον 600x100px. Όταν λείπει, χρησιμοποιείται η μικρογραφία του κόμβου diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 93f663641..32e079074 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -566,6 +566,7 @@ es-AR: domain_blocks_rationale: title: Mostrar razonamiento enable_bootstrap_timeline_accounts: + desc_html: Hacer que los nuevos usuarios sigan automáticamente las cuentas configuradas para que su línea temporal principal no comience vacía title: Habilitar seguimientos predeterminados para nuevas cuentas hero: desc_html: Mostrado en la página principal. Se recomienda un tamaño mínimo de 600x100 píxeles. Predeterminadamente se establece a la miniatura del servidor diff --git a/config/locales/es.yml b/config/locales/es.yml index 8d458edc6..0582fd1f1 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -566,6 +566,7 @@ es: domain_blocks_rationale: title: Mostrar la razón de ser enable_bootstrap_timeline_accounts: + desc_html: Hacer que los nuevos usuarios sigan automáticamente las cuentas configuradas para que su línea temporal de inicio no comience vacía title: Habilitar seguimientos predeterminados para usuarios nuevos hero: desc_html: Mostrado en la página principal. Recomendable al menos 600x100px. Por defecto se establece a la miniatura de la instancia diff --git a/config/locales/fr.yml b/config/locales/fr.yml index bed43fee1..0c96d462d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -566,6 +566,7 @@ fr: domain_blocks_rationale: title: Montrer la raison enable_bootstrap_timeline_accounts: + desc_html: Faire suivre automatiquement les comptes configurés aux nouveaux·lles utilisateurs·rices afin que leur flux personnel ne démarre pas vide title: Activer les abonnements par défaut pour les nouveaux·elles utilisateur·rice·s hero: desc_html: Affichée sur la page d’accueil. Au moins 600x100px recommandé. Lorsqu’elle n’est pas définie, se rabat sur la vignette du serveur diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 36980f800..48aaff0ad 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -402,6 +402,8 @@ gl: silence: Silenciar suspend: Suspender title: Novo bloqueo de dominio + obfuscate: Ofuscar o nome de dominio + obfuscate_hint: Ofuscar parcialmente o nome do dominio na lista se está activada a publicación da lista de limitacións de dominio private_comment: Comentario privado private_comment_hint: Comentar sobre esta limitación de dominio para uso interno polos moderadores. public_comment: Comentario público @@ -564,6 +566,7 @@ gl: domain_blocks_rationale: title: Amosar motivo enable_bootstrap_timeline_accounts: + desc_html: Facer que as novas usuarias sigan automáticamente certas contas para que así a cronoloxía inicial non esté baleira title: Activar seguimentos por omisión para novas usuarias hero: desc_html: Amosado na páxina principal. Polo menos 600x100px recomendados. Se non está definido, estará por defecto a miniatura do servidor @@ -921,6 +924,8 @@ gl: status: Estado da validación view_proof: Ver proba imports: + errors: + over_rows_processing_limit: contén máis de %{count} filas modes: merge: Fusionar merge_long: Manter os rexistros actuais e engadir novos diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 0fc35c9ac..97596ff0c 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -21,9 +21,9 @@ hu: federation_hint_html: Egy %{instance} fiókkal bármely más Mastodon szerveren vagy a föderációban lévő felhasználót követni tudsz. get_apps: Próbálj ki egy mobil appot hosted_on: "%{domain} Mastodon szerver" - instance_actor_flash: 'Ez a fiók egy virtuális szereplő, mely magát a szervert reprezentálja, nem egy felhasználót. Ez a föderáció támogatására készült, ezért nem szabad blokkolni, hacsak egy teljes szervert nem akarsz kitiltani, amire persze a domain blokkolása jobb megoldás. - -' + instance_actor_flash: | + Ez a fiók virtuális, magát a szervert reprezentálja, nem pedig konkrét + felhasználót. Föderációs célokra szolgál, nem szabad tehát felfüggeszteni, hacsak nem akarod a teljes szervert kitiltani, mely esetben a domain tiltásának használata javasolt. learn_more: Tudj meg többet privacy_policy: Adatvédelmi szabályzat see_whats_happening: Nézd, mi történik @@ -60,7 +60,9 @@ hu: one: Követő other: Követő following: Követett - instance_actor_flash: Ez a fiók virtuális és magát a kiszolgálót reprezentálja, nem egy konkrét felhasználót. Föderációs célokból használt, és nem szabad felfüggeszteni. + instance_actor_flash: |- + Ez a fiók virtuális, magát a szervert reprezentálja, nem pedig konkrét + felhasználót. Föderációs célokra szolgál, nem szabad tehát felfüggeszteni. joined: Csatlakozott %{date} last_active: utoljára aktív link_verified_on: A link tulajdonosát %{date} -n ellenőriztük @@ -226,15 +228,15 @@ hu: create_announcement: Közlemény létrehozása create_custom_emoji: Egyéni emodzsi létrehozása create_domain_allow: Domain engedélyezés létrehozása - create_domain_block: Domain blokkolás létrehozása - create_email_domain_block: E-mail domain blokkolás létrehozása + create_domain_block: Domain tiltás létrehozása + create_email_domain_block: E-mail domain tiltás létrehozása create_ip_block: IP szabály létrehozása demote_user: Felhasználó lefokozása destroy_announcement: Közlemény törlése destroy_custom_emoji: Egyéni emodzsi törlése destroy_domain_allow: Domain engedélyezés törlése - destroy_domain_block: Domain blokkolás törlése - destroy_email_domain_block: E-mail domain blokkolás törlése + destroy_domain_block: Domain tiltás törlése + destroy_email_domain_block: E-mail domain tiltás törlése destroy_ip_block: IP szabály törlése destroy_status: Állapot törlése disable_2fa_user: Kétlépcsős hitelesítés letiltása @@ -257,7 +259,7 @@ hu: unsuspend_account: Fiók felfüggesztésének feloldása update_announcement: Közlemény frissítése update_custom_emoji: Egyéni emodzsi frissítése - update_domain_block: Domain blokkolás frissítése + update_domain_block: Domain tiltás frissítése update_status: Állapot frissítése actions: assigned_to_self_report: "%{name} a %{target} bejelentést magához rendelte" @@ -268,14 +270,14 @@ hu: create_custom_emoji: "%{name} új emodzsit töltött fel: %{target}" create_domain_allow: "%{name} engedélyező listára vette %{target} domaint" create_domain_block: "%{name} letiltotta az alábbi domaint: %{target}" - create_email_domain_block: "%{name} feketelistára tette az alábbi e-mail domaint: %{target}" + create_email_domain_block: "%{name} letiltotta az e-mail domaint: %{target}" create_ip_block: "%{name} létrehozott egy szabályt a %{target} IP-vel kapcsolatban" demote_user: "%{name} lefokozta az alábbi felhasználót: %{target}" destroy_announcement: "%{name} törölte a közleményt %{target}" destroy_custom_emoji: "%{name} törölte az emodzsit: %{target}" destroy_domain_allow: "%{name} leszedte %{target} domaint az engedélyező listáról" destroy_domain_block: "%{name} engedélyezte az alábbi domaint: %{target}" - destroy_email_domain_block: "%{name} fehérlistára tette az alábbi e-mail domaint: %{target}" + destroy_email_domain_block: "%{name} engedélyezte az e-mail domaint: %{target}" destroy_ip_block: "%{name} törölt egy szabályt a %{target} IP-vel kapcsolatban" destroy_status: "%{name} eltávolította az alábbi felhasználó tülkjét: %{target}" disable_2fa_user: "%{name} kikapcsolta a kétlépcsős azonosítást %{target} felhasználó fiókján" @@ -298,7 +300,7 @@ hu: unsuspend_account: "%{name} feloldotta %{target} felhasználói fiókjának felfüggesztését" update_announcement: "%{name} frissítette a közleményt %{target}" update_custom_emoji: "%{name} frissítette az alábbi emodzsit: %{target}" - update_domain_block: "%{name} frissítette a(z) %{target} domain blokkolását" + update_domain_block: "%{name} frissítette a %{target} domain tiltását" update_status: "%{name} frissítette %{target} felhasználó tülkjét" deleted_status: "(törölt tülk)" empty: Nem található napló. @@ -430,16 +432,16 @@ hu: view: Domain tiltásának megtekintése email_domain_blocks: add_new: Új hozzáadása - created_msg: E-mail domain sikeresen hozzáadva a feketelistához + created_msg: E-mail domain sikeresen letiltva delete: Törlés - destroyed_msg: E-mail domain sikeresen eltávolítva a feketelistáról + destroyed_msg: E-mail domain sikeresen engedélyezve domain: Domain - empty: Nincs email domain a feketelistán. + empty: Nincs letiltott email domain. from_html: "%{domain}-ról" new: create: Domain hozzáadása - title: Új e-mail feketelista bejegyzés - title: E-mail feketelista + title: Új e-mail domain tiltása + title: Tiltott e-mail domainek instances: by_domain: Domain delivery_available: Kézbesítés elérhető @@ -566,6 +568,7 @@ hu: domain_blocks_rationale: title: Mutasd meg az indokolást enable_bootstrap_timeline_accounts: + desc_html: Az új felhasználók automatikusan követik a beállított fiókokat, így a Saját idővonaluk kezdéskor nem lesz üres title: Alapértelmezett követés engedélyezése új felhasználóknak hero: desc_html: A kezdőoldalon látszik. Legalább 600x100px méret javasolt. Ha nincs beállítva, a szerver bélyegképet használjuk @@ -1004,7 +1007,7 @@ hu: moderation: title: Moderáció move_handler: - carry_blocks_over_text: Ez a fiók elköltözött innen %{acct}, melyet blokkoltatok. + carry_blocks_over_text: Ez a fiók elköltözött innen %{acct}, melyet letiltottatok. carry_mutes_over_text: Ez a fiók elköltözött innen %{acct}, melyet lenémítottatok. copy_account_note_text: 'Ez a fiók elköltözött innen %{acct}, itt vannak a bejegyzéseitek róla:' notification_mailer: @@ -1187,7 +1190,7 @@ hu: preferences: Beállítások profile: Profil relationships: Követések és követők - two_factor_authentication: Kétlépcsős azonosítás + two_factor_authentication: Kétlépcsős hitelesítés webauthn_authentication: Biztonsági kulcsok spam_check: spam_detected: Ez egy automatikus jelentés. Spamet érzékeltünk. diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 1afd4d927..48050d6a2 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -166,10 +166,12 @@ hy: roles: admin: Ադմինիստրատոր moderator: Մոդերատոր + staff: Անձնակազմ user: Oգտատէր search: Որոնել search_same_email_domain: Այլ օգտատէրեր նոյն էլ․ փոստի դոմէյնով search_same_ip: Այլ օգտատէրեր նոյն IP֊ով + sensitive: Զգայուն show: created_reports: Կազմել բողոքներ targeted_reports: Այլոց կողմից բողոքարկուած @@ -194,6 +196,7 @@ hy: confirm_user: Հաստատել օգտատիրոջը create_account_warning: Ստեղծել զգուշացում create_announcement: Ստեղծել յայտարարութիւն + create_custom_emoji: Ստեղծել սեփական էմոջիները create_email_domain_block: Ստեղծել էլ․ հասցէի դոմէյնի արգելափակում create_ip_block: Ստեղծել IP կանոն destroy_announcement: Ջնջել յայտարարութիւնը @@ -278,8 +281,11 @@ hy: image_hint: PNG մինչեւ 50KB list: Ցանկ listed: Ցուցակագրուած + new: + title: Աւելացնել նոր էմոջի overwrite: Վերագրել shortcode: Հապավում + title: Սեփական էմօջիներ uncategorized: Չդասակարգուած unlist: Ապացուցակագրում unlisted: Ծածուկ @@ -290,6 +296,7 @@ hy: feature_invites: Հրաւէրի յղումներ feature_profile_directory: Օգտատիրոջ մատեան feature_registrations: Գրանցումներ + feature_spam_check: Հակա-սպամ feature_timeline_preview: Հոսքի նախադիտում features: Յատկանիշներ open_reports: բաց բողոքներ @@ -346,6 +353,7 @@ hy: title: էլ․ փոստի արգելափակուած տիրոյթներ instances: by_domain: Դոմեն + empty: Դոմեյնները չեն գտնուել known_accounts: one: "%{count} յայտնի հաշիւ" other: "%{count} յայտնի հաշիւներ" @@ -387,6 +395,7 @@ hy: relationships: title: "%{acct}ի յարաբերութիւններ" relays: + add_new: Աւելացնել նոր վերահեռարձակուիչ delete: Ջնջել disable: Անջատել disabled: Անջատված է @@ -424,6 +433,7 @@ hy: updated_at: Թարմացուած settings: contact_information: + email: Գործնական էլփոստ username: Կոնտակտի ծածկանուն custom_css: title: Սեփական CSS @@ -449,6 +459,10 @@ hy: approved: Գրանցման համար անհրաժեշտ է հաստատում none: Ոչ ոք չի կարող գրանցուել open: Բոլորը կարող են գրանցուել + title: Գրանցումային ռեժիմ + show_staff_badge: + desc_html: Ցուցադրել անձնակազմի անդամի նշանը օգտատիրոջ էջում + title: Ցուցադրել անձնակազմի անդամի նշանը site_description: title: Կայքի նկարագրութիւն site_short_description: @@ -468,10 +482,13 @@ hy: back_to_account: Վերադառնալ անձնական էջ batch: delete: Ջնջել + nsfw_on: Նշել որպէս դիւրազգաց deleted: Ջնջված է + failed_to_execute: Կատարումը ձախողուեց media: title: Մեդիա no_media: Մեդիա չկայ + title: Օգտատիրոջ գրառումները with_media: Մեդիայի հետ tags: context: Համատեքստ @@ -509,6 +526,7 @@ hy: view_status: Նայել գրառումը applications: invalid_url: Տրամադրուած URL անվաւեր է + your_token: Քո մուտքի բանալին auth: apply_for_account: Հրաւէրի հարցում change_password: Գաղտնաբառ @@ -519,6 +537,7 @@ hy: login: Մտնել logout: Դուրս գալ migrate_account: Տեղափոխուել այլ հաշիւ + or_log_in_with: Կամ մուտք գործել օգտագործելով՝ providers: cas: CAS saml: SAML @@ -531,6 +550,7 @@ hy: title: Կարգավորում status: account_status: Հաշուի կարգավիճակ + pending: Դիմումը պէտք է քննուի մեր անձնակազմի կողմից, ինչը կարող է մի փոքր ժամանակ խլել։ Դիմումի հաստատուելու դէպքում, կտեղեկացնենք նամակով։ authorize_follow: follow: Հետևել following: Յաջողութի՜ւն։ Դու այժմ հետեւում ես․ @@ -578,7 +598,7 @@ hy: 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. + '404': Էջը, որը փնտրում ես գոյութիւն չունի։ '406': This page is not available in the requested format. '410': The page you were looking for doesn't exist here anymore. '422': @@ -633,6 +653,7 @@ hy: identity_proofs: active: Ակտիվ authorize: Այո, նոյնականացնել + authorize_connection_prompt: Հաւաստագրէ՞լ այս ծածկագրման կապակցումը i_am_html: Ես %{username}ն եմ %{service}ում։ identity: Ինքնութիւն inactive: Ոչ ակտիւ @@ -650,6 +671,7 @@ hy: blocking: Արգելափակումների ցուցակ bookmarks: Էջանիշեր domain_blocking: Տիրոյթի արգելափակումների ցուցակ + following: Հետեւումների ցանկ upload: Վերբեռնել invites: delete: Ապաակտիւացնել @@ -680,11 +702,14 @@ hy: not_found: չգտնուեց past_migrations: Նախոդ միգրացիաները proceed_with_move: Տեղափոխել հետեւորդներին + redirecting_to: Քո հաշիւը վերահասցեաորում է %{acct}-ին warning: followers: Այս քայլով քո բոլոր հետեւորդներին այս հաշուից կը տեղափոխես դէպի նորը moderation: title: Մոդերացիա notification_mailer: + digest: + title: Երբ բացակայ էիր... favourite: title: Նոր հաւանում follow: @@ -695,6 +720,8 @@ hy: title: Նոր հետեւելու հայցեր mention: action: Պատասխանել + notifications: + other_settings: Ծանուցումների այլ կարգաւորումներ number: human: decimal_units: @@ -714,8 +741,12 @@ hy: older: Ավելի հին prev: Նախորդ truncate: "…" + polls: + errors: + duration_too_short: շատ կարճ է preferences: other: Այլ + posting_defaults: Կանխադիր կարգաւորումներ public_timelines: Հանրային հոսք relationships: activity: Հաշուի ակտիւութիւնը @@ -732,6 +763,8 @@ hy: remove_selected_domains: Հեռացնել բոլոր հետեւորդներին նշուած դոմեյններից remove_selected_followers: Հեռացնել նշուած հետեւորդներին status: Հաշուի կարգավիճակ + scheduled_statuses: + too_soon: Նախադրուած ամսաթիւը պէտք է լինի ապագայում sessions: activity: Վերջին թութը browser: Դիտարկիչ @@ -771,11 +804,14 @@ hy: title: Սեսսիա settings: account: Հաշիվ + account_settings: Հաշուի կարգաւորումներ appearance: Տեսք + back: Ետ գնալ մաստադոն delete: Հաշուի ջնջում development: Ծրագրավորում edit_profile: Խմբագրել պրոֆիլը export: Տվյալների արտահանում + featured_tags: Ընտրուած հէշթեգեր identity_proofs: Անձի նոյնացումներ import: Ներմուծել import_and_export: Ներմուծել և արտահանել @@ -926,12 +962,21 @@ hy: otp: Նոյնականացման հավելված recovery_codes: Վերականգնման կոդեր recovery_codes_regenerated: Վերականգման կոդերը հաջողութեամբ ստեղծուել են + webauthn: Անվտանգութեան բանալիներ user_mailer: + sign_in_token: + title: Մուտքի փորձ warning: + get_in_touch: Կարող էք կապուել %{instance} հանգոյցի անձնակազմի հետ պատասխանելով այս նամակին։ + statuses: Մասնաւորապէս, միայն՝ title: none: Զգուշացում + sensitive: Մեդիաֆայլը պիտակուել է որպէս զգայուն։ + suspend: Հաշիւը արգելափակուած է welcome: + edit_profile_action: Կարգաւորել հաշիւը final_action: Սկսել թթել + review_preferences_action: Փոփոխել կարգաւորումները subject: Բարի գալուստ Մաստոդոն tip_federated_timeline: Դաշնային հոսքում երևում է ամբողջ Մաստոդոնի ցանցը։ Բայց այն ներառում է միայն այն օգտատերերին որոնց բաժանորդագրուած են ձեր հարևաններ, այդ պատճառով այն կարող է լինել ոչ ամբողջական։ tip_following: Դու հետեւում էս քո հանգոյցի ադմին(ներ)ին լռելայն։ Այլ հետաքրքիր անձանց գտնելու համար՝ թերթիր տեղական և դաշնային հոսքերը։ @@ -949,3 +994,4 @@ hy: verification: Ստուգում webauthn_credentials: delete: Ջնջել + registered_on: Գրանցուել է %{date} diff --git a/config/locales/id.yml b/config/locales/id.yml index 8d3291adf..bf63f62a4 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -556,6 +556,7 @@ id: domain_blocks_rationale: title: Tampilkan alasan enable_bootstrap_timeline_accounts: + desc_html: Buat pengguna baru mengikuti akun yang sudah dipilih agar beranda mereka tidak kosong title: Aktifkan opsi ikuti otomatis untuk pengguna baru hero: desc_html: Ditampilkan di halaman depan. Direkomendasikan minimal 600x100px. Jika tidak diatur, kembali ke server gambar kecil diff --git a/config/locales/is.yml b/config/locales/is.yml index 97ac62a4d..2d6102d98 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -566,6 +566,7 @@ is: domain_blocks_rationale: title: Birta röksemdafærslu enable_bootstrap_timeline_accounts: + desc_html: Láta nýja notendur sjálfkrafa fylgjast með uppsettum aðgöngum svo að heimastreymi þeirra byrji ekki autt title: Virkja sjálfgefnar fylgnistillingar fyrir nýja notendur hero: desc_html: Birt á forsíðunni. Mælt með að hún sé a.m.k. 600×100 mynddílar. Þegar þetta er ekki stillt, er notuð smámynd netþjónsins diff --git a/config/locales/it.yml b/config/locales/it.yml index 65e24a4c7..1e0ab42f0 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -566,6 +566,7 @@ it: domain_blocks_rationale: title: Mostra motivazione enable_bootstrap_timeline_accounts: + desc_html: I nuovi utenti seguiranno automaticamente gli account configurati, in modo che il loro home feed all'inizio non sia vuoto title: Abilita seguiti predefiniti per i nuovi utenti hero: desc_html: Mostrata nella pagina iniziale. Almeno 600x100 px consigliati. Se non impostata, sarà usato il thumbnail del server diff --git a/config/locales/ko.yml b/config/locales/ko.yml index c7b63fbf7..cc4ec52cd 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -128,6 +128,7 @@ ko: follows: 팔로잉 수 header: 헤더 inbox_url: 수신함 URL + invite_request_text: 가입 하려는 이유 invited_by: 초대자 ip: IP joined: 가입 @@ -399,6 +400,8 @@ ko: silence: 침묵 suspend: 정지 title: 새로운 도메인 차단 + obfuscate: 도메인 이름 난독화 + obfuscate_hint: 도메인 제한 목록을 공개하는 경우 도메인 이름의 일부를 난독화 합니다 private_comment: 비공개 주석 private_comment_hint: 이 도메인 제한에 대한 주석은 중재자를 위해 내부적으로 사용 됩니다. public_comment: 공개 주석 @@ -557,6 +560,7 @@ ko: domain_blocks_rationale: title: 사유 보여주기 enable_bootstrap_timeline_accounts: + desc_html: 새 사용자들이 자동으로 설정 된 계정들을 팔로우 하도록 해서 그들의 홈 피드가 빈 상태로 시작하지 않도록 합니다 title: 새 유저가 팔로우할 계정을 보여주기 hero: desc_html: 프론트페이지에 표시 됩니다. 최소 600x100픽셀을 권장합니다. 만약 설정되지 않았다면, 서버의 썸네일이 사용 됩니다 diff --git a/config/locales/ml.yml b/config/locales/ml.yml index 603bf157a..2f24ee3ec 100644 --- a/config/locales/ml.yml +++ b/config/locales/ml.yml @@ -1,32 +1,52 @@ --- ml: about: + about_this: കുറിച്ച് + api: API + apps: മൊബൈൽ ആപ്പുകൾ + contact: ബന്ധപ്പെടുക contact_missing: സജ്ജമാക്കിയിട്ടില്ല contact_unavailable: ലഭ്യമല്ല discover_users: ഉപയോഗ്‌താക്കളെ കണ്ടെത്തുക + get_apps: മൊബൈൽ ആപ്പ് പരീക്ഷിക്കുക learn_more: കൂടുതൽ പഠിക്കുക privacy_policy: സ്വകാര്യതാ നയം see_whats_happening: എന്തൊക്കെ സംഭവിക്കുന്നു എന്ന് കാണുക + source_code: സോഴ്സ് കോഡ് status_count_before: ആരാൽ എഴുതപ്പെട്ടു tagline: സുഹൃത്തുക്കളെ പിന്തുടരുകയും പുതിയവരെ കണ്ടെത്തുകയും ചെയ്യുക terms: സേവന വ്യവസ്ഥകൾ unavailable_content: ലഭ്യമല്ലാത്ത ഉള്ളടക്കം unavailable_content_description: + domain: സെർവർ reason: കാരണം what_is_mastodon: എന്താണ് മാസ്റ്റഡോൺ? accounts: follow: പിന്തുടരുക - following: നിങ്ങൾ പിന്തുടരുന്നവർ + following: പിന്തുടരുന്നു joined: "%{date} ൽ ചേർന്നു" last_active: അവസാനം സജീവമായിരുന്നത് link_verified_on: സന്ധിയുടെ ഉടമസ്ഥാവസ്‌കാശം %{date} ൽ പരിശോധിക്കപ്പെട്ടു media: മാധ്യമങ്ങൾ moved_html: "%{name}, %{new_profile_link} ലേക്ക് നീങ്ങിയിരിക്കുന്നു:" + network_hidden: ഈ വിവരം ലഭ്യമല്ല + nothing_here: ഇവിടെ ഒന്നുമില്ല! + posts_tab_heading: ടൂട്ടുകൾ + posts_with_replies: ടൂട്ടുകളും മറുപടികളും + roles: + admin: അഡ്‌മിന്‍ + bot: ബോട്ട് + group: ഗ്രൂപ്പ് + unavailable: പ്രൊഫൈൽ ലഭ്യമല്ല admin: account_moderation_notes: delete: മായ്ക്കുക accounts: + add_email_domain_block: ഇ-മെയിൽ ഡൊമെയ്ൻ തടയുക approve: അംഗീകരിക്കുക + approve_all: എല്ലാം അംഗീകരിക്കുക + are_you_sure: നിങ്ങൾക്ക് ഉറപ്പാണോ? + avatar: അവതാർ by_domain: മേഖല change_email: changed_msg: അംഗത്തിന്റെ ഇലക്ട്രോണിക് കത്തിന്റെ മേൽവിലാസം വിജയകരമായി മാറ്റിയിരിക്കുന്നു! @@ -37,6 +57,8 @@ ml: title: "%{username} ന്റെ ഇലക്ട്രോണിക് കത്ത് മേൽവിലാസം മാറ്റുക" confirm: നിജപ്പെടുത്തുക confirmed: നിജപ്പെടുത്തി + confirming: സ്ഥിരീകരിക്കുന്നു + delete: ഡാറ്റ ഇല്ലാതാക്കുക deleted: മായിച്ചു demote: തരം താഴ്ത്തുക disable: പ്രവര്‍ത്തന രഹിതമാക്കുക @@ -44,6 +66,56 @@ ml: disabled: പ്രവർത്തന രഹിതമാക്കപ്പെട്ടിരിക്കുന്നു display_name: കാണപ്പെടുന്ന നാമം domain: മേഖല + edit: തിരുത്തുക + email: ഇമെയിൽ + header: തലക്കെട്ട് + location: + all: എല്ലാം + moderation: + active: സജീവമാണ് + all: എല്ലാം + resend_confirmation: + send: സ്ഥിരീകരണ ഇമെയിൽ വീണ്ടും അയയ്ക്കുക + success: സ്ഥിരീകരണ ഇമെയിൽ വിജയകരമായി അയച്ചു! + reset: പുനഃക്രമീകരിക്കുക + reset_password: പാസ്‌വേഡ് പുനഃക്രമീകരിക്കുക + role: അനുമതികൾ + roles: + user: ഉപയോക്താവ് + search: തിരയുക + title: അക്കൗണ്ടുകൾ + unconfirmed_email: സ്ഥിരീകരിക്കാത്ത ഇമെയിൽ + username: ഉപയോക്തൃനാമം + web: വെബ് + action_logs: + action_types: + confirm_user: ഉപയോക്താവിനെ സ്ഥിരീകരിക്കുക + remove_avatar_user: അവതാർ നീക്കംചെയ്യുക + reset_password_user: പാസ്‌വേഡ് പുനഃക്രമീകരിക്കുക + custom_emojis: + copy: പകര്‍ത്തുക + create_new_category: പുതിയ വിഭാഗം സൃഷ്ടിക്കുക + delete: ഇല്ലാതാക്കുക + emoji: ഇമോജി + dashboard: + feature_profile_directory: പ്രൊഫൈൽ ഡയറക്ടറി + features: സവിശേഷതകൾ + title: ഡാഷ്ബോർഡ് + total_users: മൊത്തം ഉപയോക്താക്കൾ + trends: ട്രെൻഡുകൾ + email_domain_blocks: + add_new: പുതിയത് ചേര്‍ക്കുക + delete: ഇല്ലാതാക്കുക + domain: ഡൊമൈന്‍ + new: + create: ഡൊമൈൻ ചേര്‍ക്കുക + invites: + filter: + all: എല്ലാം + authorize_follow: + following: 'വിജയകരം! നിങ്ങൾ ഇപ്പോൾ പിന്തുടരുന്നു:' + directories: + directory: പ്രൊഫൈൽ ഡയറക്ടറി errors: '400': The request you submitted was invalid or malformed. '403': You don't have permission to view this page. @@ -54,3 +126,18 @@ ml: '429': Too many requests '500': '503': The page could not be served due to a temporary server failure. + filters: + contexts: + notifications: അറിയിപ്പുകൾ + generic: + all: എല്ലാം + notification_mailer: + digest: + action: എല്ലാ അറിയിപ്പുകളും കാണിക്കുക + follow: + body: "%{name} ഇപ്പോൾ നിങ്ങളെ പിന്തുടരുന്നു!" + subject: "%{name} ഇപ്പോൾ നിങ്ങളെ പിന്തുടരുന്നു" + relationships: + following: പിന്തുടരുന്നു + settings: + notifications: അറിയിപ്പുകൾ diff --git a/config/locales/nl.yml b/config/locales/nl.yml index d9c4e20fa..a419e0b47 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -60,6 +60,7 @@ nl: one: Volger other: Volgers following: Volgend + instance_actor_flash: Dit account is een 'virtual actor' waarmee de server zichzelf vertegenwoordigd en is dus geen individuele gebruiker. Het wordt voor federatiedoeleinden gebruikt en moet niet worden opgeschort. joined: Geregistreerd in %{date} last_active: laatst actief link_verified_on: Eigendom van deze link is gecontroleerd op %{date} @@ -131,6 +132,7 @@ nl: follows: Volgt header: Omslagfoto inbox_url: Inbox-URL + invite_request_text: Redenen om te registreren invited_by: Uitgenodigd door ip: IP joined: Geregistreerd in @@ -207,8 +209,11 @@ nl: undo_sensitized: Niet meer als gevoelig markeren undo_silenced: Niet langer negeren undo_suspension: Niet langer opschorten + unsilenced_msg: Het opheffen van de beperkingen van %{username} zijn geslaagd unsubscribe: Opzeggen + unsuspended_msg: Het niet langer opschorten van %{username} is geslaagd username: Gebruikersnaam + view_domain: Samenvatting voor domein bekijken warn: Waarschuwen web: Webapp whitelisted: Goedgekeurd voor federatie @@ -243,13 +248,16 @@ nl: reopen_report: Rapportage heropenen reset_password_user: Wachtwoord opnieuw instellen resolve_report: Rapportage oplossen + sensitive_account: De media in jouw account als gevoelig markeren silence_account: Account negeren suspend_account: Account opschorten unassigned_report: Rapportage niet langer toewijzen + unsensitive_account: De media in jouw account niet langer als gevoelig markeren unsilence_account: Account niet langer negeren unsuspend_account: Account niet langer opschorten update_announcement: Mededeling bijwerken update_custom_emoji: Lokale emoji bijwerken + update_domain_block: Domeinblokkade bijwerken update_status: Toot bijwerken actions: assigned_to_self_report: "%{name} heeft rapportage %{target} aan zichzelf toegewezen" @@ -428,6 +436,7 @@ nl: instances: by_domain: Domein delivery_available: Bezorging is mogelijk + empty: Geen domeinen gevonden. known_accounts: one: "%{count} bekend account" other: "%{count} bekende accounts" @@ -505,6 +514,8 @@ nl: comment: none: Geen created_at: Gerapporteerd op + forwarded: Doorgestuurd + forwarded_to: Doorgestuurd naar %{domain} mark_as_resolved: Markeer als opgelost mark_as_unresolved: Markeer als onopgelost notes: @@ -742,6 +753,7 @@ nl: functional: Jouw account is volledig operationeel. pending: Jouw aanvraag moet nog worden beoordeeld door een van onze medewerkers. Dit kan misschien eventjes duren. Je ontvangt een e-mail wanneer jouw aanvraag is goedgekeurd. redirecting_to: Jouw account is inactief omdat het momenteel wordt doorverwezen naar %{acct}. + too_fast: Formulier is te snel ingediend. Probeer het nogmaals. trouble_logging_in: Problemen met inloggen? use_security_key: Beveiligingssleutel gebruiken authorize_follow: @@ -901,6 +913,8 @@ nl: status: Verificatiestatus view_proof: Bekijk bewijs imports: + errors: + over_rows_processing_limit: bevat meer dan %{count} rijen modes: merge: Samenvoegen merge_long: Bestaande gegevens behouden en nieuwe toevoegen @@ -1350,11 +1364,13 @@ nl: subject: disable: Jouw account %{acct} is bevroren none: Waarschuwing voor %{acct} + sensitive: De door jouw account %{acct} geplaatste media is als gevoelig gemarkeerd silence: Jouw account %{acct} is nu beperkt suspend: Jouw account %{acct} is opgeschort title: disable: Account bevroren none: Waarschuwing + sensitive: Jouw media is als gevoelig gemarkeerd silence: Account beperkt suspend: Account opgeschort welcome: @@ -1392,9 +1408,14 @@ nl: webauthn_credentials: add: Nieuwe beveiligingssleutel toevoegen create: + error: Er deed zich een probleem voor met het toevoegen van jouw beveiligingssleutel. Probeer het nogmaals. success: Het toevoegen van je beveiligingssleutel is geslaagd. delete: Verwijderen delete_confirmation: Weet je zeker dat je deze beveiligingssleutel wilt verwijderen? + description_html: Wanneer je verificatie met beveiligingssleutels inschakelt, moet je tijdens het inloggen een van jouw beveiligingssleutels gebruiken. + destroy: + error: Er deed zich een probleem voor met het verwijderen van jouw beveiligingssleutel. Probeer het nogmaals. + success: Het verwijderen van jouw beveiligingssleutel is geslaagd. invalid_credential: Ongeldige beveiligingssleutel nickname_hint: Voer de bijnaam in van jouw nieuwe beveiligingssleutel not_enabled: Je hebt WebAuthn nog niet ingeschakeld diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 763a59fbb..a53f0cee7 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -132,6 +132,7 @@ oc: login_status: Estat formulari de connexion media_attachments: Mèdias enviats memorialize: Passar en memorial + memorialized: Memorizat moderation: active: Actius all: Totes @@ -773,6 +774,7 @@ oc: request: Demandar vòstre archiu size: Talha blocks: Personas que blocatz + bookmarks: Marcadors csv: CSV domain_blocks: Blocatge de domenis lists: Listas @@ -847,6 +849,7 @@ oc: success: Vòstras donadas son ben estadas mandadas e seràn tractadas tre que possible types: blocking: Lista de blocatge + bookmarks: Marcadors domain_blocking: Lista dels domenis blocats following: Lista de monde que seguètz muting: Lista de monde que volètz pas legir @@ -1083,6 +1086,9 @@ oc: spam_detected: Aquò es un senhalament automatic. D’spam es estat detectat. statuses: attached: + audio: + one: "%{count} àudio" + other: "%{count} àudios" description: 'Ajustat : %{attached}' image: one: "%{count} imatge" @@ -1232,6 +1238,7 @@ oc: recovery_codes: Salvar los còdis de recuperacion recovery_codes_regenerated: Los còdis de recuperacion son ben estats tornats generar recovery_instructions_html: Se vos arriba de perdre vòstre mobil, podètz utilizar un dels còdis de recuperacion cai-jos per poder tornar accedir a vòstre compte. Gardatz los còdis en seguretat, per exemple, imprimissètz los e gardatz los amb vòstres documents importants. + webauthn: Claus de seguretat user_mailer: backup_ready: explanation: Avètz demandat una salvagarda complèta de vòstre compte Mastodon. Es prèsta per telecargament ! @@ -1284,4 +1291,7 @@ oc: 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 + delete: Suprimir + invalid_credential: Cau de seguretat invalida registered_on: Inscripcion del %{date} diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 6b0f5ae58..23c67267e 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -582,6 +582,7 @@ pl: domain_blocks_rationale: title: Pokaż uzasadnienia enable_bootstrap_timeline_accounts: + desc_html: Niech nowi użytkownicy automatycznie śledzą ustawione konta, aby ich główna oś czasu nie był początkowo pusta title: Dodawaj domyślne obserwacje nowym użytkownikom hero: desc_html: Wyświetlany na stronie głównej. Zalecany jest rozmiar przynajmniej 600x100 pikseli. Jeżeli nie ustawiony, zostanie użyta miniatura serwera diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 19584201f..f7b47fb10 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -566,6 +566,7 @@ pt-PT: domain_blocks_rationale: title: Mostrar motivo enable_bootstrap_timeline_accounts: + desc_html: Faça com que novos utilizadores sigam automaticamente contas configuradas, para que a cronologia destes não se apresente inicialmente vazia title: Habilitar seguidores predefinidos para novos utilizadores hero: desc_html: Apresentado na primeira página. Pelo menos 600x100px recomendados. Quando não é definido, é apresentada a miniatura da instância diff --git a/config/locales/simple_form.hy.yml b/config/locales/simple_form.hy.yml index cdea55a5d..65cd315ac 100644 --- a/config/locales/simple_form.hy.yml +++ b/config/locales/simple_form.hy.yml @@ -94,6 +94,7 @@ hy: types: disable: Փակել մուտքը none: Ոչինչ չանել + sensitive: Զգայուն silence: Լուռ suspend: Արգելափակել եւ անվերադարձ ջնջել հաշուի ամբողջ ինֆորմացիան warning_preset_id: Օգտագործել զգուշացնող նախադիր @@ -119,6 +120,7 @@ hy: expires_in: Սպառուում է fields: Հաշուի մետադատա header: Վերնագիր + honeypot: "%{label} (չլրացնել)" inbox_url: Ներմուծման շերտի URL irreversible: Թաքցնելու փոխարէն ջնջել locale: Ինտերֆեյսի լեզու diff --git a/config/locales/simple_form.ml.yml b/config/locales/simple_form.ml.yml index df04a15e8..c60cd9699 100644 --- a/config/locales/simple_form.ml.yml +++ b/config/locales/simple_form.ml.yml @@ -14,3 +14,7 @@ ml: acct: പഴയ അംഗത്വത്തിലേക്കുള്ള പിടി account_migration: acct: പുതിയ അംഗത്വത്തിലേക്കുള്ള പിടി + defaults: + email: ഇ-മെയിൽ വിലാസം + notification_emails: + follow: ആരോ നിങ്ങളെ പിന്തുടർന്നു diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index bdaa1dd5c..8abc9448c 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -121,6 +121,7 @@ nl: expires_in: Vervalt na fields: Metadata profiel header: Omslagfoto + honeypot: "%{label} (niet invullen)" inbox_url: Inbox-URL van de relayserver irreversible: Verwijderen in plaats van verbergen locale: Taal van de gebruikersomgeving @@ -173,7 +174,7 @@ nl: invite: comment: Opmerking invite_request: - text: Waarom wil jij je aanmelden? + text: Waarom wil je je hier registreren? ip_block: comment: Opmerking ip: IP diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml index 120ddfbe0..79c621ee2 100644 --- a/config/locales/simple_form.oc.yml +++ b/config/locales/simple_form.oc.yml @@ -126,6 +126,7 @@ oc: expires_in: Expira aprèp fields: Metadonada del perfil header: Bandièra + honeypot: "%{label} (emplenar pas)" inbox_url: URL de la bóstia de recepcion del relai irreversible: Suprimir allòc de rescondre locale: Lenga de l’interfàcia diff --git a/config/locales/sq.yml b/config/locales/sq.yml index a46c3a586..e841ab690 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -566,6 +566,7 @@ sq: domain_blocks_rationale: title: Shfaq arsye enable_bootstrap_timeline_accounts: + desc_html: Bëj që përdoruesit e rinj automatikisht të ndjekin llogaritë e formësuara, që prurja e tyre bazë të mos nisë e zbrazët title: Aktivizo ndjekje parazgjedhje për përdorues të rinj hero: desc_html: E shfaqur në faqen ballore. Këshillohet të paktën 600x100px. Kur nuk caktohet gjë, përdoret miniaturë e shërbyesit diff --git a/config/locales/vi.yml b/config/locales/vi.yml index be681b3a6..48bc6c844 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -558,6 +558,7 @@ vi: domain_blocks_rationale: title: Hiển thị lý do enable_bootstrap_timeline_accounts: + desc_html: Thiết lập người mới đăng ký sẽ tự động theo dõi những tài khoản cho trước nhằm tránh việc bảng tin trống title: Gợi ý theo dõi cho người dùng mới hero: desc_html: Hiển thị trên trang chủ. Kích cỡ tối thiểu 600x100px. Mặc định dùng hình thu nhỏ của máy chủ diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 6c9079834..c44e2ce5b 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -57,6 +57,7 @@ zh-CN: followers: other: 关注者 following: 正在关注 + instance_actor_flash: 这个账户是虚拟账户,用来代表服务器自身,不代表任何实际用户。它用于互通功能,不应该封禁。 joined: 加入于 %{date} last_active: 最近活动 link_verified_on: 此链接的所有权已在 %{date} 检查 @@ -397,6 +398,8 @@ zh-CN: silence: 自动隐藏 suspend: 自动封禁 title: 新增域名屏蔽 + obfuscate: 混淆域名 + obfuscate_hint: 如果启用了域名列表公开限制,就部分混淆列表中的域名 private_comment: 私密评论 private_comment_hint: 给这一域名限制添加备注,供监察员内部使用 public_comment: 公开评论 @@ -555,6 +558,7 @@ zh-CN: domain_blocks_rationale: title: 显示理由 enable_bootstrap_timeline_accounts: + desc_html: 让新用户自动关注指定用户,这样,他们的主页时间线就不会在一开始的时候空空荡荡 title: 开启新用户默认关注功能 hero: desc_html: 将用于在首页展示。推荐使用分辨率 600×100px 以上的图片。如未设置,将默认使用本站缩略图。 @@ -583,7 +587,7 @@ zh-CN: title: 允许发送邀请的用户组 require_invite_text: desc_html: 当注册需要手动批准时,将“你为什么想要加入?”设为必填项 - title: 要求新用户填写注册申请 + title: 要求新用户填写申请注册的原因 registrations_mode: modes: approved: 注册时需要批准 @@ -911,6 +915,8 @@ zh-CN: status: 验证状态 view_proof: 查看证明 imports: + errors: + over_rows_processing_limit: 包含行数超过了 %{count} modes: merge: 合并 merge_long: 保留现有记录并添加新的记录 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index a2ad6fbde..da340a1bc 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -57,6 +57,7 @@ zh-TW: followers: other: 關注者 following: 正在關注 + instance_actor_flash: 這個帳號是一個用來代表此伺服器的虛擬執行者,而非真實使用者。它用途為站點聯盟且不應被停權。 joined: 加入於 %{date} last_active: 上次活躍時間 link_verified_on: 此連結的所有權已在 %{date} 檢查過 @@ -127,6 +128,7 @@ zh-TW: follows: 正在關注 header: 開頭 inbox_url: 收件箱 (Inbox) URL + invite_request_text: 加入原因 invited_by: 邀請者 ip: IP 位址 joined: 已加入 @@ -251,6 +253,7 @@ zh-TW: unsuspend_account: 取消用戶的暫停狀態 update_announcement: 更新公告 update_custom_emoji: 更新自訂顏文字 + update_domain_block: 更新封鎖網域 update_status: 更新狀態 actions: assigned_to_self_report: "%{name} 接受了檢舉 %{target}" @@ -291,6 +294,7 @@ zh-TW: unsuspend_account: "%{name} 取消了使用者 %{target} 的停權狀態" update_announcement: "%{name} 更新了公告 %{target}" update_custom_emoji: "%{name} 更新了自訂表情符號 %{target}" + update_domain_block: "%{name} 更新封鎖網域 %{target}" update_status: "%{name} 重整了 %{target} 的嘟文" deleted_status: "(已刪除嘟文)" empty: 找不到 log @@ -394,6 +398,8 @@ zh-TW: silence: 靜音 suspend: 停權 title: 新增封鎖站點 + obfuscate: 混淆網域名稱 + obfuscate_hint: 若啟用網域廣告列表限制,於列表部份混淆網域名稱 private_comment: 私人留言 private_comment_hint: 請提供更多有關此站台限制的資訊以供版主作內部參考。 public_comment: 公開留言 @@ -432,6 +438,7 @@ zh-TW: instances: by_domain: 站台 delivery_available: 可傳送 + empty: 找不到網域 known_accounts: other: "%{count} 已知的帳戶" moderation: @@ -483,19 +490,31 @@ zh-TW: 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} 則備註" + reports: + other: "%{count} 則檢舉" action_taken_by: 操作執行者 are_you_sure: 你確定嗎? assign_to_self: 指派給自己 assigned: 指派負責人 + by_target_domain: 檢舉帳號之網域 comment: none: 無 created_at: 日期 + forwarded: 已轉寄 + forwarded_to: 轉寄到 %{domain} mark_as_resolved: 標記為「已解決」 mark_as_unresolved: 標記為「未解決」 notes: @@ -526,12 +545,20 @@ zh-TW: email: 用於聯絡的公開電子信箱位址 username: 請輸入使用者名稱 custom_css: + desc_html: 透過於每個頁面都載入的 CSS 調整外觀 title: 自訂 CSS + default_noindex: + desc_html: 影響所有沒有變更此設定的使用者 + title: 預設將使用者退出搜尋引擎索引 domain_blocks: all: 給任何人 disabled: 給沒有人 title: 顯示封鎖的網域 + users: 套用至所有登入的本機使用者 + domain_blocks_rationale: + title: 顯示解釋原因 enable_bootstrap_timeline_accounts: + desc_html: 使新使用者自動跟隨設定之帳號,所以他們的首頁動態一開始不會空白 title: 啟用新使用者的預設追蹤 hero: desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會重設回伺服器預覽圖 @@ -543,6 +570,7 @@ zh-TW: desc_html: 本伺服器在聯邦中發現的站點 title: 發布已知伺服器的列表 preview_sensitive_media: + desc_html: 連結來自其他網站的預覽將顯示於縮圖,即使這些媒體被標記為敏感 title: 在 OpenGraph 預覽中顯示敏感媒體 profile_directory: desc_html: 允許能探索使用者 From 814b7775fbb175bf6fb30e7f775b77c334658a8a Mon Sep 17 00:00:00 2001 From: ThibG Date: Wed, 23 Dec 2020 01:35:02 +0100 Subject: [PATCH 8/9] Improve performances of deleting favourites when deleting accounts (#15412) Co-authored-by: Claire --- app/services/delete_account_service.rb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb index 58f6ef2ab..2bb533cfb 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -9,13 +9,11 @@ class DeleteAccountService < BaseService aliases block_relationships blocked_by_relationships - bookmarks conversation_mutes conversations custom_filters devices domain_blocks - favourites featured_tags follow_requests identity_proofs @@ -147,6 +145,8 @@ class DeleteAccountService < BaseService purge_media_attachments! purge_polls! purge_generated_notifications! + purge_favourites! + purge_bookmarks! purge_feeds! purge_other_associations! @@ -178,6 +178,24 @@ class DeleteAccountService < BaseService Notification.where(from_account: @account).in_batches.delete_all end + def purge_favourites! + @account.favourites.in_batches do |favourites| + ids = favourites.pluck(:status_id) + StatusStat.where(status_id: ids).update_all('favourites_count = GREATEST(0, favourites_count - 1)') + Chewy.strategy.current.update(StatusesIndex, ids) if Chewy.enabled? + # Rails.cache.delete_multi would be better, but we don't have it yet + ids.each { |id| Rails.cache.delete("statuses/#{id}") } + favourites.delete_all + end + end + + def purge_bookmarks! + @account.bookmarks.in_batches do |bookmarks| + Chewy.strategy.current.update(StatusesIndex, bookmarks.pluck(:status_id)) if Chewy.enabled? + bookmarks.delete_all + end + end + def purge_other_associations! associations_for_destruction.each do |association_name| purge_association(association_name) From 444b21b55ff5768e4cbbaf7cfa8285c65a4b54f9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 23 Dec 2020 01:36:13 +0100 Subject: [PATCH 9/9] Bump version to 3.3.0rc3 (#15411) --- CHANGELOG.md | 8 +++++--- lib/mastodon/version.rb | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4396dc96c..12c996641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,7 +55,7 @@ All notable changes to this project will be documented in this file. - Add indication to admin UI of whether a report has been forwarded ([ThibG](https://github.com/tootsuite/mastodon/pull/13237)) - Add display of reasons for joining of an account in admin UI ([mashirozx](https://github.com/tootsuite/mastodon/pull/15265)) - Add option to obfuscate domain name in public list of domain blocks ([Gargron](https://github.com/tootsuite/mastodon/pull/15355)) -- Add option to make reasons for joining required on sign-up ([ThibG](https://github.com/tootsuite/mastodon/pull/15326), [ThibG](https://github.com/tootsuite/mastodon/pull/15358)) +- Add option to make reasons for joining required on sign-up ([ThibG](https://github.com/tootsuite/mastodon/pull/15326), [ThibG](https://github.com/tootsuite/mastodon/pull/15358), [ThibG](https://github.com/tootsuite/mastodon/pull/15385), [ThibG](https://github.com/tootsuite/mastodon/pull/15405)) - Add ActivityPub follower synchronization mechanism ([ThibG](https://github.com/tootsuite/mastodon/pull/14510), [ThibG](https://github.com/tootsuite/mastodon/pull/15026)) - Add outbox attribute to instance actor ([ThibG](https://github.com/tootsuite/mastodon/pull/14721)) - Add featured hashtags as an ActivityPub collection ([Gargron](https://github.com/tootsuite/mastodon/pull/11595), [noellabo](https://github.com/tootsuite/mastodon/pull/15277)) @@ -66,7 +66,7 @@ All notable changes to this project will be documented in this file. - Add `tootctl accounts merge` ([Gargron](https://github.com/tootsuite/mastodon/pull/15201), [ThibG](https://github.com/tootsuite/mastodon/pull/15264), [ThibG](https://github.com/tootsuite/mastodon/pull/15256)) - Has someone changed their domain or subdomain thereby creating two accounts where there should be one? - This command will fix it on your end -- Add `tootctl maintenance fix-duplicates` ([ThibG](https://github.com/tootsuite/mastodon/pull/14860), [Gargron](https://github.com/tootsuite/mastodon/pull/15223)) +- Add `tootctl maintenance fix-duplicates` ([ThibG](https://github.com/tootsuite/mastodon/pull/14860), [Gargron](https://github.com/tootsuite/mastodon/pull/15223), [ThibG](https://github.com/tootsuite/mastodon/pull/15373)) - Index corruption in the database? - This command is for you - **Add support for managing multiple stream subscriptions in a single connection** ([Gargron](https://github.com/tootsuite/mastodon/pull/14524), [Gargron](https://github.com/tootsuite/mastodon/pull/14566), [mfmfuyu](https://github.com/tootsuite/mastodon/pull/14859), [zunda](https://github.com/tootsuite/mastodon/pull/14608)) @@ -77,6 +77,7 @@ All notable changes to this project will be documented in this file. - Add `GET /api/v1/accounts/:id/featured_tags` to REST API ([noellabo](https://github.com/tootsuite/mastodon/pull/11817), [noellabo](https://github.com/tootsuite/mastodon/pull/15270)) - Add stoplight for object storage failures, return HTTP 503 in REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/13043)) - Add optional `tootctl remove media` cronjob in Helm chart ([dunn](https://github.com/tootsuite/mastodon/pull/14396)) +- Add clean error message when `RAILS_ENV` is unset ([ThibG](https://github.com/tootsuite/mastodon/pull/15381)) ### Changed @@ -84,7 +85,7 @@ All notable changes to this project will be documented in this file. - Background of the overlay matches the color of the image - Action bar to interact with or open the toot from the modal - Change order of announcements in admin UI to be newest-first ([ThibG](https://github.com/tootsuite/mastodon/pull/15091)) -- **Change account suspensions to be reversible by default** ([Gargron](https://github.com/tootsuite/mastodon/pull/14726), [ThibG](https://github.com/tootsuite/mastodon/pull/15152), [ThibG](https://github.com/tootsuite/mastodon/pull/15106), [ThibG](https://github.com/tootsuite/mastodon/pull/15100), [ThibG](https://github.com/tootsuite/mastodon/pull/15099), [noellabo](https://github.com/tootsuite/mastodon/pull/14855)) +- **Change account suspensions to be reversible by default** ([Gargron](https://github.com/tootsuite/mastodon/pull/14726), [ThibG](https://github.com/tootsuite/mastodon/pull/15152), [ThibG](https://github.com/tootsuite/mastodon/pull/15106), [ThibG](https://github.com/tootsuite/mastodon/pull/15100), [ThibG](https://github.com/tootsuite/mastodon/pull/15099), [noellabo](https://github.com/tootsuite/mastodon/pull/14855), [ThibG](https://github.com/tootsuite/mastodon/pull/15380)) - Suspensions no longer equal deletions - A suspended account can be unsuspended with minimal consequences for 30 days - Immediate deletion of data is still available as an explicit option @@ -162,6 +163,7 @@ All notable changes to this project will be documented in this file. - Fix inefficiency when fetching bookmarks ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14674)) - Fix inefficiency when fetching favourites ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14673)) - Fix inefficiency when fetching media-only account timeline ([akihikodaki](https://github.com/tootsuite/mastodon/pull/14675)) +- Fix inefficieny when deleting accounts ([Gargron](https://github.com/tootsuite/mastodon/pull/15387), [ThibG](https://github.com/tootsuite/mastodon/pull/15409), [ThibG](https://github.com/tootsuite/mastodon/pull/15407), [ThibG](https://github.com/tootsuite/mastodon/pull/15408), [ThibG](https://github.com/tootsuite/mastodon/pull/15402)) - Fix redundant query when processing batch actions on custom emojis ([niwatori24](https://github.com/tootsuite/mastodon/pull/14534)) - Fix slow distinct queries where grouped queries are faster ([Gargron](https://github.com/tootsuite/mastodon/pull/15287)) - Fix performance on instances list in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/15282)) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 7282ea7b5..95ae777f2 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -17,7 +17,7 @@ module Mastodon end def flags - 'rc2' + 'rc3' end def suffix