about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml13
-rw-r--r--.ruby-version2
-rw-r--r--CHANGELOG.md73
-rw-r--r--Dockerfile6
-rw-r--r--Gemfile32
-rw-r--r--Gemfile.lock244
-rw-r--r--Vagrantfile2
-rw-r--r--app/chewy/statuses_index.rb5
-rw-r--r--app/controllers/account_follow_controller.rb2
-rw-r--r--app/controllers/admin/action_logs_controller.rb14
-rw-r--r--app/controllers/admin/email_domain_blocks_controller.rb28
-rw-r--r--app/controllers/admin/site_uploads_controller.rb21
-rw-r--r--app/controllers/admin/warning_presets_controller.rb6
-rw-r--r--app/controllers/api/base_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/follower_accounts_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/following_accounts_controller.rb4
-rw-r--r--app/controllers/api/v1/accounts/identity_proofs_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/lists_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/pins_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/relationships_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/search_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb2
-rw-r--r--app/controllers/api/v1/accounts_controller.rb4
-rw-r--r--app/controllers/api/v1/apps/credentials_controller.rb2
-rw-r--r--app/controllers/api/v1/blocks_controller.rb2
-rw-r--r--app/controllers/api/v1/bookmarks_controller.rb2
-rw-r--r--app/controllers/api/v1/conversations_controller.rb2
-rw-r--r--app/controllers/api/v1/custom_emojis_controller.rb2
-rw-r--r--app/controllers/api/v1/domain_blocks_controller.rb2
-rw-r--r--app/controllers/api/v1/endorsements_controller.rb2
-rw-r--r--app/controllers/api/v1/favourites_controller.rb2
-rw-r--r--app/controllers/api/v1/featured_tags/suggestions_controller.rb3
-rw-r--r--app/controllers/api/v1/filters_controller.rb2
-rw-r--r--app/controllers/api/v1/instances/activity_controller.rb2
-rw-r--r--app/controllers/api/v1/instances/peers_controller.rb2
-rw-r--r--app/controllers/api/v1/instances_controller.rb2
-rw-r--r--app/controllers/api/v1/media_controller.rb31
-rw-r--r--app/controllers/api/v1/mutes_controller.rb2
-rw-r--r--app/controllers/api/v1/notifications_controller.rb2
-rw-r--r--app/controllers/api/v1/polls/votes_controller.rb2
-rw-r--r--app/controllers/api/v1/polls_controller.rb2
-rw-r--r--app/controllers/api/v1/preferences_controller.rb2
-rw-r--r--app/controllers/api/v1/reports_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/bookmarks_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/favourites_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/mutes_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/pins_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb2
-rw-r--r--app/controllers/api/v1/statuses/reblogs_controller.rb3
-rw-r--r--app/controllers/api/v1/statuses_controller.rb14
-rw-r--r--app/controllers/api/v1/streaming_controller.rb2
-rw-r--r--app/controllers/api/v1/suggestions_controller.rb2
-rw-r--r--app/controllers/api/v1/timelines/home_controller.rb2
-rw-r--r--app/controllers/api/v1/timelines/public_controller.rb2
-rw-r--r--app/controllers/api/v1/timelines/tag_controller.rb2
-rw-r--r--app/controllers/api/v1/trends_controller.rb2
-rw-r--r--app/controllers/api/v2/media_controller.rb12
-rw-r--r--app/controllers/api/v2/search_controller.rb2
-rw-r--r--app/controllers/api/web/embeds_controller.rb2
-rw-r--r--app/controllers/api/web/push_subscriptions_controller.rb2
-rw-r--r--app/controllers/api/web/settings_controller.rb2
-rw-r--r--app/controllers/application_controller.rb5
-rw-r--r--app/controllers/authorize_interactions_controller.rb2
-rw-r--r--app/controllers/concerns/rate_limit_headers.rb16
-rw-r--r--app/controllers/follower_accounts_controller.rb11
-rw-r--r--app/controllers/following_accounts_controller.rb11
-rw-r--r--app/controllers/settings/imports_controller.rb2
-rw-r--r--app/helpers/admin/action_logs_helper.rb75
-rw-r--r--app/helpers/admin/filter_helper.rb1
-rw-r--r--app/helpers/admin/settings_helper.rb11
-rw-r--r--app/javascript/core/admin.js6
-rw-r--r--app/javascript/core/public.js16
-rw-r--r--app/javascript/core/settings.js2
-rw-r--r--app/javascript/flavours/glitch/actions/accounts.js3
-rw-r--r--app/javascript/flavours/glitch/actions/alerts.js4
-rw-r--r--app/javascript/flavours/glitch/actions/compose.js23
-rw-r--r--app/javascript/flavours/glitch/actions/identity_proofs.js1
-rw-r--r--app/javascript/flavours/glitch/actions/timelines.js1
-rw-r--r--app/javascript/flavours/glitch/components/domain.js2
-rw-r--r--app/javascript/flavours/glitch/components/intersection_observer_article.js2
-rw-r--r--app/javascript/flavours/glitch/components/media_gallery.js2
-rw-r--r--app/javascript/flavours/glitch/components/poll.js28
-rw-r--r--app/javascript/flavours/glitch/containers/domain_container.js2
-rw-r--r--app/javascript/flavours/glitch/features/account/components/header.js8
-rw-r--r--app/javascript/flavours/glitch/features/audio/index.js6
-rw-r--r--app/javascript/flavours/glitch/features/blocks/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/compose_form.js29
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/options.js8
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/poll_form.js3
-rw-r--r--app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js9
-rw-r--r--app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js2
-rw-r--r--app/javascript/flavours/glitch/features/domain_blocks/index.js8
-rw-r--r--app/javascript/flavours/glitch/features/favourites/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/follow_requests/index.js19
-rw-r--r--app/javascript/flavours/glitch/features/followers/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/following/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/getting_started/components/announcements.js19
-rw-r--r--app/javascript/flavours/glitch/features/lists/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/mutes/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/reblogs/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/status/components/card.js2
-rw-r--r--app/javascript/flavours/glitch/features/status/components/detailed_status.js6
-rw-r--r--app/javascript/flavours/glitch/features/video/index.js20
-rw-r--r--app/javascript/flavours/glitch/middleware/errors.js2
-rw-r--r--app/javascript/flavours/glitch/packs/common.js2
-rw-r--r--app/javascript/flavours/glitch/packs/public.js24
-rw-r--r--app/javascript/flavours/glitch/packs/settings.js2
-rw-r--r--app/javascript/flavours/glitch/reducers/compose.js1
-rw-r--r--app/javascript/flavours/glitch/reducers/notifications.js4
-rw-r--r--app/javascript/flavours/glitch/reducers/timelines.js4
-rw-r--r--app/javascript/flavours/glitch/selectors/index.js2
-rw-r--r--app/javascript/flavours/glitch/store/configureStore.js2
-rw-r--r--app/javascript/flavours/glitch/styles/admin.scss68
-rw-r--r--app/javascript/flavours/glitch/styles/components/accounts.scss1
-rw-r--r--app/javascript/flavours/glitch/styles/components/announcements.scss7
-rw-r--r--app/javascript/flavours/glitch/styles/components/columns.scss8
-rw-r--r--app/javascript/flavours/glitch/styles/components/composer.scss4
-rw-r--r--app/javascript/flavours/glitch/styles/components/emoji.scss6
-rw-r--r--app/javascript/flavours/glitch/styles/components/index.scss1
-rw-r--r--app/javascript/flavours/glitch/styles/components/media.scss6
-rw-r--r--app/javascript/flavours/glitch/styles/components/status.scss6
-rw-r--r--app/javascript/flavours/glitch/styles/polls.scss42
-rw-r--r--app/javascript/flavours/glitch/util/log_out.js2
-rw-r--r--app/javascript/mastodon/actions/accounts.js5
-rw-r--r--app/javascript/mastodon/actions/alerts.js4
-rw-r--r--app/javascript/mastodon/actions/compose.js23
-rw-r--r--app/javascript/mastodon/actions/identity_proofs.js1
-rw-r--r--app/javascript/mastodon/actions/timelines.js1
-rw-r--r--app/javascript/mastodon/common.js2
-rw-r--r--app/javascript/mastodon/components/column_header.js3
-rw-r--r--app/javascript/mastodon/components/domain.js2
-rw-r--r--app/javascript/mastodon/components/intersection_observer_article.js2
-rw-r--r--app/javascript/mastodon/components/media_gallery.js2
-rw-r--r--app/javascript/mastodon/components/poll.js28
-rw-r--r--app/javascript/mastodon/components/scrollable_list.js20
-rw-r--r--app/javascript/mastodon/components/status.js8
-rw-r--r--app/javascript/mastodon/components/status_action_bar.js4
-rw-r--r--app/javascript/mastodon/components/status_content.js14
-rw-r--r--app/javascript/mastodon/containers/domain_container.js2
-rw-r--r--app/javascript/mastodon/features/account/components/header.js8
-rw-r--r--app/javascript/mastodon/features/audio/index.js6
-rw-r--r--app/javascript/mastodon/features/blocks/index.js2
-rw-r--r--app/javascript/mastodon/features/compose/components/action_bar.js2
-rw-r--r--app/javascript/mastodon/features/compose/components/poll_form.js3
-rw-r--r--app/javascript/mastodon/features/compose/components/privacy_dropdown.js8
-rw-r--r--app/javascript/mastodon/features/direct_timeline/components/conversation.js2
-rw-r--r--app/javascript/mastodon/features/domain_blocks/index.js8
-rw-r--r--app/javascript/mastodon/features/favourites/index.js2
-rw-r--r--app/javascript/mastodon/features/follow_requests/index.js19
-rw-r--r--app/javascript/mastodon/features/followers/index.js2
-rw-r--r--app/javascript/mastodon/features/following/index.js2
-rw-r--r--app/javascript/mastodon/features/getting_started/components/announcements.js19
-rw-r--r--app/javascript/mastodon/features/getting_started/index.js8
-rw-r--r--app/javascript/mastodon/features/lists/index.js2
-rw-r--r--app/javascript/mastodon/features/mutes/index.js2
-rw-r--r--app/javascript/mastodon/features/reblogs/index.js2
-rw-r--r--app/javascript/mastodon/features/status/components/action_bar.js4
-rw-r--r--app/javascript/mastodon/features/status/components/card.js2
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/__tests__/column-test.js2
-rw-r--r--app/javascript/mastodon/features/video/index.js14
-rw-r--r--app/javascript/mastodon/locales/ast.json4
-rw-r--r--app/javascript/mastodon/locales/bg.json2
-rw-r--r--app/javascript/mastodon/locales/br.json486
-rw-r--r--app/javascript/mastodon/locales/cs.json6
-rw-r--r--app/javascript/mastodon/locales/de.json14
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json46
-rw-r--r--app/javascript/mastodon/locales/el.json12
-rw-r--r--app/javascript/mastodon/locales/en.json25
-rw-r--r--app/javascript/mastodon/locales/eo.json4
-rw-r--r--app/javascript/mastodon/locales/es-AR.json4
-rw-r--r--app/javascript/mastodon/locales/eu.json18
-rw-r--r--app/javascript/mastodon/locales/fa.json10
-rw-r--r--app/javascript/mastodon/locales/fi.json40
-rw-r--r--app/javascript/mastodon/locales/fr.json166
-rw-r--r--app/javascript/mastodon/locales/ga.json2
-rw-r--r--app/javascript/mastodon/locales/gl.json36
-rw-r--r--app/javascript/mastodon/locales/hi.json2
-rw-r--r--app/javascript/mastodon/locales/hu.json2
-rw-r--r--app/javascript/mastodon/locales/hy.json124
-rw-r--r--app/javascript/mastodon/locales/it.json4
-rw-r--r--app/javascript/mastodon/locales/ja.json24
-rw-r--r--app/javascript/mastodon/locales/kab.json124
-rw-r--r--app/javascript/mastodon/locales/kn.json2
-rw-r--r--app/javascript/mastodon/locales/ko.json12
-rw-r--r--app/javascript/mastodon/locales/lt.json2
-rw-r--r--app/javascript/mastodon/locales/lv.json2
-rw-r--r--app/javascript/mastodon/locales/mk.json2
-rw-r--r--app/javascript/mastodon/locales/ml.json2
-rw-r--r--app/javascript/mastodon/locales/mr.json2
-rw-r--r--app/javascript/mastodon/locales/ms.json2
-rw-r--r--app/javascript/mastodon/locales/nl.json32
-rw-r--r--app/javascript/mastodon/locales/nn.json16
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json20
-rw-r--r--app/javascript/mastodon/locales/pt-PT.json34
-rw-r--r--app/javascript/mastodon/locales/ru.json18
-rw-r--r--app/javascript/mastodon/locales/sk.json12
-rw-r--r--app/javascript/mastodon/locales/sr.json130
-rw-r--r--app/javascript/mastodon/locales/sv.json6
-rw-r--r--app/javascript/mastodon/locales/th.json40
-rw-r--r--app/javascript/mastodon/locales/ur.json2
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json2
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json14
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json14
-rw-r--r--app/javascript/mastodon/middleware/errors.js2
-rw-r--r--app/javascript/mastodon/reducers/compose.js1
-rw-r--r--app/javascript/mastodon/reducers/notifications.js4
-rw-r--r--app/javascript/mastodon/reducers/timelines.js4
-rw-r--r--app/javascript/mastodon/selectors/index.js2
-rw-r--r--app/javascript/mastodon/service_worker/web_push_notifications.js2
-rw-r--r--app/javascript/mastodon/store/configureStore.js2
-rw-r--r--app/javascript/mastodon/utils/log_out.js2
-rw-r--r--app/javascript/packs/public.js24
-rw-r--r--app/javascript/styles/mastodon-light/diff.scss2
-rw-r--r--app/javascript/styles/mastodon/admin.scss68
-rw-r--r--app/javascript/styles/mastodon/components.scss39
-rw-r--r--app/javascript/styles/mastodon/polls.scss42
-rw-r--r--app/lib/activitypub/tag_manager.rb2
-rw-r--r--app/lib/entity_cache.rb4
-rw-r--r--app/lib/exceptions.rb1
-rw-r--r--app/lib/formatter.rb8
-rw-r--r--app/lib/language_detector.rb4
-rw-r--r--app/lib/rate_limiter.rb64
-rw-r--r--app/lib/sanitize_config.rb14
-rw-r--r--app/models/account.rb10
-rw-r--r--app/models/account_filter.rb27
-rw-r--r--app/models/account_warning_preset.rb3
-rw-r--r--app/models/admin/account_action.rb12
-rw-r--r--app/models/admin/action_log_filter.rb81
-rw-r--r--app/models/announcement.rb11
-rw-r--r--app/models/concerns/account_interactions.rb16
-rw-r--r--app/models/concerns/attachmentable.rb2
-rw-r--r--app/models/concerns/rate_limitable.rb36
-rw-r--r--app/models/email_domain_block.rb14
-rw-r--r--app/models/follow.rb3
-rw-r--r--app/models/follow_request.rb3
-rw-r--r--app/models/media_attachment.rb122
-rw-r--r--app/models/report.rb11
-rw-r--r--app/models/status.rb20
-rw-r--r--app/policies/settings_policy.rb4
-rw-r--r--app/serializers/rest/announcement_serializer.rb13
-rw-r--r--app/serializers/rest/media_attachment_serializer.rb4
-rw-r--r--app/services/account_search_service.rb2
-rw-r--r--app/services/activitypub/process_account_service.rb25
-rw-r--r--app/services/fetch_resource_service.rb3
-rw-r--r--app/services/follow_service.rb78
-rw-r--r--app/services/import_service.rb3
-rw-r--r--app/services/post_status_service.rb23
-rw-r--r--app/services/reblog_service.rb16
-rw-r--r--app/services/resolve_url_service.rb10
-rw-r--r--app/services/search_service.rb4
-rw-r--r--app/views/admin/account_actions/new.html.haml2
-rw-r--r--app/views/admin/accounts/_account.html.haml2
-rw-r--r--app/views/admin/accounts/index.html.haml6
-rw-r--r--app/views/admin/accounts/show.html.haml15
-rw-r--r--app/views/admin/action_logs/_action_log.html.haml6
-rw-r--r--app/views/admin/action_logs/index.html.haml21
-rw-r--r--app/views/admin/email_domain_blocks/_email_domain_block.html.haml10
-rw-r--r--app/views/admin/email_domain_blocks/new.html.haml5
-rw-r--r--app/views/admin/settings/edit.html.haml11
-rw-r--r--app/views/admin/warning_presets/_warning_preset.html.haml10
-rw-r--r--app/views/admin/warning_presets/edit.html.haml3
-rw-r--r--app/views/admin/warning_presets/index.html.haml24
-rw-r--r--app/views/errors/429.html.haml5
-rw-r--r--app/views/settings/preferences/appearance/show.html.haml5
-rw-r--r--app/views/settings/preferences/notifications/show.html.haml8
-rw-r--r--app/views/settings/preferences/other/show.html.haml5
-rw-r--r--app/views/settings/profiles/show.html.haml5
-rw-r--r--app/views/statuses/_poll.html.haml10
-rw-r--r--app/workers/activitypub/distribute_poll_update_worker.rb2
-rw-r--r--app/workers/activitypub/synchronize_featured_collection_worker.rb2
-rw-r--r--app/workers/after_remote_follow_request_worker.rb9
-rw-r--r--app/workers/after_remote_follow_worker.rb9
-rw-r--r--app/workers/backup_worker.rb8
-rw-r--r--app/workers/notification_worker.rb9
-rw-r--r--app/workers/poll_expiration_notify_worker.rb2
-rw-r--r--app/workers/post_process_media_worker.rb34
-rw-r--r--app/workers/processing_worker.rb9
-rw-r--r--app/workers/publish_scheduled_announcement_worker.rb15
-rw-r--r--app/workers/publish_scheduled_status_worker.rb2
-rw-r--r--app/workers/pubsubhubbub/confirmation_worker.rb9
-rw-r--r--app/workers/pubsubhubbub/delivery_worker.rb9
-rw-r--r--app/workers/pubsubhubbub/distribution_worker.rb9
-rw-r--r--app/workers/pubsubhubbub/raw_distribution_worker.rb9
-rw-r--r--app/workers/pubsubhubbub/subscribe_worker.rb9
-rw-r--r--app/workers/pubsubhubbub/unsubscribe_worker.rb9
-rw-r--r--app/workers/regeneration_worker.rb2
-rw-r--r--app/workers/remote_profile_update_worker.rb9
-rw-r--r--app/workers/resolve_account_worker.rb2
-rw-r--r--app/workers/salmon_worker.rb9
-rw-r--r--app/workers/scheduler/backup_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/doorkeeper_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/email_scheduler.rb2
-rw-r--r--app/workers/scheduler/feed_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/ip_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/media_cleanup_scheduler.rb2
-rw-r--r--app/workers/scheduler/pghero_scheduler.rb2
-rw-r--r--app/workers/scheduler/scheduled_statuses_scheduler.rb2
-rw-r--r--app/workers/scheduler/subscriptions_cleanup_scheduler.rb9
-rw-r--r--app/workers/scheduler/subscriptions_scheduler.rb9
-rw-r--r--app/workers/scheduler/trending_tags_scheduler.rb2
-rw-r--r--app/workers/scheduler/user_cleanup_scheduler.rb2
-rw-r--r--app/workers/verify_account_links_worker.rb2
-rw-r--r--config/application.rb2
-rw-r--r--config/deploy.rb2
-rw-r--r--config/initializers/content_security_policy.rb1
-rw-r--r--config/initializers/kaminari_config.rb2
-rw-r--r--config/initializers/rack_attack.rb2
-rw-r--r--config/initializers/sidekiq.rb7
-rw-r--r--config/locales/activerecord.br.yml6
-rw-r--r--config/locales/activerecord.hy.yml16
-rw-r--r--config/locales/activerecord.kab.yml5
-rw-r--r--config/locales/activerecord.zh-HK.yml4
-rw-r--r--config/locales/ar.yml70
-rw-r--r--config/locales/ast.yml3
-rw-r--r--config/locales/bg.yml2
-rw-r--r--config/locales/bn.yml2
-rw-r--r--config/locales/br.yml219
-rw-r--r--config/locales/ca.yml50
-rw-r--r--config/locales/co.yml50
-rw-r--r--config/locales/cs.yml4
-rw-r--r--config/locales/cy.yml6
-rw-r--r--config/locales/da.yml1
-rw-r--r--config/locales/de.yml50
-rw-r--r--config/locales/devise.br.yml8
-rw-r--r--config/locales/devise.fr.yml20
-rw-r--r--config/locales/devise.hy.yml6
-rw-r--r--config/locales/devise.is.yml4
-rw-r--r--config/locales/devise.kab.yml9
-rw-r--r--config/locales/devise.nn.yml62
-rw-r--r--config/locales/devise.pt-BR.yml106
-rw-r--r--config/locales/devise.pt-PT.yml4
-rw-r--r--config/locales/devise.ru.yml24
-rw-r--r--config/locales/devise.zh-HK.yml16
-rw-r--r--config/locales/doorkeeper.br.yml51
-rw-r--r--config/locales/doorkeeper.fr.yml10
-rw-r--r--config/locales/doorkeeper.kab.yml10
-rw-r--r--config/locales/doorkeeper.ko.yml4
-rw-r--r--config/locales/doorkeeper.nn.yml24
-rw-r--r--config/locales/doorkeeper.pt-BR.yml2
-rw-r--r--config/locales/doorkeeper.sk.yml4
-rw-r--r--config/locales/doorkeeper.th.yml2
-rw-r--r--config/locales/el.yml60
-rw-r--r--config/locales/en.yml51
-rw-r--r--config/locales/en_GB.yml1
-rw-r--r--config/locales/eo.yml13
-rw-r--r--config/locales/es-AR.yml52
-rw-r--r--config/locales/es.yml50
-rw-r--r--config/locales/et.yml1
-rw-r--r--config/locales/eu.yml21
-rw-r--r--config/locales/fa.yml59
-rw-r--r--config/locales/fi.yml19
-rw-r--r--config/locales/fr.yml194
-rw-r--r--config/locales/gl.yml50
-rw-r--r--config/locales/hi.yml2
-rw-r--r--config/locales/hr.yml2
-rw-r--r--config/locales/hu.yml88
-rw-r--r--config/locales/hy.yml7
-rw-r--r--config/locales/id.yml31
-rw-r--r--config/locales/io.yml2
-rw-r--r--config/locales/is.yml54
-rw-r--r--config/locales/it.yml52
-rw-r--r--config/locales/ja.yml50
-rw-r--r--config/locales/kab.yml105
-rw-r--r--config/locales/kk.yml1
-rw-r--r--config/locales/kn.yml2
-rw-r--r--config/locales/ko.yml50
-rw-r--r--config/locales/lt.yml1
-rw-r--r--config/locales/lv.yml2
-rw-r--r--config/locales/mk.yml2
-rw-r--r--config/locales/ml.yml2
-rw-r--r--config/locales/mr.yml2
-rw-r--r--config/locales/ms.yml2
-rw-r--r--config/locales/nl.yml5
-rw-r--r--config/locales/nn.yml5
-rw-r--r--config/locales/no.yml1
-rw-r--r--config/locales/oc.yml31
-rw-r--r--config/locales/pl.yml212
-rw-r--r--config/locales/pt-BR.yml76
-rw-r--r--config/locales/pt-PT.yml84
-rw-r--r--config/locales/ru.yml81
-rw-r--r--config/locales/simple_form.ar.yml2
-rw-r--r--config/locales/simple_form.ast.yml2
-rw-r--r--config/locales/simple_form.br.yml22
-rw-r--r--config/locales/simple_form.ca.yml7
-rw-r--r--config/locales/simple_form.co.yml7
-rw-r--r--config/locales/simple_form.cy.yml2
-rw-r--r--config/locales/simple_form.de.yml9
-rw-r--r--config/locales/simple_form.el.yml20
-rw-r--r--config/locales/simple_form.en.yml11
-rw-r--r--config/locales/simple_form.eo.yml6
-rw-r--r--config/locales/simple_form.es-AR.yml7
-rw-r--r--config/locales/simple_form.es.yml7
-rw-r--r--config/locales/simple_form.eu.yml25
-rw-r--r--config/locales/simple_form.fa.yml13
-rw-r--r--config/locales/simple_form.fr.yml43
-rw-r--r--config/locales/simple_form.gl.yml7
-rw-r--r--config/locales/simple_form.hu.yml7
-rw-r--r--config/locales/simple_form.id.yml7
-rw-r--r--config/locales/simple_form.is.yml7
-rw-r--r--config/locales/simple_form.it.yml9
-rw-r--r--config/locales/simple_form.ja.yml13
-rw-r--r--config/locales/simple_form.kab.yml20
-rw-r--r--config/locales/simple_form.ko.yml7
-rw-r--r--config/locales/simple_form.nl.yml2
-rw-r--r--config/locales/simple_form.oc.yml4
-rw-r--r--config/locales/simple_form.pl.yml24
-rw-r--r--config/locales/simple_form.pt-BR.yml13
-rw-r--r--config/locales/simple_form.pt-PT.yml17
-rw-r--r--config/locales/simple_form.ru.yml9
-rw-r--r--config/locales/simple_form.sk.yml8
-rw-r--r--config/locales/simple_form.sv.yml3
-rw-r--r--config/locales/simple_form.ta.yml9
-rw-r--r--config/locales/simple_form.th.yml20
-rw-r--r--config/locales/simple_form.zh-CN.yml7
-rw-r--r--config/locales/simple_form.zh-HK.yml33
-rw-r--r--config/locales/simple_form.zh-TW.yml33
-rw-r--r--config/locales/sk.yml29
-rw-r--r--config/locales/sl.yml1
-rw-r--r--config/locales/sq.yml1
-rw-r--r--config/locales/sr.yml1
-rw-r--r--config/locales/sv.yml9
-rw-r--r--config/locales/ta.yml15
-rw-r--r--config/locales/te.yml2
-rw-r--r--config/locales/th.yml67
-rw-r--r--config/locales/tr.yml1
-rw-r--r--config/locales/uk.yml1
-rw-r--r--config/locales/ur.yml2
-rw-r--r--config/locales/vi.yml1
-rw-r--r--config/locales/zh-CN.yml17
-rw-r--r--config/locales/zh-HK.yml89
-rw-r--r--config/locales/zh-TW.yml89
-rw-r--r--config/routes.rb6
-rw-r--r--config/webpack/development.js2
-rw-r--r--config/webpack/shared.js2
-rw-r--r--db/migrate/20191212163405_add_hide_collections_to_accounts.rb5
-rw-r--r--db/migrate/20200306035625_add_processing_to_media_attachments.rb5
-rw-r--r--db/migrate/20200312144258_add_title_to_account_warning_presets.rb15
-rw-r--r--db/migrate/20200312162302_add_status_ids_to_announcements.rb6
-rw-r--r--db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb5
-rw-r--r--db/schema.rb8
-rw-r--r--dist/nginx.conf12
-rw-r--r--lib/mastodon/media_cli.rb113
-rw-r--r--lib/mastodon/statuses_cli.rb8
-rw-r--r--lib/mastodon/version.rb2
-rw-r--r--lib/paperclip/attachment_extensions.rb43
-rw-r--r--lib/paperclip/url_generator_extensions.rb17
-rw-r--r--lib/paperclip/video_transcoder.rb18
-rw-r--r--package.json61
-rw-r--r--spec/controllers/account_follow_controller_spec.rb2
-rw-r--r--spec/controllers/admin/reports_controller_spec.rb20
-rw-r--r--spec/controllers/api/v1/statuses_controller_spec.rb46
-rw-r--r--spec/features/profile_spec.rb2
-rw-r--r--spec/helpers/admin/action_log_helper_spec.rb238
-rw-r--r--spec/lib/sanitize_config_spec.rb17
-rw-r--r--spec/rails_helper.rb2
-rw-r--r--spec/services/import_service_spec.rb8
-rw-r--r--spec/services/post_status_service_spec.rb7
-rw-r--r--yarn.lock1651
460 files changed, 6395 insertions, 3246 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 3ba027d95..dd943e327 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -6,6 +6,7 @@ aliases:
       - image: circleci/ruby:2.7-buster-node
         environment: &ruby_environment
           BUNDLE_APP_CONFIG: ./.bundle/
+          BUNDLE_PATH: ./vendor/bundle/
           DB_HOST: localhost
           DB_USER: root
           RAILS_ENV: test
@@ -138,9 +139,10 @@ jobs:
     docker:
       - image: circleci/ruby:2.7-buster-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.6-alpine
+      - image: circleci/postgres:12.2
         environment:
           POSTGRES_USER: root
+          POSTGRES_HOST_AUTH_METHOD: trust
       - image: circleci/redis:5-alpine
     steps:
       - *attach_workspace
@@ -157,9 +159,10 @@ jobs:
     docker:
       - image: circleci/ruby:2.7-buster-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.6-alpine
+      - image: circleci/postgres:12.2
         environment:
           POSTGRES_USER: root
+          POSTGRES_HOST_AUTH_METHOD: trust
       - image: circleci/redis:5-alpine
     <<: *test_steps
 
@@ -168,9 +171,10 @@ jobs:
     docker:
       - image: circleci/ruby:2.6-buster-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.6-alpine
+      - image: circleci/postgres:12.2
         environment:
           POSTGRES_USER: root
+          POSTGRES_HOST_AUTH_METHOD: trust
       - image: circleci/redis:5-alpine
     <<: *test_steps
 
@@ -179,9 +183,10 @@ jobs:
     docker:
       - image: circleci/ruby:2.5-buster-node
         environment: *ruby_environment
-      - image: circleci/postgres:10.6-alpine
+      - image: circleci/postgres:12.2
         environment:
           POSTGRES_USER: root
+          POSTGRES_HOST_AUTH_METHOD: trust
       - image: circleci/redis:5-alpine
     <<: *test_steps
 
diff --git a/.ruby-version b/.ruby-version
index 57cf282eb..338a5b5d8 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.6.5
+2.6.6
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33663c2ad..ad353e2ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,79 @@ Changelog
 
 All notable changes to this project will be documented in this file.
 
+## [v3.1.3] - 2020-04-05
+### Added
+
+- Add ability to filter audit log in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/13381))
+- Add titles to warning presets in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/13252))
+- Add option to include resolved DNS records when blacklisting e-mail domains in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/13254))
+- Add ability to delete files uploaded for settings in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13192))
+- Add sorting by username, creation and last activity in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13076))
+- Add explanation as to why unlocked accounts may have follow requests in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13385))
+- Add link to bookmarks to dropdown in web UI ([mayaeh](https://github.com/tootsuite/mastodon/pull/13273))
+- Add support for links to statuses in announcements to be opened in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13212), [ThibG](https://github.com/tootsuite/mastodon/pull/13250))
+- Add tooltips to audio/video player buttons in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13203))
+- Add submit button to the top of preferences pages ([guigeekz](https://github.com/tootsuite/mastodon/pull/13068))
+- Add specific rate limits for posting, following and reporting ([Gargron](https://github.com/tootsuite/mastodon/pull/13172), [Gargron](https://github.com/tootsuite/mastodon/pull/13390))
+  - 300 posts every 3 hours
+  - 400 follows or follow requests every 24 hours
+  - 400 reports every 24 hours
+- Add federation support for the "hide network" preference ([ThibG](https://github.com/tootsuite/mastodon/pull/11673))
+- Add `--skip-media-remove` option to `tootctl statuses remove` ([tateisu](https://github.com/tootsuite/mastodon/pull/13080))
+
+### Changed
+
+- **Change design of polls in web UI** ([Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/13257), [ThibG](https://github.com/tootsuite/mastodon/pull/13313))
+- Change status click areas in web UI to be bigger ([ariasuni](https://github.com/tootsuite/mastodon/pull/13327))
+- **Change `tootctl media remove-orphans` to work for all classes** ([Gargron](https://github.com/tootsuite/mastodon/pull/13316))
+- **Change local media attachments to perform heavy processing asynchronously** ([Gargron](https://github.com/tootsuite/mastodon/pull/13210))
+- Change video uploads to always be converted to H264/MP4 ([Gargron](https://github.com/tootsuite/mastodon/pull/13220), [ThibG](https://github.com/tootsuite/mastodon/pull/13239), [ThibG](https://github.com/tootsuite/mastodon/pull/13242))
+- Change video uploads to enforce certain limits ([Gargron](https://github.com/tootsuite/mastodon/pull/13218))
+  - Dimensions smaller than 1920x1200px
+  - Frame rate at most 60fps
+- Change the tooltip "Toggle visibility" to "Hide media" in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13199))
+- Change description of privacy levels to be more intuitive in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13197))
+- Change GIF label to be displayed even when autoplay is enabled in web UI ([koyuawsmbrtn](https://github.com/tootsuite/mastodon/pull/13209))
+- Change the string "Hide everything from …" to "Block domain …" in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13178), [mayaeh](https://github.com/tootsuite/mastodon/pull/13221))
+- Change wording of media display preferences to be more intuitive ([ariasuni](https://github.com/tootsuite/mastodon/pull/13198))
+
+### Deprecated
+
+- `POST /api/v1/media` → `POST /api/v2/media` ([Gargron](https://github.com/tootsuite/mastodon/pull/13210))
+
+### Fixed
+
+- Fix `tootctl media remove-orphans` ignoring `PAPERCLIP_ROOT_PATH` ([Gargron](https://github.com/tootsuite/mastodon/pull/13375))
+- Fix returning results when searching for URL with non-zero offset ([Gargron](https://github.com/tootsuite/mastodon/pull/13377))
+- Fix pinning a column in web UI sometimes redirecting out of web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/13376))
+- Fix background jobs not using locks like they are supposed to ([Gargron](https://github.com/tootsuite/mastodon/pull/13361))
+- Fix content warning being unnecessarily cleared when hiding content warning input in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13348))
+- Fix "Show more" not switching to "Show less" on public pages ([ThibG](https://github.com/tootsuite/mastodon/pull/13174))
+- Fix import overwrite option not being selectable ([noellabo](https://github.com/tootsuite/mastodon/pull/13347))
+- Fix wrong color for ellipsis in boost confirmation dialog in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13355))
+- Fix unnecessary unfollowing when importing follows with overwrite option ([noellabo](https://github.com/tootsuite/mastodon/pull/13350))
+- Fix 404 and 410 API errors being silently discarded in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13279))
+- Fix OCR not working on Safari because of unsupported worker-src CSP ([ThibG](https://github.com/tootsuite/mastodon/pull/13323))
+- Fix media not being marked sensitive when a content warning is set with no text ([ThibG](https://github.com/tootsuite/mastodon/pull/13277))
+- Fix crash after deleting announcements in web UI ([codesections](https://github.com/tootsuite/mastodon/pull/13283), [ThibG](https://github.com/tootsuite/mastodon/pull/13312))
+- Fix bookmarks not being searchable ([Kjwon15](https://github.com/tootsuite/mastodon/pull/13271), [noellabo](https://github.com/tootsuite/mastodon/pull/13293))
+- Fix reported accounts not being whitelisted from further spam checks when resolving a spam check report ([ThibG](https://github.com/tootsuite/mastodon/pull/13289))
+- Fix web UI crash in single-column mode on prehistoric browsers ([ThibG](https://github.com/tootsuite/mastodon/pull/13267))
+- Fix some timeouts when searching for URLs ([ThibG](https://github.com/tootsuite/mastodon/pull/13253))
+- Fix detailed view of direct messages displaying a 0 boost count in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13244))
+- Fix regression in “Edit media” modal in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13243))
+- Fix public posts from silenced accounts not being changed to unlisted visibility ([ThibG](https://github.com/tootsuite/mastodon/pull/13096))
+- Fix error when searching for URLs that contain the mention syntax ([ThibG](https://github.com/tootsuite/mastodon/pull/13151))
+- Fix text area above/right of emoji picker being accidentally clickable in web UI ([ariasuni](https://github.com/tootsuite/mastodon/pull/13148))
+- Fix too large announcements not being scrollable in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13211))
+- Fix `tootctl media remove-orphans` crashing when encountering invalid media ([ThibG](https://github.com/tootsuite/mastodon/pull/13170))
+- Fix installation failing when Redis password contains special characters ([ThibG](https://github.com/tootsuite/mastodon/pull/13156))
+- Fix announcements with fully-qualified mentions to local users crashing web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13164))
+
+### Security
+
+- Fix re-sending of e-mail confirmation not being rate limited ([Gargron](https://github.com/tootsuite/mastodon/pull/13360))
+
 ## [v3.1.2] - 2020-02-27
 ### Added
 
diff --git a/Dockerfile b/Dockerfile
index eeaad758f..3d111baff 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,7 +4,7 @@ FROM ubuntu:18.04 as build-dep
 SHELL ["bash", "-c"]
 
 # Install Node v12 (LTS)
-ENV NODE_VER="12.14.0"  
+ENV NODE_VER="12.16.1"
 RUN	ARCH= && \
     dpkgArch="$(dpkg --print-architecture)" && \
   case "${dpkgArch##*-}" in \
@@ -38,8 +38,8 @@ RUN apt update && \
 	make -j$(nproc) > /dev/null && \
 	make install_bin install_include install_lib
 
-# Install ruby
-ENV RUBY_VER="2.6.5"
+# Install Ruby
+ENV RUBY_VER="2.6.6"
 ENV CPPFLAGS="-I/opt/jemalloc/include"
 ENV LDFLAGS="-L/opt/jemalloc/lib/"
 RUN apt update && \
diff --git a/Gemfile b/Gemfile
index 852def278..d77be40c0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,12 +1,12 @@
 # frozen_string_literal: true
 
 source 'https://rubygems.org'
-ruby '>= 2.4.0', '< 3.0.0'
+ruby '>= 2.5.0', '< 3.0.0'
 
 gem 'pkg-config', '~> 1.4'
 
 gem 'puma', '~> 4.3'
-gem 'rails', '~> 5.2.4'
+gem 'rails', '~> 5.2.4.2'
 gem 'sprockets', '~> 3.7.2'
 gem 'thor', '~> 0.20'
 gem 'rack', '~> 2.2.2'
@@ -20,7 +20,7 @@ gem 'makara', '~> 0.4'
 gem 'pghero', '~> 2.4'
 gem 'dotenv-rails', '~> 2.7'
 
-gem 'aws-sdk-s3', '~> 1.60', require: false
+gem 'aws-sdk-s3', '~> 1.61', require: false
 gem 'fog-core', '<= 2.1.0'
 gem 'fog-openstack', '~> 0.3', require: false
 gem 'paperclip', '~> 6.0'
@@ -35,7 +35,7 @@ gem 'browser'
 gem 'charlock_holmes', '~> 0.7.7'
 gem 'iso-639'
 gem 'chewy', '~> 5.1'
-gem 'cld3', '~> 3.2.6'
+gem 'cld3', '~> 3.3.0'
 gem 'devise', '~> 4.7'
 gem 'devise-two-factor', '~> 3.1'
 
@@ -48,8 +48,8 @@ gem 'omniauth-cas', '~> 1.1'
 gem 'omniauth-saml', '~> 1.10'
 gem 'omniauth', '~> 1.9'
 
-gem 'discard', '~> 1.1'
-gem 'doorkeeper', '~> 5.2'
+gem 'discard', '~> 1.2'
+gem 'doorkeeper', '~> 5.3'
 gem 'fast_blank', '~> 1.0'
 gem 'fastimage'
 gem 'goldfinger', '~> 2.1'
@@ -69,7 +69,7 @@ gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b
 gem 'nokogiri', '~> 1.10'
 gem 'nsa', '~> 0.2'
 gem 'oj', '~> 3.10'
-gem 'ox', '~> 2.12'
+gem 'ox', '~> 2.13'
 gem 'parslet'
 gem 'parallel', '~> 1.19'
 gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
@@ -84,7 +84,7 @@ gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
 gem 'rqrcode', '~> 1.1'
 gem 'ruby-progressbar', '~> 1.10'
 gem 'sanitize', '~> 5.1'
-gem 'sidekiq', '~> 5.2'
+gem 'sidekiq', '~> 6.0'
 gem 'sidekiq-scheduler', '~> 3.0'
 gem 'sidekiq-unique-jobs', '~> 6.0'
 gem 'sidekiq-bulk', '~>0.2.0'
@@ -92,9 +92,9 @@ gem 'simple-navigation', '~> 4.1'
 gem 'simple_form', '~> 5.0'
 gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
 gem 'stoplight', '~> 2.2.0'
-gem 'strong_migrations', '~> 0.5'
+gem 'strong_migrations', '~> 0.6'
 gem 'tty-command', '~> 0.9', require: false
-gem 'tty-prompt', '~> 0.20', require: false
+gem 'tty-prompt', '~> 0.21', require: false
 gem 'twitter-text', '~> 1.14'
 gem 'tzinfo-data', '~> 1.2019'
 gem 'webpacker', '~> 4.2'
@@ -112,7 +112,7 @@ group :development, :test do
   gem 'i18n-tasks', '~> 0.9', require: false
   gem 'pry-byebug', '~> 3.8'
   gem 'pry-rails', '~> 0.3'
-  gem 'rspec-rails', '~> 3.9'
+  gem 'rspec-rails', '~> 4.0'
 end
 
 group :production, :test do
@@ -122,19 +122,19 @@ end
 group :test do
   gem 'capybara', '~> 3.31'
   gem 'climate_control', '~> 0.2'
-  gem 'faker', '~> 2.10'
+  gem 'faker', '~> 2.11'
   gem 'microformats', '~> 4.2'
   gem 'rails-controller-testing', '~> 1.0'
   gem 'rspec-sidekiq', '~> 3.0'
   gem 'simplecov', '~> 0.18', require: false
   gem 'webmock', '~> 3.8'
-  gem 'parallel_tests', '~> 2.30'
+  gem 'parallel_tests', '~> 2.32'
 end
 
 group :development do
   gem 'active_record_query_trace', '~> 1.7'
   gem 'annotate', '~> 3.0'
-  gem 'better_errors', '~> 2.5'
+  gem 'better_errors', '~> 2.6'
   gem 'binding_of_caller', '~> 0.7'
   gem 'bullet', '~> 6.1'
   gem 'letter_opener', '~> 1.7'
@@ -142,10 +142,10 @@ group :development do
   gem 'memory_profiler'
   gem 'rubocop', '~> 0.79', require: false
   gem 'rubocop-rails', '~> 2.4', require: false
-  gem 'brakeman', '~> 4.7', require: false
+  gem 'brakeman', '~> 4.8', require: false
   gem 'bundler-audit', '~> 0.6', require: false
 
-  gem 'capistrano', '~> 3.11'
+  gem 'capistrano', '~> 3.12'
   gem 'capistrano-rails', '~> 1.4'
   gem 'capistrano-rbenv', '~> 2.1'
   gem 'capistrano-yarn', '~> 2.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 16871e8e3..d1f6a6214 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -31,25 +31,25 @@ GIT
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (5.2.4.1)
-      actionpack (= 5.2.4.1)
+    actioncable (5.2.4.2)
+      actionpack (= 5.2.4.2)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailer (5.2.4.1)
-      actionpack (= 5.2.4.1)
-      actionview (= 5.2.4.1)
-      activejob (= 5.2.4.1)
+    actionmailer (5.2.4.2)
+      actionpack (= 5.2.4.2)
+      actionview (= 5.2.4.2)
+      activejob (= 5.2.4.2)
       mail (~> 2.5, >= 2.5.4)
       rails-dom-testing (~> 2.0)
-    actionpack (5.2.4.1)
-      actionview (= 5.2.4.1)
-      activesupport (= 5.2.4.1)
+    actionpack (5.2.4.2)
+      actionview (= 5.2.4.2)
+      activesupport (= 5.2.4.2)
       rack (~> 2.0, >= 2.0.8)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.2)
-    actionview (5.2.4.1)
-      activesupport (= 5.2.4.1)
+    actionview (5.2.4.2)
+      activesupport (= 5.2.4.2)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
@@ -60,20 +60,20 @@ GEM
       case_transform (>= 0.2)
       jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
     active_record_query_trace (1.7)
-    activejob (5.2.4.1)
-      activesupport (= 5.2.4.1)
+    activejob (5.2.4.2)
+      activesupport (= 5.2.4.2)
       globalid (>= 0.3.6)
-    activemodel (5.2.4.1)
-      activesupport (= 5.2.4.1)
-    activerecord (5.2.4.1)
-      activemodel (= 5.2.4.1)
-      activesupport (= 5.2.4.1)
+    activemodel (5.2.4.2)
+      activesupport (= 5.2.4.2)
+    activerecord (5.2.4.2)
+      activemodel (= 5.2.4.2)
+      activesupport (= 5.2.4.2)
       arel (>= 9.0)
-    activestorage (5.2.4.1)
-      actionpack (= 5.2.4.1)
-      activerecord (= 5.2.4.1)
+    activestorage (5.2.4.2)
+      actionpack (= 5.2.4.2)
+      activerecord (= 5.2.4.2)
       marcel (~> 0.3.1)
-    activesupport (5.2.4.1)
+    activesupport (5.2.4.2)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 0.7, < 2)
       minitest (~> 5.1)
@@ -92,23 +92,23 @@ GEM
     av (0.9.0)
       cocaine (~> 0.5.3)
     aws-eventstream (1.0.3)
-    aws-partitions (1.261.0)
-    aws-sdk-core (3.86.0)
+    aws-partitions (1.286.0)
+    aws-sdk-core (3.92.0)
       aws-eventstream (~> 1.0, >= 1.0.2)
       aws-partitions (~> 1, >= 1.239.0)
       aws-sigv4 (~> 1.1)
       jmespath (~> 1.0)
-    aws-sdk-kms (1.27.0)
+    aws-sdk-kms (1.30.0)
       aws-sdk-core (~> 3, >= 3.71.0)
       aws-sigv4 (~> 1.1)
-    aws-sdk-s3 (1.60.1)
+    aws-sdk-s3 (1.61.1)
       aws-sdk-core (~> 3, >= 3.83.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.1)
-    aws-sigv4 (1.1.0)
+    aws-sigv4 (1.1.1)
       aws-eventstream (~> 1.0, >= 1.0.2)
     bcrypt (3.1.12)
-    better_errors (2.5.1)
+    better_errors (2.6.0)
       coderay (>= 1.0.0)
       erubi (>= 1.0.0)
       rack (>= 0.9.0)
@@ -116,10 +116,10 @@ GEM
       debug_inspector (>= 0.0.1)
     blurhash (0.1.4)
       ffi (~> 1.10.0)
-    bootsnap (1.4.5)
+    bootsnap (1.4.6)
       msgpack (~> 1.0)
-    brakeman (4.7.2)
-    browser (3.0.3)
+    brakeman (4.8.0)
+    browser (4.0.0)
     builder (3.2.4)
     bullet (6.1.0)
       activesupport (>= 3.0.0)
@@ -128,7 +128,7 @@ GEM
       bundler (>= 1.2.0, < 3)
       thor (~> 0.18)
     byebug (11.1.1)
-    capistrano (3.11.2)
+    capistrano (3.12.1)
       airbrussh (>= 1.0.0)
       i18n
       rake (>= 10.0.0)
@@ -160,13 +160,13 @@ GEM
       elasticsearch (>= 2.0.0)
       elasticsearch-dsl
     chunky_png (1.3.11)
-    cld3 (3.2.6)
+    cld3 (3.3.0)
       ffi (>= 1.1.0, < 1.12.0)
     climate_control (0.2.0)
     cocaine (0.5.8)
       climate_control (>= 0.0.3, < 1.0)
     coderay (1.1.2)
-    concurrent-ruby (1.1.5)
+    concurrent-ruby (1.1.6)
     connection_pool (2.2.2)
     crack (0.4.3)
       safe_yaml (~> 1.0.0)
@@ -190,12 +190,12 @@ GEM
       devise (>= 4.0.0)
       rpam2 (~> 4.0)
     diff-lcs (1.3)
-    discard (1.1.0)
+    discard (1.2.0)
       activerecord (>= 4.2, < 7)
     docile (1.3.2)
     domain_name (0.5.20190701)
       unf (>= 0.0.5, < 1.0.0)
-    doorkeeper (5.2.3)
+    doorkeeper (5.3.1)
       railties (>= 5)
     dotenv (2.7.5)
     dotenv-rails (2.7.5)
@@ -214,11 +214,11 @@ GEM
     encryptor (3.0.0)
     equatable (0.6.1)
     erubi (1.9.0)
-    et-orbi (1.1.6)
+    et-orbi (1.2.3)
       tzinfo
     excon (0.71.0)
     fabrication (2.21.0)
-    faker (2.10.1)
+    faker (2.11.0)
       i18n (>= 1.6, < 2)
     faraday (0.17.3)
       multipart-post (>= 1.2, < 3)
@@ -241,8 +241,8 @@ GEM
       fog-json (>= 1.0)
       ipaddress (>= 0.8)
     formatador (0.2.5)
-    fugit (1.1.6)
-      et-orbi (~> 1.1, >= 1.1.6)
+    fugit (1.3.3)
+      et-orbi (~> 1.1, >= 1.1.8)
       raabro (~> 1.1)
     fuubar (2.5.0)
       rspec-core (~> 3.0)
@@ -265,8 +265,8 @@ GEM
       railties (>= 4.0.1)
     hamster (3.0.0)
       concurrent-ruby (~> 1.0)
-    hashdiff (1.0.0)
-    hashie (3.6.0)
+    hashdiff (1.0.1)
+    hashie (4.1.0)
     highline (2.0.3)
     hiredis (0.6.3)
     hkdf (0.3.0)
@@ -287,7 +287,7 @@ GEM
       rainbow (>= 2.0.0)
     i18n (1.8.2)
       concurrent-ruby (~> 1.0)
-    i18n-tasks (0.9.30)
+    i18n-tasks (0.9.31)
       activesupport (>= 4.0.2)
       ast (>= 2.1.0)
       erubi
@@ -299,19 +299,19 @@ GEM
       terminal-table (>= 1.5.1)
     idn-ruby (0.1.0)
     ipaddress (0.8.3)
-    iso-639 (0.2.8)
+    iso-639 (0.3.5)
     jaro_winkler (1.5.4)
     jmespath (1.4.0)
     json (2.3.0)
     json-canonicalization (0.2.0)
-    json-ld (3.1.0)
+    json-ld (3.1.2)
       htmlentities (~> 4.3)
-      json-canonicalization (~> 0.1)
+      json-canonicalization (~> 0.2)
       link_header (~> 0.0, >= 0.0.8)
       multi_json (~> 1.14)
       rack (~> 2.0)
       rdf (~> 3.1)
-    json-ld-preloaded (3.1.0)
+    json-ld-preloaded (3.1.2)
       json-ld (~> 3.1)
       rdf (~> 3.1)
     jsonapi-renderer (0.2.2)
@@ -361,11 +361,11 @@ GEM
     mime-types (3.3.1)
       mime-types-data (~> 3.2015)
     mime-types-data (3.2019.1009)
-    mimemagic (0.3.3)
+    mimemagic (0.3.4)
     mini_mime (1.0.2)
     mini_portile2 (2.4.0)
     minitest (5.14.0)
-    msgpack (1.3.1)
+    msgpack (1.3.3)
     multi_json (1.14.1)
     multipart-post (2.1.1)
     necromancer (0.5.1)
@@ -374,7 +374,7 @@ GEM
       net-ssh (>= 2.6.5, < 6.0.0)
     net-ssh (5.2.0)
     nio4r (2.5.2)
-    nokogiri (1.10.8)
+    nokogiri (1.10.9)
       mini_portile2 (~> 2.4.0)
     nokogumbo (2.0.1)
       nokogiri (~> 1.8, >= 1.8.4)
@@ -383,9 +383,9 @@ GEM
       concurrent-ruby (~> 1.0, >= 1.0.2)
       sidekiq (>= 3.5)
       statsd-ruby (~> 1.4, >= 1.4.0)
-    oj (3.10.1)
-    omniauth (1.9.0)
-      hashie (>= 3.4.6, < 3.7.0)
+    oj (3.10.5)
+    omniauth (1.9.1)
+      hashie (>= 3.4.6)
       rack (>= 1.6.2, < 3)
     omniauth-cas (1.1.1)
       addressable (~> 2.3)
@@ -395,7 +395,7 @@ GEM
       omniauth (~> 1.3, >= 1.3.2)
       ruby-saml (~> 1.7)
     orm_adapter (0.5.0)
-    ox (2.12.1)
+    ox (2.13.2)
     paperclip (6.0.0)
       activemodel (>= 4.2.0)
       activesupport (>= 4.2.0)
@@ -406,15 +406,15 @@ GEM
       av (~> 0.9.0)
       paperclip (>= 2.5.2)
     parallel (1.19.1)
-    parallel_tests (2.30.1)
+    parallel_tests (2.32.0)
       parallel
-    parser (2.7.0.2)
+    parser (2.7.0.5)
       ast (~> 2.4.0)
     parslet (1.8.2)
     pastel (0.7.3)
       equatable (~> 0.6)
       tty-color (~> 0.5)
-    pg (1.2.2)
+    pg (1.2.3)
     pghero (2.4.1)
       activerecord (>= 5)
     pkg-config (1.4.1)
@@ -435,7 +435,7 @@ GEM
     pry-rails (0.3.9)
       pry (>= 0.10.4)
     public_suffix (4.0.3)
-    puma (4.3.2)
+    puma (4.3.3)
       nio4r (~> 2.0)
     pundit (2.1.0)
       activesupport (>= 3.0.0)
@@ -445,24 +445,24 @@ GEM
       rack (>= 1.0, < 3)
     rack-cors (1.1.1)
       rack (>= 2.0.0)
-    rack-protection (2.0.7)
+    rack-protection (2.0.8.1)
       rack
     rack-proxy (0.6.5)
       rack
     rack-test (1.1.0)
       rack (>= 1.0, < 3)
-    rails (5.2.4.1)
-      actioncable (= 5.2.4.1)
-      actionmailer (= 5.2.4.1)
-      actionpack (= 5.2.4.1)
-      actionview (= 5.2.4.1)
-      activejob (= 5.2.4.1)
-      activemodel (= 5.2.4.1)
-      activerecord (= 5.2.4.1)
-      activestorage (= 5.2.4.1)
-      activesupport (= 5.2.4.1)
+    rails (5.2.4.2)
+      actioncable (= 5.2.4.2)
+      actionmailer (= 5.2.4.2)
+      actionpack (= 5.2.4.2)
+      actionview (= 5.2.4.2)
+      activejob (= 5.2.4.2)
+      activemodel (= 5.2.4.2)
+      activerecord (= 5.2.4.2)
+      activestorage (= 5.2.4.2)
+      activesupport (= 5.2.4.2)
       bundler (>= 1.3.0)
-      railties (= 5.2.4.1)
+      railties (= 5.2.4.2)
       sprockets-rails (>= 2.0.0)
     rails-controller-testing (1.0.4)
       actionpack (>= 5.0.1.x)
@@ -478,9 +478,9 @@ GEM
       railties (>= 5.0, < 6)
     rails-settings-cached (0.6.6)
       rails (>= 4.2.0)
-    railties (5.2.4.1)
-      actionpack (= 5.2.4.1)
-      activesupport (= 5.2.4.1)
+    railties (5.2.4.2)
+      actionpack (= 5.2.4.2)
+      activesupport (= 5.2.4.2)
       method_source
       rake (>= 0.8.7)
       thor (>= 0.19.0, < 2.0)
@@ -523,26 +523,26 @@ GEM
       chunky_png (~> 1.0)
       rqrcode_core (~> 0.1)
     rqrcode_core (0.1.1)
-    rspec-core (3.9.0)
-      rspec-support (~> 3.9.0)
-    rspec-expectations (3.9.0)
+    rspec-core (3.9.1)
+      rspec-support (~> 3.9.1)
+    rspec-expectations (3.9.1)
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.9.0)
-    rspec-mocks (3.9.0)
+    rspec-mocks (3.9.1)
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.9.0)
-    rspec-rails (3.9.0)
-      actionpack (>= 3.0)
-      activesupport (>= 3.0)
-      railties (>= 3.0)
-      rspec-core (~> 3.9.0)
-      rspec-expectations (~> 3.9.0)
-      rspec-mocks (~> 3.9.0)
-      rspec-support (~> 3.9.0)
+    rspec-rails (4.0.0)
+      actionpack (>= 4.2)
+      activesupport (>= 4.2)
+      railties (>= 4.2)
+      rspec-core (~> 3.9)
+      rspec-expectations (~> 3.9)
+      rspec-mocks (~> 3.9)
+      rspec-support (~> 3.9)
     rspec-sidekiq (3.0.3)
       rspec-core (~> 3.0, >= 3.0.0)
       sidekiq (>= 2.4.0)
-    rspec-support (3.9.0)
+    rspec-support (3.9.2)
     rubocop (0.79.0)
       jaro_winkler (~> 1.5.1)
       parallel (~> 1.10)
@@ -556,38 +556,40 @@ GEM
     ruby-progressbar (1.10.1)
     ruby-saml (1.9.0)
       nokogiri (>= 1.5.10)
-    rufus-scheduler (3.5.2)
-      fugit (~> 1.1, >= 1.1.5)
+    rufus-scheduler (3.6.0)
+      fugit (~> 1.1, >= 1.1.6)
     safe_yaml (1.0.5)
     sanitize (5.1.0)
       crass (~> 1.0.2)
       nokogiri (>= 1.8.0)
       nokogumbo (~> 2.0)
-    sidekiq (5.2.7)
-      connection_pool (~> 2.2, >= 2.2.2)
-      rack (>= 1.5.0)
-      rack-protection (>= 1.5.0)
-      redis (>= 3.3.5, < 5)
+    sidekiq (6.0.4)
+      connection_pool (>= 2.2.2)
+      rack (>= 2.0.0)
+      rack-protection (>= 2.0.0)
+      redis (>= 4.1.0)
     sidekiq-bulk (0.2.0)
       sidekiq
-    sidekiq-scheduler (3.0.0)
+    sidekiq-scheduler (3.0.1)
+      e2mmap
       redis (>= 3, < 5)
       rufus-scheduler (~> 3.2)
       sidekiq (>= 3)
+      thwait
       tilt (>= 1.4.0)
-    sidekiq-unique-jobs (6.0.18)
+    sidekiq-unique-jobs (6.0.21)
       concurrent-ruby (~> 1.0, >= 1.0.5)
       sidekiq (>= 4.0, < 7.0)
       thor (~> 0)
     simple-navigation (4.1.0)
       activesupport (>= 2.3.2)
-    simple_form (5.0.1)
+    simple_form (5.0.2)
       actionpack (>= 5.0)
       activemodel (>= 5.0)
-    simplecov (0.18.2)
+    simplecov (0.18.5)
       docile (~> 1.1)
       simplecov-html (~> 0.11)
-    simplecov-html (0.12.0)
+    simplecov-html (0.12.2)
     sprockets (3.7.2)
       concurrent-ruby (~> 1.0)
       rack (> 1, < 3)
@@ -595,7 +597,7 @@ GEM
       actionpack (>= 4.0)
       activesupport (>= 4.0)
       sprockets (>= 3.0.0)
-    sshkit (1.20.0)
+    sshkit (1.21.0)
       net-scp (>= 1.1.2)
       net-ssh (>= 2.8.0)
     stackprof (0.2.15)
@@ -603,7 +605,7 @@ GEM
     stoplight (2.2.0)
     streamio-ffmpeg (3.0.2)
       multi_json (~> 1.8)
-    strong_migrations (0.5.1)
+    strong_migrations (0.6.2)
       activerecord (>= 5)
     temple (0.8.2)
     terminal-table (1.8.0)
@@ -614,11 +616,11 @@ GEM
     thread_safe (0.3.6)
     thwait (0.1.0)
     tilt (2.0.10)
-    tty-color (0.5.0)
+    tty-color (0.5.1)
     tty-command (0.9.0)
       pastel (~> 0.7.0)
-    tty-cursor (0.7.0)
-    tty-prompt (0.20.0)
+    tty-cursor (0.7.1)
+    tty-prompt (0.21.0)
       necromancer (~> 0.5.0)
       pastel (~> 0.7.0)
       tty-reader (~> 0.7.0)
@@ -626,10 +628,10 @@ GEM
       tty-cursor (~> 0.7)
       tty-screen (~> 0.7)
       wisper (~> 2.0.0)
-    tty-screen (0.7.0)
+    tty-screen (0.7.1)
     twitter-text (1.14.7)
       unf (~> 0.1.0)
-    tzinfo (1.2.6)
+    tzinfo (1.2.7)
       thread_safe (~> 0.1)
     tzinfo-data (1.2019.3)
       tzinfo (>= 1.0.0)
@@ -640,7 +642,7 @@ GEM
     uniform_notifier (1.13.0)
     warden (1.2.8)
       rack (>= 2.0.6)
-    webmock (3.8.0)
+    webmock (3.8.3)
       addressable (>= 2.3.6)
       crack (>= 0.3.2)
       hashdiff (>= 0.4.0, < 2.0.0)
@@ -666,35 +668,35 @@ DEPENDENCIES
   active_record_query_trace (~> 1.7)
   addressable (~> 2.7)
   annotate (~> 3.0)
-  aws-sdk-s3 (~> 1.60)
-  better_errors (~> 2.5)
+  aws-sdk-s3 (~> 1.61)
+  better_errors (~> 2.6)
   binding_of_caller (~> 0.7)
   blurhash (~> 0.1)
   bootsnap (~> 1.4)
-  brakeman (~> 4.7)
+  brakeman (~> 4.8)
   browser
   bullet (~> 6.1)
   bundler-audit (~> 0.6)
-  capistrano (~> 3.11)
+  capistrano (~> 3.12)
   capistrano-rails (~> 1.4)
   capistrano-rbenv (~> 2.1)
   capistrano-yarn (~> 2.0)
   capybara (~> 3.31)
   charlock_holmes (~> 0.7.7)
   chewy (~> 5.1)
-  cld3 (~> 3.2.6)
+  cld3 (~> 3.3.0)
   climate_control (~> 0.2)
   concurrent-ruby
   connection_pool
   devise (~> 4.7)
   devise-two-factor (~> 3.1)
   devise_pam_authenticatable2 (~> 9.2)
-  discard (~> 1.1)
-  doorkeeper (~> 5.2)
+  discard (~> 1.2)
+  doorkeeper (~> 5.3)
   dotenv-rails (~> 2.7)
   e2mmap (~> 0.1.0)
   fabrication (~> 2.21)
-  faker (~> 2.10)
+  faker (~> 2.11)
   fast_blank (~> 1.0)
   fastimage
   fog-core (<= 2.1.0)
@@ -732,11 +734,11 @@ DEPENDENCIES
   omniauth (~> 1.9)
   omniauth-cas (~> 1.1)
   omniauth-saml (~> 1.10)
-  ox (~> 2.12)
+  ox (~> 2.13)
   paperclip (~> 6.0)
   paperclip-av-transcoder (~> 0.6)
   parallel (~> 1.19)
-  parallel_tests (~> 2.30)
+  parallel_tests (~> 2.32)
   parslet
   pg (~> 1.2)
   pghero (~> 2.4)
@@ -751,7 +753,7 @@ DEPENDENCIES
   rack (~> 2.2.2)
   rack-attack (~> 6.2)
   rack-cors (~> 1.1)
-  rails (~> 5.2.4)
+  rails (~> 5.2.4.2)
   rails-controller-testing (~> 1.0)
   rails-i18n (~> 5.1)
   rails-settings-cached (~> 0.6)
@@ -761,13 +763,13 @@ DEPENDENCIES
   redis-namespace (~> 1.7)
   redis-rails (~> 5.0)
   rqrcode (~> 1.1)
-  rspec-rails (~> 3.9)
+  rspec-rails (~> 4.0)
   rspec-sidekiq (~> 3.0)
   rubocop (~> 0.79)
   rubocop-rails (~> 2.4)
   ruby-progressbar (~> 1.10)
   sanitize (~> 5.1)
-  sidekiq (~> 5.2)
+  sidekiq (~> 6.0)
   sidekiq-bulk (~> 0.2.0)
   sidekiq-scheduler (~> 3.0)
   sidekiq-unique-jobs (~> 6.0)
@@ -779,11 +781,11 @@ DEPENDENCIES
   stackprof
   stoplight (~> 2.2.0)
   streamio-ffmpeg (~> 3.0)
-  strong_migrations (~> 0.5)
+  strong_migrations (~> 0.6)
   thor (~> 0.20)
   thwait (~> 0.1.0)
   tty-command (~> 0.9)
-  tty-prompt (~> 0.20)
+  tty-prompt (~> 0.21)
   twitter-text (~> 1.14)
   tzinfo-data (~> 1.2019)
   webmock (~> 3.8)
diff --git a/Vagrantfile b/Vagrantfile
index e00ed1ca6..143fa27fd 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -91,7 +91,7 @@ VAGRANTFILE_API_VERSION = "2"
 
 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 
-  config.vm.box = "ubuntu/xenial64"
+  config.vm.box = "ubuntu/bionic64"
 
   config.vm.provider :virtualbox do |vb|
     vb.name = "mastodon"
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
index f5735421c..bec9ed88b 100644
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -47,6 +47,11 @@ class StatusesIndex < Chewy::Index
       data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
     end
 
+    crutch :bookmarks do |collection|
+      data = ::Bookmark.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id)
+      data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
+    end
+
     root date_detection: false do
       field :id, type: 'long'
       field :account_id, type: 'long'
diff --git a/app/controllers/account_follow_controller.rb b/app/controllers/account_follow_controller.rb
index 185a355f8..33394074d 100644
--- a/app/controllers/account_follow_controller.rb
+++ b/app/controllers/account_follow_controller.rb
@@ -6,7 +6,7 @@ class AccountFollowController < ApplicationController
   before_action :authenticate_user!
 
   def create
-    FollowService.new.call(current_user.account, @account.acct)
+    FollowService.new.call(current_user.account, @account, with_rate_limit: true)
     redirect_to account_path(@account)
   end
 end
diff --git a/app/controllers/admin/action_logs_controller.rb b/app/controllers/admin/action_logs_controller.rb
index e273dfeae..2d77620df 100644
--- a/app/controllers/admin/action_logs_controller.rb
+++ b/app/controllers/admin/action_logs_controller.rb
@@ -2,8 +2,18 @@
 
 module Admin
   class ActionLogsController < BaseController
-    def index
-      @action_logs = Admin::ActionLog.page(params[:page])
+    before_action :set_action_logs
+
+    def index; end
+
+    private
+
+    def set_action_logs
+      @action_logs = Admin::ActionLogFilter.new(filter_params).results.page(params[:page])
+    end
+
+    def filter_params
+      params.slice(:page, *Admin::ActionLogFilter::KEYS).permit(:page, *Admin::ActionLogFilter::KEYS)
     end
   end
 end
diff --git a/app/controllers/admin/email_domain_blocks_controller.rb b/app/controllers/admin/email_domain_blocks_controller.rb
index 9fe85064e..c25919726 100644
--- a/app/controllers/admin/email_domain_blocks_controller.rb
+++ b/app/controllers/admin/email_domain_blocks_controller.rb
@@ -6,12 +6,12 @@ module Admin
 
     def index
       authorize :email_domain_block, :index?
-      @email_domain_blocks = EmailDomainBlock.page(params[:page])
+      @email_domain_blocks = EmailDomainBlock.where(parent_id: nil).includes(:children).order(id: :desc).page(params[:page])
     end
 
     def new
       authorize :email_domain_block, :create?
-      @email_domain_block = EmailDomainBlock.new
+      @email_domain_block = EmailDomainBlock.new(domain: params[:_domain])
     end
 
     def create
@@ -21,6 +21,28 @@ module Admin
 
       if @email_domain_block.save
         log_action :create, @email_domain_block
+
+        if @email_domain_block.with_dns_records?
+          hostnames = []
+          ips       = []
+
+          Resolv::DNS.open do |dns|
+            dns.timeouts = 1
+
+            hostnames = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
+
+            ([@email_domain_block.domain] + hostnames).uniq.each do |hostname|
+              ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s })
+              ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA).to_a.map { |e| e.address.to_s })
+            end
+          end
+
+          (hostnames + ips).each do |hostname|
+            another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: @email_domain_block)
+            log_action :create, another_email_domain_block if another_email_domain_block.save
+          end
+        end
+
         redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg')
       else
         render :new
@@ -41,7 +63,7 @@ module Admin
     end
 
     def resource_params
-      params.require(:email_domain_block).permit(:domain)
+      params.require(:email_domain_block).permit(:domain, :with_dns_records)
     end
   end
 end
diff --git a/app/controllers/admin/site_uploads_controller.rb b/app/controllers/admin/site_uploads_controller.rb
new file mode 100644
index 000000000..cacecedb0
--- /dev/null
+++ b/app/controllers/admin/site_uploads_controller.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Admin
+  class SiteUploadsController < BaseController
+    before_action :set_site_upload
+
+    def destroy
+      authorize :settings, :destroy?
+
+      @site_upload.destroy!
+
+      redirect_to edit_admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg')
+    end
+
+    private
+
+    def set_site_upload
+      @site_upload = SiteUpload.find(params[:id])
+    end
+  end
+end
diff --git a/app/controllers/admin/warning_presets_controller.rb b/app/controllers/admin/warning_presets_controller.rb
index 37be842c5..b376f8d9b 100644
--- a/app/controllers/admin/warning_presets_controller.rb
+++ b/app/controllers/admin/warning_presets_controller.rb
@@ -7,7 +7,7 @@ module Admin
     def index
       authorize :account_warning_preset, :index?
 
-      @warning_presets = AccountWarningPreset.all
+      @warning_presets = AccountWarningPreset.alphabetic
       @warning_preset  = AccountWarningPreset.new
     end
 
@@ -19,7 +19,7 @@ module Admin
       if @warning_preset.save
         redirect_to admin_warning_presets_path
       else
-        @warning_presets = AccountWarningPreset.all
+        @warning_presets = AccountWarningPreset.alphabetic
         render :index
       end
     end
@@ -52,7 +52,7 @@ module Admin
     end
 
     def warning_preset_params
-      params.require(:account_warning_preset).permit(:text)
+      params.require(:account_warning_preset).permit(:title, :text)
     end
   end
 end
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 68bf425f4..153ade253 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -44,6 +44,10 @@ class Api::BaseController < ApplicationController
     render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
   end
 
+  rescue_from Mastodon::RateLimitExceededError do
+    render json: { error: I18n.t('errors.429') }, status: 429
+  end
+
   rescue_from ActionController::ParameterMissing do |e|
     render json: { error: e.to_s }, status: 400
   end
diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index e360b8a92..1daa1ed0d 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
   before_action :set_account
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
@@ -27,7 +25,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
   end
 
   def hide_results?
-    (@account.user_hides_network? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
+    (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
   end
 
   def default_accounts
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index a405b365f..6fc23cf75 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
   before_action :set_account
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
@@ -27,7 +25,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
   end
 
   def hide_results?
-    (@account.user_hides_network? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
+    (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
   end
 
   def default_accounts
diff --git a/app/controllers/api/v1/accounts/identity_proofs_controller.rb b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
index bea51ae11..8dad6fee9 100644
--- a/app/controllers/api/v1/accounts/identity_proofs_controller.rb
+++ b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
@@ -4,8 +4,6 @@ class Api::V1::Accounts::IdentityProofsController < Api::BaseController
   before_action :require_user!
   before_action :set_account
 
-  respond_to :json
-
   def index
     @proofs = @account.identity_proofs.active
     render json: @proofs, each_serializer: REST::IdentityProofSerializer
diff --git a/app/controllers/api/v1/accounts/lists_controller.rb b/app/controllers/api/v1/accounts/lists_controller.rb
index 72392453c..ccb751f8f 100644
--- a/app/controllers/api/v1/accounts/lists_controller.rb
+++ b/app/controllers/api/v1/accounts/lists_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::Accounts::ListsController < Api::BaseController
   before_action :require_user!
   before_action :set_account
 
-  respond_to :json
-
   def index
     @lists = @account.lists.where(account: current_account)
     render json: @lists, each_serializer: REST::ListSerializer
diff --git a/app/controllers/api/v1/accounts/pins_controller.rb b/app/controllers/api/v1/accounts/pins_controller.rb
index 0a0239c42..3915b5669 100644
--- a/app/controllers/api/v1/accounts/pins_controller.rb
+++ b/app/controllers/api/v1/accounts/pins_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Accounts::PinsController < Api::BaseController
   before_action :require_user!
   before_action :set_account
 
-  respond_to :json
-
   def create
     AccountPin.create!(account: current_account, target_account: @account)
     render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
diff --git a/app/controllers/api/v1/accounts/relationships_controller.rb b/app/controllers/api/v1/accounts/relationships_controller.rb
index ab8a0461f..1d3992a28 100644
--- a/app/controllers/api/v1/accounts/relationships_controller.rb
+++ b/app/controllers/api/v1/accounts/relationships_controller.rb
@@ -4,8 +4,6 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
   before_action -> { doorkeeper_authorize! :read, :'read:follows' }
   before_action :require_user!
 
-  respond_to :json
-
   def index
     accounts = Account.where(id: account_ids).select('id')
     # .where doesn't guarantee that our results are in the same order
diff --git a/app/controllers/api/v1/accounts/search_controller.rb b/app/controllers/api/v1/accounts/search_controller.rb
index 4217b527a..3061fcb7e 100644
--- a/app/controllers/api/v1/accounts/search_controller.rb
+++ b/app/controllers/api/v1/accounts/search_controller.rb
@@ -4,8 +4,6 @@ class Api::V1::Accounts::SearchController < Api::BaseController
   before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
   before_action :require_user!
 
-  respond_to :json
-
   def show
     @accounts = account_search
     render json: @accounts, each_serializer: REST::AccountSerializer
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index 333db9618..114ee0a82 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -6,8 +6,6 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
 
   after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) }
 
-  respond_to :json
-
   def index
     @statuses = load_statuses
     render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
index d68d2715f..0080faf33 100644
--- a/app/controllers/api/v1/accounts_controller.rb
+++ b/app/controllers/api/v1/accounts_controller.rb
@@ -14,7 +14,7 @@ class Api::V1::AccountsController < Api::BaseController
 
   skip_before_action :require_authenticated_user!, only: :create
 
-  respond_to :json
+  override_rate_limit_headers :follow, family: :follows
 
   def show
     render json: @account, serializer: REST::AccountSerializer
@@ -31,7 +31,7 @@ class Api::V1::AccountsController < Api::BaseController
   end
 
   def follow
-    FollowService.new.call(current_user.account, @account, reblogs: truthy_param?(:reblogs))
+    FollowService.new.call(current_user.account, @account, reblogs: truthy_param?(:reblogs), with_rate_limit: true)
 
     options = @account.locked? || current_user.account.silenced? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } }
 
diff --git a/app/controllers/api/v1/apps/credentials_controller.rb b/app/controllers/api/v1/apps/credentials_controller.rb
index 8b63d0490..0475b2d4a 100644
--- a/app/controllers/api/v1/apps/credentials_controller.rb
+++ b/app/controllers/api/v1/apps/credentials_controller.rb
@@ -3,8 +3,6 @@
 class Api::V1::Apps::CredentialsController < Api::BaseController
   before_action -> { doorkeeper_authorize! :read }
 
-  respond_to :json
-
   def show
     render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer, fields: %i(name website vapid_key)
   end
diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb
index 4cff04cad..a2baeef90 100644
--- a/app/controllers/api/v1/blocks_controller.rb
+++ b/app/controllers/api/v1/blocks_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::BlocksController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
diff --git a/app/controllers/api/v1/bookmarks_controller.rb b/app/controllers/api/v1/bookmarks_controller.rb
index e1b244e76..c15212f0a 100644
--- a/app/controllers/api/v1/bookmarks_controller.rb
+++ b/app/controllers/api/v1/bookmarks_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::BookmarksController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @statuses = load_statuses
     render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
diff --git a/app/controllers/api/v1/conversations_controller.rb b/app/controllers/api/v1/conversations_controller.rb
index b19f27ebf..bc8013379 100644
--- a/app/controllers/api/v1/conversations_controller.rb
+++ b/app/controllers/api/v1/conversations_controller.rb
@@ -9,8 +9,6 @@ class Api::V1::ConversationsController < Api::BaseController
   before_action :set_conversation, except: :index
   after_action :insert_pagination_headers, only: :index
 
-  respond_to :json
-
   def index
     @conversations = paginated_conversations
     render json: @conversations, each_serializer: REST::ConversationSerializer
diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb
index 4e6d5d7c6..08b3474cc 100644
--- a/app/controllers/api/v1/custom_emojis_controller.rb
+++ b/app/controllers/api/v1/custom_emojis_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Api::V1::CustomEmojisController < Api::BaseController
-  respond_to :json
-
   skip_before_action :set_cache_headers
 
   def index
diff --git a/app/controllers/api/v1/domain_blocks_controller.rb b/app/controllers/api/v1/domain_blocks_controller.rb
index af9e7a20f..5bb02d834 100644
--- a/app/controllers/api/v1/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/domain_blocks_controller.rb
@@ -8,8 +8,6 @@ class Api::V1::DomainBlocksController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers, only: :show
 
-  respond_to :json
-
   def show
     @blocks = load_domain_blocks
     render json: @blocks.map(&:domain)
diff --git a/app/controllers/api/v1/endorsements_controller.rb b/app/controllers/api/v1/endorsements_controller.rb
index 2770c7aef..c87dbc4ce 100644
--- a/app/controllers/api/v1/endorsements_controller.rb
+++ b/app/controllers/api/v1/endorsements_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::EndorsementsController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb
index db827f9d4..3e242905d 100644
--- a/app/controllers/api/v1/favourites_controller.rb
+++ b/app/controllers/api/v1/favourites_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::FavouritesController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @statuses = load_statuses
     render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb
index fb27ef88b..8c1b81a0f 100644
--- a/app/controllers/api/v1/featured_tags/suggestions_controller.rb
+++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb
@@ -2,12 +2,9 @@
 
 class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
   before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
-
   before_action :require_user!
   before_action :set_most_used_tags, only: :index
 
-  respond_to :json
-
   def index
     render json: @most_used_tags, each_serializer: REST::TagSerializer
   end
diff --git a/app/controllers/api/v1/filters_controller.rb b/app/controllers/api/v1/filters_controller.rb
index e5ebaff4d..b0ace3af0 100644
--- a/app/controllers/api/v1/filters_controller.rb
+++ b/app/controllers/api/v1/filters_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::FiltersController < Api::BaseController
   before_action :set_filters, only: :index
   before_action :set_filter, only: [:show, :update, :destroy]
 
-  respond_to :json
-
   def index
     render json: @filters, each_serializer: REST::FilterSerializer
   end
diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb
index b30e8464c..4f6b4bcbf 100644
--- a/app/controllers/api/v1/instances/activity_controller.rb
+++ b/app/controllers/api/v1/instances/activity_controller.rb
@@ -6,8 +6,6 @@ class Api::V1::Instances::ActivityController < Api::BaseController
   skip_before_action :set_cache_headers
   skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
 
-  respond_to :json
-
   def show
     expires_in 1.day, public: true
     render_with_cache json: :activity, expires_in: 1.day
diff --git a/app/controllers/api/v1/instances/peers_controller.rb b/app/controllers/api/v1/instances/peers_controller.rb
index cc00d8a6b..9fa440935 100644
--- a/app/controllers/api/v1/instances/peers_controller.rb
+++ b/app/controllers/api/v1/instances/peers_controller.rb
@@ -6,8 +6,6 @@ class Api::V1::Instances::PeersController < Api::BaseController
   skip_before_action :set_cache_headers
   skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
 
-  respond_to :json
-
   def index
     expires_in 1.day, public: true
     render_with_cache(expires_in: 1.day) { Account.remote.domains }
diff --git a/app/controllers/api/v1/instances_controller.rb b/app/controllers/api/v1/instances_controller.rb
index c323b60b4..5b5058a7b 100644
--- a/app/controllers/api/v1/instances_controller.rb
+++ b/app/controllers/api/v1/instances_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Api::V1::InstancesController < Api::BaseController
-  respond_to :json
-
   skip_before_action :set_cache_headers
   skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
 
diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb
index 81825db15..0bb3d0d27 100644
--- a/app/controllers/api/v1/media_controller.rb
+++ b/app/controllers/api/v1/media_controller.rb
@@ -3,27 +3,42 @@
 class Api::V1::MediaController < Api::BaseController
   before_action -> { doorkeeper_authorize! :write, :'write:media' }
   before_action :require_user!
-
-  respond_to :json
+  before_action :set_media_attachment, except: [:create]
+  before_action :check_processing, except: [:create]
 
   def create
-    @media = current_account.media_attachments.create!(media_params)
-    render json: @media, serializer: REST::MediaAttachmentSerializer
+    @media_attachment = current_account.media_attachments.create!(media_attachment_params)
+    render json: @media_attachment, serializer: REST::MediaAttachmentSerializer
   rescue Paperclip::Errors::NotIdentifiedByImageMagickError
     render json: file_type_error, status: 422
   rescue Paperclip::Error
     render json: processing_error, status: 500
   end
 
+  def show
+    render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
+  end
+
   def update
-    @media = current_account.media_attachments.where(status_id: nil).find(params[:id])
-    @media.update!(media_params)
-    render json: @media, serializer: REST::MediaAttachmentSerializer
+    @media_attachment.update!(media_attachment_params)
+    render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
   end
 
   private
 
-  def media_params
+  def status_code_for_media_attachment
+    @media_attachment.not_processed? ? 206 : 200
+  end
+
+  def set_media_attachment
+    @media_attachment = current_account.media_attachments.unattached.find(params[:id])
+  end
+
+  def check_processing
+    render json: processing_error, status: 422 if @media_attachment.processing_failed?
+  end
+
+  def media_attachment_params
     params.permit(:file, :description, :focus)
   end
 
diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb
index 3b3a39943..5dc047b43 100644
--- a/app/controllers/api/v1/mutes_controller.rb
+++ b/app/controllers/api/v1/mutes_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::MutesController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @data = @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index c91753ae7..9dce9b807 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -6,8 +6,6 @@ class Api::V1::NotificationsController < Api::BaseController
   before_action :require_user!
   after_action :insert_pagination_headers, only: :index
 
-  respond_to :json
-
   DEFAULT_NOTIFICATIONS_LIMIT = 15
 
   def index
diff --git a/app/controllers/api/v1/polls/votes_controller.rb b/app/controllers/api/v1/polls/votes_controller.rb
index 3fa0b6a76..e1d26106a 100644
--- a/app/controllers/api/v1/polls/votes_controller.rb
+++ b/app/controllers/api/v1/polls/votes_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Polls::VotesController < Api::BaseController
   before_action :require_user!
   before_action :set_poll
 
-  respond_to :json
-
   def create
     VoteService.new.call(current_account, @poll, vote_params[:choices])
     render json: @poll, serializer: REST::PollSerializer
diff --git a/app/controllers/api/v1/polls_controller.rb b/app/controllers/api/v1/polls_controller.rb
index 031e6d42d..744baf7bb 100644
--- a/app/controllers/api/v1/polls_controller.rb
+++ b/app/controllers/api/v1/polls_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::PollsController < Api::BaseController
   before_action :set_poll
   before_action :refresh_poll
 
-  respond_to :json
-
   def show
     render json: @poll, serializer: REST::PollSerializer, include_results: true
   end
diff --git a/app/controllers/api/v1/preferences_controller.rb b/app/controllers/api/v1/preferences_controller.rb
index 077d39f5d..1640a8224 100644
--- a/app/controllers/api/v1/preferences_controller.rb
+++ b/app/controllers/api/v1/preferences_controller.rb
@@ -4,8 +4,6 @@ class Api::V1::PreferencesController < Api::BaseController
   before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
   before_action :require_user!
 
-  respond_to :json
-
   def index
     render json: current_account, serializer: REST::PreferencesSerializer
   end
diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb
index 1b0b4b05b..e10083d45 100644
--- a/app/controllers/api/v1/reports_controller.rb
+++ b/app/controllers/api/v1/reports_controller.rb
@@ -4,7 +4,7 @@ class Api::V1::ReportsController < Api::BaseController
   before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
   before_action :require_user!
 
-  respond_to :json
+  override_rate_limit_headers :create, family: :reports
 
   def create
     @report = ReportService.new.call(
diff --git a/app/controllers/api/v1/statuses/bookmarks_controller.rb b/app/controllers/api/v1/statuses/bookmarks_controller.rb
index a7f1eed00..3954af3c9 100644
--- a/app/controllers/api/v1/statuses/bookmarks_controller.rb
+++ b/app/controllers/api/v1/statuses/bookmarks_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Statuses::BookmarksController < Api::BaseController
   before_action :require_user!
   before_action :set_status
 
-  respond_to :json
-
   def create
     current_account.bookmarks.find_or_create_by!(account: current_account, status: @status)
     render json: @status, serializer: REST::StatusSerializer
diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
index 05f4acc33..8229786d6 100644
--- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
   before_action :set_status
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
diff --git a/app/controllers/api/v1/statuses/favourites_controller.rb b/app/controllers/api/v1/statuses/favourites_controller.rb
index f18ace996..7afa822ed 100644
--- a/app/controllers/api/v1/statuses/favourites_controller.rb
+++ b/app/controllers/api/v1/statuses/favourites_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController
   before_action :require_user!
   before_action :set_status
 
-  respond_to :json
-
   def create
     FavouriteService.new.call(current_account, @status)
     render json: @status, serializer: REST::StatusSerializer
diff --git a/app/controllers/api/v1/statuses/mutes_controller.rb b/app/controllers/api/v1/statuses/mutes_controller.rb
index b02469b4f..43c7a525a 100644
--- a/app/controllers/api/v1/statuses/mutes_controller.rb
+++ b/app/controllers/api/v1/statuses/mutes_controller.rb
@@ -8,8 +8,6 @@ class Api::V1::Statuses::MutesController < Api::BaseController
   before_action :set_status
   before_action :set_conversation
 
-  respond_to :json
-
   def create
     current_account.mute_conversation!(@conversation)
     @mutes_map = { @conversation.id => true }
diff --git a/app/controllers/api/v1/statuses/pins_controller.rb b/app/controllers/api/v1/statuses/pins_controller.rb
index 4118a8ce4..51b1621b6 100644
--- a/app/controllers/api/v1/statuses/pins_controller.rb
+++ b/app/controllers/api/v1/statuses/pins_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Statuses::PinsController < Api::BaseController
   before_action :require_user!
   before_action :set_status
 
-  respond_to :json
-
   def create
     StatusPin.create!(account: current_account, status: @status)
     distribute_add_activity!
diff --git a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
index fa60e7d84..6c9e49d90 100644
--- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
   before_action :set_status
   after_action :insert_pagination_headers
 
-  respond_to :json
-
   def index
     @accounts = load_accounts
     render json: @accounts, each_serializer: REST::AccountSerializer
diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb
index 67106ccbe..7fa774a4d 100644
--- a/app/controllers/api/v1/statuses/reblogs_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogs_controller.rb
@@ -7,10 +7,11 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
   before_action :require_user!
   before_action :set_reblog
 
-  respond_to :json
+  override_rate_limit_headers :create, family: :statuses
 
   def create
     @status = ReblogService.new.call(current_account, @reblog, reblog_params)
+
     render json: @status, serializer: REST::StatusSerializer
   end
 
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 486004f9c..29ae91762 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -7,8 +7,9 @@ class Api::V1::StatusesController < Api::BaseController
   before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only:   [:create, :destroy]
   before_action :require_user!, except:  [:show, :context]
   before_action :set_status, only:       [:show, :context]
+  before_action :set_thread, only:       [:create]
 
-  respond_to :json
+  override_rate_limit_headers :create, family: :statuses
 
   # This API was originally unlimited, pagination cannot be introduced without
   # breaking backwards-compatibility. Arbitrarily high number to cover most
@@ -36,7 +37,7 @@ class Api::V1::StatusesController < Api::BaseController
   def create
     @status = PostStatusService.new.call(current_user.account,
                                          text: status_params[:status],
-                                         thread: status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
+                                         thread: @thread,
                                          media_ids: status_params[:media_ids],
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
@@ -45,7 +46,8 @@ class Api::V1::StatusesController < Api::BaseController
                                          application: doorkeeper_token.application,
                                          poll: status_params[:poll],
                                          content_type: status_params[:content_type],
-                                         idempotency: request.headers['Idempotency-Key'])
+                                         idempotency: request.headers['Idempotency-Key'],
+                                         with_rate_limit: true)
 
     render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
   end
@@ -69,6 +71,12 @@ class Api::V1::StatusesController < Api::BaseController
     raise ActiveRecord::RecordNotFound
   end
 
+  def set_thread
+    @thread = status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id])
+  rescue ActiveRecord::RecordNotFound
+    render json: { error: I18n.t('statuses.errors.in_reply_not_found') }, status: 404
+  end
+
   def status_params
     params.permit(
       :status,
diff --git a/app/controllers/api/v1/streaming_controller.rb b/app/controllers/api/v1/streaming_controller.rb
index ebb17608c..7cd60615a 100644
--- a/app/controllers/api/v1/streaming_controller.rb
+++ b/app/controllers/api/v1/streaming_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Api::V1::StreamingController < Api::BaseController
-  respond_to :json
-
   def index
     if Rails.configuration.x.streaming_api_base_url != request.host
       redirect_to streaming_api_url, status: 301
diff --git a/app/controllers/api/v1/suggestions_controller.rb b/app/controllers/api/v1/suggestions_controller.rb
index 9da2b60ae..52054160d 100644
--- a/app/controllers/api/v1/suggestions_controller.rb
+++ b/app/controllers/api/v1/suggestions_controller.rb
@@ -7,8 +7,6 @@ class Api::V1::SuggestionsController < Api::BaseController
   before_action :require_user!
   before_action :set_accounts
 
-  respond_to :json
-
   def index
     render json: @accounts, each_serializer: REST::AccountSerializer
   end
diff --git a/app/controllers/api/v1/timelines/home_controller.rb b/app/controllers/api/v1/timelines/home_controller.rb
index ff5ede138..ae6dbcb8b 100644
--- a/app/controllers/api/v1/timelines/home_controller.rb
+++ b/app/controllers/api/v1/timelines/home_controller.rb
@@ -5,8 +5,6 @@ class Api::V1::Timelines::HomeController < Api::BaseController
   before_action :require_user!, only: [:show]
   after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
 
-  respond_to :json
-
   def show
     @statuses = load_statuses
 
diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb
index ccc10f966..581befef1 100644
--- a/app/controllers/api/v1/timelines/public_controller.rb
+++ b/app/controllers/api/v1/timelines/public_controller.rb
@@ -4,8 +4,6 @@ class Api::V1::Timelines::PublicController < Api::BaseController
   before_action :require_user!, only: [:show], if: :require_auth?
   after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
 
-  respond_to :json
-
   def show
     @statuses = load_statuses
     render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb
index 9adc4ad29..2d6ad5a80 100644
--- a/app/controllers/api/v1/timelines/tag_controller.rb
+++ b/app/controllers/api/v1/timelines/tag_controller.rb
@@ -4,8 +4,6 @@ class Api::V1::Timelines::TagController < Api::BaseController
   before_action :load_tag
   after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
 
-  respond_to :json
-
   def show
     @statuses = load_statuses
     render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
diff --git a/app/controllers/api/v1/trends_controller.rb b/app/controllers/api/v1/trends_controller.rb
index bcea9857e..c875e9041 100644
--- a/app/controllers/api/v1/trends_controller.rb
+++ b/app/controllers/api/v1/trends_controller.rb
@@ -3,8 +3,6 @@
 class Api::V1::TrendsController < Api::BaseController
   before_action :set_tags
 
-  respond_to :json
-
   def index
     render json: @tags, each_serializer: REST::TagSerializer
   end
diff --git a/app/controllers/api/v2/media_controller.rb b/app/controllers/api/v2/media_controller.rb
new file mode 100644
index 000000000..0c1baf01d
--- /dev/null
+++ b/app/controllers/api/v2/media_controller.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class Api::V2::MediaController < Api::V1::MediaController
+  def create
+    @media_attachment = current_account.media_attachments.create!({ delay_processing: true }.merge(media_attachment_params))
+    render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: 202
+  rescue Paperclip::Errors::NotIdentifiedByImageMagickError
+    render json: file_type_error, status: 422
+  rescue Paperclip::Error
+    render json: processing_error, status: 500
+  end
+end
diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb
index 76decdb25..ddcf92200 100644
--- a/app/controllers/api/v2/search_controller.rb
+++ b/app/controllers/api/v2/search_controller.rb
@@ -8,8 +8,6 @@ class Api::V2::SearchController < Api::BaseController
   before_action -> { doorkeeper_authorize! :read, :'read:search' }
   before_action :require_user!
 
-  respond_to :json
-
   def index
     @search = Search.new(search_results)
     render json: @search, serializer: REST::SearchSerializer
diff --git a/app/controllers/api/web/embeds_controller.rb b/app/controllers/api/web/embeds_controller.rb
index 4aa31695c..741ba910f 100644
--- a/app/controllers/api/web/embeds_controller.rb
+++ b/app/controllers/api/web/embeds_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Api::Web::EmbedsController < Api::Web::BaseController
-  respond_to :json
-
   before_action :require_user!
 
   def create
diff --git a/app/controllers/api/web/push_subscriptions_controller.rb b/app/controllers/api/web/push_subscriptions_controller.rb
index f388b17e5..7916b82fa 100644
--- a/app/controllers/api/web/push_subscriptions_controller.rb
+++ b/app/controllers/api/web/push_subscriptions_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Api::Web::PushSubscriptionsController < Api::Web::BaseController
-  respond_to :json
-
   before_action :require_user!
 
   def create
diff --git a/app/controllers/api/web/settings_controller.rb b/app/controllers/api/web/settings_controller.rb
index e3178bf48..3d65e46ed 100644
--- a/app/controllers/api/web/settings_controller.rb
+++ b/app/controllers/api/web/settings_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Api::Web::SettingsController < Api::Web::BaseController
-  respond_to :json
-
   before_action :require_user!
 
   def update
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index c882d40ab..63d9f91fb 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -30,6 +30,7 @@ class ApplicationController < ActionController::Base
   rescue_from Mastodon::NotPermittedError, with: :forbidden
   rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error
   rescue_from Mastodon::RaceConditionError, with: :service_unavailable
+  rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests
 
   before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
   before_action :require_functional!, if: :user_signed_in?
@@ -181,6 +182,10 @@ class ApplicationController < ActionController::Base
     respond_with_error(503)
   end
 
+  def too_many_requests
+    respond_with_error(429)
+  end
+
   def single_user_mode?
     @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.where('id > 0').exists?
   end
diff --git a/app/controllers/authorize_interactions_controller.rb b/app/controllers/authorize_interactions_controller.rb
index 20b3fa94b..f0bcac75b 100644
--- a/app/controllers/authorize_interactions_controller.rb
+++ b/app/controllers/authorize_interactions_controller.rb
@@ -21,7 +21,7 @@ class AuthorizeInteractionsController < ApplicationController
   end
 
   def create
-    if @resource.is_a?(Account) && FollowService.new.call(current_account, @resource)
+    if @resource.is_a?(Account) && FollowService.new.call(current_account, @resource, with_rate_limit: true)
       render :success
     else
       render :error
diff --git a/app/controllers/concerns/rate_limit_headers.rb b/app/controllers/concerns/rate_limit_headers.rb
index b79c558d8..86fe58a71 100644
--- a/app/controllers/concerns/rate_limit_headers.rb
+++ b/app/controllers/concerns/rate_limit_headers.rb
@@ -3,6 +3,20 @@
 module RateLimitHeaders
   extend ActiveSupport::Concern
 
+  class_methods do
+    def override_rate_limit_headers(method_name, options = {})
+      around_action(only: method_name, if: :current_account) do |_controller, block|
+        begin
+          block.call
+        ensure
+          rate_limiter = RateLimiter.new(current_account, options)
+          rate_limit_headers = rate_limiter.to_headers
+          response.headers.merge!(rate_limit_headers) unless response.headers['X-RateLimit-Remaining'].present? && rate_limit_headers['X-RateLimit-Remaining'].to_i > response.headers['X-RateLimit-Remaining'].to_i
+        end
+      end
+    end
+  end
+
   included do
     before_action :set_rate_limit_headers, if: :rate_limited_request?
   end
@@ -44,7 +58,7 @@ module RateLimitHeaders
   end
 
   def api_throttle_data
-    most_limited_type, = request.env['rack.attack.throttle_data'].min_by { |_, v| v[:limit] }
+    most_limited_type, = request.env['rack.attack.throttle_data'].min_by { |_, v| v[:limit] - v[:count] }
     request.env['rack.attack.throttle_data'][most_limited_type]
   end
 
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index a5dfffd6d..eb223c3f7 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -29,7 +29,8 @@ class FollowerAccountsController < ApplicationController
         render json: collection_presenter,
                serializer: ActivityPub::CollectionSerializer,
                adapter: ActivityPub::Adapter,
-               content_type: 'application/activity+json'
+               content_type: 'application/activity+json',
+               fields: restrict_fields_to
       end
     end
   end
@@ -72,4 +73,12 @@ class FollowerAccountsController < ApplicationController
       )
     end
   end
+
+  def restrict_fields_to
+    if page_requested? || !@account.user_hides_network?
+      # Return all fields
+    else
+      %i(id type totalItems)
+    end
+  end
 end
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index ff23d97f9..4ddccf607 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -29,7 +29,8 @@ class FollowingAccountsController < ApplicationController
         render json: collection_presenter,
                serializer: ActivityPub::CollectionSerializer,
                adapter: ActivityPub::Adapter,
-               content_type: 'application/activity+json'
+               content_type: 'application/activity+json',
+               fields: restrict_fields_to
       end
     end
   end
@@ -72,4 +73,12 @@ class FollowingAccountsController < ApplicationController
       )
     end
   end
+
+  def restrict_fields_to
+    if page_requested? || !@account.user_hides_network?
+      # Return all fields
+    else
+      %i(id type totalItems)
+    end
+  end
 end
diff --git a/app/controllers/settings/imports_controller.rb b/app/controllers/settings/imports_controller.rb
index 38f2e39c1..7b8c4ae23 100644
--- a/app/controllers/settings/imports_controller.rb
+++ b/app/controllers/settings/imports_controller.rb
@@ -29,6 +29,6 @@ class Settings::ImportsController < Settings::BaseController
   end
 
   def import_params
-    params.require(:import).permit(:data, :type)
+    params.require(:import).permit(:data, :type, :mode)
   end
 end
diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb
index 6bc75aa56..88d6e4580 100644
--- a/app/helpers/admin/action_logs_helper.rb
+++ b/app/helpers/admin/action_logs_helper.rb
@@ -9,79 +9,8 @@ module Admin::ActionLogsHelper
     end
   end
 
-  def relevant_log_changes(log)
-    if log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action)
-      log.recorded_changes.slice('domain')
-    elsif log.target_type == 'CustomEmoji' && log.action == :update
-      log.recorded_changes.slice('domain', 'visible_in_picker')
-    elsif log.target_type == 'User' && [:promote, :demote].include?(log.action)
-      log.recorded_changes.slice('moderator', 'admin')
-    elsif log.target_type == 'User' && [:change_email].include?(log.action)
-      log.recorded_changes.slice('email', 'unconfirmed_email')
-    elsif log.target_type == 'DomainBlock'
-      log.recorded_changes.slice('severity', 'reject_media')
-    elsif log.target_type == 'Status' && log.action == :update
-      log.recorded_changes.slice('sensitive')
-    elsif log.target_type == 'Announcement' && log.action == :update
-      log.recorded_changes.slice('text', 'starts_at', 'ends_at', 'all_day')
-    end
-  end
-
-  def log_extra_attributes(hash)
-    safe_join(hash.to_a.map { |key, value| safe_join([content_tag(:span, key, class: 'diff-key'), '=', log_change(value)]) }, ' ')
-  end
-
-  def log_change(val)
-    return content_tag(:span, val, class: 'diff-neutral') unless val.is_a?(Array)
-    safe_join([content_tag(:span, val.first, class: 'diff-old'), content_tag(:span, val.last, class: 'diff-new')], '→')
-  end
-
-  def icon_for_log(log)
-    case log.target_type
-    when 'Account', 'User'
-      'user'
-    when 'CustomEmoji'
-      'file'
-    when 'Report'
-      'flag'
-    when 'DomainBlock'
-      'lock'
-    when 'DomainAllow'
-      'plus-circle'
-    when 'EmailDomainBlock'
-      'envelope'
-    when 'Status'
-      'pencil'
-    when 'AccountWarning'
-      'warning'
-    when 'Announcement'
-      'bullhorn'
-    end
-  end
-
-  def class_for_log_icon(log)
-    case log.action
-    when :enable, :unsuspend, :unsilence, :confirm, :promote, :resolve
-      'positive'
-    when :create
-      opposite_verbs?(log) ? 'negative' : 'positive'
-    when :update, :reset_password, :disable_2fa, :memorialize, :change_email
-      'neutral'
-    when :demote, :silence, :disable, :suspend, :remove_avatar, :remove_header, :reopen
-      'negative'
-    when :destroy
-      opposite_verbs?(log) ? 'positive' : 'negative'
-    else
-      ''
-    end
-  end
-
   private
 
-  def opposite_verbs?(log)
-    %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type)
-  end
-
   def linkable_log_target(record)
     case record.class.name
     when 'Account'
@@ -99,7 +28,7 @@ module Admin::ActionLogsHelper
     when 'AccountWarning'
       link_to record.target_account.acct, admin_account_path(record.target_account_id)
     when 'Announcement'
-      link_to "##{record.id}", edit_admin_announcement_path(record.id)
+      link_to truncate(record.text), edit_admin_announcement_path(record.id)
     end
   end
 
@@ -118,7 +47,7 @@ module Admin::ActionLogsHelper
         I18n.t('admin.action_logs.deleted_status')
       end
     when 'Announcement'
-      "##{attributes['id']}"
+      truncate(attributes['text'])
     end
   end
 end
diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb
index 6ab92939d..ba0ca9638 100644
--- a/app/helpers/admin/filter_helper.rb
+++ b/app/helpers/admin/filter_helper.rb
@@ -10,6 +10,7 @@ module Admin::FilterHelper
     InviteFilter::KEYS,
     RelationshipFilter::KEYS,
     AnnouncementFilter::KEYS,
+    Admin::ActionLogFilter::KEYS,
   ].flatten.freeze
 
   def filter_link_to(text, link_to_params, link_class_params = link_to_params)
diff --git a/app/helpers/admin/settings_helper.rb b/app/helpers/admin/settings_helper.rb
new file mode 100644
index 000000000..baf14ab25
--- /dev/null
+++ b/app/helpers/admin/settings_helper.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Admin::SettingsHelper
+  def site_upload_delete_hint(hint, var)
+    upload = SiteUpload.find_by(var: var.to_s)
+    return hint unless upload
+
+    link = link_to t('admin.site_uploads.delete'), admin_site_upload_path(upload), data: { method: :delete }
+    safe_join([hint, link], '<br/>'.html_safe)
+  end
+end
diff --git a/app/javascript/core/admin.js b/app/javascript/core/admin.js
index e4d683dd0..f2334c254 100644
--- a/app/javascript/core/admin.js
+++ b/app/javascript/core/admin.js
@@ -1,6 +1,6 @@
 //  This file will be loaded on admin pages, regardless of theme.
 
-import { delegate } from 'rails-ujs';
+import { delegate } from '@rails/ujs';
 import ready from '../mastodon/ready';
 
 const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]';
@@ -32,6 +32,10 @@ delegate(document, '.media-spoiler-hide-button', 'click', () => {
   });
 });
 
+delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => {
+  target.form.submit();
+});
+
 const onDomainBlockSeverityChange = (target) => {
   const rejectMediaDiv   = document.querySelector('.input.with_label.domain_block_reject_media');
   const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports');
diff --git a/app/javascript/core/public.js b/app/javascript/core/public.js
index 0f4222139..39f198fe7 100644
--- a/app/javascript/core/public.js
+++ b/app/javascript/core/public.js
@@ -3,7 +3,7 @@
 import createHistory from 'history/createBrowserHistory';
 import ready from '../mastodon/ready';
 
-const { delegate } = require('rails-ujs');
+const { delegate } = require('@rails/ujs');
 const { length } = require('stringz');
 
 delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
@@ -14,20 +14,6 @@ delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
   return false;
 });
 
-delegate(document, '.status__content__spoiler-link', 'click', function() {
-  const contentEl = this.parentNode.parentNode.querySelector('.e-content');
-
-  if (contentEl.style.display === 'block') {
-    contentEl.style.display = 'none';
-    this.parentNode.style.marginBottom = 0;
-  } else {
-    contentEl.style.display = 'block';
-    this.parentNode.style.marginBottom = null;
-  }
-
-  return false;
-});
-
 delegate(document, '.modal-button', 'click', e => {
   e.preventDefault();
 
diff --git a/app/javascript/core/settings.js b/app/javascript/core/settings.js
index e0cb944e0..e02c91cc7 100644
--- a/app/javascript/core/settings.js
+++ b/app/javascript/core/settings.js
@@ -1,7 +1,7 @@
 //  This file will be loaded on settings pages, regardless of theme.
 
 import escapeTextContentForBrowser from 'escape-html';
-const { delegate } = require('rails-ujs');
+const { delegate } = require('@rails/ujs');
 import emojify from '../mastodon/features/emoji/emoji';
 
 delegate(document, '#account_display_name', 'input', ({ target }) => {
diff --git a/app/javascript/flavours/glitch/actions/accounts.js b/app/javascript/flavours/glitch/actions/accounts.js
index b659e4ff3..e1012a80b 100644
--- a/app/javascript/flavours/glitch/actions/accounts.js
+++ b/app/javascript/flavours/glitch/actions/accounts.js
@@ -370,6 +370,7 @@ export function fetchFollowersFail(id, error) {
     type: FOLLOWERS_FETCH_FAIL,
     id,
     error,
+    skipNotFound: true,
   };
 };
 
@@ -456,6 +457,7 @@ export function fetchFollowingFail(id, error) {
     type: FOLLOWING_FETCH_FAIL,
     id,
     error,
+    skipNotFound: true,
   };
 };
 
@@ -545,6 +547,7 @@ export function fetchRelationshipsFail(error) {
     type: RELATIONSHIPS_FETCH_FAIL,
     error,
     skipLoading: true,
+    skipNotFound: true,
   };
 };
 
diff --git a/app/javascript/flavours/glitch/actions/alerts.js b/app/javascript/flavours/glitch/actions/alerts.js
index cd36d8007..1670f9c10 100644
--- a/app/javascript/flavours/glitch/actions/alerts.js
+++ b/app/javascript/flavours/glitch/actions/alerts.js
@@ -34,11 +34,11 @@ export function showAlert(title = messages.unexpectedTitle, message = messages.u
   };
 };
 
-export function showAlertForError(error) {
+export function showAlertForError(error, skipNotFound = false) {
   if (error.response) {
     const { data, status, statusText, headers } = error.response;
 
-    if (status === 404 || status === 410) {
+    if (skipNotFound && (status === 404 || status === 410)) {
       // Skip these errors as they are reflected in the UI
       return { type: ALERT_NOOP };
     }
diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js
index 0be746048..f98cb7bf8 100644
--- a/app/javascript/flavours/glitch/actions/compose.js
+++ b/app/javascript/flavours/glitch/actions/compose.js
@@ -259,12 +259,31 @@ export function uploadCompose(files) {
         // Account for disparity in size of original image and resized data
         total += file.size - f.size;
 
-        return api(getState).post('/api/v1/media', data, {
+        return api(getState).post('/api/v2/media', data, {
           onUploadProgress: function({ loaded }){
             progress[i] = loaded;
             dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
           },
-        }).then(({ data }) => dispatch(uploadComposeSuccess(data, f)));
+        }).then(({ status, data }) => {
+          // If server-side processing of the media attachment has not completed yet,
+          // poll the server until it is, before showing the media attachment as uploaded
+
+          if (status === 200) {
+            dispatch(uploadComposeSuccess(data, f));
+          } else if (status === 202) {
+            const poll = () => {
+              api(getState).get(`/api/v1/media/${data.id}`).then(response => {
+                if (response.status === 200) {
+                  dispatch(uploadComposeSuccess(response.data, f));
+                } else if (response.status === 206) {
+                  setTimeout(() => poll(), 1000);
+                }
+              }).catch(error => dispatch(uploadComposeFail(error)));
+            };
+
+            poll();
+          }
+        });
       }).catch(error => dispatch(uploadComposeFail(error)));
     };
   };
diff --git a/app/javascript/flavours/glitch/actions/identity_proofs.js b/app/javascript/flavours/glitch/actions/identity_proofs.js
index a7241da20..18e679aec 100644
--- a/app/javascript/flavours/glitch/actions/identity_proofs.js
+++ b/app/javascript/flavours/glitch/actions/identity_proofs.js
@@ -27,4 +27,5 @@ export const fetchAccountIdentityProofsFail = (accountId, err) => ({
   type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
   accountId,
   err,
+  skipNotFound: true,
 });
diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js
index 2ef78025e..1bbdd6142 100644
--- a/app/javascript/flavours/glitch/actions/timelines.js
+++ b/app/javascript/flavours/glitch/actions/timelines.js
@@ -165,6 +165,7 @@ export function expandTimelineFail(timeline, error, isLoadingMore) {
     timeline,
     error,
     skipLoading: !isLoadingMore,
+    skipNotFound: timeline.startsWith('account:'),
   };
 };
 
diff --git a/app/javascript/flavours/glitch/components/domain.js b/app/javascript/flavours/glitch/components/domain.js
index 85729ca94..697065d87 100644
--- a/app/javascript/flavours/glitch/components/domain.js
+++ b/app/javascript/flavours/glitch/components/domain.js
@@ -5,7 +5,7 @@ import { defineMessages, injectIntl } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
 const messages = defineMessages({
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
 });
 
 export default @injectIntl
diff --git a/app/javascript/flavours/glitch/components/intersection_observer_article.js b/app/javascript/flavours/glitch/components/intersection_observer_article.js
index 03b3700df..88f29892e 100644
--- a/app/javascript/flavours/glitch/components/intersection_observer_article.js
+++ b/app/javascript/flavours/glitch/components/intersection_observer_article.js
@@ -45,7 +45,7 @@ export default class IntersectionObserverArticle extends React.Component {
     intersectionObserverWrapper.observe(
       id,
       this.node,
-      this.handleIntersection
+      this.handleIntersection,
     );
 
     this.componentMounted = true;
diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js
index 9754c73dc..9472e34bf 100644
--- a/app/javascript/flavours/glitch/components/media_gallery.js
+++ b/app/javascript/flavours/glitch/components/media_gallery.js
@@ -23,7 +23,7 @@ const messages = defineMessages({
     id: 'status.sensitive_toggle',
   },
   toggle_visible: {
-    defaultMessage: 'Toggle visibility',
+    defaultMessage: 'Hide media',
     id: 'media_gallery.toggle_visible',
   },
   warning: {
diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js
index 62965df94..46fd1e8c0 100644
--- a/app/javascript/flavours/glitch/components/poll.js
+++ b/app/javascript/flavours/glitch/components/poll.js
@@ -127,15 +127,7 @@ class Poll extends ImmutablePureComponent {
 
     return (
       <li key={option.get('title')}>
-        {showResults && (
-          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
-            {({ width }) =>
-              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
-            }
-          </Motion>
-        )}
-
-        <label className={classNames('poll__text', { selectable: !showResults })}>
+        <label className={classNames('poll__option', { selectable: !showResults })}>
           <input
             name='vote-options'
             type={poll.get('multiple') ? 'checkbox' : 'radio'}
@@ -157,12 +149,26 @@ class Poll extends ImmutablePureComponent {
             />
           )}
           {showResults && <span className='poll__number'>
-            {!!voted && <Icon id='check' className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
             {Math.round(percent)}%
           </span>}
 
-          <span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
+          <span
+            className='poll__option__text'
+            dangerouslySetInnerHTML={{ __html: titleEmojified }}
+          />
+
+          {!!voted && <span className='poll__voted'>
+            <Icon id='check' className='poll__voted__mark' title={intl.formatMessage(messages.voted)} />
+          </span>}
         </label>
+
+        {showResults && (
+          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
+            {({ width }) =>
+              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
+            }
+          </Motion>
+        )}
       </li>
     );
   }
diff --git a/app/javascript/flavours/glitch/containers/domain_container.js b/app/javascript/flavours/glitch/containers/domain_container.js
index 52d5c1613..e92e102ab 100644
--- a/app/javascript/flavours/glitch/containers/domain_container.js
+++ b/app/javascript/flavours/glitch/containers/domain_container.js
@@ -6,7 +6,7 @@ import Domain from '../components/domain';
 import { openModal } from '../actions/modal';
 
 const messages = defineMessages({
-  blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
+  blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
 });
 
 const makeMapStateToProps = () => {
diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js
index 6b4aff616..fb0f165ff 100644
--- a/app/javascript/flavours/glitch/features/account/components/header.js
+++ b/app/javascript/flavours/glitch/features/account/components/header.js
@@ -30,8 +30,8 @@ const messages = defineMessages({
   report: { id: 'account.report', defaultMessage: 'Report @{name}' },
   share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
   media: { id: 'account.media', defaultMessage: 'Media' },
-  blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
   hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' },
   showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' },
   pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
@@ -40,7 +40,7 @@ const messages = defineMessages({
   favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
   lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
   blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
-  domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
+  domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' },
   mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
   endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
   unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
@@ -136,7 +136,7 @@ class Header extends ImmutablePureComponent {
     if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) {
       info.push(<span className='relationship-tag'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>);
     } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) {
-      info.push(<span className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' /></span>);
+      info.push(<span className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain blocked' /></span>);
     }
 
     if (me !== account.get('id')) {
diff --git a/app/javascript/flavours/glitch/features/audio/index.js b/app/javascript/flavours/glitch/features/audio/index.js
index 033d92adf..49e91227f 100644
--- a/app/javascript/flavours/glitch/features/audio/index.js
+++ b/app/javascript/flavours/glitch/features/audio/index.js
@@ -199,8 +199,8 @@ class Audio extends React.PureComponent {
         <div className='video-player__controls active'>
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
-              <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
 
               <div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
                 &nbsp;
@@ -221,7 +221,7 @@ class Audio extends React.PureComponent {
             </div>
 
             <div className='video-player__buttons right'>
-              <button type='button' aria-label={intl.formatMessage(messages.download)}>
+              <button type='button' title={intl.formatMessage(messages.download)} aria-label={intl.formatMessage(messages.download)}>
                 <a className='video-player__download__icon' href={this.props.src} download>
                   <Icon id={'download'} fixedWidth />
                 </a>
diff --git a/app/javascript/flavours/glitch/features/blocks/index.js b/app/javascript/flavours/glitch/features/blocks/index.js
index 9eb6fe02e..4992689ff 100644
--- a/app/javascript/flavours/glitch/features/blocks/index.js
+++ b/app/javascript/flavours/glitch/features/blocks/index.js
@@ -66,7 +66,7 @@ class Blocks extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} />
+            <AccountContainer key={id} id={id} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/compose/components/compose_form.js b/app/javascript/flavours/glitch/features/compose/components/compose_form.js
index daacbb73f..3d736e83f 100644
--- a/app/javascript/flavours/glitch/features/compose/components/compose_form.js
+++ b/app/javascript/flavours/glitch/features/compose/components/compose_form.js
@@ -81,18 +81,6 @@ class ComposeForm extends ImmutablePureComponent {
     this.props.onChange(e.target.value);
   }
 
-  handleKeyDown = ({ ctrlKey, keyCode, metaKey, altKey }) => {
-    //  We submit the status on control/meta + enter.
-    if (keyCode === 13 && (ctrlKey || metaKey)) {
-      this.handleSubmit();
-    }
-
-    // Submit the status with secondary visibility on alt + enter.
-    if (keyCode === 13 && altKey) {
-      this.handleSecondarySubmit();
-    }
-  }
-
   handleSubmit = (overriddenVisibility = null) => {
     const { textarea: { value }, uploadForm } = this;
     const {
@@ -123,7 +111,7 @@ class ComposeForm extends ImmutablePureComponent {
     // Submit unless there are media with missing descriptions
     if (mediaDescriptionConfirmation && onMediaDescriptionConfirm && media && media.some(item => !item.get('description'))) {
       const firstWithoutDescription = media.find(item => !item.get('description'));
-      onMediaDescriptionConfirm(this.context.router ? this.context.router.history : null, firstWithoutDescription.get('id'));
+      onMediaDescriptionConfirm(this.context.router ? this.context.router.history : null, firstWithoutDescription.get('id'), overriddenVisibility);
     } else if (onSubmit) {
       if (onChangeVisibility && overriddenVisibility) {
         onChangeVisibility(overriddenVisibility);
@@ -171,10 +159,20 @@ class ComposeForm extends ImmutablePureComponent {
   }
 
   //  When the escape key is released, we focus the UI.
-  handleKeyUp = ({ key }) => {
+  handleKeyUp = ({ key, ctrlKey, keyCode, metaKey, altKey }) => {
     if (key === 'Escape') {
       document.querySelector('.ui').parentElement.focus();
     }
+
+    //  We submit the status on control/meta + enter.
+    if (keyCode === 13 && (ctrlKey || metaKey)) {
+      this.handleSubmit();
+    }
+
+    // Submit the status with secondary visibility on alt + enter.
+    if (keyCode === 13 && altKey) {
+      this.handleSecondarySubmit();
+    }
   }
 
   //  Sets a reference to the textarea.
@@ -307,7 +305,6 @@ class ComposeForm extends ImmutablePureComponent {
             placeholder={intl.formatMessage(messages.spoiler_placeholder)}
             value={spoilerText}
             onChange={this.handleChangeSpoiler}
-            onKeyDown={this.handleKeyDown}
             onKeyUp={this.handleKeyUp}
             disabled={!spoiler}
             ref={this.handleRefSpoilerText}
@@ -328,9 +325,9 @@ class ComposeForm extends ImmutablePureComponent {
           disabled={isSubmitting}
           value={this.props.text}
           onChange={this.handleChange}
+          onKeyUp={this.handleKeyUp}
           suggestions={this.props.suggestions}
           onFocus={this.handleFocus}
-          onKeyDown={this.handleKeyDown}
           onSuggestionsFetchRequested={onFetchSuggestions}
           onSuggestionsClearRequested={onClearSuggestions}
           onSuggestionSelected={this.onSuggestionSelected}
diff --git a/app/javascript/flavours/glitch/features/compose/components/options.js b/app/javascript/flavours/glitch/features/compose/components/options.js
index 92348b000..9e332aabd 100644
--- a/app/javascript/flavours/glitch/features/compose/components/options.js
+++ b/app/javascript/flavours/glitch/features/compose/components/options.js
@@ -34,7 +34,7 @@ const messages = defineMessages({
     id: 'content-type.change',
   },
   direct_long: {
-    defaultMessage: 'Post to mentioned users only',
+    defaultMessage: 'Visible for mentioned users only',
     id: 'privacy.direct.long',
   },
   direct_short: {
@@ -66,7 +66,7 @@ const messages = defineMessages({
     id: 'compose.content-type.plain',
   },
   private_long: {
-    defaultMessage: 'Post to followers only',
+    defaultMessage: 'Visible for followers only',
     id: 'privacy.private.long',
   },
   private_short: {
@@ -74,7 +74,7 @@ const messages = defineMessages({
     id: 'privacy.private.short',
   },
   public_long: {
-    defaultMessage: 'Post to public timelines',
+    defaultMessage: 'Visible for all, shown in public timelines',
     id: 'privacy.public.long',
   },
   public_short: {
@@ -94,7 +94,7 @@ const messages = defineMessages({
     id: 'advanced_options.threaded_mode.short',
   },
   unlisted_long: {
-    defaultMessage: 'Do not show in public timelines',
+    defaultMessage: 'Visible for all, but not in public timelines',
     id: 'privacy.unlisted.long',
   },
   unlisted_short: {
diff --git a/app/javascript/flavours/glitch/features/compose/components/poll_form.js b/app/javascript/flavours/glitch/features/compose/components/poll_form.js
index 3d818ea20..57fac10ac 100644
--- a/app/javascript/flavours/glitch/features/compose/components/poll_form.js
+++ b/app/javascript/flavours/glitch/features/compose/components/poll_form.js
@@ -62,7 +62,7 @@ class Option extends React.PureComponent {
 
     return (
       <li>
-        <label className='poll__text editable'>
+        <label className='poll__option editable'>
           <span className={classNames('poll__input', { checkbox: isPollMultiple })} />
 
           <AutosuggestInput
@@ -143,6 +143,7 @@ class PollForm extends ImmutablePureComponent {
             <option value='true'>{intl.formatMessage(messages.multiple_choices)}</option>
           </select>
 
+          {/* eslint-disable-next-line jsx-a11y/no-onchange */}
           <select value={expiresIn} onChange={this.handleSelectDuration}>
             <option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>
             <option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
diff --git a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js
index 18e2b2f39..fcd2caf1b 100644
--- a/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js
+++ b/app/javascript/flavours/glitch/features/compose/containers/compose_form_container.js
@@ -114,11 +114,16 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
     dispatch(changeComposeVisibility(value));
   },
 
-  onMediaDescriptionConfirm(routerHistory, mediaId) {
+  onMediaDescriptionConfirm(routerHistory, mediaId, overriddenVisibility = null) {
     dispatch(openModal('CONFIRM', {
       message: intl.formatMessage(messages.missingDescriptionMessage),
       confirm: intl.formatMessage(messages.missingDescriptionConfirm),
-      onConfirm: () => dispatch(submitCompose(routerHistory)),
+      onConfirm: () => {
+        if (overriddenVisibility) {
+          dispatch(changeComposeVisibility(overriddenVisibility));
+        };
+        dispatch(submitCompose(routerHistory));
+      },
       secondary: intl.formatMessage(messages.missingDescriptionEdit),
       onSecondary: () => dispatch(openModal('FOCAL_POINT', { id: mediaId })),
       onDoNotAsk: () => dispatch(changeLocalSetting(['confirm_missing_media_description'], false)),
diff --git a/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js b/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js
index ba01f8d5c..47b92560d 100644
--- a/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js
+++ b/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js
@@ -195,7 +195,7 @@ class Conversation extends ImmutablePureComponent {
     return (
       <HotKeys handlers={handlers}>
         <div className={classNames('conversation focusable muted', { 'conversation--unread': unread })} tabIndex='0'>
-          <div className='conversation__avatar'>
+          <div className='conversation__avatar' onClick={this.handleClick} role='presentation'>
             <AvatarComposite accounts={accounts} size={48} />
           </div>
 
diff --git a/app/javascript/flavours/glitch/features/domain_blocks/index.js b/app/javascript/flavours/glitch/features/domain_blocks/index.js
index cd105a49b..acce87d5a 100644
--- a/app/javascript/flavours/glitch/features/domain_blocks/index.js
+++ b/app/javascript/flavours/glitch/features/domain_blocks/index.js
@@ -13,8 +13,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import ScrollableList from 'flavours/glitch/components/scrollable_list';
 
 const messages = defineMessages({
-  heading: { id: 'column.domain_blocks', defaultMessage: 'Hidden domains' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
 });
 
 const mapStateToProps = state => ({
@@ -54,7 +54,7 @@ class Blocks extends ImmutablePureComponent {
       );
     }
 
-    const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no hidden domains yet.' />;
+    const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />;
 
     return (
       <Column bindToDocument={!multiColumn} icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
@@ -67,7 +67,7 @@ class Blocks extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {domains.map(domain =>
-            <DomainContainer key={domain} domain={domain} />
+            <DomainContainer key={domain} domain={domain} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/favourites/index.js b/app/javascript/flavours/glitch/features/favourites/index.js
index 953bf171f..bd6f782ce 100644
--- a/app/javascript/flavours/glitch/features/favourites/index.js
+++ b/app/javascript/flavours/glitch/features/favourites/index.js
@@ -88,7 +88,7 @@ class Favourites extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/follow_requests/index.js b/app/javascript/flavours/glitch/features/follow_requests/index.js
index 36770aace..efbe1a23c 100644
--- a/app/javascript/flavours/glitch/features/follow_requests/index.js
+++ b/app/javascript/flavours/glitch/features/follow_requests/index.js
@@ -11,6 +11,7 @@ import { fetchFollowRequests, expandFollowRequests } from 'flavours/glitch/actio
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import ScrollableList from 'flavours/glitch/components/scrollable_list';
+import { me } from 'flavours/glitch/util/initial_state';
 
 const messages = defineMessages({
   heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
@@ -19,6 +20,8 @@ const messages = defineMessages({
 const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
   hasMore: !!state.getIn(['user_lists', 'follow_requests', 'next']),
+  locked: !!state.getIn(['accounts', me, 'locked']),
+  domain: state.getIn(['meta', 'domain']),
 });
 
 export default @connect(mapStateToProps)
@@ -30,6 +33,8 @@ class FollowRequests extends ImmutablePureComponent {
     dispatch: PropTypes.func.isRequired,
     hasMore: PropTypes.bool,
     accountIds: ImmutablePropTypes.list,
+    locked: PropTypes.bool,
+    domain: PropTypes.string,
     intl: PropTypes.object.isRequired,
     multiColumn: PropTypes.bool,
   };
@@ -43,7 +48,7 @@ class FollowRequests extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, accountIds, hasMore, multiColumn } = this.props;
+    const { intl, accountIds, hasMore, multiColumn, locked, domain } = this.props;
 
     if (!accountIds) {
       return (
@@ -54,6 +59,15 @@ class FollowRequests extends ImmutablePureComponent {
     }
 
     const emptyMessage = <FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />;
+    const unlockedPrependMessage = locked ? null : (
+      <div className='follow_requests-unlocked_explanation'>
+        <FormattedMessage
+          id='follow_requests.unlocked_explanation'
+          defaultMessage='Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.'
+          values={{ domain: domain }}
+        />
+      </div>
+    );
 
     return (
       <Column bindToDocument={!multiColumn} name='follow-requests' icon='user-plus' heading={intl.formatMessage(messages.heading)}>
@@ -65,9 +79,10 @@ class FollowRequests extends ImmutablePureComponent {
           hasMore={hasMore}
           emptyMessage={emptyMessage}
           bindToDocument={!multiColumn}
+          prepend={unlockedPrependMessage}
         >
           {accountIds.map(id =>
-            <AccountAuthorizeContainer key={id} id={id} />
+            <AccountAuthorizeContainer key={id} id={id} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/followers/index.js b/app/javascript/flavours/glitch/features/followers/index.js
index c78dcc8e4..2b86cc805 100644
--- a/app/javascript/flavours/glitch/features/followers/index.js
+++ b/app/javascript/flavours/glitch/features/followers/index.js
@@ -105,7 +105,7 @@ class Followers extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/following/index.js b/app/javascript/flavours/glitch/features/following/index.js
index df7c19c22..cf374e494 100644
--- a/app/javascript/flavours/glitch/features/following/index.js
+++ b/app/javascript/flavours/glitch/features/following/index.js
@@ -105,7 +105,7 @@ class Following extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/getting_started/components/announcements.js b/app/javascript/flavours/glitch/features/getting_started/components/announcements.js
index e34c9009b..acaa78fe3 100644
--- a/app/javascript/flavours/glitch/features/getting_started/components/announcements.js
+++ b/app/javascript/flavours/glitch/features/getting_started/components/announcements.js
@@ -95,6 +95,10 @@ class Content extends ImmutablePureComponent {
       } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
         link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
       } else {
+        let status = this.props.announcement.get('statuses').find(item => link.href === item.get('url'));
+        if (status) {
+          link.addEventListener('click', this.onStatusClick.bind(this, status), false);
+        }
         link.setAttribute('title', link.href);
         link.classList.add('unhandled-link');
       }
@@ -120,6 +124,13 @@ class Content extends ImmutablePureComponent {
     }
   }
 
+  onStatusClick = (status, e) => {
+    if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${status.get('id')}`);
+    }
+  }
+
   handleEmojiMouseEnter = ({ target }) => {
     target.src = target.getAttribute('data-original');
   }
@@ -367,6 +378,14 @@ class Announcements extends ImmutablePureComponent {
     index: 0,
   };
 
+  static getDerivedStateFromProps(props, state) {
+    if (props.announcements.size > 0 && state.index >= props.announcements.size) {
+      return { index: props.announcements.size - 1 };
+    } else {
+      return null;
+    }
+  }
+
   componentDidMount () {
     this._markAnnouncementAsRead();
   }
diff --git a/app/javascript/flavours/glitch/features/lists/index.js b/app/javascript/flavours/glitch/features/lists/index.js
index adde3dd5c..e384f301b 100644
--- a/app/javascript/flavours/glitch/features/lists/index.js
+++ b/app/javascript/flavours/glitch/features/lists/index.js
@@ -73,7 +73,7 @@ class Lists extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {lists.map(list =>
-            <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />
+            <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/mutes/index.js b/app/javascript/flavours/glitch/features/mutes/index.js
index c27a530d5..62dccd971 100644
--- a/app/javascript/flavours/glitch/features/mutes/index.js
+++ b/app/javascript/flavours/glitch/features/mutes/index.js
@@ -66,7 +66,7 @@ class Mutes extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} />
+            <AccountContainer key={id} id={id} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/reblogs/index.js b/app/javascript/flavours/glitch/features/reblogs/index.js
index 258070358..d88916d19 100644
--- a/app/javascript/flavours/glitch/features/reblogs/index.js
+++ b/app/javascript/flavours/glitch/features/reblogs/index.js
@@ -89,7 +89,7 @@ class Reblogs extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/status/components/card.js b/app/javascript/flavours/glitch/features/status/components/card.js
index 7352dc6b4..e3ee7dada 100644
--- a/app/javascript/flavours/glitch/features/status/components/card.js
+++ b/app/javascript/flavours/glitch/features/status/components/card.js
@@ -90,7 +90,7 @@ export default class Card extends React.PureComponent {
           },
         },
       ]),
-      0
+      0,
     );
   };
 
diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js
index c4ac8f0a6..180b11a54 100644
--- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js
+++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js
@@ -198,8 +198,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
       reblogIcon = 'lock';
     }
 
-    if (status.get('visibility') === 'private') {
-      reblogLink = <Icon id={reblogIcon} />;
+    if (!['unlisted', 'public'].includes(status.get('visibility'))) {
+      reblogLink = null;
     } else if (this.context.router) {
       reblogLink = (
         <Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
@@ -265,7 +265,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
           <div className='detailed-status__meta'>
             <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener noreferrer'>
               <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
-            </a>{applicationLink} · {reblogLink} · {favouriteLink} · <VisibilityIcon visibility={status.get('visibility')} />
+            </a>{applicationLink} {!!reblogLink && ['·', reblogLink]} · {favouriteLink} · <VisibilityIcon visibility={status.get('visibility')} />
           </div>
         </div>
       </div>
diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js
index 1b5fbce9f..6a8952c8d 100644
--- a/app/javascript/flavours/glitch/features/video/index.js
+++ b/app/javascript/flavours/glitch/features/video/index.js
@@ -488,8 +488,9 @@ class Video extends React.PureComponent {
 
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
-              <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+
               <div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
                 &nbsp;
                 <div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />
@@ -512,16 +513,11 @@ class Video extends React.PureComponent {
             </div>
 
             <div className='video-player__buttons right'>
-              {(!onCloseVideo && !editable && !fullscreen) && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
-              {(!fullscreen && onOpenVideo) && <button type='button' aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
-              {onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
-              <button type='button' aria-label={intl.formatMessage(messages.download)}>
-                <a className='video-player__download__icon' href={this.props.src} download>
-                  <Icon id={'download'} fixedWidth />
-                </a>
-              </button>
-              <button type='button' aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
-
+              {(!onCloseVideo && !editable && !fullscreen) && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
+              {(!fullscreen && onOpenVideo) && <button type='button' title={intl.formatMessage(messages.expand)} aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
+              {onCloseVideo && <button type='button' title={intl.formatMessage(messages.close)} aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
+              <button type='button' title={intl.formatMessage(messages.download)} aria-label={intl.formatMessage(messages.download)}><a className='video-player__download__icon' href={this.props.src} download><Icon id={'download'} fixedWidth /></a></button>
+              <button type='button' title={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
             </div>
           </div>
         </div>
diff --git a/app/javascript/flavours/glitch/middleware/errors.js b/app/javascript/flavours/glitch/middleware/errors.js
index 212c1f4ad..ade529a4e 100644
--- a/app/javascript/flavours/glitch/middleware/errors.js
+++ b/app/javascript/flavours/glitch/middleware/errors.js
@@ -8,7 +8,7 @@ export default function errorsMiddleware() {
       const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
 
       if (action.type.match(isFail)) {
-        dispatch(showAlertForError(action.error));
+        dispatch(showAlertForError(action.error, action.skipNotFound));
       }
     }
 
diff --git a/app/javascript/flavours/glitch/packs/common.js b/app/javascript/flavours/glitch/packs/common.js
index 94a4e6ee4..1fedc890a 100644
--- a/app/javascript/flavours/glitch/packs/common.js
+++ b/app/javascript/flavours/glitch/packs/common.js
@@ -1,4 +1,4 @@
-import { start } from 'rails-ujs';
+import { start } from '@rails/ujs';
 
 start();
 
diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js
index d8a97704f..e5a567205 100644
--- a/app/javascript/flavours/glitch/packs/public.js
+++ b/app/javascript/flavours/glitch/packs/public.js
@@ -5,7 +5,7 @@ import loadKeyboardExtensions from 'flavours/glitch/util/load_keyboard_extension
 function main() {
   const IntlMessageFormat = require('intl-messageformat').default;
   const { timeAgoString } = require('flavours/glitch/components/relative_timestamp');
-  const { delegate } = require('rails-ujs');
+  const { delegate } = require('@rails/ujs');
   const emojify = require('flavours/glitch/util/emoji').default;
   const { getLocale } = require('locales');
   const { messages } = getLocale();
@@ -97,6 +97,28 @@ function main() {
 
     delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original'));
     delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static'));
+
+    delegate(document, '.status__content__spoiler-link', 'click', function() {
+      const contentEl = this.parentNode.parentNode.querySelector('.e-content');
+
+      if (contentEl.style.display === 'block') {
+        contentEl.style.display = 'none';
+        this.parentNode.style.marginBottom = 0;
+        this.textContent = (new IntlMessageFormat(messages['status.show_more'] || 'Show more', locale)).format();
+      } else {
+        contentEl.style.display = 'block';
+        this.parentNode.style.marginBottom = null;
+        this.textContent = (new IntlMessageFormat(messages['status.show_less'] || 'Show less', locale)).format();
+      }
+
+      return false;
+    });
+
+    [].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => {
+      const contentEl = spoilerLink.parentNode.parentNode.querySelector('.e-content');
+      const message = (contentEl.style.display === 'block') ? (messages['status.show_less'] || 'Show less') : (messages['status.show_more'] || 'Show more');
+      spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();
+    });
   });
 
   delegate(document, '.sidebar__toggle__icon', 'click', () => {
diff --git a/app/javascript/flavours/glitch/packs/settings.js b/app/javascript/flavours/glitch/packs/settings.js
index edf1b82e0..8a9f23505 100644
--- a/app/javascript/flavours/glitch/packs/settings.js
+++ b/app/javascript/flavours/glitch/packs/settings.js
@@ -3,7 +3,7 @@ import ready from 'flavours/glitch/util/ready';
 import loadKeyboardExtensions from 'flavours/glitch/util/load_keyboard_extensions';
 
 function main() {
-  const { delegate } = require('rails-ujs');
+  const { delegate } = require('@rails/ujs');
 
   delegate(document, '.sidebar__toggle__icon', 'click', () => {
     const target = document.querySelector('.sidebar ul');
diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js
index 92a9859d9..f758d5c93 100644
--- a/app/javascript/flavours/glitch/reducers/compose.js
+++ b/app/javascript/flavours/glitch/reducers/compose.js
@@ -344,7 +344,6 @@ export default function compose(state = initialState, action) {
     });
   case COMPOSE_SPOILERNESS_CHANGE:
     return state.withMutations(map => {
-      map.set('spoiler_text', '');
       map.set('spoiler', !state.get('spoiler'));
       map.set('idempotencyKey', uuid());
 
diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js
index d0eb7bb5a..31d9611a3 100644
--- a/app/javascript/flavours/glitch/reducers/notifications.js
+++ b/app/javascript/flavours/glitch/reducers/notifications.js
@@ -91,11 +91,11 @@ const expandNormalizedNotifications = (state, notifications, next, isLoadingRece
 
       mutable.update(usePendingItems ? 'pendingItems' : 'items', list => {
         const lastIndex = 1 + list.findLastIndex(
-          item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id'))
+          item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id')),
         );
 
         const firstIndex = 1 + list.take(lastIndex).findLastIndex(
-          item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
+          item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0,
         );
 
         return list.take(firstIndex).concat(items, list.skip(lastIndex));
diff --git a/app/javascript/flavours/glitch/reducers/timelines.js b/app/javascript/flavours/glitch/reducers/timelines.js
index 1ea9ed645..be7b2441b 100644
--- a/app/javascript/flavours/glitch/reducers/timelines.js
+++ b/app/javascript/flavours/glitch/reducers/timelines.js
@@ -53,7 +53,7 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is
 
         return oldIds.take(firstIndex + 1).concat(
           isPartial && oldIds.get(firstIndex) !== null ? newIds.unshift(null) : newIds,
-          oldIds.skip(lastIndex)
+          oldIds.skip(lastIndex),
         );
       });
     }
@@ -171,7 +171,7 @@ export default function timelines(state = initialState, action) {
     return state.update(
       action.timeline,
       initialTimeline,
-      map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items)
+      map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items),
     );
   default:
     return state;
diff --git a/app/javascript/flavours/glitch/selectors/index.js b/app/javascript/flavours/glitch/selectors/index.js
index ab7dac66a..4a3303c36 100644
--- a/app/javascript/flavours/glitch/selectors/index.js
+++ b/app/javascript/flavours/glitch/selectors/index.js
@@ -146,7 +146,7 @@ export const makeGetStatus = () => {
         map.set('account', accountBase);
         map.set('filtered', filtered);
       });
-    }
+    },
   );
 };
 
diff --git a/app/javascript/flavours/glitch/store/configureStore.js b/app/javascript/flavours/glitch/store/configureStore.js
index 7e7472841..e18af842f 100644
--- a/app/javascript/flavours/glitch/store/configureStore.js
+++ b/app/javascript/flavours/glitch/store/configureStore.js
@@ -10,6 +10,6 @@ export default function configureStore() {
     thunk,
     loadingBarMiddleware({ promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'] }),
     errorsMiddleware(),
-    soundsMiddleware()
+    soundsMiddleware(),
   ), window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f));
 };
diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss
index 26a98c66f..0d24da4dd 100644
--- a/app/javascript/flavours/glitch/styles/admin.scss
+++ b/app/javascript/flavours/glitch/styles/admin.scss
@@ -418,6 +418,11 @@ body,
       }
     }
 
+    &--with-select strong {
+      display: block;
+      margin-bottom: 10px;
+    }
+
     a {
       display: inline-block;
       color: $darker-text-color;
@@ -567,19 +572,22 @@ body,
 }
 
 .log-entry {
-  margin-bottom: 20px;
   line-height: 20px;
+  padding: 15px 0;
+  background: $ui-base-color;
+  border-bottom: 1px solid lighten($ui-base-color, 4%);
+
+  &:last-child {
+    border-bottom: 0;
+  }
 
   &__header {
     display: flex;
     justify-content: flex-start;
     align-items: center;
-    padding: 10px;
-    background: $ui-base-color;
     color: $darker-text-color;
-    border-radius: 4px 4px 0 0;
     font-size: 14px;
-    position: relative;
+    padding: 0 10px;
   }
 
   &__avatar {
@@ -606,44 +614,6 @@ body,
     color: $dark-text-color;
   }
 
-  &__extras {
-    background: lighten($ui-base-color, 6%);
-    border-radius: 0 0 4px 4px;
-    padding: 10px;
-    color: $darker-text-color;
-    font-family: $font-monospace, monospace;
-    font-size: 12px;
-    word-wrap: break-word;
-    min-height: 20px;
-  }
-
-  &__icon {
-    font-size: 28px;
-    margin-right: 10px;
-    color: $dark-text-color;
-  }
-
-  &__icon__overlay {
-    position: absolute;
-    top: 10px;
-    right: 10px;
-    width: 10px;
-    height: 10px;
-    border-radius: 50%;
-
-    &.positive {
-      background: $success-green;
-    }
-
-    &.negative {
-      background: lighten($error-red, 12%);
-    }
-
-    &.neutral {
-      background: $ui-highlight-color;
-    }
-  }
-
   a,
   .username,
   .target {
@@ -651,18 +621,6 @@ body,
     text-decoration: none;
     font-weight: 500;
   }
-
-  .diff-old {
-    color: lighten($error-red, 12%);
-  }
-
-  .diff-neutral {
-    color: $secondary-text-color;
-  }
-
-  .diff-new {
-    color: $success-green;
-  }
 }
 
 a.name-tag,
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss
index 6305e2a4d..491ceb6ec 100644
--- a/app/javascript/flavours/glitch/styles/components/accounts.scss
+++ b/app/javascript/flavours/glitch/styles/components/accounts.scss
@@ -51,7 +51,6 @@
     @include avatar-radius;
     overflow: hidden;
     position: relative;
-    cursor: default;
 
     & div {
       @include avatar-radius;
diff --git a/app/javascript/flavours/glitch/styles/components/announcements.scss b/app/javascript/flavours/glitch/styles/components/announcements.scss
index eab6c728b..52feefd3c 100644
--- a/app/javascript/flavours/glitch/styles/components/announcements.scss
+++ b/app/javascript/flavours/glitch/styles/components/announcements.scss
@@ -1,5 +1,6 @@
 .announcements__item__content {
   word-wrap: break-word;
+  overflow-y: auto;
 
   .emojione {
     width: 20px;
@@ -69,17 +70,21 @@
     box-sizing: border-box;
     width: 100%;
     padding: 15px;
-    padding-right: 15px + 18px;
     position: relative;
     font-size: 15px;
     line-height: 20px;
     word-wrap: break-word;
     font-weight: 400;
+    max-height: 50vh;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
 
     &__range {
       display: block;
       font-weight: 500;
       margin-bottom: 10px;
+      padding-right: 18px;
     }
 
     &__unread {
diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss
index 525dcaf90..3269638eb 100644
--- a/app/javascript/flavours/glitch/styles/components/columns.scss
+++ b/app/javascript/flavours/glitch/styles/components/columns.scss
@@ -452,7 +452,8 @@
 }
 
 .empty-column-indicator,
-.error-column {
+.error-column,
+.follow_requests-unlocked_explanation {
   color: $dark-text-color;
   background: $ui-base-color;
   text-align: center;
@@ -482,6 +483,11 @@
   }
 }
 
+.follow_requests-unlocked_explanation {
+  background: darken($ui-base-color, 4%);
+  contain: initial;
+}
+
 .error-column {
   flex-direction: column;
 }
diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss
index 943776010..460f75c1f 100644
--- a/app/javascript/flavours/glitch/styles/components/composer.scss
+++ b/app/javascript/flavours/glitch/styles/components/composer.scss
@@ -3,8 +3,8 @@
 
   .emoji-picker-dropdown {
     position: absolute;
-    right: 5px;
-    top: 5px;
+    top: 0;
+    right: 0;
 
     ::-webkit-scrollbar-track:hover,
     ::-webkit-scrollbar-track:active {
diff --git a/app/javascript/flavours/glitch/styles/components/emoji.scss b/app/javascript/flavours/glitch/styles/components/emoji.scss
index 160e9d811..9dfee346a 100644
--- a/app/javascript/flavours/glitch/styles/components/emoji.scss
+++ b/app/javascript/flavours/glitch/styles/components/emoji.scss
@@ -72,10 +72,7 @@
 
 .emoji-button {
   display: block;
-  font-size: 24px;
-  line-height: 24px;
-  margin-left: 2px;
-  width: 24px;
+  padding: 5px 5px 2px 2px;
   outline: 0;
   cursor: pointer;
 
@@ -91,7 +88,6 @@
     margin: 0;
     width: 22px;
     height: 22px;
-    margin-top: 2px;
   }
 
   &:hover,
diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss
index d97ab436d..50cea8b26 100644
--- a/app/javascript/flavours/glitch/styles/components/index.scss
+++ b/app/javascript/flavours/glitch/styles/components/index.scss
@@ -1515,6 +1515,7 @@
     padding: 10px;
     padding-top: 12px;
     position: relative;
+    cursor: pointer;
   }
 
   &__unread {
diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss
index 39bfaae9a..3cb076191 100644
--- a/app/javascript/flavours/glitch/styles/components/media.scss
+++ b/app/javascript/flavours/glitch/styles/components/media.scss
@@ -62,12 +62,6 @@
 }
 
 .media-gallery__gifv {
-  &.autoplay {
-    .media-gallery__gifv__label {
-      display: none;
-    }
-  }
-
   &:hover {
     .media-gallery__gifv__label {
       opacity: 1;
diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss
index fa26c4706..50b7f2a72 100644
--- a/app/javascript/flavours/glitch/styles/components/status.scss
+++ b/app/javascript/flavours/glitch/styles/components/status.scss
@@ -331,13 +331,11 @@
     }
 
     .display-name {
+      color: $light-text-color;
+
       strong {
         color: $inverted-text-color;
       }
-
-      span {
-        color: $lighter-text-color;
-      }
     }
 
     .status__content {
diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss
index 9c86cca58..44338338f 100644
--- a/app/javascript/flavours/glitch/styles/polls.scss
+++ b/app/javascript/flavours/glitch/styles/polls.scss
@@ -14,20 +14,18 @@
   }
 
   &__chart {
-    position: absolute;
-    top: 0;
-    left: 0;
-    height: 100%;
-    display: inline-block;
     border-radius: 4px;
-    background: darken($ui-primary-color, 14%);
+    display: block;
+    background: darken($ui-primary-color, 5%);
+    height: 5px;
+    min-width: 1%;
 
     &.leading {
       background: $ui-highlight-color;
     }
   }
 
-  &__text {
+  &__option {
     position: relative;
     display: flex;
     padding: 6px 0;
@@ -35,6 +33,13 @@
     cursor: default;
     overflow: hidden;
 
+    &__text {
+      display: inline-block;
+      word-wrap: break-word;
+      overflow-wrap: break-word;
+      max-width: calc(100% - 45px - 25px);
+    }
+
     input[type=radio],
     input[type=checkbox] {
       display: none;
@@ -102,8 +107,8 @@
     &:active,
     &:focus,
     &:hover {
+      border-color: lighten($valid-value-color, 15%);
       border-width: 4px;
-      background: none;
     }
 
     &::-moz-focus-inner {
@@ -119,19 +124,18 @@
 
   &__number {
     display: inline-block;
-    width: 52px;
+    width: 45px;
     font-weight: 700;
-    padding: 0 10px;
-    padding-left: 8px;
-    text-align: right;
-    margin-top: auto;
-    margin-bottom: auto;
-    flex: 0 0 52px;
+    flex: 0 0 45px;
   }
 
-  &__vote__mark {
-    float: left;
-    line-height: 18px;
+  &__voted {
+    padding: 0 5px;
+    display: inline-block;
+
+    &__mark {
+      font-size: 18px;
+    }
   }
 
   &__footer {
@@ -208,7 +212,7 @@
     display: flex;
     align-items: center;
 
-    .poll__text {
+    .poll__option {
       flex: 0 0 auto;
       width: calc(100% - (23px + 6px));
       margin-right: 6px;
diff --git a/app/javascript/flavours/glitch/util/log_out.js b/app/javascript/flavours/glitch/util/log_out.js
index 8e1659293..42dcee03e 100644
--- a/app/javascript/flavours/glitch/util/log_out.js
+++ b/app/javascript/flavours/glitch/util/log_out.js
@@ -1,4 +1,4 @@
-import Rails from 'rails-ujs';
+import Rails from '@rails/ujs';
 import { signOutLink } from 'flavours/glitch/util/backend_links';
 
 export const logOut = () => {
diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js
index d4a824e2c..cb2c682a4 100644
--- a/app/javascript/mastodon/actions/accounts.js
+++ b/app/javascript/mastodon/actions/accounts.js
@@ -106,7 +106,7 @@ export function fetchAccount(id) {
       dispatch,
       getState,
       db.transaction('accounts', 'read').objectStore('accounts').index('id'),
-      id
+      id,
     ).then(() => db.close(), error => {
       db.close();
       throw error;
@@ -396,6 +396,7 @@ export function fetchFollowersFail(id, error) {
     type: FOLLOWERS_FETCH_FAIL,
     id,
     error,
+    skipNotFound: true,
   };
 };
 
@@ -482,6 +483,7 @@ export function fetchFollowingFail(id, error) {
     type: FOLLOWING_FETCH_FAIL,
     id,
     error,
+    skipNotFound: true,
   };
 };
 
@@ -571,6 +573,7 @@ export function fetchRelationshipsFail(error) {
     type: RELATIONSHIPS_FETCH_FAIL,
     error,
     skipLoading: true,
+    skipNotFound: true,
   };
 };
 
diff --git a/app/javascript/mastodon/actions/alerts.js b/app/javascript/mastodon/actions/alerts.js
index cd36d8007..1670f9c10 100644
--- a/app/javascript/mastodon/actions/alerts.js
+++ b/app/javascript/mastodon/actions/alerts.js
@@ -34,11 +34,11 @@ export function showAlert(title = messages.unexpectedTitle, message = messages.u
   };
 };
 
-export function showAlertForError(error) {
+export function showAlertForError(error, skipNotFound = false) {
   if (error.response) {
     const { data, status, statusText, headers } = error.response;
 
-    if (status === 404 || status === 410) {
+    if (skipNotFound && (status === 404 || status === 410)) {
       // Skip these errors as they are reflected in the UI
       return { type: ALERT_NOOP };
     }
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index c3c6ff1a1..6b73fc90e 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -230,12 +230,31 @@ export function uploadCompose(files) {
         // Account for disparity in size of original image and resized data
         total += file.size - f.size;
 
-        return api(getState).post('/api/v1/media', data, {
+        return api(getState).post('/api/v2/media', data, {
           onUploadProgress: function({ loaded }){
             progress[i] = loaded;
             dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
           },
-        }).then(({ data }) => dispatch(uploadComposeSuccess(data, f)));
+        }).then(({ status, data }) => {
+          // If server-side processing of the media attachment has not completed yet,
+          // poll the server until it is, before showing the media attachment as uploaded
+
+          if (status === 200) {
+            dispatch(uploadComposeSuccess(data, f));
+          } else if (status === 202) {
+            const poll = () => {
+              api(getState).get(`/api/v1/media/${data.id}`).then(response => {
+                if (response.status === 200) {
+                  dispatch(uploadComposeSuccess(response.data, f));
+                } else if (response.status === 206) {
+                  setTimeout(() => poll(), 1000);
+                }
+              }).catch(error => dispatch(uploadComposeFail(error)));
+            };
+
+            poll();
+          }
+        });
       }).catch(error => dispatch(uploadComposeFail(error)));
     };
   };
diff --git a/app/javascript/mastodon/actions/identity_proofs.js b/app/javascript/mastodon/actions/identity_proofs.js
index 449debf61..103983956 100644
--- a/app/javascript/mastodon/actions/identity_proofs.js
+++ b/app/javascript/mastodon/actions/identity_proofs.js
@@ -27,4 +27,5 @@ export const fetchAccountIdentityProofsFail = (accountId, err) => ({
   type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
   accountId,
   err,
+  skipNotFound: true,
 });
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index 054668655..cdd2111f8 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -149,6 +149,7 @@ export function expandTimelineFail(timeline, error, isLoadingMore) {
     timeline,
     error,
     skipLoading: !isLoadingMore,
+    skipNotFound: timeline.startsWith('account:'),
   };
 };
 
diff --git a/app/javascript/mastodon/common.js b/app/javascript/mastodon/common.js
index fba21316a..6818aa5d5 100644
--- a/app/javascript/mastodon/common.js
+++ b/app/javascript/mastodon/common.js
@@ -1,4 +1,4 @@
-import Rails from 'rails-ujs';
+import Rails from '@rails/ujs';
 
 export function start() {
   require('font-awesome/css/font-awesome.css');
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index ea82f9ef9..1bb583583 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -76,8 +76,9 @@ class ColumnHeader extends React.PureComponent {
 
   handlePin = () => {
     if (!this.props.pinned) {
-      this.historyBack();
+      this.context.router.history.replace('/');
     }
+
     this.props.onPin();
   }
 
diff --git a/app/javascript/mastodon/components/domain.js b/app/javascript/mastodon/components/domain.js
index 85729ca94..697065d87 100644
--- a/app/javascript/mastodon/components/domain.js
+++ b/app/javascript/mastodon/components/domain.js
@@ -5,7 +5,7 @@ import { defineMessages, injectIntl } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
 const messages = defineMessages({
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
 });
 
 export default @injectIntl
diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.js
index e453730ba..124b34b02 100644
--- a/app/javascript/mastodon/components/intersection_observer_article.js
+++ b/app/javascript/mastodon/components/intersection_observer_article.js
@@ -44,7 +44,7 @@ export default class IntersectionObserverArticle extends React.Component {
     intersectionObserverWrapper.observe(
       id,
       this.node,
-      this.handleIntersection
+      this.handleIntersection,
     );
 
     this.componentMounted = true;
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index cfe164a50..283d7e0a5 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -10,7 +10,7 @@ import { autoPlayGif, cropImages, displayMedia, useBlurhash } from '../initial_s
 import { decode } from 'blurhash';
 
 const messages = defineMessages({
-  toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },
+  toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Hide media' },
 });
 
 class Item extends React.PureComponent {
diff --git a/app/javascript/mastodon/components/poll.js b/app/javascript/mastodon/components/poll.js
index 3a17e80e7..7525a1030 100644
--- a/app/javascript/mastodon/components/poll.js
+++ b/app/javascript/mastodon/components/poll.js
@@ -127,15 +127,7 @@ class Poll extends ImmutablePureComponent {
 
     return (
       <li key={option.get('title')}>
-        {showResults && (
-          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
-            {({ width }) =>
-              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
-            }
-          </Motion>
-        )}
-
-        <label className={classNames('poll__text', { selectable: !showResults })}>
+        <label className={classNames('poll__option', { selectable: !showResults })}>
           <input
             name='vote-options'
             type={poll.get('multiple') ? 'checkbox' : 'radio'}
@@ -157,12 +149,26 @@ class Poll extends ImmutablePureComponent {
             />
           )}
           {showResults && <span className='poll__number'>
-            {!!voted && <Icon id='check' className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
             {Math.round(percent)}%
           </span>}
 
-          <span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
+          <span
+            className='poll__option__text'
+            dangerouslySetInnerHTML={{ __html: titleEmojified }}
+          />
+
+          {!!voted && <span className='poll__voted'>
+            <Icon id='check' className='poll__voted__mark' title={intl.formatMessage(messages.voted)} />
+          </span>}
         </label>
+
+        {showResults && (
+          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
+            {({ width }) =>
+              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
+            }
+          </Motion>
+        )}
       </li>
     );
   }
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js
index 3a490e78e..65ca43911 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -82,15 +82,19 @@ export default class ScrollableList extends PureComponent {
   lastScrollWasSynthetic = false;
   scrollToTopOnMouseIdle = false;
 
+  _getScrollingElement = () => {
+    if (this.props.bindToDocument) {
+      return (document.scrollingElement || document.body);
+    } else {
+      return this.node;
+    }
+  }
+
   setScrollTop = newScrollTop => {
     if (this.getScrollTop() !== newScrollTop) {
       this.lastScrollWasSynthetic = true;
 
-      if (this.props.bindToDocument) {
-        document.scrollingElement.scrollTop = newScrollTop;
-      } else {
-        this.node.scrollTop = newScrollTop;
-      }
+      this._getScrollingElement().scrollTop = newScrollTop;
     }
   };
 
@@ -151,15 +155,15 @@ export default class ScrollableList extends PureComponent {
   }
 
   getScrollTop = () => {
-    return this.props.bindToDocument ? document.scrollingElement.scrollTop : this.node.scrollTop;
+    return this._getScrollingElement().scrollTop;
   }
 
   getScrollHeight = () => {
-    return this.props.bindToDocument ? document.scrollingElement.scrollHeight : this.node.scrollHeight;
+    return this._getScrollingElement().scrollHeight;
   }
 
   getClientHeight = () => {
-    return this.props.bindToDocument ? document.scrollingElement.clientHeight : this.node.clientHeight;
+    return this._getScrollingElement().clientHeight;
   }
 
   updateScrollBottom = (snapshot) => {
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 0dc00cb98..075ee1b87 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -432,16 +432,10 @@ class Status extends ImmutablePureComponent {
               </a>
             </div>
 
-            <StatusContent status={status} onClick={this.handleClick} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} collapsable onCollapsedToggle={this.handleCollapsedToggle} />
+            <StatusContent status={status} onClick={this.handleClick} expanded={!status.get('hidden')} showThread={showThread} onExpandedToggle={this.handleExpandedToggle} collapsable onCollapsedToggle={this.handleCollapsedToggle} />
 
             {media}
 
-            {showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) && (
-              <button className='status__content__read-more-button' onClick={this.handleClick}>
-                <FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
-              </button>
-            )}
-
             <StatusActionBar status={status} account={account} {...other} />
           </div>
         </div>
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index e2c8d43c9..bebbbcb5a 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -36,8 +36,8 @@ const messages = defineMessages({
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
   admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
   copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
-  blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
   unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
 });
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index 5d921fd41..3200f2d82 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -20,6 +20,7 @@ export default class StatusContent extends React.PureComponent {
   static propTypes = {
     status: ImmutablePropTypes.map.isRequired,
     expanded: PropTypes.bool,
+    showThread: PropTypes.bool,
     onExpandedToggle: PropTypes.func,
     onClick: PropTypes.func,
     collapsable: PropTypes.bool,
@@ -181,6 +182,7 @@ export default class StatusContent extends React.PureComponent {
 
     const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden;
     const renderReadMore = this.props.onClick && status.get('collapsed');
+    const renderViewThread = this.props.showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']);
 
     const content = { __html: status.get('contentHtml') };
     const spoilerContent = { __html: status.get('spoilerHtml') };
@@ -195,6 +197,12 @@ export default class StatusContent extends React.PureComponent {
       directionStyle.direction = 'rtl';
     }
 
+    const showThreadButton = (
+      <button className='status__content__read-more-button' onClick={this.props.onClick}>
+        <FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
+      </button>
+    );
+
     const readMoreButton = (
       <button className='status__content__read-more-button' onClick={this.props.onClick} key='read-more'>
         <FormattedMessage id='status.read_more' defaultMessage='Read more' /><Icon id='angle-right' fixedWidth />
@@ -229,6 +237,8 @@ export default class StatusContent extends React.PureComponent {
           <div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''}`} style={directionStyle} dangerouslySetInnerHTML={content} />
 
           {!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
+
+          {renderViewThread && showThreadButton}
         </div>
       );
     } else if (this.props.onClick) {
@@ -237,6 +247,8 @@ export default class StatusContent extends React.PureComponent {
           <div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} />
 
           {!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
+
+          {renderViewThread && showThreadButton}
         </div>,
       ];
 
@@ -251,6 +263,8 @@ export default class StatusContent extends React.PureComponent {
           <div className='status__content__text status__content__text--visible' style={directionStyle} dangerouslySetInnerHTML={content} />
 
           {!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
+
+          {renderViewThread && showThreadButton}
         </div>
       );
     }
diff --git a/app/javascript/mastodon/containers/domain_container.js b/app/javascript/mastodon/containers/domain_container.js
index 813178bbf..8a8ba1df1 100644
--- a/app/javascript/mastodon/containers/domain_container.js
+++ b/app/javascript/mastodon/containers/domain_container.js
@@ -6,7 +6,7 @@ import Domain from '../components/domain';
 import { openModal } from '../actions/modal';
 
 const messages = defineMessages({
-  blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
+  blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' },
 });
 
 const makeMapStateToProps = () => {
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 8bd7f2db5..92780a70b 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -29,8 +29,8 @@ const messages = defineMessages({
   report: { id: 'account.report', defaultMessage: 'Report @{name}' },
   share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
   media: { id: 'account.media', defaultMessage: 'Media' },
-  blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
   hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' },
   showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' },
   pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' },
@@ -39,7 +39,7 @@ const messages = defineMessages({
   favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
   lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
   blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
-  domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' },
+  domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' },
   mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
   endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
   unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
@@ -142,7 +142,7 @@ class Header extends ImmutablePureComponent {
     if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) {
       info.push(<span key='muted' className='relationship-tag'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>);
     } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) {
-      info.push(<span key='domain_blocked' className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain hidden' /></span>);
+      info.push(<span key='domain_blocked' className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain blocked' /></span>);
     }
 
     if (me !== account.get('id')) {
diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js
index fda5a074f..95c9c7751 100644
--- a/app/javascript/mastodon/features/audio/index.js
+++ b/app/javascript/mastodon/features/audio/index.js
@@ -214,8 +214,8 @@ class Audio extends React.PureComponent {
         <div className='video-player__controls active'>
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
-              <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
 
               <div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
                 &nbsp;
@@ -236,7 +236,7 @@ class Audio extends React.PureComponent {
             </div>
 
             <div className='video-player__buttons right'>
-              <button type='button' aria-label={intl.formatMessage(messages.download)}>
+              <button type='button' title={intl.formatMessage(messages.download)} aria-label={intl.formatMessage(messages.download)}>
                 <a className='video-player__download__icon' href={this.props.src} download>
                   <Icon id={'download'} fixedWidth />
                 </a>
diff --git a/app/javascript/mastodon/features/blocks/index.js b/app/javascript/mastodon/features/blocks/index.js
index 051431ed2..870c0de09 100644
--- a/app/javascript/mastodon/features/blocks/index.js
+++ b/app/javascript/mastodon/features/blocks/index.js
@@ -68,7 +68,7 @@ class Blocks extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} />
+            <AccountContainer key={id} id={id} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/compose/components/action_bar.js b/app/javascript/mastodon/features/compose/components/action_bar.js
index dd2632796..07d92bb7e 100644
--- a/app/javascript/mastodon/features/compose/components/action_bar.js
+++ b/app/javascript/mastodon/features/compose/components/action_bar.js
@@ -16,6 +16,7 @@ const messages = defineMessages({
   mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
   filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
   logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
+  bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
 });
 
 export default @injectIntl
@@ -42,6 +43,7 @@ class ActionBar extends React.PureComponent {
     menu.push(null);
     menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
     menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
+    menu.push({ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' });
     menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
     menu.push(null);
     menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
diff --git a/app/javascript/mastodon/features/compose/components/poll_form.js b/app/javascript/mastodon/features/compose/components/poll_form.js
index cac3776bb..271019dfe 100644
--- a/app/javascript/mastodon/features/compose/components/poll_form.js
+++ b/app/javascript/mastodon/features/compose/components/poll_form.js
@@ -75,7 +75,7 @@ class Option extends React.PureComponent {
 
     return (
       <li>
-        <label className='poll__text editable'>
+        <label className='poll__option editable'>
           <span
             className={classNames('poll__input', { checkbox: isPollMultiple })}
             onClick={this.handleToggleMultiple}
@@ -155,6 +155,7 @@ class PollForm extends ImmutablePureComponent {
         <div className='poll__footer'>
           <button disabled={options.size >= 5} className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
 
+          {/* eslint-disable-next-line jsx-a11y/no-onchange */}
           <select value={expiresIn} onChange={this.handleSelectDuration}>
             <option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>
             <option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
index 7cbfe463a..de030b7a2 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
@@ -11,13 +11,13 @@ import Icon from 'mastodon/components/icon';
 
 const messages = defineMessages({
   public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
-  public_long: { id: 'privacy.public.long', defaultMessage: 'Post to public timelines' },
+  public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for all, shown in public timelines' },
   unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
-  unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Do not show in public timelines' },
+  unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Visible for all, but not in public timelines' },
   private_short: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
-  private_long: { id: 'privacy.private.long', defaultMessage: 'Post to followers only' },
+  private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for followers only' },
   direct_short: { id: 'privacy.direct.short', defaultMessage: 'Direct' },
-  direct_long: { id: 'privacy.direct.long', defaultMessage: 'Post to mentioned users only' },
+  direct_long: { id: 'privacy.direct.long', defaultMessage: 'Visible for mentioned users only' },
   change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' },
 });
 
diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.js b/app/javascript/mastodon/features/direct_timeline/components/conversation.js
index 235cb7ad8..f9e45067f 100644
--- a/app/javascript/mastodon/features/direct_timeline/components/conversation.js
+++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.js
@@ -160,7 +160,7 @@ class Conversation extends ImmutablePureComponent {
     return (
       <HotKeys handlers={handlers}>
         <div className={classNames('conversation focusable muted', { 'conversation--unread': unread })} tabIndex='0'>
-          <div className='conversation__avatar'>
+          <div className='conversation__avatar' onClick={this.handleClick} role='presentation'>
             <AvatarComposite accounts={accounts} size={48} />
           </div>
 
diff --git a/app/javascript/mastodon/features/domain_blocks/index.js b/app/javascript/mastodon/features/domain_blocks/index.js
index 482245c86..a6d988912 100644
--- a/app/javascript/mastodon/features/domain_blocks/index.js
+++ b/app/javascript/mastodon/features/domain_blocks/index.js
@@ -13,8 +13,8 @@ import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_bloc
 import ScrollableList from '../../components/scrollable_list';
 
 const messages = defineMessages({
-  heading: { id: 'column.domain_blocks', defaultMessage: 'Hidden domains' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
 });
 
 const mapStateToProps = state => ({
@@ -55,7 +55,7 @@ class Blocks extends ImmutablePureComponent {
       );
     }
 
-    const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no hidden domains yet.' />;
+    const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />;
 
     return (
       <Column bindToDocument={!multiColumn} icon='minus-circle' heading={intl.formatMessage(messages.heading)}>
@@ -69,7 +69,7 @@ class Blocks extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {domains.map(domain =>
-            <DomainContainer key={domain} domain={domain} />
+            <DomainContainer key={domain} domain={domain} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/favourites/index.js b/app/javascript/mastodon/features/favourites/index.js
index 249e6a044..75cb00c0e 100644
--- a/app/javascript/mastodon/features/favourites/index.js
+++ b/app/javascript/mastodon/features/favourites/index.js
@@ -79,7 +79,7 @@ class Favourites extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/follow_requests/index.js b/app/javascript/mastodon/features/follow_requests/index.js
index 57ef44145..7078e4e6c 100644
--- a/app/javascript/mastodon/features/follow_requests/index.js
+++ b/app/javascript/mastodon/features/follow_requests/index.js
@@ -11,6 +11,7 @@ import ColumnBackButtonSlim from '../../components/column_back_button_slim';
 import AccountAuthorizeContainer from './containers/account_authorize_container';
 import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
 import ScrollableList from '../../components/scrollable_list';
+import { me } from '../../initial_state';
 
 const messages = defineMessages({
   heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' },
@@ -19,6 +20,8 @@ const messages = defineMessages({
 const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
   hasMore: !!state.getIn(['user_lists', 'follow_requests', 'next']),
+  locked: !!state.getIn(['accounts', me, 'locked']),
+  domain: state.getIn(['meta', 'domain']),
 });
 
 export default @connect(mapStateToProps)
@@ -31,6 +34,8 @@ class FollowRequests extends ImmutablePureComponent {
     shouldUpdateScroll: PropTypes.func,
     hasMore: PropTypes.bool,
     accountIds: ImmutablePropTypes.list,
+    locked: PropTypes.bool,
+    domain: PropTypes.string,
     intl: PropTypes.object.isRequired,
     multiColumn: PropTypes.bool,
   };
@@ -44,7 +49,7 @@ class FollowRequests extends ImmutablePureComponent {
   }, 300, { leading: true });
 
   render () {
-    const { intl, shouldUpdateScroll, accountIds, hasMore, multiColumn } = this.props;
+    const { intl, shouldUpdateScroll, accountIds, hasMore, multiColumn, locked, domain } = this.props;
 
     if (!accountIds) {
       return (
@@ -55,6 +60,15 @@ class FollowRequests extends ImmutablePureComponent {
     }
 
     const emptyMessage = <FormattedMessage id='empty_column.follow_requests' defaultMessage="You don't have any follow requests yet. When you receive one, it will show up here." />;
+    const unlockedPrependMessage = locked ? null : (
+      <div className='follow_requests-unlocked_explanation'>
+        <FormattedMessage
+          id='follow_requests.unlocked_explanation'
+          defaultMessage='Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.'
+          values={{ domain: domain }}
+        />
+      </div>
+    );
 
     return (
       <Column bindToDocument={!multiColumn} icon='user-plus' heading={intl.formatMessage(messages.heading)}>
@@ -66,9 +80,10 @@ class FollowRequests extends ImmutablePureComponent {
           shouldUpdateScroll={shouldUpdateScroll}
           emptyMessage={emptyMessage}
           bindToDocument={!multiColumn}
+          prepend={unlockedPrependMessage}
         >
           {accountIds.map(id =>
-            <AccountAuthorizeContainer key={id} id={id} />
+            <AccountAuthorizeContainer key={id} id={id} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js
index 9e635d250..f8723e055 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.js
@@ -93,7 +93,7 @@ class Followers extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {blockedBy ? [] : accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js
index 284ae2c11..5112bfa9d 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.js
@@ -93,7 +93,7 @@ class Following extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {blockedBy ? [] : accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.js b/app/javascript/mastodon/features/getting_started/components/announcements.js
index 91cf6215e..1896994da 100644
--- a/app/javascript/mastodon/features/getting_started/components/announcements.js
+++ b/app/javascript/mastodon/features/getting_started/components/announcements.js
@@ -95,6 +95,10 @@ class Content extends ImmutablePureComponent {
       } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
         link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
       } else {
+        let status = this.props.announcement.get('statuses').find(item => link.href === item.get('url'));
+        if (status) {
+          link.addEventListener('click', this.onStatusClick.bind(this, status), false);
+        }
         link.setAttribute('title', link.href);
         link.classList.add('unhandled-link');
       }
@@ -120,6 +124,13 @@ class Content extends ImmutablePureComponent {
     }
   }
 
+  onStatusClick = (status, e) => {
+    if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${status.get('id')}`);
+    }
+  }
+
   handleEmojiMouseEnter = ({ target }) => {
     target.src = target.getAttribute('data-original');
   }
@@ -367,6 +378,14 @@ class Announcements extends ImmutablePureComponent {
     index: 0,
   };
 
+  static getDerivedStateFromProps(props, state) {
+    if (props.announcements.size > 0 && state.index >= props.announcements.size) {
+      return { index: props.announcements.size - 1 };
+    } else {
+      return null;
+    }
+  }
+
   componentDidMount () {
     this._markAnnouncementAsRead();
   }
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index adbc147d1..d9838e1c7 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -106,20 +106,20 @@ class GettingStarted extends ImmutablePureComponent {
 
       if (profile_directory) {
         navItems.push(
-          <ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />
+          <ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />,
         );
 
         height += 48;
       }
 
       navItems.push(
-        <ColumnSubheading key={i++} text={intl.formatMessage(messages.personal)} />
+        <ColumnSubheading key={i++} text={intl.formatMessage(messages.personal)} />,
       );
 
       height += 34;
     } else if (profile_directory) {
       navItems.push(
-        <ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />
+        <ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />,
       );
 
       height += 48;
@@ -129,7 +129,7 @@ class GettingStarted extends ImmutablePureComponent {
       <ColumnLink key={i++} icon='envelope' text={intl.formatMessage(messages.direct)} to='/timelines/direct' />,
       <ColumnLink key={i++} icon='bookmark' text={intl.formatMessage(messages.bookmarks)} to='/bookmarks' />,
       <ColumnLink key={i++} icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
-      <ColumnLink key={i++} icon='list-ul' text={intl.formatMessage(messages.lists)} to='/lists' />
+      <ColumnLink key={i++} icon='list-ul' text={intl.formatMessage(messages.lists)} to='/lists' />,
     );
 
     height += 48*4;
diff --git a/app/javascript/mastodon/features/lists/index.js b/app/javascript/mastodon/features/lists/index.js
index 7f7f5009c..ca1fa1f5e 100644
--- a/app/javascript/mastodon/features/lists/index.js
+++ b/app/javascript/mastodon/features/lists/index.js
@@ -74,7 +74,7 @@ class Lists extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {lists.map(list =>
-            <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />
+            <ColumnLink key={list.get('id')} to={`/timelines/list/${list.get('id')}`} icon='list-ul' text={list.get('title')} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/mutes/index.js b/app/javascript/mastodon/features/mutes/index.js
index 91dd268c1..3f58a62d2 100644
--- a/app/javascript/mastodon/features/mutes/index.js
+++ b/app/javascript/mastodon/features/mutes/index.js
@@ -68,7 +68,7 @@ class Mutes extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} />
+            <AccountContainer key={id} id={id} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/reblogs/index.js b/app/javascript/mastodon/features/reblogs/index.js
index 9179e51db..4becb5fb7 100644
--- a/app/javascript/mastodon/features/reblogs/index.js
+++ b/app/javascript/mastodon/features/reblogs/index.js
@@ -79,7 +79,7 @@ class Reblogs extends ImmutablePureComponent {
           bindToDocument={!multiColumn}
         >
           {accountIds.map(id =>
-            <AccountContainer key={id} id={id} withNote={false} />
+            <AccountContainer key={id} id={id} withNote={false} />,
           )}
         </ScrollableList>
       </Column>
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js
index 959774da4..ba62d7b10 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.js
@@ -32,8 +32,8 @@ const messages = defineMessages({
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
   admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
   copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
-  blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' },
-  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
+  blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
+  unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
   unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
 });
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js
index 2993fe29a..b8344a667 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.js
@@ -98,7 +98,7 @@ export default class Card extends React.PureComponent {
           },
         },
       ]),
-      0
+      0,
     );
   };
 
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index 2fec247c1..7a82fa13a 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -166,7 +166,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
       reblogIcon = 'lock';
     }
 
-    if (status.get('visibility') === 'private') {
+    if (['private', 'direct'].includes(status.get('visibility'))) {
       reblogLink = <Icon id={reblogIcon} />;
     } else if (this.context.router) {
       reblogLink = (
diff --git a/app/javascript/mastodon/features/ui/components/__tests__/column-test.js b/app/javascript/mastodon/features/ui/components/__tests__/column-test.js
index 11cc1b6e8..89cb2458d 100644
--- a/app/javascript/mastodon/features/ui/components/__tests__/column-test.js
+++ b/app/javascript/mastodon/features/ui/components/__tests__/column-test.js
@@ -19,7 +19,7 @@ describe('<Column />', () => {
       const wrapper = mount(
         <Column heading='notifications'>
           <div className='scrollable' />
-        </Column>
+        </Column>,
       );
       wrapper.find(ColumnHeader).find('button').simulate('click');
       expect(global.requestAnimationFrame.mock.calls.length).toEqual(1);
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 8ac9c8db7..42ded9d21 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -492,8 +492,8 @@ class Video extends React.PureComponent {
 
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
-              <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
 
               <div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
                 &nbsp;
@@ -517,11 +517,11 @@ class Video extends React.PureComponent {
             </div>
 
             <div className='video-player__buttons right'>
-              {(!onCloseVideo && !editable && !fullscreen) && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
-              {(!fullscreen && onOpenVideo) && <button type='button' aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
-              {onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
-              <button type='button' aria-label={intl.formatMessage(messages.download)}><a className='video-player__download__icon' href={this.props.src} download><Icon id={'download'} fixedWidth /></a></button>
-              <button type='button' aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
+              {(!onCloseVideo && !editable && !fullscreen) && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
+              {(!fullscreen && onOpenVideo) && <button type='button' title={intl.formatMessage(messages.expand)} aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
+              {onCloseVideo && <button type='button' title={intl.formatMessage(messages.close)} aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
+              <button type='button' title={intl.formatMessage(messages.download)} aria-label={intl.formatMessage(messages.download)}><a className='video-player__download__icon' href={this.props.src} download><Icon id={'download'} fixedWidth /></a></button>
+              <button type='button' title={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
             </div>
           </div>
         </div>
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index 8006a1306..38653e0fe 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -123,7 +123,7 @@
   "directory.federated": "Dende'l fediversu",
   "directory.local": "Dende {domain} namái",
   "directory.new_arrivals": "Cuentes nueves",
-  "directory.recently_active": "Recently active",
+  "directory.recently_active": "Actividá recién",
   "embed.instructions": "Empotra esti estáu nun sitiu web copiando'l códigu d'embaxo.",
   "embed.preview": "Asina ye cómo va vese:",
   "emoji_button.activity": "Actividaes",
@@ -154,7 +154,7 @@
   "empty_column.home": "¡Tienes la llinia temporal balera! Visita {public} o usa la gueta pa entamar y conocer a otros usuarios.",
   "empty_column.home.public_timeline": "la llinia temporal pública",
   "empty_column.list": "Entá nun hai nada nesta llista. Cuando los miembros d'esta llista espublicen estaos nuevos, van apaecer equí.",
-  "empty_column.lists": "Entá nun tienes nunenguna llista. Cuando crees una, va amosase equí.",
+  "empty_column.lists": "Entá nun tienes nenguna llista. Cuando crees una, va amosase equí.",
   "empty_column.mutes": "Entá nun silenciesti a nunengún usuariu.",
   "empty_column.notifications": "Entá nun tienes nunengún avisu. Interactúa con otros p'aniciar la conversación.",
   "empty_column.public": "¡Equí nun hai nada! Escribi daqué público o sigui a usuarios d'otros sirvidores pa rellenar esto",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index 5429f358f..c1a7bb533 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Зареждане...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json
index 96092457f..19a091fa0 100644
--- a/app/javascript/mastodon/locales/br.json
+++ b/app/javascript/mastodon/locales/br.json
@@ -1,64 +1,64 @@
 {
-  "account.add_or_remove_from_list": "Ouzhpenn pe lemel ag ar listennadoù",
+  "account.add_or_remove_from_list": "Ouzhpenn pe dilemel eus al listennadoù",
   "account.badges.bot": "Robot",
   "account.badges.group": "Strollad",
-  "account.block": "Stankañ @{name}",
-  "account.block_domain": "Kuzh kement tra a {domain}",
+  "account.block": "Berzañ @{name}",
+  "account.block_domain": "Berzañ pep tra eus {domain}",
   "account.blocked": "Stanket",
-  "account.cancel_follow_request": "Nullañ ar pedad heuliañ",
-  "account.direct": "Kas ur c'hemennad da @{name}",
-  "account.domain_blocked": "Domani kuzhet",
+  "account.cancel_follow_request": "Nullañ ar bedadenn heuliañ",
+  "account.direct": "Kas ur gemennadenn da @{name}",
+  "account.domain_blocked": "Domani berzet",
   "account.edit_profile": "Aozañ ar profil",
   "account.endorse": "Lakaat war-wel war ar profil",
   "account.follow": "Heuliañ",
-  "account.followers": "Heilour·ezed·ion",
-  "account.followers.empty": "Den na heul an implijour-mañ c'hoazh.",
+  "account.followers": "Heulier·ezed·ien",
+  "account.followers.empty": "Den na heul an implijer-mañ c'hoazh.",
   "account.follows": "Koumanantoù",
-  "account.follows.empty": "An implijer-mañ na heul ket den ebet.",
+  "account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
   "account.follows_you": "Ho heul",
-  "account.hide_reblogs": "Kuzh toudoù skignet gant @{name}",
+  "account.hide_reblogs": "Kuzh toudoù rannet gant @{name}",
   "account.last_status": "Oberiantiz zivezhañ",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.link_verified_on": "Gwiriet eo bet perc'hennidigezh al liamm d'an deiziad-mañ : {date}",
+  "account.locked_info": "Prennet eo ar gon-mañ. Dibab a ra ar perc'henn ar re a c'hall heuliañ anezhi pe anezhañ.",
   "account.media": "Media",
   "account.mention": "Menegiñ @{name}",
-  "account.moved_to": "Dilojet en·he deus {name} da:",
+  "account.moved_to": "Dilojet en·he deus {name} da :",
   "account.mute": "Kuzhat @{name}",
-  "account.mute_notifications": "Kuzh kemennoù a @{name}",
+  "account.mute_notifications": "Kuzh kemennoù eus @{name}",
   "account.muted": "Kuzhet",
   "account.never_active": "Birviken",
-  "account.posts": "Toudoù",
+  "account.posts": "a doudoù",
   "account.posts_with_replies": "Toudoù ha respontoù",
   "account.report": "Disklêriañ @{name}",
-  "account.requested": "É c'hortoz bout aprouet. Clikit da nullañ ar pedad heuliañ",
+  "account.requested": "O c'hortoz an asant. Klikit evit nullañ ar goulenn heuliañ",
   "account.share": "Skignañ profil @{name}",
-  "account.show_reblogs": "Diskouez toudoù a @{name}",
-  "account.unblock": "Distankañ @{name}",
-  "account.unblock_domain": "Diguzh {domain}",
+  "account.show_reblogs": "Diskouez skignadennoù @{name}",
+  "account.unblock": "Diverzañ @{name}",
+  "account.unblock_domain": "Diverzañ an domani {domain}",
   "account.unendorse": "Paouez da lakaat war-wel war ar profil",
   "account.unfollow": "Diheuliañ",
   "account.unmute": "Diguzhat @{name}",
   "account.unmute_notifications": "Diguzhat kemennoù a @{name}",
   "alert.rate_limited.message": "Klaskit en-dro a-benn {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Rate limited",
+  "alert.rate_limited.title": "Feur bevennet",
   "alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.",
-  "alert.unexpected.title": "C'hem !",
+  "alert.unexpected.title": "Hopala!",
   "announcement.announcement": "Kemenn",
   "autosuggest_hashtag.per_week": "{count} bep sizhun",
   "boost_modal.combo": "Ar wezh kentañ e c'halliot gwaskañ war {combo} evit tremen hebiou",
-  "bundle_column_error.body": "Something went wrong while loading this component.",
-  "bundle_column_error.retry": "Klask endro",
+  "bundle_column_error.body": "Degouezhet ez eus bet ur fazi en ur gargañ an elfenn-mañ.",
+  "bundle_column_error.retry": "Klask en-dro",
   "bundle_column_error.title": "Fazi rouedad",
   "bundle_modal_error.close": "Serriñ",
-  "bundle_modal_error.message": "Something went wrong while loading this component.",
-  "bundle_modal_error.retry": "Klask endro",
-  "column.blocks": "Implijour·ezed·ion stanket",
+  "bundle_modal_error.message": "Degouezhet ez eus bet ur fazi en ur gargañ an elfenn-mañ.",
+  "bundle_modal_error.retry": "Klask en-dro",
+  "column.blocks": "Implijer·ezed·ien berzet",
   "column.bookmarks": "Sinedoù",
   "column.community": "Red-amzer lec'hel",
   "column.direct": "Kemennadoù prevez",
   "column.directory": "Mont a-dreuz ar profiloù",
-  "column.domain_blocks": "Domani kuzhet",
-  "column.favourites": "Ar re vuiañ-karet",
+  "column.domain_blocks": "Domani berzet",
+  "column.favourites": "Muiañ-karet",
   "column.follow_requests": "Pedadoù heuliañ",
   "column.home": "Degemer",
   "column.lists": "Listennoù",
@@ -68,150 +68,150 @@
   "column.public": "Red-amzer kevreet",
   "column_back_button.label": "Distro",
   "column_header.hide_settings": "Kuzhat an arventennoù",
-  "column_header.moveLeft_settings": "Move column to the left",
-  "column_header.moveRight_settings": "Move column to the right",
+  "column_header.moveLeft_settings": "Dilec'hiañ ar bannad a-gleiz",
+  "column_header.moveRight_settings": "Dilec'hiañ ar bannad a-zehou",
   "column_header.pin": "Spilhennañ",
   "column_header.show_settings": "Diskouez an arventennoù",
   "column_header.unpin": "Dispilhennañ",
   "column_subheading.settings": "Arventennoù",
   "community.column_settings.media_only": "Nemet Mediaoù",
-  "compose_form.direct_message_warning": "An toud-mañ a vo kaset nemet d'an implijer·ion·ezed meneget.",
-  "compose_form.direct_message_warning_learn_more": "Gouiet hiroc'h",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
-  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
+  "compose_form.direct_message_warning": "An toud-mañ a vo kaset nemet d'an implijer·ezed·ien meneget.",
+  "compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h",
+  "compose_form.hashtag_warning": "Ne vo ket lakaet an toud-mañ er rolloù gerioù-klik dre mard eo anlistennet. N'eus nemet an toudoù foran a c'hall bezañ klasket dre c'her-klik.",
+  "compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal heuliañ ac'hanoc'h evit gwelout ho toudoù prevez.",
   "compose_form.lock_disclaimer.lock": "prennet",
   "compose_form.placeholder": "Petra eh oc'h é soñjal a-barzh ?",
   "compose_form.poll.add_option": "Ouzhpenniñ un dibab",
-  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.duration": "Pad ar sontadeg",
   "compose_form.poll.option_placeholder": "Dibab {number}",
   "compose_form.poll.remove_option": "Lemel an dibab-mañ",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "Kemmañ ar sontadeg evit aotren meur a zibab",
+  "compose_form.poll.switch_to_single": "Kemmañ ar sontadeg evit aotren un dibab hepken",
   "compose_form.publish": "Toudañ",
   "compose_form.publish_loud": "{publish} !",
-  "compose_form.sensitive.hide": "Mark media as sensitive",
-  "compose_form.sensitive.marked": "Media is marked as sensitive",
-  "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
-  "compose_form.spoiler.marked": "Text is hidden behind warning",
+  "compose_form.sensitive.hide": "Merkañ ar media evel kizidik",
+  "compose_form.sensitive.marked": "Merket eo ar media evel kizidik",
+  "compose_form.sensitive.unmarked": "N'eo ket merket ar media evel kizidik",
+  "compose_form.spoiler.marked": "Kuzhet eo an destenn a-dreñv ur c'hemenn",
   "compose_form.spoiler.unmarked": "N'eo ket kuzhet an destenn",
-  "compose_form.spoiler_placeholder": "Write your warning here",
+  "compose_form.spoiler_placeholder": "Skrivit ho kemenn amañ",
   "confirmation_modal.cancel": "Nullañ",
-  "confirmations.block.block_and_report": "Block & Report",
-  "confirmations.block.confirm": "Block",
-  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.block.block_and_report": "Berzañ ha Disklêriañ",
+  "confirmations.block.confirm": "Stankañ",
+  "confirmations.block.message": "Ha sur oc'h e fell deoc'h stankañ {name} ?",
   "confirmations.delete.confirm": "Dilemel",
-  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?",
   "confirmations.delete_list.confirm": "Dilemel",
   "confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?",
-  "confirmations.domain_block.confirm": "Kuzhat an domani a-bezh",
-  "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.domain_block.confirm": "Berzañ an domani a-bezh",
+  "confirmations.domain_block.message": "Ha sur oc'h e fell deoc'h berzañ an {domain} a-bezh? Peurvuiañ eo trawalc'h berzañ pe mudañ un nebeud implijer·ezed·ien. Ne welot danvez ebet o tont eus an domani-mañ. Dilamet e vo ar c'houmanantoù war an domani-mañ.",
   "confirmations.logout.confirm": "Digevreañ",
-  "confirmations.logout.message": "Are you sure you want to log out?",
+  "confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?",
   "confirmations.mute.confirm": "Kuzhat",
-  "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.explanation": "Kuzhat a raio an toudoù skrivet gantañ·i hag ar re a veneg anezhañ·i, met aotren a raio anezhañ·i da welet ho todoù ha a heuliañ ac'hanoc'h.",
   "confirmations.mute.message": "Ha sur oc'h e fell deoc'h kuzhaat {name} ?",
   "confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
+  "confirmations.redraft.message": "Ha sur oc'h e fell deoc'h dilemel ar statud-mañ hag adlakaat anezhañ er bouilhoñs? Kollet e vo ar merkoù muiañ-karet hag ar skignadennoù hag emzivat e vo ar respontoù d'an toud orin.",
   "confirmations.reply.confirm": "Respont",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.reply.message": "Respont bremañ a zilamo ar gemennadenn emaoc'h o skrivañ. Sur e oc'h e fell deoc'h kenderc'hel ganti?",
   "confirmations.unfollow.confirm": "Diheuliañ",
-  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
-  "conversation.delete": "Delete conversation",
-  "conversation.mark_as_read": "Mark as read",
-  "conversation.open": "View conversation",
-  "conversation.with": "With {names}",
-  "directory.federated": "From known fediverse",
-  "directory.local": "From {domain} only",
-  "directory.new_arrivals": "New arrivals",
-  "directory.recently_active": "Recently active",
-  "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
-  "emoji_button.activity": "Activity",
-  "emoji_button.custom": "Custom",
-  "emoji_button.flags": "Flags",
-  "emoji_button.food": "Food & Drink",
-  "emoji_button.label": "Insert emoji",
-  "emoji_button.nature": "Nature",
-  "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
-  "emoji_button.objects": "Objects",
-  "emoji_button.people": "People",
-  "emoji_button.recent": "Frequently used",
-  "emoji_button.search": "Search...",
-  "emoji_button.search_results": "Search results",
-  "emoji_button.symbols": "Symbols",
-  "emoji_button.travel": "Travel & Places",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.account_unavailable": "Profile unavailable",
-  "empty_column.blocks": "You haven't blocked any users yet.",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
-  "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
-  "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.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
-  "empty_column.home.public_timeline": "the public timeline",
-  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
-  "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.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
-  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
-  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
-  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
-  "errors.unexpected_crash.report_issue": "Report issue",
-  "follow_request.authorize": "Authorize",
-  "follow_request.reject": "Reject",
-  "getting_started.developers": "Developers",
-  "getting_started.directory": "Profile directory",
-  "getting_started.documentation": "Documentation",
-  "getting_started.heading": "Getting started",
-  "getting_started.invite": "Invite people",
+  "confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name}?",
+  "conversation.delete": "Dilemel ar gaozeadenn",
+  "conversation.mark_as_read": "Merkañ evel lennet",
+  "conversation.open": "Gwelout ar gaozeadenn",
+  "conversation.with": "Gant {names}",
+  "directory.federated": "Eus ar c'hevrebed anavezet",
+  "directory.local": "Eus {domain} hepken",
+  "directory.new_arrivals": "Degouezhet a-nevez",
+  "directory.recently_active": "Oberiant nevez zo",
+  "embed.instructions": "Enkorfit ar statud war ho lec'hienn en ur eilañ ar c'hod dindan.",
+  "embed.preview": "Setu penaos e vo diskouezet:",
+  "emoji_button.activity": "Obererezh",
+  "emoji_button.custom": "Kempennet",
+  "emoji_button.flags": "Bannieloù",
+  "emoji_button.food": "Boued hag Evaj",
+  "emoji_button.label": "Enlakaat un emoji",
+  "emoji_button.nature": "Natur",
+  "emoji_button.not_found": "Emoji ebet !! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.objects": "Traoù",
+  "emoji_button.people": "Tud",
+  "emoji_button.recent": "Implijet alies",
+  "emoji_button.search": "O klask...",
+  "emoji_button.search_results": "Disoc'hoù an enklask",
+  "emoji_button.symbols": "Arouezioù",
+  "emoji_button.travel": "Lec'hioù ha Beajoù",
+  "empty_column.account_timeline": "Toud ebet amañ!",
+  "empty_column.account_unavailable": "Profil dihegerz",
+  "empty_column.blocks": "N'eus ket bet berzet implijer·ez ganeoc'h c'hoazh.",
+  "empty_column.bookmarked_statuses": "N'ho peus toud ebet enrollet en ho sinedoù c'hoazh. Pa vo ouzhpennet unan ganeoc'h e teuio war wel amañ.",
+  "empty_column.community": "Goulo eo ar red-amzer lec'hel. Skrivit'ta un dra evit lakaat tan dezhi !",
+  "empty_column.direct": "N'ho peus kemennad prevez ebet c'hoazh. Pa vo resevet pe kaset unan ganeoc'h e teuio war wel amañ.",
+  "empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.",
+  "empty_column.favourited_statuses": "N'ho peus toud muiañ-karet ebet c'hoazh. Pa vo lakaet unan ganeoc'h e vo diskouezet amañ.",
+  "empty_column.favourites": "Den ebet n'eus lakaet an toud-mañ en e reoù muiañ-karet. Pa vo graet gant unan bennak e vo diskouezet amañ.",
+  "empty_column.follow_requests": "N'ho peus goulenn heuliañ ebet c'hoazh. Pa resevot reoù e vo diskouezet amañ.",
+  "empty_column.hashtag": "N'eus netra er ger-klik-mañ c'hoazh.",
+  "empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.",
+  "empty_column.home.public_timeline": "ar red-amzer publik",
+  "empty_column.list": "Goullo eo ar roll-mañ evit ar poent. Pa vo toudet gant e izili e vo diskouezet amañ.",
+  "empty_column.lists": "N'ho peus roll ebet c'hoazh. Pa vo krouet unan ganeoc'h e vo diskouezet amañ.",
+  "empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.",
+  "empty_column.notifications": "N'ho peus kemenn ebet c'hoazh. Grit gant implijer·ezed·ien all evit loc'hañ ar gomz.",
+  "empty_column.public": "N'eus netra amañ! Skrivit un dra bennak foran pe heuilhit implijer·ien·ezed eus dafariadoù all evit leuniañ",
+  "error.unexpected_crash.explanation": "Abalamour d'ur beug en hor c'hod pe d'ur gudenn geverlec'hded n'hallomp ket skrammañ ar bajenn-mañ en un doare dereat.",
+  "error.unexpected_crash.next_steps": "Klaskit azbevaat ar bajenn. Ma n'a ket en-dro e c'hallit klask ober gant Mastodon dre ur merdeer disheñvel pe dre an arload genidik.",
+  "errors.unexpected_crash.copy_stacktrace": "Eilañ ar roudoù diveugañ er golver",
+  "errors.unexpected_crash.report_issue": "Danevellañ ur fazi",
+  "follow_request.authorize": "Aotren",
+  "follow_request.reject": "Nac'hañ",
+  "getting_started.developers": "Diorroerien",
+  "getting_started.directory": "Roll ar profiloù",
+  "getting_started.documentation": "Teuliadur",
+  "getting_started.heading": "Loc'hañ",
+  "getting_started.invite": "Pediñ tud",
   "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
-  "getting_started.security": "Security",
-  "getting_started.terms": "Terms of service",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.select.no_options_message": "No suggestions found",
-  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
+  "getting_started.security": "Arventennoù ar gont",
+  "getting_started.terms": "Divizoù gwerzhañ hollek",
+  "hashtag.column_header.tag_mode.all": "ha {additional}",
+  "hashtag.column_header.tag_mode.any": "pe {additional}",
+  "hashtag.column_header.tag_mode.none": "hep {additional}",
+  "hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet",
+  "hashtag.column_settings.select.placeholder": "Ouzhpennañ gerioù-klik…",
+  "hashtag.column_settings.tag_mode.all": "An holl elfennoù-mañ",
+  "hashtag.column_settings.tag_mode.any": "Unan e mesk anezho",
+  "hashtag.column_settings.tag_mode.none": "Hini ebet anezho",
+  "hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ",
+  "home.column_settings.basic": "Diazez",
+  "home.column_settings.show_reblogs": "Diskouez ar skignadennoù",
+  "home.column_settings.show_replies": "Diskouez ar respontoù",
   "home.hide_announcements": "Hide announcements",
   "home.show_announcements": "Show announcements",
-  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
-  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
-  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
+  "intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}",
+  "intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}",
+  "intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}",
+  "introduction.federation.action": "Da-heul",
+  "introduction.federation.federated.headline": "Kevreet",
   "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.headline": "Degemer",
   "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": "Local",
+  "introduction.federation.local.headline": "Lec'hel",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
   "introduction.interactions.action": "Finish toot-orial!",
-  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.favourite.headline": "Muiañ-karet",
   "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
-  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.headline": "Skignañ",
   "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
-  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.headline": "Respont",
   "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
-  "introduction.welcome.action": "Let's go!",
-  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.action": "Bec'h dezhi!",
+  "introduction.welcome.headline": "Pazennoù kentañ",
   "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.blocked": "to open blocked users list",
-  "keyboard_shortcuts.boost": "to boost",
+  "keyboard_shortcuts.boost": "da skignañ",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
   "keyboard_shortcuts.compose": "to focus the compose textarea",
-  "keyboard_shortcuts.description": "Description",
+  "keyboard_shortcuts.description": "Deskrivadur",
   "keyboard_shortcuts.direct": "to open direct messages column",
   "keyboard_shortcuts.down": "to move down in the list",
   "keyboard_shortcuts.enter": "to open status",
@@ -230,7 +230,7 @@
   "keyboard_shortcuts.open_media": "to open media",
   "keyboard_shortcuts.pinned": "to open pinned toots list",
   "keyboard_shortcuts.profile": "to open author's profile",
-  "keyboard_shortcuts.reply": "to reply",
+  "keyboard_shortcuts.reply": "da respont",
   "keyboard_shortcuts.requests": "to open follow requests list",
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "to open \"get started\" column",
@@ -239,48 +239,48 @@
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
+  "lightbox.close": "Serriñ",
   "lightbox.next": "Next",
   "lightbox.previous": "Previous",
   "lightbox.view_context": "View context",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
-  "lists.delete": "Delete list",
-  "lists.edit": "Edit list",
-  "lists.edit.submit": "Change title",
-  "lists.new.create": "Add list",
-  "lists.new.title_placeholder": "New list title",
+  "lists.account.add": "Ouzhpennañ d'al listenn",
+  "lists.account.remove": "Lemel kuit eus al listenn",
+  "lists.delete": "Dilemel al listenn",
+  "lists.edit": "Aozañ al listenn",
+  "lists.edit.submit": "Cheñch an titl",
+  "lists.new.create": "Ouzhpennañ ul listenn",
+  "lists.new.title_placeholder": "Titl nevez al listenn",
   "lists.search": "Search among people you follow",
-  "lists.subheading": "Your lists",
+  "lists.subheading": "Ho listennoù",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
-  "loading_indicator.label": "Loading...",
+  "loading_indicator.label": "O kargañ...",
   "media_gallery.toggle_visible": "Toggle visibility",
-  "missing_indicator.label": "Not found",
+  "missing_indicator.label": "Digavet",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
-  "navigation_bar.apps": "Mobile apps",
-  "navigation_bar.blocks": "Blocked users",
-  "navigation_bar.bookmarks": "Bookmarks",
-  "navigation_bar.community_timeline": "Local timeline",
-  "navigation_bar.compose": "Compose new toot",
-  "navigation_bar.direct": "Direct messages",
-  "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
-  "navigation_bar.edit_profile": "Edit profile",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.filters": "Muted words",
-  "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.apps": "Arloadoù pellgomz",
+  "navigation_bar.blocks": "Implijer·ezed·ien berzet",
+  "navigation_bar.bookmarks": "Sinedoù",
+  "navigation_bar.community_timeline": "Red-amzer lec'hel",
+  "navigation_bar.compose": "Skrivañ un toud nevez",
+  "navigation_bar.direct": "Kemennadoù prevez",
+  "navigation_bar.discover": "Dizoleiñ",
+  "navigation_bar.domain_blocks": "Domanioù kuzhet",
+  "navigation_bar.edit_profile": "Aozañ ar profil",
+  "navigation_bar.favourites": "Ar re vuiañ-karet",
+  "navigation_bar.filters": "Gerioù kuzhet",
+  "navigation_bar.follow_requests": "Pedadoù heuliañ",
   "navigation_bar.follows_and_followers": "Follows and followers",
-  "navigation_bar.info": "About this server",
-  "navigation_bar.keyboard_shortcuts": "Hotkeys",
-  "navigation_bar.lists": "Lists",
-  "navigation_bar.logout": "Logout",
-  "navigation_bar.mutes": "Muted users",
-  "navigation_bar.personal": "Personal",
-  "navigation_bar.pins": "Pinned toots",
-  "navigation_bar.preferences": "Preferences",
-  "navigation_bar.public_timeline": "Federated timeline",
-  "navigation_bar.security": "Security",
+  "navigation_bar.info": "Diwar-benn an dafariad-mañ",
+  "navigation_bar.keyboard_shortcuts": "Berradurioù",
+  "navigation_bar.lists": "Listennoù",
+  "navigation_bar.logout": "Digennaskañ",
+  "navigation_bar.mutes": "Implijer·ion·ezed kuzhet",
+  "navigation_bar.personal": "Personel",
+  "navigation_bar.pins": "Toudoù spilhennet",
+  "navigation_bar.preferences": "Gwellvezioù",
+  "navigation_bar.public_timeline": "Red-amzer kevreet",
+  "navigation_bar.security": "Diogelroez",
   "notification.favourite": "{name} favourited your status",
   "notification.follow": "{name} followed you",
   "notification.follow_request": "{name} has requested to follow you",
@@ -291,135 +291,135 @@
   "notifications.clear": "Clear notifications",
   "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.favourite": "Ar re vuiañ-karet:",
   "notifications.column_settings.filter_bar.advanced": "Display all categories",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
+  "notifications.column_settings.filter_bar.category": "Barrenn siloù prim",
+  "notifications.column_settings.filter_bar.show": "Diskouez",
   "notifications.column_settings.follow": "New followers:",
   "notifications.column_settings.follow_request": "New follow requests:",
-  "notifications.column_settings.mention": "Mentions:",
-  "notifications.column_settings.poll": "Poll results:",
+  "notifications.column_settings.mention": "Menegoù:",
+  "notifications.column_settings.poll": "Disoc'hoù ar sontadeg:",
   "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
+  "notifications.column_settings.reblog": "Skignadennoù:",
+  "notifications.column_settings.show": "Diskouez er bann",
+  "notifications.column_settings.sound": "Seniñ",
+  "notifications.filter.all": "Pep tra",
+  "notifications.filter.boosts": "Skignadennoù",
+  "notifications.filter.favourites": "Muiañ-karet",
   "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.filter.polls": "Poll results",
-  "notifications.group": "{count} notifications",
-  "poll.closed": "Closed",
-  "poll.refresh": "Refresh",
+  "notifications.filter.mentions": "Menegoù",
+  "notifications.filter.polls": "Disoc'hoù ar sontadegoù",
+  "notifications.group": "{count} a gemennoù",
+  "poll.closed": "Serret",
+  "poll.refresh": "Azbevaat",
   "poll.total_people": "{count, plural, one {# person} other {# people}}",
   "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
-  "poll.vote": "Vote",
-  "poll.voted": "You voted for this answer",
-  "poll_button.add_poll": "Add a poll",
-  "poll_button.remove_poll": "Remove poll",
-  "privacy.change": "Adjust status privacy",
-  "privacy.direct.long": "Post to mentioned users only",
-  "privacy.direct.short": "Direct",
-  "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!",
+  "poll.vote": "Mouezhiañ",
+  "poll.voted": "Mouezhiet ho peus evit ar respont-mañ",
+  "poll_button.add_poll": "Ouzhpennañ ur sontadeg",
+  "poll_button.remove_poll": "Dilemel ar sontadeg",
+  "privacy.change": "Kemmañ gwelidigezh ar statud",
+  "privacy.direct.long": "Embann evit an implijer·ezed·ien meneget hepken",
+  "privacy.direct.short": "War-eeun",
+  "privacy.private.long": "Embann evit ar re a heuilh ac'hanon hepken",
+  "privacy.private.short": "Ar re a heuilh ac'hanon hepken",
+  "privacy.public.long": "Embann war ar redoù-amzer foran",
+  "privacy.public.short": "Publik",
+  "privacy.unlisted.long": "Na embann war ar redoù-amzer foran",
+  "privacy.unlisted.short": "Anlistennet",
+  "refresh": "Freskaat",
+  "regeneration_indicator.label": "O kargañ…",
+  "regeneration_indicator.sublabel": "War brientiñ emañ ho red degemer!",
   "relative_time.days": "{number}d",
-  "relative_time.hours": "{number}h",
-  "relative_time.just_now": "now",
+  "relative_time.hours": "{number}e",
+  "relative_time.just_now": "bremañ",
   "relative_time.minutes": "{number}m",
-  "relative_time.seconds": "{number}s",
-  "relative_time.today": "today",
-  "reply_indicator.cancel": "Cancel",
-  "report.forward": "Forward to {target}",
+  "relative_time.seconds": "{number}eil",
+  "relative_time.today": "hiziv",
+  "reply_indicator.cancel": "Nullañ",
+  "report.forward": "Treuzkas da: {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.target": "Report {target}",
-  "search.placeholder": "Search",
+  "search.placeholder": "Klask",
   "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": "ger-klik",
+  "search_popout.tips.status": "statud",
   "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": "implijer·ez",
+  "search_results.accounts": "Tud",
+  "search_results.hashtags": "Gerioù-klik",
+  "search_results.statuses": "a doudoù",
   "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.bookmark": "Ouzhpennañ d'ar sinedoù",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "This post cannot be boosted",
   "status.copy": "Copy link to status",
-  "status.delete": "Delete",
+  "status.delete": "Dilemel",
   "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
-  "status.embed": "Embed",
-  "status.favourite": "Favourite",
+  "status.direct": "Kas ur c'hemennad da @{name}",
+  "status.embed": "Enframmañ",
+  "status.favourite": "Muiañ-karet",
   "status.filtered": "Filtered",
-  "status.load_more": "Load more",
-  "status.media_hidden": "Media hidden",
-  "status.mention": "Mention @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
-  "status.mute_conversation": "Mute conversation",
+  "status.load_more": "Kargañ muioc'h",
+  "status.media_hidden": "Media kuzhet",
+  "status.mention": "Menegiñ @{name}",
+  "status.more": "Muioc'h",
+  "status.mute": "Kuzhat @{name}",
+  "status.mute_conversation": "Kuzhat ar gaozeadenn",
   "status.open": "Expand this status",
-  "status.pin": "Pin on profile",
-  "status.pinned": "Pinned toot",
-  "status.read_more": "Read more",
-  "status.reblog": "Boost",
+  "status.pin": "Spilhennañ d'ar profil",
+  "status.pinned": "Toud spilhennet",
+  "status.read_more": "Lenn muioc'h",
+  "status.reblog": "Skignañ",
   "status.reblog_private": "Boost to original audience",
   "status.reblogged_by": "{name} boosted",
   "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.reply": "Respont",
   "status.replyAll": "Reply to thread",
-  "status.report": "Report @{name}",
+  "status.report": "Disklêriañ @{name}",
   "status.sensitive_warning": "Sensitive content",
-  "status.share": "Share",
+  "status.share": "Rannañ",
   "status.show_less": "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_thread": "Show thread",
   "status.uncached_media_warning": "Not available",
-  "status.unmute_conversation": "Unmute conversation",
-  "status.unpin": "Unpin from profile",
+  "status.unmute_conversation": "Diguzhat ar gaozeadenn",
+  "status.unpin": "Dispilhennañ eus ar profil",
   "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",
+  "tabs_bar.home": "Degemer",
+  "tabs_bar.local_timeline": "Lec'hel",
+  "tabs_bar.notifications": "Kemennoù",
+  "tabs_bar.search": "Klask",
   "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",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
-  "trends.trending_now": "Trending now",
+  "trends.trending_now": "Luskad ar mare",
   "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
   "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add media ({formats})",
+  "upload_button.label": "Ouzhpennañ ur media ({formats})",
   "upload_error.limit": "File upload limit exceeded.",
   "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.undo": "Delete",
+  "upload_form.edit": "Aozañ",
+  "upload_form.undo": "Dilemel",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
@@ -428,9 +428,9 @@
   "upload_modal.edit_media": "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.preview_label": "Preview ({ratio})",
-  "upload_progress.label": "Uploading…",
+  "upload_progress.label": "O pellgargañ...",
   "video.close": "Close video",
-  "video.download": "Download file",
+  "video.download": "Pellgargañ ar restr",
   "video.exit_fullscreen": "Exit full screen",
   "video.expand": "Expand video",
   "video.fullscreen": "Full screen",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index 7b427c3f0..9df1e0c65 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "Základní",
   "home.column_settings.show_reblogs": "Zobrazit boosty",
   "home.column_settings.show_replies": "Zobrazit odpovědi",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "Skrýt oznámení",
+  "home.show_announcements": "Zobrazit oznámení",
   "intervals.full.days": "{number, plural, one {# den} few {# dny} many {# dní} other {# dní}}",
   "intervals.full.hours": "{number, plural, one {# hodina} few {# hodiny} many {# hodin} other {# hodin}}",
   "intervals.full.minutes": "{number, plural, one {# minuta} few {# minuty} many {# minut} other {# minut}}",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "teď",
   "relative_time.minutes": "{number} m",
   "relative_time.seconds": "{number} s",
-  "relative_time.today": "today",
+  "relative_time.today": "dnes",
   "reply_indicator.cancel": "Zrušit",
   "report.forward": "Přeposlat na {target}",
   "report.forward_hint": "Tento účet je z jiného serveru. Chcete na něj také poslat anonymizovanou kopii?",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index cd4ba01a5..cf28408c4 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -3,7 +3,7 @@
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppe",
   "account.block": "@{name} blockieren",
-  "account.block_domain": "Alles von {domain} verstecken",
+  "account.block_domain": "Alles von {domain} blockieren",
   "account.blocked": "Blockiert",
   "account.cancel_follow_request": "Folgeanfrage abbrechen",
   "account.direct": "Direktnachricht an @{name}",
@@ -34,7 +34,7 @@
   "account.share": "Profil von @{name} teilen",
   "account.show_reblogs": "Von @{name} geteilte Beiträge anzeigen",
   "account.unblock": "@{name} entblocken",
-  "account.unblock_domain": "{domain} wieder anzeigen",
+  "account.unblock_domain": "Blockieren von {domain} beenden",
   "account.unendorse": "Nicht auf Profil hervorheben",
   "account.unfollow": "Entfolgen",
   "account.unmute": "@{name} nicht mehr stummschalten",
@@ -86,7 +86,7 @@
   "compose_form.poll.option_placeholder": "Wahl {number}",
   "compose_form.poll.remove_option": "Wahl entfernen",
   "compose_form.poll.switch_to_multiple": "Umfrage ändern, um mehrere Optionen zu erlauben",
-  "compose_form.poll.switch_to_single": "Umfrage ändern, um eine einzige Wahl zu ermöglichen",
+  "compose_form.poll.switch_to_single": "Umfrage ändern, um eine einzige Wahl zu erlauben",
   "compose_form.publish": "Tröt",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.hide": "Medien als heikel markieren",
@@ -143,7 +143,7 @@
   "empty_column.account_timeline": "Keine Beiträge!",
   "empty_column.account_unavailable": "Konto nicht verfügbar",
   "empty_column.blocks": "Du hast keine Profile blockiert.",
-  "empty_column.bookmarked_statuses": "Du hast bis jetzt keine Beiträge als Toots gespeichert. Wenn du einen Beitrag als Toot speicherst, wird er hier erscheinen.",
+  "empty_column.bookmarked_statuses": "Du hast bis jetzt keine Beiträge als Lesezeichen gespeichert. Wenn du einen Beitrag als Lesezeichen speicherst wird er hier erscheinen.",
   "empty_column.community": "Die lokale Zeitleiste ist leer. Schreibe einen öffentlichen Beitrag, um den Ball ins Rollen zu bringen!",
   "empty_column.direct": "Du hast noch keine Direktnachrichten erhalten. Wenn du eine sendest oder empfängst, wird sie hier zu sehen sein.",
   "empty_column.domain_blocks": "Es ist noch keine versteckten Domains.",
@@ -158,7 +158,7 @@
   "empty_column.mutes": "Du hast keine Profile stummgeschaltet.",
   "empty_column.notifications": "Du hast noch keine Mitteilungen. Interagiere mit anderen, um ins Gespräch zu kommen.",
   "empty_column.public": "Hier ist nichts zu sehen! Schreibe etwas öffentlich oder folge Profilen von anderen Servern, um die Zeitleiste aufzufüllen",
-  "error.unexpected_crash.explanation": "Aufgrund eines Fehlers in unserem Code oder einer Browsereinkompatibilität konnte diese Seite nicht korrekt angezeigt werden.",
+  "error.unexpected_crash.explanation": "Aufgrund eines Fehlers in unserem Code oder einer Browser-Inkompatibilität konnte diese Seite nicht korrekt angezeigt werden.",
   "error.unexpected_crash.next_steps": "Versuche die Seite zu aktualisieren. Wenn das nicht hilft, kannst du Mastodon über einen anderen Browser oder eine native App verwenden.",
   "errors.unexpected_crash.copy_stacktrace": "Fehlerlog in die Zwischenablage kopieren",
   "errors.unexpected_crash.report_issue": "Problem melden",
@@ -296,7 +296,7 @@
   "notifications.column_settings.filter_bar.category": "Schnellfilterleiste",
   "notifications.column_settings.filter_bar.show": "Anzeigen",
   "notifications.column_settings.follow": "Neue Folgende:",
-  "notifications.column_settings.follow_request": "Neue Folge-Anfragen:",
+  "notifications.column_settings.follow_request": "Neue Folgeanfragen:",
   "notifications.column_settings.mention": "Erwähnungen:",
   "notifications.column_settings.poll": "Ergebnisse von Umfragen:",
   "notifications.column_settings.push": "Push-Benachrichtigungen",
@@ -321,7 +321,7 @@
   "privacy.change": "Sichtbarkeit des Beitrags anpassen",
   "privacy.direct.long": "Wird an erwähnte Profile gesendet",
   "privacy.direct.short": "Direktnachricht",
-  "privacy.private.long": "Wird nur für deine Folgende sichtbar sein",
+  "privacy.private.long": "Beitrag nur an Folgende",
   "privacy.private.short": "Nur für Folgende",
   "privacy.public.long": "Wird in öffentlichen Zeitleisten erscheinen",
   "privacy.public.short": "Öffentlich",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 18692bc44..993347273 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -142,7 +142,7 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Unhide {domain}",
+        "defaultMessage": "Unblock domain {domain}",
         "id": "account.unblock_domain"
       }
     ],
@@ -217,7 +217,7 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Toggle visibility",
+        "defaultMessage": "Hide media",
         "id": "media_gallery.toggle_visible"
       },
       {
@@ -451,11 +451,11 @@
         "id": "status.copy"
       },
       {
-        "defaultMessage": "Hide everything from {domain}",
+        "defaultMessage": "Block domain {domain}",
         "id": "account.block_domain"
       },
       {
-        "defaultMessage": "Unhide {domain}",
+        "defaultMessage": "Unblock domain {domain}",
         "id": "account.unblock_domain"
       },
       {
@@ -523,7 +523,7 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Hide entire domain",
+        "defaultMessage": "Block entire domain",
         "id": "confirmations.domain_block.confirm"
       },
       {
@@ -697,11 +697,11 @@
         "id": "account.media"
       },
       {
-        "defaultMessage": "Hide everything from {domain}",
+        "defaultMessage": "Block domain {domain}",
         "id": "account.block_domain"
       },
       {
-        "defaultMessage": "Unhide {domain}",
+        "defaultMessage": "Unblock domain {domain}",
         "id": "account.unblock_domain"
       },
       {
@@ -737,7 +737,7 @@
         "id": "navigation_bar.blocks"
       },
       {
-        "defaultMessage": "Hidden domains",
+        "defaultMessage": "Blocked domains",
         "id": "navigation_bar.domain_blocks"
       },
       {
@@ -773,7 +773,7 @@
         "id": "account.muted"
       },
       {
-        "defaultMessage": "Domain hidden",
+        "defaultMessage": "Domain blocked",
         "id": "account.domain_blocked"
       },
       {
@@ -917,6 +917,10 @@
       {
         "defaultMessage": "Logout",
         "id": "navigation_bar.logout"
+      },
+      {
+        "defaultMessage": "Bookmarks",
+        "id": "navigation_bar.bookmarks"
       }
     ],
     "path": "app/javascript/mastodon/features/compose/components/action_bar.json"
@@ -1073,7 +1077,7 @@
         "id": "privacy.public.short"
       },
       {
-        "defaultMessage": "Post to public timelines",
+        "defaultMessage": "Visible for all, shown in public timelines",
         "id": "privacy.public.long"
       },
       {
@@ -1081,7 +1085,7 @@
         "id": "privacy.unlisted.short"
       },
       {
-        "defaultMessage": "Do not show in public timelines",
+        "defaultMessage": "Visible for all, but not in public timelines",
         "id": "privacy.unlisted.long"
       },
       {
@@ -1089,7 +1093,7 @@
         "id": "privacy.private.short"
       },
       {
-        "defaultMessage": "Post to followers only",
+        "defaultMessage": "Visible for followers only",
         "id": "privacy.private.long"
       },
       {
@@ -1097,7 +1101,7 @@
         "id": "privacy.direct.short"
       },
       {
-        "defaultMessage": "Post to mentioned users only",
+        "defaultMessage": "Visible for mentioned users only",
         "id": "privacy.direct.long"
       },
       {
@@ -1466,15 +1470,15 @@
   {
     "descriptors": [
       {
-        "defaultMessage": "Hidden domains",
+        "defaultMessage": "Blocked domains",
         "id": "column.domain_blocks"
       },
       {
-        "defaultMessage": "Unhide {domain}",
+        "defaultMessage": "Unblock domain {domain}",
         "id": "account.unblock_domain"
       },
       {
-        "defaultMessage": "There are no hidden domains yet.",
+        "defaultMessage": "There are no blocked domains yet.",
         "id": "empty_column.domain_blocks"
       }
     ],
@@ -1528,6 +1532,10 @@
       {
         "defaultMessage": "You don't have any follow requests yet. When you receive one, it will show up here.",
         "id": "empty_column.follow_requests"
+      },
+      {
+        "defaultMessage": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+        "id": "follow_requests.unlocked_explanation"
       }
     ],
     "path": "app/javascript/mastodon/features/follow_requests/index.json"
@@ -2384,11 +2392,11 @@
         "id": "status.copy"
       },
       {
-        "defaultMessage": "Hide everything from {domain}",
+        "defaultMessage": "Block domain {domain}",
         "id": "account.block_domain"
       },
       {
-        "defaultMessage": "Unhide {domain}",
+        "defaultMessage": "Unblock domain {domain}",
         "id": "account.unblock_domain"
       },
       {
@@ -2957,4 +2965,4 @@
     ],
     "path": "app/javascript/mastodon/features/video/index.json"
   }
-]
\ No newline at end of file
+]
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 5b0067acb..d92a0e35a 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -150,7 +150,7 @@
   "empty_column.favourited_statuses": "Δεν έχεις κανένα αγαπημένο τουτ ακόμα. Μόλις αγαπήσεις κάποιο, θα εμφανιστεί εδώ.",
   "empty_column.favourites": "Κανείς δεν έχει αγαπήσει αυτό το τουτ ακόμα. Μόλις το κάνει κάποια, θα εμφανιστούν εδώ.",
   "empty_column.follow_requests": "Δεν έχεις κανένα αίτημα παρακολούθησης ακόμα. Μόλις λάβεις κάποιο, θα εμφανιστεί εδώ.",
-  "empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ταμπέλα.",
+  "empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ετικέτα.",
   "empty_column.home": "Η τοπική σου ροή είναι κενή! Πήγαινε στο {public} ή κάνε αναζήτηση για να ξεκινήσεις και να γνωρίσεις άλλους χρήστες.",
   "empty_column.home.public_timeline": "η δημόσια ροή",
   "empty_column.list": "Δεν υπάρχει τίποτα σε αυτή τη λίστα ακόμα. Όταν τα μέλη της δημοσιεύσουν νέες καταστάσεις, θα εμφανιστούν εδώ.",
@@ -176,7 +176,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": "Κανένα από αυτά",
@@ -345,13 +345,13 @@
   "report.target": "Καταγγελία {target}",
   "search.placeholder": "Αναζήτηση",
   "search_popout.search_format": "Προχωρημένη αναζήτηση",
-  "search_popout.tips.full_text": "Απλό κείμενο που επιστρέφει καταστάσεις που έχεις γράψει, σημειώσει ως αγαπημένες, προωθήσει ή έχεις αναφερθεί σε αυτές, καθώς και όσα ονόματα χρηστών και ταμπέλες ταιριάζουν.",
-  "search_popout.tips.hashtag": "ταμπέλα",
+  "search_popout.tips.full_text": "Απλό κείμενο που επιστρέφει καταστάσεις που έχεις γράψει, έχεις σημειώσει ως αγαπημένες, έχεις προωθήσει ή έχεις αναφερθεί σε αυτές, καθώς και όσα ονόματα χρηστών και ετικέτες ταιριάζουν.",
+  "search_popout.tips.hashtag": "ετικέτα",
   "search_popout.tips.status": "κατάσταση",
-  "search_popout.tips.text": "Απλό κείμενο που επιστρέφει ονόματα και ταμπέλες που ταιριάζουν",
+  "search_popout.tips.text": "Απλό κείμενο που επιστρέφει ονόματα και ετικέτες που ταιριάζουν",
   "search_popout.tips.user": "χρήστης",
   "search_results.accounts": "Άνθρωποι",
-  "search_results.hashtags": "Ταμπέλες",
+  "search_results.hashtags": "Ετικέτες",
   "search_results.statuses": "Τουτ",
   "search_results.statuses_fts_disabled": "Η αναζήτηση τουτ βάσει του περιεχόμενού τους δεν είναι ενεργοποιημένη σε αυτό τον κόμβο.",
   "search_results.total": "{count, number} {count, plural, zero {αποτελέσματα} one {αποτέλεσμα} other {αποτελέσματα}}",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index e25199905..c7153b7b1 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -3,11 +3,11 @@
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
   "account.block": "Block @{name}",
-  "account.block_domain": "Hide everything from {domain}",
+  "account.block_domain": "Block domain {domain}",
   "account.blocked": "Blocked",
   "account.cancel_follow_request": "Cancel follow request",
   "account.direct": "Direct message @{name}",
-  "account.domain_blocked": "Domain hidden",
+  "account.domain_blocked": "Domain blocked",
   "account.edit_profile": "Edit profile",
   "account.endorse": "Feature on profile",
   "account.follow": "Follow",
@@ -34,7 +34,7 @@
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.unblock": "Unblock @{name}",
-  "account.unblock_domain": "Unhide {domain}",
+  "account.unblock_domain": "Unblock domain {domain}",
   "account.unendorse": "Don't feature on profile",
   "account.unfollow": "Unfollow",
   "account.unmute": "Unmute @{name}",
@@ -57,7 +57,7 @@
   "column.community": "Local timeline",
   "column.direct": "Direct messages",
   "column.directory": "Browse profiles",
-  "column.domain_blocks": "Hidden domains",
+  "column.domain_blocks": "Blocked domains",
   "column.favourites": "Favourites",
   "column.follow_requests": "Follow requests",
   "column.home": "Home",
@@ -107,7 +107,7 @@
   "confirmations.delete.message": "Are you sure you want to delete this status?",
   "confirmations.delete_list.confirm": "Delete",
   "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
-  "confirmations.domain_block.confirm": "Hide entire domain",
+  "confirmations.domain_block.confirm": "Block entire domain",
   "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": "Log out",
   "confirmations.logout.message": "Are you sure you want to log out?",
@@ -150,7 +150,7 @@
   "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
-  "empty_column.domain_blocks": "There are no hidden domains yet.",
+  "empty_column.domain_blocks": "There are no blocked domains yet.",
   "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
   "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
   "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
@@ -168,6 +168,7 @@
   "errors.unexpected_crash.report_issue": "Report issue",
   "follow_request.authorize": "Authorize",
   "follow_request.reject": "Reject",
+  "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.",
   "getting_started.developers": "Developers",
   "getting_started.directory": "Profile directory",
   "getting_started.documentation": "Documentation",
@@ -258,7 +259,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
@@ -269,7 +270,7 @@
   "navigation_bar.compose": "Compose new toot",
   "navigation_bar.direct": "Direct messages",
   "navigation_bar.discover": "Discover",
-  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.domain_blocks": "Blocked domains",
   "navigation_bar.edit_profile": "Edit profile",
   "navigation_bar.favourites": "Favourites",
   "navigation_bar.filters": "Muted words",
@@ -324,13 +325,13 @@
   "poll_button.add_poll": "Add a poll",
   "poll_button.remove_poll": "Remove poll",
   "privacy.change": "Adjust status privacy",
-  "privacy.direct.long": "Post to mentioned users only",
+  "privacy.direct.long": "Visible for mentioned users only",
   "privacy.direct.short": "Direct",
-  "privacy.private.long": "Post to followers only",
+  "privacy.private.long": "Visible for followers only",
   "privacy.private.short": "Followers-only",
-  "privacy.public.long": "Post to public timelines",
+  "privacy.public.long": "Visible for all, shown in public timelines",
   "privacy.public.short": "Public",
-  "privacy.unlisted.long": "Do not post to public timelines",
+  "privacy.unlisted.long": "Visible for all, but not in public timelines",
   "privacy.unlisted.short": "Unlisted",
   "refresh": "Refresh",
   "regeneration_indicator.label": "Loading…",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index a315c9226..5138b85a0 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -374,7 +374,7 @@
   "status.more": "Pli",
   "status.mute": "Silentigi @{name}",
   "status.mute_conversation": "Silentigi konversacion",
-  "status.open": "Grandigi",
+  "status.open": "Grandigi ĉi tiun mesaĝon",
   "status.pin": "Alpingli profile",
   "status.pinned": "Alpinglita mesaĝo",
   "status.read_more": "Legi pli",
@@ -392,7 +392,7 @@
   "status.show_less": "Malgrandigi",
   "status.show_less_all": "Malgrandigi ĉiujn",
   "status.show_more": "Grandigi",
-  "status.show_more_all": "Grandigi ĉiujn",
+  "status.show_more_all": "Malfoldi ĉiun",
   "status.show_thread": "Montri la fadenon",
   "status.uncached_media_warning": "Nedisponebla",
   "status.unmute_conversation": "Malsilentigi la konversacion",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index 8e1f84ab8..4f7a9e59f 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -375,7 +375,7 @@
   "status.mute": "Silenciar a @{name}",
   "status.mute_conversation": "Silenciar conversación",
   "status.open": "Expandir este estado",
-  "status.pin": "Pin en el perfil",
+  "status.pin": "Fijar en el perfil",
   "status.pinned": "Toot fijado",
   "status.read_more": "Leer más",
   "status.reblog": "Retootear",
@@ -396,7 +396,7 @@
   "status.show_thread": "Mostrar hilo",
   "status.uncached_media_warning": "No disponible",
   "status.unmute_conversation": "Dejar de silenciar conversación",
-  "status.unpin": "Desmarcar del perfil",
+  "status.unpin": "Dejar de fijar",
   "suggestions.dismiss": "Descartar sugerencia",
   "suggestions.header": "Es posible que te interese…",
   "tabs_bar.federated_timeline": "Federado",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index 5dc4e60c2..3a44dceb5 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -27,8 +27,8 @@
   "account.mute_notifications": "Mututu @{name}(r)en jakinarazpenak",
   "account.muted": "Mutututa",
   "account.never_active": "Inoiz ez",
-  "account.posts": "Tootak",
-  "account.posts_with_replies": "Toot-ak eta erantzunak",
+  "account.posts": "Toot",
+  "account.posts_with_replies": "Tootak eta erantzunak",
   "account.report": "Salatu @{name}",
   "account.requested": "Onarpenaren zain. Klikatu jarraitzeko eskaera ezeztatzeko",
   "account.share": "@{name}(e)ren profila elkarbanatu",
@@ -64,7 +64,7 @@
   "column.lists": "Zerrendak",
   "column.mutes": "Mutututako erabiltzaileak",
   "column.notifications": "Jakinarazpenak",
-  "column.pins": "Finkatutako toot-ak",
+  "column.pins": "Finkatutako tootak",
   "column.public": "Federatutako denbora-lerroa",
   "column_back_button.label": "Atzera",
   "column_header.hide_settings": "Ezkutatu ezarpenak",
@@ -140,7 +140,7 @@
   "emoji_button.search_results": "Bilaketaren emaitzak",
   "emoji_button.symbols": "Sinboloak",
   "emoji_button.travel": "Bidaiak eta tokiak",
-  "empty_column.account_timeline": "Ez dago toot-ik hemen!",
+  "empty_column.account_timeline": "Ez dago tootik hemen!",
   "empty_column.account_unavailable": "Profila ez dago eskuragarri",
   "empty_column.blocks": "Ez duzu erabiltzailerik blokeatu oraindik.",
   "empty_column.bookmarked_statuses": "Oraindik ez dituzu toot laster-markatutarik. Bat laster-markatzerakoan, hemen agertuko da.",
@@ -228,7 +228,7 @@
   "keyboard_shortcuts.my_profile": "zure profila irekitzeko",
   "keyboard_shortcuts.notifications": "jakinarazpenen zutabea irekitzeko",
   "keyboard_shortcuts.open_media": "media zabaltzeko",
-  "keyboard_shortcuts.pinned": "finkatutako toot-en zerrenda irekitzeko",
+  "keyboard_shortcuts.pinned": "finkatutako tooten zerrenda irekitzeko",
   "keyboard_shortcuts.profile": "egilearen profila irekitzeko",
   "keyboard_shortcuts.reply": "erantzutea",
   "keyboard_shortcuts.requests": "jarraitzeko eskarien zerrenda irekitzeko",
@@ -277,7 +277,7 @@
   "navigation_bar.logout": "Amaitu saioa",
   "navigation_bar.mutes": "Mutututako erabiltzaileak",
   "navigation_bar.personal": "Pertsonala",
-  "navigation_bar.pins": "Finkatutako toot-ak",
+  "navigation_bar.pins": "Finkatutako tootak",
   "navigation_bar.preferences": "Hobespenak",
   "navigation_bar.public_timeline": "Federatutako denbora-lerroa",
   "navigation_bar.security": "Segurtasuna",
@@ -352,8 +352,8 @@
   "search_popout.tips.user": "erabiltzailea",
   "search_results.accounts": "Jendea",
   "search_results.hashtags": "Traolak",
-  "search_results.statuses": "Toot-ak",
-  "search_results.statuses_fts_disabled": "Mastodon zerbitzari honek ez du Toot-en edukiaren bilaketa gaitu.",
+  "search_results.statuses": "Tootak",
+  "search_results.statuses_fts_disabled": "Mastodon zerbitzari honek ez du tooten edukiaren bilaketa gaitu.",
   "search_results.total": "{count, number} {count, plural, one {emaitza} other {emaitza}}",
   "status.admin_account": "Ireki @{name} erabiltzailearen moderazio interfazea",
   "status.admin_status": "Ireki mezu hau moderazio interfazean",
@@ -376,7 +376,7 @@
   "status.mute_conversation": "Mututu elkarrizketa",
   "status.open": "Hedatu mezu hau",
   "status.pin": "Finkatu profilean",
-  "status.pinned": "Finkatutako toot-a",
+  "status.pinned": "Finkatutako toota",
   "status.read_more": "Irakurri gehiago",
   "status.reblog": "Bultzada",
   "status.reblog_private": "Bultzada jatorrizko hartzaileei",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 0fc39b16d..f2e7f300a 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -254,7 +254,7 @@
   "lists.subheading": "فهرست‌های شما",
   "load_pending": "{count, plural, one {# مورد تازه} other {# مورد تازه}}",
   "loading_indicator.label": "بارگیری...",
-  "media_gallery.toggle_visible": "تغییر پیدایی",
+  "media_gallery.toggle_visible": "تغییر وضعیت نمایانی",
   "missing_indicator.label": "پیدا نشد",
   "missing_indicator.sublabel": "این منبع پیدا نشد",
   "mute_modal.hide_notifications": "اعلان‌های این کاربر پنهان شود؟",
@@ -319,13 +319,13 @@
   "poll_button.add_poll": "افزودن نظرسنجی",
   "poll_button.remove_poll": "حذف نظرسنجی",
   "privacy.change": "تنظیم محرمانگی نوشته",
-  "privacy.direct.long": "تنها به کاربران نام‌برده‌شده نشان بده",
+  "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.long": "ارسال نکردن به خط‌زمانی عمومی",
   "privacy.unlisted.short": "فهرست‌نشده",
   "refresh": "به‌روزرسانی",
   "regeneration_indicator.label": "در حال باز شدن…",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index b46083477..32bc8de49 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -1,7 +1,7 @@
 {
   "account.add_or_remove_from_list": "Lisää tai poista listoilta",
   "account.badges.bot": "Botti",
-  "account.badges.group": "Group",
+  "account.badges.group": "Ryhmä",
   "account.block": "Estä @{name}",
   "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}",
   "account.blocked": "Estetty",
@@ -34,7 +34,7 @@
   "account.share": "Jaa käyttäjän @{name} profiili",
   "account.show_reblogs": "Näytä buustaukset käyttäjältä @{name}",
   "account.unblock": "Salli @{name}",
-  "account.unblock_domain": "Näytä {domain}",
+  "account.unblock_domain": "Salli {domain}",
   "account.unendorse": "Poista suosittelu profiilistasi",
   "account.unfollow": "Lakkaa seuraamasta",
   "account.unmute": "Poista käyttäjän @{name} mykistys",
@@ -43,7 +43,7 @@
   "alert.rate_limited.title": "Määrää rajoitettu",
   "alert.unexpected.message": "Tapahtui odottamaton virhe.",
   "alert.unexpected.title": "Hups!",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "Ilmoitus",
   "autosuggest_hashtag.per_week": "{count} viikossa",
   "boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}",
   "bundle_column_error.body": "Jokin meni vikaan komponenttia ladattaessa.",
@@ -85,8 +85,8 @@
   "compose_form.poll.duration": "Äänestyksen kesto",
   "compose_form.poll.option_placeholder": "Valinta numero",
   "compose_form.poll.remove_option": "Poista tämä valinta",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "Muuta kysely monivalinnaksi",
+  "compose_form.poll.switch_to_single": "Muuta kysely sallimaan vain yksi valinta",
   "compose_form.publish": "Tuuttaa",
   "compose_form.publish_loud": "Julkista!",
   "compose_form.sensitive.hide": "Valitse tämä arkaluontoisena",
@@ -143,7 +143,7 @@
   "empty_column.account_timeline": "Ei ole 'toots' täällä!",
   "empty_column.account_unavailable": "Profiilia ei löydy",
   "empty_column.blocks": "Et ole vielä estänyt yhtään käyttäjää.",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
+  "empty_column.bookmarked_statuses": "Et ole vielä lisännyt tuuttauksia kirjanmerkkeihisi. Kun teet niin, tuuttaus näkyy tässä.",
   "empty_column.community": "Paikallinen aikajana on tyhjä. Homma lähtee käyntiin, kun kirjoitat jotain julkista!",
   "empty_column.direct": "Sinulla ei ole vielä yhtään viestiä yksittäiselle käyttäjälle. Kun lähetät tai vastaanotat sellaisen, se näkyy täällä.",
   "empty_column.domain_blocks": "Yhtään verkko-osoitetta ei ole vielä piilotettu.",
@@ -160,7 +160,7 @@
   "empty_column.public": "Täällä ei ole mitään! Saat sisältöä, kun kirjoitat jotain julkisesti tai käyt seuraamassa muiden instanssien käyttäjiä",
   "error.unexpected_crash.explanation": "Sivua ei voi näyttää oikein, johtuen bugista tai ongelmasta selaimen yhteensopivuudessa.",
   "error.unexpected_crash.next_steps": "Kokeile päivittää sivu. Jos tämä ei auta, saatat yhä pystyä käyttämään Mastodonia toisen selaimen tai sovelluksen kautta.",
-  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "errors.unexpected_crash.copy_stacktrace": "Kopioi stacktrace leikepöydälle",
   "errors.unexpected_crash.report_issue": "Ilmoita ongelmasta",
   "follow_request.authorize": "Valtuuta",
   "follow_request.reject": "Hylkää",
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "Perusasetukset",
   "home.column_settings.show_reblogs": "Näytä buustaukset",
   "home.column_settings.show_replies": "Näytä vastaukset",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "Piilota ilmoitukset",
+  "home.show_announcements": "Näytä ilmoitukset",
   "intervals.full.days": "Päivä päiviä",
   "intervals.full.hours": "Tunti tunteja",
   "intervals.full.minutes": "Minuuti minuuteja",
@@ -215,7 +215,7 @@
   "keyboard_shortcuts.direct": "avaa pikaviestisarake",
   "keyboard_shortcuts.down": "siirry listassa alaspäin",
   "keyboard_shortcuts.enter": "avaa tilapäivitys",
-  "keyboard_shortcuts.favourite": "tykkää",
+  "keyboard_shortcuts.favourite": "lisää suosikkeihin",
   "keyboard_shortcuts.favourites": "avaa lista suosikeista",
   "keyboard_shortcuts.federated": "avaa yleinen aikajana",
   "keyboard_shortcuts.heading": "Näppäinkomennot",
@@ -227,7 +227,7 @@
   "keyboard_shortcuts.muted": "avaa lista mykistetyistä käyttäjistä",
   "keyboard_shortcuts.my_profile": "avaa profiilisi",
   "keyboard_shortcuts.notifications": "avaa ilmoitukset-sarake",
-  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.open_media": "median avaus",
   "keyboard_shortcuts.pinned": "avaa lista kiinnitetyistä tuuttauksista",
   "keyboard_shortcuts.profile": "avaa kirjoittajan profiili",
   "keyboard_shortcuts.reply": "vastaa",
@@ -260,7 +260,7 @@
   "mute_modal.hide_notifications": "Piilota tältä käyttäjältä tulevat ilmoitukset?",
   "navigation_bar.apps": "Mobiilisovellukset",
   "navigation_bar.blocks": "Estetyt käyttäjät",
-  "navigation_bar.bookmarks": "Bookmarks",
+  "navigation_bar.bookmarks": "Kirjanmerkit",
   "navigation_bar.community_timeline": "Paikallinen aikajana",
   "navigation_bar.compose": "Kirjoita uusi tuuttaus",
   "navigation_bar.direct": "Viestit",
@@ -283,9 +283,9 @@
   "navigation_bar.security": "Tunnukset",
   "notification.favourite": "{name} tykkäsi tilastasi",
   "notification.follow": "{name} seurasi sinua",
-  "notification.follow_request": "{name} has requested to follow you",
+  "notification.follow_request": "{name} haluaa seurata sinua",
   "notification.mention": "{name} mainitsi sinut",
-  "notification.own_poll": "Your poll has ended",
+  "notification.own_poll": "Kyselysi on päättynyt",
   "notification.poll": "Kysely, johon osallistuit, on päättynyt",
   "notification.reblog": "{name} buustasi tilaasi",
   "notifications.clear": "Tyhjennä ilmoitukset",
@@ -296,7 +296,7 @@
   "notifications.column_settings.filter_bar.category": "Pikasuodatuspalkki",
   "notifications.column_settings.filter_bar.show": "Näytä",
   "notifications.column_settings.follow": "Uudet seuraajat:",
-  "notifications.column_settings.follow_request": "New follow requests:",
+  "notifications.column_settings.follow_request": "Uudet seuraamispyynnöt:",
   "notifications.column_settings.mention": "Maininnat:",
   "notifications.column_settings.poll": "Kyselyn tulokset:",
   "notifications.column_settings.push": "Push-ilmoitukset",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "nyt",
   "relative_time.minutes": "{number} m",
   "relative_time.seconds": "{number} s",
-  "relative_time.today": "today",
+  "relative_time.today": "tänään",
   "reply_indicator.cancel": "Peruuta",
   "report.forward": "Välitä kohteeseen {target}",
   "report.forward_hint": "Tämä tili on toisella palvelimella. Haluatko lähettää nimettömän raportin myös sinne?",
@@ -358,7 +358,7 @@
   "status.admin_account": "Avaa moderaattorinäkymä tilistä @{name}",
   "status.admin_status": "Avaa tilapäivitys moderaattorinäkymässä",
   "status.block": "Estä @{name}",
-  "status.bookmark": "Bookmark",
+  "status.bookmark": "Tallenna kirjanmerkki",
   "status.cancel_reblog_private": "Peru buustaus",
   "status.cannot_reblog": "Tätä julkaisua ei voi buustata",
   "status.copy": "Kopioi linkki tilapäivitykseen",
@@ -383,7 +383,7 @@
   "status.reblogged_by": "{name} buustasi",
   "status.reblogs.empty": "Kukaan ei ole vielä buustannut tätä tuuttausta. Kun joku tekee niin, näkyy kyseinen henkilö tässä.",
   "status.redraft": "Poista & palauta muokattavaksi",
-  "status.remove_bookmark": "Remove bookmark",
+  "status.remove_bookmark": "Poista kirjanmerkki",
   "status.reply": "Vastaa",
   "status.replyAll": "Vastaa ketjuun",
   "status.report": "Raportoi @{name}",
@@ -416,11 +416,11 @@
   "upload_button.label": "Lisää mediaa",
   "upload_error.limit": "Tiedostolatauksien raja ylitetty.",
   "upload_error.poll": "Tiedon lataaminen ei ole sallittua kyselyissä.",
-  "upload_form.audio_description": "Describe for people with hearing loss",
+  "upload_form.audio_description": "Kuvaile kuulovammaisille",
   "upload_form.description": "Anna kuvaus näkörajoitteisia varten",
   "upload_form.edit": "Muokkaa",
   "upload_form.undo": "Peru",
-  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_form.video_description": "Kuvaile kuulo- tai näkövammaisille",
   "upload_modal.analyzing_picture": "Analysoidaan kuvaa…",
   "upload_modal.apply": "Käytä",
   "upload_modal.description_placeholder": "Eräänä jäätävänä ja pimeänä yönä gorilla ratkaisi sudokun kahdessa minuutissa",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index f61c15d57..cf07cd3db 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -3,29 +3,29 @@
   "account.badges.bot": "Robot",
   "account.badges.group": "Groupe",
   "account.block": "Bloquer @{name}",
-  "account.block_domain": "Tout masquer venant de {domain}",
+  "account.block_domain": "Bloquer le domaine {domain}",
   "account.blocked": "Bloqué·e",
   "account.cancel_follow_request": "Annuler la demande de suivi",
   "account.direct": "Envoyer un message direct à @{name}",
-  "account.domain_blocked": "Domaine caché",
+  "account.domain_blocked": "Domaine bloqué",
   "account.edit_profile": "Modifier le profil",
   "account.endorse": "Recommander sur le profil",
   "account.follow": "Suivre",
-  "account.followers": "Abonné⋅e⋅s",
-  "account.followers.empty": "Personne ne suit cet utilisateur·rice pour l’instant.",
+  "account.followers": "Abonné·e·s",
+  "account.followers.empty": "Personne ne suit cet·te utilisateur·rice pour l’instant.",
   "account.follows": "Abonnements",
   "account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.",
   "account.follows_you": "Vous suit",
   "account.hide_reblogs": "Masquer les partages de @{name}",
   "account.last_status": "Dernière activité",
   "account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}",
-  "account.locked_info": "Ce compte est verrouillé. Son propriétaire approuve manuellement qui peut le ou la suivre.",
-  "account.media": "Média",
+  "account.locked_info": "Ce compte est verrouillé. Son ou sa propriétaire approuve manuellement qui peut le suivre.",
+  "account.media": "Médias",
   "account.mention": "Mentionner @{name}",
   "account.moved_to": "{name} a déménagé vers :",
   "account.mute": "Masquer @{name}",
   "account.mute_notifications": "Ignorer les notifications de @{name}",
-  "account.muted": "Silencé·e",
+  "account.muted": "Masqué·e",
   "account.never_active": "Jamais",
   "account.posts": "Pouets",
   "account.posts_with_replies": "Pouets et réponses",
@@ -38,14 +38,14 @@
   "account.unendorse": "Ne plus recommander sur le profil",
   "account.unfollow": "Ne plus suivre",
   "account.unmute": "Ne plus masquer @{name}",
-  "account.unmute_notifications": "Réactiver les notifications de @{name}",
+  "account.unmute_notifications": "Ne plus masquer les notifications de @{name}",
   "alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Débit limité",
+  "alert.rate_limited.title": "Taux limité",
   "alert.unexpected.message": "Une erreur inattendue s’est produite.",
   "alert.unexpected.title": "Oups !",
   "announcement.announcement": "Annonce",
   "autosuggest_hashtag.per_week": "{count} par semaine",
-  "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci, la prochaine fois",
+  "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois",
   "bundle_column_error.body": "Une erreur s’est produite lors du chargement de ce composant.",
   "bundle_column_error.retry": "Réessayer",
   "bundle_column_error.title": "Erreur réseau",
@@ -55,7 +55,7 @@
   "column.blocks": "Comptes bloqués",
   "column.bookmarks": "Marque-pages",
   "column.community": "Fil public local",
-  "column.direct": "Messages privés",
+  "column.direct": "Messages directs",
   "column.directory": "Parcourir les profils",
   "column.domain_blocks": "Domaines cachés",
   "column.favourites": "Favoris",
@@ -67,7 +67,7 @@
   "column.pins": "Pouets épinglés",
   "column.public": "Fil public global",
   "column_back_button.label": "Retour",
-  "column_header.hide_settings": "Masquer les paramètres",
+  "column_header.hide_settings": "Cacher les paramètres",
   "column_header.moveLeft_settings": "Déplacer la colonne vers la gauche",
   "column_header.moveRight_settings": "Déplacer la colonne vers la droite",
   "column_header.pin": "Épingler",
@@ -94,39 +94,39 @@
   "compose_form.sensitive.unmarked": "Le média n’est pas marqué comme sensible",
   "compose_form.spoiler.marked": "Le texte est caché derrière un avertissement",
   "compose_form.spoiler.unmarked": "Le texte n’est pas caché",
-  "compose_form.spoiler_placeholder": "Écrivez ici votre avertissement",
+  "compose_form.spoiler_placeholder": "Écrivez votre avertissement ici",
   "confirmation_modal.cancel": "Annuler",
   "confirmations.block.block_and_report": "Bloquer et signaler",
   "confirmations.block.confirm": "Bloquer",
-  "confirmations.block.message": "Confirmez-vous le blocage de {name} ?",
+  "confirmations.block.message": "Voulez-vous vraiment bloquer {name} ?",
   "confirmations.delete.confirm": "Supprimer",
-  "confirmations.delete.message": "Confirmez-vous la suppression de ce pouet ?",
+  "confirmations.delete.message": "Voulez-vous vraiment supprimer ce pouet ?",
   "confirmations.delete_list.confirm": "Supprimer",
-  "confirmations.delete_list.message": "Êtes-vous sûr·e de vouloir supprimer définitivement cette liste ?",
+  "confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste ?",
   "confirmations.domain_block.confirm": "Masquer le domaine entier",
-  "confirmations.domain_block.message": "Êtes-vous vraiment, vraiment sûr⋅e de vouloir bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.",
-  "confirmations.logout.confirm": "Déconnexion",
-  "confirmations.logout.message": "Êtes-vous sûr·e de vouloir vous déconnecter ?",
+  "confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.",
+  "confirmations.logout.confirm": "Se déconnecter",
+  "confirmations.logout.message": "Voulez-vous vraiment vous déconnecter ?",
   "confirmations.mute.confirm": "Masquer",
   "confirmations.mute.explanation": "Cela masquera ses messages et les messages le ou la mentionnant, mais cela lui permettra quand même de voir vos messages et de vous suivre.",
-  "confirmations.mute.message": "Êtes-vous sûr·e de vouloir masquer {name} ?",
-  "confirmations.redraft.confirm": "Effacer et ré-écrire",
-  "confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire ? Ses partages ainsi que ses mises en favori seront perdu·e·s et ses réponses seront orphelines.",
+  "confirmations.mute.message": "Voulez-vous vraiment masquer {name} ?",
+  "confirmations.redraft.confirm": "Supprimer et ré-écrire",
+  "confirmations.redraft.message": "Voulez-vous vraiment supprimer ce pouet pour le ré-écrire ? Ses partages ainsi que ses mises en favori seront perdu·e·s et ses réponses seront orphelines.",
   "confirmations.reply.confirm": "Répondre",
-  "confirmations.reply.message": "Répondre maintenant écrasera le message que vous composez actuellement. Êtes-vous sûr·e de vouloir continuer ?",
+  "confirmations.reply.message": "Répondre maintenant écrasera le message que vous rédigez actuellement. Voulez-vous vraiment continuer ?",
   "confirmations.unfollow.confirm": "Ne plus suivre",
-  "confirmations.unfollow.message": "Êtes-vous sûr·e de vouloir arrêter de suivre {name} ?",
+  "confirmations.unfollow.message": "Voulez-vous vraiment arrêter de suivre {name} ?",
   "conversation.delete": "Supprimer la conversation",
   "conversation.mark_as_read": "Marquer comme lu",
   "conversation.open": "Afficher la conversation",
   "conversation.with": "Avec {names}",
   "directory.federated": "Du fédiverse connu",
   "directory.local": "De {domain} seulement",
-  "directory.new_arrivals": "Nouveaux·elles arrivant·e·s",
-  "directory.recently_active": "Récemment actif·ve·s",
+  "directory.new_arrivals": "Inscrit·e·s récemment",
+  "directory.recently_active": "Actif·ve·s récemment",
   "embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.",
   "embed.preview": "Il apparaîtra comme cela :",
-  "emoji_button.activity": "Activités",
+  "emoji_button.activity": "Activité",
   "emoji_button.custom": "Personnalisés",
   "emoji_button.flags": "Drapeaux",
   "emoji_button.food": "Nourriture & Boisson",
@@ -136,7 +136,7 @@
   "emoji_button.objects": "Objets",
   "emoji_button.people": "Personnes",
   "emoji_button.recent": "Fréquemment utilisés",
-  "emoji_button.search": "Recherche…",
+  "emoji_button.search": "Recherche...",
   "emoji_button.search_results": "Résultats de la recherche",
   "emoji_button.symbols": "Symboles",
   "emoji_button.travel": "Lieux & Voyages",
@@ -155,7 +155,7 @@
   "empty_column.home.public_timeline": "le fil public",
   "empty_column.list": "Il n’y a rien dans cette liste pour l’instant. Dès que des personnes de cette liste publieront de nouveaux statuts, ils apparaîtront ici.",
   "empty_column.lists": "Vous n’avez pas encore de liste. Lorsque vous en créerez une, elle apparaîtra ici.",
-  "empty_column.mutes": "Vous n’avez pas encore silencié d’utilisateur·rice·s.",
+  "empty_column.mutes": "Vous n’avez masqué aucun·e utilisateur·rice pour le moment.",
   "empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres personnes pour débuter la conversation.",
   "empty_column.public": "Il n’y a rien ici ! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes d’autres serveurs pour remplir le fil public",
   "error.unexpected_crash.explanation": "En raison d’un bug dans notre code ou d’un problème de compatibilité avec votre navigateur, cette page n’a pas pu être affichée correctement.",
@@ -176,12 +176,12 @@
   "hashtag.column_header.tag_mode.any": "ou {additional}",
   "hashtag.column_header.tag_mode.none": "sans {additional}",
   "hashtag.column_settings.select.no_options_message": "Aucune suggestion trouvée",
-  "hashtag.column_settings.select.placeholder": "Ajouter des hashtags…",
+  "hashtag.column_settings.select.placeholder": "Entrer des hashtags…",
   "hashtag.column_settings.tag_mode.all": "Tous ces éléments",
   "hashtag.column_settings.tag_mode.any": "Au moins un de ces éléments",
   "hashtag.column_settings.tag_mode.none": "Aucun de ces éléments",
-  "hashtag.column_settings.tag_toggle": "Inclure des mots-clés additionnels dans cette colonne",
-  "home.column_settings.basic": "Base",
+  "hashtag.column_settings.tag_toggle": "Inclure des hashtags additionnels pour cette colonne",
+  "home.column_settings.basic": "Basique",
   "home.column_settings.show_reblogs": "Afficher les partages",
   "home.column_settings.show_replies": "Afficher les réponses",
   "home.hide_announcements": "Masquer les annonces",
@@ -199,46 +199,46 @@
   "introduction.interactions.action": "Finir le tutoriel !",
   "introduction.interactions.favourite.headline": "Favoris",
   "introduction.interactions.favourite.text": "Vous pouvez garder un pouet pour plus tard et faire savoir à son auteur·ice que vous l’avez aimé, en l'ajoutant aux favoris.",
-  "introduction.interactions.reblog.headline": "Repartager",
+  "introduction.interactions.reblog.headline": "Partager",
   "introduction.interactions.reblog.text": "Vous pouvez partager les pouets d'autres personnes avec vos abonné·e·s en les repartageant.",
   "introduction.interactions.reply.headline": "Répondre",
   "introduction.interactions.reply.text": "Vous pouvez répondre aux pouets d'autres personnes et à vos propres pouets, ce qui les enchaînera dans une conversation.",
   "introduction.welcome.action": "Allons-y !",
   "introduction.welcome.headline": "Premiers pas",
   "introduction.welcome.text": "Bienvenue dans le fédiverse ! Dans quelques instants, vous pourrez diffuser des messages et parler à vos ami·e·s sur une grande variété de serveurs. Mais ce serveur, {domain}, est spécial - il héberge votre profil, alors souvenez-vous de son nom.",
-  "keyboard_shortcuts.back": "pour revenir en arrière",
-  "keyboard_shortcuts.blocked": "pour ouvrir la liste des comptes bloqués",
-  "keyboard_shortcuts.boost": "pour partager",
-  "keyboard_shortcuts.column": "pour focaliser un statut dans l’une des colonnes",
-  "keyboard_shortcuts.compose": "pour focaliser la zone de rédaction",
+  "keyboard_shortcuts.back": "revenir en arrière",
+  "keyboard_shortcuts.blocked": "ouvrir la liste des comptes bloqués",
+  "keyboard_shortcuts.boost": "partager",
+  "keyboard_shortcuts.column": "cibler un pouet d’une des colonnes",
+  "keyboard_shortcuts.compose": "cibler la zone de rédaction",
   "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.direct": "pour ouvrir la colonne des messages directs",
-  "keyboard_shortcuts.down": "pour descendre dans la liste",
-  "keyboard_shortcuts.enter": "pour ouvrir le statut",
-  "keyboard_shortcuts.favourite": "pour ajouter aux favoris",
-  "keyboard_shortcuts.favourites": "pour ouvrir la liste des pouets favoris",
-  "keyboard_shortcuts.federated": "pour ouvrir le fil public global",
+  "keyboard_shortcuts.direct": "ouvrir la colonne des messages directs",
+  "keyboard_shortcuts.down": "descendre dans la liste",
+  "keyboard_shortcuts.enter": "ouvrir le pouet",
+  "keyboard_shortcuts.favourite": "ajouter aux favoris",
+  "keyboard_shortcuts.favourites": "ouvrir la liste des favoris",
+  "keyboard_shortcuts.federated": "ouvrir le fil public global",
   "keyboard_shortcuts.heading": "Raccourcis clavier",
-  "keyboard_shortcuts.home": "pour ouvrir l’accueil",
-  "keyboard_shortcuts.hotkey": "Raccourci",
-  "keyboard_shortcuts.legend": "pour afficher cette légende",
-  "keyboard_shortcuts.local": "pour ouvrir le fil public local",
-  "keyboard_shortcuts.mention": "pour mentionner l’auteur·rice",
-  "keyboard_shortcuts.muted": "pour ouvrir la liste des utilisateur·rice·s muté·e·s",
-  "keyboard_shortcuts.my_profile": "pour ouvrir votre profil",
-  "keyboard_shortcuts.notifications": "pour ouvrir votre colonne de notifications",
-  "keyboard_shortcuts.open_media": "pour ouvrir le média",
-  "keyboard_shortcuts.pinned": "pour ouvrir une liste des pouets épinglés",
-  "keyboard_shortcuts.profile": "pour ouvrir le profil de l’auteur·rice",
-  "keyboard_shortcuts.reply": "pour répondre",
-  "keyboard_shortcuts.requests": "pour ouvrir la liste de demandes de suivi",
-  "keyboard_shortcuts.search": "pour cibler la recherche",
-  "keyboard_shortcuts.start": "pour ouvrir la colonne « pour commencer »",
-  "keyboard_shortcuts.toggle_hidden": "pour afficher/cacher un texte derrière CW",
-  "keyboard_shortcuts.toggle_sensitivity": "pour afficher/cacher les médias",
-  "keyboard_shortcuts.toot": "pour démarrer un tout nouveau pouet",
-  "keyboard_shortcuts.unfocus": "pour quitter la zone de composition/recherche",
-  "keyboard_shortcuts.up": "pour remonter dans la liste",
+  "keyboard_shortcuts.home": "le fil d’accueil",
+  "keyboard_shortcuts.hotkey": "Raccourci clavier",
+  "keyboard_shortcuts.legend": "afficher cet aide-mémoire",
+  "keyboard_shortcuts.local": "ouvrir le fil public local",
+  "keyboard_shortcuts.mention": "mentionner l’auteur·rice",
+  "keyboard_shortcuts.muted": "ouvrir la liste des comptes masqués",
+  "keyboard_shortcuts.my_profile": "ouvrir votre profil",
+  "keyboard_shortcuts.notifications": "ouvrir la colonne de notifications",
+  "keyboard_shortcuts.open_media": "ouvrir le média",
+  "keyboard_shortcuts.pinned": "ouvrir la liste des pouets épinglés",
+  "keyboard_shortcuts.profile": "ouvrir le profil de l’auteur·rice",
+  "keyboard_shortcuts.reply": "répondre",
+  "keyboard_shortcuts.requests": "ouvrir la liste de demandes d’abonnement",
+  "keyboard_shortcuts.search": "cibler la zone de recherche",
+  "keyboard_shortcuts.start": "ouvrir la colonne « Pour commencer »",
+  "keyboard_shortcuts.toggle_hidden": "déplier/replier le texte derrière un CW",
+  "keyboard_shortcuts.toggle_sensitivity": "afficher/cacher les médias",
+  "keyboard_shortcuts.toot": "démarrer un tout nouveau pouet",
+  "keyboard_shortcuts.unfocus": "quitter la zone de rédaction/recherche",
+  "keyboard_shortcuts.up": "remonter dans la liste",
   "lightbox.close": "Fermer",
   "lightbox.next": "Suivant",
   "lightbox.previous": "Précédent",
@@ -254,7 +254,7 @@
   "lists.subheading": "Vos listes",
   "load_pending": "{count, plural, one {# nouvel élément} other {# nouveaux éléments}}",
   "loading_indicator.label": "Chargement…",
-  "media_gallery.toggle_visible": "Modifier la visibilité",
+  "media_gallery.toggle_visible": "Intervertir la visibilité",
   "missing_indicator.label": "Non trouvé",
   "missing_indicator.sublabel": "Ressource introuvable",
   "mute_modal.hide_notifications": "Masquer les notifications de cette personne ?",
@@ -268,7 +268,7 @@
   "navigation_bar.domain_blocks": "Domaines cachés",
   "navigation_bar.edit_profile": "Modifier le profil",
   "navigation_bar.favourites": "Favoris",
-  "navigation_bar.filters": "Mots silenciés",
+  "navigation_bar.filters": "Mots masqués",
   "navigation_bar.follow_requests": "Demandes de suivi",
   "navigation_bar.follows_and_followers": "Abonnements et abonné⋅e·s",
   "navigation_bar.info": "À propos de ce serveur",
@@ -287,15 +287,15 @@
   "notification.mention": "{name} vous a mentionné·e :",
   "notification.own_poll": "Votre sondage est terminé",
   "notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
-  "notification.reblog": "{name} a partagé votre statut :",
-  "notifications.clear": "Nettoyer les notifications",
-  "notifications.clear_confirmation": "Voulez-vous vraiment supprimer toutes vos notifications ?",
-  "notifications.column_settings.alert": "Notifications locales",
+  "notification.reblog": "{name} a partagé votre statut",
+  "notifications.clear": "Effacer les notifications",
+  "notifications.clear_confirmation": "Voulez-vous vraiment effacer toutes vos notifications ?",
+  "notifications.column_settings.alert": "Notifications du navigateur",
   "notifications.column_settings.favourite": "Favoris :",
   "notifications.column_settings.filter_bar.advanced": "Afficher toutes les catégories",
   "notifications.column_settings.filter_bar.category": "Barre de filtrage rapide",
   "notifications.column_settings.filter_bar.show": "Afficher",
-  "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e·s :",
+  "notifications.column_settings.follow": "Nouveaux·elles abonné·e·s :",
   "notifications.column_settings.follow_request": "Nouvelles demandes d’abonnement :",
   "notifications.column_settings.mention": "Mentions :",
   "notifications.column_settings.poll": "Résultats des sondage :",
@@ -306,7 +306,7 @@
   "notifications.filter.all": "Tout",
   "notifications.filter.boosts": "Partages",
   "notifications.filter.favourites": "Favoris",
-  "notifications.filter.follows": "Abonné·e·s",
+  "notifications.filter.follows": "Abonnés",
   "notifications.filter.mentions": "Mentions",
   "notifications.filter.polls": "Résultats des sondages",
   "notifications.group": "{count} notifications",
@@ -321,8 +321,8 @@
   "privacy.change": "Ajuster la confidentialité du message",
   "privacy.direct.long": "N’envoyer qu’aux personnes mentionnées",
   "privacy.direct.short": "Direct",
-  "privacy.private.long": "Seul⋅e⋅s vos abonné⋅e⋅s verront vos statuts",
-  "privacy.private.short": "Abonné⋅e⋅s uniquement",
+  "privacy.private.long": "Seul·e·s vos abonné·e·s verront vos statuts",
+  "privacy.private.short": "Abonné·e·s uniquement",
   "privacy.public.long": "Afficher dans les fils publics",
   "privacy.public.short": "Public",
   "privacy.unlisted.long": "Ne pas afficher dans les fils publics",
@@ -347,22 +347,22 @@
   "search_popout.search_format": "Recherche avancée",
   "search_popout.tips.full_text": "Un texte normal retourne les pouets que vous avez écris, mis en favori, partagés, ou vous mentionnant, ainsi que les identifiants, les noms affichés, et les hashtags des personnes et messages correspondant.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "statuts",
+  "search_popout.tips.status": "pouet",
   "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les identifiants et les hashtags correspondants",
-  "search_popout.tips.user": "utilisateur⋅ice",
+  "search_popout.tips.user": "utilisateur·ice",
   "search_results.accounts": "Comptes",
   "search_results.hashtags": "Hashtags",
   "search_results.statuses": "Pouets",
   "search_results.statuses_fts_disabled": "La recherche de pouets par leur contenu n'est pas activée sur ce serveur Mastodon.",
   "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
   "status.admin_account": "Ouvrir l’interface de modération pour @{name}",
-  "status.admin_status": "Ouvrir ce statut dans l’interface de modération",
+  "status.admin_status": "Ouvrir ce pouet dans l’interface de modération",
   "status.block": "Bloquer @{name}",
   "status.bookmark": "Ajouter aux marque-pages",
   "status.cancel_reblog_private": "Annuler le partage",
   "status.cannot_reblog": "Ce pouet ne peut pas être partagé",
   "status.copy": "Copier le lien vers le pouet",
-  "status.delete": "Effacer",
+  "status.delete": "Supprimer",
   "status.detailed_status": "Vue détaillée de la conversation",
   "status.direct": "Envoyer un message direct à @{name}",
   "status.embed": "Intégrer",
@@ -374,15 +374,15 @@
   "status.more": "Plus",
   "status.mute": "Masquer @{name}",
   "status.mute_conversation": "Masquer la conversation",
-  "status.open": "Déplier ce statut",
+  "status.open": "Voir les détails du pouet",
   "status.pin": "Épingler sur le profil",
   "status.pinned": "Pouet épinglé",
   "status.read_more": "En savoir plus",
   "status.reblog": "Partager",
   "status.reblog_private": "Partager à l’audience originale",
-  "status.reblogged_by": "{name} a partagé :",
+  "status.reblogged_by": "{name} a partagé",
   "status.reblogs.empty": "Personne n’a encore partagé ce pouet. Lorsque quelqu’un le fera, il apparaîtra ici.",
-  "status.redraft": "Effacer et ré-écrire",
+  "status.redraft": "Supprimer et ré-écrire",
   "status.remove_bookmark": "Retirer des marque-pages",
   "status.reply": "Répondre",
   "status.replyAll": "Répondre au fil",
@@ -393,7 +393,7 @@
   "status.show_less_all": "Tout replier",
   "status.show_more": "Déplier",
   "status.show_more_all": "Tout déplier",
-  "status.show_thread": "Lire le fil",
+  "status.show_thread": "Montrer le fil",
   "status.uncached_media_warning": "Indisponible",
   "status.unmute_conversation": "Ne plus masquer la conversation",
   "status.unpin": "Retirer du profil",
@@ -409,7 +409,7 @@
   "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} restantes",
   "time_remaining.moments": "Encore quelques instants",
   "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} restantes",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {personne} other {personnes}} discutent",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {personne discute} other {personnes discutent}}",
   "trends.trending_now": "Tendance en ce moment",
   "ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.",
   "upload_area.title": "Glissez et déposez pour envoyer",
diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json
index 0e9c9d6d1..b69ec2b95 100644
--- a/app/javascript/mastodon/locales/ga.json
+++ b/app/javascript/mastodon/locales/ga.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 76657cdde..f26b39c21 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -128,7 +128,7 @@
   "embed.preview": "Así será mostrado:",
   "emoji_button.activity": "Actividade",
   "emoji_button.custom": "Personalizado",
-  "emoji_button.flags": "Bandeiras",
+  "emoji_button.flags": "Marcas",
   "emoji_button.food": "Comida e Bebida",
   "emoji_button.label": "Inserir emoticona",
   "emoji_button.nature": "Natureza",
@@ -150,33 +150,33 @@
   "empty_column.favourited_statuses": "Aínda non tes toots favoritos. Cando che goste algún, aparecerá aquí.",
   "empty_column.favourites": "A ninguén lle gostou este toot polo momento. Cando a alguén lle goste, aparecerá aquí.",
   "empty_column.follow_requests": "Non tes peticións de seguimento. Cando recibas unha, amosarase aquí.",
-  "empty_column.hashtag": "Aínda non hai nada con este cancelo.",
+  "empty_column.hashtag": "Aínda non hai nada con esta etiqueta.",
   "empty_column.home": "A túa cronoloxía inicial está baleira! Visita {public} ou emprega a procura para atopar outras usuarias.",
   "empty_column.home.public_timeline": "a cronoloxía pública",
   "empty_column.list": "Aínda non hai nada en esta lista. Cando as usuarias incluídas na lista publiquen mensaxes, aparecerán aquí.",
   "empty_column.lists": "Aínda non tes listaxes. Cando crees unha, amosarase aquí.",
   "empty_column.mutes": "Aínda non silenciaches a ningúnha usuaria.",
-  "empty_column.notifications": "Aínda non tes notificacións. Interactúa con outros para comezar unha conversa.",
+  "empty_column.notifications": "Aínda non tes notificacións. Interactúa con outras para comezar unha conversa.",
   "empty_column.public": "Nada por aquí! Escribe algo de xeito público, ou segue de xeito manual usuarias doutros servidores para ir enchéndoo",
   "error.unexpected_crash.explanation": "Debido a un erro no noso código ou a unha compatilidade co teu navegador, esta páxina non pode ser amosada correctamente.",
-  "error.unexpected_crash.next_steps": "Tenta actualizar a páxina. Se esto non axuda podes tamén empregar o Mastodon noutro navegador ou aplicación nativa.",
+  "error.unexpected_crash.next_steps": "Tenta actualizar a páxina. Se esto non axuda podes tamén empregar Mastodon noutro navegador ou aplicación nativa.",
   "errors.unexpected_crash.copy_stacktrace": "Copiar trazas (stacktrace) ó portapapeis",
-  "errors.unexpected_crash.report_issue": "Denunciar un problema",
+  "errors.unexpected_crash.report_issue": "Informar sobre un problema",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Rexeitar",
-  "getting_started.developers": "Desenvolvedores",
+  "getting_started.developers": "Desenvolvedoras",
   "getting_started.directory": "Directorio local",
   "getting_started.documentation": "Documentación",
   "getting_started.heading": "Primeiros pasos",
   "getting_started.invite": "Convidar persoas",
-  "getting_started.open_source_notice": "O Mastodon é software de código aberto. Podes contribuír ou informar de fallos no GitHub en {github}.",
+  "getting_started.open_source_notice": "Mastodon é software de código aberto. Podes contribuír ou informar de fallos en GitHub en {github}.",
   "getting_started.security": "Seguranza",
   "getting_started.terms": "Termos do servizo",
   "hashtag.column_header.tag_mode.all": "e {additional}",
   "hashtag.column_header.tag_mode.any": "ou {additional}",
   "hashtag.column_header.tag_mode.none": "sen {additional}",
   "hashtag.column_settings.select.no_options_message": "Non se atoparon suxestións",
-  "hashtag.column_settings.select.placeholder": "Inserir cancelos…",
+  "hashtag.column_settings.select.placeholder": "Inserir etiquetas…",
   "hashtag.column_settings.tag_mode.all": "Todos estes",
   "hashtag.column_settings.tag_mode.any": "Calquera destes",
   "hashtag.column_settings.tag_mode.none": "Ningún destes",
@@ -192,7 +192,7 @@
   "introduction.federation.action": "Seguinte",
   "introduction.federation.federated.headline": "Federado",
   "introduction.federation.federated.text": "Publicacións públicas doutros servidores do fediverso aparecerán na cronoloxía federada.",
-  "introduction.federation.home.headline": "Páxina inicial",
+  "introduction.federation.home.headline": "Inicio",
   "introduction.federation.home.text": "Publicacións de persoas que ti segues aparecerán na cronoloxía do inicio. Podes seguir calquera persoa en calquera servidor!",
   "introduction.federation.local.headline": "Local",
   "introduction.federation.local.text": "Publicacións públicas de persoas no teu mesmo servidor aparecerán na cronoloxía local.",
@@ -205,7 +205,7 @@
   "introduction.interactions.reply.text": "Podes responder ós toots doutras persoas e ós teus propios, así ficarán encadeados nunha conversa.",
   "introduction.welcome.action": "Imos!",
   "introduction.welcome.headline": "Primeiros pasos",
-  "introduction.welcome.text": "Benvido ó fediverso! Nun intre poderás difundir mensaxes e falar coas túas amizades nun grande número de servidores. Mais este servidor, {domain}, é especial—hospeda o teu perfil, por iso lémbrate do seu nome.",
+  "introduction.welcome.text": "Benvida ó fediverso! Nun intre poderás difundir mensaxes e falar coas túas amizades nun grande número de servidores. Mais este servidor, {domain}, é especial—hospeda o teu perfil, por iso lémbra o seu nome.",
   "keyboard_shortcuts.back": "para voltar atrás",
   "keyboard_shortcuts.blocked": "abrir lista de usuarias bloqueadas",
   "keyboard_shortcuts.boost": "promover",
@@ -270,7 +270,7 @@
   "navigation_bar.favourites": "Favoritos",
   "navigation_bar.filters": "Palabras silenciadas",
   "navigation_bar.follow_requests": "Peticións de seguimento",
-  "navigation_bar.follows_and_followers": "Seguindo e seguidores",
+  "navigation_bar.follows_and_followers": "Seguindo e seguidoras",
   "navigation_bar.info": "Sobre este servidor",
   "navigation_bar.keyboard_shortcuts": "Atallos do teclado",
   "navigation_bar.lists": "Listaxes",
@@ -295,7 +295,7 @@
   "notifications.column_settings.filter_bar.advanced": "Amosar todas as categorías",
   "notifications.column_settings.filter_bar.category": "Barra de filtrado rápido",
   "notifications.column_settings.filter_bar.show": "Amosar",
-  "notifications.column_settings.follow": "Novos seguidores:",
+  "notifications.column_settings.follow": "Novas seguidoras:",
   "notifications.column_settings.follow_request": "Novas peticións de seguimento:",
   "notifications.column_settings.mention": "Mencións:",
   "notifications.column_settings.poll": "Resultados da enquisa:",
@@ -312,7 +312,7 @@
   "notifications.group": "{count} notificacións",
   "poll.closed": "Pechado",
   "poll.refresh": "Actualizar",
-  "poll.total_people": "{count, plural,one {# persoa}other {# persoas}}",
+  "poll.total_people": "{count, plural,one {# persoa} other {# persoas}}",
   "poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
   "poll.vote": "Votar",
   "poll.voted": "Votaches por esta opción",
@@ -321,14 +321,14 @@
   "privacy.change": "Axustar privacidade",
   "privacy.direct.long": "Só para as usuarias mencionadas",
   "privacy.direct.short": "Directo",
-  "privacy.private.long": "Só para os seguidores",
-  "privacy.private.short": "Só seguidores",
+  "privacy.private.long": "Só para os seguidoras",
+  "privacy.private.short": "Só para seguidoras",
   "privacy.public.long": "Publicar nas cronoloxías públicas",
   "privacy.public.short": "Público",
   "privacy.unlisted.long": "Non publicar nas cronoloxías públicas",
   "privacy.unlisted.short": "Non listado",
   "refresh": "Actualizar",
-  "regeneration_indicator.label": "Estase a cargar…",
+  "regeneration_indicator.label": "Cargando…",
   "regeneration_indicator.sublabel": "Estase a preparar a túa cronoloxía de inicio!",
   "relative_time.days": "{number}d",
   "relative_time.hours": "{number}h",
@@ -365,7 +365,7 @@
   "status.delete": "Eliminar",
   "status.detailed_status": "Vista detallada da conversa",
   "status.direct": "Mensaxe directa a @{name}",
-  "status.embed": "Embeber nunha web",
+  "status.embed": "Incrustar",
   "status.favourite": "Favorito",
   "status.filtered": "Filtrado",
   "status.load_more": "Cargar máis",
@@ -411,7 +411,7 @@
   "time_remaining.seconds": "{number, plural, one {# segundo} other {# segundos}} restantes",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {persoa} other {persoas}} falando",
   "trends.trending_now": "Tendencias actuais",
-  "ui.beforeunload": "O borrador perderase se saes do Mastodon.",
+  "ui.beforeunload": "O borrador perderase se saes de Mastodon.",
   "upload_area.title": "Arrastra e solta para subir",
   "upload_button.label": "Engadir multimedia ({formats})",
   "upload_error.limit": "Límite máximo do ficheiro a subir excedido.",
diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json
index d4659bc2e..ee9d701b0 100644
--- a/app/javascript/mastodon/locales/hi.json
+++ b/app/javascript/mastodon/locales/hi.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "लोड हो रहा है...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "नहीं मिला",
   "missing_indicator.sublabel": "यह संसाधन नहीं मिल सका।",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index b25369326..d2d851436 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -130,7 +130,7 @@
   "emoji_button.custom": "Egyéni",
   "emoji_button.flags": "Zászlók",
   "emoji_button.food": "Étel és Ital",
-  "emoji_button.label": "Emoji beszúrása",
+  "emoji_button.label": "Emodzsi beszúrása",
   "emoji_button.nature": "Természet",
   "emoji_button.not_found": "Nincsenek emodzsik!! (╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "Tárgyak",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 6a0e825b0..b3f1df94c 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -40,10 +40,10 @@
   "account.unmute": "Ապալռեցնել @{name}֊ին",
   "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից",
   "alert.rate_limited.message": "Փորձէք  որոշ ժամանակ անց՝ {retry_time, time, medium}։",
-  "alert.rate_limited.title": "Rate limited",
+  "alert.rate_limited.title": "Գործողությունների հաճախությունը գերազանցում է թույլատրելին",
   "alert.unexpected.message": "Անսպասելի սխալ տեղի ունեցաւ։",
   "alert.unexpected.title": "Վա՜յ",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "Հայտարարություններ",
   "autosuggest_hashtag.per_week": "շաբաթը՝ {count}",
   "boost_modal.combo": "Կարող ես սեղմել {combo}՝ սա հաջորդ անգամ բաց թողնելու համար",
   "bundle_column_error.body": "Այս բաղադրիչը բեռնելու ընթացքում ինչ֊որ բան խափանվեց։",
@@ -85,8 +85,8 @@
   "compose_form.poll.duration": "Հարցման տեւողութիւնը",
   "compose_form.poll.option_placeholder": "Տարբերակ {number}",
   "compose_form.poll.remove_option": "Հեռացնել այս տարբերակը",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "Հարցումը դարձնել բազմակի ընտրությամբ",
+  "compose_form.poll.switch_to_single": "Հարցումը դարձնել եզակի ընտրությամբ",
   "compose_form.publish": "Թթել",
   "compose_form.publish_loud": "Թթե՜լ",
   "compose_form.sensitive.hide": "Նշել մեդիան որպէս դիւրազգաց",
@@ -143,29 +143,29 @@
   "empty_column.account_timeline": "Այստեղ թթեր չկա՛ն։",
   "empty_column.account_unavailable": "Անձնական էջը հասանելի չի",
   "empty_column.blocks": "Դու դեռ ոչ մէկի չես արգելափակել։",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
+  "empty_column.bookmarked_statuses": "Դու դեռ չունես որեւէ էջանշւած թութ։ Երբ էջանշես, դրանք կերեւան այստեղ։",
   "empty_column.community": "Տեղական հոսքը դատա՛րկ է։ Հրապարակային մի բան գրիր շարժիչը խոդ տալու համար։",
   "empty_column.direct": "Դու դեռ չունես ոչ մի հասցէագրուած հաղորդագրութիւն։ Երբ ուղարկես կամ ստանաս որեւէ անձնական նամակ, այն այստեղ կերեւայ։",
   "empty_column.domain_blocks": "Թաքցուած տիրոյթներ դեռ չկան։",
   "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.follow_requests": "Դու դեռ չունես որեւէ հետևելու հայտ։ Բոլոր նման հայտերը կհայտնվեն այստեղ։",
   "empty_column.hashtag": "Այս պիտակով դեռ ոչինչ չկա։",
   "empty_column.home": "Քո հիմնական հոսքը դատա՛րկ է։ Այցելի՛ր {public}ը կամ օգտվիր որոնումից՝ այլ մարդկանց հանդիպելու համար։",
   "empty_column.home.public_timeline": "հրապարակային հոսք",
   "empty_column.list": "Այս ցանկում դեռ ոչինչ չկա։ Երբ ցանկի անդամներից որեւէ մեկը նոր թութ գրի, այն կհայտնվի այստեղ։",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "Առայժմ ոչ ոքի չեք արգելափակել։",
+  "empty_column.lists": "Դուք դեռ չունեք ստեղծած ցանկ։ Ցանկ ստեղծելուն պես այն կհայտնվի այստեղ։",
+  "empty_column.mutes": "Առայժմ ոչ ոքի չեք լռեցրել։",
   "empty_column.notifications": "Ոչ մի ծանուցում դեռ չունես։ Բզիր մյուսներին՝ խոսակցությունը սկսելու համար։",
   "empty_column.public": "Այստեղ բան չկա՛։ Հրապարակային մի բան գրիր կամ հետեւիր այլ հանգույցներից էակների՝ այն լցնելու համար։",
-  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
-  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
-  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "error.unexpected_crash.explanation": "Մեր ծրագրակազմում վրիպակի կամ դիտարկչի անհամատեղելիության պատճառով այս էջը չի կարող լիարժեք պատկերվել։",
+  "error.unexpected_crash.next_steps": "Փորձիր թարմացնել էջը։ Եթե դա չօգնի ապա կարող ես օգտվել Մաստադոնից ուրիշ դիտարկիչով կամ հավելվածով։",
+  "errors.unexpected_crash.copy_stacktrace": "Պատճենել սթաքթրեյսը սեղմատախտակին",
   "errors.unexpected_crash.report_issue": "Զեկուցել խնդրի մասին",
   "follow_request.authorize": "Վավերացնել",
   "follow_request.reject": "Մերժել",
   "getting_started.developers": "Մշակողներ",
-  "getting_started.directory": "Պրոֆիլի տեղադրավայրը",
+  "getting_started.directory": "Օգտատերերի շտեմարան",
   "getting_started.documentation": "Փաստաթղթեր",
   "getting_started.heading": "Ինչպես սկսել",
   "getting_started.invite": "Հրավիրել մարդկանց",
@@ -175,8 +175,8 @@
   "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": "No suggestions found",
-  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.select.no_options_message": "Առաջարկներ չկան",
+  "hashtag.column_settings.select.placeholder": "Ավելացրու հեշթեգեր…",
   "hashtag.column_settings.tag_mode.all": "Բոլորը",
   "hashtag.column_settings.tag_mode.any": "Ցանկացածը",
   "hashtag.column_settings.tag_mode.none": "Ոչ մեկը",
@@ -184,50 +184,50 @@
   "home.column_settings.basic": "Հիմնական",
   "home.column_settings.show_reblogs": "Ցուցադրել տարածածները",
   "home.column_settings.show_replies": "Ցուցադրել պատասխանները",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
-  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
-  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
-  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "home.hide_announcements": "Թաքցնել հայտարարությունները",
+  "home.show_announcements": "Ցուցադրել հայտարարությունները",
+  "intervals.full.days": "{number, plural, one {# օր} other {# օր}}",
+  "intervals.full.hours": "{number, plural, one {# ժամ} other {# ժամ}}",
+  "intervals.full.minutes": "{number, plural, one {# րոպե} other {# րոպե}}",
   "introduction.federation.action": "Հաջորդ",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.federated.headline": "Դաշնային",
+  "introduction.federation.federated.text": "Դաշտնեզերքի հարևան հանգույցների հանրային գրառումները կհայտնվեն դաշնային հոսքում։",
   "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.home.text": "Այն անձանց թթերը ում հետևում ես, կհայտնվի հիմնական հոսքում։ Դու կարող ես հետևել ցանկացած անձի ցանկացած հանգույցից։",
   "introduction.federation.local.headline": "Տեղային",
-  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
+  "introduction.federation.local.text": "Տեղական հոսքում կարող ես տեսնել քո հանգույցի բոլոր հանրային գրառումները։",
   "introduction.interactions.action": "Finish toot-orial!",
   "introduction.interactions.favourite.headline": "Նախընտրելի",
-  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.favourite.text": "Փոխանցիր հեղինակին որ քեզ դուր է եկել իր թութը հավանելով այն։",
   "introduction.interactions.reblog.headline": "Տարածել",
-  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reblog.text": "Կիսիր այլ օգտատերերի թութերը քո հետևորդների հետ տարածելով դրանք քո անձնական էջում։",
   "introduction.interactions.reply.headline": "Պատասխանել",
-  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+  "introduction.interactions.reply.text": "Արձագանքիր ուրիշների և քո թթերին, դրանք կդարսվեն մեկ ընհանուր քննարկման շղթայով։",
   "introduction.welcome.action": "Գնացի՜նք։",
   "introduction.welcome.headline": "Առաջին քայլեր",
-  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+  "introduction.welcome.text": "Դաշնեզերքը ողջունում է ձեզ։ Շուտով կկարողանաս ուղարկել նամակներ ու շփվել տարբեր հանգույցների ընկերներիդ հետ։ Բայց մտապահիր {domain} հանգույցը, այն յուրահատուկ է, այստեղ է պահվում քո հաշիվը։",
   "keyboard_shortcuts.back": "ետ նավարկելու համար",
   "keyboard_shortcuts.blocked": "արգելափակված օգտատերերի ցանկը բացելու համար",
   "keyboard_shortcuts.boost": "տարածելու համար",
   "keyboard_shortcuts.column": "սյուներից մեկի վրա սեւեռվելու համար",
   "keyboard_shortcuts.compose": "շարադրման տիրույթին սեւեռվելու համար",
   "keyboard_shortcuts.description": "Նկարագրություն",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "հասցեագրված գրվածքների հոսքը բացելու համար",
   "keyboard_shortcuts.down": "ցանկով ներքեւ շարժվելու համար",
   "keyboard_shortcuts.enter": "թութը բացելու համար",
   "keyboard_shortcuts.favourite": "հավանելու համար",
-  "keyboard_shortcuts.favourites": "to open favourites list",
-  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.favourites": "էջանիշերի ցուցակը բացելու համար",
+  "keyboard_shortcuts.federated": "դաշնային հոսքին անցնելու համար",
   "keyboard_shortcuts.heading": "Ստեղնաշարի կարճատներ",
-  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.home": "անձնական հոսքին անցնելու համար",
   "keyboard_shortcuts.hotkey": "Հատուկ ստեղն",
   "keyboard_shortcuts.legend": "այս ձեռնարկը ցուցադրելու համար",
-  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.local": "տեղական հոսքին անցնելու համար",
   "keyboard_shortcuts.mention": "հեղինակին նշելու համար",
-  "keyboard_shortcuts.muted": "to open muted users list",
-  "keyboard_shortcuts.my_profile": "to open your profile",
-  "keyboard_shortcuts.notifications": "to open notifications column",
-  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.muted": "լռեցված օգտատերերի ցանկը բացելու համար",
+  "keyboard_shortcuts.my_profile": "սեփական էջին անցնելու համար",
+  "keyboard_shortcuts.notifications": "ծանուցումեների սյունակը բացելու համար",
+  "keyboard_shortcuts.open_media": "ցուցադրել մեդիան",
   "keyboard_shortcuts.pinned": "ամրացուած թթերի ցանկը բացելու համար",
   "keyboard_shortcuts.profile": "հեղինակի անձնական էջը բացելու համար",
   "keyboard_shortcuts.reply": "պատասխանելու համար",
@@ -252,7 +252,7 @@
   "lists.new.title_placeholder": "Նոր ցանկի վերնագիր",
   "lists.search": "Փնտրել քո հետեւած մարդկանց մեջ",
   "lists.subheading": "Քո ցանկերը",
-  "load_pending": "{count, plural, one {# new item} other {# new items}}",
+  "load_pending": "{count, plural, one {# նոր նյութ} other {# նոր նյութ}}",
   "loading_indicator.label": "Բեռնվում է…",
   "media_gallery.toggle_visible": "Ցուցադրել/թաքցնել",
   "missing_indicator.label": "Չգտնվեց",
@@ -283,7 +283,7 @@
   "navigation_bar.security": "Անվտանգություն",
   "notification.favourite": "{name} հավանեց թութդ",
   "notification.follow": "{name} սկսեց հետեւել քեզ",
-  "notification.follow_request": "{name} has requested to follow you",
+  "notification.follow_request": "{name} քեզ հետևելու հայց է ուղարկել",
   "notification.mention": "{name} նշեց քեզ",
   "notification.own_poll": "Հարցումդ աւարտուեց",
   "notification.poll": "Հարցումը, ուր դու քուէարկել ես, աւարտուեց։",
@@ -296,7 +296,7 @@
   "notifications.column_settings.filter_bar.category": "Արագ զտման վահանակ",
   "notifications.column_settings.filter_bar.show": "Ցուցադրել",
   "notifications.column_settings.follow": "Նոր հետեւողներ՝",
-  "notifications.column_settings.follow_request": "New follow requests:",
+  "notifications.column_settings.follow_request": "Նոր հետեւելու հայցեր:",
   "notifications.column_settings.mention": "Նշումներ՝",
   "notifications.column_settings.poll": "Հարցման արդիւնքները՝",
   "notifications.column_settings.push": "Հրելու ծանուցումներ",
@@ -312,8 +312,8 @@
   "notifications.group": "{count} ծանուցում",
   "poll.closed": "Փակ",
   "poll.refresh": "Թարմացնել",
-  "poll.total_people": "{count, plural, one {# person} other {# people}}",
-  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.total_people": "{count, plural, one {# հոգի} other {# հոգի}}",
+  "poll.total_votes": "{count, plural, one {# ձայն} other {# ձայն}}",
   "poll.vote": "Քուէարկել",
   "poll.voted": "Դու քուէարկել ես այս տարբերակի համար",
   "poll_button.add_poll": "Աւելացնել հարցում",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "նոր",
   "relative_time.minutes": "{number}ր",
   "relative_time.seconds": "{number}վ",
-  "relative_time.today": "today",
+  "relative_time.today": "Այսօր",
   "reply_indicator.cancel": "Չեղարկել",
   "report.forward": "Փոխանցել {target}֊ին",
   "report.forward_hint": "Այս հաշիւ այլ հանգոյցից է։ Ուղարկե՞մ այնտեղ էլ այս բողոքի անոնիմ պատճէնը։",
@@ -361,10 +361,10 @@
   "status.bookmark": "Էջանիշ",
   "status.cancel_reblog_private": "Ապատարածել",
   "status.cannot_reblog": "Այս թութը չի կարող տարածվել",
-  "status.copy": "Copy link to status",
+  "status.copy": "Պատճենել գրառման հղումը",
   "status.delete": "Ջնջել",
-  "status.detailed_status": "Detailed conversation view",
-  "status.direct": "Direct message @{name}",
+  "status.detailed_status": "Շղթայի ընդլայնված դիտում",
+  "status.direct": "Նամակ գրել {name} -ին",
   "status.embed": "Ներդնել",
   "status.favourite": "Հավանել",
   "status.filtered": "Զտված",
@@ -376,57 +376,57 @@
   "status.mute_conversation": "Լռեցնել խոսակցությունը",
   "status.open": "Ընդարձակել այս թութը",
   "status.pin": "Ամրացնել անձնական էջում",
-  "status.pinned": "Pinned toot",
+  "status.pinned": "Ամրացված թութ",
   "status.read_more": "Կարդալ ավելին",
   "status.reblog": "Տարածել",
-  "status.reblog_private": "Boost to original audience",
+  "status.reblog_private": "Տարածել սեփական լսարանին",
   "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.reblogs.empty": "Այս թութը ոչ մէկ դեռ չի տարածել։ Տարածողները կերեւան այստեղ, երբ որևէ մեկը տարածի։",
+  "status.redraft": "Ջնջել եւ վերակազմել",
+  "status.remove_bookmark": "Հեռացնել էջանիշերից",
   "status.reply": "Պատասխանել",
   "status.replyAll": "Պատասխանել թելին",
   "status.report": "Բողոքել @{name}֊ից",
   "status.sensitive_warning": "Կասկածելի բովանդակություն",
   "status.share": "Կիսվել",
   "status.show_less": "Պակաս",
-  "status.show_less_all": "Show less for all",
+  "status.show_less_all": "Թաքցնել բոլոր նախազգուշացնումները",
   "status.show_more": "Ավելին",
-  "status.show_more_all": "Show more for all",
-  "status.show_thread": "Show thread",
+  "status.show_more_all": "Ցուցադրել բոլոր նախազգուշացնումները",
+  "status.show_thread": "Բացել շղթան",
   "status.uncached_media_warning": "Անհասանելի",
   "status.unmute_conversation": "Ապալռեցնել խոսակցությունը",
   "status.unpin": "Հանել անձնական էջից",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "Անտեսել առաջարկը",
+  "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.days": "{number, plural, one {մնաց # օր} other {մնաց # օր}}",
   "time_remaining.hours": "{number, plural, one {# ժամ} other {# ժամ}} անց",
   "time_remaining.minutes": "{number, plural, one {# րոպե} other {# րոպե}} անց",
-  "time_remaining.moments": "Moments remaining",
+  "time_remaining.moments": "Մնացել է մի քանի վարկյան",
   "time_remaining.seconds": "{number, plural, one {# վայրկյան} other {# վայրկյան}} անց",
-  "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
+  "trends.count_by_accounts": "{count} {rawCount, plural, one {հոգի} other {հոգի}} խոսում է սրա մասին",
   "trends.trending_now": "Այժմ արդիական",
   "ui.beforeunload": "Քո սեւագիրը կկորի, եթե լքես Մաստոդոնը։",
   "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_error.poll": "Հարցումների հետ ֆայլ կցել հնարավոր չէ։",
+  "upload_form.audio_description": "Նկարագրիր ձայնագրության բովանդակությունը լսողական խնդիրներով անձանց համար",
   "upload_form.description": "Նկարագրություն ավելացրու տեսողական խնդիրներ ունեցողների համար",
   "upload_form.edit": "Խմբագրել",
   "upload_form.undo": "Հետարկել",
-  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_form.video_description": "Նկարագրիր տեսանյութը լսողական կամ տեսողական խնդիրներով անձանց համար",
   "upload_modal.analyzing_picture": "Լուսանկարի վերլուծում…",
   "upload_modal.apply": "Կիրառել",
   "upload_modal.description_placeholder": "Ճկուն շագանակագույն աղվեսը ցատկում է ծույլ շան վրայով",
   "upload_modal.detect_text": "Հայտնբերել տեքստը նկարից",
   "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.hint": "Սեղմեք և տեղաշարժեք նախատեսքի վրայի շրջանակը ընտրելու այն կետը որը միշտ տեսանելի կլինի մանրապատկերներում։",
   "upload_modal.preview_label": "Նախադիտում ({ratio})",
   "upload_progress.label": "Վերբեռնվում է…",
   "video.close": "Փակել  տեսագրությունը",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 94f81116c..c1b47f860 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -5,7 +5,7 @@
   "account.block": "Blocca @{name}",
   "account.block_domain": "Nascondi tutto da {domain}",
   "account.blocked": "Bloccato",
-  "account.cancel_follow_request": "Annulla richiesta di seguito",
+  "account.cancel_follow_request": "Annulla richiesta di seguire",
   "account.direct": "Invia messaggio privato a @{name}",
   "account.domain_blocked": "Dominio nascosto",
   "account.edit_profile": "Modifica profilo",
@@ -36,7 +36,7 @@
   "account.unblock": "Sblocca @{name}",
   "account.unblock_domain": "Non nascondere {domain}",
   "account.unendorse": "Non mettere in evidenza sul profilo",
-  "account.unfollow": "Non seguire",
+  "account.unfollow": "Smetti di seguire",
   "account.unmute": "Non silenziare @{name}",
   "account.unmute_notifications": "Non silenziare più le notifiche da @{name}",
   "alert.rate_limited.message": "Riprova dopo {retry_time, time, medium}.",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index b1a9ad9ce..83c7db6c1 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -3,11 +3,11 @@
   "account.badges.bot": "Bot",
   "account.badges.group": "Group",
   "account.block": "@{name}さんをブロック",
-  "account.block_domain": "{domain}全体を非表示",
+  "account.block_domain": "{domain}全体をブロック",
   "account.blocked": "ブロック済み",
   "account.cancel_follow_request": "フォローリクエストを取り消す",
   "account.direct": "@{name}さんにダイレクトメッセージ",
-  "account.domain_blocked": "ドメイン非表示中",
+  "account.domain_blocked": "ドメインブロック中",
   "account.edit_profile": "プロフィール編集",
   "account.endorse": "プロフィールで紹介する",
   "account.follow": "フォロー",
@@ -34,7 +34,7 @@
   "account.share": "@{name}さんのプロフィールを共有する",
   "account.show_reblogs": "@{name}さんからのブーストを表示",
   "account.unblock": "@{name}さんのブロックを解除",
-  "account.unblock_domain": "{domain}の非表示を解除",
+  "account.unblock_domain": "{domain}のブロックを解除",
   "account.unendorse": "プロフィールから外す",
   "account.unfollow": "フォロー解除",
   "account.unmute": "@{name}さんのミュートを解除",
@@ -57,7 +57,7 @@
   "column.community": "ローカルタイムライン",
   "column.direct": "ダイレクトメッセージ",
   "column.directory": "ディレクトリ",
-  "column.domain_blocks": "非表示にしたドメイン",
+  "column.domain_blocks": "ブロックしたドメイン",
   "column.favourites": "お気に入り",
   "column.follow_requests": "フォローリクエスト",
   "column.home": "ホーム",
@@ -107,7 +107,7 @@
   "confirmations.delete.message": "本当に削除しますか?",
   "confirmations.delete_list.confirm": "削除",
   "confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?",
-  "confirmations.domain_block.confirm": "ドメイン全体を非表示",
+  "confirmations.domain_block.confirm": "ドメイン全体をブロック",
   "confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。公開タイムラインにそのドメインのコンテンツが表示されなくなり、通知も届かなくなります。そのドメインのフォロワーはアンフォローされます。",
   "confirmations.logout.confirm": "ログアウト",
   "confirmations.logout.message": "本当にログアウトしますか?",
@@ -150,7 +150,7 @@
   "empty_column.bookmarked_statuses": "まだ何もブックマーク登録していません。ブックマーク登録するとここに表示されます。",
   "empty_column.community": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!",
   "empty_column.direct": "ダイレクトメッセージはまだありません。ダイレクトメッセージをやりとりすると、ここに表示されます。",
-  "empty_column.domain_blocks": "非表示にしているドメインはありません。",
+  "empty_column.domain_blocks": "ブロックしているドメインはありません。",
   "empty_column.favourited_statuses": "まだ何もお気に入り登録していません。お気に入り登録するとここに表示されます。",
   "empty_column.favourites": "まだ誰もお気に入り登録していません。お気に入り登録されるとここに表示されます。",
   "empty_column.follow_requests": "まだフォローリクエストを受けていません。フォローリクエストを受けるとここに表示されます。",
@@ -258,7 +258,7 @@
   "lists.subheading": "あなたのリスト",
   "load_pending": "{count} 件の新着",
   "loading_indicator.label": "読み込み中...",
-  "media_gallery.toggle_visible": "表示切り替え",
+  "media_gallery.toggle_visible": "メディアを隠す",
   "missing_indicator.label": "見つかりません",
   "missing_indicator.sublabel": "見つかりませんでした",
   "mute_modal.hide_notifications": "このユーザーからの通知を隠しますか?",
@@ -269,7 +269,7 @@
   "navigation_bar.compose": "トゥートの新規作成",
   "navigation_bar.direct": "ダイレクトメッセージ",
   "navigation_bar.discover": "見つける",
-  "navigation_bar.domain_blocks": "非表示にしたドメイン",
+  "navigation_bar.domain_blocks": "ブロックしたドメイン",
   "navigation_bar.edit_profile": "プロフィールを編集",
   "navigation_bar.favourites": "お気に入り",
   "navigation_bar.filters": "フィルター設定",
@@ -324,13 +324,13 @@
   "poll_button.add_poll": "アンケートを追加",
   "poll_button.remove_poll": "アンケートを削除",
   "privacy.change": "公開範囲を変更",
-  "privacy.direct.long": "メンションしたユーザーだけに公開",
+  "privacy.direct.long": "送信した相手のみ閲覧可",
   "privacy.direct.short": "ダイレクト",
-  "privacy.private.long": "フォロワーだけに公開",
+  "privacy.private.long": "フォロワーのみ閲覧可",
   "privacy.private.short": "フォロワー限定",
-  "privacy.public.long": "公開TLに投稿する",
+  "privacy.public.long": "誰でも閲覧可、公開TLに表示",
   "privacy.public.short": "公開",
-  "privacy.unlisted.long": "公開TLで表示しない",
+  "privacy.unlisted.long": "誰でも閲覧可、公開TLに非表示",
   "privacy.unlisted.short": "未収載",
   "refresh": "更新",
   "regeneration_indicator.label": "読み込み中…",
diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json
index e78b4cc4f..8ce4c2774 100644
--- a/app/javascript/mastodon/locales/kab.json
+++ b/app/javascript/mastodon/locales/kab.json
@@ -1,51 +1,51 @@
 {
-  "account.add_or_remove_from_list": "Rnu neγ kkes seg tebdarin",
+  "account.add_or_remove_from_list": "Rnu neɣ kkes seg tebdarin",
   "account.badges.bot": "Aṛubut",
   "account.badges.group": "Agraw",
   "account.block": "Seḥbes @{name}",
   "account.block_domain": "Ffer kra i d-yekkan seg {domain}",
   "account.blocked": "Yettuseḥbes",
-  "account.cancel_follow_request": "Sefsex asuter n weḍfaṛ",
+  "account.cancel_follow_request": "Sefsex asuter n uḍfaṛ",
   "account.direct": "Izen usrid i @{name}",
-  "account.domain_blocked": "Taγult yeffren",
-  "account.edit_profile": "Ẓreg amaγnu",
-  "account.endorse": "Welleh fell-as deg umaγnu-inek",
+  "account.domain_blocked": "Taɣult yeffren",
+  "account.edit_profile": "Ẓreg amaɣnu",
+  "account.endorse": "Welleh fell-as deg umaɣnu-inek",
   "account.follow": "Ḍfeṛ",
   "account.followers": "Imeḍfaṛen",
   "account.followers.empty": "Ar tura, ulac yiwen i yeṭṭafaṛen amseqdac-agi.",
-  "account.follows": "Ig ṭafaṛ",
+  "account.follows": "I yeṭṭafaṛ",
   "account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.",
   "account.follows_you": "Yeṭṭafaṛ-ik",
   "account.hide_reblogs": "Ffer ayen i ibeṭṭu @{name}",
   "account.last_status": "Armud aneggaru",
   "account.link_verified_on": "Taγara n useγwen-a tettwasenqed ass n {date}",
   "account.locked_info": "Amiḍan-agi uslig isekweṛ. D bab-is kan i izemren ad yeǧǧ, s ufus-is, win ara t-iḍefṛen.",
-  "account.media": "Allal n teywalt",
+  "account.media": "Amidya",
   "account.mention": "Bder-d @{name}",
-  "account.moved_to": "{name} ibeddel γer:",
+  "account.moved_to": "{name} ibeddel ɣer:",
   "account.mute": "Sgugem @{name}",
-  "account.mute_notifications": "Susem ilγa sγur @{name}",
+  "account.mute_notifications": "Sgugem tilɣa sγur @{name}",
   "account.muted": "Yettwasgugem",
   "account.never_active": "Werǧin",
   "account.posts": "Tijewwaqin",
   "account.posts_with_replies": "Tijewwaqin akked tririyin",
-  "account.report": "Sewɛed @{name}",
-  "account.requested": "Di laɛḍil ad yettwaqbel. Ssit iwakken ad yefsex usuter n weḍfar",
-  "account.share": "Bḍu amaγnu n @{name}",
+  "account.report": "Cetki ɣef @{name}",
+  "account.requested": "Di laɛḍil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uḍfar",
+  "account.share": "Bḍu amaɣnu n @{name}",
   "account.show_reblogs": "Sken-d inebḍa n @{name}",
   "account.unblock": "Serreḥ i @{name}",
-  "account.unblock_domain": "Kkes tuffra i {domain}",
-  "account.unendorse": "Ur ttwellih ara fell-as deg umaγnu-inek",
+  "account.unblock_domain": "Sken-d {domain}",
+  "account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek",
   "account.unfollow": "Ur ṭṭafaṛ ara",
-  "account.unmute": "Kkes asgugem γef @{name}",
-  "account.unmute_notifications": "Serreḥ ilγa sγur @{name}",
-  "alert.rate_limited.message": "Ma ulac aγilif ɛreḍ tikelt-nniḍen mbeɛd {retry_time, time, medium}.",
+  "account.unmute": "Kkes asgugem ɣef @{name}",
+  "account.unmute_notifications": "Serreḥ ilɣa sɣur @{name}",
+  "alert.rate_limited.message": "Ma ulac aɣilif ɛreḍ tikelt-nniḍen akka {retry_time, time, medium}.",
   "alert.rate_limited.title": "Aktum s talast",
-  "alert.unexpected.message": "Tella-d tuccḍa i γef ur nedmi ara.",
+  "alert.unexpected.message": "Yeḍra-d unezri ur netturaǧu ara.",
   "alert.unexpected.title": "Ayhuh!",
-  "announcement.announcement": "Ulγu",
+  "announcement.announcement": "Ulɣu",
   "autosuggest_hashtag.per_week": "{count} i yimalas",
-  "boost_modal.combo": "Tzemreḍ ad tetekkiḍ γef {combo} akken ad tessurfeḍ aya tikelt-nniḍen",
+  "boost_modal.combo": "Tzemreḍ ad tetekkiḍ ɣef {combo} akken ad tessurfeḍ aya tikelt-nniḍen",
   "bundle_column_error.body": "Tella-d kra n tuccḍa mi d-yettali ugbur-agi.",
   "bundle_column_error.retry": "Ɛreḍ tikelt-nniḍen",
   "bundle_column_error.title": "Tuccḍa deg uẓeṭṭa",
@@ -56,22 +56,22 @@
   "column.bookmarks": "Ticraḍ",
   "column.community": "Tasuddemt tadigant",
   "column.direct": "Iznan usriden",
-  "column.directory": "Qelleb deg imaγnuten",
-  "column.domain_blocks": "Tiγula yettwaffren",
+  "column.directory": "Inig deg imaɣnuten",
+  "column.domain_blocks": "Taɣulin yeffren",
   "column.favourites": "Ismenyifen",
   "column.follow_requests": "Isuturen n teḍfeṛt",
   "column.home": "Agejdan",
   "column.lists": "Tibdarin",
   "column.mutes": "Imiḍanen yettwasgugmen",
-  "column.notifications": "Tilγa",
+  "column.notifications": "Tilɣa",
   "column.pins": "Tijewwaqin yettwasenṭḍen",
   "column.public": "Tasuddemt tamatut",
-  "column_back_button.label": "Tuγalin",
-  "column_header.hide_settings": "Ffer iγewwaṛen",
-  "column_header.moveLeft_settings": "Err ajgu γer tama tazelmaḍt",
-  "column_header.moveRight_settings": "Err ajgu γer tama tayfust",
+  "column_back_button.label": "Tuɣalin",
+  "column_header.hide_settings": "Ffer iɣewwaṛen",
+  "column_header.moveLeft_settings": "Err ajgu ɣer tama tazelmaḍt",
+  "column_header.moveRight_settings": "Err ajgu ɣer tama tayfust",
   "column_header.pin": "Senteḍ",
-  "column_header.show_settings": "Sken iγewwaṛen",
+  "column_header.show_settings": "Sken iɣewwaṛen",
   "column_header.unpin": "Kkes asenteḍ",
   "column_subheading.settings": "Iγewwaṛen",
   "community.column_settings.media_only": "Allal n teywalt kan",
@@ -102,7 +102,7 @@
   "confirmations.delete.confirm": "Kkes",
   "confirmations.delete.message": "Tebγiḍ s tidet ad tekkseḍ tasuffeγt-agi?",
   "confirmations.delete_list.confirm": "Kkes",
-  "confirmations.delete_list.message": "Tebγiḍ s tidet ad tekkseḍ tabdert-agi i lebda?",
+  "confirmations.delete_list.message": "Tebγiḍ s tidet ad tekkseḍ umuγ-agi i lebda?",
   "confirmations.domain_block.confirm": "Ffer taγult meṛṛa",
   "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": "Ffeγ",
@@ -137,7 +137,7 @@
   "emoji_button.people": "Medden",
   "emoji_button.recent": "Wid yettuseqdacen s waṭas",
   "emoji_button.search": "Nadi…",
-  "emoji_button.search_results": "Igmaḍ u unadi",
+  "emoji_button.search_results": "Igemmaḍ n unadi",
   "emoji_button.symbols": "Izamulen",
   "emoji_button.travel": "Imeḍqan d Yinigen",
   "empty_column.account_timeline": "Ulac tijewwaqin dagi!",
@@ -153,8 +153,8 @@
   "empty_column.hashtag": "Ar tura ulac kra n ugbur yesɛan assaγ γer uhacṭag-agi.",
   "empty_column.home": "Tasuddemt tagejdant n yisallen d tilemt! Ẓer {public} neγ nadi ad tafeḍ imseqdacen-nniḍen ad ten-ḍefṛeḍ.",
   "empty_column.home.public_timeline": "tasuddemt tazayezt n yisallen",
-  "empty_column.list": "Ar tura ur yelli kra deg tebdert-a. Ad d-yettwasken da ticki iɛeggalen n tebdert-a suffγen-d kra.",
-  "empty_column.lists": "Ulac γur-k kra n tebdert yakan. Ad d-tettwasken da ticki tesluleḍ-d yiwet.",
+  "empty_column.list": "Ar tura ur yelli kra deg umuγ-a. Ad d-yettwasken da ticki iɛeggalen n wumuγ-a suffγen-d kra.",
+  "empty_column.lists": "Ulac γur-k kra n wumuγ yakan. Ad d-tettwasken da ticki tesluleḍ-d yiwet.",
   "empty_column.mutes": "Ulac γur-k imseqdacen i yettwasgugmen.",
   "empty_column.notifications": "Ulac γur-k tilγa. Sedmer akked yemdanen-nniḍen akken ad tebduḍ adiwenni.",
   "empty_column.public": "Ulac kra da! Aru kra, neγ ḍfeṛ imdanen i yellan deg yiqeddacen-nniḍen akken ad d-teččar tsuddemt tazayezt",
@@ -202,58 +202,58 @@
   "introduction.interactions.reblog.headline": "Bḍu tikelt-nniḍen",
   "introduction.interactions.reblog.text": "Tzemreḍ ad tebḍuḍ tijewwaqin n medden akk d yimeḍfaṛen-ik s beṭṭu-nsent tikelt-nniḍen.",
   "introduction.interactions.reply.headline": "Err",
-  "introduction.interactions.reply.text": "Tzemreḍ ad terreḍ γef tjewwakin-ik d tid n medden-nniḍen, d acu ara tent-id-iɛeqden ta deffir ta deg yiwen udiwenni.",
+  "introduction.interactions.reply.text": "Tzemreḍ ad terreḍ γef tjewwaqin-ik·im akked tid n medden-nniḍen, aya atent-id-icudd ta deffir ta deg yiwen udiwenni.",
   "introduction.welcome.action": "Bdu!",
   "introduction.welcome.headline": "Isurifen imenza",
   "introduction.welcome.text": "Anṣuf γer fediverse! Deg kra n yimiren, ad tizmireḍ ad tzzuzreḍ iznan neγ ad tmeslayeḍ i yemddukkal deg waṭas n yiqeddacen. Maca aqeddac-agi, {domain}, mačči am wiyaḍ - deg-s i yella umaγnu-ik, ihi cfu γef yisem-is.",
   "keyboard_shortcuts.back": "uγal ar deffir",
-  "keyboard_shortcuts.blocked": "akken ad teldiḍ tabdert n yimseqdacen yettwasḥebsen",
+  "keyboard_shortcuts.blocked": "akken ad teldiḍ umuγ n yimseqdacen yettwasḥebsen",
   "keyboard_shortcuts.boost": "i beṭṭu tikelt-nniḍen",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
   "keyboard_shortcuts.compose": "to focus the compose textarea",
   "keyboard_shortcuts.description": "Aglam",
   "keyboard_shortcuts.direct": "akken ad teldiḍ ajgu n yiznan usriden",
-  "keyboard_shortcuts.down": "i kennu γer wadda n tebdert",
+  "keyboard_shortcuts.down": "i kennu γer wadda n wumuγ",
   "keyboard_shortcuts.enter": "i tildin n tsuffeγt",
   "keyboard_shortcuts.favourite": "akken ad ternuḍ γer yismenyifen",
-  "keyboard_shortcuts.favourites": "i tildin n tebdert n yismenyifen",
+  "keyboard_shortcuts.favourites": "i tildin umuγ n yismenyifen",
   "keyboard_shortcuts.federated": "i tildin n tsuddemt tamatut n yisallen",
   "keyboard_shortcuts.heading": "Inegzumen n unasiw",
   "keyboard_shortcuts.home": "i tildin n tsuddemt tagejdant n yisallen",
   "keyboard_shortcuts.hotkey": "Inegzumen",
-  "keyboard_shortcuts.legend": "to display this legend",
+  "keyboard_shortcuts.legend": "akken ad tsekneḍ taneffust-agi",
   "keyboard_shortcuts.local": "i tildin n tsuddemt tadigant n yisallen",
   "keyboard_shortcuts.mention": "akken ad d-bedreḍ ameskar",
-  "keyboard_shortcuts.muted": "akken ad teldiḍ tabdert n yimseqdacen yettwasgugmen",
+  "keyboard_shortcuts.muted": "akken ad teldiḍ umuγ n yimseqdacen yettwasgugmen",
   "keyboard_shortcuts.my_profile": "akken ad d-teldiḍ amaγnu-ik",
   "keyboard_shortcuts.notifications": "akken ad d-teldiḍ ajgu n tilγa",
-  "keyboard_shortcuts.open_media": "to open media",
-  "keyboard_shortcuts.pinned": "i tildin n tebdert n tjewwaqin yettwasentḍen",
+  "keyboard_shortcuts.open_media": "i taɣwalin yeldin ",
+  "keyboard_shortcuts.pinned": "akken ad teldiḍ umuγ n tjewwiqin yettwasentḍen",
   "keyboard_shortcuts.profile": "akken ad d-teldiḍ amaγnu n umeskar",
   "keyboard_shortcuts.reply": "i tririt",
-  "keyboard_shortcuts.requests": "akken ad d-teldiḍ tabdert n yisuturen n teḍfeṛt",
+  "keyboard_shortcuts.requests": "akken ad d-teldiḍ umuγ n yisuturen n teḍfeṛt",
   "keyboard_shortcuts.search": "to focus search",
   "keyboard_shortcuts.start": "akken ad d-teldiḍ ajgu n \"bdu\"",
   "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
   "keyboard_shortcuts.toggle_sensitivity": "i teskent/tuffra n yimidyaten",
   "keyboard_shortcuts.toot": "i wakken attebdud tajewwaqt tamaynut",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
-  "keyboard_shortcuts.up": "i tulin γer ufella n tebdert",
+  "keyboard_shortcuts.up": "i tulin γer d asawen n wumuγ",
   "lightbox.close": "Mdel",
   "lightbox.next": "Γer zdat",
   "lightbox.previous": "Γer deffir",
   "lightbox.view_context": "Ẓer amnaḍ",
-  "lists.account.add": "Rnu γer tabdart",
-  "lists.account.remove": "Kkes seg tebdart",
-  "lists.delete": "Kkes tabdert",
-  "lists.edit": "Ẓreg tabdert",
+  "lists.account.add": "Rnu γer wumuγ",
+  "lists.account.remove": "Kkes seg umuγ",
+  "lists.delete": "Kkes umuγ",
+  "lists.edit": "Ẓreg umuγ",
   "lists.edit.submit": "Beddel azwel",
-  "lists.new.create": "Rnu tabdart",
-  "lists.new.title_placeholder": "Azwel n tebdert tamaynut",
+  "lists.new.create": "Rnu umuγ",
+  "lists.new.title_placeholder": "Azwel amaynut n wumuγ",
   "lists.search": "Nadi gar yemdanen i teṭṭafaṛeḍ",
-  "lists.subheading": "Tibdarin-ik·im",
+  "lists.subheading": "Umuγen-ik·im",
   "load_pending": "{count, plural, one {# n uferdis amaynut} other {# n yiferdisen imaynuten}}",
-  "loading_indicator.label": "Yessalay-ed…",
+  "loading_indicator.label": "Yessalay-d…",
   "media_gallery.toggle_visible": "Sken / Ffer",
   "missing_indicator.label": "Ulac-it",
   "missing_indicator.sublabel": "Ur nufi ara aγbalu-a",
@@ -271,9 +271,9 @@
   "navigation_bar.filters": "Awalen i yettwasgugmen",
   "navigation_bar.follow_requests": "Isuturen n teḍfeṛt",
   "navigation_bar.follows_and_followers": "Imeḍfaṛen akked wid i teṭṭafaṛeḍ",
-  "navigation_bar.info": "Γef uqeddac-a",
+  "navigation_bar.info": "Ɣef uqeddac-agi",
   "navigation_bar.keyboard_shortcuts": "Inegzumen n unasiw",
-  "navigation_bar.lists": "Tibdarin",
+  "navigation_bar.lists": "Umuγen",
   "navigation_bar.logout": "Ffeγ",
   "navigation_bar.mutes": "Iseqdacen yettwasusmen",
   "navigation_bar.personal": "Udmawan",
@@ -326,15 +326,15 @@
   "privacy.public.long": "Bḍu deg tsuddemt tazayezt",
   "privacy.public.short": "Azayez",
   "privacy.unlisted.long": "Ur beṭṭu ara deg tsuddemt tazayezt",
-  "privacy.unlisted.short": "War tabdert",
+  "privacy.unlisted.short": "War umuγ",
   "refresh": "Smiren",
-  "regeneration_indicator.label": "Yessalay-ed…",
+  "regeneration_indicator.label": "Yessalay-d…",
   "regeneration_indicator.sublabel": "Tasuddemt tagejdant ara d-tettwaheggay!",
   "relative_time.days": "{number}u",
-  "relative_time.hours": "{number}a",
+  "relative_time.hours": "{number}isr",
   "relative_time.just_now": "tura",
-  "relative_time.minutes": "{number}t",
-  "relative_time.seconds": "{number}t",
+  "relative_time.minutes": "{number}tis",
+  "relative_time.seconds": "{number}tas",
   "relative_time.today": "assa",
   "reply_indicator.cancel": "Sefsex",
   "report.forward": "Bren-it γeṛ {target}",
@@ -391,13 +391,13 @@
   "status.share": "Bḍu",
   "status.show_less": "Sken-d drus",
   "status.show_less_all": "Semẓi akk tisuffγin",
-  "status.show_more": "Sken-ed ugar",
+  "status.show_more": "Sken-d ugar",
   "status.show_more_all": "Ẓerr ugar lebda",
-  "status.show_thread": "Sken-ed lxiḍ",
+  "status.show_thread": "Sken-d lxiḍ",
   "status.uncached_media_warning": "Ulac-it",
   "status.unmute_conversation": "Kkes asgugem n udiwenni",
   "status.unpin": "Kkes asenteḍ seg umaγnu",
-  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.dismiss": "Sefsex asumer",
   "suggestions.header": "Ahat ad tcelgeḍ deg…",
   "tabs_bar.federated_timeline": "Amatu",
   "tabs_bar.home": "Agejdan",
@@ -408,10 +408,10 @@
   "time_remaining.hours": "Mazal {number, plural, one {# n usrag} other {# n yesragen}}",
   "time_remaining.minutes": "Mazal {number, plural, one {# n tesdat} other {# n tesdatin}}",
   "time_remaining.moments": "Moments remaining",
-  "time_remaining.seconds": "Mazal {number, plural, one {# n tasint} other {# n tsinin}}",
+  "time_remaining.seconds": "Mazal {number, plural, one {# n tasint} other {# n tsinin}} id yugran",
   "trends.count_by_accounts": "{count} {rawCount, plural, one {n umdan} other {n yemdanen}} i yettmeslayen",
   "trends.trending_now": "Trending now",
-  "ui.beforeunload": "Arewway-ik·im ad iruḥ ma yella tefeγ-ed deg Maṣṭudun.",
+  "ui.beforeunload": "Arewway-ik·im ad iruḥ ma yella tefeɣ-d deg Maṣṭudun.",
   "upload_area.title": "Zuḥeb rnu sers i tasalyt",
   "upload_button.label": "Rnu Taγwalt ({formats})",
   "upload_error.limit": "File upload limit exceeded.",
diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json
index 5385de456..eafb7ede7 100644
--- a/app/javascript/mastodon/locales/kn.json
+++ b/app/javascript/mastodon/locales/kn.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 6d6bf2ea2..cdcce62ff 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -53,7 +53,7 @@
   "bundle_modal_error.message": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.",
   "bundle_modal_error.retry": "다시 시도",
   "column.blocks": "차단 중인 사용자",
-  "column.bookmarks": "갈무리",
+  "column.bookmarks": "보관함",
   "column.community": "로컬 타임라인",
   "column.direct": "다이렉트 메시지",
   "column.directory": "프로필 둘러보기",
@@ -143,7 +143,7 @@
   "empty_column.account_timeline": "여긴 툿이 없어요!",
   "empty_column.account_unavailable": "프로필 사용 불가",
   "empty_column.blocks": "아직 아무도 차단하지 않았습니다.",
-  "empty_column.bookmarked_statuses": "아직 갈무리한 툿이 없습니다. 툿을 갈무리하면 여기에 나타납니다.",
+  "empty_column.bookmarked_statuses": "아직 보관한 툿이 없습니다. 툿을 보관하면 여기에 나타납니다.",
   "empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!",
   "empty_column.direct": "아직 다이렉트 메시지가 없습니다. 다이렉트 메시지를 보내거나 받은 경우, 여기에 표시 됩니다.",
   "empty_column.domain_blocks": "아직 숨겨진 도메인이 없습니다.",
@@ -260,7 +260,7 @@
   "mute_modal.hide_notifications": "이 사용자로부터의 알림을 숨기시겠습니까?",
   "navigation_bar.apps": "모바일 앱",
   "navigation_bar.blocks": "차단한 사용자",
-  "navigation_bar.bookmarks": "갈무리",
+  "navigation_bar.bookmarks": "보관함",
   "navigation_bar.community_timeline": "로컬 타임라인",
   "navigation_bar.compose": "새 툿 작성",
   "navigation_bar.direct": "다이렉트 메시지",
@@ -358,7 +358,7 @@
   "status.admin_account": "@{name}에 대한 중재 화면 열기",
   "status.admin_status": "중재 화면에서 이 게시물 열기",
   "status.block": "@{name} 차단",
-  "status.bookmark": "갈무리",
+  "status.bookmark": "보관",
   "status.cancel_reblog_private": "부스트 취소",
   "status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
   "status.copy": "게시물 링크 복사",
@@ -383,7 +383,7 @@
   "status.reblogged_by": "{name}님이 부스트 했습니다",
   "status.reblogs.empty": "아직 아무도 이 툿을 부스트하지 않았습니다. 부스트 한 사람들이 여기에 표시 됩니다.",
   "status.redraft": "지우고 다시 쓰기",
-  "status.remove_bookmark": "갈무리 삭제",
+  "status.remove_bookmark": "보관한 툿 삭제",
   "status.reply": "답장",
   "status.replyAll": "전원에게 답장",
   "status.report": "신고",
@@ -398,7 +398,7 @@
   "status.unmute_conversation": "이 대화의 뮤트 해제하기",
   "status.unpin": "고정 해제",
   "suggestions.dismiss": "추천 지우기",
-  "suggestions.header": "이것에 관심이 있을 것 같습니다…",
+  "suggestions.header": "여기에 관심이 있을 것 같습니다…",
   "tabs_bar.federated_timeline": "연합",
   "tabs_bar.home": "홈",
   "tabs_bar.local_timeline": "로컬",
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
index 5385de456..eafb7ede7 100644
--- a/app/javascript/mastodon/locales/lt.json
+++ b/app/javascript/mastodon/locales/lt.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 1b5b7cf5e..82ec3b8e8 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json
index 4a1f736cf..ee8b13ace 100644
--- a/app/javascript/mastodon/locales/mk.json
+++ b/app/javascript/mastodon/locales/mk.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json
index 58bb9b723..b3a06d6ed 100644
--- a/app/javascript/mastodon/locales/ml.json
+++ b/app/javascript/mastodon/locales/ml.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json
index 8c0fed9b0..be5d9a396 100644
--- a/app/javascript/mastodon/locales/mr.json
+++ b/app/javascript/mastodon/locales/mr.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json
index 0d23e0d2c..19f3ca257 100644
--- a/app/javascript/mastodon/locales/ms.json
+++ b/app/javascript/mastodon/locales/ms.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 5048a3a49..6589c2b1d 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -2,11 +2,11 @@
   "account.add_or_remove_from_list": "Toevoegen of verwijderen vanuit lijsten",
   "account.badges.bot": "Bot",
   "account.badges.group": "Groep",
-  "account.block": "Blokkeer @{name}",
-  "account.block_domain": "Verberg alles van {domain}",
+  "account.block": "@{name} blokkeren",
+  "account.block_domain": "Alles van {domain} verbergen",
   "account.blocked": "Geblokkeerd",
   "account.cancel_follow_request": "Volgverzoek annuleren",
-  "account.direct": "Direct bericht @{name}",
+  "account.direct": "@{name} een direct bericht sturen",
   "account.domain_blocked": "Domein verborgen",
   "account.edit_profile": "Profiel bewerken",
   "account.endorse": "Op profiel weergeven",
@@ -21,19 +21,19 @@
   "account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}",
   "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie hen kan volgen.",
   "account.media": "Media",
-  "account.mention": "Vermeld @{name}",
+  "account.mention": "@{name} vermelden",
   "account.moved_to": "{name} is verhuisd naar:",
-  "account.mute": "Negeer @{name}",
-  "account.mute_notifications": "Negeer meldingen van @{name}",
+  "account.mute": "@{name} negeren",
+  "account.mute_notifications": "Meldingen van @{name} negeren",
   "account.muted": "Genegeerd",
   "account.never_active": "Nooit",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots en reacties",
-  "account.report": "Rapporteer @{name}",
+  "account.report": "@{name} rapporteren",
   "account.requested": "Wacht op goedkeuring. Klik om het volgverzoek te annuleren",
   "account.share": "Profiel van @{name} delen",
   "account.show_reblogs": "Toon boosts van @{name}",
-  "account.unblock": "Deblokkeer @{name}",
+  "account.unblock": "@{name} deblokkeren",
   "account.unblock_domain": "{domain} niet langer verbergen",
   "account.unendorse": "Niet op profiel weergeven",
   "account.unfollow": "Ontvolgen",
@@ -254,7 +254,7 @@
   "lists.subheading": "Jouw lijsten",
   "load_pending": "{count, plural, one {# nieuw item} other {# nieuwe items}}",
   "loading_indicator.label": "Laden…",
-  "media_gallery.toggle_visible": "Media wel/niet tonen",
+  "media_gallery.toggle_visible": "Media verbergen",
   "missing_indicator.label": "Niet gevonden",
   "missing_indicator.sublabel": "Deze hulpbron kan niet gevonden worden",
   "mute_modal.hide_notifications": "Verberg meldingen van deze persoon?",
@@ -323,9 +323,9 @@
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Alleen aan volgers tonen",
   "privacy.private.short": "Alleen volgers",
-  "privacy.public.long": "Op openbare tijdlijnen tonen",
+  "privacy.public.long": "Voor iedereen zichtbaar en op openbare tijdlijnen tonen",
   "privacy.public.short": "Openbaar",
-  "privacy.unlisted.long": "Niet op openbare tijdlijnen tonen",
+  "privacy.unlisted.long": "Voor iedereen zichtbaar, maar niet op openbare tijdlijnen tonen",
   "privacy.unlisted.short": "Minder openbaar",
   "refresh": "Vernieuwen",
   "regeneration_indicator.label": "Aan het laden…",
@@ -357,22 +357,22 @@
   "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}",
   "status.admin_account": "Moderatie-omgeving van @{name} openen",
   "status.admin_status": "Deze toot in de moderatie-omgeving openen",
-  "status.block": "Blokkeer @{name}",
+  "status.block": "@{name} blokkeren",
   "status.bookmark": "Bladwijzer toevoegen",
   "status.cancel_reblog_private": "Niet langer boosten",
   "status.cannot_reblog": "Deze toot kan niet geboost worden",
   "status.copy": "Link naar toot kopiëren",
   "status.delete": "Verwijderen",
   "status.detailed_status": "Uitgebreide gespreksweergave",
-  "status.direct": "Direct bericht @{name}",
+  "status.direct": "@{name} een direct bericht sturen",
   "status.embed": "Insluiten",
   "status.favourite": "Favoriet",
   "status.filtered": "Gefilterd",
   "status.load_more": "Meer laden",
   "status.media_hidden": "Media verborgen",
-  "status.mention": "Vermeld @{name}",
+  "status.mention": "@{name} vermelden",
   "status.more": "Meer",
-  "status.mute": "Negeer @{name}",
+  "status.mute": "@{name} negeren",
   "status.mute_conversation": "Negeer gesprek",
   "status.open": "Uitgebreide toot tonen",
   "status.pin": "Aan profielpagina vastmaken",
@@ -386,7 +386,7 @@
   "status.remove_bookmark": "Bladwijzer verwijderen",
   "status.reply": "Reageren",
   "status.replyAll": "Reageer op iedereen",
-  "status.report": "Rapporteer @{name}",
+  "status.report": "@{name} rapporteren",
   "status.sensitive_warning": "Gevoelige inhoud",
   "status.share": "Delen",
   "status.show_less": "Minder tonen",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index 9dd48767d..39fe5158e 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -43,7 +43,7 @@
   "alert.rate_limited.title": "Begrensa rate",
   "alert.unexpected.message": "Eit uventa problem oppstod.",
   "alert.unexpected.title": "Oi sann!",
-  "announcement.announcement": "Kunngjøring",
+  "announcement.announcement": "Kunngjering",
   "autosuggest_hashtag.per_week": "{count} per veke",
   "boost_modal.combo": "Du kan trykkja {combo} for å hoppa over dette neste gong",
   "bundle_column_error.body": "Noko gjekk gale mens denne komponenten vart lasta ned.",
@@ -85,8 +85,8 @@
   "compose_form.poll.duration": "Varigskap for røysting",
   "compose_form.poll.option_placeholder": "Val {number}",
   "compose_form.poll.remove_option": "Ta vekk dette valet",
-  "compose_form.poll.switch_to_multiple": "Endre avstemning til å tillate flere valg",
-  "compose_form.poll.switch_to_single": "Endre avstemning til å tillate ett valg",
+  "compose_form.poll.switch_to_multiple": "Endre avstemninga til å tillate fleirval",
+  "compose_form.poll.switch_to_single": "Endra avstemninga til tillate berre eitt val",
   "compose_form.publish": "Tut",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.hide": "Merk medium som sensitivt",
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "Enkelt",
   "home.column_settings.show_reblogs": "Vis framhevingar",
   "home.column_settings.show_replies": "Vis svar",
-  "home.hide_announcements": "Skjul kunngjøring",
-  "home.show_announcements": "Vis kunngjøring",
+  "home.hide_announcements": "Skjul kunngjeringar",
+  "home.show_announcements": "Vis kunngjeringar",
   "intervals.full.days": "{number, plural, one {# dag} other {# dagar}}",
   "intervals.full.hours": "{number, plural, one {# time} other {# timar}}",
   "intervals.full.minutes": "{number, plural, one {# minutt} other {# minutt}}",
@@ -237,7 +237,7 @@
   "keyboard_shortcuts.toggle_hidden": "for å visa/gøyma tekst bak innhaldsvarsel",
   "keyboard_shortcuts.toggle_sensitivity": "for å visa/gøyma media",
   "keyboard_shortcuts.toot": "for å laga ein heilt ny tut",
-  "keyboard_shortcuts.unfocus": "å ufokusere komponerings-/søkefeltet",
+  "keyboard_shortcuts.unfocus": "for å fokusere vekk skrive-/søkefeltet",
   "keyboard_shortcuts.up": "for å flytta seg opp på lista",
   "lightbox.close": "Lukk att",
   "lightbox.next": "Neste",
@@ -416,11 +416,11 @@
   "upload_button.label": "Legg til medium ({formats})",
   "upload_error.limit": "Du har gått over opplastingsgrensa.",
   "upload_error.poll": "Filopplasting ikkje tillate med meiningsmålingar.",
-  "upload_form.audio_description": "Beskriv det for folk med hørselstap",
+  "upload_form.audio_description": "Grei ut for folk med nedsett høyrsel",
   "upload_form.description": "Skildr for synshemja",
   "upload_form.edit": "Rediger",
   "upload_form.undo": "Slett",
-  "upload_form.video_description": "Beskriv det for folk med hørselstap eller synshemminger",
+  "upload_form.video_description": "Greit ut for folk med nedsett høyrsel eller syn",
   "upload_modal.analyzing_picture": "Analyserer bilete…",
   "upload_modal.apply": "Bruk",
   "upload_modal.description_placeholder": "Ein rask brun rev hoppar over den late hunden",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 024bbb9df..a019f39ee 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -65,7 +65,7 @@
   "column.mutes": "Usuários silenciados",
   "column.notifications": "Notificações",
   "column.pins": "Toots fixados",
-  "column.public": "Linha global",
+  "column.public": "Global",
   "column_back_button.label": "Voltar",
   "column_header.hide_settings": "Ocultar configurações",
   "column_header.moveLeft_settings": "Mover coluna para a esquerda",
@@ -92,7 +92,7 @@
   "compose_form.sensitive.hide": "Marcar mídia como sensível",
   "compose_form.sensitive.marked": "Mídia está marcada como sensível",
   "compose_form.sensitive.unmarked": "Mídia não está marcada como sensível",
-  "compose_form.spoiler.marked": "O texto está oculto por um aviso de conteúdo",
+  "compose_form.spoiler.marked": "Com Aviso de Conteúdo",
   "compose_form.spoiler.unmarked": "Sem Aviso de Conteúdo",
   "compose_form.spoiler_placeholder": "Aviso de Conteúdo aqui",
   "confirmation_modal.cancel": "Cancelar",
@@ -100,7 +100,7 @@
   "confirmations.block.confirm": "Bloquear",
   "confirmations.block.message": "Você tem certeza de que deseja bloquear {name}?",
   "confirmations.delete.confirm": "Excluir",
-  "confirmations.delete.message": "Excluir este toot?",
+  "confirmations.delete.message": "Você tem certeza de que deseja excluir este toot?",
   "confirmations.delete_list.confirm": "Excluir",
   "confirmations.delete_list.message": "Você tem certeza de que deseja excluir esta lista?",
   "confirmations.domain_block.confirm": "Bloquear domínio",
@@ -113,9 +113,9 @@
   "confirmations.redraft.confirm": "Excluir e rascunhar",
   "confirmations.redraft.message": "Você tem certeza de que deseja apagar o toot e usá-lo como rascunho? Boosts e favoritos serão perdidos e as respostas ao toot original ficarão desconectadas.",
   "confirmations.reply.confirm": "Responder",
-  "confirmations.reply.message": "Responder agora vai sobrescrever o toot que você está compondo. Deseja continuar?",
+  "confirmations.reply.message": "Responder agora sobrescreverá o toot que você está compondo. Deseja continuar?",
   "confirmations.unfollow.confirm": "Deixar de seguir",
-  "confirmations.unfollow.message": "Deixar de seguir {name}?",
+  "confirmations.unfollow.message": "Você tem certeza de que deseja deixar de seguir {name}?",
   "conversation.delete": "Excluir conversa",
   "conversation.mark_as_read": "Marcar como lida",
   "conversation.open": "Ver conversa",
@@ -143,7 +143,7 @@
   "empty_column.account_timeline": "Nada aqui!",
   "empty_column.account_unavailable": "Perfil indisponível",
   "empty_column.blocks": "Nada aqui.",
-  "empty_column.bookmarked_statuses": "Sem toots salvos. Quando você salvar alguns, eles aparecerão aqui.",
+  "empty_column.bookmarked_statuses": "Nada aqui. Quando você salvar um toot, ele aparecerá aqui.",
   "empty_column.community": "A linha do tempo local está vazia. Poste algo publicamente para começar!",
   "empty_column.direct": "Nada aqui. Quando você enviar ou receber toots diretos, eles aparecerão aqui.",
   "empty_column.domain_blocks": "Nada aqui.",
@@ -185,7 +185,7 @@
   "home.column_settings.show_reblogs": "Mostrar boosts",
   "home.column_settings.show_replies": "Mostrar respostas",
   "home.hide_announcements": "Ocultar anúncios",
-  "home.show_announcements": "Exibir anúncios",
+  "home.show_announcements": "Mostrar anúncios",
   "intervals.full.days": "{number, plural, one {# dia} other {# dias}}",
   "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
   "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
@@ -198,7 +198,7 @@
   "introduction.federation.local.text": "Toots públicos de pessoas na mesma instância que você aparecerão na linha local.",
   "introduction.interactions.action": "Terminar o tutorial!",
   "introduction.interactions.favourite.headline": "Favoritos",
-  "introduction.interactions.favourite.text": "Ao favoritar, você salva o toot para mais tarde ou sinaliza ao autor que você gostou do toot.",
+  "introduction.interactions.favourite.text": "Ao favoritar, você sinaliza ao autor que você gostou do toot.",
   "introduction.interactions.reblog.headline": "Boost",
   "introduction.interactions.reblog.text": "Ao dar boost, você compartilha toots de outras pessoas para seus seguidores.",
   "introduction.interactions.reply.headline": "Responder",
@@ -289,14 +289,14 @@
   "notification.poll": "Uma enquete que você votou terminou",
   "notification.reblog": "{name} deu boost no seu toot",
   "notifications.clear": "Limpar notificações",
-  "notifications.clear_confirmation": "Você tem certeza de que quer limpar todas as suas notificações?",
+  "notifications.clear_confirmation": "Você tem certeza de que deseja limpar todas as suas notificações?",
   "notifications.column_settings.alert": "Notificações no computador",
   "notifications.column_settings.favourite": "Favoritos:",
   "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias",
   "notifications.column_settings.filter_bar.category": "Barra de filtro rápido",
   "notifications.column_settings.filter_bar.show": "Mostrar",
   "notifications.column_settings.follow": "Seguidores:",
-  "notifications.column_settings.follow_request": "Novos seguidores pendentes:",
+  "notifications.column_settings.follow_request": "Seguidores pendentes:",
   "notifications.column_settings.mention": "Menções:",
   "notifications.column_settings.poll": "Enquetes:",
   "notifications.column_settings.push": "Enviar notificações",
diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json
index 34acbfc9a..b8902d65e 100644
--- a/app/javascript/mastodon/locales/pt-PT.json
+++ b/app/javascript/mastodon/locales/pt-PT.json
@@ -17,9 +17,9 @@
   "account.follows.empty": "Este utilizador ainda não segue alguém.",
   "account.follows_you": "É teu seguidor",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
-  "account.last_status": "Última actividade",
+  "account.last_status": "Última atividade",
   "account.link_verified_on": "A posse deste link foi verificada em {date}",
-  "account.locked_info": "O estatuto de privacidade desta conta é fechado. O dono revê manualmente que a pode seguir.",
+  "account.locked_info": "O estatuto de privacidade desta conta é fechado. O dono revê manualmente quem a pode seguir.",
   "account.media": "Média",
   "account.mention": "Mencionar @{name}",
   "account.moved_to": "{name} mudou a sua conta para:",
@@ -53,7 +53,7 @@
   "bundle_modal_error.message": "Algo de errado aconteceu enquanto este componente era carregado.",
   "bundle_modal_error.retry": "Tente de novo",
   "column.blocks": "Utilizadores Bloqueados",
-  "column.bookmarks": "Favoritos",
+  "column.bookmarks": "Marcadores",
   "column.community": "Cronologia local",
   "column.direct": "Mensagens directas",
   "column.directory": "Procurar perfis",
@@ -74,7 +74,7 @@
   "column_header.show_settings": "Mostrar configurações",
   "column_header.unpin": "Desafixar",
   "column_subheading.settings": "Configurações",
-  "community.column_settings.media_only": "Somente multimédia",
+  "community.column_settings.media_only": "Somente média",
   "compose_form.direct_message_warning": "Esta publicação será enviada apenas para os utilizadores mencionados.",
   "compose_form.direct_message_warning_learn_more": "Conhecer mais",
   "compose_form.hashtag_warning": "Este toot não será listado em nenhuma hashtag por ser não listado. Apenas toots públics podem ser pesquisados por hashtag.",
@@ -89,7 +89,7 @@
   "compose_form.poll.switch_to_single": "Alterar a votação para permitir uma única escolha",
   "compose_form.publish": "Toot",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.sensitive.hide": "Marcar multimédia como sensível",
+  "compose_form.sensitive.hide": "Marcar média como sensível",
   "compose_form.sensitive.marked": "Média marcada como sensível",
   "compose_form.sensitive.unmarked": "Média não está marcada como sensível",
   "compose_form.spoiler.marked": "Texto escondido atrás de aviso",
@@ -124,7 +124,7 @@
   "directory.local": "Apenas de {domain}",
   "directory.new_arrivals": "Recém chegados",
   "directory.recently_active": "Com actividade recente",
-  "embed.instructions": "Publica esta publicação no teu site copiando o código abaixo.",
+  "embed.instructions": "Incorpora esta publicação no teu site copiando o código abaixo.",
   "embed.preview": "Podes ver aqui como irá ficar:",
   "emoji_button.activity": "Actividade",
   "emoji_button.custom": "Personalizar",
@@ -143,7 +143,7 @@
   "empty_column.account_timeline": "Sem toots por aqui!",
   "empty_column.account_unavailable": "Perfil indisponível",
   "empty_column.blocks": "Ainda não bloqueaste qualquer utilizador.",
-  "empty_column.bookmarked_statuses": "Ainda não assinalou toots como favoritos. Quando o fizer, eles aparecerão aqui.",
+  "empty_column.bookmarked_statuses": "Ainda não adicionou nenhum toot aos Itens salvos. Quando adicionar, eles serão exibidos aqui.",
   "empty_column.community": "A timeline local está vazia. Escreve algo publicamente para começar!",
   "empty_column.direct": "Ainda não tens qualquer mensagem directa. Quando enviares ou receberes alguma, ela irá aparecer aqui.",
   "empty_column.domain_blocks": "Ainda não há qualquer domínio escondido.",
@@ -214,7 +214,7 @@
   "keyboard_shortcuts.description": "Descrição",
   "keyboard_shortcuts.direct": "para abrir a coluna das mensagens directas",
   "keyboard_shortcuts.down": "para mover para baixo na lista",
-  "keyboard_shortcuts.enter": "para expandir um estado",
+  "keyboard_shortcuts.enter": "para expandir uma publicação",
   "keyboard_shortcuts.favourite": "para adicionar aos favoritos",
   "keyboard_shortcuts.favourites": "para abrir a lista dos favoritos",
   "keyboard_shortcuts.federated": "para abrir a cronologia federada",
@@ -254,13 +254,13 @@
   "lists.subheading": "As tuas listas",
   "load_pending": "{count, plural, one {# novo item} other {# novos itens}}",
   "loading_indicator.label": "A carregar...",
-  "media_gallery.toggle_visible": "Mostrar/ocultar",
+  "media_gallery.toggle_visible": "Alternar visibilidade",
   "missing_indicator.label": "Não encontrado",
   "missing_indicator.sublabel": "Este recurso não foi encontrado",
   "mute_modal.hide_notifications": "Esconder notificações deste utilizador?",
   "navigation_bar.apps": "Aplicações móveis",
   "navigation_bar.blocks": "Utilizadores bloqueados",
-  "navigation_bar.bookmarks": "Favoritos",
+  "navigation_bar.bookmarks": "Marcadores",
   "navigation_bar.community_timeline": "Cronologia local",
   "navigation_bar.compose": "Escrever novo toot",
   "navigation_bar.direct": "Mensagens directas",
@@ -281,13 +281,13 @@
   "navigation_bar.preferences": "Preferências",
   "navigation_bar.public_timeline": "Cronologia federada",
   "navigation_bar.security": "Segurança",
-  "notification.favourite": "{name} adicionou o teu estado aos favoritos",
+  "notification.favourite": "{name} adicionou a tua publicação aos favoritos",
   "notification.follow": "{name} começou a seguir-te",
   "notification.follow_request": "{name} pediu para segui-lo",
   "notification.mention": "{name} mencionou-te",
   "notification.own_poll": "A sua votação terminou",
   "notification.poll": "Uma votação em participaste chegou ao fim",
-  "notification.reblog": "{name} fez boost ao teu o teu estado",
+  "notification.reblog": "{name} partilhou a tua publicação",
   "notifications.clear": "Limpar notificações",
   "notifications.clear_confirmation": "Queres mesmo limpar todas as notificações?",
   "notifications.column_settings.alert": "Notificações no computador",
@@ -318,7 +318,7 @@
   "poll.voted": "Você votou nesta resposta",
   "poll_button.add_poll": "Adicionar votação",
   "poll_button.remove_poll": "Remover votação",
-  "privacy.change": "Ajustar a privacidade da mensagem",
+  "privacy.change": "Ajustar a privacidade da publicação",
   "privacy.direct.long": "Apenas para utilizadores mencionados",
   "privacy.direct.short": "Directo",
   "privacy.private.long": "Apenas para os seguidores",
@@ -347,7 +347,7 @@
   "search_popout.search_format": "Formato avançado de pesquisa",
   "search_popout.tips.full_text": "Texto simples devolve publicações que tu escreveste, marcaste como favorita, partilhaste ou em que foste mencionado, tal como nomes de utilizador correspondentes, alcunhas e hashtags.",
   "search_popout.tips.hashtag": "hashtag",
-  "search_popout.tips.status": "estado",
+  "search_popout.tips.status": "publicação",
   "search_popout.tips.text": "O texto simples retorna a correspondência de nomes, utilizadores e hashtags",
   "search_popout.tips.user": "utilizador",
   "search_results.accounts": "Pessoas",
@@ -358,7 +358,7 @@
   "status.admin_account": "Abrir a interface de moderação para @{name}",
   "status.admin_status": "Abrir esta publicação na interface de moderação",
   "status.block": "Bloquear @{name}",
-  "status.bookmark": "Favorito",
+  "status.bookmark": "Salvar",
   "status.cancel_reblog_private": "Remover boost",
   "status.cannot_reblog": "Não é possível fazer boost a esta publicação",
   "status.copy": "Copiar o link para a publicação",
@@ -383,7 +383,7 @@
   "status.reblogged_by": "{name} fez boost",
   "status.reblogs.empty": "Ainda ninguém fez boost a este toot. Quando alguém o fizer, ele irá aparecer aqui.",
   "status.redraft": "Apagar & reescrever",
-  "status.remove_bookmark": "Remover favorito",
+  "status.remove_bookmark": "Remover dos itens salvos",
   "status.reply": "Responder",
   "status.replyAll": "Responder à conversa",
   "status.report": "Denunciar @{name}",
@@ -394,7 +394,7 @@
   "status.show_more": "Mostrar mais",
   "status.show_more_all": "Mostrar mais para todas",
   "status.show_thread": "Mostrar conversa",
-  "status.uncached_media_warning": "Não diponível",
+  "status.uncached_media_warning": "Não disponível",
   "status.unmute_conversation": "Deixar de silenciar esta conversa",
   "status.unpin": "Não fixar no perfil",
   "suggestions.dismiss": "Dispensar a sugestão",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index f805215c1..ac88661bb 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -41,7 +41,7 @@
   "account.unmute_notifications": "Показывать уведомления от @{name}",
   "alert.rate_limited.message": "Пожалуйста, повторите после {retry_time, time, medium}.",
   "alert.rate_limited.title": "Вы выполняете действие слишком часто",
-  "alert.unexpected.message": "Что-то пошло не так.",
+  "alert.unexpected.message": "Произошла непредвиденная ошибка.",
   "alert.unexpected.title": "Ой!",
   "announcement.announcement": "Объявление",
   "autosuggest_hashtag.per_week": "{count} / неделю",
@@ -155,12 +155,12 @@
   "empty_column.home.public_timeline": "публичные ленты",
   "empty_column.list": "В этом списке пока ничего нет.",
   "empty_column.lists": "У вас ещё нет списков. Созданные вами списки будут показаны здесь.",
-  "empty_column.mutes": "Вы никого не игнорируете и всех внимательно выслушиваете.",
+  "empty_column.mutes": "Вы ещё никого не добавляли в список игнорируемых.",
   "empty_column.notifications": "У вас пока нет уведомлений. Взаимодействуйте с другими, чтобы завести разговор.",
   "empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других узлов, чтобы заполнить ленту",
   "error.unexpected_crash.explanation": "Из-за несовместимого браузера или ошибки в нашем коде, эта страница не может быть корректно отображена.",
   "error.unexpected_crash.next_steps": "Попробуйте обновить страницу. Если проблема не исчезает, используйте Mastodon из-под другого браузера или приложения.",
-  "errors.unexpected_crash.copy_stacktrace": "Копировать стектрейс в буфер обмена",
+  "errors.unexpected_crash.copy_stacktrace": "Скопировать диагностическую информацию",
   "errors.unexpected_crash.report_issue": "Сообщить о проблеме",
   "follow_request.authorize": "Авторизовать",
   "follow_request.reject": "Отказать",
@@ -197,12 +197,12 @@
   "introduction.federation.local.headline": "Локальная лента",
   "introduction.federation.local.text": "Публичные посты от людей с того же сервера, что и вы, будут отображены в локальной ленте.",
   "introduction.interactions.action": "Завершить обучение",
-  "introduction.interactions.favourite.headline": "Отметки «нравится»",
+  "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.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} — особенный: на нём располагается ваш профиль, так что не забудьте его название.",
@@ -366,7 +366,7 @@
   "status.detailed_status": "Подробный просмотр обсуждения",
   "status.direct": "Написать @{name}",
   "status.embed": "Встроить на свой сайт",
-  "status.favourite": "Нравится",
+  "status.favourite": "В избранное",
   "status.filtered": "Отфильтровано",
   "status.load_more": "Загрузить остальное",
   "status.media_hidden": "Файл скрыт",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index ad4407e9d..819496911 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -10,12 +10,12 @@
   "account.domain_blocked": "Doména ukrytá",
   "account.edit_profile": "Uprav profil",
   "account.endorse": "Zobrazuj na profile",
-  "account.follow": "Následuj",
+  "account.follow": "Nasleduj",
   "account.followers": "Sledujúci",
-  "account.followers.empty": "Tohto užívateľa ešte nikto nenásleduje.",
-  "account.follows": "Následuje",
-  "account.follows.empty": "Tento užívateľ ešte nikoho nenásleduje.",
-  "account.follows_you": "Následuje ťa",
+  "account.followers.empty": "Tohto používateľa ešte nikto nenásleduje.",
+  "account.follows": "Nasleduje",
+  "account.follows.empty": "Tento používateľ ešte nikoho nenasleduje.",
+  "account.follows_you": "Nasleduje ťa",
   "account.hide_reblogs": "Skry vyzdvihnutia od @{name}",
   "account.last_status": "Naposledy aktívny",
   "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}",
@@ -193,7 +193,7 @@
   "introduction.federation.federated.headline": "Federovaná",
   "introduction.federation.federated.text": "Verejné príspevky z ostatných serverov vo fediverse budú zobrazené vo federovanej časovej osi.",
   "introduction.federation.home.headline": "Domovská",
-  "introduction.federation.home.text": "Príspevky od ľudí ktorých následuješ sa zobrazia na tvojej domovskej nástenke. Môžeš následovať hocikoho na ktoromkoľvek serveri!",
+  "introduction.federation.home.text": "Príspevky od ľudí ktorých nasleduješ sa zobrazia na tvojej domovskej nástenke. Môžeš nasledovať hocikoho na ktoromkoľvek serveri!",
   "introduction.federation.local.headline": "Miestna",
   "introduction.federation.local.text": "Verejné príspevky od ľudí v rámci toho istého serveru na akom si aj ty, budú zobrazované na miestnej časovej osi.",
   "introduction.interactions.action": "Ukonči návod!",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index fbe48bf2e..b50cc611c 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -1,11 +1,11 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "Додај или Одстрани са листа",
   "account.badges.bot": "Бот",
-  "account.badges.group": "Group",
+  "account.badges.group": "Група",
   "account.block": "Блокирај @{name}",
   "account.block_domain": "Сакриј све са домена {domain}",
   "account.blocked": "Блокиран",
-  "account.cancel_follow_request": "Cancel follow request",
+  "account.cancel_follow_request": "Поништи захтеве за праћење",
   "account.direct": "Директна порука @{name}",
   "account.domain_blocked": "Домен сакривен",
   "account.edit_profile": "Измени профил",
@@ -17,16 +17,16 @@
   "account.follows.empty": "Корисник тренутно не прати никога.",
   "account.follows_you": "Прати Вас",
   "account.hide_reblogs": "Сакриј подршке које даје корисника @{name}",
-  "account.last_status": "Last active",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.last_status": "Последњи пут активан/на",
+  "account.link_verified_on": "Власништво над овом везом је проверено {date}",
+  "account.locked_info": "Статус приватности овог налога је подешен на закључано. Власник ручно прегледа ко га може пратити.",
   "account.media": "Медији",
   "account.mention": "Помени корисника @{name}",
   "account.moved_to": "{name} се померио на:",
   "account.mute": "Ућуткај корисника @{name}",
   "account.mute_notifications": "Искључи обавештења од корисника @{name}",
   "account.muted": "Ућуткан",
-  "account.never_active": "Never",
+  "account.never_active": "Никада",
   "account.posts": "Трубе",
   "account.posts_with_replies": "Трубе и одговори",
   "account.report": "Пријави @{name}",
@@ -39,12 +39,12 @@
   "account.unfollow": "Отпрати",
   "account.unmute": "Уклони ућуткавање кориснику @{name}",
   "account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
-  "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Rate limited",
+  "alert.rate_limited.message": "Молимо покушајте поново после {retry_time, time, medium}.",
+  "alert.rate_limited.title": "Ограничена брзина",
   "alert.unexpected.message": "Појавила се неочекивана грешка.",
   "alert.unexpected.title": "Упс!",
-  "announcement.announcement": "Announcement",
-  "autosuggest_hashtag.per_week": "{count} per week",
+  "announcement.announcement": "Најава",
+  "autosuggest_hashtag.per_week": "{count} недељно",
   "boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
   "bundle_column_error.body": "Нешто је пошло по злу приликом учитавања ове компоненте.",
   "bundle_column_error.retry": "Покушајте поново",
@@ -53,10 +53,10 @@
   "bundle_modal_error.message": "Нешто није било у реду при учитавању ове компоненте.",
   "bundle_modal_error.retry": "Покушајте поново",
   "column.blocks": "Блокирани корисници",
-  "column.bookmarks": "Bookmarks",
+  "column.bookmarks": "Обележивачи",
   "column.community": "Локална временска линија",
   "column.direct": "Директне поруке",
-  "column.directory": "Browse profiles",
+  "column.directory": "Претражиј профиле",
   "column.domain_blocks": "Скривени домени",
   "column.favourites": "Омиљене",
   "column.follow_requests": "Захтеви за праћење",
@@ -81,22 +81,22 @@
   "compose_form.lock_disclaimer": "Ваш налог није {locked}. Свако може да Вас запрати и да види објаве намењене само Вашим пратиоцима.",
   "compose_form.lock_disclaimer.lock": "закључан",
   "compose_form.placeholder": "Шта Вам је на уму?",
-  "compose_form.poll.add_option": "Add a choice",
-  "compose_form.poll.duration": "Poll duration",
-  "compose_form.poll.option_placeholder": "Choice {number}",
-  "compose_form.poll.remove_option": "Remove this choice",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.add_option": "Додајте избор",
+  "compose_form.poll.duration": "Трајање анкете",
+  "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": "Mark media as sensitive",
+  "compose_form.sensitive.hide": "Означи мултимедију као осетљиву",
   "compose_form.sensitive.marked": "Медији су означени као осетљиви",
   "compose_form.sensitive.unmarked": "Медији су означени као не-осетљиви",
   "compose_form.spoiler.marked": "Текст је сакривен иза упозорења",
   "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": "Да ли сте сигурни да желите да блокирате корисника {name}?",
   "confirmations.delete.confirm": "Обриши",
@@ -105,25 +105,25 @@
   "confirmations.delete_list.message": "Да ли сте сигурни да желите да бесповратно обришете ову листу?",
   "confirmations.domain_block.confirm": "Сакриј цео домен",
   "confirmations.domain_block.message": "Да ли сте заиста сигурни да желите да блокирате цео домен {domain}? У већини случајева, неколико добро промишљених блокирања или ућуткавања су довољна и препоручљива.",
-  "confirmations.logout.confirm": "Log out",
-  "confirmations.logout.message": "Are you sure you want to log out?",
+  "confirmations.logout.confirm": "Одјави се",
+  "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.explanation": "Ово ће сакрити објаве од њих и објаве које их помињу, али ће им и даље дозволити да виде ваше постове и да вас запрате.",
   "confirmations.mute.message": "Да ли стварно желите да ућуткате корисника {name}?",
   "confirmations.redraft.confirm": "Избриши и преправи",
   "confirmations.redraft.message": "Да ли сте сигурни да желите да избришете овај статус и да га преправите? Сва стављања у омиљене трубе, као и подршке ће бити изгубљене, а одговори на оригинални пост ће бити поништени.",
-  "confirmations.reply.confirm": "Reply",
-  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.reply.confirm": "Одговори",
+  "confirmations.reply.message": "Одговарањем ћете обрисати поруку коју састављате. Јесте ли сигурни да желите да наставите?",
   "confirmations.unfollow.confirm": "Отпрати",
   "confirmations.unfollow.message": "Да ли сте сигурни да желите да отпратите корисника {name}?",
-  "conversation.delete": "Delete conversation",
-  "conversation.mark_as_read": "Mark as read",
-  "conversation.open": "View conversation",
-  "conversation.with": "With {names}",
-  "directory.federated": "From known fediverse",
-  "directory.local": "From {domain} only",
-  "directory.new_arrivals": "New arrivals",
-  "directory.recently_active": "Recently active",
+  "conversation.delete": "Обриши преписку",
+  "conversation.mark_as_read": "Означи као прочитано",
+  "conversation.open": "Прикажи преписку",
+  "conversation.with": "Са {names}",
+  "directory.federated": "Са знаних здружених инстанци",
+  "directory.local": "Само са {domain}",
+  "directory.new_arrivals": "Новопридошли",
+  "directory.recently_active": "Недавно активни",
   "embed.instructions": "Угради овај статус на Ваш веб сајт копирањем кода испод.",
   "embed.preview": "Овако ће да изгледа:",
   "emoji_button.activity": "Активност",
@@ -140,10 +140,10 @@
   "emoji_button.search_results": "Резултати претраге",
   "emoji_button.symbols": "Симболи",
   "emoji_button.travel": "Путовања и места",
-  "empty_column.account_timeline": "No toots here!",
-  "empty_column.account_unavailable": "Profile unavailable",
+  "empty_column.account_timeline": "Овде нема труба!",
+  "empty_column.account_unavailable": "Профил недоступан",
   "empty_column.blocks": "Још увек немате блокираних корисника.",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
+  "empty_column.bookmarked_statuses": "Још увек немате обележене трубе. Када их обележите, појавиће се овде.",
   "empty_column.community": "Локална временска линија је празна. Напишите нешто јавно да започнете!",
   "empty_column.direct": "Још увек немате директних порука. Када пошаљете или примите једну, појавиће се овде.",
   "empty_column.domain_blocks": "Још увек нема сакривених домена.",
@@ -158,41 +158,41 @@
   "empty_column.mutes": "Још увек немате ућутканих корисника.",
   "empty_column.notifications": "Тренутно немате обавештења. Дружите се мало да започнете разговор.",
   "empty_column.public": "Овде нема ничега! Напишите нешто јавно, или нађите кориснике са других инстанци које ћете запратити да попуните ову празнину",
-  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
-  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
-  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
-  "errors.unexpected_crash.report_issue": "Report issue",
+  "error.unexpected_crash.explanation": "Због грешке у нашем коду или проблема са компатибилношћу прегледача, ова страница се није могла правилно приказати.",
+  "error.unexpected_crash.next_steps": "Покушајте да освежите страницу. Ако то не помогне, можда ћете и даље моћи да користите Мастодон путем другог прегледача или матичне апликације.",
+  "errors.unexpected_crash.copy_stacktrace": "Копирај \"stacktrace\" у клипборд",
+  "errors.unexpected_crash.report_issue": "Пријави проблем",
   "follow_request.authorize": "Одобри",
   "follow_request.reject": "Одбиј",
   "getting_started.developers": "Програмери",
-  "getting_started.directory": "Profile directory",
+  "getting_started.directory": "Профил фасцикле",
   "getting_started.documentation": "Документација",
   "getting_started.heading": "Да почнете",
   "getting_started.invite": "Позовите људе",
   "getting_started.open_source_notice": "Мастoдон је софтвер отвореног кода. Можете му допринети или пријавити проблеме преко ГитХаба на {github}.",
   "getting_started.security": "Безбедност",
   "getting_started.terms": "Услови коришћења",
-  "hashtag.column_header.tag_mode.all": "and {additional}",
-  "hashtag.column_header.tag_mode.any": "or {additional}",
-  "hashtag.column_header.tag_mode.none": "without {additional}",
-  "hashtag.column_settings.select.no_options_message": "No suggestions found",
-  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "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.tag_mode.all": "Све оve",
+  "hashtag.column_settings.tag_mode.any": "Било које од ових",
+  "hashtag.column_settings.tag_mode.none": "Ништа од ових",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
   "home.column_settings.basic": "Основно",
   "home.column_settings.show_reblogs": "Прикажи и подржавања",
   "home.column_settings.show_replies": "Прикажи одговоре",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
-  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
-  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
-  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
-  "introduction.federation.action": "Next",
-  "introduction.federation.federated.headline": "Federated",
-  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
-  "introduction.federation.home.headline": "Home",
+  "home.hide_announcements": "Сакриј најаве",
+  "home.show_announcements": "Пријажи најаве",
+  "intervals.full.days": "{number, plural, one {# дан} other {# дана}}",
+  "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.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": "Local",
   "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
@@ -355,13 +355,13 @@
   "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 {резултат} few {резултата} other {резултата}}",
-  "status.admin_account": "Open moderation interface for @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_account": "Отвори модераторски интерфејс за @{name}",
+  "status.admin_status": "Отвори овај статус у модераторском интерфејсу",
   "status.block": "Блокирај @{name}",
-  "status.bookmark": "Bookmark",
+  "status.bookmark": "Обележи",
   "status.cancel_reblog_private": "Уклони подршку",
   "status.cannot_reblog": "Овај статус не може да се подржи",
-  "status.copy": "Copy link to status",
+  "status.copy": "Копирај везу на статус",
   "status.delete": "Обриши",
   "status.detailed_status": "Детаљни преглед разговора",
   "status.direct": "Директна порука @{name}",
@@ -377,13 +377,13 @@
   "status.open": "Прошири овај статус",
   "status.pin": "Закачи на профил",
   "status.pinned": "Закачена труба",
-  "status.read_more": "Read more",
+  "status.read_more": "Прочитајте више",
   "status.reblog": "Подржи",
   "status.reblog_private": "Подржи да види првобитна публика",
   "status.reblogged_by": "{name} подржао/ла",
   "status.reblogs.empty": "Још увек нико није подржао ову трубу. Када буде подржана, појавиће се овде.",
   "status.redraft": "Избриши и преправи",
-  "status.remove_bookmark": "Remove bookmark",
+  "status.remove_bookmark": "Уклони обележивач",
   "status.reply": "Одговори",
   "status.replyAll": "Одговори на дискусију",
   "status.report": "Пријави корисника @{name}",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 29b8b023e..763dae5ef 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "Grundläggande",
   "home.column_settings.show_reblogs": "Visa knuffar",
   "home.column_settings.show_replies": "Visa svar",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "Dölj notiser",
+  "home.show_announcements": "Visa notiser",
   "intervals.full.days": "{number, plural, one {# dag} other {# dagar}}",
   "intervals.full.hours": "{number, plural, one {# timme} other {# timmar}}",
   "intervals.full.minutes": "{number, plural, one {# minut} other {# minuter}}",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "nu",
   "relative_time.minutes": "{number}min",
   "relative_time.seconds": "{number}sek",
-  "relative_time.today": "today",
+  "relative_time.today": "idag",
   "reply_indicator.cancel": "Ångra",
   "report.forward": "Vidarebefordra till {target}",
   "report.forward_hint": "Kontot är från en annan server. Skicka även en anonymiserad kopia av anmälan dit?",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 71de4beaf..479d0ab31 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -3,11 +3,11 @@
   "account.badges.bot": "บอต",
   "account.badges.group": "กลุ่ม",
   "account.block": "ปิดกั้น @{name}",
-  "account.block_domain": "ซ่อนทุกอย่างจาก {domain}",
+  "account.block_domain": "ปิดกั้นโดเมน {domain}",
   "account.blocked": "ปิดกั้นอยู่",
   "account.cancel_follow_request": "ยกเลิกคำขอติดตาม",
   "account.direct": "ส่งข้อความโดยตรงถึง @{name}",
-  "account.domain_blocked": "ซ่อนโดเมนอยู่",
+  "account.domain_blocked": "ปิดกั้นโดเมนอยู่",
   "account.edit_profile": "แก้ไขโปรไฟล์",
   "account.endorse": "แสดงให้เห็นในโปรไฟล์",
   "account.follow": "ติดตาม",
@@ -34,7 +34,7 @@
   "account.share": "แบ่งปันโปรไฟล์ของ @{name}",
   "account.show_reblogs": "แสดงการดันจาก @{name}",
   "account.unblock": "เลิกปิดกั้น @{name}",
-  "account.unblock_domain": "เลิกซ่อน {domain}",
+  "account.unblock_domain": "เลิกปิดกั้นโดเมน {domain}",
   "account.unendorse": "ไม่แสดงให้เห็นในโปรไฟล์",
   "account.unfollow": "เลิกติดตาม",
   "account.unmute": "เลิกปิดเสียง @{name}",
@@ -54,10 +54,10 @@
   "bundle_modal_error.retry": "ลองอีกครั้ง",
   "column.blocks": "ผู้ใช้ที่ปิดกั้นอยู่",
   "column.bookmarks": "ที่คั่นหน้า",
-  "column.community": "เส้นเวลาในเว็บ",
+  "column.community": "เส้นเวลาในเซิร์ฟเวอร์",
   "column.direct": "ข้อความโดยตรง",
   "column.directory": "เรียกดูโปรไฟล์",
-  "column.domain_blocks": "โดเมนที่ซ่อนอยู่",
+  "column.domain_blocks": "โดเมนที่ปิดกั้นอยู่",
   "column.favourites": "รายการโปรด",
   "column.follow_requests": "คำขอติดตาม",
   "column.home": "หน้าแรก",
@@ -103,7 +103,7 @@
   "confirmations.delete.message": "คุณแน่ใจหรือไม่ว่าต้องการลบสถานะนี้?",
   "confirmations.delete_list.confirm": "ลบ",
   "confirmations.delete_list.message": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการนี้อย่างถาวร?",
-  "confirmations.domain_block.confirm": "ซ่อนทั้งโดเมน",
+  "confirmations.domain_block.confirm": "ปิดกั้นทั้งโดเมน",
   "confirmations.domain_block.message": "คุณแน่ใจจริง ๆ หรือไม่ว่าต้องการปิดกั้นทั้ง {domain}? ในกรณีส่วนใหญ่ การปิดกั้นหรือการปิดเสียงแบบกำหนดเป้าหมายไม่กี่รายการนั้นเพียงพอและเป็นที่นิยม คุณจะไม่เห็นเนื้อหาจากโดเมนนั้นในเส้นเวลาสาธารณะใด ๆ หรือการแจ้งเตือนของคุณ จะเอาผู้ติดตามของคุณจากโดเมนนั้นออก",
   "confirmations.logout.confirm": "ออกจากระบบ",
   "confirmations.logout.message": "คุณแน่ใจหรือไม่ว่าต้องการออกจากระบบ?",
@@ -144,9 +144,9 @@
   "empty_column.account_unavailable": "ไม่มีโปรไฟล์",
   "empty_column.blocks": "คุณยังไม่ได้ปิดกั้นผู้ใช้ใด ๆ",
   "empty_column.bookmarked_statuses": "คุณยังไม่มีโพสต์ที่เพิ่มที่คั่นหน้าไว้ใด ๆ เมื่อคุณเพิ่มที่คั่นหน้าโพสต์ โพสต์จะปรากฏที่นี่",
-  "empty_column.community": "เส้นเวลาในเว็บว่างเปล่า เขียนบางอย่างเป็นสาธารณะเพื่อเริ่มต้น!",
+  "empty_column.community": "เส้นเวลาในเซิร์ฟเวอร์ว่างเปล่า เขียนบางอย่างเป็นสาธารณะเพื่อเริ่มต้น!",
   "empty_column.direct": "คุณยังไม่มีข้อความโดยตรงใด ๆ เมื่อคุณส่งหรือรับข้อความ ข้อความจะปรากฏที่นี่",
-  "empty_column.domain_blocks": "ยังไม่มีโดเมนที่ซ่อนอยู่",
+  "empty_column.domain_blocks": "ยังไม่มีโดเมนที่ปิดกั้นอยู่",
   "empty_column.favourited_statuses": "คุณยังไม่มีโพสต์ที่ชื่นชอบใด ๆ เมื่อคุณชื่นชอบโพสต์ โพสต์จะปรากฏที่นี่",
   "empty_column.favourites": "ยังไม่มีใครชื่นชอบโพสต์นี้ เมื่อใครสักคนชื่นชอบ เขาจะปรากฏที่นี่",
   "empty_column.follow_requests": "คุณยังไม่มีคำขอติดตามใด ๆ เมื่อคุณได้รับคำขอ คำขอจะปรากฏที่นี่",
@@ -194,8 +194,8 @@
   "introduction.federation.federated.text": "โพสต์สาธารณะจากเซิร์ฟเวอร์อื่น ๆ ของเฟดิเวิร์สจะปรากฏในเส้นเวลาที่ติดต่อกับภายนอก",
   "introduction.federation.home.headline": "หน้าแรก",
   "introduction.federation.home.text": "โพสต์จากผู้คนที่คุณติดตามจะปรากฏในฟีดหน้าแรกของคุณ คุณสามารถติดตามใครก็ตามในเซิร์ฟเวอร์ใดก็ตาม!",
-  "introduction.federation.local.headline": "ในเว็บ",
-  "introduction.federation.local.text": "โพสต์สาธารณะจากผู้คนในเซิร์ฟเวอร์เดียวกันกับคุณจะปรากฏในเส้นเวลาในเว็บ",
+  "introduction.federation.local.headline": "ในเซิร์ฟเวอร์",
+  "introduction.federation.local.text": "โพสต์สาธารณะจากผู้คนในเซิร์ฟเวอร์เดียวกันกับคุณจะปรากฏในเส้นเวลาในเซิร์ฟเวอร์",
   "introduction.interactions.action": "เสร็จสิ้นบทช่วยสอน!",
   "introduction.interactions.favourite.headline": "ชื่นชอบ",
   "introduction.interactions.favourite.text": "คุณสามารถบันทึกโพสต์ไว้ในภายหลังและแจ้งให้ผู้สร้างทราบว่าคุณชอบโพสต์โดยการชื่นชอบโพสต์",
@@ -222,7 +222,7 @@
   "keyboard_shortcuts.home": "เพื่อเปิดเส้นเวลาหน้าแรก",
   "keyboard_shortcuts.hotkey": "ปุ่มลัด",
   "keyboard_shortcuts.legend": "เพื่อแสดงคำอธิบายนี้",
-  "keyboard_shortcuts.local": "เพื่อเปิดเส้นเวลาในเว็บ",
+  "keyboard_shortcuts.local": "เพื่อเปิดเส้นเวลาในเซิร์ฟเวอร์",
   "keyboard_shortcuts.mention": "เพื่อกล่าวถึงผู้สร้าง",
   "keyboard_shortcuts.muted": "เพื่อเปิดรายการผู้ใช้ที่ปิดเสียงอยู่",
   "keyboard_shortcuts.my_profile": "เพื่อเปิดโปรไฟล์ของคุณ",
@@ -254,18 +254,18 @@
   "lists.subheading": "รายการของคุณ",
   "load_pending": "{count, plural, other {# รายการใหม่}}",
   "loading_indicator.label": "กำลังโหลด...",
-  "media_gallery.toggle_visible": "เปิด/ปิดการมองเห็น",
+  "media_gallery.toggle_visible": "ซ่อนสื่อ",
   "missing_indicator.label": "ไม่พบ",
   "missing_indicator.sublabel": "ไม่พบทรัพยากรนี้",
   "mute_modal.hide_notifications": "ซ่อนการแจ้งเตือนจากผู้ใช้นี้?",
   "navigation_bar.apps": "แอปมือถือ",
   "navigation_bar.blocks": "ผู้ใช้ที่ปิดกั้นอยู่",
   "navigation_bar.bookmarks": "ที่คั่นหน้า",
-  "navigation_bar.community_timeline": "เส้นเวลาในเว็บ",
+  "navigation_bar.community_timeline": "เส้นเวลาในเซิร์ฟเวอร์",
   "navigation_bar.compose": "เขียนโพสต์ใหม่",
   "navigation_bar.direct": "ข้อความโดยตรง",
   "navigation_bar.discover": "ค้นพบ",
-  "navigation_bar.domain_blocks": "โดเมนที่ซ่อนอยู่",
+  "navigation_bar.domain_blocks": "โดเมนที่ปิดกั้นอยู่",
   "navigation_bar.edit_profile": "แก้ไขโปรไฟล์",
   "navigation_bar.favourites": "รายการโปรด",
   "navigation_bar.filters": "คำที่ปิดเสียงอยู่",
@@ -319,13 +319,13 @@
   "poll_button.add_poll": "เพิ่มการสำรวจความคิดเห็น",
   "poll_button.remove_poll": "เอาการสำรวจความคิดเห็นออก",
   "privacy.change": "ปรับเปลี่ยนความเป็นส่วนตัวของสถานะ",
-  "privacy.direct.long": "โพสต์ไปยังผู้ใช้ที่กล่าวถึงเท่านั้น",
+  "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.long": "ปรากฏแก่ทุกคน แต่ไม่อยู่ในเส้นเวลาสาธารณะ",
   "privacy.unlisted.short": "ไม่อยู่ในรายการ",
   "refresh": "รีเฟรช",
   "regeneration_indicator.label": "กำลังโหลด…",
@@ -401,7 +401,7 @@
   "suggestions.header": "คุณอาจสนใจ…",
   "tabs_bar.federated_timeline": "ที่ติดต่อกับภายนอก",
   "tabs_bar.home": "หน้าแรก",
-  "tabs_bar.local_timeline": "ในเว็บ",
+  "tabs_bar.local_timeline": "ในเซิร์ฟเวอร์",
   "tabs_bar.notifications": "การแจ้งเตือน",
   "tabs_bar.search": "ค้นหา",
   "time_remaining.days": "เหลืออีก {number, plural, other {# วัน}}",
@@ -409,7 +409,7 @@
   "time_remaining.minutes": "เหลืออีก {number, plural, other {# นาที}}",
   "time_remaining.moments": "ช่วงเวลาที่เหลือ",
   "time_remaining.seconds": "เหลืออีก {number, plural, other {# วินาที}}",
-  "trends.count_by_accounts": "{count} {rawCount, plural, other {คน}}กำลังคุย",
+  "trends.count_by_accounts": "{count} {rawCount, plural, other {คน}}กำลังพูดคุย",
   "trends.trending_now": "กำลังนิยม",
   "ui.beforeunload": "แบบร่างของคุณจะหายไปหากคุณออกจาก Mastodon",
   "upload_area.title": "ลากแล้วปล่อยเพื่ออัปโหลด",
diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json
index 664eebfbf..d625a88bf 100644
--- a/app/javascript/mastodon/locales/ur.json
+++ b/app/javascript/mastodon/locales/ur.json
@@ -254,7 +254,7 @@
   "lists.subheading": "Your lists",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
   "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "Toggle visibility",
+  "media_gallery.toggle_visible": "Hide media",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 41ecfe1f2..57658706a 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -158,7 +158,7 @@
   "empty_column.mutes": "你没有隐藏任何用户。",
   "empty_column.notifications": "你还没有收到过任何通知,快和其他用户互动吧。",
   "empty_column.public": "这里什么都没有!写一些公开的嘟文,或者关注其他服务器的用户后,这里就会有嘟文出现了",
-  "error.unexpected_crash.explanation": "此页面无法正确现实,这可能是因为我们的代码中有错误,也可能是因为浏览器兼容问题。",
+  "error.unexpected_crash.explanation": "此页面无法正确显示,这可能是因为我们的代码中有错误,也可能是因为浏览器兼容问题。",
   "error.unexpected_crash.next_steps": "刷新一下页面试试。如果没用,您可以换个浏览器或者用本地应用。",
   "errors.unexpected_crash.copy_stacktrace": "把堆栈跟踪信息复制到剪贴板",
   "errors.unexpected_crash.report_issue": "报告问题",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 12f154a2c..a321e5a66 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -1,7 +1,7 @@
 {
   "account.add_or_remove_from_list": "從名單中新增或移除",
   "account.badges.bot": "機械人",
-  "account.badges.group": "Group",
+  "account.badges.group": "群組",
   "account.block": "封鎖 @{name}",
   "account.block_domain": "隱藏來自 {domain} 的一切文章",
   "account.blocked": "封鎖",
@@ -43,7 +43,7 @@
   "alert.rate_limited.title": "已限速",
   "alert.unexpected.message": "發生不可預期的錯誤。",
   "alert.unexpected.title": "噢!",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "公告",
   "autosuggest_hashtag.per_week": "{count} / 週",
   "boost_modal.combo": "如你想在下次路過這顯示,請按{combo},",
   "bundle_column_error.body": "加載本組件出錯。",
@@ -85,8 +85,8 @@
   "compose_form.poll.duration": "投票期限",
   "compose_form.poll.option_placeholder": "第 {number} 個選擇",
   "compose_form.poll.remove_option": "移除此選擇",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "變更投票為允許多個選項",
+  "compose_form.poll.switch_to_single": "變更投票為允許單一選項",
   "compose_form.publish": "發文",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.hide": "標記媒體為敏感內容",
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "基本",
   "home.column_settings.show_reblogs": "顯示被轉推的文章",
   "home.column_settings.show_replies": "顯示回應文章",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "隱藏公告",
+  "home.show_announcements": "顯示公告",
   "intervals.full.days": "{number, plural, one {# 天} other {# 天}}",
   "intervals.full.hours": "{number, plural, one {# 小時} other {# 小時}}",
   "intervals.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "剛剛",
   "relative_time.minutes": "{number}分鐘",
   "relative_time.seconds": "{number}秒",
-  "relative_time.today": "today",
+  "relative_time.today": "今天",
   "reply_indicator.cancel": "取消",
   "report.forward": "轉寄到 {target}",
   "report.forward_hint": "這個帳戶屬於其他服務站。要向該服務站發送匿名的舉報訊息嗎?",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index 56c4de066..112d5cb2f 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -1,7 +1,7 @@
 {
   "account.add_or_remove_from_list": "從名單中新增或移除",
   "account.badges.bot": "機器人",
-  "account.badges.group": "Group",
+  "account.badges.group": "群組",
   "account.block": "封鎖 @{name}",
   "account.block_domain": "隱藏來自 {domain} 的所有內容",
   "account.blocked": "已封鎖",
@@ -43,7 +43,7 @@
   "alert.rate_limited.title": "已限速",
   "alert.unexpected.message": "發生了非預期的錯誤。",
   "alert.unexpected.title": "哎呀!",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "公告",
   "autosuggest_hashtag.per_week": "{count} / 週",
   "boost_modal.combo": "下次您可以按 {combo} 跳過",
   "bundle_column_error.body": "載入此元件時發生錯誤。",
@@ -85,8 +85,8 @@
   "compose_form.poll.duration": "投票期限",
   "compose_form.poll.option_placeholder": "第 {number} 個選擇",
   "compose_form.poll.remove_option": "移除此選擇",
-  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "變更投票為允許多個選項",
+  "compose_form.poll.switch_to_single": "變更投票為允許單一選項",
   "compose_form.publish": "嘟出去",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.sensitive.hide": "標記媒體為敏感內容",
@@ -184,8 +184,8 @@
   "home.column_settings.basic": "基本",
   "home.column_settings.show_reblogs": "顯示轉嘟",
   "home.column_settings.show_replies": "顯示回覆",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
+  "home.hide_announcements": "隱藏公告",
+  "home.show_announcements": "顯示公告",
   "intervals.full.days": "{number, plural, one {# 天} other {# 天}}",
   "intervals.full.hours": "{number, plural, one {# 小時} other {# 小時}}",
   "intervals.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}",
@@ -335,7 +335,7 @@
   "relative_time.just_now": "剛剛",
   "relative_time.minutes": "{number} 分",
   "relative_time.seconds": "{number} 秒",
-  "relative_time.today": "today",
+  "relative_time.today": "今天",
   "reply_indicator.cancel": "取消",
   "report.forward": "轉寄到 {target}",
   "report.forward_hint": "這個帳戶屬於其他站點。要像該站點發送匿名的檢舉訊息嗎?",
diff --git a/app/javascript/mastodon/middleware/errors.js b/app/javascript/mastodon/middleware/errors.js
index 3cebb42e0..0a65fd321 100644
--- a/app/javascript/mastodon/middleware/errors.js
+++ b/app/javascript/mastodon/middleware/errors.js
@@ -8,7 +8,7 @@ export default function errorsMiddleware() {
       const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
 
       if (action.type.match(isFail)) {
-        dispatch(showAlertForError(action.error));
+        dispatch(showAlertForError(action.error, action.skipNotFound));
       }
     }
 
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index c6653fe4c..e6e6d2ae1 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -261,7 +261,6 @@ export default function compose(state = initialState, action) {
     });
   case COMPOSE_SPOILERNESS_CHANGE:
     return state.withMutations(map => {
-      map.set('spoiler_text', '');
       map.set('spoiler', !state.get('spoiler'));
       map.set('idempotencyKey', uuid());
 
diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js
index 60e901e39..ed1ba0272 100644
--- a/app/javascript/mastodon/reducers/notifications.js
+++ b/app/javascript/mastodon/reducers/notifications.js
@@ -72,11 +72,11 @@ const expandNormalizedNotifications = (state, notifications, next, isLoadingRece
 
       mutable.update(usePendingItems ? 'pendingItems' : 'items', list => {
         const lastIndex = 1 + list.findLastIndex(
-          item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id'))
+          item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id')),
         );
 
         const firstIndex = 1 + list.take(lastIndex).findLastIndex(
-          item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0
+          item => item !== null && compareId(item.get('id'), items.first().get('id')) > 0,
         );
 
         return list.take(firstIndex).concat(items, list.skip(lastIndex));
diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js
index 0d7222e10..63b76773d 100644
--- a/app/javascript/mastodon/reducers/timelines.js
+++ b/app/javascript/mastodon/reducers/timelines.js
@@ -54,7 +54,7 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is
 
         return oldIds.take(firstIndex + 1).concat(
           isPartial && oldIds.get(firstIndex) !== null ? newIds.unshift(null) : newIds,
-          oldIds.skip(lastIndex)
+          oldIds.skip(lastIndex),
         );
       });
     }
@@ -166,7 +166,7 @@ export default function timelines(state = initialState, action) {
     return state.update(
       action.timeline,
       initialTimeline,
-      map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items)
+      map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items),
     );
   default:
     return state;
diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js
index 6a48f3b3f..673268c5a 100644
--- a/app/javascript/mastodon/selectors/index.js
+++ b/app/javascript/mastodon/selectors/index.js
@@ -117,7 +117,7 @@ export const makeGetStatus = () => {
         map.set('account', accountBase);
         map.set('filtered', filtered);
       });
-    }
+    },
   );
 };
 
diff --git a/app/javascript/mastodon/service_worker/web_push_notifications.js b/app/javascript/mastodon/service_worker/web_push_notifications.js
index 1ab0dc0fa..958e5fc12 100644
--- a/app/javascript/mastodon/service_worker/web_push_notifications.js
+++ b/app/javascript/mastodon/service_worker/web_push_notifications.js
@@ -117,7 +117,7 @@ const handlePush = (event) => {
         badge: '/badge.png',
         data: { access_token, preferred_locale, url: '/web/notifications' },
       });
-    })
+    }),
   );
 };
 
diff --git a/app/javascript/mastodon/store/configureStore.js b/app/javascript/mastodon/store/configureStore.js
index 7e7472841..e18af842f 100644
--- a/app/javascript/mastodon/store/configureStore.js
+++ b/app/javascript/mastodon/store/configureStore.js
@@ -10,6 +10,6 @@ export default function configureStore() {
     thunk,
     loadingBarMiddleware({ promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'] }),
     errorsMiddleware(),
-    soundsMiddleware()
+    soundsMiddleware(),
   ), window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f));
 };
diff --git a/app/javascript/mastodon/utils/log_out.js b/app/javascript/mastodon/utils/log_out.js
index b43417f4b..3a4cc8ecb 100644
--- a/app/javascript/mastodon/utils/log_out.js
+++ b/app/javascript/mastodon/utils/log_out.js
@@ -1,4 +1,4 @@
-import Rails from 'rails-ujs';
+import Rails from '@rails/ujs';
 
 export const logOut = () => {
   const form = document.createElement('form');
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index 13cb5d548..5b699e767 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -8,7 +8,7 @@ start();
 function main() {
   const IntlMessageFormat = require('intl-messageformat').default;
   const { timeAgoString } = require('../mastodon/components/relative_timestamp');
-  const { delegate } = require('rails-ujs');
+  const { delegate } = require('@rails/ujs');
   const emojify = require('../mastodon/features/emoji/emoji').default;
   const { getLocale } = require('../mastodon/locales');
   const { messages } = getLocale();
@@ -101,6 +101,28 @@ function main() {
 
     delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original'));
     delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static'));
+
+    delegate(document, '.status__content__spoiler-link', 'click', function() {
+      const contentEl = this.parentNode.parentNode.querySelector('.e-content');
+
+      if (contentEl.style.display === 'block') {
+        contentEl.style.display = 'none';
+        this.parentNode.style.marginBottom = 0;
+        this.textContent = (new IntlMessageFormat(messages['status.show_more'] || 'Show more', locale)).format();
+      } else {
+        contentEl.style.display = 'block';
+        this.parentNode.style.marginBottom = null;
+        this.textContent = (new IntlMessageFormat(messages['status.show_less'] || 'Show less', locale)).format();
+      }
+
+      return false;
+    });
+
+    [].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => {
+      const contentEl = spoilerLink.parentNode.parentNode.querySelector('.e-content');
+      const message = (contentEl.style.display === 'block') ? (messages['status.show_less'] || 'Show less') : (messages['status.show_more'] || 'Show more');
+      spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format();
+    });
   });
 
   delegate(document, '.sidebar__toggle__icon', 'click', () => {
diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index 05e52966b..7a846bcc6 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -142,7 +142,7 @@ html {
 }
 
 .compose-form__autosuggest-wrapper,
-.poll__text input[type="text"],
+.poll__option input[type="text"],
 .compose-form .spoiler-input__input,
 .compose-form__poll-wrapper select,
 .search__input,
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index fb136d1a3..7bff2daa1 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -418,6 +418,11 @@ body,
       }
     }
 
+    &--with-select strong {
+      display: block;
+      margin-bottom: 10px;
+    }
+
     a {
       display: inline-block;
       color: $darker-text-color;
@@ -583,19 +588,22 @@ body,
 }
 
 .log-entry {
-  margin-bottom: 20px;
   line-height: 20px;
+  padding: 15px 0;
+  background: $ui-base-color;
+  border-bottom: 1px solid lighten($ui-base-color, 4%);
+
+  &:last-child {
+    border-bottom: 0;
+  }
 
   &__header {
     display: flex;
     justify-content: flex-start;
     align-items: center;
-    padding: 10px;
-    background: $ui-base-color;
     color: $darker-text-color;
-    border-radius: 4px 4px 0 0;
     font-size: 14px;
-    position: relative;
+    padding: 0 10px;
   }
 
   &__avatar {
@@ -622,44 +630,6 @@ body,
     color: $dark-text-color;
   }
 
-  &__extras {
-    background: lighten($ui-base-color, 6%);
-    border-radius: 0 0 4px 4px;
-    padding: 10px;
-    color: $darker-text-color;
-    font-family: $font-monospace, monospace;
-    font-size: 12px;
-    word-wrap: break-word;
-    min-height: 20px;
-  }
-
-  &__icon {
-    font-size: 28px;
-    margin-right: 10px;
-    color: $dark-text-color;
-  }
-
-  &__icon__overlay {
-    position: absolute;
-    top: 10px;
-    right: 10px;
-    width: 10px;
-    height: 10px;
-    border-radius: 50%;
-
-    &.positive {
-      background: $success-green;
-    }
-
-    &.negative {
-      background: lighten($error-red, 12%);
-    }
-
-    &.neutral {
-      background: $ui-highlight-color;
-    }
-  }
-
   a,
   .username,
   .target {
@@ -667,18 +637,6 @@ body,
     text-decoration: none;
     font-weight: 500;
   }
-
-  .diff-old {
-    color: lighten($error-red, 12%);
-  }
-
-  .diff-neutral {
-    color: $secondary-text-color;
-  }
-
-  .diff-new {
-    color: $success-green;
-  }
 }
 
 a.name-tag,
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index aa885e241..dd82b0824 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -388,8 +388,8 @@
 
   .emoji-picker-dropdown {
     position: absolute;
-    top: 5px;
-    right: 5px;
+    top: 0;
+    right: 0;
   }
 
   .compose-form__autosuggest-wrapper {
@@ -870,6 +870,7 @@
 
 .announcements__item__content {
   word-wrap: break-word;
+  overflow-y: auto;
 
   .emojione {
     width: 20px;
@@ -1027,13 +1028,11 @@
     }
 
     .display-name {
+      color: $light-text-color;
+
       strong {
         color: $inverted-text-color;
       }
-
-      span {
-        color: $light-text-color;
-      }
     }
 
     .status__content {
@@ -1332,7 +1331,6 @@
     border-radius: 50%;
     overflow: hidden;
     position: relative;
-    cursor: default;
 
     & > div {
       float: left;
@@ -3802,7 +3800,8 @@ a.status-card.compact:hover {
 }
 
 .empty-column-indicator,
-.error-column {
+.error-column,
+.follow_requests-unlocked_explanation {
   color: $dark-text-color;
   background: $ui-base-color;
   text-align: center;
@@ -3833,6 +3832,11 @@ a.status-card.compact:hover {
   }
 }
 
+.follow_requests-unlocked_explanation {
+  background: darken($ui-base-color, 4%);
+  contain: initial;
+}
+
 .error-column {
   flex-direction: column;
 }
@@ -4060,10 +4064,7 @@ a.status-card.compact:hover {
 
 .emoji-button {
   display: block;
-  font-size: 24px;
-  line-height: 24px;
-  margin-left: 2px;
-  width: 24px;
+  padding: 5px 5px 2px 2px;
   outline: 0;
   cursor: pointer;
 
@@ -4079,7 +4080,6 @@ a.status-card.compact:hover {
     margin: 0;
     width: 22px;
     height: 22px;
-    margin-top: 2px;
   }
 
   &:hover,
@@ -5058,12 +5058,6 @@ a.status-card.compact:hover {
 }
 
 .media-gallery__gifv {
-  &.autoplay {
-    .media-gallery__gifv__label {
-      display: none;
-    }
-  }
-
   &:hover {
     .media-gallery__gifv__label {
       opacity: 1;
@@ -6579,6 +6573,7 @@ noscript {
     padding: 10px;
     padding-top: 12px;
     position: relative;
+    cursor: pointer;
   }
 
   &__unread {
@@ -6682,17 +6677,21 @@ noscript {
     box-sizing: border-box;
     width: 100%;
     padding: 15px;
-    padding-right: 15px + 18px;
     position: relative;
     font-size: 15px;
     line-height: 20px;
     word-wrap: break-word;
     font-weight: 400;
+    max-height: 50vh;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
 
     &__range {
       display: block;
       font-weight: 500;
       margin-bottom: 10px;
+      padding-right: 18px;
     }
 
     &__unread {
diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss
index d7d850a1e..1ecc8434d 100644
--- a/app/javascript/styles/mastodon/polls.scss
+++ b/app/javascript/styles/mastodon/polls.scss
@@ -8,20 +8,18 @@
   }
 
   &__chart {
-    position: absolute;
-    top: 0;
-    left: 0;
-    height: 100%;
-    display: inline-block;
     border-radius: 4px;
-    background: darken($ui-primary-color, 14%);
+    display: block;
+    background: darken($ui-primary-color, 5%);
+    height: 5px;
+    min-width: 1%;
 
     &.leading {
       background: $ui-highlight-color;
     }
   }
 
-  &__text {
+  &__option {
     position: relative;
     display: flex;
     padding: 6px 0;
@@ -29,6 +27,13 @@
     cursor: default;
     overflow: hidden;
 
+    &__text {
+      display: inline-block;
+      word-wrap: break-word;
+      overflow-wrap: break-word;
+      max-width: calc(100% - 45px - 25px);
+    }
+
     input[type=radio],
     input[type=checkbox] {
       display: none;
@@ -95,8 +100,8 @@
     &:active,
     &:focus,
     &:hover {
+      border-color: lighten($valid-value-color, 15%);
       border-width: 4px;
-      background: none;
     }
 
     &::-moz-focus-inner {
@@ -112,19 +117,18 @@
 
   &__number {
     display: inline-block;
-    width: 52px;
+    width: 45px;
     font-weight: 700;
-    padding: 0 10px;
-    padding-left: 8px;
-    text-align: right;
-    margin-top: auto;
-    margin-bottom: auto;
-    flex: 0 0 52px;
+    flex: 0 0 45px;
   }
 
-  &__vote__mark {
-    float: left;
-    line-height: 18px;
+  &__voted {
+    padding: 0 5px;
+    display: inline-block;
+
+    &__mark {
+      font-size: 18px;
+    }
   }
 
   &__footer {
@@ -199,7 +203,7 @@
     display: flex;
     align-items: center;
 
-    .poll__text {
+    .poll__option {
       flex: 0 0 auto;
       width: calc(100% - (23px + 6px));
       margin-right: 6px;
diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb
index ed680d762..1523f86d4 100644
--- a/app/lib/activitypub/tag_manager.rb
+++ b/app/lib/activitypub/tag_manager.rb
@@ -15,6 +15,8 @@ class ActivityPub::TagManager
   def url_for(target)
     return target.url if target.respond_to?(:local?) && !target.local?
 
+    return unless target.respond_to?(:object_type)
+
     case target.object_type
     when :person
       target.instance_actor? ? about_more_url(instance_actor: true) : short_account_url(target)
diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb
index 35a3773d2..afdbd70f2 100644
--- a/app/lib/entity_cache.rb
+++ b/app/lib/entity_cache.rb
@@ -7,6 +7,10 @@ class EntityCache
 
   MAX_EXPIRATION = 7.days.freeze
 
+  def status(url)
+    Rails.cache.fetch(to_key(:status, url), expires_in: MAX_EXPIRATION) { FetchRemoteStatusService.new.call(url) }
+  end
+
   def mention(username, domain)
     Rails.cache.fetch(to_key(:mention, username, domain), expires_in: MAX_EXPIRATION) { Account.select(:id, :username, :domain, :url).find_remote(username, domain) }
   end
diff --git a/app/lib/exceptions.rb b/app/lib/exceptions.rb
index 01346bfe5..3362576b0 100644
--- a/app/lib/exceptions.rb
+++ b/app/lib/exceptions.rb
@@ -8,6 +8,7 @@ module Mastodon
   class LengthValidationError < ValidationError; end
   class DimensionsValidationError < ValidationError; end
   class RaceConditionError < Error; end
+  class RateLimitExceededError < Error; end
 
   class UnexpectedResponseError < Error
     def initialize(response = nil)
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
index fcc99d009..051f27408 100644
--- a/app/lib/formatter.rb
+++ b/app/lib/formatter.rb
@@ -59,7 +59,7 @@ class Formatter
     html = "RT @#{prepend_reblog} #{html}" if prepend_reblog
     html = format_markdown(html) if status.content_type == 'text/markdown'
     html = encode_and_link_urls(html, linkable_accounts, keep_html: %w(text/markdown text/html).include?(status.content_type))
-    html = reformat(html) if %w(text/markdown text/html).include?(status.content_type)
+    html = reformat(html, true) if %w(text/markdown text/html).include?(status.content_type)
     html = encode_custom_emojis(html, status.emojis, options[:autoplay]) if options[:custom_emojify]
 
     unless %w(text/markdown text/html).include?(status.content_type)
@@ -75,8 +75,8 @@ class Formatter
     html.delete("\r").delete("\n")
   end
 
-  def reformat(html)
-    sanitize(html, Sanitize::Config::MASTODON_STRICT)
+  def reformat(html, outgoing = false)
+    sanitize(html, Sanitize::Config::MASTODON_STRICT.merge(outgoing: outgoing))
   rescue ArgumentError
     ''
   end
@@ -131,7 +131,7 @@ class Formatter
   end
 
   def link_url(url)
-    "<a href=\"#{encode(url)}\" target=\"blank\" rel=\"nofollow noopener\">#{link_html(url)}</a>"
+    "<a href=\"#{encode(url)}\" target=\"blank\" rel=\"nofollow noopener noreferrer\">#{link_html(url)}</a>"
   end
 
   private
diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb
index 302072bcc..05a06726d 100644
--- a/app/lib/language_detector.rb
+++ b/app/lib/language_detector.rb
@@ -52,8 +52,10 @@ class LanguageDetector
 
   def detect_language_code(text)
     return if unreliable_input?(text)
+
     result = @identifier.find_language(text)
-    iso6391(result.language.to_s).to_sym if result.reliable?
+
+    iso6391(result.language.to_s).to_sym if result&.reliable?
   end
 
   def iso6391(bcp47)
diff --git a/app/lib/rate_limiter.rb b/app/lib/rate_limiter.rb
new file mode 100644
index 000000000..0e2c9a894
--- /dev/null
+++ b/app/lib/rate_limiter.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+class RateLimiter
+  include Redisable
+
+  FAMILIES = {
+    follows: {
+      limit: 400,
+      period: 24.hours.freeze,
+    }.freeze,
+
+    statuses: {
+      limit: 300,
+      period: 3.hours.freeze,
+    }.freeze,
+
+    reports: {
+      limit: 400,
+      period: 24.hours.freeze,
+    }.freeze,
+  }.freeze
+
+  def initialize(by, options = {})
+    @by     = by
+    @family = options[:family]
+    @limit  = FAMILIES[@family][:limit]
+    @period = FAMILIES[@family][:period].to_i
+  end
+
+  def record!
+    count = redis.get(key)
+
+    if count.nil?
+      redis.set(key, 0)
+      redis.expire(key, (@period - (last_epoch_time % @period) + 1).to_i)
+    end
+
+    raise Mastodon::RateLimitExceededError if count.present? && count.to_i >= @limit
+
+    redis.incr(key)
+  end
+
+  def rollback!
+    redis.decr(key)
+  end
+
+  def to_headers(now = Time.now.utc)
+    {
+      'X-RateLimit-Limit' => @limit.to_s,
+      'X-RateLimit-Remaining' => (@limit - (redis.get(key) || 0).to_i).to_s,
+      'X-RateLimit-Reset' => (now + (@period - now.to_i % @period)).iso8601(6),
+    }
+  end
+
+  private
+
+  def key
+    @key ||= "rate_limit:#{@by.id}:#{@family}:#{(last_epoch_time / @period).to_i}"
+  end
+
+  def last_epoch_time
+    @last_epoch_time ||= Time.now.to_i
+  end
+end
diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb
index e3fc94ba6..34793ed93 100644
--- a/app/lib/sanitize_config.rb
+++ b/app/lib/sanitize_config.rb
@@ -54,6 +54,18 @@ class Sanitize
       end
     end
 
+    LINK_REL_TRANSFORMER = lambda do |env|
+      return unless env[:node_name] == 'a'
+
+      node = env[:node]
+
+      rel = (node['rel'] || '').split(' ') & ['tag']
+      unless env[:config][:outgoing] && TagManager.instance.local_url?(node['href'])
+        rel += ['nofollow', 'noopener', 'noreferrer']
+      end
+      node['rel'] = rel.join(' ')
+    end
+
     UNSUPPORTED_HREF_TRANSFORMER = lambda do |env|
       return unless env[:node_name] == 'a'
 
@@ -82,7 +94,6 @@ class Sanitize
 
       add_attributes: {
         'a' => {
-          'rel' => 'nofollow noopener tag noreferrer',
           'target' => '_blank',
         },
       },
@@ -96,6 +107,7 @@ class Sanitize
         CLASS_WHITELIST_TRANSFORMER,
         IMG_TAG_TRANSFORMER,
         UNSUPPORTED_HREF_TRANSFORMER,
+        LINK_REL_TRANSFORMER,
       ]
     )
 
diff --git a/app/models/account.rb b/app/models/account.rb
index 0fcf897c9..82d4d10de 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -46,6 +46,7 @@
 #  silenced_at             :datetime
 #  suspended_at            :datetime
 #  trust_level             :integer
+#  hide_collections        :boolean
 #
 
 class Account < ApplicationRecord
@@ -106,6 +107,7 @@ class Account < ApplicationRecord
   scope :discoverable, -> { searchable.without_silenced.where(discoverable: true).left_outer_joins(:account_stat) }
   scope :tagged_with, ->(tag) { joins(:accounts_tags).where(accounts_tags: { tag_id: tag }) }
   scope :by_recent_status, -> { order(Arel.sql('(case when account_stats.last_status_at is null then 1 else 0 end) asc, account_stats.last_status_at desc, accounts.id desc')) }
+  scope :by_recent_sign_in, -> { order(Arel.sql('(case when users.current_sign_in_at is null then 1 else 0 end) asc, users.current_sign_in_at desc, accounts.id desc')) }
   scope :popular, -> { order('account_stats.followers_count desc') }
   scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches('%.' + domain))) }
   scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) }
@@ -324,6 +326,14 @@ class Account < ApplicationRecord
     save!
   end
 
+  def hides_followers?
+    hide_collections? || user_hides_network?
+  end
+
+  def hides_following?
+    hide_collections? || user_hides_network?
+  end
+
   def object_type
     :person
   end
diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb
index c7bf07787..7b6012e0f 100644
--- a/app/models/account_filter.rb
+++ b/app/models/account_filter.rb
@@ -14,6 +14,7 @@ class AccountFilter
     email
     ip
     staff
+    order
   ).freeze
 
   attr_reader :params
@@ -24,7 +25,7 @@ class AccountFilter
   end
 
   def results
-    scope = Account.recent.includes(:user)
+    scope = Account.includes(:user).reorder(nil)
 
     params.each do |key, value|
       scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
@@ -38,6 +39,7 @@ class AccountFilter
   def set_defaults!
     params['local']  = '1' if params['remote'].blank?
     params['active'] = '1' if params['suspended'].blank? && params['silenced'].blank? && params['pending'].blank?
+    params['order']  = 'recent' if params['order'].blank?
   end
 
   def scope_for(key, value)
@@ -51,9 +53,9 @@ class AccountFilter
     when 'active'
       Account.without_suspended
     when 'pending'
-      accounts_with_users.merge User.pending
+      accounts_with_users.merge(User.pending)
     when 'disabled'
-      accounts_with_users.merge User.disabled
+      accounts_with_users.merge(User.disabled)
     when 'silenced'
       Account.silenced
     when 'suspended'
@@ -63,16 +65,31 @@ class AccountFilter
     when 'display_name'
       Account.matches_display_name(value)
     when 'email'
-      accounts_with_users.merge User.matches_email(value)
+      accounts_with_users.merge(User.matches_email(value))
     when 'ip'
       valid_ip?(value) ? accounts_with_users.merge(User.matches_ip(value)) : Account.none
     when 'staff'
-      accounts_with_users.merge User.staff
+      accounts_with_users.merge(User.staff)
+    when 'order'
+      order_scope(value)
     else
       raise "Unknown filter: #{key}"
     end
   end
 
+  def order_scope(value)
+    case value
+    when 'active'
+      params['remote'] ? Account.joins(:account_stat).by_recent_status : Account.joins(:user).by_recent_sign_in
+    when 'recent'
+      Account.recent
+    when 'alphabetic'
+      Account.alphabetic
+    else
+      raise "Unknown order: #{value}"
+    end
+  end
+
   def accounts_with_users
     Account.joins(:user)
   end
diff --git a/app/models/account_warning_preset.rb b/app/models/account_warning_preset.rb
index ba8ceabb3..c20f683cf 100644
--- a/app/models/account_warning_preset.rb
+++ b/app/models/account_warning_preset.rb
@@ -8,8 +8,11 @@
 #  text       :text             default(""), not null
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
+#  title      :string           default(""), not null
 #
 
 class AccountWarningPreset < ApplicationRecord
   validates :text, presence: true
+
+  scope :alphabetic, -> { order(title: :asc, text: :asc) }
 end
diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb
index e9da003a3..b30a82369 100644
--- a/app/models/admin/account_action.rb
+++ b/app/models/admin/account_action.rb
@@ -62,8 +62,6 @@ class Admin::AccountAction
 
   def process_action!
     case type
-    when 'none'
-      handle_resolve!
     when 'disable'
       handle_disable!
     when 'silence'
@@ -105,16 +103,6 @@ class Admin::AccountAction
     end
   end
 
-  def handle_resolve!
-    if with_report? && report.account_id == -99 && target_account.trust_level == Account::TRUST_LEVELS[:untrusted]
-      # This is an automated report and it is being dismissed, so it's
-      # a false positive, in which case update the account's trust level
-      # to prevent further spam checks
-
-      target_account.update(trust_level: Account::TRUST_LEVELS[:trusted])
-    end
-  end
-
   def handle_disable!
     authorize(target_account.user, :disable?)
     log_action(:disable, target_account.user)
diff --git a/app/models/admin/action_log_filter.rb b/app/models/admin/action_log_filter.rb
new file mode 100644
index 000000000..0ba7e1609
--- /dev/null
+++ b/app/models/admin/action_log_filter.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+class Admin::ActionLogFilter
+  KEYS = %i(
+    action_type
+    account_id
+    target_account_id
+  ).freeze
+
+  ACTION_TYPE_MAP = {
+    assigned_to_self_report: { target_type: 'Report', action: 'assigned_to_self' }.freeze,
+    change_email_user: { target_type: 'User', action: 'change_email' }.freeze,
+    confirm_user: { target_type: 'User', action: 'confirm' }.freeze,
+    create_account_warning: { target_type: 'AccountWarning', action: 'create' }.freeze,
+    create_announcement: { target_type: 'Announcement', action: 'create' }.freeze,
+    create_custom_emoji: { target_type: 'CustomEmoji', action: 'create' }.freeze,
+    create_domain_allow: { target_type: 'DomainAllow', action: 'create' }.freeze,
+    create_domain_block: { target_type: 'DomainBlock', action: 'create' }.freeze,
+    create_email_domain_block: { target_type: 'EmailDomainBlock', action: 'create' }.freeze,
+    demote_user: { target_type: 'User', action: 'demote' }.freeze,
+    destroy_announcement: { target_type: 'Announcement', action: 'destroy' }.freeze,
+    destroy_custom_emoji: { target_type: 'CustomEmoji', action: 'destroy' }.freeze,
+    destroy_domain_allow: { target_type: 'DomainAllow', action: 'destroy' }.freeze,
+    destroy_domain_block: { target_type: 'DomainBlock', action: 'destroy' }.freeze,
+    destroy_email_domain_block: { target_type: 'EmailDomainBlock', action: 'destroy' }.freeze,
+    destroy_status: { target_type: 'Status', action: 'destroy' }.freeze,
+    disable_2fa_user: { target_type: 'User', action: 'disable' }.freeze,
+    disable_custom_emoji: { target_type: 'CustomEmoji', action: 'disable' }.freeze,
+    disable_user: { target_type: 'User', action: 'disable' }.freeze,
+    enable_custom_emoji: { target_type: 'CustomEmoji', action: 'enable' }.freeze,
+    enable_user: { target_type: 'User', action: 'enable' }.freeze,
+    memorialize_account: { target_type: 'Account', action: 'memorialize' }.freeze,
+    promote_user: { target_type: 'User', action: 'promote' }.freeze,
+    remove_avatar_user: { target_type: 'User', action: 'remove_avatar' }.freeze,
+    reopen_report: { target_type: 'Report', action: 'reopen' }.freeze,
+    reset_password_user: { target_type: 'User', action: 'reset_password' }.freeze,
+    resolve_report: { target_type: 'Report', action: 'resolve' }.freeze,
+    silence_account: { target_type: 'Account', action: 'silence' }.freeze,
+    suspend_account: { target_type: 'Account', action: 'suspend' }.freeze,
+    unassigned_report: { target_type: 'Report', action: 'unassigned' }.freeze,
+    unsilence_account: { target_type: 'Account', action: 'unsilence' }.freeze,
+    unsuspend_account: { target_type: 'Account', action: 'unsuspend' }.freeze,
+    update_announcement: { target_type: 'Announcement', action: 'update' }.freeze,
+    update_custom_emoji: { target_type: 'CustomEmoji', action: 'update' }.freeze,
+    update_status: { target_type: 'Status', action: 'update' }.freeze,
+  }.freeze
+
+  attr_reader :params
+
+  def initialize(params)
+    @params = params
+  end
+
+  def results
+    scope = Admin::ActionLog.includes(:target)
+
+    params.each do |key, value|
+      next if key.to_s == 'page'
+
+      scope.merge!(scope_for(key.to_s, value.to_s.strip)) if value.present?
+    end
+
+    scope
+  end
+
+  private
+
+  def scope_for(key, value)
+    case key
+    when 'action_type'
+      Admin::ActionLog.where(ACTION_TYPE_MAP[value.to_sym])
+    when 'account_id'
+      Admin::ActionLog.where(account_id: value)
+    when 'target_account_id'
+      account = Account.find(value)
+      Admin::ActionLog.where(target: [account, account.user].compact)
+    else
+      raise "Unknown filter: #{key}"
+    end
+  end
+end
diff --git a/app/models/announcement.rb b/app/models/announcement.rb
index d99502f44..a4e427b49 100644
--- a/app/models/announcement.rb
+++ b/app/models/announcement.rb
@@ -14,6 +14,7 @@
 #  created_at   :datetime         not null
 #  updated_at   :datetime         not null
 #  published_at :datetime
+#  status_ids   :bigint           is an Array
 #
 
 class Announcement < ApplicationRecord
@@ -48,6 +49,16 @@ class Announcement < ApplicationRecord
     @mentions ||= Account.from_text(text)
   end
 
+  def statuses
+    @statuses ||= begin
+      if status_ids.nil?
+        []
+      else
+        Status.where(id: status_ids, visibility: [:public, :unlisted])
+      end
+    end
+  end
+
   def tags
     @tags ||= Tag.find_or_create_by_names(Extractor.extract_hashtags(text))
   end
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index 14bcf7bb1..32fcb5397 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -87,10 +87,10 @@ module AccountInteractions
     has_many :announcement_mutes, dependent: :destroy
   end
 
-  def follow!(other_account, reblogs: nil, uri: nil)
+  def follow!(other_account, reblogs: nil, uri: nil, rate_limit: false)
     reblogs = true if reblogs.nil?
 
-    rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri)
+    rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri, rate_limit: rate_limit)
                               .find_or_create_by!(target_account: other_account)
 
     rel.update!(show_reblogs: reblogs)
@@ -99,6 +99,18 @@ module AccountInteractions
     rel
   end
 
+  def request_follow!(other_account, reblogs: nil, uri: nil, rate_limit: false)
+    reblogs = true if reblogs.nil?
+
+    rel = follow_requests.create_with(show_reblogs: reblogs, uri: uri, rate_limit: rate_limit)
+                         .find_or_create_by!(target_account: other_account)
+
+    rel.update!(show_reblogs: reblogs)
+    remove_potential_friendship(other_account)
+
+    rel
+  end
+
   def block!(other_account, uri: nil)
     remove_potential_friendship(other_account)
     block_relationships.create_with(uri: uri)
diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb
index 43ff8ac12..18b872c1e 100644
--- a/app/models/concerns/attachmentable.rb
+++ b/app/models/concerns/attachmentable.rb
@@ -74,7 +74,7 @@ module Attachmentable
     self.class.attachment_definitions.each_key do |attachment_name|
       attachment = send(attachment_name)
 
-      next if attachment.blank? || attachment.queued_for_write[:original].blank?
+      next if attachment.blank? || attachment.queued_for_write[:original].blank? || attachment.options[:preserve_files]
 
       attachment.instance_write :file_name, SecureRandom.hex(8) + File.extname(attachment.instance_read(:file_name))
     end
diff --git a/app/models/concerns/rate_limitable.rb b/app/models/concerns/rate_limitable.rb
new file mode 100644
index 000000000..ad1b5e44e
--- /dev/null
+++ b/app/models/concerns/rate_limitable.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module RateLimitable
+  extend ActiveSupport::Concern
+
+  def rate_limit=(value)
+    @rate_limit = value
+  end
+
+  def rate_limit?
+    @rate_limit
+  end
+
+  def rate_limiter(by, options = {})
+    return @rate_limiter if defined?(@rate_limiter)
+
+    @rate_limiter = RateLimiter.new(by, options)
+  end
+
+  class_methods do
+    def rate_limit(options = {})
+      after_create do
+        by = public_send(options[:by])
+
+        if rate_limit? && by&.local?
+          rate_limiter(by, options).record!
+          @rate_limit_recorded = true
+        end
+      end
+
+      after_rollback do
+        rate_limiter(public_send(options[:by]), options).rollback! if @rate_limit_recorded
+      end
+    end
+  end
+end
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index bc70dea25..f50fa46ba 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -7,13 +7,27 @@
 #  domain     :string           default(""), not null
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
+#  parent_id  :bigint(8)
 #
 
 class EmailDomainBlock < ApplicationRecord
   include DomainNormalizable
 
+  belongs_to :parent, class_name: 'EmailDomainBlock', optional: true
+  has_many :children, class_name: 'EmailDomainBlock', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy
+
   validates :domain, presence: true, uniqueness: true, domain: true
 
+  def with_dns_records=(val)
+    @with_dns_records = ActiveModel::Type::Boolean.new.cast(val)
+  end
+
+  def with_dns_records?
+    @with_dns_records
+  end
+
+  alias with_dns_records with_dns_records?
+
   def self.block?(email)
     _, domain = email.split('@', 2)
 
diff --git a/app/models/follow.rb b/app/models/follow.rb
index 87fa11425..f3e48a2ed 100644
--- a/app/models/follow.rb
+++ b/app/models/follow.rb
@@ -15,6 +15,9 @@
 class Follow < ApplicationRecord
   include Paginable
   include RelationshipCacheable
+  include RateLimitable
+
+  rate_limit by: :account, family: :follows
 
   belongs_to :account
   belongs_to :target_account, class_name: 'Account'
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index 96ac7eaa5..3325e264c 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -15,6 +15,9 @@
 class FollowRequest < ApplicationRecord
   include Paginable
   include RelationshipCacheable
+  include RateLimitable
+
+  rate_limit by: :account, family: :follows
 
   belongs_to :account
   belongs_to :target_account, class_name: 'Account'
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 6a0b892f6..40624c73c 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -19,12 +19,14 @@
 #  description         :text
 #  scheduled_status_id :bigint(8)
 #  blurhash            :string
+#  processing          :integer
 #
 
 class MediaAttachment < ApplicationRecord
   self.inheritance_column = nil
 
   enum type: [:image, :gifv, :video, :unknown, :audio]
+  enum processing: [:queued, :in_progress, :complete, :failed], _prefix: true
 
   MAX_DESCRIPTION_LENGTH = 1_500
 
@@ -55,6 +57,43 @@ class MediaAttachment < ApplicationRecord
     },
   }.freeze
 
+  VIDEO_FORMAT = {
+    format: 'mp4',
+    content_type: 'video/mp4',
+    convert_options: {
+      output: {
+        'loglevel' => 'fatal',
+        'movflags' => 'faststart',
+        'pix_fmt' => 'yuv420p',
+        'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
+        'vsync' => 'cfr',
+        'c:v' => 'h264',
+        'maxrate' => '1300K',
+        'bufsize' => '1300K',
+        'frames:v' => 60 * 60 * 3,
+        'crf' => 18,
+        'map_metadata' => '-1',
+      },
+    },
+  }.freeze
+
+  VIDEO_PASSTHROUGH_OPTIONS = {
+    video_codecs: ['h264'],
+    audio_codecs: ['aac', nil],
+    colorspaces: ['yuv420p'],
+    options: {
+      format: 'mp4',
+      convert_options: {
+        output: {
+          'loglevel' => 'fatal',
+          'map_metadata' => '-1',
+          'c:v' => 'copy',
+          'c:a' => 'copy',
+        },
+      },
+    },
+  }.freeze
+
   VIDEO_STYLES = {
     small: {
       convert_options: {
@@ -69,17 +108,7 @@ class MediaAttachment < ApplicationRecord
       blurhash: BLURHASH_OPTIONS,
     },
 
-    original: {
-      keep_same_format: true,
-      convert_options: {
-        output: {
-          'loglevel' => 'fatal',
-          'map_metadata' => '-1',
-          'c:v' => 'copy',
-          'c:a' => 'copy',
-        },
-      },
-    },
+    original: VIDEO_FORMAT.merge(passthrough_options: VIDEO_PASSTHROUGH_OPTIONS),
   }.freeze
 
   AUDIO_STYLES = {
@@ -96,26 +125,6 @@ class MediaAttachment < ApplicationRecord
     },
   }.freeze
 
-  VIDEO_FORMAT = {
-    format: 'mp4',
-    content_type: 'video/mp4',
-    convert_options: {
-      output: {
-        'loglevel' => 'fatal',
-        'movflags' => 'faststart',
-        'pix_fmt' => 'yuv420p',
-        'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
-        'vsync' => 'cfr',
-        'c:v' => 'h264',
-        'maxrate' => '1300K',
-        'bufsize' => '1300K',
-        'frames:v' => 60 * 60 * 3,
-        'crf' => 18,
-        'map_metadata' => '-1',
-      },
-    },
-  }.freeze
-
   VIDEO_CONVERTED_STYLES = {
     small: VIDEO_STYLES[:small],
     original: VIDEO_FORMAT,
@@ -124,6 +133,9 @@ class MediaAttachment < ApplicationRecord
   IMAGE_LIMIT = (ENV['MAX_IMAGE_SIZE'] || 10.megabytes).to_i
   VIDEO_LIMIT = (ENV['MAX_VIDEO_SIZE'] || 40.megabytes).to_i
 
+  MAX_VIDEO_MATRIX_LIMIT = 2_304_000 # 1920x1200px
+  MAX_VIDEO_FRAME_RATE   = 60
+
   belongs_to :account,          inverse_of: :media_attachments, optional: true
   belongs_to :status,           inverse_of: :media_attachments, optional: true
   belongs_to :scheduled_status, inverse_of: :media_attachments, optional: true
@@ -156,6 +168,10 @@ class MediaAttachment < ApplicationRecord
     remote_url.blank?
   end
 
+  def not_processed?
+    processing.present? && !processing_complete?
+  end
+
   def needs_redownload?
     file.blank? && remote_url.present?
   end
@@ -168,18 +184,6 @@ class MediaAttachment < ApplicationRecord
     audio? || video?
   end
 
-  def variant?(other_file_name)
-    return true if file_file_name == other_file_name
-
-    formats = file.styles.values.map(&:format).compact
-
-    return false if formats.empty?
-
-    extension = File.extname(other_file_name)
-
-    formats.include?(extension.delete('.')) && File.basename(other_file_name, extension) == File.basename(file_file_name, File.extname(file_file_name))
-  end
-
   def to_param
     shortcode
   end
@@ -202,12 +206,21 @@ class MediaAttachment < ApplicationRecord
     "#{x},#{y}"
   end
 
+  attr_writer :delay_processing
+
+  def delay_processing?
+    @delay_processing
+  end
+
+  after_commit :enqueue_processing, on: :create
   after_commit :reset_parent_cache, on: :update
 
   before_create :prepare_description, unless: :local?
   before_create :set_shortcode
+  before_create :set_processing
 
   before_post_process :set_type_and_extension
+  before_post_process :check_video_dimensions
 
   before_save :set_meta
 
@@ -276,6 +289,21 @@ class MediaAttachment < ApplicationRecord
     end
   end
 
+  def set_processing
+    self.processing = delay_processing? ? :queued : :complete
+  end
+
+  def check_video_dimensions
+    return unless (video? || gifv?) && file.queued_for_write[:original].present?
+
+    movie = FFMPEG::Movie.new(file.queued_for_write[:original].path)
+
+    return unless movie.valid?
+
+    raise Mastodon::DimensionsValidationError, "#{movie.width}x#{movie.height} videos are not supported" if movie.width * movie.height > MAX_VIDEO_MATRIX_LIMIT
+    raise Mastodon::DimensionsValidationError, "#{movie.frame_rate.to_i}fps videos are not supported" if movie.frame_rate > MAX_VIDEO_FRAME_RATE
+  end
+
   def set_meta
     meta = populate_meta
 
@@ -321,9 +349,11 @@ class MediaAttachment < ApplicationRecord
     }.compact
   end
 
-  def reset_parent_cache
-    return if status_id.nil?
+  def enqueue_processing
+    PostProcessMediaWorker.perform_async(id) if delay_processing?
+  end
 
-    Rails.cache.delete("statuses/#{status_id}")
+  def reset_parent_cache
+    Rails.cache.delete("statuses/#{status_id}") if status_id.present?
   end
 end
diff --git a/app/models/report.rb b/app/models/report.rb
index fb2e040ee..f31bcfd2e 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -18,6 +18,9 @@
 
 class Report < ApplicationRecord
   include Paginable
+  include RateLimitable
+
+  rate_limit by: :account, family: :reports
 
   belongs_to :account
   belongs_to :target_account, class_name: 'Account'
@@ -59,6 +62,14 @@ class Report < ApplicationRecord
   end
 
   def resolve!(acting_account)
+    if account_id == -99 && target_account.trust_level == Account::TRUST_LEVELS[:untrusted]
+      # This is an automated report and it is being dismissed, so it's
+      # a false positive, in which case update the account's trust level
+      # to prevent further spam checks
+
+      target_account.update(trust_level: Account::TRUST_LEVELS[:trusted])
+    end
+
     RemovalWorker.push_bulk(Status.with_discarded.discarded.where(id: status_ids).pluck(:id)) { |status_id| [status_id, { immediate: true }] }
     update!(action_taken: true, action_taken_by_account_id: acting_account.id)
   end
diff --git a/app/models/status.rb b/app/models/status.rb
index f4284f771..31e77770d 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -35,6 +35,9 @@ class Status < ApplicationRecord
   include Paginable
   include Cacheable
   include StatusThreadingConcern
+  include RateLimitable
+
+  rate_limit by: :account, family: :statuses
 
   self.discard_column = :deleted_at
 
@@ -145,10 +148,12 @@ class Status < ApplicationRecord
       ids += mentions.where(account: Account.local).pluck(:account_id)
       ids += favourites.where(account: Account.local).pluck(:account_id)
       ids += reblogs.where(account: Account.local).pluck(:account_id)
+      ids += bookmarks.where(account: Account.local).pluck(:account_id)
     else
       ids += preloaded.mentions[id] || []
       ids += preloaded.favourites[id] || []
       ids += preloaded.reblogs[id] || []
+      ids += preloaded.bookmarks[id] || []
     end
 
     ids.uniq
@@ -416,6 +421,21 @@ class Status < ApplicationRecord
       end
     end
 
+    def from_text(text)
+      return [] if text.blank?
+
+      text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.map do |url|
+        status = begin
+          if TagManager.instance.local_url?(url)
+            ActivityPub::TagManager.instance.uri_to_resource(url, Status)
+          else
+            EntityCache.instance.status(url)
+          end
+        end
+        status&.distributable? ? status : nil
+      end.compact
+    end
+
     private
 
     def timeline_scope(local_only = false)
diff --git a/app/policies/settings_policy.rb b/app/policies/settings_policy.rb
index 2dcb79f51..874f97bab 100644
--- a/app/policies/settings_policy.rb
+++ b/app/policies/settings_policy.rb
@@ -8,4 +8,8 @@ class SettingsPolicy < ApplicationPolicy
   def show?
     admin?
   end
+
+  def destroy?
+    admin?
+  end
 end
diff --git a/app/serializers/rest/announcement_serializer.rb b/app/serializers/rest/announcement_serializer.rb
index f27feb669..9343b97d2 100644
--- a/app/serializers/rest/announcement_serializer.rb
+++ b/app/serializers/rest/announcement_serializer.rb
@@ -7,6 +7,7 @@ class REST::AnnouncementSerializer < ActiveModel::Serializer
   attribute :read, if: :current_user?
 
   has_many :mentions
+  has_many :statuses
   has_many :tags, serializer: REST::StatusSerializer::TagSerializer
   has_many :emojis, serializer: REST::CustomEmojiSerializer
   has_many :reactions, serializer: REST::ReactionSerializer
@@ -46,4 +47,16 @@ class REST::AnnouncementSerializer < ActiveModel::Serializer
       object.pretty_acct
     end
   end
+
+  class StatusSerializer < ActiveModel::Serializer
+    attributes :id, :url
+
+    def id
+      object.id.to_s
+    end
+
+    def url
+      ActivityPub::TagManager.instance.url_for(object)
+    end
+  end
 end
diff --git a/app/serializers/rest/media_attachment_serializer.rb b/app/serializers/rest/media_attachment_serializer.rb
index 1b3498ea4..cc10e3001 100644
--- a/app/serializers/rest/media_attachment_serializer.rb
+++ b/app/serializers/rest/media_attachment_serializer.rb
@@ -12,7 +12,9 @@ class REST::MediaAttachmentSerializer < ActiveModel::Serializer
   end
 
   def url
-    if object.needs_redownload?
+    if object.not_processed?
+      nil
+    elsif object.needs_redownload?
       media_proxy_url(object.id, :original)
     else
       full_asset_url(object.file.url(:original))
diff --git a/app/services/account_search_service.rb b/app/services/account_search_service.rb
index d217dabb3..493813aab 100644
--- a/app/services/account_search_service.rb
+++ b/app/services/account_search_service.rb
@@ -171,7 +171,7 @@ class AccountSearchService < BaseService
   end
 
   def username_complete?
-    query.include?('@') && "@#{query}" =~ Account::MENTION_RE
+    query.include?('@') && "@#{query}" =~ /\A#{Account::MENTION_RE}\Z/
   end
 
   def likely_acct?
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index d5ede0388..7b4c53d50 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -94,6 +94,7 @@ class ActivityPub::ProcessAccountService < BaseService
     @account.statuses_count    = outbox_total_items    if outbox_total_items.present?
     @account.following_count   = following_total_items if following_total_items.present?
     @account.followers_count   = followers_total_items if followers_total_items.present?
+    @account.hide_collections  = following_private? || followers_private?
     @account.moved_to_account  = @json['movedTo'].present? ? moved_account : nil
   end
 
@@ -166,26 +167,36 @@ class ActivityPub::ProcessAccountService < BaseService
   end
 
   def outbox_total_items
-    collection_total_items('outbox')
+    collection_info('outbox').first
   end
 
   def following_total_items
-    collection_total_items('following')
+    collection_info('following').first
   end
 
   def followers_total_items
-    collection_total_items('followers')
+    collection_info('followers').first
   end
 
-  def collection_total_items(type)
-    return if @json[type].blank?
+  def following_private?
+    !collection_info('following').last
+  end
+
+  def followers_private?
+    !collection_info('followers').last
+  end
+
+  def collection_info(type)
+    return [nil, nil] if @json[type].blank?
     return @collections[type] if @collections.key?(type)
 
     collection = fetch_resource_without_id_validation(@json[type])
 
-    @collections[type] = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
+    total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
+    has_first_page = collection.is_a?(Hash) && collection['first'].present?
+    @collections[type] = [total_items, has_first_page]
   rescue HTTP::Error, OpenSSL::SSL::SSLError
-    @collections[type] = nil
+    @collections[type] = [nil, nil]
   end
 
   def moved_account
diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb
index abe7766d4..880cdde92 100644
--- a/app/services/fetch_resource_service.rb
+++ b/app/services/fetch_resource_service.rb
@@ -5,6 +5,8 @@ class FetchResourceService < BaseService
 
   ACCEPT_HEADER = 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams", text/html;q=0.1'
 
+  attr_reader :response_code
+
   def call(url)
     return if url.blank?
 
@@ -27,6 +29,7 @@ class FetchResourceService < BaseService
   end
 
   def process_response(response, terminal = false)
+    @response_code = response.code
     return nil if response.code != 200
 
     if ['application/activity+json', 'application/ld+json'].include?(response.mime_type)
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index 4d19002c4..311ae7fa6 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -7,54 +7,68 @@ class FollowService < BaseService
   # Follow a remote user, notify remote user about the follow
   # @param [Account] source_account From which to follow
   # @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
-  # @param [true, false, nil] reblogs Whether or not to show reblogs, defaults to true
-  def call(source_account, target_account, reblogs: nil, bypass_locked: false)
-    reblogs = true if reblogs.nil?
-    target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true)
-
-    raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended?
-    raise Mastodon::NotPermittedError  if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved? || (!target_account.local? && target_account.ostatus?) || source_account.domain_blocking?(target_account.domain)
-
-    if source_account.following?(target_account)
-      # We're already following this account, but we'll call follow! again to
-      # make sure the reblogs status is set correctly.
-      return source_account.follow!(target_account, reblogs: reblogs)
-    elsif source_account.requested?(target_account)
-      # This isn't managed by a method in AccountInteractions, so we modify it
-      # ourselves if necessary.
-      req = source_account.follow_requests.find_by(target_account: target_account)
-      req.update!(show_reblogs: reblogs)
-      return req
+  # @param [Hash] options
+  # @option [Boolean] :reblogs Whether or not to show reblogs, defaults to true
+  # @option [Boolean] :bypass_locked
+  # @option [Boolean] :with_rate_limit
+  def call(source_account, target_account, options = {})
+    @source_account = source_account
+    @target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true)
+    @options        = { reblogs: true, bypass_locked: false, with_rate_limit: false }.merge(options)
+
+    raise ActiveRecord::RecordNotFound if following_not_possible?
+    raise Mastodon::NotPermittedError  if following_not_allowed?
+
+    if @source_account.following?(@target_account)
+      return change_follow_options!
+    elsif @source_account.requested?(@target_account)
+      return change_follow_request_options!
     end
 
     ActivityTracker.increment('activity:interactions')
 
-    if (target_account.locked? && !bypass_locked) || source_account.silenced? || target_account.activitypub?
-      request_follow(source_account, target_account, reblogs: reblogs)
-    elsif target_account.local?
-      direct_follow(source_account, target_account, reblogs: reblogs)
+    if (@target_account.locked? && !@options[:bypass_locked]) || @source_account.silenced? || @target_account.activitypub?
+      request_follow!
+    elsif @target_account.local?
+      direct_follow!
     end
   end
 
   private
 
-  def request_follow(source_account, target_account, reblogs: true)
-    follow_request = FollowRequest.create!(account: source_account, target_account: target_account, show_reblogs: reblogs)
+  def following_not_possible?
+    @target_account.nil? || @target_account.id == @source_account.id || @target_account.suspended?
+  end
+
+  def following_not_allowed?
+    @target_account.blocking?(@source_account) || @source_account.blocking?(@target_account) || @target_account.moved? || (!@target_account.local? && @target_account.ostatus?) || @source_account.domain_blocking?(@target_account.domain)
+  end
+
+  def change_follow_options!
+    @source_account.follow!(@target_account, reblogs: @options[:reblogs])
+  end
+
+  def change_follow_request_options!
+    @source_account.request_follow!(@target_account, reblogs: @options[:reblogs])
+  end
+
+  def request_follow!
+    follow_request = @source_account.request_follow!(@target_account, reblogs: @options[:reblogs], rate_limit: @options[:with_rate_limit])
 
-    if target_account.local?
-      LocalNotificationWorker.perform_async(target_account.id, follow_request.id, follow_request.class.name)
-    elsif target_account.activitypub?
-      ActivityPub::DeliveryWorker.perform_async(build_json(follow_request), source_account.id, target_account.inbox_url)
+    if @target_account.local?
+      LocalNotificationWorker.perform_async(@target_account.id, follow_request.id, follow_request.class.name)
+    elsif @target_account.activitypub?
+      ActivityPub::DeliveryWorker.perform_async(build_json(follow_request), @source_account.id, @target_account.inbox_url)
     end
 
     follow_request
   end
 
-  def direct_follow(source_account, target_account, reblogs: true)
-    follow = source_account.follow!(target_account, reblogs: reblogs)
+  def direct_follow!
+    follow = @source_account.follow!(@target_account, reblogs: @options[:reblogs], rate_limit: @options[:with_rate_limit])
 
-    LocalNotificationWorker.perform_async(target_account.id, follow.id, follow.class.name)
-    MergeWorker.perform_async(target_account.id, source_account.id)
+    LocalNotificationWorker.perform_async(@target_account.id, follow.id, follow.class.name)
+    MergeWorker.perform_async(@target_account.id, @source_account.id)
 
     follow
   end
diff --git a/app/services/import_service.rb b/app/services/import_service.rb
index 4ee431ea3..c0d741d57 100644
--- a/app/services/import_service.rb
+++ b/app/services/import_service.rb
@@ -64,7 +64,8 @@ class ImportService < BaseService
   end
 
   def import_relationships!(action, undo_action, overwrite_scope, limit, extra_fields = {})
-    items = @data.take(limit).map { |row| [row['Account address']&.strip, Hash[extra_fields.map { |key, header| [key, row[header]&.strip] }]] }.reject { |(id, _)| id.blank? }
+    local_domain_suffix = "@#{Rails.configuration.x.local_domain}"
+    items = @data.take(limit).map { |row| [row['Account address']&.strip&.delete_suffix(local_domain_suffix), Hash[extra_fields.map { |key, header| [key, row[header]&.strip] }]] }.reject { |(id, _)| id.blank? }
 
     if @import.overwrite?
       presence_hash = items.each_with_object({}) { |(id, extra), mapping| mapping[id] = [true, extra] }
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 936e6ac55..250d0e8ed 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -19,6 +19,7 @@ class PostStatusService < BaseService
   # @option [Enumerable] :media_ids Optional array of media IDs to attach
   # @option [Doorkeeper::Application] :application
   # @option [String] :idempotency Optional idempotency key
+  # @option [Boolean] :with_rate_limit
   # @return [Status]
   def call(account, options = {})
     @account     = account
@@ -49,16 +50,17 @@ class PostStatusService < BaseService
   def preprocess_attributes!
     if @text.blank? && @options[:spoiler_text].present?
      @text = '.'
-     if @media.find(&:video?) || @media.find(&:gifv?)
+     if @media&.find(&:video?) || @media&.find(&:gifv?)
        @text = '📹'
-     elsif @media.find(&:audio?)
+     elsif @media&.find(&:audio?)
        @text = '🎵'
-     elsif @media.find(&:image?)
+     elsif @media&.find(&:image?)
        @text = '🖼'
      end
     end
+    @sensitive    = (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?
     @visibility   = @options[:visibility] || @account.user&.setting_default_privacy
-    @visibility   = :unlisted if @visibility == :public && @account.silenced?
+    @visibility   = :unlisted if @visibility&.to_sym == :public && @account.silenced?
     @scheduled_at = @options[:scheduled_at]&.to_datetime
     @scheduled_at = nil if scheduled_in_the_past?
   rescue ArgumentError
@@ -109,6 +111,7 @@ class PostStatusService < BaseService
     @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
 
     raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?)
+    raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?)
   end
 
   def language_from_option(str)
@@ -164,12 +167,13 @@ class PostStatusService < BaseService
       media_attachments: @media || [],
       thread: @in_reply_to,
       poll_attributes: poll_attributes,
-      sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?,
+      sensitive: @sensitive,
       spoiler_text: @options[:spoiler_text] || '',
       visibility: @visibility,
       language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account),
       application: @options[:application],
       content_type: @options[:content_type] || @account.user&.setting_default_content_type,
+      rate_limit: @options[:with_rate_limit],
     }.compact
   end
 
@@ -189,10 +193,11 @@ class PostStatusService < BaseService
 
   def scheduled_options
     @options.tap do |options_hash|
-      options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id
-      options_hash[:application_id] = options_hash.delete(:application)&.id
-      options_hash[:scheduled_at]   = nil
-      options_hash[:idempotency]    = nil
+      options_hash[:in_reply_to_id]  = options_hash.delete(:thread)&.id
+      options_hash[:application_id]  = options_hash.delete(:application)&.id
+      options_hash[:scheduled_at]    = nil
+      options_hash[:idempotency]     = nil
+      options_hash[:with_rate_limit] = false
     end
   end
 end
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 0b12f143c..0a46509f8 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -8,6 +8,8 @@ class ReblogService < BaseService
   # @param [Account] account Account to reblog from
   # @param [Status] reblogged_status Status to be reblogged
   # @param [Hash] options
+  # @option [String]  :visibility
+  # @option [Boolean] :with_rate_limit
   # @return [Status]
   def call(account, reblogged_status, options = {})
     reblogged_status = reblogged_status.reblog if reblogged_status.reblog?
@@ -18,9 +20,15 @@ class ReblogService < BaseService
 
     return reblog unless reblog.nil?
 
-    visibility = options[:visibility] || account.user&.setting_default_privacy
-    visibility = reblogged_status.visibility if reblogged_status.hidden?
-    reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: visibility)
+    visibility = begin
+      if reblogged_status.hidden?
+        reblogged_status.visibility
+      else
+        options[:visibility] || account.user&.setting_default_privacy
+      end
+    end
+
+    reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: visibility, rate_limit: options[:with_rate_limit])
 
     DistributionWorker.perform_async(reblog.id)
     ActivityPub::DistributionWorker.perform_async(reblog.id) unless reblogged_status.local_only?
@@ -45,7 +53,9 @@ class ReblogService < BaseService
 
   def bump_potential_friendship(account, reblog)
     ActivityTracker.increment('activity:interactions')
+
     return if account.following?(reblog.reblog.account_id)
+
     PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
   end
 
diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb
index 1a2b0d60c..78080d878 100644
--- a/app/services/resolve_url_service.rb
+++ b/app/services/resolve_url_service.rb
@@ -12,7 +12,7 @@ class ResolveURLService < BaseService
       process_local_url
     elsif !fetched_resource.nil?
       process_url
-    elsif @on_behalf_of.present?
+    else
       process_url_from_db
     end
   end
@@ -30,6 +30,8 @@ class ResolveURLService < BaseService
   end
 
   def process_url_from_db
+    return unless @on_behalf_of.present? && [401, 403, 404].include?(fetch_resource_service.response_code)
+
     # It may happen that the resource is a private toot, and thus not fetchable,
     # but we can return the toot if we already know about it.
     status = Status.find_by(uri: @url) || Status.find_by(url: @url)
@@ -40,7 +42,11 @@ class ResolveURLService < BaseService
   end
 
   def fetched_resource
-    @fetched_resource ||= FetchResourceService.new.call(@url)
+    @fetched_resource ||= fetch_resource_service.call(@url)
+  end
+
+  def fetch_resource_service
+    @_fetch_resource_service ||= FetchResourceService.new
   end
 
   def resource_url
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 090fd409b..830de4de3 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -10,10 +10,10 @@ class SearchService < BaseService
     @resolve = options[:resolve] || false
 
     default_results.tap do |results|
-      next if @query.blank?
+      next if @query.blank? || @limit.zero?
 
       if url_query?
-        results.merge!(url_resource_results) unless url_resource.nil? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym)
+        results.merge!(url_resource_results) unless url_resource.nil? || @offset.positive? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym)
       elsif @query.present?
         results[:accounts] = perform_accounts_search! if account_searchable?
         results[:statuses] = perform_statuses_search! if full_text_searchable?
diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml
index 20fbeef33..aa88b1448 100644
--- a/app/views/admin/account_actions/new.html.haml
+++ b/app/views/admin/account_actions/new.html.haml
@@ -21,7 +21,7 @@
 
     - unless @warning_presets.empty?
       .fields-group
-        = f.input :warning_preset_id, collection: @warning_presets, label_method: :text, wrapper: :with_block_label
+        = f.input :warning_preset_id, collection: @warning_presets, label_method: ->(warning_preset) { [warning_preset.title.presence, truncate(warning_preset.text)].compact.join(' - ') }, wrapper: :with_block_label
 
     .fields-group
       = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path)
diff --git a/app/views/admin/accounts/_account.html.haml b/app/views/admin/accounts/_account.html.haml
index b057d3e42..44b10af6e 100644
--- a/app/views/admin/accounts/_account.html.haml
+++ b/app/views/admin/accounts/_account.html.haml
@@ -11,6 +11,8 @@
   %td
     - if account.user_current_sign_in_at
       %time.time-ago{ datetime: account.user_current_sign_in_at.iso8601, title: l(account.user_current_sign_in_at) }= l account.user_current_sign_in_at
+    - elsif account.last_status_at.present?
+      %time.time-ago{ datetime: account.last_status_at.iso8601, title: l(account.last_status_at) }= l account.last_status_at
     - else
       \-
   %td
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 3a85324c9..7592161c9 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -19,6 +19,12 @@
     %ul
       %li= filter_link_to t('admin.accounts.moderation.all'), staff: nil
       %li= filter_link_to t('admin.accounts.roles.staff'), staff: '1'
+  .filter-subset
+    %strong= t 'generic.order_by'
+    %ul
+      %li= filter_link_to t('relationships.most_recent'), order: nil
+      %li= filter_link_to t('admin.accounts.username'), order: 'alphabetic'
+      %li= filter_link_to t('relationships.last_active'), order: 'active'
 
 = form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do
   .fields-group
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index a30b78db2..965fd6fb6 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -53,7 +53,7 @@
       .dashboard__counters__num= number_with_delimiter @account.targeted_reports.count
       .dashboard__counters__label= t '.targeted_reports'
   %div
-    %div
+    = link_to admin_action_logs_path(target_account_id: @account.id) do
       .dashboard__counters__text
         - if @account.local? && @account.user.nil?
           %span.neutral= t('admin.accounts.deleted')
@@ -96,10 +96,17 @@
               = table_link_to 'angle-double-down', t('admin.accounts.demote'), demote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:demote, @account.user)
 
           %tr
-            %th= t('admin.accounts.email')
-            %td= @account.user_email
+            %th{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= t('admin.accounts.email')
+            %td{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= @account.user_email
             %td= table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user)
 
+          %tr
+            %td= table_link_to 'search', t('admin.accounts.search_same_email_domain'), admin_accounts_path(email: "%@#{@account.user_email.split('@').last}")
+
+          - if can?(:create, :email_domain_block)
+            %tr
+              %td= table_link_to 'ban', t('admin.accounts.add_email_domain_block'), new_admin_email_domain_block_path(_domain: @account.user_email.split('@').last)
+
           - if @account.user_unconfirmed_email.present?
             %tr
               %th= t('admin.accounts.unconfirmed_email')
@@ -204,7 +211,7 @@
         = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button button--destructive' if can?(:suspend, @account)
 
       - unless @account.local?
-        - if DomainBlock.where(domain: @account.domain).exists?
+        - if DomainBlock.rule_for(@account.domain)
           = link_to t('admin.domain_blocks.view'), admin_instance_path(@account.domain), class: 'button'
         - else
           = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @account.domain), class: 'button button--destructive'
diff --git a/app/views/admin/action_logs/_action_log.html.haml b/app/views/admin/action_logs/_action_log.html.haml
index a545e189e..59905f341 100644
--- a/app/views/admin/action_logs/_action_log.html.haml
+++ b/app/views/admin/action_logs/_action_log.html.haml
@@ -7,9 +7,3 @@
         = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')).html_safe
       .log-entry__timestamp
         %time.formatted{ datetime: action_log.created_at.iso8601 }
-    .spacer
-    .log-entry__icon
-      = fa_icon icon_for_log(action_log)
-      .log-entry__icon__overlay{ class: class_for_log_icon(action_log) }
-  .log-entry__extras
-    = log_extra_attributes relevant_log_changes(action_log)
diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml
index a4d3871a9..937664c4b 100644
--- a/app/views/admin/action_logs/index.html.haml
+++ b/app/views/admin/action_logs/index.html.haml
@@ -1,6 +1,25 @@
 - content_for :page_title do
   = t('admin.action_logs.title')
 
-= render @action_logs
+= form_tag admin_action_logs_url, method: 'GET', class: 'simple_form' do
+  = hidden_field_tag :target_account_id, params[:target_account_id] if params[:target_account_id].present?
+
+  .filters
+    .filter-subset.filter-subset--with-select
+      %strong= t('admin.action_logs.filter_by_user')
+      .input.select.optional
+        = select_tag :account_id, options_from_collection_for_select(Account.joins(:user).merge(User.staff), :id, :username, params[:account_id]), prompt: I18n.t('admin.accounts.moderation.all')
+
+    .filter-subset.filter-subset--with-select
+      %strong= t('admin.action_logs.filter_by_action')
+      .input.select.optional
+        = select_tag :action_type, options_for_select(Admin::ActionLogFilter::ACTION_TYPE_MAP.keys.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key]}, params[:action_type]), prompt: I18n.t('admin.accounts.moderation.all')
+
+- if @action_logs.empty?
+  %div.muted-hint.center-text
+    = t 'admin.action_logs.empty'
+- else
+  .announcements-list
+    = render @action_logs
 
 = paginate @action_logs
diff --git a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
index bf66c9001..41ab8c171 100644
--- a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
+++ b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml
@@ -3,3 +3,13 @@
     %samp= email_domain_block.domain
   %td
     = table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(email_domain_block), method: :delete
+
+- email_domain_block.children.each do |child_email_domain_block|
+  %tr
+    %td
+      %samp= child_email_domain_block.domain
+      %span.muted-hint
+        = surround '(', ')' do
+          = t('admin.email_domain_blocks.from_html', domain: content_tag(:samp, email_domain_block.domain))
+    %td
+      = table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(child_email_domain_block), method: :delete
diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml
index f372fa512..4a346f240 100644
--- a/app/views/admin/email_domain_blocks/new.html.haml
+++ b/app/views/admin/email_domain_blocks/new.html.haml
@@ -5,7 +5,10 @@
   = render 'shared/error_messages', object: @email_domain_block
 
   .fields-group
-    = f.input :domain, wrapper: :with_label, label: t('admin.email_domain_blocks.domain')
+    = f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain')
+
+  .fields-group
+    = f.input :with_dns_records, as: :boolean, wrapper: :with_label
 
   .actions
     = f.button :button, t('.create'), type: :submit
diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml
index 63b352361..bff706389 100644
--- a/app/views/admin/settings/edit.html.haml
+++ b/app/views/admin/settings/edit.html.haml
@@ -1,7 +1,10 @@
 - content_for :page_title do
   = t('admin.settings.title')
 
-= simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch } do |f|
+  - content_for :heading_actions do
+    = button_tag t('generic.save_changes'), class: 'button', form: 'edit_admin'
+
+= simple_form_for @admin_settings, url: admin_settings_path, html: { method: :patch, id: 'edit_admin' } do |f|
   = render 'shared/error_messages', object: @admin_settings
 
   .fields-group
@@ -27,13 +30,13 @@
 
   .fields-row
     .fields-row__column.fields-row__column-6.fields-group
-      = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html')
+      = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: site_upload_delete_hint(t('admin.settings.thumbnail.desc_html'), :thumbnail)
     .fields-row__column.fields-row__column-6.fields-group
-      = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html')
+      = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: site_upload_delete_hint(t('admin.settings.hero.desc_html'), :hero)
 
   .fields-row
     .fields-row__column.fields-row__column-6.fields-group
-      = f.input :mascot, as: :file, wrapper: :with_block_label, label: t('admin.settings.mascot.title'), hint: t('admin.settings.mascot.desc_html')
+      = f.input :mascot, as: :file, wrapper: :with_block_label, label: t('admin.settings.mascot.title'), hint: site_upload_delete_hint(t('admin.settings.mascot.desc_html'), :mascot)
 
   %hr.spacer/
 
diff --git a/app/views/admin/warning_presets/_warning_preset.html.haml b/app/views/admin/warning_presets/_warning_preset.html.haml
new file mode 100644
index 000000000..a58199c80
--- /dev/null
+++ b/app/views/admin/warning_presets/_warning_preset.html.haml
@@ -0,0 +1,10 @@
+.announcements-list__item
+  = link_to edit_admin_warning_preset_path(warning_preset), class: 'announcements-list__item__title' do
+    = warning_preset.title.presence || truncate(warning_preset.text)
+
+  .announcements-list__item__action-bar
+    .announcements-list__item__meta
+      = truncate(warning_preset.text)
+
+    %div
+      = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(warning_preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, warning_preset)
diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml
index 9522746cd..b5c5107ef 100644
--- a/app/views/admin/warning_presets/edit.html.haml
+++ b/app/views/admin/warning_presets/edit.html.haml
@@ -5,6 +5,9 @@
   = render 'shared/error_messages', object: @warning_preset
 
   .fields-group
+    = f.input :title, wrapper: :with_block_label
+
+  .fields-group
     = f.input :text, wrapper: :with_block_label
 
   .actions
diff --git a/app/views/admin/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml
index 45913ef73..dbc23fa30 100644
--- a/app/views/admin/warning_presets/index.html.haml
+++ b/app/views/admin/warning_presets/index.html.haml
@@ -6,6 +6,9 @@
     = render 'shared/error_messages', object: @warning_preset
 
     .fields-group
+      = f.input :title, wrapper: :with_block_label
+
+    .fields-group
       = f.input :text, wrapper: :with_block_label
 
     .actions
@@ -13,18 +16,9 @@
 
   %hr.spacer/
 
-- unless @warning_presets.empty?
-  .table-wrapper
-    %table.table
-      %thead
-        %tr
-          %th= t('simple_form.labels.account_warning_preset.text')
-          %th
-      %tbody
-        - @warning_presets.each do |preset|
-          %tr
-            %td
-              = Formatter.instance.linkify(preset.text)
-            %td
-              = table_link_to 'pencil', t('admin.warning_presets.edit'), edit_admin_warning_preset_path(preset)
-              = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
+- if @warning_presets.empty?
+  %div.muted-hint.center-text
+    = t 'admin.warning_presets.empty'
+- else
+  .announcements-list
+    = render partial: 'warning_preset', collection: @warning_presets
diff --git a/app/views/errors/429.html.haml b/app/views/errors/429.html.haml
new file mode 100644
index 000000000..2df4f4175
--- /dev/null
+++ b/app/views/errors/429.html.haml
@@ -0,0 +1,5 @@
+- content_for :page_title do
+  = t('errors.429')
+
+- content_for :content do
+  = t('errors.429')
diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml
index f460cebba..5453177fd 100644
--- a/app/views/settings/preferences/appearance/show.html.haml
+++ b/app/views/settings/preferences/appearance/show.html.haml
@@ -1,7 +1,10 @@
 - content_for :page_title do
   = t('settings.appearance')
 
-= simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put } do |f|
+- content_for :heading_actions do
+  = button_tag t('generic.save_changes'), class: 'button', form: 'edit_user'
+
+= simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put, id: 'edit_user' } do |f|
   .fields-group
     = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale, hint: false
 
diff --git a/app/views/settings/preferences/notifications/show.html.haml b/app/views/settings/preferences/notifications/show.html.haml
index a496be21b..d7cc1ed5d 100644
--- a/app/views/settings/preferences/notifications/show.html.haml
+++ b/app/views/settings/preferences/notifications/show.html.haml
@@ -1,7 +1,10 @@
 - content_for :page_title do
   = t('settings.notifications')
 
-= simple_form_for current_user, url: settings_preferences_notifications_path, html: { method: :put } do |f|
+- content_for :heading_actions do
+  = button_tag t('generic.save_changes'), class: 'button', form: 'edit_notification'
+
+= simple_form_for current_user, url: settings_preferences_notifications_path, html: { method: :put, id: 'edit_notification' } do |f|
   = render 'shared/error_messages', object: current_user
 
   %h4= t 'notifications.email_events'
@@ -32,6 +35,3 @@
       = ff.input :must_be_follower, as: :boolean, wrapper: :with_label
       = ff.input :must_be_following, as: :boolean, wrapper: :with_label
       = ff.input :must_be_following_dm, as: :boolean, wrapper: :with_label
-
-  .actions
-    = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml
index 9bdcb368d..3b5c7016d 100644
--- a/app/views/settings/preferences/other/show.html.haml
+++ b/app/views/settings/preferences/other/show.html.haml
@@ -1,7 +1,10 @@
 - content_for :page_title do
   = t('settings.preferences')
 
-= simple_form_for current_user, url: settings_preferences_other_path, html: { method: :put } do |f|
+- content_for :heading_actions do
+  = button_tag t('generic.save_changes'), class: 'button', form: 'edit_preferences'
+
+= simple_form_for current_user, url: settings_preferences_other_path, html: { method: :put, id: 'edit_preferences' } do |f|
   = render 'shared/error_messages', object: current_user
 
   .fields-group
diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml
index f5d928233..7413be1db 100644
--- a/app/views/settings/profiles/show.html.haml
+++ b/app/views/settings/profiles/show.html.haml
@@ -1,7 +1,10 @@
 - content_for :page_title do
   = t('settings.edit_profile')
 
-= simple_form_for @account, url: settings_profile_path, html: { method: :put } do |f|
+- content_for :heading_actions do
+  = button_tag t('generic.save_changes'), class: 'button', form: 'edit_profile'
+
+= simple_form_for @account, url: settings_profile_path, html: { method: :put, id: 'edit_profile' } do |f|
   = render 'shared/error_messages', object: @account
 
   .fields-row
diff --git a/app/views/statuses/_poll.html.haml b/app/views/statuses/_poll.html.haml
index d1aba6ef9..c17476657 100644
--- a/app/views/statuses/_poll.html.haml
+++ b/app/views/statuses/_poll.html.haml
@@ -8,16 +8,16 @@
       %li
         - if show_results
           - percent = total_votes_count > 0 ? 100 * option.votes_count / total_votes_count : 0
-          %span.poll__chart{ style: "width: #{percent}%" }
-
-          %label.poll__text><
+          %label.poll__option><
             %span.poll__number><
               - if own_votes.include?(index)
-                %i.poll__vote__mark.fa.fa-check
+                %i.poll__voted__mark.fa.fa-check
               = percent.round
             = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
+
+            %span.poll__chart{ style: "width: #{percent}%" }
         - else
-          %label.poll__text><
+          %label.poll__option><
             %span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}><
             = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
   .poll__footer
diff --git a/app/workers/activitypub/distribute_poll_update_worker.rb b/app/workers/activitypub/distribute_poll_update_worker.rb
index 37a13db2b..601075ea6 100644
--- a/app/workers/activitypub/distribute_poll_update_worker.rb
+++ b/app/workers/activitypub/distribute_poll_update_worker.rb
@@ -4,7 +4,7 @@ class ActivityPub::DistributePollUpdateWorker
   include Sidekiq::Worker
   include Payloadable
 
-  sidekiq_options queue: 'push', unique: :until_executed, retry: 0
+  sidekiq_options queue: 'push', lock: :until_executed, retry: 0
 
   def perform(status_id)
     @status  = Status.find(status_id)
diff --git a/app/workers/activitypub/synchronize_featured_collection_worker.rb b/app/workers/activitypub/synchronize_featured_collection_worker.rb
index 7b16d3426..7a0898e89 100644
--- a/app/workers/activitypub/synchronize_featured_collection_worker.rb
+++ b/app/workers/activitypub/synchronize_featured_collection_worker.rb
@@ -3,7 +3,7 @@
 class ActivityPub::SynchronizeFeaturedCollectionWorker
   include Sidekiq::Worker
 
-  sidekiq_options queue: 'pull', unique: :until_executed
+  sidekiq_options queue: 'pull', lock: :until_executed
 
   def perform(account_id)
     ActivityPub::FetchFeaturedCollectionService.new.call(Account.find(account_id))
diff --git a/app/workers/after_remote_follow_request_worker.rb b/app/workers/after_remote_follow_request_worker.rb
deleted file mode 100644
index ce9c65834..000000000
--- a/app/workers/after_remote_follow_request_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AfterRemoteFollowRequestWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'pull', retry: 5
-
-  def perform(follow_request_id); end
-end
diff --git a/app/workers/after_remote_follow_worker.rb b/app/workers/after_remote_follow_worker.rb
deleted file mode 100644
index d9719f2bf..000000000
--- a/app/workers/after_remote_follow_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class AfterRemoteFollowWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'pull', retry: 5
-
-  def perform(follow_id); end
-end
diff --git a/app/workers/backup_worker.rb b/app/workers/backup_worker.rb
index e4c609d70..7b0b52844 100644
--- a/app/workers/backup_worker.rb
+++ b/app/workers/backup_worker.rb
@@ -9,8 +9,12 @@ class BackupWorker
     backup_id = msg['args'].first
 
     ActiveRecord::Base.connection_pool.with_connection do
-      backup = Backup.find(backup_id)
-      backup&.destroy
+      begin
+        backup = Backup.find(backup_id)
+        backup.destroy
+      rescue ActiveRecord::RecordNotFound
+        true
+      end
     end
   end
 
diff --git a/app/workers/notification_worker.rb b/app/workers/notification_worker.rb
deleted file mode 100644
index 1c0f001cf..000000000
--- a/app/workers/notification_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class NotificationWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push', retry: 5
-
-  def perform(xml, source_account_id, target_account_id); end
-end
diff --git a/app/workers/poll_expiration_notify_worker.rb b/app/workers/poll_expiration_notify_worker.rb
index e08f0c249..64b4cbd7e 100644
--- a/app/workers/poll_expiration_notify_worker.rb
+++ b/app/workers/poll_expiration_notify_worker.rb
@@ -3,7 +3,7 @@
 class PollExpirationNotifyWorker
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options lock: :until_executed
 
   def perform(poll_id)
     poll = Poll.find(poll_id)
diff --git a/app/workers/post_process_media_worker.rb b/app/workers/post_process_media_worker.rb
new file mode 100644
index 000000000..d3ebda194
--- /dev/null
+++ b/app/workers/post_process_media_worker.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class PostProcessMediaWorker
+  include Sidekiq::Worker
+
+  sidekiq_options retry: 1, dead: false
+
+  sidekiq_retries_exhausted do |msg|
+    media_attachment_id = msg['args'].first
+
+    ActiveRecord::Base.connection_pool.with_connection do
+      begin
+        media_attachment = MediaAttachment.find(media_attachment_id)
+        media_attachment.processing = :failed
+        media_attachment.save
+      rescue ActiveRecord::RecordNotFound
+        true
+      end
+    end
+
+    Sidekiq.logger.error("Processing media attachment #{media_attachment_id} failed with #{msg['error_message']}")
+  end
+
+  def perform(media_attachment_id)
+    media_attachment = MediaAttachment.find(media_attachment_id)
+    media_attachment.processing = :in_progress
+    media_attachment.save
+    media_attachment.file.reprocess_original!
+    media_attachment.processing = :complete
+    media_attachment.save
+  rescue ActiveRecord::RecordNotFound
+    true
+  end
+end
diff --git a/app/workers/processing_worker.rb b/app/workers/processing_worker.rb
deleted file mode 100644
index cf3bd8397..000000000
--- a/app/workers/processing_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class ProcessingWorker
-  include Sidekiq::Worker
-
-  sidekiq_options backtrace: true
-
-  def perform(account_id, body); end
-end
diff --git a/app/workers/publish_scheduled_announcement_worker.rb b/app/workers/publish_scheduled_announcement_worker.rb
index efca39d3d..1392efed0 100644
--- a/app/workers/publish_scheduled_announcement_worker.rb
+++ b/app/workers/publish_scheduled_announcement_worker.rb
@@ -5,15 +5,24 @@ class PublishScheduledAnnouncementWorker
   include Redisable
 
   def perform(announcement_id)
-    announcement = Announcement.find(announcement_id)
+    @announcement = Announcement.find(announcement_id)
 
-    announcement.publish! unless announcement.published?
+    refresh_status_ids!
 
-    payload = InlineRenderer.render(announcement, nil, :announcement)
+    @announcement.publish! unless @announcement.published?
+
+    payload = InlineRenderer.render(@announcement, nil, :announcement)
     payload = Oj.dump(event: :announcement, payload: payload)
 
     FeedManager.instance.with_active_accounts do |account|
       redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}")
     end
   end
+
+  private
+
+  def refresh_status_ids!
+    @announcement.status_ids = Status.from_text(@announcement.text).map(&:id)
+    @announcement.save
+  end
 end
diff --git a/app/workers/publish_scheduled_status_worker.rb b/app/workers/publish_scheduled_status_worker.rb
index 850610c4e..ce42f7be7 100644
--- a/app/workers/publish_scheduled_status_worker.rb
+++ b/app/workers/publish_scheduled_status_worker.rb
@@ -3,7 +3,7 @@
 class PublishScheduledStatusWorker
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options lock: :until_executed
 
   def perform(scheduled_status_id)
     scheduled_status = ScheduledStatus.find(scheduled_status_id)
diff --git a/app/workers/pubsubhubbub/confirmation_worker.rb b/app/workers/pubsubhubbub/confirmation_worker.rb
deleted file mode 100644
index 783a8c95f..000000000
--- a/app/workers/pubsubhubbub/confirmation_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Pubsubhubbub::ConfirmationWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push', retry: false
-
-  def perform(subscription_id, mode, secret = nil, lease_seconds = nil); end
-end
diff --git a/app/workers/pubsubhubbub/delivery_worker.rb b/app/workers/pubsubhubbub/delivery_worker.rb
deleted file mode 100644
index 1260060bd..000000000
--- a/app/workers/pubsubhubbub/delivery_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Pubsubhubbub::DeliveryWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push', retry: 3, dead: false
-
-  def perform(subscription_id, payload); end
-end
diff --git a/app/workers/pubsubhubbub/distribution_worker.rb b/app/workers/pubsubhubbub/distribution_worker.rb
deleted file mode 100644
index 75bac5d6f..000000000
--- a/app/workers/pubsubhubbub/distribution_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Pubsubhubbub::DistributionWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push'
-
-  def perform(stream_entry_ids); end
-end
diff --git a/app/workers/pubsubhubbub/raw_distribution_worker.rb b/app/workers/pubsubhubbub/raw_distribution_worker.rb
deleted file mode 100644
index ece9c80ac..000000000
--- a/app/workers/pubsubhubbub/raw_distribution_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Pubsubhubbub::RawDistributionWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push'
-
-  def perform(xml, source_account_id); end
-end
diff --git a/app/workers/pubsubhubbub/subscribe_worker.rb b/app/workers/pubsubhubbub/subscribe_worker.rb
deleted file mode 100644
index b861b5e67..000000000
--- a/app/workers/pubsubhubbub/subscribe_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Pubsubhubbub::SubscribeWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push', retry: 10, unique: :until_executed, dead: false
-
-  def perform(account_id); end
-end
diff --git a/app/workers/pubsubhubbub/unsubscribe_worker.rb b/app/workers/pubsubhubbub/unsubscribe_worker.rb
deleted file mode 100644
index 0c1c263f6..000000000
--- a/app/workers/pubsubhubbub/unsubscribe_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Pubsubhubbub::UnsubscribeWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'push', retry: false, unique: :until_executed, dead: false
-
-  def perform(account_id); end
-end
diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb
index 5c6a040bd..5c13c894f 100644
--- a/app/workers/regeneration_worker.rb
+++ b/app/workers/regeneration_worker.rb
@@ -3,7 +3,7 @@
 class RegenerationWorker
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed
+  sidekiq_options lock: :until_executed
 
   def perform(account_id, _ = :home)
     account = Account.find(account_id)
diff --git a/app/workers/remote_profile_update_worker.rb b/app/workers/remote_profile_update_worker.rb
deleted file mode 100644
index 01e8daf8f..000000000
--- a/app/workers/remote_profile_update_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class RemoteProfileUpdateWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'pull'
-
-  def perform(account_id, body, resubscribe); end
-end
diff --git a/app/workers/resolve_account_worker.rb b/app/workers/resolve_account_worker.rb
index cd7c4d7dd..2b5be6d1b 100644
--- a/app/workers/resolve_account_worker.rb
+++ b/app/workers/resolve_account_worker.rb
@@ -3,7 +3,7 @@
 class ResolveAccountWorker
   include Sidekiq::Worker
 
-  sidekiq_options queue: 'pull', unique: :until_executed
+  sidekiq_options queue: 'pull', lock: :until_executed
 
   def perform(uri)
     ResolveAccountService.new.call(uri)
diff --git a/app/workers/salmon_worker.rb b/app/workers/salmon_worker.rb
deleted file mode 100644
index 10200b06c..000000000
--- a/app/workers/salmon_worker.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class SalmonWorker
-  include Sidekiq::Worker
-
-  sidekiq_options backtrace: true
-
-  def perform(account_id, body); end
-end
diff --git a/app/workers/scheduler/backup_cleanup_scheduler.rb b/app/workers/scheduler/backup_cleanup_scheduler.rb
index d43660699..d69ca2556 100644
--- a/app/workers/scheduler/backup_cleanup_scheduler.rb
+++ b/app/workers/scheduler/backup_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::BackupCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     old_backups.reorder(nil).find_each(&:destroy!)
diff --git a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
index e5e5f6bc4..94788a85b 100644
--- a/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
+++ b/app/workers/scheduler/doorkeeper_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::DoorkeeperCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     Doorkeeper::AccessToken.where('revoked_at IS NOT NULL').where('revoked_at < NOW()').delete_all
diff --git a/app/workers/scheduler/email_scheduler.rb b/app/workers/scheduler/email_scheduler.rb
index 1eeeee412..9a7355524 100644
--- a/app/workers/scheduler/email_scheduler.rb
+++ b/app/workers/scheduler/email_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::EmailScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   FREQUENCY      = 7.days.freeze
   SIGN_IN_OFFSET = 1.day.freeze
diff --git a/app/workers/scheduler/feed_cleanup_scheduler.rb b/app/workers/scheduler/feed_cleanup_scheduler.rb
index 4933f1753..99e3440fe 100644
--- a/app/workers/scheduler/feed_cleanup_scheduler.rb
+++ b/app/workers/scheduler/feed_cleanup_scheduler.rb
@@ -4,7 +4,7 @@ class Scheduler::FeedCleanupScheduler
   include Sidekiq::Worker
   include Redisable
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     clean_home_feeds!
diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb
index 4f44078d8..6d38b52a2 100644
--- a/app/workers/scheduler/ip_cleanup_scheduler.rb
+++ b/app/workers/scheduler/ip_cleanup_scheduler.rb
@@ -5,7 +5,7 @@ class Scheduler::IpCleanupScheduler
 
   RETENTION_PERIOD = 1.year
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     time_ago = RETENTION_PERIOD.ago
diff --git a/app/workers/scheduler/media_cleanup_scheduler.rb b/app/workers/scheduler/media_cleanup_scheduler.rb
index fb01aa70c..671ebf6e0 100644
--- a/app/workers/scheduler/media_cleanup_scheduler.rb
+++ b/app/workers/scheduler/media_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::MediaCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     unattached_media.find_each(&:destroy)
diff --git a/app/workers/scheduler/pghero_scheduler.rb b/app/workers/scheduler/pghero_scheduler.rb
index 4453bf2cd..cf5570048 100644
--- a/app/workers/scheduler/pghero_scheduler.rb
+++ b/app/workers/scheduler/pghero_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::PgheroScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     PgHero.capture_space_stats
diff --git a/app/workers/scheduler/scheduled_statuses_scheduler.rb b/app/workers/scheduler/scheduled_statuses_scheduler.rb
index 9cfe949de..25df3c07d 100644
--- a/app/workers/scheduler/scheduled_statuses_scheduler.rb
+++ b/app/workers/scheduler/scheduled_statuses_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::ScheduledStatusesScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     publish_scheduled_statuses!
diff --git a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb b/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
deleted file mode 100644
index 75fe681a9..000000000
--- a/app/workers/scheduler/subscriptions_cleanup_scheduler.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Scheduler::SubscriptionsCleanupScheduler
-  include Sidekiq::Worker
-
-  sidekiq_options unique: :until_executed, retry: 0
-
-  def perform; end
-end
diff --git a/app/workers/scheduler/subscriptions_scheduler.rb b/app/workers/scheduler/subscriptions_scheduler.rb
deleted file mode 100644
index 6903cadc7..000000000
--- a/app/workers/scheduler/subscriptions_scheduler.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-class Scheduler::SubscriptionsScheduler
-  include Sidekiq::Worker
-
-  sidekiq_options unique: :until_executed, retry: 0
-
-  def perform; end
-end
diff --git a/app/workers/scheduler/trending_tags_scheduler.rb b/app/workers/scheduler/trending_tags_scheduler.rb
index 77f0d5747..e9891424e 100644
--- a/app/workers/scheduler/trending_tags_scheduler.rb
+++ b/app/workers/scheduler/trending_tags_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::TrendingTagsScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     TrendingTags.update! if Setting.trends
diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb
index 881b911be..6113edde1 100644
--- a/app/workers/scheduler/user_cleanup_scheduler.rb
+++ b/app/workers/scheduler/user_cleanup_scheduler.rb
@@ -3,7 +3,7 @@
 class Scheduler::UserCleanupScheduler
   include Sidekiq::Worker
 
-  sidekiq_options unique: :until_executed, retry: 0
+  sidekiq_options lock: :until_executed, retry: 0
 
   def perform
     User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch|
diff --git a/app/workers/verify_account_links_worker.rb b/app/workers/verify_account_links_worker.rb
index 901498583..8114d59be 100644
--- a/app/workers/verify_account_links_worker.rb
+++ b/app/workers/verify_account_links_worker.rb
@@ -3,7 +3,7 @@
 class VerifyAccountLinksWorker
   include Sidekiq::Worker
 
-  sidekiq_options queue: 'pull', retry: false, unique: :until_executed
+  sidekiq_options queue: 'pull', retry: false, lock: :until_executed
 
   def perform(account_id)
     account = Account.find(account_id)
diff --git a/config/application.rb b/config/application.rb
index 1baa166ce..4c34efa15 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -7,6 +7,8 @@ require 'rails/all'
 Bundler.require(*Rails.groups)
 
 require_relative '../app/lib/exceptions'
+require_relative '../lib/paperclip/url_generator_extensions'
+require_relative '../lib/paperclip/attachment_extensions'
 require_relative '../lib/paperclip/lazy_thumbnail'
 require_relative '../lib/paperclip/gif_transcoder'
 require_relative '../lib/paperclip/video_transcoder'
diff --git a/config/deploy.rb b/config/deploy.rb
index 4dc36c65c..79550baed 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-lock '3.11.2'
+lock '3.12.1'
 
 set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git')
 set :branch, ENV.fetch('BRANCH', 'master')
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
index 221afab93..0ee16d509 100644
--- a/config/initializers/content_security_policy.rb
+++ b/config/initializers/content_security_policy.rb
@@ -37,6 +37,7 @@ if Rails.env.production?
     p.style_src       :self, :unsafe_inline, assets_host
     p.media_src       :self, :data, *data_hosts, "pool.jortage.com", "blob.jortage.com", "s3-us-east-2.amazonaws.com"
     p.frame_src       :self, :https
+    p.child_src       :self, :blob, assets_host
     p.worker_src      :self, :blob, assets_host
     p.connect_src     :self, :blob, :data, Rails.configuration.x.streaming_api_base_url, *data_hosts
     p.manifest_src    :self, assets_host
diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb
index aa1517256..4fec4320c 100644
--- a/config/initializers/kaminari_config.rb
+++ b/config/initializers/kaminari_config.rb
@@ -2,6 +2,6 @@
 
 Kaminari.configure do |config|
   config.default_per_page = 40
-  config.window = 1
+  config.window = 2
   config.outer_window = 1
 end
diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb
index 3cd7ea3a6..09458c540 100644
--- a/config/initializers/rack_attack.rb
+++ b/config/initializers/rack_attack.rb
@@ -42,6 +42,7 @@ class Rack::Attack
     /auth/sign_in
     /auth
     /auth/password
+    /auth/confirmation
   ).freeze
 
   PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
@@ -70,7 +71,6 @@ class Rack::Attack
     req.remote_ip if req.post? && req.path == '/api/v1/accounts'
   end
 
-  # Throttle paging, as it is mainly used for public pages and AP collections
   throttle('throttle_authenticated_paging', limit: 300, period: 15.minutes) do |req|
     req.authenticated_user_id if req.paging_request?
   end
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index 7f8a40d7b..f2733562f 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -13,10 +13,15 @@ Sidekiq.configure_server do |config|
   config.server_middleware do |chain|
     chain.add SidekiqErrorHandler
   end
+
+  config.death_handlers << lambda do |job, _ex|
+    digest = job['lock_digest']
+    SidekiqUniqueJobs::Digests.delete_by_digest(digest) if digest
+  end
 end
 
 Sidekiq.configure_client do |config|
   config.redis = redis_params
 end
 
-Sidekiq::Logging.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)
+Sidekiq.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)
diff --git a/config/locales/activerecord.br.yml b/config/locales/activerecord.br.yml
index 77fc4f2a1..a7eab580c 100644
--- a/config/locales/activerecord.br.yml
+++ b/config/locales/activerecord.br.yml
@@ -10,4 +10,8 @@ br:
         account:
           attributes:
             username:
-              invalid: nemet lizherennoù, niverennoù ha isbarrennigoù
+              invalid: nemet lizherennoù, niverennoù hag isbarrennigoù
+        status:
+          attributes:
+            reblog:
+              taken: eus ar statud a zo dija
diff --git a/config/locales/activerecord.hy.yml b/config/locales/activerecord.hy.yml
index c40654016..0da0b3d5e 100644
--- a/config/locales/activerecord.hy.yml
+++ b/config/locales/activerecord.hy.yml
@@ -1 +1,17 @@
+---
 hy:
+  activerecord:
+    attributes:
+      poll:
+        expires_at: Վերջնաժամկետ
+        options: Տարբերակներ
+    errors:
+      models:
+        account:
+          attributes:
+            username:
+              invalid: միայն տառեր, թվեր և ընդգիծկներ
+        status:
+          attributes:
+            reblog:
+              taken: թութը գոյություն ունի
diff --git a/config/locales/activerecord.kab.yml b/config/locales/activerecord.kab.yml
index 21007347c..24e2760da 100644
--- a/config/locales/activerecord.kab.yml
+++ b/config/locales/activerecord.kab.yml
@@ -3,6 +3,7 @@ kab:
   activerecord:
     attributes:
       poll:
+        expires_at: Azemz n tagara
         options: Tifranin
     errors:
       models:
@@ -10,3 +11,7 @@ kab:
           attributes:
             username:
               invalid: isekkilen, uṭṭunen d yijerriden n wadda kan
+        status:
+          attributes:
+            reblog:
+              taken: n iddaden yellan yakan
diff --git a/config/locales/activerecord.zh-HK.yml b/config/locales/activerecord.zh-HK.yml
index 2ebf9586c..c968e55aa 100644
--- a/config/locales/activerecord.zh-HK.yml
+++ b/config/locales/activerecord.zh-HK.yml
@@ -1,6 +1,10 @@
 ---
 zh-HK:
   activerecord:
+    attributes:
+      poll:
+        expires_at: 截止時間
+        options: 選擇
     errors:
       models:
         account:
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index f5a6f067d..c73115e2a 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -2,7 +2,7 @@
 ar:
   about:
     about_hashtag_html: هذه تبويقات متاحة للجمهور تحتوي على الكلمات الدلالية <strong>#%{hashtag}</strong>. يمكنك التفاعل معها إن كان لديك حساب في أي مكان على الفديفرس.
-    about_mastodon_html: ماستدون شبكة اجتماعية مبنية على أسُس بروتوكولات برمجيات الويب الحرة و مفتوحة المصدر. و هو لامركزي تمامًا كالبريد الإلكتروني.
+    about_mastodon_html: 'شبكة التواصل الإجتماعية المستقبَليّة: مِن دون إعلانات ، غير خاضعة لرقابة الشركات ، تصميم أخلاقي ولامركزية! بياناتكم مِلك لكم مع ماستدون!'
     about_this: عن مثيل الخادوم هذا
     active_count_after: نشط
     active_footnote: مستخدم نشيط شهريا (MAU)
@@ -39,8 +39,9 @@ ar:
     unavailable_content: محتوى غير متوفر
     unavailable_content_description:
       domain: الخادم
-      reason: 'السبب:'
+      reason: السبب
       silenced: 'سيتم إخفاء المنشورات القادمة من هذه الخوادم في الخيوط الزمنية والمحادثات العامة، ولن يتم إنشاء أي إخطارات من جراء تفاعلات مستخدميها، ما لم تُتَابعهم:'
+    unavailable_content_html: يسمح لك ماستدون عموماً بعرض محتوى المستخدمين القادم من أي خادم آخر في الفديفرس والتفاعل معهم. وهذه هي الاستثناءات التي وضعت على هذا الخادوم بالذات.
     user_count_after:
       few: مستخدمين
       many: مستخدمين
@@ -53,6 +54,7 @@ ar:
   accounts:
     choices_html: 'توصيات %{name}:'
     endorsements_hint: يمكنك التوصية بالأشخاص الذين تتابعهم من واجهة الويب، وسيظهرون هنا.
+    featured_tags_hint: يمكنك عرض وسوم محددة سيتم عرضها هنا.
     follow: اتبع
     followers:
       few: متابِعون
@@ -202,6 +204,34 @@ ar:
       web: الويب
       whitelisted: في القائمة البيضاء
     action_logs:
+      action_types:
+        assigned_to_self_report: أسند التقرير
+        change_email_user: تغيير عنوان البريد الإلكتروني الخاص بالمستخدم
+        confirm_user: تأكيد المستخدم
+        create_account_warning: إنشاء تحذير
+        create_announcement: إنشاء إعلان
+        create_custom_emoji: إنشاء إيموجي مخصص
+        destroy_announcement: احذف الإعلان
+        destroy_custom_emoji: احذف الإيموجي المخصص
+        disable_2fa_user: تعطيل 2FA
+        disable_custom_emoji: تعطيل الإيموجي المخصص
+        disable_user: تعطيل المستخدم
+        enable_custom_emoji: تفعيل الإيموجي المخصص
+        enable_user: تفعيل المستخدم
+        memorialize_account: جعل الحساب تذكاريا
+        promote_user: ترقية المستخدم
+        remove_avatar_user: احذف الصورة الرمزية
+        reopen_report: إعادة فتح التقرير
+        reset_password_user: إعادة تعيين كلمة المرور
+        resolve_report: حل الشكوى
+        silence_account: كتم الحساب
+        suspend_account: تعليق الحساب
+        unassigned_report: إلغاء إسناد الشكوى
+        unsilence_account: إلغاء كتم الحساب
+        unsuspend_account: إلغاء تعليق الحساب
+        update_announcement: تحديث الإعلان
+        update_custom_emoji: تحديث الإيموجي المخصص
+        update_status: تحديث الحالة
       actions:
         assigned_to_self_report: قام %{name} بتعيين التقرير %{target} لأنفسهم
         change_email_user: غيّر %{name} عنوان البريد الإلكتروني للمستخدم %{target}
@@ -239,6 +269,9 @@ ar:
         update_custom_emoji: "%{name} قام بتحديث الإيموجي %{target}"
         update_status: لقد قام %{name} بتحديث منشور %{target}
       deleted_status: "(منشور محذوف)"
+      empty: لم يتم العثور على سجلات.
+      filter_by_action: تصفية بحسب الإجراء
+      filter_by_user: تصفية حسب المستخدم
       title: سِجلّ التفتيش و المعاينة
     announcements:
       destroyed_msg: تم حذف الإعلان بنجاح!
@@ -364,6 +397,7 @@ ar:
       destroyed_msg: تم حذف نطاق البريد الإلكتروني من اللائحة السوداء بنجاح
       domain: النطاق
       empty: ليس هناك أية نطاقات للبريد الإلكتروني مُدرَجة في القائمة السوداء.
+      from_html: مِن %{domain}
       new:
         create: إضافة نطاق
         title: إضافة نطاق بريد جديد إلى اللائحة السوداء
@@ -421,10 +455,26 @@ ar:
       created_msg: تم إنشاء ملاحظة الشكوى بنجاح!
       destroyed_msg: تم حذف ملاحظة الشكوى بنجاح!
     reports:
+      account:
+        notes:
+          few: "%{count} ملاحظات"
+          many: "%{count} ملاحظات"
+          one: "%{count} ملاحظة"
+          other: "%{count} ملاحظات"
+          two: "%{count} ملاحظتَيْن"
+          zero: "%{count} ملاحظات"
+        reports:
+          few: "%{count} تقارير"
+          many: "%{count} تقارير"
+          one: "%{count} تقرير واحد"
+          other: "%{count} تقارير"
+          two: "%{count} تقريرَيْن"
+          zero: "%{count} تقارير"
       action_taken_by: تم اتخاذ الإجراء مِن طرف
       are_you_sure: هل أنت متأكد ؟
       assign_to_self: عين لي
       assigned: تعين رئيس
+      by_target_domain: نطاق الحساب المبلّغ عنه
       comment:
         none: لا شيء
       created_at: ذكرت
@@ -466,11 +516,16 @@ ar:
         all: للجميع
         disabled: لا أحد
         title: اظهر خاصية حجب النطاقات
+        users: للمستخدمين المتصلين محليا
       domain_blocks_rationale:
         title: اظهر السبب
+      enable_bootstrap_timeline_accounts:
+        title: تمكين الاشتراكات الافتراضية للمستخدمين الجدد
       hero:
         desc_html: معروض على الصفحة الأولى. لا يقل عن 600 × 100 بكسل. عند عدم التعيين ، تعود الصورة إلى النسخة المصغرة على سبيل المثال
         title: الصورة الرأسية
+      mascot:
+        title: صورة الماسكوت
       peers_api_enabled:
         desc_html: أسماء النطاقات التي التقى بها مثيل الخادوم على البيئة الموحَّدة فديفرس
         title: نشر عدد مثيلات الخوادم التي تم مصادفتها
@@ -527,6 +582,9 @@ ar:
         title: السماح للوسوم بالظهور على المتداوَلة بدون مراجعة مسبقة
       trends:
         title: الوسوم المتداولة
+    site_uploads:
+      delete: احذف الملف الذي تم تحميله
+      destroyed_msg: تم حذف التحميل مِن الموقع بنجاح!
     statuses:
       back_to_account: العودة إلى صفحة الحساب
       batch:
@@ -562,7 +620,6 @@ ar:
     warning_presets:
       add_new: إضافة واحد جديد
       delete: حذف
-      edit: تعديل
       edit_preset: تعديل نموذج التحذير
       title: إدارة نماذج التحذير
   admin_mailer:
@@ -578,6 +635,7 @@ ar:
     remove: إلغاء ربط الكنية
   appearance:
     advanced_web_interface: واجهة الويب المتقدمة
+    advanced_web_interface_hint: 'إذا كنت ترغب في استخدام عرض شاشتك بأكمله، فواجهة الويب المتقدمة تسمح لك بضبط العديد من الأعمدة المختلفة لرؤية أكبر قدر من المعلومات التي ترغب فيها في آن واحد: الخيط الرئيسي والإخطارات والخيط الزمني الفدرالي وأي عدد من القوائم والوسوم.'
     animations_and_accessibility: الإتاحة والحركة
     confirmation_dialogs: نوافذ التأكيد
     discovery: استكشاف
@@ -642,6 +700,7 @@ ar:
     trouble_logging_in: هل صادفتكم مشكلة في الولوج؟
   authorize_follow:
     already_following: أنت تتابع بالفعل هذا الحساب
+    already_requested: لقد قُمتَ بإرسال طلب متابَعة إلى هذا الحساب مِن قَبل
     error: يا للأسف، وقع هناك خطأ إثر عملية البحث عن الحساب عن بعد
     follow: اتبع
     follow_request: 'لقد قمت بإرسال طلب متابعة إلى:'
@@ -684,6 +743,7 @@ ar:
       data_removal: سوف تُحذَف منشوراتك والبيانات الأخرى نهائيا
       email_change_html: بإمكانك <a href="%{path}">تغيير عنوان بريدك الإلكتروني</a> دون أن يُحذف حسابك
       email_contact_html: إن لم تتلقّ أي شيء ، يمكنك مراسلة <a href="mailto:%{email}">%{email}</a> لطلب المساعدة
+      email_reconfirmation_html: إن لم تتلقّ الرسالة الإلكترونية للتأكيد ، بإمكانك <a href="%{path}">إعادة طلبها ثانيةً</a>
       irreversible: لن يكون بإمكانك استرجاع أو إعادة تنشيط حسابك
       more_details_html: للمزيد مِن التفاصيل ، يرجى الإطلاع على <a href="%{terms_path}">سياسة الخصوصية</a>.
       username_available: سيصبح اسم مستخدمك متوفرا ثانية
@@ -825,7 +885,7 @@ ar:
       images_and_video: ليس بالإمكان إرفاق فيديو في منشور يحتوي مسبقا على صور
       too_many: لا يمكن إرفاق أكثر من 4 ملفات
   migrations:
-    acct: username@domain للحساب الجديد
+    acct: انتقل إلى
     cancel: ألغِ التوجيه
     cancelled_msg: تم إلغاء التوجيه بنجاح.
     errors:
@@ -1089,6 +1149,8 @@ ar:
     pinned: تبويق مثبّت
     reblogged: رقّاه
     sensitive_content: محتوى حساس
+  tags:
+    does_not_match_previous_name: لا يطابق الإسم السابق
   terms:
     title: شروط الخدمة وسياسة الخصوصية على %{instance}
   themes:
diff --git a/config/locales/ast.yml b/config/locales/ast.yml
index d7e0faf41..1d6c11f13 100644
--- a/config/locales/ast.yml
+++ b/config/locales/ast.yml
@@ -209,6 +209,7 @@ ast:
     trouble_logging_in: "¿Problemes col aniciu de sesión?"
   authorize_follow:
     already_following: Yá tas siguiendo a esta cuenta
+    already_requested: Yá unviesti una solicitú de siguimientu a esa cuenta
     error: Desafortunadamente, hebo un fallu guetando la cuenta remota
     follow_request: 'Unviesti una solicitú de siguimientu a:'
     post_follow:
@@ -354,7 +355,7 @@ ast:
     errors:
       already_voted: Yá votesti nesta encuesta
       expired: La encuesta yá finó
-      invalid_choice: El la opción de votu escoyida nun esiste
+      invalid_choice: La opción de votu escoyida nun esiste
   preferences:
     public_timelines: Llinies temporales públiques
   relationships:
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 07149f51f..4142d439f 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -54,7 +54,7 @@ bg:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   exports:
diff --git a/config/locales/bn.yml b/config/locales/bn.yml
index 7dd49ff96..ad613f721 100644
--- a/config/locales/bn.yml
+++ b/config/locales/bn.yml
@@ -201,7 +201,7 @@ bn:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/br.yml b/config/locales/br.yml
index 7d15639ee..5da24d25c 100644
--- a/config/locales/br.yml
+++ b/config/locales/br.yml
@@ -3,8 +3,140 @@ br:
   about:
     about_this: Diàr-benn
     active_count_after: oberiant
+    api: API
     apps: Arloadoù pellgomz
     apps_platforms: Ober get Mastodoñ àr iOS, Android ha savennoù arall
+    contact: Darempred
+    discover_users: Dizoleiñ implijer·ien·ezed
+    learn_more: Gouzout hiroc'h
+    privacy_policy: Reolennoù prevezded
+    source_code: Boneg tarzh
+    terms: Divizoù gwerzhañ hollek
+    unavailable_content_description:
+      domain: Dafariad
+  accounts:
+    media: Media
+    posts_tab_heading: Toudoù
+    posts_with_replies: Toudoù ha respontoù
+    roles:
+      admin: Merour
+      bot: Robot
+      group: Strollad
+      moderator: Mod
+    unavailable: Profil dihegerz
+    unfollow: Diheuliañ
+  admin:
+    account_moderation_notes:
+      delete: Dilemel
+    accounts:
+      change_email:
+        current_email: Postel bremanel
+        label: Kemm ar postel
+        new_email: Postel nevez
+        submit: Kemm ar postel
+      enable: Gweredekaat
+      enabled: Gweredekaet
+      followers: Heulier·ezed·ien
+      header: Talbenn
+      ip: IP
+      location:
+        local: Lec'hel
+        remote: A-bell
+      moderation:
+        active: Oberiant
+        silenced: Mudet
+        suspended: Astalet
+      perform_full_suspension: Astalañ
+      protocol: Komenad
+      public: Publik
+      reject: Nac'hañ
+      reject_all: Nac'hañ pep hini
+      remove_header: Dilemel an talbenn
+      reset: Adderaouekaat
+      reset_password: Adderaouekaat ar ger-tremen
+      roles:
+        admin: Merour
+        moderator: Habaskaer·ez
+        user: Implijer·ez
+    action_logs:
+      deleted_status: "(statud dilemet)"
+    announcements:
+      new:
+        create: Sevel ur gemenn
+        title: Kemenn nevez
+      title: Kemennoù
+    custom_emojis:
+      delete: Dilemel
+      disable: Diweredekaat
+      disabled: Diweredekaet
+      emoji: Fromlun
+      enable: Gweredekaat
+      enabled: Gweredekaet
+    dashboard:
+      config: Kefluniadur
+      software: Meziant
+      trends: Luskadoù
+    domain_blocks:
+      domain: Domani
+      new:
+        create: Sevel ur stanker
+        severity:
+          noop: Hini ebet
+          silence: Mudañ
+          suspend: Astalañ
+      severity:
+        silence: mudet
+        suspend: astalet
+      show:
+        undo: Dizober
+    email_domain_blocks:
+      add_new: Ouzhpenniñ unan nevez
+      delete: Dilemel
+      domain: Domani
+      from_html: eus %{domain}
+      new:
+        create: Ouzhpenniñ un domani
+    instances:
+      by_domain: Domani
+      moderation:
+        all: Pep tra
+    settings:
+      domain_blocks:
+        all: D'an holl dud
+      site_title: Anv ar servijer
+      title: Arventennoù al lec'hienn
+  auth:
+    change_password: Ger-tremen
+    delete_account: Dilemel ar gont
+    login: Mont tre
+    logout: Digennaskañ
+    providers:
+      saml: SAML
+    reset_password: Adderaouekaat ar ger-tremen
+    security: Diogelroez
+    setup:
+      title: Kefluniañ
+  authorize_follow:
+    title: Heuliañ %{acct}
+  challenge:
+    confirm: Kenderc' hel
+    invalid_password: Ger-tremen diwiriek
+  datetime:
+    distance_in_words:
+      about_x_hours: "%{count}e"
+      about_x_months: "%{count}miz"
+      about_x_years: "%{count}b"
+      almost_x_years: "%{count}b"
+      less_than_x_minutes: "%{count}m"
+      over_x_years: "%{count}b"
+      x_days: "%{count}d"
+      x_minutes: "%{count}m"
+      x_months: "%{count}miz"
+      x_seconds: "%{count}eil"
+  deletes:
+    proceed: Dilemel ar gont
+  directories:
+    directory: Roll ar profiloù
   errors:
     '400': The request you submitted was invalid or malformed.
     '403': You don't have permission to view this page.
@@ -12,14 +144,93 @@ br:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
+  featured_tags:
+    add_new: Ouzhpenniñ unan nevez
+  filters:
+    contexts:
+      account: Profiloù
+      notifications: Kemennoù
+    index:
+      delete: Dilemel
+  footer:
+    developers: Diorroerien
+    more: Muioc'h…
+  generic:
+    all: Pep tra
+    copy: Eilañ
+    delete: Dilemel
+    order_by: Urzhiañ dre
   invites:
     expires_in:
       '1800': 30 minutes
       '21600': 6 hours
       '3600': 1 hour
-      '43200': 12 hours
-      '604800': 1 week
-      '86400': 1 day
+      '43200': 12 eur
+      '604800': 1 sizhun
+      '86400': 1 deiz
+    expires_in_prompt: Birviken
+    title: Pediñ tud
+  notification_mailer:
+    follow:
+      title: Heulier nevez
+    mention:
+      action: Respont
+  relationships:
+    followers: Heulier·ezed·ien
+  sessions:
+    browser: Merdeer
+    browsers:
+      alipay: Alipay
+      blackberry: Blackberry
+      chrome: Chrome
+      edge: Microsoft Edge
+      electron: Electron
+      firefox: Firefox
+      ie: Internet Explorer
+      micro_messenger: MicroMessenger
+      nokia: Nokia S40 Ovi Browser
+      opera: Opera
+      otter: Otter
+      phantom_js: PhantomJS
+      qq: QQ Browser
+      safari: Safari
+      uc_browser: UCBrowser
+      weibo: Weibo
+    ip: IP
+    platforms:
+      adobe_air: Adobe Air
+      android: Android
+      blackberry: Blackberry
+      chrome_os: ChromeOS
+      firefox_os: Firefox OS
+      ios: iOS
+      linux: Linux
+      mac: macOS
+      windows: Windows
+  statuses:
+    show_more: Diskouez muioc'h
+    title: '%{name}: "%{quote}"'
+    visibilities:
+      public: Publik
+  stream_entries:
+    pinned: Toud spilhennet
+  themes:
+    default: Mastodoñ (Teñval)
+    mastodon-light: Mastodoñ (Sklaer)
+  time:
+    formats:
+      default: "%He%M, %d %b %Y"
+      month: "%b %Y"
+  two_factor_authentication:
+    disable: Diweredekaat
+    enable: Gweredekaat
+    setup: Kefluniañ
+  user_mailer:
+    warning:
+      title:
+        none: Diwall
+    welcome:
+      edit_profile_action: Kefluniañ ar profil
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 1c30b6b7a..f056bb943 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -92,6 +92,7 @@ ca:
       delete: Suprimeix
       destroyed_msg: Nota de moderació destruïda amb èxit!
     accounts:
+      add_email_domain_block: Afegir el domini de correu a la llista negra
       approve: Aprova
       approve_all: Aprova'ls tots
       are_you_sure: N'estàs segur?
@@ -172,6 +173,7 @@ ca:
         staff: Personal
         user: Usuari
       search: Cerca
+      search_same_email_domain: Altres usuaris amb el mateix domini de correu
       search_same_ip: Altres usuaris amb la mateixa IP
       shared_inbox_url: URL de la safata d'entrada compartida
       show:
@@ -193,6 +195,42 @@ ca:
       web: Web
       whitelisted: Llista blanca
     action_logs:
+      action_types:
+        assigned_to_self_report: Assigna l'informe
+        change_email_user: Canvia l'adreça electrònica per l'usuari
+        confirm_user: Confirma l'usuari
+        create_account_warning: Crea un avís
+        create_announcement: Crea un anunci
+        create_custom_emoji: Crea un emoji personalitzat
+        create_domain_allow: Crea un domini permès
+        create_domain_block: Crea un bloqueig de domini
+        create_email_domain_block: Crea un bloqueig de domini d'adreça de correu
+        demote_user: Degrada l'usuari
+        destroy_announcement: Esborra l'anunci
+        destroy_custom_emoji: Esborra l'emoji personalitzat
+        destroy_domain_allow: Esborra el domini permès
+        destroy_domain_block: Esborra el bloqueig de domini
+        destroy_email_domain_block: Esborra el bloqueig de domini de l'adreça de correu
+        destroy_status: Esborra el tut
+        disable_2fa_user: Desactiva 2FA
+        disable_custom_emoji: Desactiva l'emoji personalitzat
+        disable_user: Deshabilita l'usuari
+        enable_custom_emoji: Activa l'emoji personalitzat
+        enable_user: Activa l'usuari
+        memorialize_account: Memoritza el compte
+        promote_user: Promou l'usuari
+        remove_avatar_user: Eliminar avatar
+        reopen_report: Reobre l'informe
+        reset_password_user: Restableix la contrasenya
+        resolve_report: Resolt l'informe
+        silence_account: Silencia el compte
+        suspend_account: Suspèn el compte
+        unassigned_report: Des-assigna l'informe
+        unsilence_account: Desfés el silenci del compte
+        unsuspend_account: Desfés la suspensió del compte
+        update_announcement: Actualitza l'anunci
+        update_custom_emoji: Actualitza l'emoji personalitzat
+        update_status: Actualitza l'estat
       actions:
         assigned_to_self_report: "%{name} han assignat l'informe %{target} a ells mateixos"
         change_email_user: "%{name} ha canviat l'adreça de correu electrònic del usuari %{target}"
@@ -230,6 +268,9 @@ ca:
         update_custom_emoji: "%{name} ha actualitzat l'emoji %{target}"
         update_status: "%{name} estat actualitzat per %{target}"
       deleted_status: "(tut esborrat)"
+      empty: No s’han trobat registres.
+      filter_by_action: Filtra per acció
+      filter_by_user: Filtra per usuari
       title: Registre d'auditoria
     announcements:
       destroyed_msg: L’anunci s’ha esborrat amb èxit!
@@ -358,6 +399,7 @@ ca:
       destroyed_msg: S'ha eliminat correctament el bloc del domini de correu
       domain: Domini
       empty: Cap domini de correu a la llista negre.
+      from_html: des de %{domain}
       new:
         create: Afegeix un domini
         title: Nova adreça de correu en la llista negra
@@ -537,6 +579,9 @@ ca:
       trends:
         desc_html: Mostra públicament les etiquetes revisades anteriorment que actualment estan en tendència
         title: Etiquetes tendència
+    site_uploads:
+      delete: Esborra el fitxer pujat
+      destroyed_msg: La càrrega al lloc s'ha suprimit correctament!
     statuses:
       back_to_account: Torna a la pàgina del compte
       batch:
@@ -573,7 +618,6 @@ ca:
     warning_presets:
       add_new: Afegeix-ne un de nou
       delete: Esborra
-      edit: Edita
       edit_preset: Edita l'avís predeterminat
       title: Gestiona les configuracions predefinides dels avisos
   admin_mailer:
@@ -661,6 +705,7 @@ ca:
     trouble_logging_in: Problemes per iniciar la sessió?
   authorize_follow:
     already_following: Ja estàs seguint aquest compte
+    already_requested: Ja has enviat una sol·licitud de seguiment a aquest usuari
     error: Malauradament, ha ocorregut un error cercant el compte remot
     follow: Segueix
     follow_request: 'Has enviat una sol·licitud de seguiment a:'
@@ -849,6 +894,7 @@ ca:
   media_attachments:
     validations:
       images_and_video: No es pot adjuntar un vídeo a una publicació que ja contingui imatges
+      not_ready: No es poden adjuntar fitxers que no s'hagin acabat de processar. Torna-ho a provar en un moment!
       too_many: No es poden adjuntar més de 4 fitxers
   migrations:
     acct: Mogut a
@@ -1070,6 +1116,8 @@ ca:
     disallowed_hashtags:
       one: 'conté una etiqueta no permesa: %{tags}'
       other: 'conté les etiquetes no permeses: %{tags}'
+    errors:
+      in_reply_not_found: El tut al qual intentes respondre sembla que no existeix.
     language_detection: Detecta automàticament el llenguatge
     open_in_web: Obre en la web
     over_character_limit: Límit de caràcters de %{max} superat
diff --git a/config/locales/co.yml b/config/locales/co.yml
index 24f7f45fc..2d50cefd7 100644
--- a/config/locales/co.yml
+++ b/config/locales/co.yml
@@ -92,6 +92,7 @@ co:
       delete: Toglie
       destroyed_msg: Nota di muderazione sguassata!
     accounts:
+      add_email_domain_block: Mette u duminiu e-mail in lista nera
       approve: Appruvà
       approve_all: Appruvà tuttu
       are_you_sure: Site sicuru·a?
@@ -172,6 +173,7 @@ co:
         staff: Squadra
         user: Utilizatore
       search: Cercà
+      search_same_email_domain: Altri utilizatori cù listessu duminiu d'e-mail
       search_same_ip: Altri utilizatori cù listessa IP
       shared_inbox_url: URL di l’inbox spartuta
       show:
@@ -193,6 +195,42 @@ co:
       web: Web
       whitelisted: In a lista bianca
     action_logs:
+      action_types:
+        assigned_to_self_report: Assignà signalamentu
+        change_email_user: Mudificà l'E-mail di l'Utilizatore
+        confirm_user: Cunfirmà Utilizatore
+        create_account_warning: Creà avertimentu
+        create_announcement: Creà Annunziu
+        create_custom_emoji: Creà Emoji Persunalizata
+        create_domain_allow: Creà Auturizazione di Duminiu
+        create_domain_block: Creà Blucchime di Duminiu
+        create_email_domain_block: Creà Blucchime di Duminiu E-mail
+        demote_user: Ritrugadà Utilizatore
+        destroy_announcement: Toglie Annunziu
+        destroy_custom_emoji: Toglie Emoji Persunalizata
+        destroy_domain_allow: Toglie Auturizazione di Duminiu
+        destroy_domain_block: Toglie Blucchime di Duminiu
+        destroy_email_domain_block: Toglie blucchime di duminiu e-mail
+        destroy_status: Toglie u statutu
+        disable_2fa_user: Disattivà l’identificazione à 2 fattori
+        disable_custom_emoji: Disattivà Emoji Persunalizata
+        disable_user: Disattivà Utilizatore
+        enable_custom_emoji: Attivà Emoji Persunalizata
+        enable_user: Attivà utilizatore
+        memorialize_account: Trasfurmà contu in mimuriale
+        promote_user: Prumove Utilizatore
+        remove_avatar_user: Toglie Avatar
+        reopen_report: Riapre Signalamentu
+        reset_password_user: Riinizializà Chjave d'Accessu
+        resolve_report: Chjode Signalamentu
+        silence_account: Silenzà Contu
+        suspend_account: Suspende Contu
+        unassigned_report: Disassignà signalamentu
+        unsilence_account: Ùn Silenzà Più u Contu
+        unsuspend_account: Ùn Suspende Più u Contu
+        update_announcement: Cambià Annunziu
+        update_custom_emoji: Cambià Emoji Persunalizata
+        update_status: Cambià Statutu
       actions:
         assigned_to_self_report: "%{name} s’hè assignatu u signalamentu %{target}"
         change_email_user: "%{name} hà cambiatu l’indirizzu e-mail di %{target}"
@@ -230,6 +268,9 @@ co:
         update_custom_emoji: "%{name} hà messu à ghjornu l’emoji %{target}"
         update_status: "%{name} hà cambiatu u statutu di %{target}"
       deleted_status: "(statutu sguassatu)"
+      empty: Nunda trovu.
+      filter_by_action: Filtrà da azzione
+      filter_by_user: Filtrà da utilizatore
       title: Ghjurnale d’audit
     announcements:
       destroyed_msg: Annunziu sguassatu!
@@ -358,6 +399,7 @@ co:
       destroyed_msg: U blucchime di u duminiu d’e-mail ùn hè più attivu
       domain: Duminiu
       empty: Ùn c'hè manc'un duminiu d'email in lista nera.
+      from_html: da %{domain}
       new:
         create: Creà un blucchime
         title: Nova iscrizzione nant’a lista nera e-mail
@@ -537,6 +579,9 @@ co:
       trends:
         desc_html: Mustrà à u pubblicu i hashtag chì sò stati digià verificati è chì sò in e tendenze avà
         title: Tendenze di hashtag
+    site_uploads:
+      delete: Sguassà u fugliale caricatu
+      destroyed_msg: Fugliale sguassatu da u situ!
     statuses:
       back_to_account: Ritornu à a pagina di u contu
       batch:
@@ -573,7 +618,6 @@ co:
     warning_presets:
       add_new: Aghjunghje
       delete: Sguassà
-      edit: Cambià
       edit_preset: Cambià a preselezzione d'avertimentu
       title: Amministrà e preselezzione d'avertimentu
   admin_mailer:
@@ -661,6 +705,7 @@ co:
     trouble_logging_in: Difficultà per cunnettavi?
   authorize_follow:
     already_following: Site digià abbunatu·a à stu contu
+    already_requested: Avete digià mandatu una dumanda d'abbunamentu à stu contu
     error: Peccatu, c’hè statu un prublemu ricercandu u contu
     follow: Siguità
     follow_request: 'Avete dumandatu di siguità:'
@@ -849,6 +894,7 @@ co:
   media_attachments:
     validations:
       images_and_video: Ùn si pò micca aghjunghje un filmettu à un statutu chì hà digià ritratti
+      not_ready: Ùn si pò micca aghjunghje un fugliale micca ancu trattatu. Ripruvate più tardi!
       too_many: Ùn si pò micca aghjunghje più di 4 fugliali
   migrations:
     acct: cugnome@duminiu di u novu contu
@@ -1070,6 +1116,8 @@ co:
     disallowed_hashtags:
       one: 'cuntene l’hashtag disattivatu: %{tags}'
       other: 'cuntene l’hashtag disattivati: %{tags}'
+    errors:
+      in_reply_not_found: U statutu à quellu avete pruvatu di risponde ùn sembra micca esiste.
     language_detection: Truvà a lingua autumaticamente
     open_in_web: Apre nant’à u web
     over_character_limit: Site sopr’à a limita di %{max} caratteri
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index bab669e7e..d7c49279d 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -244,6 +244,7 @@ cs:
       edit:
         title: Upravit oznámení
       empty: Nebyla nalezena žádná oznámení.
+      live: Živě
       new:
         create: Vytvořit oznámení
         title: Nové oznámení
@@ -588,7 +589,6 @@ cs:
     warning_presets:
       add_new: Přidat nové
       delete: Smazat
-      edit: Upravit
       edit_preset: Upravit předlohu pro varování
       title: Spravovat předlohy pro varování
   admin_mailer:
@@ -676,6 +676,7 @@ cs:
     trouble_logging_in: Problémy s přihlášením?
   authorize_follow:
     already_following: Tento účet již sledujete
+    already_requested: Tomuto účtu už jste žádost o sledování zaslali
     error: Při hledání vzdáleného účtu bohužel nastala chyba
     follow: Sledovat
     follow_request: 'Poslali jste žádost o sledování uživateli:'
@@ -1119,6 +1120,7 @@ cs:
         other: "%{count} hlasů"
       vote: Hlasovat
     show_more: Zobrazit více
+    show_thread: Zobrazit vlákno
     sign_in_to_participate: Chcete-li se zúčastnit této konverzace, přihlaste se
     title: "%{name}: „%{quote}“"
     visibilities:
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index afca0212a..572cf895a 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -569,6 +569,9 @@ cy:
       trends:
         desc_html: Arddangos hashnodau a adolygwyd yn gynt yn gyhoeddus sydd yn tueddu yn bresennol
         title: Hashnodau tueddig
+    site_uploads:
+      delete: Dileu ffeil sydd wedi'i uwchlwytho
+      destroyed_msg: Uwchlwythiad wefan wedi'i ddileu yn lwyddianus!
     statuses:
       back_to_account: Yn ôl i dudalen y cyfrif
       batch:
@@ -605,7 +608,6 @@ cy:
     warning_presets:
       add_new: Ychwanegu newydd
       delete: Dileu
-      edit: Golygu
       edit_preset: Golygu rhagosodiad rhybudd
       title: Rheoli rhagosodiadau rhybudd
   admin_mailer:
@@ -693,6 +695,7 @@ cy:
     trouble_logging_in: Trafferdd mewngofnodi?
   authorize_follow:
     already_following: Yr ydych yn dilyn y cyfrif hwn yn barod
+    already_requested: Rydych barod wedi anfon ceisiad dilyn i'r cyfrif hynny
     error: Yn anffodus, roedd gwall tra'n edrych am y cyfrif anghysbell
     follow: Dilyn
     follow_request: 'Yr ydych wedi anfon cais dilyn at:'
@@ -889,6 +892,7 @@ cy:
   media_attachments:
     validations:
       images_and_video: Ni ellir ychwanegu fideo at statws sy'n cynnwys delweddau'n barod
+      not_ready: Methu atodi ffeiliau sydd dal yn prosesu. Ceisiwch eto mewn foment!
       too_many: Ni ellir ychwanegu mwy na 4 dogfen
   migrations:
     acct: enwdefnyddiwr@parth y cyfrif newydd
diff --git a/config/locales/da.yml b/config/locales/da.yml
index 1cdf7722e..c978029b3 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -489,7 +489,6 @@ da:
       most_recent: Seneste
     warning_presets:
       delete: Slet
-      edit: Rediger
   admin_mailer:
     new_report:
       body: "%{reporter} har anmeldt %{target}"
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 50f994473..d99b36d14 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -92,6 +92,7 @@ de:
       delete: Löschen
       destroyed_msg: Moderationsnotiz erfolgreich gelöscht!
     accounts:
+      add_email_domain_block: E-Mail-Domain blacklisten
       approve: Akzeptieren
       approve_all: Alle akzeptieren
       are_you_sure: Bist du sicher?
@@ -172,6 +173,7 @@ de:
         staff: Mitarbeiter
         user: Nutzer
       search: Suche
+      search_same_email_domain: Andere Benutzer mit der gleichen E-Mail-Domain
       search_same_ip: Andere Benutzer mit derselben IP
       shared_inbox_url: Geteilte Posteingang-URL
       show:
@@ -193,6 +195,42 @@ de:
       web: Web
       whitelisted: Auf der Whitelist
     action_logs:
+      action_types:
+        assigned_to_self_report: Bericht zuweisen
+        change_email_user: E-Mail des Benutzers ändern
+        confirm_user: Benutzer bestätigen
+        create_account_warning: Warnung erstellen
+        create_announcement: Ankündigung erstellen
+        create_custom_emoji: Eigene Emoji erstellen
+        create_domain_allow: Domain erlauben
+        create_domain_block: Domain blockieren
+        create_email_domain_block: E-Mail-Domain-Block erstellen
+        demote_user: Benutzer degradieren
+        destroy_announcement: Ankündigung löschen
+        destroy_custom_emoji: Eigene Emoji löschen
+        destroy_domain_allow: Erlaube das Löschen von Domains
+        destroy_domain_block: Domain-Blockade löschen
+        destroy_email_domain_block: E-Mail-Domain-Blockade löschen
+        destroy_status: Beitrag löschen
+        disable_2fa_user: 2FA deaktivieren
+        disable_custom_emoji: Benutzerdefiniertes Emoji deaktivieren
+        disable_user: Benutzer deaktivieren
+        enable_custom_emoji: Benutzerdefiniertes Emoji aktivieren
+        enable_user: Benutzer aktivieren
+        memorialize_account: Konto in ein Konto von einer verstorbenen Person umwandeln
+        promote_user: Benutzer befördern
+        remove_avatar_user: Profilbild entfernen
+        reopen_report: Meldung wieder eröffnen
+        reset_password_user: Passwort zurücksetzen
+        resolve_report: Bericht lösen
+        silence_account: Konto stummschalten
+        suspend_account: Konto sperren
+        unassigned_report: Berichtszuweisung entfernen
+        unsilence_account: Konto nicht mehr stummschalten
+        unsuspend_account: Konto nicht mehr sperren
+        update_announcement: Ankündigung aktualisieren
+        update_custom_emoji: Benutzerdefiniertes Emoji aktualisieren
+        update_status: Beitrag aktualisieren
       actions:
         assigned_to_self_report: "%{name} hat sich die Meldung %{target} selbst zugewiesen"
         change_email_user: "%{name} hat die E-Mail-Adresse des Nutzers %{target} geändert"
@@ -230,6 +268,9 @@ de:
         update_custom_emoji: "%{name} hat das %{target} Emoji geändert"
         update_status: "%{name} hat einen Beitrag von %{target} aktualisiert"
       deleted_status: "(gelöschter Beitrag)"
+      empty: Keine Protokolle gefunden.
+      filter_by_action: Nach Aktion filtern
+      filter_by_user: Nach Benutzer filtern
       title: Überprüfungsprotokoll
     announcements:
       destroyed_msg: Ankündigung erfolgreich gelöscht!
@@ -358,6 +399,7 @@ de:
       destroyed_msg: E-Mail-Domain-Blockade erfolgreich gelöscht
       domain: Domain
       empty: Keine E-Mail-Domains sind momentan auf der Blacklist.
+      from_html: von %{domain}
       new:
         create: Blockade erstellen
         title: Neue E-Mail-Domain-Blockade
@@ -537,6 +579,9 @@ de:
       trends:
         desc_html: Zuvor überprüfte Hashtags öffentlich anzeigen, die derzeit angesagt sind
         title: Trendende Hashtags
+    site_uploads:
+      delete: Hochgeladene Datei löschen
+      destroyed_msg: Upload erfolgreich gelöscht!
     statuses:
       back_to_account: Zurück zum Konto
       batch:
@@ -573,7 +618,6 @@ de:
     warning_presets:
       add_new: Neu hinzufügen
       delete: Löschen
-      edit: Bearbeiten
       edit_preset: Warnungsvorlage bearbeiten
       title: Warnungsvorlagen verwalten
   admin_mailer:
@@ -661,6 +705,7 @@ de:
     trouble_logging_in: Schwierigkeiten beim Anmelden?
   authorize_follow:
     already_following: Du folgst diesem Konto bereits
+    already_requested: Du hast bereits eine Anfrage zum Folgen diesen Accounts versendet
     error: Das Remote-Konto konnte nicht geladen werden
     follow: Folgen
     follow_request: 'Du hast eine Folgeanfrage gesendet an:'
@@ -849,6 +894,7 @@ de:
   media_attachments:
     validations:
       images_and_video: Es kann kein Video an einen Beitrag, der bereits Bilder enthält, angehängt werden
+      not_ready: Dateien die noch nicht bearbeitet wurden, können nicht angehängt werden. Versuche es gleich noch einmal!
       too_many: Es können nicht mehr als 4 Dateien angehängt werden
   migrations:
     acct: benutzername@domain des neuen Kontos
@@ -1070,6 +1116,8 @@ de:
     disallowed_hashtags:
       one: 'enthält einen verbotenen Hashtag: %{tags}'
       other: 'enthält verbotene Hashtags: %{tags}'
+    errors:
+      in_reply_not_found: Der Beitrag, auf den du antworten möchtest, scheint nicht zu existieren.
     language_detection: Sprache automatisch erkennen
     open_in_web: Im Web öffnen
     over_character_limit: Zeichenlimit von %{max} überschritten
diff --git a/config/locales/devise.br.yml b/config/locales/devise.br.yml
index 3fe043754..acfa884b4 100644
--- a/config/locales/devise.br.yml
+++ b/config/locales/devise.br.yml
@@ -27,7 +27,15 @@ br:
       reset_password_instructions:
         action: Cheñch ar ger-tremen
         explanation: Goulennet ho peus ur ger-tremen nevez evit ho kont.
+        title: Adderaouekaat ar ger-tremen
+      two_factor_disabled:
+        title: 2FA diweredekaet
+      two_factor_enabled:
+        title: 2FA gweredekaet
     passwords:
       updated_not_active: Kemmet eo bet ho ker-tremen ent reizh.
     registrations:
       signed_up: Donemat ! Kevreet oc'h.
+  errors:
+    messages:
+      not_found: digavet
diff --git a/config/locales/devise.fr.yml b/config/locales/devise.fr.yml
index 71c647f2b..3edd348e6 100644
--- a/config/locales/devise.fr.yml
+++ b/config/locales/devise.fr.yml
@@ -67,16 +67,16 @@ fr:
       no_token: Vous ne pouvez accéder à cette page sans passer par un courriel de réinitialisation de mot de passe. Si vous êtes passé⋅e par un courriel de ce type, assurez-vous d’utiliser l’URL complète.
       send_instructions: Vous allez recevoir les instructions de réinitialisation du mot de passe dans quelques instants. Veuillez, dans le cas où vous ne recevriez pas ce message, vérifier votre dossier d’indésirables.
       send_paranoid_instructions: Si votre adresse électronique existe dans notre base de données, vous allez recevoir un lien de réinitialisation par courriel. Veuillez, dans le cas où vous ne recevriez pas ce message, vérifier votre dossier d’indésirables.
-      updated: Votre mot de passe a été modifié avec succès, vous êtes maintenant connecté⋅e.
+      updated: Votre mot de passe a été modifié avec succès, vous êtes maintenant connecté·e.
       updated_not_active: Votre mot de passe a été modifié avec succès.
     registrations:
       destroyed: Au revoir ! Votre compte a été supprimé avec succès. Nous espérons vous revoir bientôt.
-      signed_up: Bienvenue ! Vous êtes connecté⋅e.
-      signed_up_but_inactive: Vous êtes bien enregistré⋅e. Vous ne pouvez cependant pas vous connecter car votre compte n’est pas encore activé.
-      signed_up_but_locked: Vous êtes bien enregistré⋅e. Vous ne pouvez cependant pas vous connecter car votre compte est verrouillé.
-      signed_up_but_pending: Un message avec un lien de confirmation a été envoyé à votre adresse courriel. Après avoir cliqué sur le lien, nous étudierons votre demande. Vous serez informé·e si elle a été approuvée.
+      signed_up: Bienvenue ! Vous êtes connecté·e.
+      signed_up_but_inactive: Vous êtes bien enregistré·e. Vous ne pouvez cependant pas vous connecter car votre compte n’est pas encore activé.
+      signed_up_but_locked: Vous êtes bien enregistré·e. Vous ne pouvez cependant pas vous connecter car votre compte est verrouillé.
+      signed_up_but_pending: Un message avec un lien de confirmation a été envoyé à votre adresse courriel. Après avoir cliqué sur le lien, nous examinerons votre demande. Vous serez informé·e si elle a été approuvée.
       signed_up_but_unconfirmed: Un message contenant un lien de confirmation a été envoyé à votre adresse courriel. Ouvrez ce lien pour activer votre compte. Veuillez vérifier votre dossier d'indésirables si vous ne recevez pas le courriel.
-      update_needs_confirmation: Votre compte a bien été mis à jour, mais nous devons vérifier votre nouvelle adresse courriel. Merci de vérifier vos courriels et de cliquer sur le lien de confirmation pour finaliser la validation de votre nouvelle adresse. Si vous n'avez pas reçu le courriel, vérifiez votre dossier d'indésirables.
+      update_needs_confirmation: Votre compte a bien été mis à jour, mais nous devons vérifier votre nouvelle adresse courriel. Merci de vérifier vos courriels et de cliquer sur le lien de confirmation pour finaliser la validation de votre nouvelle adresse. Si vous n'avez pas reçu le courriel, vérifiez votre dossier de spams.
       updated: Votre compte a été modifié avec succès.
     sessions:
       already_signed_out: Déconnecté·e.
@@ -85,14 +85,14 @@ fr:
     unlocks:
       send_instructions: Vous allez recevoir les instructions nécessaires au déverrouillage de votre compte dans quelques instants. Veuillez, dans le cas où vous ne recevriez pas ce message, vérifier votre dossier d’indésirables.
       send_paranoid_instructions: Si votre compte existe, vous allez bientôt recevoir un courriel contenant les instructions pour le déverrouiller. Veuillez, dans le cas où vous ne recevriez pas ce message, vérifier votre dossier d’indésirables.
-      unlocked: Votre compte a été déverrouillé avec succès, vous êtes maintenant connecté⋅e.
+      unlocked: Votre compte a été déverrouillé avec succès, vous êtes maintenant connecté·e.
   errors:
     messages:
       already_confirmed: a déjà été validée, veuillez essayer de vous connecter
       confirmation_period_expired: à confirmer dans les %{period}, merci de faire une nouvelle demande
       expired: a expiré, merci d’en faire une nouvelle demande
-      not_found: n’a pas été trouvé⋅e
-      not_locked: n’était pas verrouillé⋅e
+      not_found: n’a pas été trouvé·e
+      not_locked: n’était pas verrouillé·e
       not_saved:
-        one: 'Une erreur a empêché ce(tte) %{resource} d’être sauvegardé⋅e :'
+        one: 'Une erreur a empêché ce·tte %{resource} d’être sauvegardé·e :'
         other: "%{count} erreurs ont empêché %{resource} d’être sauvegardé⋅e :"
diff --git a/config/locales/devise.hy.yml b/config/locales/devise.hy.yml
index c40654016..666c4c996 100644
--- a/config/locales/devise.hy.yml
+++ b/config/locales/devise.hy.yml
@@ -1 +1,7 @@
+---
 hy:
+  devise:
+    confirmations:
+      confirmed: Ձեր էլփոստի հասցեն հաջողությամբ հաստատվեց։
+    sessions:
+      signed_in: Մուտքը հաջողվեց։
diff --git a/config/locales/devise.is.yml b/config/locales/devise.is.yml
index 288617be8..4d6fb3902 100644
--- a/config/locales/devise.is.yml
+++ b/config/locales/devise.is.yml
@@ -8,10 +8,10 @@ is:
     failure:
       already_authenticated: Þú ert nú þegar skráð(ur) inn.
       inactive: Aðgangur þinn hefur ekki enn verið virkjaður.
-      invalid: Ógildur %{authentication_keys} eða lykilorð.
+      invalid: Ógilt %{authentication_keys} eða lykilorð.
       last_attempt: Þú getur reynt einu sinni í viðbót áður en aðgangnum þínum verður læst.
       locked: Notandaaðgangurinn þinn er læstur.
-      not_found_in_database: Ógildur %{authentication_keys} eða lykilorð.
+      not_found_in_database: Ógilt %{authentication_keys} eða lykilorð.
       pending: Notandaaðgangurinn þinn er enn til yfirferðar.
       timeout: Setan þín er útrunnin. Skráðu þig aftur inn til að halda áfram.
       unauthenticated: Þú þarft að skrá þig inn eða nýskrá þig áður en lengra er haldið.
diff --git a/config/locales/devise.kab.yml b/config/locales/devise.kab.yml
index 650ade1e4..0149c4512 100644
--- a/config/locales/devise.kab.yml
+++ b/config/locales/devise.kab.yml
@@ -10,7 +10,7 @@ kab:
       inactive: Amiḍan-inek mazal ur yermed ara.
       invalid: Tella tuccḍa deg %{authentication_keys} neγ deg wawal uffir.
       last_attempt: Γur-k yiwen n uɛraḍ-nniḍen kan send ad yettucekkel umiḍan-ik.
-      locked: Amiḍan-ik yewḥel.
+      locked: Amiḍan-ik yettwargel.
       not_found_in_database: Tella tuccḍa deg %{authentication_keys} neγ deg wawal uffir.
       pending: Amiḍan-inek mazal-it deg ɛiwed n tmuγli.
       timeout: Tiγimit n tuqqna tezri. Ma ulac aγilif ɛiwed tuqqna akken ad tkemmleḍ.
@@ -22,10 +22,11 @@ kab:
         action_with_app: Wekked sakkin uγal γer %{app}
         explanation: Aqla-k terniḍ amiḍan deg %{host} s tansa imayl-agi. Mazal-ak yiwen utekki akken ad t-tremdeḍ. Ma mačči d kečč i yessutren ay-agi, ttxil-k ssinef izen-a.
         explanation_when_pending: Tsutreḍ-d ajerred deg %{host} s tansa-agi imayl. Ad nγeṛ asuter-ik ticki tsentmeḍ tansa-ik imayl. Send asentem, ur tezmireḍ ara ad teqqneḍ γer umiḍan-ik. Ma yella nugi asuter-ik, isefka-ik ad ttwakksen seg uqeddac, ihi ulac tigawt-nniḍen ara k-d-yettuqeblen. Ma mačči d kečč i yellan deffir n usuter-agi, ttxil-k ssinef izen-agi.
-        extra_html: Ttxil-k ẓer daγen <a href="%{terms_path}">ilugan n uqeddac</a> akked <a href="%{policy_path}">twetlin n useqdec</a>.
+        extra_html: Ttxil-k ẓer daγen <a href="%{terms_path}">ilugan n uqeddac</a> akked <a href="%{policy_path}">twetlin n useqdec-nneγ</a>.
         subject: 'Maṣṭudun: Asentem n ujerred deg uqeddac %{instance}'
         title: Senqed tansa-inek imayl
       email_changed:
+        explanation: 'Tansa n yimayl n umiḍan-ik ibeddel ɣer:'
         extra: Ma mačči d kečč i ibeddlen tansa imayl, ihi yezmer d alebɛaḍ i ikecmen γer umiḍan-ik. Ttxil-k beddel awal-ik uffir tura neγ siwel i unedbal n uqeddac ma tḥesleḍ berra n umiḍan-ik.
         subject: 'Maṣṭudun: Imayl-ik yettubeddel'
         title: Tansa imayl tamaynut
@@ -42,6 +43,10 @@ kab:
         action: Beddel awal uffir
         explanation: Tessutreḍ awal uffir amaynut i umiḍan-ik.
         title: Aɛiwed n wawal uffir
+      two_factor_disabled:
+        title: Asesteb s snat n tarrayin insa
+      two_factor_enabled:
+        title: Asesteb s snat n tarrayin irmed
     passwords:
       send_paranoid_instructions: Ma nufa tansa-inek imayl tella deg uzadur-nneγ n yisefka, ad n-teṭṭfeḍ izen deg kra n tesdatin, deg-s assaγ i uɛawed n wawal uffir. Ma ur k-in-yewwiḍ ara yizen, ttxil-k ẓer deg ukaram spam.
       updated: Awal-ik uffir yettwabeddel mebla ugur. Aqla-k tura tjerrḍeḍ.
diff --git a/config/locales/devise.nn.yml b/config/locales/devise.nn.yml
index d578b8dc5..42eb0690a 100644
--- a/config/locales/devise.nn.yml
+++ b/config/locales/devise.nn.yml
@@ -2,7 +2,7 @@
 nn:
   devise:
     confirmations:
-      confirmed: E-posten din er stadefesta.
+      confirmed: E-posten din er stadfesta.
       send_instructions: Om nokre få minutt får du ein e-post som fortel deg korleis du skal stadfesta e-postadressa di. Sjekk søppelpostmappa di om du ikkje fekk e-posten.
       send_paranoid_instructions: Om vi har e-postadressa di i databasen vår, får du ein e-post som fortel deg korleis du skal stadfesta e-postadressa om nokre få minutt. Ver venleg og sjekk søppelpostmappa di om du ikkje fekk denne e-posten.
     failure:
@@ -12,21 +12,22 @@ nn:
       last_attempt: Du har eitt forsøk igjen før kontoen din vert låst.
       locked: Kontoen din er låst.
       not_found_in_database: Ugyldig %{authentication_keys} eller passord.
-      pending: Kontoen din er fortsatt under gjennomgang.
-      timeout: Økten din løp ut på tid. Logg inn på nytt for å fortsette.
-      unauthenticated: Du må logge inn eller registrere deg før du kan fortsette.
+      pending: Kontoen din er vert gjennomgått enno.
+      timeout: Økta di er utgått. Logg inn omatt for å halde fram.
+      unauthenticated: Du må logge inn eller registere deg før du kan halde fram.
       unconfirmed: Du må stadfesta e-postadressa di før du kan gå vidare.
     mailer:
       confirmation_instructions:
         action: Stadfest e-postadresse
         action_with_app: Stadfest og gå tilbake til %{app}
-        explanation: Du har laget en konto på %{host} med denne e-postadressen. Du er ett klikk unna å aktivere den. Hvis dette ikke var deg, vennligst se bort fra denne e-posten.
-        extra_html: Vennligst også sjekk ut <a href="%{terms_path}">instansens regler </a> og <a href="%{policy_path}">våre bruksvilkår</a>.
-        subject: 'Mastodon: Instruksjoner for å bekrefte e-postadresse %{instance}'
+        explanation: Du har registrert deg på %{host} med denne e-postadressa. Du er eitt klikk unna aktivere kontoen. Om det ikkje var deg, berre oversjå denne e-posten.
+        explanation_when_pending: Du har søkt om en invitasjon til %{host} med denne e-postadressa. Når du har stadfesta e-postadressa di, vil vi gå gjennom søknaden. Du kan logge på for å endre detaljar eller slette kontoen, men du har ikke tilgang til dei fleste funksjonane før kontoen din er godkjent. Dersom søknaden din vert avslått, vil dataene dine verte sletta, så du treng ikkje gjera meir. Dersom dette ikke var deg, berre oversjå denne e-posten.
+        extra_html: Ta ein kikk på <a href="%{terms_path}">reglane på instansen</a> og <a href="%{policy_path}">bruksvilkåra våre</a>.
+        subject: 'Mastodon: Instruksjonar for stadfesting hos %{instance}'
         title: Stadfest e-postadresse
       email_changed:
         explanation: 'E-postadressa til kontoen din vert endra til:'
-        extra: Hvis du ikke endret din e-postadresse, er det sannsynlig at noen har fått tilgang til din konto. Vennligst endre ditt passord umiddelbart eller kontakt instansens administrator dersom du er utestengt fra kontoen din.
+        extra: Dersom du ikkje har endra e-postadressa di, er det truleg at nokon har fått tilgang til kontoen din. Bytt straks passordet ditt, eller kontakt tenaradministratoren dersom du har vorte låst ut av kontoen.
         subject: 'Mastodon: E-postadressa er endra'
         title: Ny e-postadresse
       password_change:
@@ -36,8 +37,8 @@ nn:
         title: Passord endra
       reconfirmation_instructions:
         explanation: Stadfest den nye adressa for å byta e-postadressa di.
-        extra: Se bort fra denne e-posten dersom du ikke gjorde denne endringen. E-postadressen for Mastadon-kontoen blir ikke endret før du trykker på lenken over.
-        subject: 'Mastodon: Bekreft e-postadresse for %{instance}'
+        extra: Oversjå denne eposten dersom du ikkje gjorde endra. E-postadressa for Mastodon-kontoen vert ikkje endra før lenka over vert trykt på.
+        subject: 'Mastodon: Stadfest e-post for %{instance}'
         title: Stadfest e-postadresse
       reset_password_instructions:
         action: Endr passord
@@ -46,22 +47,25 @@ nn:
         subject: 'Mastodon: Instuksjonar for å endra passord'
         title: Attstilling av passord
       two_factor_disabled:
-        subject: 'Mastodon: To-faktor autentisering deaktivert'
+        explanation: To-faktor-autentisering har vorte slått av for kontoen din. Det går no an logge inn med berre e-postadresse og passord.
+        subject: 'Mastodon: To-faktor-autentisering deaktivert'
         title: 2FA deaktivert
       two_factor_enabled:
-        explanation: To-faktor autentisering er aktivert for kontoen din. Et symbol som er generert av den sammenkoblede TOTP-appen vil være påkrevd for innlogging.
-        subject: 'Mastodon: To-faktor autentisering aktivert'
+        explanation: To-faktor-autentisering har vorte slått på for kontoen din. Ein kode frå den samankopla TOTP-appen er kravd for å logge inn.
+        subject: 'Mastodon: To-faktor-autentisering aktivert'
         title: 2FA aktivert
       two_factor_recovery_codes_changed:
-        explanation: De forrige gjenopprettingskodene er ugyldig og nye generert.
+        explanation: Dei førre gjenopprettingskodane er ugyldige og nye er genererte.
+        subject: 'Mastodon: To-faktor-gjenopprettingskodar har vorte genererte på nytt'
+        title: 2FA-gjenopprettingskodane er endra
       unlock_instructions:
-        subject: 'Mastodon: Instruksjoner for å gjenåpne konto'
+        subject: 'Mastodon: Instruksjonar for å opne kontoen igjen'
     omniauth_callbacks:
-      failure: Kunne ikke autentisere deg fra %{kind} fordi "%{reason}".
-      success: Vellykket autentisering fra %{kind}.
+      failure: Du kunne ikkje verte autentisert frå %{kind} av di "%{reason}".
+      success: Autentisert frå %{kind}-konto.
     passwords:
-      no_token: Du har ingen tilgang til denne siden hvis ikke klikket på en e-post om nullstilling av passord. Hvis du kommer fra en sådan bør du dobbelsjekke at du limte inn hele URLen.
-      send_instructions: Du vil motta en e-post med instruksjoner om nullstilling av passord om noen få minutter.
+      no_token: Du har ikkje tilgang til denne sida utan ha gått via ein e-post som gjeld å nullstille passordet. Dersom det er kva du har gjort, dobbelsjekk at du har kopiert heile URLen.
+      send_instructions: Om vi har e-postadressa di i databasen vår, får du ein e-post med lenke til gjenopprette passordet om nokre få minutt. Sjekk søppelpostmappa di om du ikkje fekk denne e-posten.
       send_paranoid_instructions: Om vi har e-postadressa di i databasen vår, får du ei lenkje til å endra passordet om nokre få minutt. Ver venleg og sjekk søppelpostmappa om du ikkje fekk denne e-posten.
       updated: Passordet ditt er endra. No er du logga inn.
       updated_not_active: Passordet ditt er endra.
@@ -71,24 +75,24 @@ nn:
       signed_up_but_inactive: Du har registrert deg inn, men vi kunne ikkje logga deg inn fordi kontoen din er ikkje aktivert enno.
       signed_up_but_locked: Du har registrert deg inn, men vi kunne ikkje logga deg inn fordi kontoen din er låst.
       signed_up_but_pending: Ei melding med ei stadfestingslenkje er vorten send til e-postadressa di. Når du klikkar på lenkja skal vi sjå gjennom søknaden din. Du får ei melding om han vert godkjend.
-      signed_up_but_unconfirmed: En e-post med en bekreftelseslenke har blitt sendt til din innboks. Klikk på lenken i e-posten for å aktivere kontoen din.
-      update_needs_confirmation: Du har oppdatert kontoen din, men vi må bekrefte din nye e-postadresse. Sjekk e-posten din og følg bekreftelseslenken for å bekrefte din nye e-postadresse.
-      updated: Kontoen din ble oppdatert.
+      signed_up_but_unconfirmed: Ei melding med ei lenke for å stadfeste kontoen har vorte sendt e-postadressa di. Klikk på lenka for å aktivere kontoen. Sjekk søppelpostmappa dersom du ikkje har fått e-posten.
+      update_needs_confirmation: Du har oppdatert kontoen din, men vi må stadfeste den nye e-postadressa. Sjekk innboksen og følg lenka for å stadfeste adressa di. Sjekk søppelpostmappa dersom du ikkje har fått den e-posten.
+      updated: Kontoen har vorte oppdatert.
     sessions:
       already_signed_out: Logga ut.
       signed_in: Logga inn.
       signed_out: Logga ut.
     unlocks:
-      send_instructions: Du vil motta en e-post med instruksjoner for å åpne kontoen din om noen få minutter.
-      send_paranoid_instructions: Hvis kontoen din eksisterer vil du motta en e-post med instruksjoner for å åpne kontoen din om noen få minutter.
-      unlocked: Kontoen din ble åpnet uten problemer. Logg på for å fortsette.
+      send_instructions: Om nokre minutt får du ein e-post med instruksjonar for korleis du kan låse opp kontoen din. Sjekk søppelpostmappa om du ikkje finn den mailen.
+      send_paranoid_instructions: Dersom du har konto her, får du ein e-post med instruksjonar for korleis du kan låse opp kontoen din om nokre minutt. Sjekk søppelpostmappa om du ikkje finn den mailen.
+      unlocked: Kontoen din har vorte låst opp. Logg inn for å halde fram.
   errors:
     messages:
-      already_confirmed: har allerede blitt bekreftet, prøv å logge på istedet
-      confirmation_period_expired: må bekreftes innen %{period}. Spør om en ny e-post for bekreftelse istedet
+      already_confirmed: er allereie stadfesta, prøv logge inn
+      confirmation_period_expired: må verte stadfesta innan %{period}, spør etter ein ny
       expired: er utgått, ver venleg å beda om ein ny ein
       not_found: ikkje funne
       not_locked: var ikkje låst
       not_saved:
-        one: '1 feil hindret denne %{resource} i å bli lagret:'
-        other: "%{count} feil hindret denne %{resource} i å bli lagret:"
+        one: '1 feil hindra %{resource} frå verte lagra:'
+        other: "%{count} feil hindra %{resource} frå verte lagra:"
diff --git a/config/locales/devise.pt-BR.yml b/config/locales/devise.pt-BR.yml
index 92ac2948e..5f46a4ba1 100644
--- a/config/locales/devise.pt-BR.yml
+++ b/config/locales/devise.pt-BR.yml
@@ -3,96 +3,96 @@ pt-BR:
   devise:
     confirmations:
       confirmed: O seu endereço de e-mail foi confirmado.
-      send_instructions: Você receberá uma mensagem em sua caixa de entrada com instruções sobre como confirmar o seu endereço de e-mail dentro de alguns minutos. Por favor, cheque a sua pasta de spam caso não tenha recebido esta mensagem.
-      send_paranoid_instructions: Se o seu endereço de e-mail já existir em nossa base de dados, você receberá uma mensagem em sua caixa de entrada com instruções sobre confirmá-lo dentro de alguns minutos. Por favor, cheque a sua pasta de spam caso não tenha recebido esta mensagem.
+      send_instructions: Você receberá um e-mail com instruções sobre como confirmar o endereço de e-mail dentro de alguns minutos. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
+      send_paranoid_instructions: Se o seu endereço de e-mail já existir em nosso banco de dados, você receberá um e-mail com instruções para confirmá-lo dentro de alguns minutos. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
     failure:
-      already_authenticated: A sua sessão já está aberta.
-      inactive: A sua contra ainda não está ativada.
+      already_authenticated: Você entrou na sua conta.
+      inactive: Sua conta não foi confirmada ainda.
       invalid: "%{authentication_keys} ou senha inválida."
       last_attempt: Você tem apenas mais uma tentativa sobrando antes que a sua conta seja bloqueada.
-      locked: A sua conta está bloqueada.
+      locked: Sua conta está bloqueada.
       not_found_in_database: "%{authentication_keys} ou senha inválida."
-      pending: Sua conta ainda está sendo revisada.
-      timeout: A sua sessão expirou. Por favor, entre novamente para continuar.
-      unauthenticated: Você precisa entrar ou cadastrar-se antes de continuar.
+      pending: Sua conta está sendo revisada.
+      timeout: Você saiu de sua conta. Por favor, entre novamente para continuar.
+      unauthenticated: Você precisa entrar ou criar uma conta antes de continuar.
       unconfirmed: Você precisa confirmar o seu endereço de e-mail antes de continuar.
     mailer:
       confirmation_instructions:
-        action: Verificar endereço de e-mail
+        action: Confirmar endereço de e-mail
         action_with_app: Confirmar e voltar para %{app}
-        explanation: Você criou uma conta em %{host} com esse endereço de e-mail. Você está a um clique de ativá-la. Se não foi você, por favor ignore esse e-mail.
-        explanation_when_pending: Você pediu um convite para %{host} com esse endereço de email. Assim que você confirmar o seu endereço de e-mail, iremos revisar o seu pedido. Você não poderá fazer login até então. Se sua aplicação for rejeitada, seus dados serão removidos e nenhuma ação será necessária da sua parte. Se você não pediu por isso, por favor ignore esse e-mail.
+        explanation: Você criou uma conta em %{host} com esse endereço de e-mail. Se não foi você, por favor, ignore este e-mail.
+        explanation_when_pending: Você solicitou um convite para %{host} com esse endereço de e-mail. Após você confirmar o seu endereço de e-mail, espere o resultado da revisão de sua solicitação. Se sua conta por vetada, seus dados serão excluídos e nenhuma ação será necessária de sua parte. Se você não solicitou nada, por favor, ignore este e-mail.
         extra_html: Por favor confira também <a href="%{terms_path}">as regras da instância</a> e <a href="%{policy_path}">nossos termos de serviço</a>.
         subject: 'Mastodon: Instruções de confirmação para %{instance}'
-        title: Verifique o endereço de e-mail
+        title: Confirme o endereço de e-mail
       email_changed:
-        explanation: 'O e-mail associado à sua conta será mudado para:'
-        extra: Se você não mudou seu e-mail é possível que alguém tenha conseguido acesso à sua conta. Por favor mude sua senha imediatamente ou entre em contato com um administrador da sua instância se você ficou sem acesso à sua conta.
-        subject: 'Mastodon: Email alterado'
+        explanation: 'O e-mail vinculado à sua conta será alterado para:'
+        extra: Se você não alterou seu e-mail, é possível que alguém tenha acessado a sua conta. Altere sua senha imediatamente ou entre em contato com o administrador da sua instância se você perdeu o acesso à sua conta.
+        subject: 'Mastodon: Endereço de e-mail alterado'
         title: Novo endereço de e-mail
       password_change:
-        explanation: A senha da sua conta foi mudada.
-        extra: Se você não mudou a sua senha, é possível que alguém tenha conseguido acesso à sua conta. Por favor mude sua senha imediatamente ou entre em contato com um administrador da sua instância se você ficou sem acesso à sua conta.
-        subject: 'Mastodon: Senha modificada'
+        explanation: A senha da sua conta foi alterada.
+        extra: Se você não alterou sua senha, é possível que alguém tenha acessado a sua conta. Altere sua senha imediatamente ou entre em contato com o administrador da sua instância se você perdeu o acesso à sua conta.
+        subject: 'Mastodon: Senha alterada'
         title: Senha alterada
       reconfirmation_instructions:
-        explanation: Confirme o seu novo endereço para mudar seu e-mail.
-        extra: Se essa mudança não foi iniciada por você, por favor ignore esse e-mail. O endereço de e-mail para essa conta do Mastodon não irá mudar até que você acesse o link acima.
-        subject: 'Mastodon: Confirmar emai para %{instance}'
-        title: Verificar o endereço de e-mail
+        explanation: Confirme seu novo endereço para alterar seu e-mail.
+        extra: Se essa alteração não foi feita por você, por favor, ignore este e-mail. O endereço de e-mail para essa conta do Mastodon não será alterado até que você entre no link acima.
+        subject: 'Mastodon: Confirmar endereço de e-mail para %{instance}'
+        title: Confirmar endereço de e-mail
       reset_password_instructions:
-        action: Mudar a senha
-        explanation: Você pediu uma nova senha para sua conta.
-        extra: Se você não fez esse pedido, por favor ignore esse e-mail. Sua senha não irá mudar até que você acesse o link acima e crie uma nova.
-        subject: 'Mastodon: Instruções para mudança de senha'
-        title: Redefinir a senha
+        action: Alterar senha
+        explanation: Você solicitou uma nova senha para sua conta.
+        extra: Se você não solicitou nada, por favor, ignore este e-mail. Sua senha não será alterada até que você entre no link acima e crie uma nova.
+        subject: 'Mastodon: Instruções para alterar senha'
+        title: Redefinir senha
       two_factor_disabled:
         explanation: A autenticação de dois fatores para sua conta foi desativada. Agora é possível acessar apenas com seu endereço de e-mail e senha.
         subject: 'Mastodon: Autenticação de dois fatores desativada'
         title: 2FA desativada
       two_factor_enabled:
-        explanation: A autenticação de dois fatores foi habilitada para sua conta. Um token gerado pelo app TOTP pareado será necessário para o login.
+        explanation: A autenticação de dois fatores foi ativada para sua conta. Um código gerado no aplicativo TOTP pareado será necessário para entrar.
         subject: 'Mastodon: Autenticação de dois fatores desativada'
         title: 2FA ativada
       two_factor_recovery_codes_changed:
         explanation: Os códigos de recuperação anteriores foram invalidados e novos códigos foram gerados.
-        subject: 'Mastodon: códigos de recuperação de dois fatores gerados novamente'
-        title: Códigos de recuperação de 2FA alterados
+        subject: 'Mastodon: Novos códigos de recuperação de dois fatores'
+        title: Códigos de recuperação de dois fatores alterados
       unlock_instructions:
         subject: 'Mastodon: Instruções de desbloqueio'
     omniauth_callbacks:
-      failure: Não foi possível autenticá-lo como %{kind} porque "%{reason}".
-      success: Autenticado com sucesso como %{kind}.
+      failure: Não foi possível entrar como %{kind} porque "%{reason}".
+      success: Entrou como %{kind}.
     passwords:
-      no_token: Você não pode acessar esta página se não tiver vindo de uma mensagem de mudança de senha. Se este for o caso, por favor verifique se a URL utilizada está completa.
-      send_instructions: Se o seu endereço de e-mail já estiver cadastrado em nossa base de dados, você receberá uma mensagem com um link para realizar a mudança de senha em alguns minutos. Por favor, cheque a sua pasta de spam caso não tenha recebido esta mensagem.
-      send_paranoid_instructions: Se o seu endereço de e-mail já estiver cadastrado em nossa base de dados, você receberá uma mensagem com um link para realizar a mudança de senha em alguns minutos. Por favor, cheque a sua pasta de spam caso não tenha recebido esta mensagem.
-      updated: A sua senha foi alterada. A sua sessão está aberta.
-      updated_not_active: A sua senha foi alterada.
+      no_token: Você não pode acessar esta página sem vir de um e-mail de alteração de senha. Se este for o caso, por favor, verifique se o link fornecido está completo.
+      send_instructions: Se o seu endereço de e-mail já existir em nosso banco de dados, você receberá um e-mail com instruções para alterar a senha dentro de alguns minutos. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
+      send_paranoid_instructions: Se o seu endereço de e-mail já existir em nosso banco de dados, você receberá um e-mail com instruções para alterar a senha dentro de alguns minutos. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
+      updated: Sua senha foi alterada e você entrou na sua conta.
+      updated_not_active: Sua senha foi alterada com sucesso.
     registrations:
-      destroyed: Adeus! A sua conta foi cancelada. Esperamos vê-lo em breve.
-      signed_up: Bem vindo! A sua conta foi registrada com sucesso.
-      signed_up_but_inactive: A sua conta foi registrada. No entanto, não abrimos a sua sessão porque a sua conta ainda não foi ativada.
-      signed_up_but_locked: A sua conta foi registrada. No entanto, não abrimos a sua sessão porque a sua conta está bloqueada.
-      signed_up_but_pending: Uma mensagem com um link de confirmação foi enviada ao seu endereço de e-mail. Depois que você clicar no link, revisaremos seu pedido. Você será notificado se seu pedido for aprovado.
-      signed_up_but_unconfirmed: Uma mensagem com um link de confirmação foi enviada para o seu endereço de e-mail. Por favor, siga o link para ativar a sua conta e, caso não tenha recebido esta mensagem, cheque a sua pasta de spam.
-      update_needs_confirmation: Você mudou o seu endereço de e-mail ou a sua senha, mas é necessário confirmar a mudança. Por favor siga o link que foi enviado para o seu novo endereço de e-mail e, caso não tenha recebido esta mensagem, cheque a sua pasta de spam.
-      updated: A sua conta foi alterada com sucesso.
+      destroyed: Adeus! Sua conta foi cancelada. Talvez um dia possamos nos ver de novo.
+      signed_up: Boas vindas! Conta criada.
+      signed_up_but_inactive: Conta criada! Agora você deve confirmá-la.
+      signed_up_but_locked: Conta criada! Porém, você deve desbloqueá-la.
+      signed_up_but_pending: Um e-mail com um link de confirmação foi enviado para o seu endereço de e-mail. Após você entrar no link, revisaremos sua solicitação e você será notificado caso seja aprovado.
+      signed_up_but_unconfirmed: Um e-mail com instruções para confirmar o seu endereço de e-mail foi enviado. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
+      update_needs_confirmation: Você alterou seu endereço de e-mail ou sua senha, porém é preciso confirmar a alteração. Por favor, entre no link que foi enviado para o seu novo endereço de e-mail e verifique sua pasta de spam caso ainda não o tenha recebido.
+      updated: Sua conta foi alterada com sucesso.
     sessions:
-      already_signed_out: Sessão encerrada.
-      signed_in: Sessão iniciada.
-      signed_out: Sessão encerrada.
+      already_signed_out: Você saiu de sua conta.
+      signed_in: Você entrou na sua conta.
+      signed_out: Você saiu de sua conta.
     unlocks:
-      send_instructions: Você receberá uma mensagem com instruções para desbloquear a sua conta em alguns instantes. Por favor, cheque a sua pasta de spam caso não tenha recebido esta mensagem.
-      send_paranoid_instructions: Se a sua conta já existe, você receberá uma mensagem com instruções para desbloquear a sua conta em alguns instantes. Por favor, cheque a sua pasta de spam caso não tenha recebido esta mensagem.
-      unlocked: A sua conta foi desbloqueada com sucesso. Por favor inicie sessão para continuar.
+      send_instructions: Você receberá um e-mail com instruções para desbloquear a sua conta dentro de alguns minutos. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
+      send_paranoid_instructions: Se a sua conta já existe, você receberá um e-mail com instruções para desbloqueá-la dentro de alguns minutos. Por favor, verifique sua pasta de spam caso ainda não o tenha recebido.
+      unlocked: Sua conta foi desbloqueada. Por favor, entre na sua conta para continuar.
   errors:
     messages:
-      already_confirmed: já foi confirmado, por favor tente iniciar sessão
+      already_confirmed: confirmado, agora tente entrar na sua conta
       confirmation_period_expired: precisa ser confirmada em até %{period}, por favor, solicite novo link de confirmação
       expired: expirou, por favor solicite uma nova
       not_found: não encontrado
-      not_locked: não está bloqueada
+      not_locked: Sua conta não está bloqueada.
       not_saved:
         one: '1 erro impediu este %{resource} de ser salvo(a):'
         other: "%{count} erros impediram este %{resource} de ser salvo(a):"
diff --git a/config/locales/devise.pt-PT.yml b/config/locales/devise.pt-PT.yml
index 9689b01f5..c6cfe0c37 100644
--- a/config/locales/devise.pt-PT.yml
+++ b/config/locales/devise.pt-PT.yml
@@ -27,12 +27,12 @@ pt-PT:
         title: Verificar o endereço de e-mail
       email_changed:
         explanation: 'O e-mail associado à tua conta será alterado para:'
-        extra: Se não alteraste o teu e-mail é possível que alguém tenha conseguido aceder à tua conta. Por favor muda a tua palavra-passe imediatamente ou entra em contato com um administrador do servidor se ficaste sem acesso à tua conta.
+        extra: Se não alterou o seu email, é possível que alguém tenha conseguido aceder à sua conta. Por favor altere a sua palavra-passe imediatamente ou entra em contacto com um administrador do servidor se tiver ficado sem acesso à sua conta.
         subject: 'Mastodon: Email alterado'
         title: Novo endereço de e-mail
       password_change:
         explanation: A palavra-passe da tua conta foi alterada.
-        extra: Se não alteraste a tua palavra-passe, é possível que alguém tenha conseguido aceder à tua conta. Por favor muda a tua palavra-passe imediatamente ou entra em contato com um administrador do servidor se ficaste sem acesso à tua conta.
+        extra: Se não alterou a sua palavra-passe, é possível que alguém tenha conseguido aceder à sua conta. Por favor altere a sua palavra-passe imediatamente ou entre em contacto com um administrador do servidor se tiver ficado sem acesso à sua conta.
         subject: 'Mastodon: Nova palavra-passe'
         title: Palavra-passe alterada
       reconfirmation_instructions:
diff --git a/config/locales/devise.ru.yml b/config/locales/devise.ru.yml
index 5d7e33422..52b229ca0 100644
--- a/config/locales/devise.ru.yml
+++ b/config/locales/devise.ru.yml
@@ -18,7 +18,7 @@ ru:
       unconfirmed: Вам необходимо подтвердить ваш адрес e-mail для продолжения.
     mailer:
       confirmation_instructions:
-        action: Подтвердите e-mail адрес
+        action: Подтвердить смену e-mail
         action_with_app: Подтвердить и вернуться в %{app}
         explanation: Вы создали учётную запись на сайте %{host}, используя этот e-mail адрес. Остался лишь один шаг для активации. Если это были не вы, просто игнорируйте письмо.
         explanation_when_pending: Вы подали заявку на %{host}, используя этот адрес e-mail. Как только вы его подтвердите, мы начнём изучать вашу заявку. До тех пор вы не сможете войти на сайт. Если ваша заявка будет отклонена, все данные будут автоматически удалены, от вас не потребуется никаких дополнительных действий. Если это были не вы, пожалуйста, проигнорируйте данное письмо.
@@ -28,7 +28,7 @@ ru:
       email_changed:
         explanation: 'E-mail адрес вашей учётной записи будет изменён на:'
         extra: Если вы не меняли e-mail адрес, возможно кто-то получил доступ к вашей учётной записи. Пожалуйста, немедленно смените пароль или свяжитесь с администратором узла, если вы уже потеряли доступ к ней.
-        subject: 'Mastodon: изменён e-mail адрес'
+        subject: 'Mastodon: Изменён e-mail адрес'
         title: Новый адрес e-mail
       password_change:
         explanation: Пароль Вашей учётной записи был изменён.
@@ -36,28 +36,28 @@ ru:
         subject: 'Mastodon: Пароль изменен'
         title: Пароль изменён
       reconfirmation_instructions:
-        explanation: Подтвердите новый адрес для смены e-mail.
-        extra: Если смену e-mail инициировали не вы, пожалуйста, игнорируйте это письмо. Адрес e-mail для учётной записи Mastodon не будет изменён, пока вы не перейдёте по ссылке выше.
-        subject: 'Mastodon: Подтверждение e-mail для узла %{instance}'
+        explanation: Для завершения смены e-mail, нажмите кнопку ниже.
+        extra: Если вы не изменяли e-mail, пожалуйста, игнорируйте это письмо. Новый адрес не будет привязан к учётной записи, пока вы не перейдёте по ссылке ниже.
+        subject: 'Mastodon: Подтвердите свой новый e-mail на %{instance}'
         title: Подтвердите e-mail адрес
       reset_password_instructions:
         action: Смена пароля
         explanation: Вы запросили новый пароль для вашей учётной записи.
         extra: Если это сделали не вы, пожалуйста, игнорируйте письмо. Ваш пароль не будет изменён, пока вы не перейдёте по ссылке выше и не создадите новый пароль.
-        subject: 'Mastodon: инструкция по смене пароля'
+        subject: 'Mastodon: Инструкция по сбросу пароля'
         title: Сброс пароля
       two_factor_disabled:
         explanation: Для вашей учётной записи была отключена двухфакторная авторизация. Выполнить вход теперь можно используя лишь e-mail и пароль.
-        subject: 'Mastodon: двухфакторная авторизация отключена'
-        title: Двухфакторная авторизация отключена
+        subject: 'Mastodon: Двухфакторная авторизация отключена'
+        title: 2ФА отключена
       two_factor_enabled:
         explanation: Для вашей учётной записи была настроена двухфакторная авторизация. Отныне для входа потребуется также временный код из приложения-аутентификатора.
-        subject: 'Mastodon: настроена двухфакторная авторизация'
-        title: Двухфакторная авторизация включена
+        subject: 'Mastodon: Настроена двухфакторная авторизация'
+        title: 2ФА включена
       two_factor_recovery_codes_changed:
         explanation: Предыдущие резервные коды были аннулированы и созданы новые.
-        subject: 'Mastodon: резервные коды двуфакторной авторизации обновлены'
-        title: Резервные коды двухфакторной авторизации изменены
+        subject: 'Mastodon: Резервные коды двуфакторной авторизации обновлены'
+        title: Резервные коды 2ФА изменены
       unlock_instructions:
         subject: 'Mastodon: Инструкция по разблокировке'
     omniauth_callbacks:
diff --git a/config/locales/devise.zh-HK.yml b/config/locales/devise.zh-HK.yml
index ceae8b238..e1bb9f959 100644
--- a/config/locales/devise.zh-HK.yml
+++ b/config/locales/devise.zh-HK.yml
@@ -12,13 +12,16 @@ zh-HK:
       last_attempt: 若你再一次嘗試失敗,我們將鎖定你的帳號,以策安全。
       locked: 你的帳號已被鎖定。
       not_found_in_database: 不正確的 %{authentication_keys} 或密碼。
+      pending: 您的帳戶仍在審核中。
       timeout: 你的登入階段已經過期,請重新登入以繼續使用。
       unauthenticated: 你必須先登入或登記,以繼續使用。
       unconfirmed: 你必須先確認電郵地址,繼續使用。
     mailer:
       confirmation_instructions:
         action: 驗證電子郵件地址
+        action_with_app: 確認並返回 %{app}
         explanation: 你在 %{host} 上使用這個電子郵件地址建立了一個帳戶。只需點擊下面的連結,即可啟用帳戶。如果你並沒有建立過帳戶,請忽略此郵件。
+        explanation_when_pending: 您使用此電子信箱位址申請了 %{host} 的邀請。當您確認電子信箱後我們將審核您的申請,而直到核准前您都無法登入。當您的申請遭拒絕,您的資料將被移除而不必做後續動作。如果這不是您,請忽略此信件。
         extra_html: 請記得閱讀本服務站的<a href="%{terms_path}">相關規定</a>和<a href="%{policy_path}">使用條款</a>。
         subject: 'Mastodon: 確認電郵地址 %{instance}'
         title: 驗證電子郵件地址
@@ -43,6 +46,18 @@ zh-HK:
         extra: 如果你沒有請求本次變更,請忽略此郵件。你的密碼只有在你點擊上面的連結並輸入新密碼後才會更改。
         subject: 'Mastodon: 重設密碼'
         title: 重設密碼
+      two_factor_disabled:
+        explanation: 您帳戶的兩步驟驗證已停用。現在只能使用電子信箱位址及密碼登入。
+        subject: Mastodon:已停用兩步驟驗證
+        title: 已停用 2FA
+      two_factor_enabled:
+        explanation: 已對您的帳戶啟用兩步驟驗證。登入時將需要配對之 TOTP 應用程式所產生的 Token。
+        subject: Mastodon:已啟用兩步驟驗證
+        title: 已啟用 2FA
+      two_factor_recovery_codes_changed:
+        explanation: 上一次的復原碼已經失效,且已產生新的。
+        subject: Mastodon:兩步驟驗證復原碼已經重新產生
+        title: 2FA 復原碼已變更
       unlock_instructions:
         subject: 'Mastodon: 解除用戶鎖定'
     omniauth_callbacks:
@@ -59,6 +74,7 @@ zh-HK:
       signed_up: 歡迎你!你的登記已經成功。
       signed_up_but_inactive: 你的登記已經成功,可是由於你的用戶還被被啟用,暫時還不能讓你登入。
       signed_up_but_locked: 你的登記已經成功,可是由於你的用戶已被鎖定,我們無法讓你登入。
+      signed_up_but_pending: 包含確認連結的訊息已寄到您的電子信箱。按下此連結後我們將審核您的申請。核准後將通知您。
       signed_up_but_unconfirmed: 一條確認連結已經電郵到你的郵址。請使用讓連結啟用你的用戶。
       update_needs_confirmation: 你的用戶已經更新,但我們需要確認你的電郵地址。請打開你的郵箱,使用確認電郵的連結來確認的地郵址。
       updated: 你的用戶已經成功更新。
diff --git a/config/locales/doorkeeper.br.yml b/config/locales/doorkeeper.br.yml
index c7677c850..a9b8d5b90 100644
--- a/config/locales/doorkeeper.br.yml
+++ b/config/locales/doorkeeper.br.yml
@@ -1 +1,52 @@
+---
 br:
+  activerecord:
+    attributes:
+      doorkeeper/application:
+        name: Anv an arload
+        website: Lec'hienn an arload
+  doorkeeper:
+    applications:
+      buttons:
+        authorize: Aotren
+        cancel: Nullañ
+        destroy: Distrujañ
+        edit: Aozañ
+      confirmations:
+        destroy: Ha sur oc'h ?
+      index:
+        application: Arload
+        delete: Dilemel
+        name: Anv
+        new: Arload nevez
+        show: Diskouez
+        title: Hoc'h arloadoù
+      new:
+        title: Arload nevez
+      show:
+        title: 'Arload : %{name}'
+    authorizations:
+      buttons:
+        authorize: Aotren
+    authorized_applications:
+      confirmations:
+        revoke: Ha sur oc'h ?
+      index:
+        application: Arload
+        date_format: "%d-%m-%Y %H:%M:%S"
+    flash:
+      applications:
+        create:
+          notice: Savet eo bet an arload.
+        destroy:
+          notice: Dilamet eo bet an arload.
+        update:
+          notice: Hizivaet eo bet an arload.
+    layouts:
+      admin:
+        nav:
+          applications: Arloadoù
+    scopes:
+      read:lists: gwelout ho listennoù
+      write:lists: krouiñ listennoù
+      write:statuses: embann toudoù
diff --git a/config/locales/doorkeeper.fr.yml b/config/locales/doorkeeper.fr.yml
index e9bf70cd2..8a628538b 100644
--- a/config/locales/doorkeeper.fr.yml
+++ b/config/locales/doorkeeper.fr.yml
@@ -25,7 +25,7 @@ fr:
         edit: Modifier
         submit: Envoyer
       confirmations:
-        destroy: Êtes-vous certain·e ?
+        destroy: Voulez-vous vraiment faire ça ?
       edit:
         title: Modifier l’application
       form:
@@ -37,7 +37,7 @@ fr:
       index:
         application: Application
         callback_url: URL de retour d’appel
-        delete: Effacer
+        delete: Supprimer
         empty: Vous n’avez pas d’application.
         name: Nom
         new: Nouvelle application
@@ -69,7 +69,7 @@ fr:
       buttons:
         revoke: Annuler
       confirmations:
-        revoke: Êtes-vous certain·e ?
+        revoke: Voulez-vous vraiment faire ça ?
       index:
         application: Application
         created_at: Créé le
@@ -145,7 +145,7 @@ fr:
       write:follows: suivre des personnes
       write:lists: créer des listes
       write:media: téléverser des fichiers média
-      write:mutes: masquer des gens et des conversations
-      write:notifications: nettoyer vos notifications
+      write:mutes: masquer des comptes et des conversations
+      write:notifications: effacer vos notifications
       write:reports: signaler d’autres personnes
       write:statuses: publier des statuts
diff --git a/config/locales/doorkeeper.kab.yml b/config/locales/doorkeeper.kab.yml
index b384b76b1..dd141a10e 100644
--- a/config/locales/doorkeeper.kab.yml
+++ b/config/locales/doorkeeper.kab.yml
@@ -51,12 +51,12 @@ kab:
     authorizations:
       buttons:
         authorize: Ssireg
-        deny: Ggami
+        deny: Aggi
       error:
         title: Tella-d tuccḍa
       new:
-        able_to: Asnas-agi yezmer
-        prompt: Eǧǧ i %{client_name} ad yekcem γer umiḍan-ik
+        able_to: Asnas-agi yezmer ad
+        prompt: Yessutred wesnan n %{client_name} akečum γer umiḍan-ik
         title: Tlaq tsiregt
       show:
         title: Nγel tangalt n wurag sakkin senteḍ-itt deg usnas.
@@ -102,7 +102,7 @@ kab:
       read:favourites: ẓer ismenyifen-ik
       read:filters: ẓer imsizedgen-ik
       read:follows: ẓer imeḍfaṛen-ik
-      read:lists: ẓer tibdarin-ik
+      read:lists: ẓer umuγen-ik·im
       read:mutes: ẓer wid i tesgugmeḍ
       read:notifications: ẓer tilγa-ik
       read:statuses: ẓer meṛṛa tisuffaγ
@@ -112,5 +112,5 @@ kab:
       write:bookmarks: ad yernu tisuffγin γer ticraḍ
       write:filters: rnu-d imsizedgen
       write:follows: ḍfeṛ imdanen
-      write:lists: rnu-d tibdarin
+      write:lists: yesnulfu umuγen
       write:media: ad yessali ifayluyen n teγwalt
diff --git a/config/locales/doorkeeper.ko.yml b/config/locales/doorkeeper.ko.yml
index 6f4192ebe..16a2d0490 100644
--- a/config/locales/doorkeeper.ko.yml
+++ b/config/locales/doorkeeper.ko.yml
@@ -126,7 +126,7 @@ ko:
       read: 계정의 모든 데이터를 읽기
       read:accounts: 계정의 정보를 보기
       read:blocks: 차단을 보기
-      read:bookmarks: 내 갈무리 보기
+      read:bookmarks: 내 보관함 보기
       read:favourites: 관심글을 보기
       read:filters: 필터를 보기
       read:follows: 팔로우를 보기
@@ -139,7 +139,7 @@ ko:
       write: 계정 정보 수정
       write:accounts: 프로필 수정
       write:blocks: 계정이나 도메인 차단
-      write:bookmarks: 게시글을 갈무리하기
+      write:bookmarks: 게시글을 보관함에 넣기
       write:favourites: 관심글 지정
       write:filters: 필터 만들기
       write:follows: 사람을 팔로우
diff --git a/config/locales/doorkeeper.nn.yml b/config/locales/doorkeeper.nn.yml
index f670d5a8b..f5437672a 100644
--- a/config/locales/doorkeeper.nn.yml
+++ b/config/locales/doorkeeper.nn.yml
@@ -5,7 +5,7 @@ nn:
       doorkeeper/application:
         name: Applikasjonsnamn
         redirect_uri: Omdirigerings-URI
-        scopes: Omfang
+        scopes: Skop
         website: Applikasjonsnettside
     errors:
       models:
@@ -33,15 +33,15 @@ nn:
       help:
         native_redirect_uri: Bruk %{native_redirect_uri} for lokale testar
         redirect_uri: Bruk ei linjer per URI
-        scopes: Adskill omfang med mellomrom. La det være blankt for å bruke standard omfang.
+        scopes: Skil skop med mellomrom. Ikkje fyll inn noko som helst for å bruke standardskop.
       index:
         application: Applikasjon
         callback_url: Callback-URL
         delete: Slett
-        empty: Du har ingen søknader.
+        empty: Du har ikkje nokon applikasjonar.
         name: Namn
         new: Ny applikasjon
-        scopes: Omfang
+        scopes: Skop
         show: Vis
         title: Dine applikasjonar
       new:
@@ -49,8 +49,8 @@ nn:
       show:
         actions: Handlingar
         application_id: Klientnøkkel
-        callback_urls: Callback-URLer
-        scopes: Omfang
+        callback_urls: Callback-URLar
+        scopes: Skop
         secret: Klienthemmelegheit
         title: 'Applikasjon: %{name}'
     authorizations:
@@ -60,8 +60,8 @@ nn:
       error:
         title: Ein feil har oppstått
       new:
-        able_to: Den vil ha mulighet til
-        prompt: Applikasjon %{client_name} spør om tilgang til din konto
+        able_to: Applikasjonen vil kunne
+        prompt: Applikasjonen %{client_name} spør om tilgang til kontoen din
         title: Autorisasjon nødvendig
       show:
         title: Kopier denne autorisasjonskoden og lim den inn i applikasjonen.
@@ -74,15 +74,15 @@ nn:
         application: Applikasjon
         created_at: Autorisert
         date_format: "%Y-%m-%d %H:%M:%S"
-        scopes: Omfang
+        scopes: Skop
         title: Dine autoriserte applikasjonar
     errors:
       messages:
-        access_denied: Ressurseieren eller autoriseringstjeneren avviste forespørslen.
-        credential_flow_not_configured: Ressurseiers passordflyt feilet fordi Doorkeeper.configure.resource_owner_from_credentials ikke var konfigurert.
+        access_denied: Ressurseigaren eller autorisasjonstenaren avviste førespurnaden.
+        credential_flow_not_configured: Flyten «Resource Owner Password Credentials» kunne ikkje verte fullført av di «Doorkeeper.configure.resource_owner_from_credentials» er ikkje konfigurert.
         invalid_client: Klientautentisering feilet på grunn av ukjent klient, ingen autentisering inkludert, eller autentiseringsmetode er ikke støttet.
         invalid_grant: Autoriseringen er ugyldig, utløpt, opphevet, stemmer ikke overens med omdirigerings-URIen eller var utstedt til en annen klient.
-        invalid_redirect_uri: Den inkluderte omdirigerings-URLen er ikke gyldig.
+        invalid_redirect_uri: Omdirigerings-URLen er ikkje gyldig.
         invalid_request: Forespørslen mangler en eller flere parametere, inkluderte en parameter som ikke støttes eller har feil struktur.
         invalid_resource_owner: Ressurseierens detaljer er ikke gyldige, eller så er det ikke mulig å finne eieren
         invalid_scope: Det etterspurte omfanget er ugyldig, ukjent eller har feil struktur.
diff --git a/config/locales/doorkeeper.pt-BR.yml b/config/locales/doorkeeper.pt-BR.yml
index 90d8f9358..7d18fb2bb 100644
--- a/config/locales/doorkeeper.pt-BR.yml
+++ b/config/locales/doorkeeper.pt-BR.yml
@@ -38,7 +38,7 @@ pt-BR:
         application: Aplicativos
         callback_url: Link de retorno
         delete: Excluir
-        empty: Não tem aplicações.
+        empty: Você não tem aplicativos.
         name: Nome
         new: Novo aplicativo
         scopes: Autorizações
diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml
index 4cd80a4e0..bf414361d 100644
--- a/config/locales/doorkeeper.sk.yml
+++ b/config/locales/doorkeeper.sk.yml
@@ -60,7 +60,7 @@ sk:
         title: Nastala chyba
       new:
         able_to: Bude môcť
-        prompt: Aplikácia %{client_name} žiada prístup k vašemu účtu
+        prompt: Aplikácia %{client_name} vyžaduje prístup k tvojmu účtu
         title: Je potrebná autorizácia
       show:
         title: Skopíruj tento autorizačný kód a vlož ho do aplikácie.
@@ -73,7 +73,7 @@ sk:
         application: Aplikácia
         created_at: Autorizované
         scopes: Oprávnenia
-        title: Vaše autorizované aplikácie
+        title: Tvoje povolené aplikácie
     errors:
       messages:
         access_denied: Prístup zamietnutý.
diff --git a/config/locales/doorkeeper.th.yml b/config/locales/doorkeeper.th.yml
index be009af4d..8ca87578b 100644
--- a/config/locales/doorkeeper.th.yml
+++ b/config/locales/doorkeeper.th.yml
@@ -29,7 +29,7 @@ th:
       edit:
         title: แก้ไขแอปพลิเคชัน
       help:
-        native_redirect_uri: ใช้ %{native_redirect_uri} สำหรับการทดสอบในเว็บ
+        native_redirect_uri: ใช้ %{native_redirect_uri} สำหรับการทดสอบในเซิร์ฟเวอร์
         redirect_uri: ใช้หนึ่งบรรทัดต่อ URI
         scopes: แยกขอบเขตด้วยช่องว่าง เว้นว่างไว้เพื่อใช้ขอบเขตเริ่มต้น
       index:
diff --git a/config/locales/el.yml b/config/locales/el.yml
index 85c7bc648..e2fe9056b 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -51,7 +51,7 @@ el:
   accounts:
     choices_html: 'Επιλογές από %{name}:'
     endorsements_hint: Μπορεις να εγκρίνεις ανθρώπους που ακολουθείς μέσω της δικτυακής εφαρμογής και αυτοί θα εμφανίζονται εδώ.
-    featured_tags_hint: Μπορείς να επιλέξεις συγκεκριμένες ταμπέλες που θα εμφανίζονται εδώ.
+    featured_tags_hint: Μπορείς να επιλέξεις συγκεκριμένες ετικέτες που θα εμφανίζονται εδώ.
     follow: Ακολούθησε
     followers:
       one: Ακόλουθος
@@ -92,6 +92,7 @@ el:
       delete: Διαγραφή
       destroyed_msg: Επιτυχής καταστροφή σημειώματος μεσολάβησης!
     accounts:
+      add_email_domain_block: Εγγραφή τομέα email σε μαύρη λίστα
       approve: Έγκριση
       approve_all: Έγκριση όλων
       are_you_sure: Σίγουρα;
@@ -172,6 +173,7 @@ el:
         staff: Προσωπικό
         user: Χρήστης
       search: Αναζήτηση
+      search_same_email_domain: Άλλοι χρήστες με τον ίδιο τομέα e-mail
       search_same_ip: Υπόλοιποι χρήστες με την ίδια διεύθυνση IP
       shared_inbox_url: URL κοινόχρηστων εισερχομένων
       show:
@@ -193,6 +195,18 @@ el:
       web: Διαδίκτυο
       whitelisted: Εγκεκριμένοι
     action_logs:
+      action_types:
+        change_email_user: Αλλαγή email για χρήστη
+        destroy_status: Διαγραφή Κατάστασης
+        disable_2fa_user: Απενεργοποίηση 2FA
+        disable_custom_emoji: Απενεργοποίηση Προσαρμοσμένων Emoji
+        disable_user: Απενεργοποίηση Χρήστη
+        enable_custom_emoji: Ενεργοποίηση Προσαρμοσμένων Emoji
+        enable_user: Ενεργοποίηση Χρήστη
+        promote_user: Προαγωγή Χρήστη
+        remove_avatar_user: Αφαίρεση Avatar
+        silence_account: Σίγαση Λογαριασμού
+        update_status: Ενημέρωση Κατάστασης
       actions:
         assigned_to_self_report: Ο/Η %{name} ανάθεσε την καταγγελία %{target} στον εαυτό του/της
         change_email_user: Ο/Η %{name} άλλαξε τη διεύθυνση email του χρήστη %{target}
@@ -230,6 +244,9 @@ el:
         update_custom_emoji: Ο/Η %{name} ενημέρωσε το emoji %{target}
         update_status: Ο/Η %{name} ενημέρωσε την κατάσταση του/της %{target}
       deleted_status: "(διαγραμμένη δημοσίευση)"
+      empty: Δεν βρέθηκαν αρχεία καταγραφής.
+      filter_by_action: Φιλτράρισμα ανά ενέργεια
+      filter_by_user: Φιλτράρισμα ανά χρήστη
       title: Αρχείο ελέγχου
     announcements:
       destroyed_msg: Επιτυχής διαγραφή ανακοίνωσης!
@@ -292,7 +309,7 @@ el:
       features: Λειτουργίες
       hidden_service: Ομοσπονδία με κρυμμένες υπηρεσίες
       open_reports: ανοιχτές καταγγελίες
-      pending_tags: ταμπέλες προς έγκριση
+      pending_tags: ετικέτες προς έγκριση
       pending_users: χρήστες προς έγκριση
       recent_users: Πρόσφατοι χρήστες
       search: Αναζήτηση πλήρους κειμένου
@@ -358,6 +375,7 @@ el:
       destroyed_msg: Επιτυχής διαγραφή email τομέα από τη μαύρη λίστα
       domain: Τομέας
       empty: Δεν έχουν οριστεί αποκλεισμένοι τομείς email.
+      from_html: από %{domain}
       new:
         create: Πρόσθεση τομέα
         title: Νέα εγγραφή email στη μαύρη λίστα
@@ -532,11 +550,14 @@ el:
         title: Προεπισκόπιση ροής
       title: Ρυθμίσεις ιστότοπου
       trendable_by_default:
-        desc_html: Επηρεάζει τις ταμπέλες που δεν είχαν απαγορευτεί νωρίτερα
-        title: Επέτρεψε στις ταμπέλες να εμφανιστούν στις τάσεις χωρίς προηγούμενη έγκριση
+        desc_html: Επηρεάζει όσες ετικέτες δεν είχαν απαγορευτεί νωρίτερα
+        title: Επέτρεψε στις ετικέτες να εμφανίζονται στις τάσεις χωρίς να χρειάζεται πρώτα έγκριση
       trends:
-        desc_html: Δημόσια εμφάνιση ταμπελών που έχουν ήδη εγκριθεί και είναι δημοφιλείς
-        title: Δημοφιλείς ταμπέλες
+        desc_html: Δημόσια εμφάνιση ετικετών που έχουν ήδη εγκριθεί και είναι δημοφιλείς
+        title: Δημοφιλείς ετικέτες
+    site_uploads:
+      delete: Διαγραφή μεταφορτωμένου αρχείου
+      destroyed_msg: Η μεταφόρτωση ιστότοπου διαγράφηκε επιτυχώς!
     statuses:
       back_to_account: Επιστροφή στη σελίδα λογαριασμού
       batch:
@@ -561,19 +582,18 @@ el:
       last_active: Τελευταία δραστηριότητα
       most_popular: Δημοφιλέστερες
       most_recent: Πιο πρόσφατες
-      name: Ταμπέλα
+      name: Ετικέτα
       review: Κατάσταση έγκρισης
       reviewed: Εγκεκριμένες
-      title: Ταμπέλες
+      title: Ετικέτες
       trending_right_now: Δημοφιλείς αυτή τη στιγμή
       unique_uses_today: "%{count} σημερινές δημοσιεύσεις"
       unreviewed: Εκκρεμεί έγκριση
-      updated_msg: Οι ρυθμίσεις των ταμπελών ενημερώθηκαν επιτυχώς
+      updated_msg: Οι ρυθμίσεις των ετικετών ενημερώθηκαν επιτυχώς
     title: Διαχείριση
     warning_presets:
       add_new: Πρόσθεση νέου
       delete: Διαγραφή
-      edit: Ενημέρωση
       edit_preset: Ενημέρωση προκαθορισμένης προειδοποίησης
       title: Διαχείριση προκαθορισμένων προειδοποιήσεων
   admin_mailer:
@@ -585,8 +605,8 @@ el:
       body_remote: Κάποιος/α από τον τομέα %{domain} κατήγγειλε τον/την %{target}
       subject: Νέα καταγγελία για %{instance} (#%{id})
     new_trending_tag:
-      body: 'Η ταμπέλα #%{name} είναι δημοφιλής σήμερα, αλλά δεν έχει εγκριθεί μέχρι τώρα. Δεν θα εμφανίζεται δημοσίως μέχρι να δοθεί έγκρισή, αλλιώς αποθηκεύστε τη φόρμα ως έχει για να μην την δείτε ξανά.'
-      subject: Νέα ταμπέλα προς έγκριση στο %{instance} (#%{name})
+      body: 'Η ετικέτα #%{name} είναι δημοφιλής σήμερα, αλλά δεν έχει εγκριθεί μέχρι τώρα. Δεν θα εμφανίζεται δημοσίως μέχρι να δοθεί έγκριση, αλλιώς αποθήκευση τη φόρμα ως έχει για να μην την δεις ξανά.'
+      subject: Νέα ετικέτα προς έγκριση στο %{instance} (#%{name})
   aliases:
     add_new: Δημιουργία ψευδώνυμου
     created_msg: Δημιουργήθηκε νέο ψευδώνυμο. Τώρα μπορείς να ξεκινήσεις τη μεταφορά από τον παλιό λογαριασμό.
@@ -595,7 +615,7 @@ el:
     remove: Αφαίρεση ψευδώνυμου
   appearance:
     advanced_web_interface: Προηγμένη λειτουργία χρήσης
-    advanced_web_interface_hint: 'Αν θέλεις να χρησιμοποιήσεις ολόκληρο το πλάτος της οθόνης σου, η προηγμένη λειτουργία χρήσης σου επιτρέπει να ορίσεις πολλαπλές κολώνες ώστε να βλέπεις ταυτόχρονα όση πληροφορία θέλεις: Την αρχική ροή, τις ειδοποιήσεις, την ομοσπονδιακή ροή και όσες λίστες και ταμπέλες θέλεις.'
+    advanced_web_interface_hint: 'Αν θέλεις να χρησιμοποιήσεις ολόκληρο το πλάτος της οθόνης σου, η προηγμένη λειτουργία χρήσης σου επιτρέπει να ορίσεις πολλαπλές κολώνες ώστε να βλέπεις ταυτόχρονα όση πληροφορία θέλεις: Την αρχική ροή, τις ειδοποιήσεις, την ομοσπονδιακή ροή και όσες λίστες και ετικέτες θέλεις.'
     animations_and_accessibility: Κίνηση και προσβασιμότητα
     confirmation_dialogs: Ερωτήσεις επιβεβαίωσης
     discovery: Εξερεύνηση
@@ -661,6 +681,7 @@ el:
     trouble_logging_in: Πρόβλημα σύνδεσης;
   authorize_follow:
     already_following: Ήδη ακολουθείς αυτό το λογαριασμό
+    already_requested: Έχετε ήδη στείλει ένα αίτημα ακολούθησης σε αυτόν τον λογαριασμό
     error: Δυστυχώς παρουσιάστηκε ένα σφάλμα κατά την αναζήτηση του απομακρυσμένου λογαριασμού
     follow: Ακολούθησε
     follow_request: 'Έστειλες αίτημα παρακολούθησης προς:'
@@ -750,8 +771,8 @@ el:
   featured_tags:
     add_new: Προσθήκη νέας
     errors:
-      limit: Έχεις ήδη προσθέσει το μέγιστο αριθμό ταμπελών
-    hint_html: "<strong>Τι είναι οι προβεβλημένες ταμπέλες;</strong> Προβάλλονται στο δημόσιο προφίλ σου επιτρέποντας σε όποιον το βλέπει να χαζέψει τις δημοσιεύσεις που τις χρησιμοποιούν. Είναι ωραίος τρόπος να παρακολουθείς κάποια δημιουργία ή ένα μακροπρόθεσμο έργο."
+      limit: Έχεις ήδη προσθέσει το μέγιστο αριθμό ετικετών
+    hint_html: "<strong>Τι είναι οι προβεβλημένες ετικέτες;</strong> Προβάλλονται στο δημόσιο προφίλ σου επιτρέποντας σε όποιον το βλέπει να χαζέψει τις δημοσιεύσεις που τις χρησιμοποιούν. Είναι ένας ωραίος τρόπος να παρακολουθείς την πορεία μιας δημιουργία ή ενός μακροπρόθεσμου έργου."
   filters:
     contexts:
       account: Προφίλ
@@ -849,6 +870,7 @@ el:
   media_attachments:
     validations:
       images_and_video: Δεν γίνεται να προσθέσεις βίντεο σε ενημέρωση που ήδη περιέχει εικόνες
+      not_ready: Δεν μπορούν να επισυναφθούν αρχεία για τα οποία δεν έχει τελειώσει η επεξεργασία. Προσπαθήστε ξανά σε λίγο!
       too_many: Δεν γίνεται να προσθέσεις περισσότερα από 4 αρχεία
   migrations:
     acct: ΌνομαΧρήστη@Τομέας του νέου λογαριασμού
@@ -1044,7 +1066,7 @@ el:
     development: Ανάπτυξη
     edit_profile: Επεξεργασία προφίλ
     export: Εξαγωγή δεδομένων
-    featured_tags: Χαρακτηριστικές ταμπέλες
+    featured_tags: Χαρακτηριστικές ετικέτες
     identity_proofs: Αποδείξεις ταυτοτήτων
     import: Εισαγωγή
     import_and_export: Εισαγωγή & Εξαγωγή
@@ -1068,8 +1090,10 @@ el:
     boosted_from_html: Προωθήθηκε από %{acct_link}
     content_warning: 'Προειδοποίηση περιεχομένου: %{warning}'
     disallowed_hashtags:
-      one: 'περιέχει μη επιτρεπτή ταμπέλα: %{tags}'
-      other: 'περιέχει μη επιτρεπτές ταμπέλες: %{tags}'
+      one: 'περιέχει μη επιτρεπτή ετικέτα: %{tags}'
+      other: περιέχει μη επιτρεπτές ετικέτες %{tags}
+    errors:
+      in_reply_not_found: Η κατάσταση στην οποία προσπαθείτε να απαντήσετε δεν υπάρχει.
     language_detection: Αυτόματη αναγνώριση γλώσσας
     open_in_web: Δες στο διαδίκτυο
     over_character_limit: υπέρβαση μέγιστου ορίου %{max} χαρακτήρων
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 6d6f67f91..5a4302606 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -92,6 +92,7 @@ en:
       delete: Delete
       destroyed_msg: Moderation note successfully destroyed!
     accounts:
+      add_email_domain_block: Blacklist e-mail domain
       approve: Approve
       approve_all: Approve all
       are_you_sure: Are you sure?
@@ -172,6 +173,7 @@ en:
         staff: Staff
         user: User
       search: Search
+      search_same_email_domain: Other users with the same e-mail domain
       search_same_ip: Other users with the same IP
       shared_inbox_url: Shared inbox URL
       show:
@@ -193,6 +195,42 @@ en:
       web: Web
       whitelisted: Whitelisted
     action_logs:
+      action_types:
+        assigned_to_self_report: Assign Report
+        change_email_user: Change E-mail for User
+        confirm_user: Confirm User
+        create_account_warning: Create Warning
+        create_announcement: Create Announcement
+        create_custom_emoji: Create Custom Emoji
+        create_domain_allow: Create Domain Allow
+        create_domain_block: Create Domain Block
+        create_email_domain_block: Create E-mail Domain Block
+        demote_user: Demote User
+        destroy_announcement: Delete Announcement
+        destroy_custom_emoji: Delete Custom Emoji
+        destroy_domain_allow: Delete Domain Allow
+        destroy_domain_block: Delete Domain Block
+        destroy_email_domain_block: Delete e-mail domain block
+        destroy_status: Delete Status
+        disable_2fa_user: Disable 2FA
+        disable_custom_emoji: Disable Custom Emoji
+        disable_user: Disable User
+        enable_custom_emoji: Enable Custom Emoji
+        enable_user: Enable User
+        memorialize_account: Memorialize Account
+        promote_user: Promote User
+        remove_avatar_user: Remove Avatar
+        reopen_report: Reopen Report
+        reset_password_user: Reset Password
+        resolve_report: Resolve Report
+        silence_account: Silence Account
+        suspend_account: Suspend Account
+        unassigned_report: Unassign Report
+        unsilence_account: Unsilence Account
+        unsuspend_account: Unsuspend Account
+        update_announcement: Update Announcement
+        update_custom_emoji: Update Custom Emoji
+        update_status: Update Status
       actions:
         assigned_to_self_report: "%{name} assigned report %{target} to themselves"
         change_email_user: "%{name} changed the e-mail address of user %{target}"
@@ -230,6 +268,9 @@ en:
         update_custom_emoji: "%{name} updated emoji %{target}"
         update_status: "%{name} updated status by %{target}"
       deleted_status: "(deleted status)"
+      empty: No logs found.
+      filter_by_action: Filter by action
+      filter_by_user: Filter by user
       title: Audit log
     announcements:
       destroyed_msg: Announcement successfully deleted!
@@ -359,6 +400,7 @@ en:
       destroyed_msg: Successfully deleted e-mail domain from blacklist
       domain: Domain
       empty: No e-mail domains currently blacklisted.
+      from_html: from %{domain}
       new:
         create: Add domain
         title: New e-mail blacklist entry
@@ -550,6 +592,9 @@ en:
       trends:
         desc_html: Publicly display previously reviewed hashtags that are currently trending
         title: Trending hashtags
+    site_uploads:
+      delete: Delete uploaded file
+      destroyed_msg: Site upload successfully deleted!
     statuses:
       back_to_account: Back to account page
       batch:
@@ -586,7 +631,6 @@ en:
     warning_presets:
       add_new: Add new
       delete: Delete
-      edit: Edit
       edit_preset: Edit warning preset
       title: Manage warning presets
   admin_mailer:
@@ -738,7 +782,7 @@ en:
     '422':
       content: Security verification failed. Are you blocking cookies?
       title: Security verification failed
-    '429': Throttled
+    '429': Too many requests
     '500':
       content: We're sorry, but something went wrong on our end.
       title: This page is not correct
@@ -864,6 +908,7 @@ en:
   media_attachments:
     validations:
       images_and_video: Cannot attach a video to a status that already contains images
+      not_ready: Cannot attach files that have not finished processing. Try again in a moment!
       too_many: Cannot attach more than 4 files
   migrations:
     acct: Moved to
@@ -1087,6 +1132,8 @@ en:
     disallowed_hashtags:
       one: 'contained a disallowed hashtag: %{tags}'
       other: 'contained the disallowed hashtags: %{tags}'
+    errors:
+      in_reply_not_found: The status you are trying to reply to does not appear to exist.
     language_detection: Automatically detect language
     open_in_web: Open in web
     over_character_limit: character limit of %{max} exceeded
diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml
index 0742559ed..1375ebb33 100644
--- a/config/locales/en_GB.yml
+++ b/config/locales/en_GB.yml
@@ -474,7 +474,6 @@ en_GB:
     warning_presets:
       add_new: Add new
       delete: Delete
-      edit: Edit
       edit_preset: Edit warning preset
       title: Manage warning presets
   admin_mailer:
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index b3cb2b523..a558efc51 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -33,7 +33,7 @@ eo:
       one: mesaĝo
       other: mesaĝoj
     status_count_before: Kie skribiĝis
-    tagline: Sekvi amikojn kaj trovi novan onin
+    tagline: Sekvi amikojn kaj trovi iujn novajn
     terms: Uzkondiĉoj
     unavailable_content: Nedisponebla enhavo
     unavailable_content_description:
@@ -557,7 +557,6 @@ eo:
     warning_presets:
       add_new: Aldoni novan
       delete: Forigi
-      edit: Redakti
       edit_preset: Redakti avertan antaŭagordon
       title: Administri avertajn antaŭagordojn
   admin_mailer:
@@ -819,11 +818,12 @@ eo:
       images_and_video: Aldoni videon al mesaĝo, kiu jam havas bildojn ne eblas
       too_many: Aldoni pli ol 4 dosierojn ne eblas
   migrations:
-    acct: uzantnomo@domajno de la nova konto
+    acct: Movigita al
     cancel: Nuligi alidirekton
     cancelled_msg: Sukcese forigis la alidirekton.
     errors:
       already_moved: estas la saman konton vi jam translokiĝis al
+      missing_also_known_as: ne returne referencas al ĉi tiu konto
       move_to_self: ne povas esti nuna konto
       not_found: ne povis trovi
       on_cooldown: Vi estas ĉe malvarmiĝi
@@ -907,11 +907,16 @@ eo:
     other: Aliaj aferoj
     posting_defaults: Afiŝadoj defaŭltoj
     public_timelines: Publikaj templinioj
+  reactions:
+    errors:
+      limit_reached: Limito de malsamaj reagoj atinginta
+      unrecognized_emoji: ne estas rekonita emoĝio
   relationships:
     activity: Konta aktiveco
     dormant: Dormanta
     followers: Sekvantoj
     following: Sekvatoj
+    invited: Invitita
     last_active: Laste aktiva
     most_recent: Plej lasta
     moved: Moviĝita
@@ -1035,7 +1040,7 @@ eo:
         one: "%{count} voĉdono"
         other: "%{count} voĉdonoj"
       vote: Voĉdoni
-    show_more: Montri pli
+    show_more: Malfoldi
     show_thread: Montri la fadenon
     sign_in_to_participate: Ensaluti por partopreni en la konversacio
     title: "%{name}: “%{quote}”"
diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml
index 6eec00cb6..b71ea5f39 100644
--- a/config/locales/es-AR.yml
+++ b/config/locales/es-AR.yml
@@ -92,6 +92,7 @@ es-AR:
       delete: Eliminar
       destroyed_msg: "¡Nota de moderación destruída exitosamente!"
     accounts:
+      add_email_domain_block: Desaprobar el dominio del correo electrónico
       approve: Aprobar
       approve_all: Aprobar todas
       are_you_sure: "¿Estás seguro?"
@@ -172,6 +173,7 @@ es-AR:
         staff: Equipo
         user: Usuario
       search: Buscar
+      search_same_email_domain: Otros usuarios con el mismo dominio de correo electrónico
       search_same_ip: Otros usuarios con la misma dirección IP
       shared_inbox_url: Dirección web de la bandeja de entrada compartida
       show:
@@ -193,6 +195,42 @@ es-AR:
       web: Web
       whitelisted: Aprobadas
     action_logs:
+      action_types:
+        assigned_to_self_report: Asignar denuncia
+        change_email_user: Cambiar correo electrónico del usuario
+        confirm_user: Confirmar usuario
+        create_account_warning: Crear advertencia
+        create_announcement: Crear anuncio
+        create_custom_emoji: Crear emoji personalizado
+        create_domain_allow: Crear permiso de dominio
+        create_domain_block: Crear bloqueo de dominio
+        create_email_domain_block: Crear bloqueo de dominio de correo electrónico
+        demote_user: Descender usuario
+        destroy_announcement: Eliminar anuncio
+        destroy_custom_emoji: Eliminar emoji personalizado
+        destroy_domain_allow: Eliminar permiso de dominio
+        destroy_domain_block: Eliminar bloquedo de dominio
+        destroy_email_domain_block: Eliminar bloquedo de dominio de correo electrónico
+        destroy_status: Eliminar estado
+        disable_2fa_user: Deshabilitar 2FA
+        disable_custom_emoji: Deshabilitar emoji personalizado
+        disable_user: Deshabilitar usuario
+        enable_custom_emoji: Habilitar emoji personalizado
+        enable_user: Habilitar usuario
+        memorialize_account: Volver cuenta conmemorativa
+        promote_user: Promover usuario
+        remove_avatar_user: Quitar avatar
+        reopen_report: Reabrir denuncia
+        reset_password_user: Cambiar contraseña
+        resolve_report: Resolver denuncia
+        silence_account: Silenciar cuenta
+        suspend_account: Suspender cuenta
+        unassigned_report: Desasignar denuncia
+        unsilence_account: Dejar de silenciar cuenta
+        unsuspend_account: Dejar de suspender cuenta
+        update_announcement: Actualizar anuncio
+        update_custom_emoji: Actualizar emoji personalizado
+        update_status: Actualizar estado
       actions:
         assigned_to_self_report: "%{name} se asignó la denuncia %{target} a sí"
         change_email_user: "%{name} cambió la dirección de correo electrónico del usuario %{target}"
@@ -230,6 +268,9 @@ es-AR:
         update_custom_emoji: "%{name} actualizó el emoji %{target}"
         update_status: "%{name} actualizó el estado de %{target}"
       deleted_status: "(estado borrado)"
+      empty: No se encontraron registros.
+      filter_by_action: Filtrar por acción
+      filter_by_user: Filtrar por usuario
       title: Registro de auditoría
     announcements:
       destroyed_msg: "¡Anuncio eliminado exitosamente!"
@@ -358,6 +399,7 @@ es-AR:
       destroyed_msg: Se aprobó dominio de correo electrónico exitosamente
       domain: Dominio
       empty: Actualmente no hay dominios de correo electrónico desaprobados.
+      from_html: de %{domain}
       new:
         create: Agregar dominio
         title: Nueva desaprobación de correo electrónico
@@ -537,6 +579,9 @@ es-AR:
       trends:
         desc_html: Mostrar públicamente etiquetas previamente revisadas que son tendencia actualmente
         title: Etiquetas tendencias
+    site_uploads:
+      delete: Eliminar archivo subido
+      destroyed_msg: "¡Subida al sitio eliminada exitosamente!"
     statuses:
       back_to_account: Volver a la página de la cuenta
       batch:
@@ -573,7 +618,6 @@ es-AR:
     warning_presets:
       add_new: Agregar nuevo
       delete: Eliminar
-      edit: Editar
       edit_preset: Editar preajuste de advertencia
       title: Administrar preajustes de advertencia
   admin_mailer:
@@ -661,6 +705,7 @@ es-AR:
     trouble_logging_in: "¿Tenés problemas para iniciar sesión?"
   authorize_follow:
     already_following: Ya estás siguiendo a esta cuenta
+    already_requested: Ya enviaste una solicitud de seguimiento a esa cuenta
     error: Lamentablemente, ocurrió un error buscando la cuenta remota
     follow: Seguir
     follow_request: 'Enviaste una solicitud de seguimiento a:'
@@ -849,6 +894,7 @@ es-AR:
   media_attachments:
     validations:
       images_and_video: No se puede adjuntar un video a un estado que ya contenga imágenes
+      not_ready: No se pueden adjuntar archivos que no terminaron de procesarse. ¡Intentá de nuevo en un rato!
       too_many: No se pueden adjuntar más de 4 archivos
   migrations:
     acct: Mudada a
@@ -1070,6 +1116,8 @@ es-AR:
     disallowed_hashtags:
       one: 'contenía una etiqueta no permitida: %{tags}'
       other: 'contenía las etiquetas no permitidas: %{tags}'
+    errors:
+      in_reply_not_found: El estado al que intentás responder no existe.
     language_detection: Detectar idioma automáticamente
     open_in_web: Abrir en web
     over_character_limit: se excedió el límite de %{max} caracteres
@@ -1099,7 +1147,7 @@ es-AR:
       unlisted_long: Todos pueden ver, pero no está listado en las líneas temporales públicas
   stream_entries:
     pinned: Toot fijado
-    reblogged: retooteado
+    reblogged: retooteó
     sensitive_content: Contenido sensible
   tags:
     does_not_match_previous_name: no coincide con el nombre anterior
diff --git a/config/locales/es.yml b/config/locales/es.yml
index a26143018..fac96aadf 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -92,6 +92,7 @@ es:
       delete: Borrar
       destroyed_msg: "¡Nota de moderación destruida con éxito!"
     accounts:
+      add_email_domain_block: Poner en lista negra el dominio del correo
       approve: Aprobar
       approve_all: Aprobar todos
       are_you_sure: "¿Estás seguro?"
@@ -172,6 +173,7 @@ es:
         staff: Personal
         user: Usuario
       search: Buscar
+      search_same_email_domain: Otros usuarios con el mismo dominio de correo
       search_same_ip: Otros usuarios con la misma IP
       shared_inbox_url: URL de bandeja compartida
       show:
@@ -193,6 +195,42 @@ es:
       web: Web
       whitelisted: Añadido a la lista blanca
     action_logs:
+      action_types:
+        assigned_to_self_report: Asignar Reporte
+        change_email_user: Cambiar Correo Electrónico del Usuario
+        confirm_user: Confirmar Usuario
+        create_account_warning: Crear Advertencia
+        create_announcement: Crear Anuncio
+        create_custom_emoji: Crear Emoji Personalizado
+        create_domain_allow: Crear Permiso de Dominio
+        create_domain_block: Crear Bloqueo de Dominio
+        create_email_domain_block: Crear Bloqueo de Dominio de Correo Electrónico
+        demote_user: Degradar Usuario
+        destroy_announcement: Eliminar Anuncio
+        destroy_custom_emoji: Eliminar Emoji Personalizado
+        destroy_domain_allow: Eliminar Permiso de Dominio
+        destroy_domain_block: Eliminar Bloqueo de Dominio
+        destroy_email_domain_block: Eliminar Bloqueo de Dominio de Correo Electrónico
+        destroy_status: Eliminar Estado
+        disable_2fa_user: Deshabilitar 2FA
+        disable_custom_emoji: Deshabilitar Emoji Personalizado
+        disable_user: Deshabilitar Usuario
+        enable_custom_emoji: Habilitar Emoji Personalizado
+        enable_user: Habilitar Usuario
+        memorialize_account: Transformar en Cuenta Conmemorativa
+        promote_user: Promover Usuario
+        remove_avatar_user: Eliminar Avatar
+        reopen_report: Reabrir Reporte
+        reset_password_user: Restablecer Contraseña
+        resolve_report: Resolver Reporte
+        silence_account: Silenciar Cuenta
+        suspend_account: Suspender Cuenta
+        unassigned_report: Desasignar Reporte
+        unsilence_account: Dejar de Silenciar Cuenta
+        unsuspend_account: Dejar de Suspender Cuenta
+        update_announcement: Actualizar Anuncio
+        update_custom_emoji: Actualizar Emoji Personalizado
+        update_status: Actualizar Estado
       actions:
         assigned_to_self_report: "%{name} se ha asignado la denuncia %{target} a sí mismo"
         change_email_user: "%{name} ha cambiado la dirección de correo del usuario %{target}"
@@ -230,6 +268,9 @@ es:
         update_custom_emoji: "%{name} actualizó el emoji %{target}"
         update_status: "%{name} actualizó el estado de %{target}"
       deleted_status: "(estado borrado)"
+      empty: No se encontraron registros.
+      filter_by_action: Filtrar por acción
+      filter_by_user: Filtrar por usuario
       title: Log de auditoría
     announcements:
       destroyed_msg: "¡Anuncio eliminado con éxito!"
@@ -358,6 +399,7 @@ es:
       destroyed_msg: Dominio de correo borrado de la lista negra con éxito
       domain: Dominio
       empty: Actualmente no hay dominios de correo electrónico en la lista negra.
+      from_html: de %{domain}
       new:
         create: Añadir dominio
         title: Nueva entrada en la lista negra de correo
@@ -537,6 +579,9 @@ es:
       trends:
         desc_html: Mostrar públicamente hashtags previamente revisados que son tendencia
         title: Hashtags de tendencia
+    site_uploads:
+      delete: Eliminar archivo subido
+      destroyed_msg: "¡Carga del sitio eliminada con éxito!"
     statuses:
       back_to_account: Volver a la cuenta
       batch:
@@ -573,7 +618,6 @@ es:
     warning_presets:
       add_new: Añadir nuevo
       delete: Borrar
-      edit: Editar
       edit_preset: Editar aviso predeterminado
       title: Editar configuración predeterminada de avisos
   admin_mailer:
@@ -661,6 +705,7 @@ es:
     trouble_logging_in: "¿Problemas para iniciar sesión?"
   authorize_follow:
     already_following: Ya estás siguiendo a esta cuenta
+    already_requested: Ya has enviado una solicitud de seguimiento a esa cuenta
     error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota
     follow: Seguir
     follow_request: 'Tienes una solicitud de seguimiento de:'
@@ -849,6 +894,7 @@ es:
   media_attachments:
     validations:
       images_and_video: No se puede adjuntar un video a un estado que ya contenga imágenes
+      not_ready: No se pueden adjuntar archivos que no se han terminado de procesar. ¡Inténtalo de nuevo en un momento!
       too_many: No se pueden adjuntar más de 4 archivos
   migrations:
     acct: username@domain de la nueva cuenta
@@ -1070,6 +1116,8 @@ es:
     disallowed_hashtags:
       one: 'contenía un hashtag no permitido: %{tags}'
       other: 'contenía los hashtags no permitidos: %{tags}'
+    errors:
+      in_reply_not_found: El estado al que intentas responder no existe.
     language_detection: Detección automática de idioma
     open_in_web: Abrir en web
     over_character_limit: Límite de caracteres de %{max} superado
diff --git a/config/locales/et.yml b/config/locales/et.yml
index 716da9010..8e3d56622 100644
--- a/config/locales/et.yml
+++ b/config/locales/et.yml
@@ -576,7 +576,6 @@ et:
     warning_presets:
       add_new: Lisa uus
       delete: Kustuta
-      edit: Redigeeri
       edit_preset: Redigeeri hoiatuse eelseadistust
       title: Halda hoiatuste eelseadistusi
   admin_mailer:
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index 3ca68d321..4c81c1617 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -72,8 +72,8 @@ eu:
     posts:
       one: Toot
       other: Toot
-    posts_tab_heading: Toot-ak
-    posts_with_replies: Toot-ak eta erantzunak
+    posts_tab_heading: Tootak
+    posts_with_replies: Tootak eta erantzunak
     reserved_username: Erabiltzaile-izena erreserbatuta dago
     roles:
       admin: Administratzailea
@@ -92,6 +92,7 @@ eu:
       delete: Ezabatu
       destroyed_msg: Moderazio ohara ongi suntsitu da!
     accounts:
+      add_email_domain_block: Sartu domeinua zerrenda beltzean
       approve: Onartu
       approve_all: Onartu denak
       are_you_sure: Ziur zaude?
@@ -172,6 +173,7 @@ eu:
         staff: Langilea
         user: Erabiltzailea
       search: Bilatu
+      search_same_email_domain: E-mail domeinu bera duten beste erabiltzailean
       search_same_ip: IP bera duten beste erabiltzaileak
       shared_inbox_url: Partekatutako sarrera ontziaren URL-a
       show:
@@ -358,6 +360,7 @@ eu:
       destroyed_msg: Ongi ezabatu da e-mail domeinua zerrenda beltzetik
       domain: Domeinua
       empty: Ez dago e-mail domeinurik zerrenda beltzean.
+      from_html: "%{domain} domeinutik"
       new:
         create: Gehitu domeinua
         title: Sarrera berria e-mail zerrenda beltzean
@@ -503,7 +506,7 @@ eu:
           open: Edonork eman dezake izena
         title: Erregistratzeko modua
       show_known_fediverse_at_about_page:
-        desc_html: Txandakatzean, fedibertso ezagun osoko toot-ak bistaratuko ditu aurrebistan. Bestela, toot lokalak besterik ez ditu erakutsiko.
+        desc_html: Txandakatzean, fedibertso ezagun osoko tootak bistaratuko ditu aurrebistan. Bestela, toot lokalak besterik ez ditu erakutsiko
         title: Erakutsi fedibertsu ezagun osoko denbora-lerroa aurrebistan
       show_staff_badge:
         desc_html: Erakutsi langile banda erabiltzailearen orrian
@@ -537,6 +540,9 @@ eu:
       trends:
         desc_html: Erakutsi publikoki orain joeran dauden aurretik errebisatutako traolak
         title: Traolak joeran
+    site_uploads:
+      delete: Ezabatu igotako fitxategia
+      destroyed_msg: Guneko igoera ongi ezabatu da!
     statuses:
       back_to_account: Atzera kontuaren orrira
       batch:
@@ -573,7 +579,6 @@ eu:
     warning_presets:
       add_new: Gehitu berria
       delete: Ezabatu
-      edit: Editatu
       edit_preset: Editatu abisu aurre-ezarpena
       title: Kudeatu abisu aurre-ezarpenak
   admin_mailer:
@@ -661,6 +666,7 @@ eu:
     trouble_logging_in: Arazoak saioa hasteko?
   authorize_follow:
     already_following: Kontu hau aurretik jarraitzen duzu
+    already_requested: Bidali duzu dagoeneko kontu hori jarraitzeko eskaera bat
     error: Zoritxarrez, urruneko kontua bilatzean errore bat gertatu da
     follow: Jarraitu
     follow_request: 'Jarraitzeko eskari bat bidali duzu hona:'
@@ -849,6 +855,7 @@ eu:
   media_attachments:
     validations:
       images_and_video: Ezin da irudiak dituen mezu batean bideo bat erantsi
+      not_ready: Ezin dira prozesatzen amaitu gabeko fitxategiak erantsi. Saiatu geroago!
       too_many: Ezin dira 4 fitxategi baino gehiago erantsi
   migrations:
     acct: Kontu berriaren erabiltzaile@domeinua
@@ -1076,7 +1083,7 @@ eu:
     pin_errors:
       limit: Gehienez finkatu daitekeen toot kopurua finkatu duzu jada
       ownership: Ezin duzu beste norbaiten toot bat finkatu
-      private: Ezin dira publikoak ez diren toot-ak finkatu
+      private: Ezin dira publikoak ez diren tootak finkatu
       reblog: Bultzada bat ezin da finkatu
     poll:
       total_people:
@@ -1098,7 +1105,7 @@ eu:
       unlisted: Zerrendatu gabea
       unlisted_long: Edonork ikusi dezake, baina ez da denbora-lerro publikoetan agertzen
   stream_entries:
-    pinned: Finkatutako toot-a
+    pinned: Finkatutako toota
     reblogged: "(r)en bultzada"
     sensitive_content: 'Kontuz: Eduki hunkigarria'
   tags:
@@ -1218,7 +1225,7 @@ eu:
     warning:
       explanation:
         disable: Zure kontua izoztuta dagoen bitartean, zure kontua bere horretan dirau, baina ezin duzu ekintzarik burutu desblokeatzen den arte.
-        silence: Zure kontua murriztua dagoen bitartean, jada zu jarraitzen zaituztenak besterik ez dituzte zure Toot-ak ikusiko zerbitzari honetan, eta agian zerrenda publikoetatik kenduko zaizu. Hala ere besteek oraindik zu jarraitu zaitzakete.
+        silence: Zure kontua murriztua dagoen bitartean, jada zu jarraitzen zaituztenak besterik ez dituzte zure tootak ikusiko zerbitzari honetan, eta agian zerrenda publikoetatik kenduko zaizu. Hala ere besteek oraindik zu jarraitu zaitzakete.
         suspend: Zure kontua kanporatua izan da, zure toot guztiak eta multimedia fitxategiak behin betiko ezabatu dira zerbitzari honetatik, eta zure jarraitzaileen zerbitzarietatik.
       get_in_touch: "%{instance} instantziako jendearekin harremanetan jartzeko e-mail honi erantzun ahal diozu."
       review_server_policies: Berrikusi zerbitzariko politikak
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 02bbd2938..868dd8bcf 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -94,6 +94,7 @@ fa:
       delete: حذف
       destroyed_msg: یادداشت نظارتی با موفقیت نابود شد!
     accounts:
+      add_email_domain_block: مسدود کردن دامنهٔ رایانامه
       approve: پذیرفتن
       approve_all: پذیرفتن همه
       are_you_sure: مطمئنید؟
@@ -174,6 +175,7 @@ fa:
         staff: کارمند
         user: کاربر
       search: جستجو
+      search_same_email_domain: دیگر کاربران با دامنهٔ رایانامهٔ یکسان
       search_same_ip: دیگر کاربران با IP یکسان
       shared_inbox_url: نشانی صندوق ورودی مشترک
       show:
@@ -195,6 +197,41 @@ fa:
       web: وب
       whitelisted: فهرست مجاز
     action_logs:
+      action_types:
+        assigned_to_self_report: واگذاری گزارش
+        change_email_user: تغییر رایانامه برای کاربر
+        confirm_user: تأیید کاربر
+        create_account_warning: ایجاد هشدار
+        create_announcement: ایجاد اعلامیه
+        create_custom_emoji: ایجاد اموجی سفارشی
+        create_domain_allow: ایجاد اجازهٔ دامنه
+        create_domain_block: ایجاد انسداد دامنه
+        create_email_domain_block: ایجاد انسداد دامنهٔ رایانامه
+        demote_user: تنزل کاربر
+        destroy_announcement: حذف اعلامیه
+        destroy_custom_emoji: حذف اموجی سفارشی
+        destroy_domain_allow: حذف اجازهٔ دامنه
+        destroy_domain_block: حذف انسداد دامنه
+        destroy_email_domain_block: حذف انسداد دامنهٔ رایانامه
+        destroy_status: حذف وضعیت
+        disable_2fa_user: از کار انداختن ورود دومرحله‌ای
+        disable_custom_emoji: از کار انداختن اموجی سفارشی
+        disable_user: از کار انداختن کاربر
+        enable_custom_emoji: به کار انداختن اموجی سفارشی
+        enable_user: به کار انداختن کاربر
+        promote_user: ترفیع کاربر
+        remove_avatar_user: برداشتن تصویر نمایه
+        reopen_report: بازگشایی گزارش
+        reset_password_user: بازنشانی گذرواژه
+        resolve_report: رفع گزارش
+        silence_account: خموشی حساب
+        suspend_account: تعلیق حساب
+        unassigned_report: رفع واگذاری گزارش
+        unsilence_account: رفع خموشی حساب
+        unsuspend_account: رفع تعلیق حساب
+        update_announcement: به‌روز رسانی اعلامیه
+        update_custom_emoji: به‌روز رسانی اموجی سفارشی
+        update_status: به‌روز رسانی وضعیت
       actions:
         assigned_to_self_report: "%{name} رسیدگی به گزارش %{target} را به عهده گرفت"
         change_email_user: "%{name} نشانی ایمیل کاربر %{target} را تغییر داد"
@@ -232,6 +269,9 @@ fa:
         update_custom_emoji: "%{name} شکلک %{target} را به‌روز کرد"
         update_status: "%{name} نوشتهٔ %{target} را به‌روز کرد"
       deleted_status: "(نوشتهٔ پاک‌شده)"
+      empty: هیچ گزارشی پیدا نشد.
+      filter_by_action: پالایش بر اساس کنش
+      filter_by_user: پالایش بر اساس کاربر
       title: سیاههٔ بازرسی
     announcements:
       destroyed_msg: اعلامیه با موفقیت حذف شد!
@@ -360,6 +400,7 @@ fa:
       destroyed_msg: مسدودسازی دامین ایمیل با موفقیت پاک شد
       domain: دامین
       empty: هیچ دامنه ایمیلی در حال حاضر در لیست‌سیاه قرار نگرفته است.
+      from_html: از %{domain}
       new:
         create: ساختن مسدودسازی
         title: مسدودسازی دامین ایمیل تازه
@@ -539,6 +580,9 @@ fa:
       trends:
         desc_html: برچسب‌های عمومی که پیش‌تر بازبینی شده‌اند و هم‌اینک پرطرفدارند
         title: برچسب‌های پرطرفدار
+    site_uploads:
+      delete: پرونده بارگذاری شده را پاک کنید
+      destroyed_msg: بارگذاری پایگاه با موفقیت حذف شد!
     statuses:
       back_to_account: بازگشت به صفحهٔ حساب
       batch:
@@ -575,7 +619,6 @@ fa:
     warning_presets:
       add_new: افزودن تازه
       delete: زدودن
-      edit: ویرایش
       edit_preset: ویرایش هشدار پیش‌فرض
       title: مدیریت هشدارهای پیش‌فرض
   admin_mailer:
@@ -663,6 +706,7 @@ fa:
     trouble_logging_in: برای ورود مشکلی دارید؟
   authorize_follow:
     already_following: شما همین الان هم این حساب را پی‌می‌گیرید
+    already_requested: درخواست پی‌گیری‌ای برای آن حساب فرستاده‌ بودید
     error: متأسفانه حین یافتن آن حساب خطایی رخ داد
     follow: پی بگیرید
     follow_request: 'شما درخواست پیگیری فرستاده‌اید به:'
@@ -762,16 +806,16 @@ fa:
       public: فهرست عمومی
       thread: گفتگوها
     edit:
-      title: ویرایش فیلتر
+      title: ویرایش پالایه
     errors:
       invalid_context: زمینه‌ای موجود نیست یا نامعتبر است
-      invalid_irreversible: فیلترهای برگشت‌ناپذیر تنها در زمینهٔ پیگیری‌ها یا اعلان‌ها کار می‌کنند
+      invalid_irreversible: پالایش برگشت‌ناپذیر تنها در زمینهٔ خانه یا آگاهی‌ها کار می‌کنند
     index:
       delete: پاک‌کردن
-      empty: شما هیچ فیلتری ندارید.
-      title: فیلترها
+      empty: هیچ پالایه‌ای ندارید.
+      title: پالایه‌ها
     new:
-      title: افزودن فیلتر تازه
+      title: افزودن پالایهٔ جدید
   footer:
     developers: برنامه‌نویسان
     more: بیشتر…
@@ -851,6 +895,7 @@ fa:
   media_attachments:
     validations:
       images_and_video: نمی‌توان برای نوشته‌ای که تصویر دارد ویدیو بارگذاری کرد
+      not_ready: پرونده‌هایی که پردازش را تمام نکرده‌اند نمی‌توانند پیوست شوند. یکبار دیگر امتحان کنید!
       too_many: نمی‌توان بیشتر از ۴ تصویر بارگذاری کرد
   migrations:
     acct: username@domain حساب تازه
@@ -1072,6 +1117,8 @@ fa:
     disallowed_hashtags:
       one: 'دارای هشتگ غیرمجاز: %{tags}'
       other: 'دارای هشتگ‌های غیرمجاز: %{tags}'
+    errors:
+      in_reply_not_found: به نظر نمی‌رسد وضعیتی که می‌خواهید به آن پاسخ دهید، وجود داشته باشد.
     language_detection: زبان نوشته خودبه‌خود شناخته شود
     open_in_web: بازکردن در وب
     over_character_limit: از حد مجاز %{max} حرف فراتر رفتید
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 063e3bb91..c5703e596 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -17,11 +17,13 @@ fi:
     hosted_on: Mastodon palvelimella %{domain}
     learn_more: Lisätietoja
     privacy_policy: Tietosuojaseloste
+    server_stats: 'Palvelimen tilastot:'
     source_code: Lähdekoodi
     status_count_after:
       one: tila
       other: tilanne
     status_count_before: He ovat luoneet
+    tagline: Seuraa ja löydä uusia kavereita
     terms: Käyttöehdot
     unavailable_content_description:
       domain: Palvelin
@@ -59,6 +61,7 @@ fi:
     roles:
       admin: Ylläpitäjä
       bot: Botti
+      group: Ryhmä
       moderator: Moderaattori
     unavailable: Profiili ei saatavilla
     unfollow: Lopeta seuraaminen
@@ -190,19 +193,27 @@ fi:
         update_custom_emoji: "%{name} päivitti emojin %{target}"
         update_status: "%{name} päivitti käyttäjän %{target} tilan"
       title: Auditointiloki
+    announcements:
+      title: Ilmoitukset
     custom_emojis:
+      assign_category: Aseta kategoria
       by_domain: Verkkotunnus
       copied_msg: Emojin paikallisen kopion luonti onnistui
       copy: Kopioi
       copy_failed_msg: Emojista ei voitu tehdä paikallista kopiota
+      create_new_category: Luo uusi kategoria
       created_msg: Emojin luonti onnistui!
       delete: Poista
       destroyed_msg: Emojon poisto onnistui!
       disable: Poista käytöstä
+      disabled: Ei käytössä
       disabled_msg: Emojin poisto käytöstä onnistui
+      emoji: Emoji
       enable: Ota käyttöön
+      enabled: Käytössä
       enabled_msg: Emojin käyttöönotto onnistui
       image_hint: PNG enintään 50 kt
+      list: Listaa
       listed: Listassa
       new:
         title: Lisää uusi mukautettu emoji
@@ -210,12 +221,20 @@ fi:
       shortcode: Lyhennekoodi
       shortcode_hint: Vähintään kaksi merkkiä, vain kirjaimia, numeroita ja alaviivoja
       title: Mukautetut emojit
+      uncategorized: Luokittelemattomat
+      unlist: Poista listalta
       unlisted: Ei listassa
       update_failed_msg: Emojin päivitys epäonnistui
       updated_msg: Emojin päivitys onnistui!
       upload: Lähetä
     dashboard:
       authorized_fetch_mode: Suojattu tila
+      config: Asetukset
+      feature_deletions: Tilien poistot
+      feature_invites: Kutsulinkit
+      feature_profile_directory: Profiilihakemisto
+      feature_registrations: Rekisteröitymiset
+      title: Hallintapaneeli
     domain_blocks:
       add_new: Lisää uusi
       created_msg: Verkkotunnuksen estoa käsitellään
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index bf79bc0ff..1b259d7c9 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -4,7 +4,7 @@ fr:
     about_hashtag_html: Voici les pouets tagués avec <strong>#%{hashtag}</strong>. Vous pouvez interagir avec eux si vous avez un compte n’importe où dans le Fédiverse.
     about_mastodon_html: 'Le réseau social de l''avenir : Pas d''annonces, pas de surveillance institutionnelle, conception éthique et décentralisation ! Possédez vos données avec Mastodon !'
     about_this: À propos
-    active_count_after: actif·ve
+    active_count_after: actif·ve·s
     active_footnote: Utilisateur·rice·s actif·ve·s mensuels (MAU)
     administered_by: 'Administrée par :'
     api: API
@@ -25,7 +25,7 @@ fr:
       Ce compte est un acteur virtuel utilisé pour représenter le serveur lui-même et non un utilisateur individuel.
       Il est utilisé à des fins de fédération et ne doit pas être bloqué à moins que vous ne vouliez bloquer l’instance entière, dans ce cas vous devriez utiliser un bloqueur de domaine.
     learn_more: En savoir plus
-    privacy_policy: Politique de vie privée
+    privacy_policy: Politique de confidentialité
     see_whats_happening: Voir ce qui se passe
     server_stats: 'Statistiques du serveur :'
     source_code: Code source
@@ -40,25 +40,25 @@ fr:
       domain: Serveur
       reason: Motif
       rejecting_media: 'Les fichiers média de ces serveurs ne seront pas traités ou stockés et aucune miniature ne sera affichée, nécessitant un clic vers le fichier d’origine :'
-      silenced: 'Les messages de ces serveurs seront cachés des flux publics et conversations, et les interactions de leurs utilisateur·ice·s ne donneront lieu à aucune notification, à moins que vous ne les suiviez :'
-      suspended: 'Aucune donnée venant de ces serveurs ne sera traitée, stockée ou échangée, rendant toute interaction ou communication avec les utilisateurs de ces serveurs impossible :'
-    unavailable_content_html: Mastodon vous permet généralement de visualiser le contenu et d'interagir avec les utilisateurs de n'importe quel autre serveur dans le fédiverse. Voici les exceptions qui ont été faites sur ce serveur en particulier.
+      silenced: 'Les messages de ces serveurs seront cachés des flux publics et conversations, et les interactions de leurs utilisateur·rice·s ne donneront lieu à aucune notification, à moins que vous ne les suiviez :'
+      suspended: 'Aucune donnée venant de ces serveurs ne sera traitée, stockée ou échangée, rendant toute interaction ou communication avec les utilisateur·rice·s de ces serveurs impossible :'
+    unavailable_content_html: Mastodon vous permet généralement de visualiser le contenu et d'interagir avec les utilisateur·rice·s de n'importe quel autre serveur dans le fédiverse. Voici les exceptions qui ont été faites sur ce serveur en particulier.
     user_count_after:
-      one: utilisateur
-      other: utilisateurs
+      one: utilisateur·rice
+      other: utilisateur·rice·s
     user_count_before: Abrite
     what_is_mastodon: Qu’est-ce que Mastodon ?
   accounts:
     choices_html: "%{name} recommande :"
     endorsements_hint: Vous pouvez recommander des personnes que vous suivez depuis l’interface web, et elles apparaîtront ici.
-    featured_tags_hint: Vous pouvez recommander des hashtags spécifiques qui seront affichés ici.
+    featured_tags_hint: Vous pouvez mettre en avant certains hashtags qui seront affichés ici.
     follow: Suivre
     followers:
       one: Abonné·e
-      other: Abonné⋅e⋅s
+      other: Abonné·e·s
     following: Abonnements
     joined: Inscrit·e en %{date}
-    last_active: actif·ve dernièrement
+    last_active: dernière activité
     link_verified_on: La propriété de ce lien a été vérifiée le %{date}
     media: Médias
     moved_html: "%{name} a changé de compte pour %{new_profile_link} :"
@@ -74,7 +74,7 @@ fr:
       other: Pouets
     posts_tab_heading: Pouets
     posts_with_replies: Pouets & réponses
-    reserved_username: Ce nom d’utilisateur⋅ice est réservé
+    reserved_username: Ce nom d’utilisateur·ice est réservé
     roles:
       admin: Admin
       bot: Robot
@@ -92,9 +92,10 @@ fr:
       delete: Supprimer
       destroyed_msg: Note de modération supprimée avec succès !
     accounts:
+      add_email_domain_block: Mettre le domaine du courriel sur liste noire
       approve: Approuver
       approve_all: Tout approuver
-      are_you_sure: Êtes-vous certain⋅e ?
+      are_you_sure: Voulez-vous vraiment faire ça ?
       avatar: Avatar
       by_domain: Domaine
       change_email:
@@ -119,7 +120,7 @@ fr:
       email_status: État du courriel
       enable: Activer
       enabled: Activé
-      followers: Abonné⋅e⋅s
+      followers: Abonné·e·s
       follows: Abonnements
       header: Entête
       inbox_url: URL d’entrée
@@ -159,7 +160,7 @@ fr:
       remove_avatar: Supprimer l’avatar
       remove_header: Supprimer l’entête
       resend_confirmation:
-        already_confirmed: Cet·te utilisateur·ice est déjà confirmé·e
+        already_confirmed: Cet·te utilisateur·rice est déjà confirmé·e
         send: Renvoyer un courriel de confirmation
         success: Courriel de confirmation envoyé avec succès !
       reset: Réinitialiser
@@ -172,6 +173,7 @@ fr:
         staff: Équipe
         user: Utilisateur
       search: Rechercher
+      search_same_email_domain: Autres utilisateurs·trices avec le même domaine de courriel
       search_same_ip: Autres utilisateur·rice·s avec la même IP
       shared_inbox_url: URL de la boite de réception partagée
       show:
@@ -188,35 +190,71 @@ fr:
       undo_silenced: Démasquer
       undo_suspension: Annuler la suspension
       unsubscribe: Se désabonner
-      username: Nom d’utilisateur⋅ice
+      username: Nom d’utilisateur·ice
       warn: Avertissement
       web: Web
       whitelisted: Sur liste blanche
     action_logs:
+      action_types:
+        assigned_to_self_report: Affecter le signalement
+        change_email_user: Modifier le courriel pour
+        confirm_user: Confirmer l’utilisateur
+        create_account_warning: Créer une alerte
+        create_announcement: Créer une annonce
+        create_custom_emoji: Créer des émojis personnalisés
+        create_domain_allow: Créer un domaine autorisé
+        create_domain_block: Créer un blocage de domaine
+        create_email_domain_block: Créer un blocage de domaine de courriel
+        demote_user: Rétrograder l’utilisateur·ice
+        destroy_announcement: Supprimer l’annonce
+        destroy_custom_emoji: Supprimer des émojis personnalisés
+        destroy_domain_allow: Supprimer le domaine autorisé
+        destroy_domain_block: Supprimer le blocage de domaine
+        destroy_email_domain_block: Supprimer le blocage de domaine de courriel
+        destroy_status: Supprimer le statut
+        disable_2fa_user: Désactiver l’A2F
+        disable_custom_emoji: Désactiver les émojis personnalisés
+        disable_user: Désactiver l’utilisateur·ice
+        enable_custom_emoji: Activer les émojis personnalisées
+        enable_user: Activer l’utilisateur
+        memorialize_account: Mémorialiser le compte
+        promote_user: Promouvoir l’utilisateur
+        remove_avatar_user: Supprimer l’avatar
+        reopen_report: Rouvrir le signalement
+        reset_password_user: Réinitialiser le mot de passe
+        resolve_report: Résoudre le signalement
+        silence_account: Rendre le compte silencieux
+        suspend_account: Suspendre le compte
+        unassigned_report: Ne plus assigner le signalement
+        unsilence_account: Désactiver le silence du compte
+        unsuspend_account: Annuler la suspension du compte
+        update_announcement: Modifier l’annonce
+        update_custom_emoji: Mettre à jour les émojis personnalisés
+        update_status: Mettre à jour le statut
       actions:
         assigned_to_self_report: "%{name} s’est assigné·e le signalement de %{target}"
         change_email_user: "%{name} a modifié l’adresse de courriel de l’utilisateur·rice %{target}"
-        confirm_user: "%{name} adresse courriel confirmée de l’utilisateur·ice %{target}"
+        confirm_user: "%{name} adresse courriel confirmée pour l’utilisateur·rice %{target}"
         create_account_warning: "%{name} a envoyé un avertissement à %{target}"
         create_announcement: "%{name} a créé une nouvelle annonce %{target}"
         create_custom_emoji: "%{name} a importé de nouveaux émojis %{target}"
         create_domain_allow: "%{name} a inscrit le domaine %{target} sur liste blanche"
         create_domain_block: "%{name} a bloqué le domaine %{target}"
         create_email_domain_block: "%{name} a mis le domaine de courriel %{target} sur liste noire"
-        demote_user: "%{name} a rétrogradé l’utilisateur·ice %{target}"
+        demote_user: "%{name} a rétrogradé l’utilisateur·rice %{target}"
         destroy_announcement: "%{name} a supprimé l’annonce %{target}"
         destroy_custom_emoji: "%{name} a détruit l’émoticône %{target}"
         destroy_domain_allow: "%{name} a supprimé le domaine %{target} de la liste blanche"
         destroy_domain_block: "%{name} a débloqué le domaine %{target}"
         destroy_email_domain_block: "%{name} a mis le domaine de courriel %{target} sur liste blanche"
         destroy_status: "%{name} a enlevé le statut de %{target}"
-        disable_2fa_user: "%{name} a désactivé l’authentification à deux facteurs pour l’utilisateur·ice %{target}"
+        disable_2fa_user: "%{name} a désactivé l’authentification à deux facteurs pour l’utilisateur·rice %{target}"
         disable_custom_emoji: "%{name} a désactivé l’émoji %{target}"
-        disable_user: "%{name} a désactivé le login pour l’utilisateur·ice %{target}"
+        disable_user: "%{name} a désactivé la connexion pour l’utilisateur·rice %{target}"
         enable_custom_emoji: "%{name} a activé l’émoji %{target}"
-        enable_user: "%{name} a activé le login pour l’utilisateur·ice %{target}"
+        enable_user: "%{name} a activé la connexion pour l’utilisateur·rice %{target}"
         memorialize_account: "%{name} a transformé le compte de %{target} en une page de mémorial"
-        promote_user: "%{name} a promu l’utilisateur·ice %{target}"
+        promote_user: "%{name} a promu l’utilisateur·rice %{target}"
         remove_avatar_user: "%{name} a supprimé l’avatar de %{target}"
         reopen_report: "%{name} a rouvert le signalement %{target}"
         reset_password_user: "%{name} a réinitialisé le mot de passe de %{target}"
@@ -230,6 +268,9 @@ fr:
         update_custom_emoji: "%{name} a mis à jour l’émoji %{target}"
         update_status: "%{name} a mis à jour le statut de %{target}"
       deleted_status: "(statut supprimé)"
+      empty: Aucun journal trouvé.
+      filter_by_action: Filtrer par action
+      filter_by_user: Filtrer par utilisateur·ice
       title: Journal d’audit
     announcements:
       destroyed_msg: Annonce supprimée avec succès !
@@ -296,7 +337,7 @@ fr:
       pending_users: utilisateur·rice·s en attente d’approbation
       recent_users: Utilisateur·rice·s récent·e·s
       search: Recherche plein texte
-      single_user_mode: Mode utilisateur·ice unique
+      single_user_mode: Mode utilisateur·rice unique
       software: Logiciel
       space: Espace utilisé
       title: Tableau de bord
@@ -347,7 +388,7 @@ fr:
         retroactive:
           silence: Annuler le masquage des comptes existants affectés pour ce domaine
           suspend: Annuler la suspension des comptes existants affectés pour ce domaine
-        title: Annuler le blocage de domaine pour %{domain}
+        title: Annuler le blocage du domaine %{domain}
         undo: Annuler
       undo: Annuler le bloqueur de domaine
       view: Afficher les bloqueurs de domaines
@@ -358,6 +399,7 @@ fr:
       destroyed_msg: Le blocage de domaine de courriel a été désactivé
       domain: Domaine
       empty: Aucun domaine de courriel n’est actuellement sur liste noire.
+      from_html: de %{domain}
       new:
         create: Créer le blocage
         title: Nouveau blocage de domaine de courriel
@@ -394,7 +436,7 @@ fr:
       title: Relations de %{acct}
     relays:
       add_new: Ajouter un nouveau relais
-      delete: Effacer
+      delete: Supprimer
       description_html: Un <strong>relai de fédération</strong> est un serveur intermédiaire qui échange de grandes quantités de pouets publics entre les serveurs qui publient dessus et ceux qui y sont abonnés. <strong>Il peut aider les petits et moyen serveurs à découvrir du contenu sur le fediverse</strong>, ce qui normalement nécessiterait que les membres locaux suivent des gens inscrits sur des serveurs distants.
       disable: Désactiver
       disabled: Désactivé
@@ -420,7 +462,7 @@ fr:
           one: "%{count} signalement"
           other: "%{count} signalements"
       action_taken_by: Intervention de
-      are_you_sure: Êtes vous certain⋅e ?
+      are_you_sure: Voulez-vous vraiment faire ça ?
       assign_to_self: Me l’assigner
       assigned: Modérateur assigné
       by_target_domain: Domaine du compte signalé
@@ -433,7 +475,7 @@ fr:
         create: Ajouter une note
         create_and_resolve: Résoudre avec une note
         create_and_unresolve: Ré-ouvrir avec une note
-        delete: Effacer
+        delete: Supprimer
         placeholder: Décrivez quelles actions ont été prises, ou toute autre mise à jour…
       reopen: Ré-ouvrir le signalement
       report: 'Signalement #%{id}'
@@ -448,14 +490,14 @@ fr:
       updated_at: Mis à jour
     settings:
       activity_api_enabled:
-        desc_html: Nombre de statuts affichés localement, d’utilisateur·ice·s actif·ve·s et de nouveaux·elles utilisateur·ice·s regroupé·e·s par semaine
-        title: Publier des statistiques agrégées sur l’activité des utilisateur·ice·s
+        desc_html: Nombre de statuts affichés localement, de comptes actifs et de nouvelles inscriptions regroupé·e·s par semaine
+        title: Publier des statistiques agrégées sur l’activité des utilisateur·rice·s
       bootstrap_timeline_accounts:
-        desc_html: Séparez les noms d’utilisateur·ice par des virgules. Ne fonctionne qu’avec des comptes locaux et non verrouillés. Si laissé vide, tous les administrateur⋅ice⋅s locaux sont sélectionné⋅e⋅s.
-        title: Abonnements par défaut pour les nouveaux·elles utilisateur·ice·s
+        desc_html: Séparez les noms d’utilisateur·rice·s par des virgules. Ne fonctionne qu’avec des comptes locaux et non verrouillés. Si laissé vide, tous les administrateur·rice·s locaux sont sélectionné⋅e⋅s.
+        title: Abonnements par défaut pour les nouveaux·elles utilisateur·rice·s
       contact_information:
         email: Entrez une adresse courriel publique
-        username: Entrez un nom d’utilisateur⋅ice
+        username: Entrez un nom d’utilisateur·ice
       custom_css:
         desc_html: Modifier l’apparence avec une CSS chargée sur chaque page
         title: CSS personnalisé
@@ -466,11 +508,11 @@ fr:
         all: À tout le monde
         disabled: À personne
         title: Afficher les bloqueurs de domaines
-        users: Pour les utilisateurs locaux connectés
+        users: Aux utilisateur·rice·s connecté·e·s localement
       domain_blocks_rationale:
         title: Montrer la raison
       enable_bootstrap_timeline_accounts:
-        title: Activer le suivi par défaut pour les nouveaux·elles utilisateur·ice·s
+        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
         title: Image d’en-tête
@@ -482,7 +524,7 @@ fr:
         title: Publier la liste des serveurs découverts
       preview_sensitive_media:
         desc_html: Les liens de prévisualisation sur les autres sites web afficheront une vignette même si le média est sensible
-        title: Afficher les médias sensibles dans les prévisualisations OpenGraph
+        title: Montrer les médias sensibles dans les prévisualisations OpenGraph
       profile_directory:
         desc_html: Permettre aux utilisateur·ice·s d’être découvert·e·s
         title: Activer l’annuaire des profils
@@ -491,7 +533,7 @@ fr:
           desc_html: Affiché sur la page d’accueil lorsque les inscriptions sont fermées. Vous pouvez utiliser des balises HTML
           title: Message de fermeture des inscriptions
         deletion:
-          desc_html: Permettre à tou·te·s les utilisateur·ice·s de supprimer leur compte
+          desc_html: Permettre à tou·te·s les utilisateur·rice·s de supprimer leur compte
           title: Autoriser les suppressions de compte
         min_invite_role:
           disabled: Personne
@@ -503,10 +545,10 @@ fr:
           open: N’importe qui peut s’inscrire
         title: Mode d’enregistrement
       show_known_fediverse_at_about_page:
-        desc_html: Lorsque l’option est activée, les pouets provenant de toutes les serveurs connus sont affichés dans la prévisualisation. Sinon, seuls les pouets locaux sont affichés
+        desc_html: Lorsque l’option est activée, les pouets provenant de toutes les serveurs connus sont montrés dans la prévisualisation. Sinon, seuls les pouets locaux sont montrés
         title: Afficher le fediverse connu dans la prévisualisation du fil
       show_staff_badge:
-        desc_html: Montrer un badge de responsable sur une page utilisateur·ice
+        desc_html: Montrer un badge de responsable sur une page utilisateur·rice
         title: Montrer un badge de responsable
       site_description:
         desc_html: Paragraphe introductif sur la page d’accueil. Décrivez ce qui rend spécifique ce serveur Mastodon et toute autre chose importante. Vous pouvez utiliser des balises HTML, en particulier <code>&lt;a&gt;</code> et <code>&lt;em&gt;</code>.
@@ -528,15 +570,18 @@ fr:
         desc_html: Utilisée pour les prévisualisations via OpenGraph et l’API. 1200x630px recommandé
         title: Vignette du serveur
       timeline_preview:
-        desc_html: Afficher le fil public sur la page d’accueil et autoriser l'accès anonyme à l'API du fil public
+        desc_html: Afficher un lien vers le fil public sur la page d’accueil et autoriser l'accès anonyme au fil public via l'API
         title: Autoriser la prévisualisation anonyme du fil global
       title: Paramètres du serveur
       trendable_by_default:
         desc_html: Affecte les hashtags qui n'ont pas été précédemment non autorisés
-        title: Autoriser les hashtags à apparaître dans les tendances sans examen préalable
+        title: Autoriser les hashtags à apparaître dans les tendances sans approbation préalable
       trends:
         desc_html: Afficher publiquement les hashtags approuvés qui sont populaires en ce moment
         title: Hashtags populaires
+    site_uploads:
+      delete: Supprimer le fichier téléversé
+      destroyed_msg: Téléversement sur le site supprimé avec succès !
     statuses:
       back_to_account: Retour à la page du compte
       batch:
@@ -556,13 +601,13 @@ fr:
       accounts_week: Utilisation unique cette semaine
       breakdown: Répartition de l’utilisation actuelle par source
       context: Contexte
-      directory: Dans le répertoire
-      in_directory: "%{count} dans le répertoire"
+      directory: Dans l’annuaire
+      in_directory: "%{count} dans l’annuaire"
       last_active: Dernière activité
       most_popular: Plus populaire
       most_recent: Plus récent
-      name: Mot-clé
-      review: État de traitement
+      name: Hashtag
+      review: État du traitement
       reviewed: Traité
       title: Hashtags
       trending_right_now: Populaire en ce moment
@@ -572,8 +617,7 @@ fr:
     title: Administration
     warning_presets:
       add_new: Ajouter un nouveau
-      delete: Effacer
-      edit: Éditer
+      delete: Supprimer
       edit_preset: Éditer les avertissements prédéfinis
       title: Gérer les avertissements prédéfinis
   admin_mailer:
@@ -585,12 +629,12 @@ fr:
       body_remote: Quelqu’un de %{domain} a signalé %{target}
       subject: Nouveau signalement sur %{instance} (#%{id})
     new_trending_tag:
-      body: 'Le hashtag #%{name} est populaire aujourd’hui, mais il n’a pas été approuvé. Il ne sera pas affiché publiquement à moins que vous l’autorisiez, ou sauvegardiez simplement ce formulaire tel quel pour ne plus jamais en entendre parler.'
-      subject: Nouveau hashtag en attente de traitement sur %{instance} (#%{name})
+      body: 'Le hashtag #%{name} est dans les tendances aujourd’hui, mais il n’a pas été approuvé. Il ne sera pas affiché publiquement à moins que vous l’autorisiez, ou sauvegardez simplement ce formulaire tel quel pour ne plus jamais en entendre parler.'
+      subject: Nouveau hashtag en attente d’approbation sur %{instance} (#%{name})
   aliases:
     add_new: Créer un alias
     created_msg: Un nouvel alias a été créé avec succès. Vous pouvez maintenant déménager depuis l'ancien compte.
-    deleted_msg: Suppression réussie de l'alias. Le déménagement de ce compte vers celui-ci ne sera plus possible.
+    deleted_msg: Alias supprimé avec succès. Le déménagement de ce compte vers celui-ci ne sera plus possible.
     hint_html: Si vous voulez déménager d’un autre compte vers celui-ci, vous pouvez créer ici un alias, qui est nécessaire avant de pouvoir migrer les abonné·e·s de l’ancien compte vers celui-ci. Cette action en soi est <strong>inoffensive et réversible</strong>. <strong>La migration du compte est initiée à partir de l’ancien compte</strong>.
     remove: Détacher l'alias
   appearance:
@@ -618,7 +662,7 @@ fr:
     invalid_url: L’URL fournie est invalide
     regenerate_token: Régénérer le jeton d’accès
     token_regenerated: Jeton d’accès régénéré avec succès
-    warning: Soyez prudent⋅e avec ces données. Ne les partagez pas !
+    warning: Soyez prudent·e avec ces données. Ne les partagez pas !
     your_token: Votre jeton d’accès
   auth:
     apply_for_account: Demander une invitation
@@ -630,7 +674,7 @@ fr:
     description:
       prefix_invited_by_user: "@%{name} vous invite à rejoindre ce serveur Mastodon !"
       prefix_sign_up: Inscrivez-vous aujourd’hui sur Mastodon !
-      suffix: Avec un compte, vous pourrez suivre des gens, publier des statuts et échanger des messages avec les utilisateurs de n'importe quel serveur Mastodon et bien plus !
+      suffix: Avec un compte, vous pourrez suivre des gens, publier des statuts et échanger des messages avec les utilisateur·rice·s de n'importe quel serveur Mastodon et bien plus !
     didnt_get_confirmation: Vous n’avez pas reçu les consignes de confirmation ?
     forgot_password: Mot de passe oublié ?
     invalid_reset_password_token: Le lien de réinitialisation du mot de passe est invalide ou a expiré. Merci de réessayer.
@@ -661,13 +705,14 @@ fr:
     trouble_logging_in: Vous avez un problème pour vous connecter ?
   authorize_follow:
     already_following: Vous suivez déjà ce compte
+    already_requested: Vous avez déjà envoyé une demande d’abonnement à ce compte
     error: Malheureusement, il y a eu une erreur en cherchant les détails du compte distant
     follow: Suivre
     follow_request: 'Vous avez demandé à suivre :'
     following: 'Youpi ! Vous suivez maintenant  :'
     post_follow:
       close: Ou bien, vous pouvez fermer cette fenêtre.
-      return: Afficher le profil de l’utilisateur⋅ice
+      return: Afficher le profil de l’utilisateur·ice
       web: Retour à l’interface web
     title: Suivre %{acct}
   challenge:
@@ -707,11 +752,11 @@ fr:
       email_reconfirmation_html: Si vous ne recevez pas le courriel de confirmation, vous pouvez le <a href="%{path}">demander à nouveau</a>
       irreversible: Vous ne pourrez pas restaurer ou réactiver votre compte
       more_details_html: Pour plus de détails, voir la <a href="%{terms_path}">politique de confidentialité</a>.
-      username_available: Votre nom d’utilisateur·ice sera à nouveau disponible
-      username_unavailable: Votre nom d’utilisateur·ice restera indisponible
+      username_available: Votre nom d’utilisateur·rice sera à nouveau disponible
+      username_unavailable: Votre nom d’utilisateur·rice restera indisponible
   directories:
     directory: Annuaire des profils
-    explanation: Découvrir des utilisateurs en se basant sur leurs centres d’intérêt
+    explanation: Découvrir des utilisateur·rice·s en selon leurs centres d’intérêt
     explore_mastodon: Explorer %{title}
   domain_validator:
     invalid_domain: n’est pas un nom de domaine valide
@@ -748,10 +793,10 @@ fr:
     mutes: Vous masquez
     storage: Médias stockés
   featured_tags:
-    add_new: Ajouter un nouvel hashtag
+    add_new: Ajouter un nouveau hashtag
     errors:
-      limit: Vous avez déjà recommandé le nombre maximum de hashtags
-    hint_html: "<strong>Que sont les hashtags vedettes ?</strong> Ils sont affichés avec emphase sur votre flux d'actualités publique et permettent aux gens de parcourir vos messages publics spécifiquement sous ces hashtags. Ils sont un excellent outil pour garder trace des œuvres créatives ou des projets à long terme."
+      limit: Vous avez déjà mis en avant le nombre maximum de hashtags
+    hint_html: "<strong>Que sont les hashtags mis en avant ?</strong> Ils sont affichés en évidence sur votre profil public et permettent aux gens de parcourir vos messages publics qui utilisent ces hashtags. Ils sont un excellent outil pour garder la trace d’activités créatrices ou de projets de long terme."
   filters:
     contexts:
       account: Profils
@@ -765,7 +810,7 @@ fr:
       invalid_context: Contexte invalide ou insuffisant
       invalid_irreversible: Le filtrage irréversible ne fonctionne que pour l’accueil et les notifications
     index:
-      delete: Effacer
+      delete: Supprimer
       empty: Vous n'avez aucun filtre.
       title: Filtres
     new:
@@ -817,8 +862,8 @@ fr:
     types:
       blocking: Liste de comptes bloqués
       domain_blocking: Liste des serveurs bloqués
-      following: Liste d’utilisateur⋅ice⋅s suivi⋅e⋅s
-      muting: Liste d’utilisateur⋅ice⋅s que vous masquez
+      following: Liste d’utilisateur·rice·s suivi·e·s
+      muting: Liste d’utilisateur·rice·s que vous masquez
     upload: Importer
   in_memoriam_html: En mémoire de.
   invites:
@@ -849,6 +894,7 @@ fr:
   media_attachments:
     validations:
       images_and_video: Impossible de joindre une vidéo à un statut contenant déjà des images
+      not_ready: Impossible de joindre les fichiers en traitements. Réessayez dans un instant !
       too_many: Impossible de joindre plus de 4 fichiers
   migrations:
     acct: A déménagé vers
@@ -857,7 +903,7 @@ fr:
     cancelled_msg: Suppression de la redirection réussie.
     errors:
       already_moved: est le même compte que vous avez déjà déplacé vers
-      missing_also_known_as: ne référence pas rétroactivement ce compte
+      missing_also_known_as: ne référence pas ce compte en retour
       move_to_self: ne peut pas être le compte actuel
       not_found: n'a pas été trouvé
       on_cooldown: Vous êtes soumis·e à un temps de rechargement
@@ -905,7 +951,7 @@ fr:
     follow_request:
       action: Gérer les demandes d’abonnement
       body: "%{name} a demandé à vous suivre"
-      subject: 'Abonné⋅e·s en attente : %{name}'
+      subject: 'Abonné·e·s en attente : %{name}'
       title: Nouvelle demande d’abonnement
     mention:
       action: Répondre
@@ -1044,7 +1090,7 @@ fr:
     development: Développement
     edit_profile: Modifier le profil
     export: Export de données
-    featured_tags: Hashtags recommandés
+    featured_tags: Hashtags mis en avant
     identity_proofs: Preuves d’identité
     import: Import de données
     import_and_export: Import et export
@@ -1070,6 +1116,8 @@ fr:
     disallowed_hashtags:
       one: 'contient un hashtag désactivé : %{tags}'
       other: 'contient les hashtags désactivés : %{tags}'
+    errors:
+      in_reply_not_found: Le statut auquel vous essayez de répondre ne semble pas exister.
     language_detection: Détecter automatiquement la langue
     open_in_web: Ouvrir sur le web
     over_character_limit: limite de %{max} caractères dépassée
@@ -1086,13 +1134,13 @@ fr:
         one: "%{count} vote"
         other: "%{count} votes"
       vote: Voter
-    show_more: Afficher plus
+    show_more: Déplier
     show_thread: Afficher le fil de discussion
     sign_in_to_participate: Inscrivez-vous pour prendre part à la conversation
     title: '%{name} : "%{quote}"'
     visibilities:
       private: Abonné⋅e⋅s uniquement
-      private_long: Seul⋅e⋅s vos abonné⋅e⋅s verront vos statuts
+      private_long: Afficher seulement à vos vos abonné·e·s
       public: Public
       public_long: Tout le monde peut voir vos statuts
       unlisted: Public sans être affiché sur le fil public
@@ -1111,7 +1159,7 @@ fr:
       <ul>
       <li><em>Informations de base sur votre compte</em> : Si vous vous inscrivez sur ce serveur, il vous sera demandé de rentrer un identifiant, une adresse électronique et un mot de passe. Vous pourrez également ajouter des informations additionnelles sur votre profil, telles qu’un nom public et une biographie, ainsi que téléverser une image de profil et une image d’en-tête. Vos identifiant, nom public, biographie, image de profil et image d’en-tête seront toujours affichés publiquement.</li>
       <li><em>Posts, liste d’abonnements et autres informations publiques</em> : La liste de vos abonnements ainsi que la liste de vos abonné·e·s sont publiques. Quand vous postez un message, la date et l’heure d’envoi ainsi que le nom de l’application utilisée pour sa transmission sont enregistré·e·s. Des médias, tels que des images ou des vidéos, peuvent être joints aux messages. Les posts publics et non listés sont affichés publiquement. Quand vous mettez en avant un post sur votre profil, ce post est également affiché publiquement. Vos messages sont délivrés à vos abonné·e·s, ce qui, dans certains cas, signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Quand vous supprimer un post, il est probable que vos abonné·e·s en soient informé·e·s. Partager un message ou le marquer comme favori est toujours une action publique.</li>
-      <li><em>Posts directs et abonné·e·s uniquement</em> : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne fois pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. <em>Gardez s’il-vous-plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages</em> et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. <em>Ne partager aucune information sensible à l’aide de Mastodon.</em></li>
+      <li><em>Posts directs et abonné·e·s uniquement</em> : Tous les posts sont stockés et traités par le serveur. Les messages abonné·e·s uniquement ne sont transmis qu’à vos abonné·e·s et aux personnes mentionnées dans le corps du message, tandis que les messages directs ne sont transmis qu’aux personnes mentionnées. Dans certains cas, cela signifie qu’ils sont délivrés à des serveurs tiers et que ces derniers en stockent une copie. Nous faisons un effort de bonne foi pour en limiter l’accès uniquement aux personnes autorisées, mais ce n’est pas nécessairement le cas des autres serveurs. Il est donc très important que vous vérifiiez les serveurs auxquels appartiennent vos abonné·e·s. Il vous est possible d’activer une option dans les paramètres afin d’approuver et de rejeter manuellement les nouveaux·lles abonné·e·s. <em>Gardez s’il vous plaît en mémoire que les opérateur·rice·s du serveur ainsi que celles et ceux de n’importe quel serveur récepteur peuvent voir ces messages</em> et qu’il est possible pour les destinataires de faire des captures d’écran, de copier et plus généralement de repartager ces messages. <em>Ne partager aucune information sensible à l’aide de Mastodon.</em></li>
       <li><em>IP et autres métadonnées</em> : Quand vous vous connectez, nous enregistrons votre adresse IP ainsi que le nom de votre navigateur web. Toutes les sessions enregistrées peuvent être consultées dans les paramètres, afin que vous puissiez les surveiller et éventuellement les révoquer. La dernière adresse IP utilisée est conservée pour une durée de 12 mois. Nous sommes également susceptibles de conserver les journaux du serveur, ce qui inclut l’adresse IP de chaque requête reçue.</li>
       </ul>
 
@@ -1124,7 +1172,7 @@ fr:
       <ul>
       <li>Pour vous fournir les fonctionnalités de base de Mastodon. Vous ne pouvez interagir avec le contenu des autres et poster votre propre contenu que lorsque vous êtes connecté·e. Par exemple, vous pouvez vous abonner à plusieurs autres comptes pour voir l’ensemble de leurs posts dans votre fil d’accueil personnalisé.</li>
       <li>Pour aider à la modération de la communauté, par exemple, comparer votre adresse IP à d’autres afin de déterminer si un bannissement a été contourné ou si une autre violation aux règles a été commise.</li>
-      <li>L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyez des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour tout autres requêtes ou questions.</li>
+      <li>L’adresse électronique que vous nous avez fournie peut être utilisée pour vous envoyer des informations, des notifications lorsque d’autres personnes interagissent avec votre contenu ou vous envoient des messages, pour répondre à des demandes de votre part ainsi que pour touts autres requêtes ou questions.</li>
       </ul>
 
       <hr class="spacer" />
@@ -1152,7 +1200,7 @@ fr:
 
       <h3 id="cookies">Utilisons-nous des témoins de connexion ?</h3>
 
-      <p>Oui. Les témoins de connexion sont de petits fichiers qu’un site ou un service transféres sur le disque dur de votre ordinateur via votre navigateur web (si vous l’avez autorisé). Ces témoins permettent au site de reconnaître votre navigateur et de, dans le cas où vous possédez un compte, de vous associer avec ce dernier.</p>
+      <p>Oui. Les témoins de connexion sont de petits fichiers qu’un site ou un service transfère sur le disque dur de votre ordinateur via votre navigateur web (si vous l’avez autorisé). Ces témoins permettent au site de reconnaître votre navigateur et de, dans le cas où vous possédez un compte, de vous associer avec ce dernier.</p>
 
       <p>Nous utilisons les témoins de connexion comme un moyen de comprendre et de nous souvenir de vos préférences pour vos prochaines visites.</p>
 
@@ -1164,13 +1212,13 @@ fr:
 
       <p>Votre contenu public peut être téléchargé par d’autres serveurs du réseau. Dans le cas où vos abonné·e·s et vos destinataires résideraient sur des serveurs différents du vôtre, vos posts publics et abonné·e·s uniquement peuvent être délivrés vers les serveurs de vos abonné·e·s tandis que vos messages directs sont délivrés aux serveurs de vos destinataires.</p>
 
-      <p>Quand vous autorisez une application à utiliser votre compte, en fonction de l’étendue des permissions que vous approuvez, il est possible qu’elle puisse accéder aux informations publiques de votre profil, votre liste d’abonnements, votre liste d’abonné·e·s, vos listes, tout vos posts et vos favoris. Les applications ne peuvent en aucun cas accéder à votre adresse électronique et à votre mot de passe.</p>
+      <p>Quand vous autorisez une application à utiliser votre compte, en fonction de l’étendue des permissions que vous approuvez, il est possible qu’elle puisse accéder aux informations publiques de votre profil, votre liste d’abonnements, votre liste d’abonné·e·s, vos listes, tous vos posts et vos favoris. Les applications ne peuvent en aucun cas accéder à votre adresse électronique et à votre mot de passe.</p>
 
       <hr class="spacer" />
 
       <h3 id="children">Utilisation de ce site par les enfants</h3>
 
-      <p>Si ce serveur est situé dans dans l’UE ou l’EEE : Notre site, produits et services sont tous destinés à des personnes âgées de 16 ans ou plus. Si vous avez moins de 16 ans, en application du RGPD (<a href="https://fr.wikipedia.org/wiki/R%C3%A8glement_g%C3%A9n%C3%A9ral_sur_la_protection_des_donn%C3%A9es">Règlement Général sur la Protection des Données</a>), merci de ne pas utiliser ce site.</p>
+      <p>Si ce serveur est situé dans l’UE ou l’EEE : Notre site, produits et services sont tous destinés à des personnes âgées de 16 ans ou plus. Si vous avez moins de 16 ans, en application du RGPD (<a href="https://fr.wikipedia.org/wiki/R%C3%A8glement_g%C3%A9n%C3%A9ral_sur_la_protection_des_donn%C3%A9es">Règlement Général sur la Protection des Données</a>), merci de ne pas utiliser ce site.</p>
 
       <p>Si ce serveur est situé dans aux États-Unis d’Amérique : Notre site, produits et services sont tous destinés à des personnes âgées de 13 ans ou plus. Si vous avez moins de 13 ans, en application du COPPA (<a href="https://fr.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act">Children's Online Privacy Protection Act</a>), merci de ne pas utiliser ce site.</p>
 
@@ -1218,8 +1266,8 @@ fr:
     warning:
       explanation:
         disable: Lorsque votre compte est gelé, les données de votre compte demeurent intactes, mais vous ne pouvez effectuer aucune action jusqu’à ce qu’il soit débloqué.
-        silence: Lorsque votre compte est limité, seulement les utilisateurs qui vous suivent déjà verront vos pouets sur ce serveur, et vous pourriez être exclu de plusieurs listes publiques. Néanmoins, d’autres utilisateurs peuvent vous suivre manuellement.
-        suspend: Votre compte a été suspendu, et tous vos pouets et vos fichiers multimédia téléversés ont été supprimés irréversiblement de ce serveur, et des serveurs où vous aviez des abonné⋅e⋅s.
+        silence: Lorsque votre compte est limité, seul·e·s les utilisateur·rice·s qui vous suivent déjà verront vos pouets sur ce serveur, et vous pourriez être exclu de plusieurs listes publiques. Néanmoins, d’autres utilisateur·rice·s peuvent vous suivre manuellement.
+        suspend: Votre compte a été suspendu, et tous vos pouets et vos fichiers multimédia téléversés ont été supprimés irréversiblement de ce serveur, et des serveurs où vous aviez des abonné·e·s.
       get_in_touch: Vous pouvez répondre à cette adresse pour entrer en contact avec l’équipe de %{instance}.
       review_server_policies: Passer en revue les politiques du serveur
       statuses: 'Spécialement, pour :'
@@ -1242,7 +1290,7 @@ fr:
       full_handle: Votre identifiant complet
       full_handle_hint: C’est ce que vous diriez à vos ami·e·s pour leur permettre de vous envoyer un message ou vous suivre à partir d’un autre serveur.
       review_preferences_action: Modifier les préférences
-      review_preferences_step: Assurez-vous de définir vos préférences, telles que les courriels que vous aimeriez recevoir ou le niveau de confidentialité auquel vous aimeriez que vos messages soient soumis par défaut. Si vous n’avez pas le mal des transports, vous pouvez choisir d’activer la lecture automatique des GIF.
+      review_preferences_step: Assurez-vous de définir vos préférences, telles que les courriels que vous aimeriez recevoir ou le niveau de confidentialité auquel vous publier vos messages par défaut. Si vous n’avez pas le mal des transports, vous pouvez choisir d’activer la lecture automatique des GIF.
       subject: Bienvenue sur Mastodon
       tip_federated_timeline: La fil public global est une vue en direct du réseau Mastodon. Mais elle n’inclut que les personnes auxquelles vos voisin·es sont abonné·e·s, donc elle n’est pas complète.
       tip_following: Vous suivez les administrateur·rice·s de votre serveur par défaut. Pour trouver d’autres personnes intéressantes, consultez les fils publics local et global.
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index c3a33932d..35d8ac2d6 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -92,6 +92,7 @@ gl:
       delete: Eliminar
       destroyed_msg: Nota de moderación eliminada de xeito correcto!
     accounts:
+      add_email_domain_block: Bloquear o dominio do email
       approve: Aprobar
       approve_all: Aprobar todos
       are_you_sure: Está segura?
@@ -172,6 +173,7 @@ gl:
         staff: Persoal (staff)
         user: Usuaria
       search: Procurar
+      search_same_email_domain: Outras usuarias co mesmo dominio de email
       search_same_ip: Outras usuarias co mesmo IP
       shared_inbox_url: URL da caixa de entrada compartida
       show:
@@ -193,6 +195,42 @@ gl:
       web: Web
       whitelisted: Lista branca
     action_logs:
+      action_types:
+        assigned_to_self_report: Asignar denuncia
+        change_email_user: Editar email do usuario
+        confirm_user: Confirmar usuario
+        create_account_warning: Crear aviso
+        create_announcement: Crear anuncio
+        create_custom_emoji: Crear emoticonas personalizadas
+        create_domain_allow: Crear permiso de dominio
+        create_domain_block: Crear bloqueo de dominio
+        create_email_domain_block: Crear bloqueo de dominio de correo electrónico
+        demote_user: Degradar usuario
+        destroy_announcement: Eliminar anuncio
+        destroy_custom_emoji: Eliminar emoticona personalizada
+        destroy_domain_allow: Eliminar permiso de dominio
+        destroy_domain_block: Eliminar bloqueo de dominio
+        destroy_email_domain_block: Eliminar bloqueo de dominio de correo electrónico
+        destroy_status: Eliminar estado
+        disable_2fa_user: Desactivar autenticación de dous factores
+        disable_custom_emoji: Deshabilitar emoticona personalizada
+        disable_user: Deshabilitar usuario
+        enable_custom_emoji: Habilitar emoticona personalizada
+        enable_user: Activar usuario
+        memorialize_account: Transformar en conta conmemorativa
+        promote_user: Promover usuario
+        remove_avatar_user: Eliminar avatar
+        reopen_report: Reabrir denuncia
+        reset_password_user: Restabelecer contrasinal
+        resolve_report: Resolver denuncia
+        silence_account: Silenciar conta
+        suspend_account: Suspender conta
+        unassigned_report: Desasignar denuncia
+        unsilence_account: Deixar de silenciar conta
+        unsuspend_account: Retirar suspensión de conta
+        update_announcement: Actualizar anuncio
+        update_custom_emoji: Actualizar emoticona personalizada
+        update_status: Actualizar estado
       actions:
         assigned_to_self_report: "%{name} atribuíu a denuncia %{target} a el mesmo"
         change_email_user: "%{name} cambiou o enderezo de correo-e da usuaria %{target}"
@@ -230,6 +268,9 @@ gl:
         update_custom_emoji: "%{name} actualizou a emoticona %{target}"
         update_status: "%{name} actualizou o estado de %{target}"
       deleted_status: "(estado eliminado)"
+      empty: Non se atoparon rexistros.
+      filter_by_action: Filtrar por acción
+      filter_by_user: Filtrar por usuario
       title: Rexistro de auditoría
     announcements:
       destroyed_msg: Anuncio eliminado de xeito correcto!
@@ -358,6 +399,7 @@ gl:
       destroyed_msg: Eliminouse de xeito correcto o dominio de email da listaxe negra
       domain: Dominio
       empty: Actualmente non hai dominios de email na listaxe negra.
+      from_html: desde %{domain}
       new:
         create: Engadir dominio
         title: Nova entrada na listaxe negra de email
@@ -537,6 +579,9 @@ gl:
       trends:
         desc_html: Amosar de xeito público cancelos revisados previamente que actualmente son tendencia
         title: Cancelos en tendencia
+    site_uploads:
+      delete: Eliminar o ficheiro subido
+      destroyed_msg: Eliminado correctamente o subido!
     statuses:
       back_to_account: Voltar a páxina da conta
       batch:
@@ -573,7 +618,6 @@ gl:
     warning_presets:
       add_new: Engadir novo
       delete: Eliminar
-      edit: Editar
       edit_preset: Editar aviso preestablecido
       title: Xestionar avisos preestablecidos
   admin_mailer:
@@ -661,6 +705,7 @@ gl:
     trouble_logging_in: Problemas para conectar?
   authorize_follow:
     already_following: Xa está a seguir esta conta
+    already_requested: Xa tes enviada unha solicitude de seguimento a esa conta
     error: Desgraciadamente, algo fallou ao buscar a conta remota
     follow: Seguir
     follow_request: 'Enviou unha petición de seguimento a:'
@@ -849,6 +894,7 @@ gl:
   media_attachments:
     validations:
       images_and_video: Non pode anexar un vídeo a un estado que xa contén imaxes
+      not_ready: Non se poden anexar ficheiros que aínda se están a procesar. Agarda un intre!
       too_many: Non pode anexar máis de 4 ficheiros
   migrations:
     acct: nomeusuaria@dominio da nova conta
@@ -1070,6 +1116,8 @@ gl:
     disallowed_hashtags:
       one: 'contiña un cancelo non permitido: %{tags}'
       other: 'contiña uns cancelos non permitidos: %{tags}'
+    errors:
+      in_reply_not_found: O estado ó cal tentas respostar semella que non existe.
     language_detection: Detección automática do idioma
     open_in_web: Abrir na web
     over_character_limit: Excedeu o límite de caracteres %{max}
diff --git a/config/locales/hi.yml b/config/locales/hi.yml
index 401d07cf6..fc4805625 100644
--- a/config/locales/hi.yml
+++ b/config/locales/hi.yml
@@ -19,7 +19,7 @@ hi:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/hr.yml b/config/locales/hr.yml
index 9dd14c1dd..d7bd91c7a 100644
--- a/config/locales/hr.yml
+++ b/config/locales/hr.yml
@@ -50,7 +50,7 @@ hr:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   exports:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 2d7f3a137..30331b2cb 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -11,9 +11,7 @@ hu:
     apps: Mobil appok
     apps_platforms: Használd a Mastodont iOS-ről, Androidról vagy más platformról
     browse_directory: Böngészd a profilokat és szűrj érdeklődési körre
-    browse_local_posts: 'Nézz bele a szerver publikus, élő adatfolyamába
-
-'
+    browse_local_posts: Nézz bele a szerver publikus, élő adatfolyamába
     browse_public_posts: Nézz bele a Mastodon élő adatfolyamába
     contact: Kapcsolat
     contact_missing: Nincs megadva
@@ -94,6 +92,7 @@ hu:
       delete: Törlés
       destroyed_msg: Moderációs bejegyzés törölve!
     accounts:
+      add_email_domain_block: Email domain tiltólistára vétele
       approve: Jóváhagyás
       approve_all: Mindet jóváhagy
       are_you_sure: Biztos vagy benne?
@@ -174,6 +173,7 @@ hu:
         staff: Stáb
         user: Felhasználó
       search: Keresés
+      search_same_email_domain: Felhasználók ugyanezzel az email domainnel
       search_same_ip: Más felhasználók ugyanezzel az IP-vel
       shared_inbox_url: Megosztott bejövő üzenetek URL
       show:
@@ -195,27 +195,63 @@ hu:
       web: Web
       whitelisted: Engedélyező-listán
     action_logs:
+      action_types:
+        assigned_to_self_report: Jelentés hozzárendelése
+        change_email_user: Felhasználó e-mail címének módosítása
+        confirm_user: Felhasználó megerősítése
+        create_account_warning: Figyelmeztetés létrehozása
+        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
+        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_status: Állapot törlése
+        disable_2fa_user: Kétlépcsős hitelesítés letiltása
+        disable_custom_emoji: Egyéni emodzsi letiltása
+        disable_user: Felhasználói letiltása
+        enable_custom_emoji: Egyéni emodzsi engedélyezése
+        enable_user: Felhasználó engedélyezése
+        memorialize_account: Fiók emlékké nyilvánítása
+        promote_user: Felhasználó előléptetése
+        remove_avatar_user: Profilkép eltávolítása
+        reopen_report: Jelentés újranyitása
+        reset_password_user: Jelszó visszaállítása
+        resolve_report: Jelentés megoldása
+        silence_account: Fiók némítása
+        suspend_account: Fiók felfüggesztése
+        unassigned_report: Jelentés hozzárendelésének megszüntetése
+        unsilence_account: Fiók némításának feloldása
+        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_status: Állapot frissítése
       actions:
         assigned_to_self_report: "%{name} a %{target} bejelentést magához rendelte"
         change_email_user: "%{name} megváltoztatta %{target} felhasználó e-mail címét"
         confirm_user: "%{name} megerősítette e-mail címét: %{target}"
         create_account_warning: "%{name} figyelmeztetést küldött %{target} felhasználónak"
         create_announcement: "%{name} új közleményt hozott létre %{target}"
-        create_custom_emoji: "%{name} új emojit töltött fel: %{target}"
+        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}"
         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 emojit: %{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_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"
-        disable_custom_emoji: "%{name} letiltotta az alábbi emojit: %{target}"
+        disable_custom_emoji: "%{name} letiltotta az alábbi emodzsit: %{target}"
         disable_user: "%{name} letiltotta az alábbi felhasználó bejelentkezését: %{target}"
-        enable_custom_emoji: "%{name} engedélyezte az alábbi emojit: %{target}"
+        enable_custom_emoji: "%{name} engedélyezte az alábbi emodzsit: %{target}"
         enable_user: "%{name} engedélyezte az alábbi felhasználó bejelentkezését: %{target}"
         memorialize_account: "%{name} emléket állított az alábbi felhasználónak: %{target}"
         promote_user: "%{name} előléptette az alábbi felhasználót: %{target}"
@@ -229,9 +265,12 @@ hu:
         unsilence_account: "%{name} feloldotta a némítást %{target} felhasználói fiókján"
         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 emojit: %{target}"
+        update_custom_emoji: "%{name} frissítette az alábbi emodzsit: %{target}"
         update_status: "%{name} frissítette %{target} felhasználó tülkjét"
       deleted_status: "(törölt tülk)"
+      empty: Nem található napló.
+      filter_by_action: Szűrés művelet alapján
+      filter_by_user: Szűrés felhasználó alapján
       title: Audit napló
     announcements:
       destroyed_msg: A közlemény sikeresen törölve!
@@ -251,34 +290,34 @@ hu:
     custom_emojis:
       assign_category: Kategóriák
       by_domain: Domain
-      copied_msg: Sikeresen létrehoztuk az emoji helyi másolatát
+      copied_msg: Sikeresen létrehoztuk az emodzsi helyi másolatát
       copy: Másolás
-      copy_failed_msg: Emoji helyi másolatának létrehozása sikertelen
+      copy_failed_msg: Emodzsi helyi másolatának létrehozása sikertelen
       create_new_category: Új kategória létrehozása
-      created_msg: Emoji létrehozva!
+      created_msg: Emodzsi létrehozva!
       delete: Törlés
-      destroyed_msg: Emoji törlése sikeres!
+      destroyed_msg: Emodzsi törlése sikeres!
       disable: Letiltás
       disabled: Letiltva
-      disabled_msg: Emoji letiltva
-      emoji: Emoji
+      disabled_msg: Emodzsi letiltva
+      emoji: Emodzsi
       enable: Engedélyezés
       enabled: Engedélyezve
-      enabled_msg: Emoji engedélyezve
+      enabled_msg: Emodzsji engedélyezve
       image_hint: PNG (maximális méret 50KB)
       list: Listázás
       listed: Listázva
       new:
-        title: Új egyedi emoji hozzáadása
+        title: Új egyedi emodzsi hozzáadása
       overwrite: Felülírás
       shortcode: Rövidítés
       shortcode_hint: Legalább két karakter, csak betűk, számok és alsóvonás
-      title: Egyedi emojik
+      title: Egyedi emodzsik
       uncategorized: Nem kategorizált
       unlist: Elrejtés a listáról
       unlisted: Nincs listázva
-      update_failed_msg: Nem sikerült frissíteni az emojit
-      updated_msg: Emoji sikeresen frissítve!
+      update_failed_msg: Nem sikerült frissíteni az emodzsit
+      updated_msg: Emodzsi sikeresen frissítve!
       upload: Feltöltés
     dashboard:
       authorized_fetch_mode: Áttöltő üzemmód engedélyezve
@@ -360,6 +399,7 @@ hu:
       destroyed_msg: E-mail domain sikeresen eltávolítva a feketelistáról
       domain: Domain
       empty: Nincs email domain a feketelistán.
+      from_html: "%{domain}-ról"
       new:
         create: Domain hozzáadása
         title: Új e-mail feketelista bejegyzés
@@ -539,6 +579,9 @@ hu:
       trends:
         desc_html: Előzetesen engedélyezett és most trendi hashtagek nyilvános mutatása
         title: Trendi hashtagek
+    site_uploads:
+      delete: Feltöltött fájl törlése
+      destroyed_msg: Sikeresen töröltük a site feltöltését!
     statuses:
       back_to_account: Vissza a fiók oldalára
       batch:
@@ -575,7 +618,6 @@ hu:
     warning_presets:
       add_new: Új hozzáadása
       delete: Törlés
-      edit: Szerkesztés
       edit_preset: Figyelmeztetés szerkesztése
       title: Figyelmeztetések
   admin_mailer:
@@ -663,6 +705,7 @@ hu:
     trouble_logging_in: Problémád van a bejelentkezéssel?
   authorize_follow:
     already_following: Már követed ezt a felhasználót
+    already_requested: Már küldtél követési kérelmet ennek a fióknak
     error: Hiba történt a távoli felhasználó keresésekor
     follow: Követés
     follow_request: 'Engedélyt kértél az alábbi felhasználó követésére:'
@@ -851,6 +894,7 @@ hu:
   media_attachments:
     validations:
       images_and_video: Nem csatolhatsz videót olyan tülkhöz, amelyhez már csatoltál képet
+      not_ready: Nem lehet olyan fájlt csatolni, melynek még nem fejeződött be a feldolgozása. Próbáld kicsit később!
       too_many: Maximum négy fájlt csatolhatsz a tülkhöz
   migrations:
     acct: Az új fiók felhasznalonev@domain formátumban
@@ -956,7 +1000,7 @@ hu:
   reactions:
     errors:
       limit_reached: A különböző reakciók száma elérte a határértéket
-      unrecognized_emoji: nem ismert emoji
+      unrecognized_emoji: nem ismert emodzsi
   relationships:
     activity: Fiók aktivitás
     dormant: Elhagyott
@@ -1072,6 +1116,8 @@ hu:
     disallowed_hashtags:
       one: 'tiltott hashtaget tartalmaz: %{tags}'
       other: 'tiltott hashtageket tartalmaz: %{tags}'
+    errors:
+      in_reply_not_found: Már nem létezik az a tülk, melyre válaszolni szeretnél.
     language_detection: Nyelv automatikus felismerése
     open_in_web: Megnyitás a weben
     over_character_limit: Túllépted a maximális %{max} karakteres keretet
diff --git a/config/locales/hy.yml b/config/locales/hy.yml
index 2c692235b..a0bed56fd 100644
--- a/config/locales/hy.yml
+++ b/config/locales/hy.yml
@@ -20,6 +20,11 @@ hy:
       other: Հետևորդներ
     media: Մեդիա
     never_active: Երբեք
+    roles:
+      admin: Ադմինիստրատոր
+      bot: Բոտ
+      group: Խումբ
+      moderator: Մոդերատոր
     unfollow: Չհետևել
   admin:
     account_moderation_notes:
@@ -33,7 +38,7 @@ hy:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/id.yml b/config/locales/id.yml
index ca222946c..27bfccc22 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -88,6 +88,7 @@ id:
       delete: Hapus
       destroyed_msg: Catatan moderasi berhasil dihapus!
     accounts:
+      add_email_domain_block: Masukkan domain surel ke daftar hitam
       approve: Terima
       approve_all: Terima semua
       are_you_sure: Anda yakin?
@@ -168,6 +169,7 @@ id:
         staff: Staf
         user: Pengguna
       search: Cari
+      search_same_email_domain: Pengguna lain dengan domain surel yang sama
       search_same_ip: Pengguna lain dengan IP yang sama
       shared_inbox_url: URL kotak masuk bersama
       show:
@@ -353,6 +355,7 @@ id:
       destroyed_msg: Berhasil menghapus domain surel dari daftar hitam
       domain: Domain
       empty: Tidak ada domain surel yang masuk daftar hitam.
+      from_html: dari %{domain}
       new:
         create: Tambah domain
         title: Entri daftar hitam surel baru
@@ -529,6 +532,9 @@ id:
       trends:
         desc_html: Tampilkan secara publik tagar tertinjau yang kini sedang tren
         title: Tagar sedang tren
+    site_uploads:
+      delete: Hapus berkas yang diunggah
+      destroyed_msg: Situs yang diunggah berhasil dihapus!
     statuses:
       back_to_account: Kembali ke halaman akun
       batch:
@@ -565,7 +571,6 @@ id:
     warning_presets:
       add_new: Tambah baru
       delete: Hapus
-      edit: Sunting
       edit_preset: Sunting preset peringatan
       title: Kelola preset peringatan
   admin_mailer:
@@ -653,6 +658,7 @@ id:
     trouble_logging_in: Kesulitan masuk?
   authorize_follow:
     already_following: Anda sudah mengikuti akun ini
+    already_requested: Anda sudah mengirimkan permintaan untuk mengikuti akun tersebut
     error: Sayangnya, ada error saat melihat akun remote
     follow: Ikuti
     follow_request: 'Anda telah mengirim permintaan untuk mengikuti ke:'
@@ -716,7 +722,7 @@ id:
     '422':
       content: Verifikasi keamanan gagal. Apa anda memblokir cookie?
       title: Verifikasi keamanan gagal
-    '429': Throttled
+    '429': Lambat
     '500':
       content: Maaf, ada sesuatu yang salah pada sistem kami.
       title: Halaman ini tidak benar
@@ -755,6 +761,7 @@ id:
       title: Ubah saringan
     errors:
       invalid_context: Konteks tidak ada atau invalid
+      invalid_irreversible: Penyaringan yang tidak dapat dipulihkan hanya bekerja di beranda atau konteks notifikasi
     index:
       delete: Hapus
       empty: Anda tidak memiliki filter.
@@ -838,6 +845,7 @@ id:
   media_attachments:
     validations:
       images_and_video: Tidak bisa melampirkan video pada status yang telah memiliki gambar
+      not_ready: Tidak dapat melampirkan berkas yang belum selesai diproses. Coba lagi nanti!
       too_many: Tidak dapat melampirkan lebih dari 4 file
   migrations:
     acct: Pindah ke
@@ -846,21 +854,27 @@ id:
     cancelled_msg: Pembatalan peralihan berhasil.
     errors:
       already_moved: adalah akun yang sama yang sudah Anda pindahkan ke
+      missing_also_known_as: ini bukan back-reference akun ini
       move_to_self: tidak boleh akun sekarang
       not_found: tidak dapat ditemukan
+      on_cooldown: Anda berada di masa tenang
     followers_count: Jumlah pengikut saat migrasi
     incoming_migrations: Pindah dari akun berbeda
     incoming_migrations_html: Untuk pindah dari akun lain ke sini, Anda harus <a href="%{path}">membuat alias akun</a> terlebih dahulu.
     moved_msg: Akun Anda dialihkan ke %{acct} dan pengikut Anda akan ikut dipindahkan.
     not_redirecting: Saat ini akun Anda tidak dialihkan ke akun lain.
     on_cooldown: Anda baru saja memindahkan akun Anda. Fungsi ini akan tersedia kembali %{count} hari lagi.
+    past_migrations: Migrasi lampau
     proceed_with_move: Pindahkan pengikut
     redirecting_to: Akun Anda dialihkan ke %{acct}.
     set_redirect: Atur peralihan
     warning:
+      backreference_required: Akun baru harus dikonfigurasi terlebih dahulu agar merujuk ke akun ini
       before: 'Sebelum lanjut, mohon perhatikan catatan ini:'
       cooldown: Setelah pindah akun adalah masa tenang, masa Anda tidak dapat pindah akun lagi
+      disabled_account: Akun Anda tidak akan dapat dipakai secara penuh. Namun, Anda tetap akan memiliki akses ke ekspor data dan aktivasi ulang.
       followers: Tindakan ini akan memindah semua pengikut Anda dari akun sekarang ke akun baru
+      only_redirect_html: Secara alternatif, Anda <a href="%{path}">hanya dapat menaruh tulisan mengarahkan ke profil Anda</a>.
       other_data: Tidak akan ada data lagi yang dipindahkan secara otomatis
       redirect: Pemberitahuan peralihan akan dimunculkan pada akun profil Anda dan akun akan dikecualikan dari pencarian
   moderation:
@@ -898,6 +912,8 @@ id:
       subject: "%{name} mem-boost status anda"
       title: Boost baru
   notifications:
+    email_events: Event untuk notifikasi surel
+    email_events_hint: 'Pilih event yang ingin Anda terima notifikasinya:'
     other_settings: Pengaturan notifikasi lain
   number:
     human:
@@ -919,6 +935,7 @@ id:
     errors:
       already_voted: Anda sudah mengikuti japat ini
       duplicate_options: berisi item ganda
+      duration_too_long: terlalu jauh ke masa depan
       duration_too_short: terlalu cepat
       expired: Japat telah berakhir
       invalid_choice: Opsi pilihan yang dipilih tidak ada
@@ -929,11 +946,16 @@ id:
     other: Lainnya
     posting_defaults: Kiriman bawaan
     public_timelines: Linimasa publik
+  reactions:
+    errors:
+      limit_reached: Batas reaksi yang berbeda terpenuhi
+      unrecognized_emoji: bukan emoji yang dikenal
   relationships:
     activity: Aktivitas akun
     dormant: Terbengkalai
     followers: Pengikut
     following: Mengikuti
+    invited: Diundang
     last_active: Terakhir aktif
     most_recent: Terkini
     moved: Dipindah
@@ -1040,6 +1062,8 @@ id:
     content_warning: 'Peringatan konten: %{warning}'
     disallowed_hashtags:
       other: 'berisi tagar yang tidak diizinkan: %{tags}'
+    errors:
+      in_reply_not_found: Status yang ingin Anda balas sudah tidak ada.
     language_detection: Deteksi bahasa secara otomatis
     open_in_web: Buka di web
     over_character_limit: melebihi %{max} karakter
@@ -1126,11 +1150,14 @@ id:
       explanation: Beberapa tips sebelum Anda memulai
       final_action: Mulai mengirim
       final_step: 'Mulai mengirim! Tanpa pengikut, pesan publik Anda akan tetap dapat dilihat oleh akun lain, contohnya di linimasa lokal atau di tagar. Anda mungkin ingin memperkenalkan diri dengan tagar #introductions.'
+      full_handle: Penanganan penuh Anda
       full_handle_hint: Ini yang dapat Anda sampaikan kepada teman agar mereka dapat mengirim pesan atau mengikuti Anda dari server lain.
       review_preferences_action: Ubah preferensi
       review_preferences_step: Pastikan Anda telah mengatur preferensi Anda, seperti surel untuk menerima pesan, atau tingkat privasi bawaan untuk kiriman Anda. Jika Anda tidak alergi dengan gerakan gambar, Anda dapat mengaktifkan opsi mainkan otomatis GIF.
       subject: Selamat datang di Mastodon
+      tip_federated_timeline: Linimasa gabungan adalah ruang yang menampilkan jaringan Mastodon. Tapi ini hanya berisi tetangga orang-orang yang Anda ikuti, jadi tidak sepenuhnya komplet.
       tip_following: Anda secara otomatis mengikuti admin server. Untuk mencari akun-akun yang menarik, silakan periksa linimasa lokal dan gabungan.
+      tip_local_timeline: Linimasa lokal adalah ruang yang menampilkan orang-orang di %{instance}. Mereka adalah tetangga dekat!
       tip_mobile_webapp: Jika peramban mobile Anda ingin menambahkan Mastodon ke layar utama, Anda dapat menerima notifikasi dorong. Ia akan berjalan seperti aplikasi asli!
       tips: Tips
       title: Selamat datang, %{name}!
diff --git a/config/locales/io.yml b/config/locales/io.yml
index 4e426e469..0b09134bb 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -79,7 +79,7 @@ io:
     '406': This page is not available in the requested format.
     '410': La pagino quan tu serchas ne plus existas.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   exports:
diff --git a/config/locales/is.yml b/config/locales/is.yml
index d6cf23966..7e681e736 100644
--- a/config/locales/is.yml
+++ b/config/locales/is.yml
@@ -92,6 +92,7 @@ is:
       delete: Eyða
       destroyed_msg: Tókst að eyða minnispunkti umsjónarmanns!
     accounts:
+      add_email_domain_block: Útiloka tölvupóstlén
       approve: Samþykkja
       approve_all: Samþykkja allt
       are_you_sure: Ertu viss?
@@ -115,7 +116,7 @@ is:
       display_name: Birtingarnafn
       domain: Lén
       edit: Breyta
-      email: Tölvupóstur
+      email: Tölvupóstfang
       email_status: Staða tölvupósts
       enable: Virkja
       enabled: Virkt
@@ -133,7 +134,7 @@ is:
         title: Staðsetning
       login_status: Staða innskráningar
       media_attachments: Myndaviðhengi
-      memorialize: Breya í minningargrein
+      memorialize: Breyta í minningargrein
       moderation:
         active: Virkur
         all: Allt
@@ -172,6 +173,7 @@ is:
         staff: Starfsmaður
         user: Notandi
       search: Leita
+      search_same_email_domain: Aðra notendur með sama tölvupóstlén
       search_same_ip: Aðrir notendur með sama IP-vistfang
       shared_inbox_url: Slóð á sameiginlegt innhólf
       show:
@@ -193,6 +195,42 @@ is:
       web: Vefur
       whitelisted: Á lista yfir leyft
     action_logs:
+      action_types:
+        assigned_to_self_report: Úthluta kæru
+        change_email_user: Skipta um tölvupóstfang notanda
+        confirm_user: Staðfesta notanda
+        create_account_warning: Útbúa aðvörun
+        create_announcement: Búa til tilkynningu
+        create_custom_emoji: Búa til sérsniðið tjáningartákn
+        create_domain_allow: Búa til lén leyft
+        create_domain_block: Búa til lén bannað
+        create_email_domain_block: Búa til tölvupóstfang bannað
+        demote_user: Lækka notanda í tign
+        destroy_announcement: Eyða tilkynningu
+        destroy_custom_emoji: Eyða sérsniðnu tjáningartákni
+        destroy_domain_allow: Eyða léni leyft
+        destroy_domain_block: Eyða léni bannað
+        destroy_email_domain_block: Eyða tölvupóstfangi bannað
+        destroy_status: Eyða stöðufærslu
+        disable_2fa_user: Gera tveggja-þátta auðkenningu óvirka
+        disable_custom_emoji: Gera sérsniðið tjáningartákn óvirkt
+        disable_user: Gera notanda óvirkan
+        enable_custom_emoji: Virkja sérsniðið tjáningartákn
+        enable_user: Virkja notanda
+        memorialize_account: Gera aðgang að minningargrein
+        promote_user: Hækka notanda í tign
+        remove_avatar_user: Fjarlægja auðkennismynd
+        reopen_report: Enduropna kæru
+        reset_password_user: Endurstilla lykilorð
+        resolve_report: Leysa kæru
+        silence_account: Hylja notandaaðgang
+        suspend_account: Setja notandaaðgang í bið
+        unassigned_report: Aftengja úthlutun kæru
+        unsilence_account: Hætta að hylja notandaaðgang
+        unsuspend_account: Taka notandaaðgang úr bið
+        update_announcement: Uppfæra tilkynningu
+        update_custom_emoji: Uppfæra sérsniðið tjáningartákn
+        update_status: Uppfæra stöðufærslu
       actions:
         assigned_to_self_report: "%{name} úthlutaði skýrslu %{target} til sín"
         change_email_user: "%{name} breytti tölvupóstfangi fyrir notandann %{target}"
@@ -230,6 +268,9 @@ is:
         update_custom_emoji: "%{name} uppfærði tjáningartákn %{target}"
         update_status: "%{name} uppfærði stöðufærslu frá %{target}"
       deleted_status: "(eydd stöðufærsla)"
+      empty: Engar atvikaskrár fundust.
+      filter_by_action: Sía eftir aðgerð
+      filter_by_user: Sía eftir notanda
       title: Atvikaskrá
     announcements:
       destroyed_msg: Það tókst að eyða auglýsingunni!
@@ -358,6 +399,7 @@ is:
       destroyed_msg: Tókst að eyða póstléni af lista yfir bannað
       domain: Lén
       empty: Engin tölvupóstlén eru á bannlista.
+      from_html: frá %{domain}
       new:
         create: Bæta við léni
         title: Ný færsla á bannlista fyrir tölvupóstföng
@@ -537,6 +579,9 @@ is:
       trends:
         desc_html: Birta opinberlega þau áður yfirförnu myllumerki sem eru núna í umræðunni
         title: Myllumerki í umræðunni
+    site_uploads:
+      delete: Eyða innsendri skrá
+      destroyed_msg: Það tókst að eyða innsendingu á vefsvæði!
     statuses:
       back_to_account: Fara aftur á síðu notandaaðgangsins
       batch:
@@ -573,7 +618,6 @@ is:
     warning_presets:
       add_new: Bæta við nýju
       delete: Eyða
-      edit: Breyta
       edit_preset: Breyta forstilltri aðvörun
       title: Sýsla með forstilltar aðvaranir
   admin_mailer:
@@ -661,6 +705,7 @@ is:
     trouble_logging_in: Vandræði við að skrá inn?
   authorize_follow:
     already_following: Þú ert að þegar fylgjast með þessum aðgangi
+    already_requested: Þú ert þegar búin/n að senda fylgjendabeiðni á þennan notanda
     error: Því miður, það kom upp villa við að fletta upp fjartengda notandaaðgangnum
     follow: Fylgjast með
     follow_request: 'Þú sendir beiðni um að fylgjast með til:'
@@ -849,6 +894,7 @@ is:
   media_attachments:
     validations:
       images_and_video: Ekki er hægt að hengja myndskeið við stöðufærslu sem þegar inniheldur myndir
+      not_ready: Ekki er hægt að hengja við skrár sem ekki er búið að vinna til fulls. Prófaðu aftur eftir augnablik!
       too_many: Ekki er hægt að hengja við fleiri en 4 skrár
   migrations:
     acct: Færði í
@@ -1070,6 +1116,8 @@ is:
     disallowed_hashtags:
       one: 'innihélt óleyfilegt myllumerki: %{tags}'
       other: 'innihélt óleyfilegu myllumerkin: %{tags}'
+    errors:
+      in_reply_not_found: Stöðufærslan sem þú ert að reyna að svara að er líklega ekki til.
     language_detection: Greina tungumál sjálfvirkt
     open_in_web: Opna í vafra
     over_character_limit: hámarksfjölda stafa (%{max}) náð
diff --git a/config/locales/it.yml b/config/locales/it.yml
index 2ccdc076c..2cc6d50d2 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -92,6 +92,7 @@ it:
       delete: Elimina
       destroyed_msg: Nota di moderazione distrutta con successo!
     accounts:
+      add_email_domain_block: Inserisci il dominio email nella blacklist
       approve: Approva
       approve_all: Approva tutto
       are_you_sure: Sei sicuro?
@@ -172,6 +173,7 @@ it:
         staff: Personale
         user: Utente
       search: Cerca
+      search_same_email_domain: Altri utenti con lo stesso dominio e-mail
       search_same_ip: Altri utenti con lo stesso IP
       shared_inbox_url: URL Inbox Condiviso
       show:
@@ -193,6 +195,42 @@ it:
       web: Web
       whitelisted: Nella whitelist
     action_logs:
+      action_types:
+        assigned_to_self_report: Assegna report
+        change_email_user: Cambia l'e-mail per l'utente
+        confirm_user: Conferma utente
+        create_account_warning: Crea avviso
+        create_announcement: Crea un annuncio
+        create_custom_emoji: Crea emoji personalizzata
+        create_domain_allow: Crea permesso di dominio
+        create_domain_block: Crea blocco di dominio
+        create_email_domain_block: Crea blocco dominio e-mail
+        demote_user: Degrada l'utente
+        destroy_announcement: Cancella annuncio
+        destroy_custom_emoji: Cancella emoji personalizzata
+        destroy_domain_allow: Cancella permesso di dominio
+        destroy_domain_block: Cancella blocco di dominio
+        destroy_email_domain_block: Cancella blocco dominio e-mail
+        destroy_status: Cancella stato
+        disable_2fa_user: Disabilita l'autenticazione a due fattori
+        disable_custom_emoji: Disabilita emoji personalizzata
+        disable_user: Disabilita utente
+        enable_custom_emoji: Abilita emoji personalizzata
+        enable_user: Abilita utente
+        memorialize_account: Trasforma in account commemorativo
+        promote_user: Promuovi utente
+        remove_avatar_user: Elimina avatar
+        reopen_report: Riapri report
+        reset_password_user: Reimposta password
+        resolve_report: Risolvi report
+        silence_account: Silenzia account
+        suspend_account: Sospendi account
+        unassigned_report: Disassegna report
+        unsilence_account: De-silenzia account
+        unsuspend_account: Annulla la sospensione dell'account
+        update_announcement: Aggiorna annuncio
+        update_custom_emoji: Aggiorna emoji personalizzata
+        update_status: Aggiorna stato
       actions:
         assigned_to_self_report: "%{name} ha assegnato il rapporto %{target} a se stesso"
         change_email_user: "%{name} ha cambiato l'indirizzo email per l'utente %{target}"
@@ -230,6 +268,9 @@ it:
         update_custom_emoji: "%{name} ha aggiornato l'emoji %{target}"
         update_status: "%{name} stato aggiornato da %{target}"
       deleted_status: "(stato cancellato)"
+      empty: Nessun log trovato.
+      filter_by_action: Filtra per azione
+      filter_by_user: Filtra per utente
       title: Registro di controllo
     announcements:
       destroyed_msg: Annuncio eliminato!
@@ -244,7 +285,7 @@ it:
       scheduled_for: Programmato per %{time}
       scheduled_msg: Annuncio programmato per la pubblicazione!
       title: Annunci
-      unpublished_msg: Annuncio tolto dalla pubblicazione!
+      unpublished_msg: Annuncio ritirato!
       updated_msg: Annuncio aggiornato!
     custom_emojis:
       assign_category: Assegna categoria
@@ -358,6 +399,7 @@ it:
       destroyed_msg: Dominio email cancellato con successo dalla lista nera
       domain: Dominio
       empty: Nessun dominio di posta elettronica attualmente in blacklist.
+      from_html: da %{domain}
       new:
         create: Aggiungi dominio
         title: Nuova voce della lista nera delle email
@@ -537,6 +579,9 @@ it:
       trends:
         desc_html: Visualizza pubblicamente gli hashtag precedentemente esaminati che sono attualmente in tendenza
         title: Hashtag di tendenza
+    site_uploads:
+      delete: Cancella il file caricato
+      destroyed_msg: Caricamento sito eliminato!
     statuses:
       back_to_account: Torna alla pagina dell'account
       batch:
@@ -573,7 +618,6 @@ it:
     warning_presets:
       add_new: Aggiungi nuovo
       delete: Cancella
-      edit: Modifica
       edit_preset: Modifica avviso predefinito
       title: Gestisci avvisi predefiniti
   admin_mailer:
@@ -662,6 +706,7 @@ it:
     trouble_logging_in: Problemi di accesso?
   authorize_follow:
     already_following: Stai già seguendo questo account
+    already_requested: Hai già mandato una richiesta di seguire questo account
     error: Sfortunatamente c'è stato un errore nel consultare l'account remoto
     follow: Segui
     follow_request: 'Hai mandato una richiesta di diventare seguace a:'
@@ -850,6 +895,7 @@ it:
   media_attachments:
     validations:
       images_and_video: Impossibile allegare video a un post che contiene già immagini
+      not_ready: Impossibile allegare file per cui l'elaborazione non è finita. Riprova tra poco!
       too_many: Impossibile allegare più di 4 file
   migrations:
     acct: utente@dominio del nuovo account
@@ -1071,6 +1117,8 @@ it:
     disallowed_hashtags:
       one: 'contiene un hashtag non permesso: %{tags}'
       other: 'contiene gli hashtags non permessi: %{tags}'
+    errors:
+      in_reply_not_found: Lo stato a cui stai tentando di rispondere non sembra esistere.
     language_detection: Individua lingua automaticamente
     open_in_web: Apri sul Web
     over_character_limit: Limite caratteri superato di %{max}
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 00e76a8da..a58d9f0d7 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -88,6 +88,7 @@ ja:
       delete: 削除
       destroyed_msg: モデレーションメモを削除しました!
     accounts:
+      add_email_domain_block: ドメインをブラックリストに追加
       approve: 承認
       approve_all: すべて承認
       are_you_sure: 本当に実行しますか?
@@ -168,6 +169,7 @@ ja:
         staff: スタッフ
         user: ユーザー
       search: 検索
+      search_same_email_domain: 同じドメインのメールアドレスを使用しているユーザー
       search_same_ip: 同じ IP のユーザーを検索
       shared_inbox_url: Shared inbox URL
       show:
@@ -189,6 +191,42 @@ ja:
       web: Web
       whitelisted: ホワイトリストに登録済み
     action_logs:
+      action_types:
+        assigned_to_self_report: 通報の担当者に設定
+        change_email_user: ユーザーのメールアドレスを変更
+        confirm_user: ユーザーの確認
+        create_account_warning: 警告を作成
+        create_announcement: お知らせを作成
+        create_custom_emoji: カスタム絵文字を作成
+        create_domain_allow: ドメインホワイトリストに追加
+        create_domain_block: ドメインブロックを作成
+        create_email_domain_block: メールドメインブロックを作成
+        demote_user: ユーザーを降格
+        destroy_announcement: お知らせを削除
+        destroy_custom_emoji: カスタム絵文字を削除
+        destroy_domain_allow: ドメインホワイトリストから削除
+        destroy_domain_block: ドメインブロックを削除
+        destroy_email_domain_block: メールドメインブロックを削除
+        destroy_status: トゥートを削除
+        disable_2fa_user: 二段階認証を無効にする
+        disable_custom_emoji: カスタム絵文字を無効化
+        disable_user: ユーザーを無効化
+        enable_custom_emoji: カスタム絵文字を有効化
+        enable_user: ユーザーを有効化
+        memorialize_account: 追悼アカウント
+        promote_user: ユーザーを昇格
+        remove_avatar_user: アイコンを削除
+        reopen_report: 通報を再度開く
+        reset_password_user: パスワードをリセット
+        resolve_report: 通報を解決済みにする
+        silence_account: アカウントをサイレンス
+        suspend_account: アカウントをサスペンド
+        unassigned_report: 通報の担当を解除
+        unsilence_account: アカウントのサイレンスを解除
+        unsuspend_account: アカウントのサスペンドを解除
+        update_announcement: お知らせを更新
+        update_custom_emoji: カスタム絵文字を更新
+        update_status: ステータスを更新
       actions:
         assigned_to_self_report: "%{name} さんが通報 %{target} を自身の担当に割り当てました"
         change_email_user: "%{name} さんが %{target} さんのメールアドレスを変更しました"
@@ -226,6 +264,9 @@ ja:
         update_custom_emoji: "%{name} さんがカスタム絵文字 %{target} を更新しました"
         update_status: "%{name} さんが %{target} さんの投稿を更新しました"
       deleted_status: "(削除済)"
+      empty: ログが見つかりませんでした
+      filter_by_action: アクションでフィルター
+      filter_by_user: ユーザーでフィルター
       title: 操作履歴
     announcements:
       destroyed_msg: お知らせが削除されました
@@ -353,6 +394,7 @@ ja:
       destroyed_msg: ブラックリストから外しました
       domain: ドメイン
       empty: メールブラックリストに登録されたドメインはありません
+      from_html: "%{domain} から"
       new:
         create: ドメインを追加
         title: メールアドレス用ブラックリスト新規追加
@@ -529,6 +571,9 @@ ja:
       trends:
         desc_html: 現在トレンドになっている承認済みのハッシュタグを公開します
         title: トレンドタグを有効にする
+    site_uploads:
+      delete: ファイルを削除
+      destroyed_msg: ファイルを削除しました!
     statuses:
       back_to_account: アカウントページに戻る
       batch:
@@ -565,7 +610,6 @@ ja:
     warning_presets:
       add_new: 追加
       delete: 削除
-      edit: 編集
       edit_preset: プリセット警告文を編集
       title: プリセット警告文を管理
   admin_mailer:
@@ -653,6 +697,7 @@ ja:
     trouble_logging_in: ログインできませんか?
   authorize_follow:
     already_following: あなたは既にこのアカウントをフォローしています
+    already_requested: 既にこのアカウントへフォローリクエストを送信しています
     error: 残念ながら、リモートアカウント情報の取得中にエラーが発生しました
     follow: フォロー
     follow_request: 'あなたは以下のアカウントにフォローリクエストを送信しました:'
@@ -840,6 +885,7 @@ ja:
   media_attachments:
     validations:
       images_and_video: 既に画像が追加されているため、動画を追加することはできません
+      not_ready: ファイルのアップロードに失敗しました。しばらくしてからもう一度お試しください!
       too_many: 追加できるファイルは4つまでです
   migrations:
     acct: 引っ越し先の ユーザー名@ドメイン
@@ -1057,6 +1103,8 @@ ja:
     content_warning: '閲覧注意: %{warning}'
     disallowed_hashtags:
       other: '許可されていないハッシュタグが含まれています: %{tags}'
+    errors:
+      in_reply_not_found: あなたが返信しようとしているトゥートは存在しないようです。
     language_detection: 自動検出
     open_in_web: Webで開く
     over_character_limit: 上限は %{max}文字までです
diff --git a/config/locales/kab.yml b/config/locales/kab.yml
index 03f4d8c13..92c14f68c 100644
--- a/config/locales/kab.yml
+++ b/config/locales/kab.yml
@@ -58,7 +58,7 @@ kab:
     posts:
       one: Tajewwiqt
       other: Tijewwiqin
-    posts_tab_heading: Tiberraḥin
+    posts_tab_heading: Tijewwiqin
     posts_with_replies: Tijewwaqin akked tririyin
     reserved_username: Isem-agi n umseqdac yettwaṭṭef yakan
     roles:
@@ -107,6 +107,7 @@ kab:
       location:
         all: Akk
         local: Adigan
+        remote: Ameccaq
         title: Amḍiq
       login_status: Addad n tuqqna
       memorialize: Err amiḍan d asebter n usmekti
@@ -122,8 +123,8 @@ kab:
       protocol: Aneggaf
       public: Azayez
       redownload: Smiren amaγnu
-      reject: Ggami
-      reject_all: Ggami-ten akk
+      reject: Aggi
+      reject_all: Aggi-ten akk
       remove_avatar: Kkes tugna n wummuγ
       resend_confirmation:
         already_confirmed: Amseqdac-agi yettwasentem yakan
@@ -143,26 +144,26 @@ kab:
       statuses: Tisuffγin
       subscribe: Jerred
       time_in_queue: Deg tebdert n uraju %{time}
-      title: Imiḍan
+      title: Imiḍanen
       unconfirmed_email: Imayl ur yettwasentem ara
       undo_silenced: Kkes asgugem
       unsubscribe: Ur ṭafar ara
       username: Isem n useqdac
       web: Web
-      whitelisted: Deg tebdert tamellalt
+      whitelisted: Deg umuγ tamellalt
     action_logs:
       actions:
         change_email_user: "%{name} ibeddel imayl n umseqdac %{target}"
         confirm_user: "%{name} isentem tansa imayl n umseqdac %{target}"
         create_account_warning: "%{name} yuzen alγu i %{target}"
         create_custom_emoji: "%{name} yessuli-d imujiten imaynuten %{target}"
-        create_domain_allow: "%{name} yerna taγult %{target} γer tebdart tamellalt"
+        create_domain_allow: "%{name} yerna taγult %{target} γer wumuγ amellal"
         create_domain_block: "%{name} yesseḥbes taγult %{target}"
-        create_email_domain_block: "%{name} yerna taγult n imayl %{target} γer tebdart taberkant"
+        create_email_domain_block: "%{name} yerna taγult n imayl %{target} γer wumuγ aberkan"
         destroy_custom_emoji: "%{name} ihudd imuji %{target}"
-        destroy_domain_allow: "%{name} yekkes taγult %{target} seg tebdart tamellalt"
+        destroy_domain_allow: "%{name} yekkes taγult %{target} seg wumuγ amellal"
         destroy_domain_block: "%{name} yekkes aseḥbes n taγult %{target}"
-        destroy_email_domain_block: "%{name} yerna taγult n imayl %{target} γer tebdart tamellalt"
+        destroy_email_domain_block: "%{name} yerna taγult n imayl %{target} γer wumuγ amellal"
         destroy_status: "%{name} yekkes tasuffeγt n %{target}"
         disable_custom_emoji: "%{name} yessens imuji %{target}"
         disable_user: "%{name} yessens tuqqna i umseqdac %{target}"
@@ -178,6 +179,7 @@ kab:
       edit:
         title: Ẓreg ulγu
       empty: Ulac kra n ulγuyen.
+      live: Srid
       new:
         create: Rnu-d ulγu
         title: Ulγu amaynut
@@ -198,32 +200,35 @@ kab:
       enabled: Yermed
       enabled_msg: Imuji yermed mebla ugur
       image_hint: PNG n ddaw n 50KT
-      list: Tabdart
+      list: Umuγ
       new:
         title: Timerna n imuji udmawan amaynut
       overwrite: Semselsi
       title: Imujiten udmawanen
-      unlist: Kkes si tabdert
-      unlisted: Yettwakkes si tabdert
+      unlist: Kkes seg wumuγ
+      unlisted: Yettwakkes seg wumuγ
       update_failed_msg: Ur izmir ara ad-issali umuji-a
       upload: Sali
     dashboard:
       config: Tawila
+      feature_invites: Iseγwan n iɛaṛuḍen
       feature_profile_directory: Akaram n imaγnuten
       feature_registrations: Ajerred
+      feature_relay: Anmegli n tfidiṛalitt
       features: Timahaltin
-      open_reports: ad yeldi ineqqisen
+      open_reports: yeldin d ineqqisen
+      pending_users: imseqdacen ttrajun aɛiwed n tmuγli
       recent_users: Iseqdacen n memli kan
       software: Aseγẓan
       title: Tafelwit
       total_users: igellan akk d iseqdacen
-      week_users_active: yermed deg yimalas-agi
+      week_users_active: urmiden deg yimalas-agi
       week_users_new: imseqdacen deg yimalas-agi
     domain_allows:
-      add_new: Timerna n taγult γer tebdart tamellalt
-      created_msg: Taγult-a tettwarna γer tebdart tamellalt mebla ugur
-      destroyed_msg: Taγult-a tettwakkes seg tebdart tamellalt
-      undo: Kkes seg tebdart tamellalt
+      add_new: Timerna n taγult γer wumuγ amellal
+      created_msg: Taγult-a tettwarna γer wumuγ amellal mebla ugur
+      destroyed_msg: Taγult-a tettwakkes seg umuγ amellal
+      undo: Kkes seg umuγ amellal
     domain_blocks:
       domain: Taγult
       new:
@@ -242,13 +247,13 @@ kab:
       domain: Taγult
       new:
         create: Rnu taγult
-        title: Timerna n taγult tamaynut n imayl γer tebdart taberkant
-      title: Tabdart taberkant n imayl
+        title: Timerna n taγult tamaynut n imayl γer wumuγ aberkan
+      title: Umuγ aberkan n imayl
     instances:
       by_domain: Taγult
       delivery_available: Yella usiweḍ
       known_accounts:
-        one: "%{count} n umiḍan i yettwassen"
+        one: "%{count} n umiḍan i yettwasnen"
         other: "%{count} n yimiḍanen i yettwassnen"
       moderation:
         all: Akk
@@ -265,13 +270,19 @@ kab:
         expired: Ifat
         title: Asizdeg
       title: Iɛaruḍen
+    pending_accounts:
+      title: Imiḍanen yettrajun (%{count})
     relays:
+      add_new: Rnu anmegli amaynut
       delete: Kkes
       disable: Gdel
+      disabled: Yettwassens
       enable: Rmed
       enabled: Yermed
+      inbox_url: URL n unmegli
       save_and_enable: Sekles rnu rmed-it
       status: Addad
+      title: Imnegliyen
     reports:
       account:
         reports:
@@ -312,6 +323,8 @@ kab:
         title: Aglam n uqeddac
       site_title: Isem n uqeddac
       title: Iγewwaṛen n usmel
+    site_uploads:
+      delete: Kkes afaylu yulin
     statuses:
       back_to_account: Tuγalin γer usebter n umiḍan
       batch:
@@ -320,6 +333,7 @@ kab:
       media:
         title: Taγwalt
       no_media: Mebla taγwalt
+      title: Tisuffiγin n umiḍan
       with_media: S taγwalt
     tags:
       directory: Deg ukaram
@@ -327,10 +341,11 @@ kab:
       last_active: Armud aneggaru
       most_popular: Ittwasnen aṭas
       most_recent: Melmi kan
+      name: Ahacṭag
+      title: Ihacṭagen
     warning_presets:
       add_new: Rnu amaynut
       delete: Kkes
-      edit: Ẓreg
   admin_mailer:
     new_report:
       subject: Aneqqis amaynut i %{instance} (#%{id})
@@ -342,9 +357,13 @@ kab:
     sensitive_content: Agbur amḥulfu
   application_mailer:
     salutation: "%{name},"
+    view: 'Ẓaṛ:'
     view_profile: Sken-d amaγnu
+    view_status: Sken-d tasuffiγt
   auth:
     change_password: Awal uffir
+    checkbox_agreement_html: Qebleγ <a href="%{rules_path}" target="_blank">ilugan n uqeddac-a</a> akked <a href="%{terms_path}" target="_blank">tiwtilin n useqdec</a>
+    checkbox_agreement_without_rules_html: Qebleγ <a href="%{terms_path}" target="_blank">tiwtilin n useqdec</a>
     delete_account: Kkes amiḍan
     description:
       prefix_sign_up: Zeddi di Maṣṭudun assa!
@@ -359,7 +378,7 @@ kab:
     register: Jerred
     reset_password: Wennez awal uffir
     security: Taγellist
-    set_new_password: Egr-ed awal uffir amaynut
+    set_new_password: Egr-d awal uffir amaynut
     status:
       account_status: Addad n umiḍan
       functional: Amiḍan-inek·m yettwaheyya.
@@ -369,7 +388,7 @@ kab:
     follow: Ḍfeṛ
     following: 'Igerrez! Aqlik teṭafareḍ tura:'
     post_follow:
-      return: Sken-ed amγnu n useqdac
+      return: Sken-d amγnu n useqdac
       web: Ddu γer Web
     title: Ḍfeṛ %{acct}
   challenge:
@@ -381,18 +400,18 @@ kab:
       default: "%d %b %Y"
   datetime:
     distance_in_words:
-      about_x_hours: "%{count}a"
+      about_x_hours: "%{count}isr"
       about_x_months: "%{count}ug"
-      about_x_years: "%{count}i"
-      almost_x_years: "%{count}i"
+      about_x_years: "%{count}isg"
+      almost_x_years: "%{count}isg"
       half_a_minute: Tura kan
-      less_than_x_minutes: "%{count}t"
+      less_than_x_minutes: "%{count}tis"
       less_than_x_seconds: Tura kan
-      over_x_years: "%{count}i"
+      over_x_years: "%{count}isg"
       x_days: "%{count}wu"
-      x_minutes: "%{count}t"
-      x_months: "%{count}ug"
-      x_seconds: "%{count}t"
+      x_minutes: "%{count}tis"
+      x_months: "%{count}agu"
+      x_seconds: "%{count}tas"
   deletes:
     proceed: Kkes amiḍan
   directories:
@@ -405,8 +424,9 @@ kab:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
-    '500': 
+    '429': Too many requests
+    '500':
+      title: Asebter-ayi d arameγtu
     '503': The page could not be served due to a temporary server failure.
   existing_username_validator:
     not_found_multiple: ur yezmir ara ad yaf %{usernames}
@@ -415,7 +435,7 @@ kab:
       date: Azemz
       size: Teγzi
     csv: CSV
-    lists: Tibdarin
+    lists: Umuγen
     mutes: Wid tesgugmeḍ
   featured_tags:
     add_new: Rnu amaynut
@@ -437,6 +457,7 @@ kab:
     more: Ugar…
   generic:
     all: Akk
+    changes_saved_msg: Ttwaskelsen ibelliden-ik·im akken ilaq!
     copy: Nγel
     delete: Kkes
     order_by: Sizwer s
@@ -452,7 +473,8 @@ kab:
     modes:
       overwrite: Semselsi
     types:
-      following: Tabdart n wid teṭafareḍ
+      following: Umuγ n wid teṭafareḍ
+      muting: Umuγ n wid tesgugmeḍ
     upload: Sali
   invites:
     expires_in:
@@ -466,7 +488,8 @@ kab:
     title: Ɛreḍ-d kra n yimdanen
   migrations:
     acct: Ibeddel γer
-    incoming_migrations: Tusiḍ-ed seg umiḍan nniḍen
+    incoming_migrations: Tusiḍ-d seg umiḍan nniḍen
+    proceed_with_move: Awid imeḍfaṛen-ik
   notification_mailer:
     digest:
       action: Wali akk tilγa
@@ -494,6 +517,12 @@ kab:
     status: Addad n umiḍan
   remote_follow:
     no_account_html: Ur tesɛid ara amiḍan? Tzmreḍ <a href='%{sign_up_path}' target='_blank'>ad jerdeḍ da</a>
+    proceed: Kemmel taḍfart
+  remote_interaction:
+    favourite:
+      proceed: Kemmel asmenyef
+    reply:
+      proceed: Kemmel tiririt
   sessions:
     activity: Armud aneggaru
     browser: Iminig
@@ -559,7 +588,7 @@ kab:
       total_people:
         one: "%{count} n wemdan"
         other: "%{count} n yemdanen"
-    show_more: Sken-ed ugar
+    show_more: Sken-d ugar
     sign_in_to_participate: Qqen i waken ad tzeddiḍ deg udiwenni
     title: '%{name}: "%{quote}"'
     visibilities:
diff --git a/config/locales/kk.yml b/config/locales/kk.yml
index 416a5fc7d..bb7a57e87 100644
--- a/config/locales/kk.yml
+++ b/config/locales/kk.yml
@@ -555,7 +555,6 @@ kk:
     warning_presets:
       add_new: Add nеw
       delete: Deletе
-      edit: Еdit
       edit_preset: Edit warning prеset
       title: Manage warning presеts
   admin_mailer:
diff --git a/config/locales/kn.yml b/config/locales/kn.yml
index d6c1d98eb..25bee609a 100644
--- a/config/locales/kn.yml
+++ b/config/locales/kn.yml
@@ -7,7 +7,7 @@ kn:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index e70fbef21..2ac3fb39d 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -88,6 +88,7 @@ ko:
       delete: 삭제
       destroyed_msg: 중재 기록이 성공적으로 삭제되었습니다!
     accounts:
+      add_email_domain_block: 이 이메일 도메인을 차단하기
       approve: 승인
       approve_all: 모두 승인
       are_you_sure: 정말로 실행하시겠습니까?
@@ -168,6 +169,7 @@ ko:
         staff: 스태프
         user: 사용자
       search: 검색
+      search_same_email_domain: 같은 이메일 도메인을 가진 다른 사용자들
       search_same_ip: 같은 IP의 다른 사용자들
       shared_inbox_url: 공유된 inbox URL
       show:
@@ -189,6 +191,42 @@ ko:
       web: 웹
       whitelisted: 허용 목록
     action_logs:
+      action_types:
+        assigned_to_self_report: 신고 맡기
+        change_email_user: 사용자의 이메일 변경
+        confirm_user: 사용자 확인
+        create_account_warning: 경고 생성
+        create_announcement: 공지사항 생성
+        create_custom_emoji: 커스텀 에모지 생성
+        create_domain_allow: 도메인 허용 생성
+        create_domain_block: 도메인 차단 추가
+        create_email_domain_block: 이메일 도메인 차단 생성
+        demote_user: 사용자 강등
+        destroy_announcement: 공지사항 삭제
+        destroy_custom_emoji: 커스텀 에모지 삭제
+        destroy_domain_allow: 도메인 허용 삭제
+        destroy_domain_block: 도메인 차단 삭제
+        destroy_email_domain_block: 이메일 도메인 차단 삭제
+        destroy_status: 게시물 삭제
+        disable_2fa_user: 2단계 인증 비활성화
+        disable_custom_emoji: 커스텀 에모지 비활성화
+        disable_user: 사용자 비활성화
+        enable_custom_emoji: 커스텀 에모지 활성화
+        enable_user: 사용자 활성화
+        memorialize_account: 계정을 장기 저장
+        promote_user: 사용자 승급
+        remove_avatar_user: 아바타 지우기
+        reopen_report: 신고 다시 열기
+        reset_password_user: 암호 재설정
+        resolve_report: 신고 처리
+        silence_account: 계정 침묵
+        suspend_account: 계정 정지
+        unassigned_report: 신고 맡기 취소
+        unsilence_account: 계정 침묵 취소
+        unsuspend_account: 계정 정지 취소
+        update_announcement: 공지사항 업데이트
+        update_custom_emoji: 커스텀 에모지 업데이트
+        update_status: 게시물 게시
       actions:
         assigned_to_self_report: "%{name}이 리포트 %{target}을 자신에게 할당했습니다"
         change_email_user: "%{name}이 %{target}의 이메일 주소를 변경했습니다"
@@ -226,6 +264,9 @@ ko:
         update_custom_emoji: "%{name}이 에모지 %{target}를 업데이트 했습니다"
         update_status: "%{name}이 %{target}의 상태를 업데이트 했습니다"
       deleted_status: "(삭제됨)"
+      empty: 로그를 찾을 수 없습니다
+      filter_by_action: 행동으로 거르기
+      filter_by_user: 유저로 거르기
       title: 감사 기록
     announcements:
       destroyed_msg: 공지가 성공적으로 삭제되었습니다!
@@ -355,6 +396,7 @@ ko:
       destroyed_msg: 이메일 도메인 차단 규칙을 삭제했습니다
       domain: 도메인
       empty: 현재 블랙리스트에 등록한 이메일 도메인이 없습니다
+      from_html: "%{domain}에서"
       new:
         create: 차단 규칙 생성
         title: 새 이메일 도메인 차단
@@ -531,6 +573,9 @@ ko:
       trends:
         desc_html: 리뷰를 거친 해시태그를 유행하는 해시태그에 공개적으로 보여줍니다
         title: 유행하는 해시태그
+    site_uploads:
+      delete: 업로드한 파일 삭제
+      destroyed_msg: 사이트 업로드를 성공적으로 삭제했습니다!
     statuses:
       back_to_account: 계정으로 돌아가기
       batch:
@@ -567,7 +612,6 @@ ko:
     warning_presets:
       add_new: 새로 추가
       delete: 삭제
-      edit: 편집
       edit_preset: 경고 틀 수정
       title: 경고 틀 관리
   admin_mailer:
@@ -655,6 +699,7 @@ ko:
     trouble_logging_in: 로그인 하는데 문제가 있나요?
   authorize_follow:
     already_following: 이미 이 계정을 팔로우 하고 있습니다
+    already_requested: 이미 이 계정에게 팔로우 요청을 보냈습니다
     error: 리모트 계정을 확인하는 도중 오류가 발생했습니다
     follow: 팔로우
     follow_request: '당신은 다음 계정에 팔로우 신청을 했습니다:'
@@ -841,6 +886,7 @@ ko:
   media_attachments:
     validations:
       images_and_video: 이미 사진이 첨부 된 게시물엔 동영상을 첨부 할 수 없습니다
+      not_ready: 처리가 끝나지 않은 파일은 첨부할 수 없습니다. 잠시 후에 다시 시도해 주세요!
       too_many: 최대 4개까지 첨부할 수 있습니다
   migrations:
     acct: 새 계정의 username@domain
@@ -1057,6 +1103,8 @@ ko:
     content_warning: '열람 주의: %{warning}'
     disallowed_hashtags:
       other: '허용되지 않은 해시태그를 포함하고 있습니다: %{tags}'
+    errors:
+      in_reply_not_found: 답장하려는 게시물이 존재하지 않습니다.
     language_detection: 자동으로 언어 감지
     open_in_web: Web으로 열기
     over_character_limit: 최대 %{max}자까지 입력할 수 있습니다
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index 9af094c01..5a4542ea8 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -410,7 +410,6 @@ lt:
     warning_presets:
       add_new: Pridėti naują
       delete: Ištrinti
-      edit: Keisti
       edit_preset: Keisti įspėjimo nustatymus
       title: Valdyti įspėjimo nustatymus
   admin_mailer:
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index f6625dd41..5c493be56 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -7,7 +7,7 @@ lv:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/mk.yml b/config/locales/mk.yml
index acb18fb5a..c2cafa5a7 100644
--- a/config/locales/mk.yml
+++ b/config/locales/mk.yml
@@ -7,7 +7,7 @@ mk:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/ml.yml b/config/locales/ml.yml
index 960ab95cc..f2731cf04 100644
--- a/config/locales/ml.yml
+++ b/config/locales/ml.yml
@@ -51,7 +51,7 @@ ml:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/mr.yml b/config/locales/mr.yml
index 3f83ed785..72228df52 100644
--- a/config/locales/mr.yml
+++ b/config/locales/mr.yml
@@ -7,7 +7,7 @@ mr:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index 71dc72d9d..3ab481846 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -291,7 +291,7 @@ ms:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   exports:
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 976072368..7ab26c4ba 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -537,6 +537,9 @@ nl:
       trends:
         desc_html: Eerder beoordeelde hashtags die op dit moment trending zijn openbaar tonen
         title: Trending hashtags
+    site_uploads:
+      delete: Geüpload bestand verwijderen
+      destroyed_msg: Verwijderen website-upload geslaagd!
     statuses:
       back_to_account: Terug naar accountpagina
       batch:
@@ -573,7 +576,6 @@ nl:
     warning_presets:
       add_new: Nieuwe toevoegen
       delete: Verwijderen
-      edit: Bewerken
       edit_preset: Voorinstelling van waarschuwing bewerken
       title: Voorinstellingen van waarschuwingen beheren
   admin_mailer:
@@ -661,6 +663,7 @@ nl:
     trouble_logging_in: Problemen met inloggen?
   authorize_follow:
     already_following: Je volgt dit account al
+    already_requested: Je hebt al een volgverzoek naar dat account verstuurd
     error: Helaas, er is een fout opgetreden bij het opzoeken van de externe account
     follow: Volgen
     follow_request: 'Jij hebt een volgverzoek ingediend bij:'
diff --git a/config/locales/nn.yml b/config/locales/nn.yml
index fd61f2156..f83646a7b 100644
--- a/config/locales/nn.yml
+++ b/config/locales/nn.yml
@@ -21,9 +21,7 @@ nn:
     federation_hint_html: Med ein konto på %{instance} kan du fylgja folk på kva som helst slags Mastod-tenar og meir.
     get_apps: Prøv ein mobilapp
     hosted_on: "%{domain} er vert for Mastodon"
-    instance_actor_flash: 'Denne brukeren er en virtuell aktør brukt til å representere selve serveren og ingen individuell bruker. Det brukes til foreningsformål og bør ikke blokkeres med mindre du vil blokkere hele instansen, hvor domeneblokkering bør brukes i stedet.
-
-'
+    instance_actor_flash: "Denne brukeren er en virtuell aktør brukt til å representere selve serveren og ingen individuell bruker. Det brukes til foreningsformål og bør ikke blokkeres med mindre du vil blokkere hele instansen, hvor domeneblokkering bør brukes i stedet. \n"
     learn_more: Lær meir
     privacy_policy: Personvernsreglar
     see_whats_happening: Sjå kva som skjer
@@ -566,7 +564,6 @@ nn:
     warning_presets:
       add_new: Legg til ny
       delete: Slett
-      edit: Rediger
       edit_preset: Endr åtvaringsoppsett
       title: Handsam åtvaringsoppsett
   admin_mailer:
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 256ed99a3..4a1b859dc 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -561,7 +561,6 @@
     warning_presets:
       add_new: Legg til ny
       delete: Slett
-      edit: Rediger
   admin_mailer:
     new_pending_account:
       body: Detaljer om den nye kontoen er nedenfor. Du kan godkjenne eller avvise denne søknaden.
diff --git a/config/locales/oc.yml b/config/locales/oc.yml
index 4a60227ab..0be4f6458 100644
--- a/config/locales/oc.yml
+++ b/config/locales/oc.yml
@@ -186,6 +186,33 @@ oc:
       web: Web
       whitelisted: Mes en lista blanca
     action_logs:
+      action_types:
+        assigned_to_self_report: Assignar lo rapòrt
+        change_email_user: Cambiar l’adreça de l’utilizaire
+        confirm_user: Confirmar l’utilizaire
+        create_account_warning: Crear un avertiment
+        create_announcement: Crear una anóncia
+        create_custom_emoji: Crear un emoji personalizat
+        demote_user: Retrogradar l’utilizaire
+        destroy_announcement: Suprimir l’anóncia
+        destroy_custom_emoji: Suprimir l’emoji personalizat
+        destroy_domain_block: Suprimir lo blocatge de domeni
+        destroy_status: Suprimir l’estatut
+        disable_2fa_user: Desactivar 2FA
+        disable_custom_emoji: Desactivar l’emoji personalizat
+        disable_user: Desactivar l’utilizaire
+        enable_custom_emoji: Activar l’emoji personalizat
+        enable_user: Activar l’utilizaire
+        promote_user: Promòure l’utilizaire
+        remove_avatar_user: Suprimir l’avatar
+        reopen_report: Tornar dobrir lo rapòrt
+        reset_password_user: Reïnicializar lo senhal
+        resolve_report: Resòlver lo rapòrt
+        suspend_account: Suspendre lo compte
+        unassigned_report: Desafectar lo rapòrt
+        update_announcement: Actualizar l’anóncia
+        update_custom_emoji: Actualizar l’emoji personalizat
+        update_status: Actualizar l’estatut
       actions:
         assigned_to_self_report: "%{name} s’assignèt lo rapòrt %{target}"
         change_email_user: "%{name} cambièt l’adreça de corrièl de %{target}"
@@ -223,6 +250,9 @@ oc:
         update_custom_emoji: "%{name} metèt a jorn l’emoji %{target}"
         update_status: "%{name} metèt a jorn l’estatut a %{target}"
       deleted_status: "(estatut suprimit)"
+      empty: Cap de jornal pas trobat.
+      filter_by_action: Filtrar per accion
+      filter_by_user: Filtrar per utilizaire
       title: Audit dels jornals
     announcements:
       destroyed_msg: Anóncia corrèctament tirada !
@@ -558,7 +588,6 @@ oc:
     warning_presets:
       add_new: N’ajustar un nòu
       delete: Escafar
-      edit: Modificar
       edit_preset: Modificar lo tèxt predefinit d’avertiment
       title: Gerir los tèxtes predefinits
   admin_mailer:
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 6f04720c5..14cfb55ab 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -100,6 +100,7 @@ pl:
       delete: Usuń
       destroyed_msg: Pomyślnie usunięto notatkę moderacyjną!
     accounts:
+      add_email_domain_block: Dodaj domenę e-mail na czarną listę
       approve: Przyjmij
       approve_all: Zatwierdź wszystkie
       are_you_sure: Jesteś tego pewien?
@@ -180,6 +181,7 @@ pl:
         staff: Ekipa
         user: Użytkownik
       search: Szukaj
+      search_same_email_domain: Inni użytkownicy z e-mail w tej domenie
       search_same_ip: Inni użytkownicy z tym samym IP
       shared_inbox_url: Adres udostępnianej skrzynki
       show:
@@ -201,6 +203,42 @@ pl:
       web: Sieć
       whitelisted: Na białej liście
     action_logs:
+      action_types:
+        assigned_to_self_report: Przypisz zgłoszenie
+        change_email_user: Zmień adres e-mail użytkownika
+        confirm_user: Potwierdź użytkownika
+        create_account_warning: Utwórz ostrzeżenie
+        create_announcement: Utwórz ogłoszenie
+        create_custom_emoji: Utwórz niestandardowe emoji
+        create_domain_allow: Utwórz zezwolenie dla domeny
+        create_domain_block: Utwórz blokadę domeny
+        create_email_domain_block: Utwórz blokadę domeny e-mail
+        demote_user: Zdegraduj użytkownika
+        destroy_announcement: Usuń ogłoszenie
+        destroy_custom_emoji: Usuń niestandardowe emoji
+        destroy_domain_allow: Usuń zezwolenie dla domeny
+        destroy_domain_block: Usuń blokadę domeny
+        destroy_email_domain_block: Usuń blokadę domeny e-mail
+        destroy_status: Usuń wpis
+        disable_2fa_user: Wyłącz 2FA
+        disable_custom_emoji: Wyłącz niestandardowe emoji
+        disable_user: Wyłącz użytkownika
+        enable_custom_emoji: Włącz niestandardowe emoji
+        enable_user: Włącz użytkownika
+        memorialize_account: Upamiętnij konto
+        promote_user: Podnieś uprawnienia
+        remove_avatar_user: Usuń awatar
+        reopen_report: Otwórz zgłoszenie ponownie
+        reset_password_user: Resetuj hasło
+        resolve_report: Rozwiąż zgłoszenie
+        silence_account: Wycisz konto
+        suspend_account: Zawieś konto
+        unassigned_report: Cofnij przypisanie zgłoszenia
+        unsilence_account: Cofnij wyciszenie konta
+        unsuspend_account: Cofnij zawieszenie konta
+        update_announcement: Aktualizuj ogłoszenie
+        update_custom_emoji: Aktualizuj niestandardowe emoji
+        update_status: Aktualizuj wpis
       actions:
         assigned_to_self_report: "%{name} przypisał(a) sobie zgłoszenie %{target}"
         change_email_user: "%{name} zmienił(a) adres e-mail użytkownika %{target}"
@@ -238,6 +276,9 @@ pl:
         update_custom_emoji: "%{name} zaktualizował(a) emoji %{target}"
         update_status: "%{name} zaktualizował(a) wpis użytkownika %{target}"
       deleted_status: "(usunięty wpis)"
+      empty: Nie znaleziono aktywności w dzienniku.
+      filter_by_action: Filtruj według działania
+      filter_by_user: Filtruj według użytkownika
       title: Dziennik działań administracyjnych
     announcements:
       destroyed_msg: Pomyślnie usunięto ogłoszenie!
@@ -368,6 +409,7 @@ pl:
       destroyed_msg: Pomyślnie usunięto blokadę domeny e-mail
       domain: Domena
       empty: Żadna domena e-mail nie znajduje się obecnie na czarnej liście.
+      from_html: z %{domain}
       new:
         create: Utwórz blokadę
         title: Nowa blokada domeny e-mail
@@ -424,6 +466,17 @@ pl:
       created_msg: Pomyslnie utworzono notatkę moderacyjną.
       destroyed_msg: Pomyślnie usunięto notatkę moderacyjną.
     reports:
+      account:
+        notes:
+          few: "%{count} notatki"
+          many: "%{count} notatek"
+          one: "%{count} notatka"
+          other: "%{count} notatki"
+        reports:
+          few: "%{count} zgłoszenia"
+          many: "%{count} zgłoszeń"
+          one: "%{count} zgłoszenie"
+          other: "%{count} zgłoszenia"
       action_taken_by: Działanie podjęte przez
       are_you_sure: Czy na pewno?
       assign_to_self: Przypisz do siebie
@@ -464,6 +517,18 @@ pl:
       custom_css:
         desc_html: Modyfikuj wygląd pliku CSS ładowanego na każdej stronie
         title: Niestandardowy CSS
+      default_noindex:
+        desc_html: Wpływa na wszystkich użytkowników, którzy nie zmienili tego ustawienia
+        title: Domyślnie żądaj nieindeksowania użytkowników w wyszukiwarkach
+      domain_blocks:
+        all: Każdemu
+        disabled: Nikomu
+        title: Pokazuj zablokowane domeny
+        users: Zalogowanym lokalnym użytkownikom
+      domain_blocks_rationale:
+        title: Pokaż uzasadnienia
+      enable_bootstrap_timeline_accounts:
+        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
         title: Obraz bohatera
@@ -514,6 +579,9 @@ pl:
         desc_html: Miejsce na własną politykę prywatności, zasady użytkowania i inne unormowania prawne. Możesz korzystać ze znaczników HTML
         title: Niestandardowe zasady użytkowania
       site_title: Nazwa serwera
+      spam_check_enabled:
+        desc_html: Mastodon może automatycznie zgłaszać konta, które wysyłają powtarzające się niechciane wiadomości. Część zgłoszeń może być nieprawidłowa.
+        title: Automatyzacja antyspamu
       thumbnail:
         desc_html: 'Używana w podglądzie przez OpenGraph i API. Zalecany rozmiar: 1200x630 pikseli'
         title: Miniatura serwera
@@ -521,12 +589,22 @@ pl:
         desc_html: Wyświetlaj publiczną oś czasu na stronie widocznej dla niezalogowanych
         title: Podgląd osi czasu
       title: Ustawienia strony
+      trendable_by_default:
+        desc_html: Wpływa na hashtagi, które nie były wcześniej niedozwolone
+        title: Hashtagi mogą pojawiać się w trendach bez wcześniejszego zatwierdzenia
+      trends:
+        desc_html: Wyświetlaj publicznie wcześniej sprawdzone hashtagi, które są obecnie na czasie
+        title: Popularne hashtagi
+    site_uploads:
+      delete: Usuń przesłany plik
+      destroyed_msg: Pomyślnie usunięto przesłany plik!
     statuses:
       back_to_account: Wróć na konto
       batch:
         delete: Usuń
         nsfw_off: Cofnij NSFW
         nsfw_on: Oznacz jako NSFW
+      deleted: Usunięto
       failed_to_execute: Nie udało się wykonać
       media:
         title: Multimedia
@@ -535,13 +613,27 @@ pl:
       title: Wpisy konta
       with_media: Z zawartością multimedialną
     tags:
+      accounts_today: Unikalne wykorzystania dzisiaj
+      accounts_week: Unikalne wykorzystania w tym tygodniu
+      breakdown: Podział dzisiejszego wykorzystania według źródła
+      context: Kontekst
+      directory: W katalogu
+      in_directory: "%{count} w katalogu"
+      last_active: Ostatnia aktywność
+      most_popular: Najpopularniejsze
+      most_recent: Ostatnie
       name: Hasztag
+      review: Stan przeglądu
+      reviewed: Przejrzany
       title: Hashtagi
+      trending_right_now: Obecnie na czasie
+      unique_uses_today: "%{count} opublikowanych dzisiaj"
+      unreviewed: Nie przejrzano
+      updated_msg: Pomyślnie uaktualniono ustawienia hashtagów
     title: Administracja
     warning_presets:
       add_new: Dodaj nowy
       delete: Usuń
-      edit: Edytuj
       edit_preset: Edytuj szablon ostrzeżenia
       title: Zarządzaj szablonami ostrzeżeń
   admin_mailer:
@@ -552,14 +644,27 @@ pl:
       body: Użytkownik %{reporter} zgłosił(a) %{target}
       body_remote: Użytkownik instancji %{domain} zgłosił(a) %{target}
       subject: Nowe zgłoszenie na %{instance} (#%{id})
+    new_trending_tag:
+      body: 'Hashtag #%{name} jest dziś popularny, ale nie został wcześniej zatwierdzony. Nie będzie wyświetlany publicznie zanim na to pozwolisz, możesz też zapisać, że nie chcesz o nim już słyszeć.'
+      subject: Nowy hashtag do zatwierdzenia na %{instance} (#%{name})
   aliases:
     add_new: Utwórz alias
+    created_msg: Pomyślnie utworzono nowy alias. Możesz teraz rozpocząć przenoszenie ze starego konta.
+    deleted_msg: Pomyślnie usunięto alias. Przenoszenie z tamtego konta na to nie będzie dłużej możliwe.
+    hint_html: Jeżeli chcesz przenieść się z innego konta na to, możesz utworzyć alias, który jest wymagany zanim zaczniesz przenoszenie obserwacji z poprzedniego konta na to. To działanie <strong>nie wyrządzi szkód i jest odwracalne</strong>. <strong>Migracja konta jest inicjowana ze starego konta</strong>.
+    remove: Odłącz alias
   appearance:
     advanced_web_interface: Zaawansowany interfejs użytkownika
     advanced_web_interface_hint: Jeśli chcesz użyć pełną szerokość swojego ekranu, zaawansowany interfejs użytkownika pozwala Ci skonfigurować wiele różnych kolumn, by zobaczyć jak najwięcej informacji kiedy tylko chcesz. Strona główna, Powiadomienia, Globalna oś czasu, dowolna ilość list i hasztagów.
     animations_and_accessibility: Animacje i dostępność
     confirmation_dialogs: Dialogi potwierdzenia
+    discovery: Odkrywanie
+    localization:
+      body: Mastodon jest tłumaczony przez wolontariuszy.
+      guide_link: https://pl.crowdin.com/project/mastodon
+      guide_link_text: Każdy może wnieść swój wkład.
     sensitive_content: Wrażliwa zawartość
+    toot_layout: Wygląd wpisów
   application_mailer:
     notification_preferences: Zmień ustawienia e-maili
     salutation: "%{name},"
@@ -579,8 +684,13 @@ pl:
     apply_for_account: Poproś o zaproszenie
     change_password: Hasło
     checkbox_agreement_html: Zgadzam się z <a href="%{rules_path}" target="_blank">regułami serwera</a> i <a href="%{terms_path}" target="_blank">zasadami korzystania z usługi</a>
+    checkbox_agreement_without_rules_html: Akceptuję <a href="%{terms_path}" target="_blank">warunki korzystania z usługi</a>
     delete_account: Usunięcie konta
     delete_account_html: Jeżeli chcesz usunąć konto, <a href="%{path}">przejdź tutaj</a>. Otrzymasz prośbę o potwierdzenie.
+    description:
+      prefix_invited_by_user: "@%{name} zaprasza Cię do dołączenia na ten serwer Mastodona!"
+      prefix_sign_up: Zarejestruj się na Mastodon już dziś!
+      suffix: Mając konto, możesz śledzić ludzi, publikować wpisy i wymieniać się wiadomościami z użytkownikami innych serwerów Mastodona i nie tylko!
     didnt_get_confirmation: Nie otrzymałeś(-aś) instrukcji weryfikacji?
     forgot_password: Nie pamiętasz hasła?
     invalid_reset_password_token: Token do resetowania hasła jest nieprawidłowy lub utracił ważność. Spróbuj uzyskać nowy.
@@ -598,9 +708,20 @@ pl:
     reset_password: Zresetuj hasło
     security: Bezpieczeństwo
     set_new_password: Ustaw nowe hasło
+    setup:
+      email_below_hint_html: Jeżeli poniższy adres e-mail jest nieprawidłowy, możesz zmienić go tutaj i otrzymać nowy e-mail potwierdzający.
+      email_settings_hint_html: E-mail potwierdzający został wysłany na %{email}. Jeżeli adres e-mail nie jest prawidłowy, możesz zmienić go w ustawieniach konta.
+      title: Konfiguracja
+    status:
+      account_status: Stan konta
+      confirming: Oczekiwanie na potwierdzenie adresu e-mail.
+      functional: Twoje konto całkowicie funkcjonuje.
+      pending: Twoje zgłoszenie czeka na zatwierdzenie przez nas. Może to trochę potrwać. Jeżeli zgłoszenie zostanie przyjęte, otrzymasz wiadomość e-mail.
+      redirecting_to: Twoje konto jest nieaktywne, ponieważ obecnie przekierowuje je na %{acct}.
     trouble_logging_in: Masz problem z zalogowaniem się?
   authorize_follow:
     already_following: Już śledzisz to konto
+    already_requested: Już wysłałeś(-aś) prośbę o możliwość śledzenia tego konta
     error: Niestety, podczas sprawdzania zdalnego konta wystąpił błąd
     follow: Śledź
     follow_request: 'Wysłano prośbę o pozwolenie na śledzenie:'
@@ -612,6 +733,12 @@ pl:
     title: Śledź %{acct}
   challenge:
     confirm: Kontynuuj
+    hint_html: "<strong>Informacja:</strong> Nie będziemy prosić Cię o ponowne podanie hasła przez następną godzinę."
+    invalid_password: Nieprawidłowe hasło
+    prompt: Potwierdź hasło, aby kontynuować
+  date:
+    formats:
+      default: "%d. %b %Y"
   datetime:
     distance_in_words:
       about_x_hours: "%{count}g"
@@ -627,18 +754,33 @@ pl:
       x_months: "%{count} miesięcy"
       x_seconds: "%{count}s"
   deletes:
+    challenge_not_passed: Wprowadzone informacje za nieprawidłowe
     confirm_password: Wprowadź aktualne hasło, aby potwierdzić tożsamość
+    confirm_username: Wprowadź swoją nazwę użytkownika aby potwierdzić procedurę
     proceed: Usuń konto
     success_msg: Twoje konto zostało pomyślnie usunięte
+    warning:
+      before: 'Zanim kontynuujesz, przeczytać uważnie te uwagi:'
+      caches: Zawartość obecna w pamięci podręcznej innych serwerów może tam pozostać
+      data_removal: Twoje wpisy i inne dane zostaną bezpowrotnie usunięte
+      email_change_html: Możesz <a href="%{path}">zmienić swój adres e-mail</a> bez usunięcia konta
+      email_contact_html: Jeżeli wciąż nie dotarł, możesz wysłać wiadomość e-mail na <a href="mailto:%{email}">%{email}</a> aby uzyskać pomoc
+      email_reconfirmation_html: Jeżeli nie otrzymujesz potwierdzającego e-maila, możesz <a href="%{path}">poprosić o kolejny</a>
+      irreversible: Nie będziesz móc przywrócić lub reaktywować swojego konta
+      more_details_html: Aby uzyskać więcej szczegółów, przeczytaj naszą <a href="%{terms_path}">politykę prywatności</a>.
+      username_available: Twoja nazwa użytkownika będzie z powrotem dostępna
+      username_unavailable: Twoja nazwa użytkownika pozostanie niedostępna
   directories:
     directory: Katalog profilów
     explanation: Poznaj profile na podstawie zainteresowań
     explore_mastodon: Odkrywaj %{title}
+  domain_validator:
+    invalid_domain: nie jest prawidłową nazwą domeny
   errors:
-    '400': The request you submitted was invalid or malformed.
+    '400': Wysłane zgłoszenie jest nieprawidłowe lub uszkodzone.
     '403': Nie masz uprawnień, aby wyświetlić tę stronę.
     '404': Strona, którą próbujesz odwiedzić, nie istnieje.
-    '406': This page is not available in the requested format.
+    '406': Ta strona nie jest dostępna w zażądanym formacie.
     '410': Strona, którą próbujesz odwiedzić, przestała istnieć.
     '422':
       content: Sprawdzanie bezpieczeństwa nie powiodło się. Czy blokujesz pliki cookie?
@@ -647,7 +789,7 @@ pl:
     '500':
       content: Przepraszamy, coś poszło nie tak, po naszej stronie.
       title: Ta strona jest nieprawidłowa
-    '503': The page could not be served due to a temporary server failure.
+    '503': Strona nie może zostać wyświetlona z powodu tymczasowego niepowodzenia serwera.
     noscript_html: Aby korzystać z aplikacji Mastodon, włącz JavaScript. Możesz też skorzystać z jednej z <a href="%{apps_path}">natywnych aplikacji</a> obsługującej Twoje urządzenie.
   existing_username_validator:
     not_found: nie znaleziono lokalnego użytkownika o tej nazwie
@@ -670,8 +812,10 @@ pl:
     add_new: Dodaj nowy
     errors:
       limit: Już przekroczyłeś(-aś) maksymalną liczbę wyróżnionych hashtagów
+    hint_html: "<strong>Czym są wyróżnione hashtagi?</strong> Są one na stałe wyświetlane na Twoim profilu i pozwalają innym na przeglądanie Twoich wpisów używających tych hashtagów. Są doskonałym narzędziem do śledzenia kreatywnej twórczości czy długoterminowych projektów."
   filters:
     contexts:
+      account: Profile
       home: Strona główna
       notifications: Powiadomienia
       public: Publiczne osie czasu
@@ -683,6 +827,7 @@ pl:
       invalid_irreversible: Nieodwracalne filtrowanie działa tylko na stronie głównej i w powiadomieniach
     index:
       delete: Usuń
+      empty: Nie masz żadnych filtrów.
       title: Filtry
     new:
       title: Dodaj nowy filtr
@@ -690,10 +835,13 @@ pl:
     developers: Dla programistów
     more: Więcej…
     resources: Zasoby
+    trending_now: Obecnie na czasie
   generic:
     all: Wszystkie
     changes_saved_msg: Ustawienia zapisane!
     copy: Kopiuj
+    delete: Usuń
+    no_batch_actions_available: Brak akcji wsadowych dostępnych na tej stronie
     order_by: Uporządkuj według
     save_changes: Zapisz zmiany
     use_this: Użyj tego
@@ -767,9 +915,38 @@ pl:
   media_attachments:
     validations:
       images_and_video: Nie możesz załączyć pliku wideo do wpisu, który zawiera już zdjęcia
+      not_ready: Nie można załączyć plików których przetwarzanie nie zostało ukończone. Spróbuj ponownie za chwilę!
       too_many: Nie możesz załączyć więcej niż 4 plików
   migrations:
     acct: nazwa@domena nowego konta
+    cancel: Anuluj przekierowanie
+    cancel_explanation: Anulowanie przekierowania aktywuje Twoje obecne konto ponownie, ale nie przeniesie z powrotem śledzących, których przeniesiono na tamto konto.
+    cancelled_msg: Pomyślnie anulowano przekierowanie.
+    errors:
+      already_moved: jest tym samym kontem, na które już się przeniosłeś(-aś)
+      missing_also_known_as: nie odwołuje się do tego konta
+      move_to_self: nie może być bieżącym kontem
+      not_found: nie mogło zostać odnalezione
+      on_cooldown: Nie możesz teraz przenieść konta
+    followers_count: Śledzący w chwili przenoszenia
+    incoming_migrations: Przenoszenie z innego konta
+    incoming_migrations_html: Aby przenieść się z innego konta na to, musisz najpierw <a href="%{path}">utworzyć alias konta</a>.
+    moved_msg: Twoje konto przekierowuje teraz na %{acct}, a śledzący są przenoszeni.
+    not_redirecting: Twoje konto nie przekierowuje obecnie na żadne inne konto.
+    on_cooldown: Ostatnio przeniosłeś(-aś) swoje konto. Ta funkcja będzie dostępna ponownie za %{count} dni.
+    past_migrations: Poprzednie migracje
+    proceed_with_move: Przenieś obserwujących
+    redirecting_to: Twoje konto przekierowuje na %{acct}.
+    set_redirect: Ustaw przekierowanie
+    warning:
+      backreference_required: Nowe konto musi wcześniej zostać skonfigurowane tak, aby odwoływało się do tego
+      before: 'Zanim kontynuujesz, przeczytaj uważnie te uwagi:'
+      cooldown: Po przeniesieniu się, istnieje okres przez który nie możesz ponownie się przenieść
+      disabled_account: Twoje obecne konto nie będzie później całkowicie użyteczne. Możesz jednak uzyskać dostęp do eksportu danych i ponownie aktywować je.
+      followers: To działanie przeniesie wszystkich Twoich śledzących z obecnego konta na nowe
+      only_redirect_html: Możesz też <a href="%{path}">po prostu skonfigurować przekierowanie na swój profil</a>.
+      other_data: Żadne inne dane nie zostaną automatycznie przeniesione
+      redirect: Twoje obecne konto zostanie uaktualnione o informację o przeniesieniu i wyłączone z wyszukiwania
   moderation:
     title: Moderacja
   notification_mailer:
@@ -810,6 +987,10 @@ pl:
       body: 'Twój wpis został podbity przez %{name}:'
       subject: Twój wpis został podbity przez %{name}
       title: Nowe podbicie
+  notifications:
+    email_events: 'Powiadamiaj e-mailem o:'
+    email_events_hint: 'Wybierz wydarzenia, o których chcesz otrzymywać powiadomienia:'
+    other_settings: Inne ustawienia powiadomień
   number:
     human:
       decimal_units:
@@ -833,6 +1014,7 @@ pl:
       duration_too_long: jest zbyt odległa
       duration_too_short: jest zbyt bliska
       expired: To głosowanie już zakończyło się
+      invalid_choice: Wybrana opcja głosowania nie istnieje
       over_character_limit: nie może zawierać więcej niż %{max} znaków
       too_few_options: musi zawierać przynajmniej dwie opcje
       too_many_options: nie może zawierać więcej niż %{max} opcji
@@ -840,9 +1022,16 @@ pl:
     other: Pozostałe
     posting_defaults: Domyślne ustawienia wpisów
     public_timelines: Publiczne osie czasu
+  reactions:
+    errors:
+      limit_reached: Przekroczono limit różnych reakcji
+      unrecognized_emoji: nie jest znanym emoji
   relationships:
     activity: Aktywność konta
     dormant: Uśpione
+    followers: Śledzący
+    following: Śledzeni
+    invited: Zaproszeni
     last_active: Ostatnia aktywność
     most_recent: Ostatnie
     moved: Przeniesione
@@ -918,6 +1107,7 @@ pl:
   settings:
     account: Konto
     account_settings: Ustawienia konta
+    aliases: Aliasy konta
     appearance: Wygląd
     authorized_apps: Uwierzytelnione aplikacje
     back: Powrót do Mastodona
@@ -936,6 +1126,8 @@ pl:
     profile: Profil
     relationships: Śledzeni i śledzący
     two_factor_authentication: Uwierzytelnianie dwuetapowe
+  spam_check:
+    spam_detected: To zgłoszenie jest automatyczne. Został wykryty spam.
   statuses:
     attached:
       description: 'Załączono: %{attached}'
@@ -956,6 +1148,8 @@ pl:
       many: 'zawiera niedozwolone hashtagi: %{tags}'
       one: 'zawiera niedozwolony hashtag: %{tags}'
       other: 'zawiera niedozwolone hashtagi: %{tags}'
+    errors:
+      in_reply_not_found: Post, na który próbujesz odpowiedzieć, nie istnieje.
     language_detection: Automatycznie wykrywaj język
     open_in_web: Otwórz w przeglądarce
     over_character_limit: limit %{max} znaków przekroczony
@@ -965,6 +1159,11 @@ pl:
       private: Nie możesz przypiąć niepublicznego wpisu
       reblog: Nie możesz przypiąć podbicia wpisu
     poll:
+      total_people:
+        few: "%{count} osoby"
+        many: "%{count} osób"
+        one: "%{count} osoba"
+        other: "%{count} osoby"
       total_votes:
         few: "%{count} głosy"
         many: "%{count} głosy"
@@ -972,6 +1171,7 @@ pl:
         other: "%{count} głosy"
       vote: Głosuj
     show_more: Pokaż więcej
+    show_thread: Pokaż wątek
     sign_in_to_participate: Zaloguj się, aby udzielić się w tej konwersacji
     title: '%{name}: "%{quote}"'
     visibilities:
@@ -985,6 +1185,8 @@ pl:
     pinned: Przypięty wpis
     reblogged: podbił
     sensitive_content: Wrażliwa zawartość
+  tags:
+    does_not_match_previous_name: nie pasuje do poprzedniej nazwy
   terms:
     body_html: |
       <h2>Polityka prywatności</h2>
@@ -1102,7 +1304,9 @@ pl:
         disable: Kiedy Twoje konto jest wyłączone, Twoje dane pozostają na serwerze, ale nie możesz wykonywać żadnych działań, zanim zostanie odblokowane.
         silence: Kiedy Twoje konto jest ograniczone, tylko osoby które je śledzą będą widzieć Twoje wpisy. Może ono też przestać być widoczne na publicznych listach. Inni wciąż mogą zacząć Cię śledzić.
         suspend: Twoje konto zostało zawieszone i wszystkie Twoje wpisy wraz z zawartością multimedialną zostały nieodwracalnie usunięte z tego serwera i serwerów, których użytkownicy śledzili Cię.
+      get_in_touch: Możesz odpowiedzieć na ten e-mail aby pozostać w kontakcie z prowadzącymi %{instance}.
       review_server_policies: Przejrzyj zasady serwera
+      statuses: 'Szczególnie dla:'
       subject:
         disable: Twoje konto %{acct} zostało wyłączone
         none: Ostrzeżenie dla %{acct}
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index abea40130..45f2b22d1 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -92,6 +92,7 @@ pt-BR:
       delete: Excluir
       destroyed_msg: Nota de moderação excluída com sucesso!
     accounts:
+      add_email_domain_block: Adicionar o domínio de email à lista negra
       approve: Aprovar
       approve_all: Aprovar tudo
       are_you_sure: Você tem certeza?
@@ -172,6 +173,7 @@ pt-BR:
         staff: Equipe
         user: Usuário
       search: Pesquisar
+      search_same_email_domain: Outros usuários com o mesmo domínio de e-mail
       search_same_ip: Outros usuários com o mesmo IP
       shared_inbox_url: Link da caixa de entrada compartilhada
       show:
@@ -193,21 +195,57 @@ pt-BR:
       web: Web
       whitelisted: Permitido
     action_logs:
+      action_types:
+        assigned_to_self_report: Adicionar relatório
+        change_email_user: Editar e-mail do usuário
+        confirm_user: Confirmar Usuário
+        create_account_warning: Criar Aviso
+        create_announcement: Criar Anúncio
+        create_custom_emoji: Criar Emoji Personalizado
+        create_domain_allow: Adicionar domínio permitido
+        create_domain_block: Adicionar domínio bloqueado
+        create_email_domain_block: Adicionar domínio de e-mail bloqueado
+        demote_user: Despromover Utilizador
+        destroy_announcement: Excluir anúncio
+        destroy_custom_emoji: Excluir emoji personalizado
+        destroy_domain_allow: Excluir domínio permitido
+        destroy_domain_block: Excluir domínio bloqueado
+        destroy_email_domain_block: Excluir domínio de e-mail bloqueado
+        destroy_status: Excluir Status
+        disable_2fa_user: Desativar autenticação de dois fatores
+        disable_custom_emoji: Desativar Emoji Personalizado
+        disable_user: Desativar usuário
+        enable_custom_emoji: Ativar Emoji Personalizado
+        enable_user: Ativar usuário
+        memorialize_account: Memorizar Conta
+        promote_user: Promover usuário
+        remove_avatar_user: Remover Avatar
+        reopen_report: Reabrir Relatório
+        reset_password_user: Redefinir a senha
+        resolve_report: Resolver Relatório
+        silence_account: Silenciar conta
+        suspend_account: Suspender Conta
+        unassigned_report: Remover relatório
+        unsilence_account: Deixar de Silenciar Conta
+        unsuspend_account: Retirar Suspensão à Conta
+        update_announcement: Editar anúncio
+        update_custom_emoji: Editar Emoji Personalizado
+        update_status: Editar Status
       actions:
         assigned_to_self_report: "%{name} pegou a denúncia %{target}"
         change_email_user: "%{name} alterou o endereço de e-mail do usuário %{target}"
         confirm_user: "%{name} confirmou o endereço de e-mail do usuário %{target}"
         create_account_warning: "%{name} enviou um aviso para %{target}"
-        create_announcement: "%{name} criou um novo anúncio %{target}"
+        create_announcement: "%{name} criou o novo anúncio %{target}"
         create_custom_emoji: "%{name} enviou o novo emoji %{target}"
         create_domain_allow: "%{name} permitiu %{target}"
-        create_domain_block: "%{name} bloqueou o domínio %{target}"
+        create_domain_block: "%{name} bloqueou %{target}"
         create_email_domain_block: "%{name} bloqueou o domínio de e-mail %{target}"
         demote_user: "%{name} rebaixou o usuário %{target}"
         destroy_announcement: "%{name} excluiu o anúncio %{target}"
         destroy_custom_emoji: "%{name} excluiu emoji %{target}"
         destroy_domain_allow: "%{name} bloqueou %{target}"
-        destroy_domain_block: "%{name} desbloqueou o domínio %{target}"
+        destroy_domain_block: "%{name} desbloqueou %{target}"
         destroy_email_domain_block: "%{name} permitiu domínio de e-mail %{target}"
         destroy_status: "%{name} excluiu toot de %{target}"
         disable_2fa_user: "%{name} desativou a exigência de autenticação de dois fatores para o usuário %{target}"
@@ -230,13 +268,16 @@ pt-BR:
         update_custom_emoji: "%{name} atualizou o emoji %{target}"
         update_status: "%{name} atualizou o status de %{target}"
       deleted_status: "(status excluído)"
+      empty: Nenhum registro encontrado.
+      filter_by_action: Filtrar por ação
+      filter_by_user: Filtrar por usuário
       title: Auditar histórico
     announcements:
       destroyed_msg: Anúncio excluído com sucesso!
       edit:
         title: Editar anúncio
-      empty: Nenhum anúncio encontrado.
-      live: Em exibição
+      empty: Sem anúncios.
+      live: Ao vivo
       new:
         create: Criar anúncio
         title: Novo anúncio
@@ -244,7 +285,7 @@ pt-BR:
       scheduled_for: Agendado para %{time}
       scheduled_msg: Anúncio agendado para publicação!
       title: Anúncios
-      unpublished_msg: Anúncio retirado de exibição com sucesso!
+      unpublished_msg: Anúncio despublicado com sucesso!
       updated_msg: Anúncio atualizado com sucesso!
     custom_emojis:
       assign_category: Atribuir categoria
@@ -307,12 +348,12 @@ pt-BR:
       week_users_new: usuários essa semana
       whitelist_mode: Modo lista de permitidos
     domain_allows:
-      add_new: Permitir
+      add_new: Permitir domínio
       created_msg: Domínio foi permitido
       destroyed_msg: Domínio foi bloqueado
       undo: Bloquear
     domain_blocks:
-      add_new: Bloquear outro domínio
+      add_new: Novo bloqueio de domínio
       created_msg: Domínio está sendo bloqueado
       destroyed_msg: Domínio desbloqueado
       domain: Domínio
@@ -358,6 +399,7 @@ pt-BR:
       destroyed_msg: Domínio de e-mail desbloqueado
       domain: Domínio
       empty: Sem domínios de e-mail bloqueados.
+      from_html: de %{domain}
       new:
         create: Adicionar domínio
         title: Novo domínio de e-mail bloqueado
@@ -421,7 +463,7 @@ pt-BR:
           other: "%{count} denúncias"
       action_taken_by: Atitude tomada por
       are_you_sure: Você tem certeza?
-      assign_to_self: Acatado por mim
+      assign_to_self: Pegar
       assigned: Moderador responsável
       by_target_domain: Domínio da conta denunciada
       comment:
@@ -537,6 +579,9 @@ pt-BR:
       trends:
         desc_html: Mostrar publicamente hashtags previamente revisadas que estão em alta
         title: Hashtags em alta
+    site_uploads:
+      delete: Excluir arquivo enviado
+      destroyed_msg: Upload do site excluído com sucesso!
     statuses:
       back_to_account: Voltar para página da conta
       batch:
@@ -573,7 +618,6 @@ pt-BR:
     warning_presets:
       add_new: Adicionar novo
       delete: Excluir
-      edit: Editar
       edit_preset: Editar o aviso pré-definido
       title: Gerenciar os avisos pré-definidos
   admin_mailer:
@@ -585,7 +629,7 @@ pt-BR:
       body_remote: Alguém da instância %{domain} reportou %{target}
       subject: Nova denúncia sobre %{instance} (#%{id})
     new_trending_tag:
-      body: 'A hashtag #%{name} está em alta hoje, mas não foi previamente revisada. Ela não estará visível publicamente a menos que você aprove, ou apenas salve o formulário do jeito que está para nunca mais ouvir falar dela.'
+      body: 'A hashtag #%{name} está em alta hoje, mas não foi previamente revisada. Ela não estará visível publicamente a menos que você aprove, ou salve o formulário do jeito que está para nunca mais ouvir falar dela.'
       subject: Nova hashtag disponível para revisão em %{instance} (#%{name})
   aliases:
     add_new: Criar alias
@@ -661,6 +705,7 @@ pt-BR:
     trouble_logging_in: Problemas para entrar?
   authorize_follow:
     already_following: Você já segue
+    already_requested: Você já enviou uma solicitação para seguir esta conta
     error: Infelizmente, ocorreu um erro ao buscar a conta remota
     follow: Seguir
     follow_request: 'Você mandou uma solicitação para seguir para:'
@@ -677,7 +722,7 @@ pt-BR:
     prompt: Confirme sua senha para continuar
   date:
     formats:
-      default: "%d %b %Y"
+      default: "%d %b, %Y"
   datetime:
     distance_in_words:
       about_x_hours: "%{count}h"
@@ -774,12 +819,12 @@ pt-BR:
     developers: Desenvolvedores
     more: Mais…
     resources: Recursos
-    trending_now: Em alta agora
+    trending_now: Em alta no momento
   generic:
     all: Tudo
     changes_saved_msg: Alterações foram salvas com sucesso!
     copy: Copiar
-    delete: Eliminar
+    delete: Excluir
     no_batch_actions_available: Nenhuma ação em lote disponível nesta página
     order_by: Ordenar por
     save_changes: Salvar alterações
@@ -849,6 +894,7 @@ pt-BR:
   media_attachments:
     validations:
       images_and_video: Não foi possível anexar um vídeo a um toot que já contém imagens
+      not_ready: Não é possível anexar arquivos que não terminaram de ser processados. Tente novamente daqui a pouco!
       too_many: Não foi possível anexar mais de 4 imagens
   migrations:
     acct: Mudou-se para
@@ -1070,6 +1116,8 @@ pt-BR:
     disallowed_hashtags:
       one: 'continha hashtag não permitida: %{tags}'
       other: 'continha hashtags não permitidas: %{tags}'
+    errors:
+      in_reply_not_found: O toot que você quer responder parece não existir.
     language_detection: Detectar idioma automaticamente
     open_in_web: Abrir no navegador
     over_character_limit: limite de caracteres de %{max} excedido
diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml
index 477c9d3a3..7bff3bf5c 100644
--- a/config/locales/pt-PT.yml
+++ b/config/locales/pt-PT.yml
@@ -92,6 +92,7 @@ pt-PT:
       delete: Eliminar
       destroyed_msg: Nota de moderação excluída com sucesso!
     accounts:
+      add_email_domain_block: Adicione o domínio de email à lista negra
       approve: Aprovar
       approve_all: Aprovar todos
       are_you_sure: Tens a certeza?
@@ -132,7 +133,7 @@ pt-PT:
         remote: Remoto
         title: Local
       login_status: Estado de início de sessão
-      media_attachments: Media anexa
+      media_attachments: Anexos de média
       memorialize: Converter em memorial
       moderation:
         active: Activo
@@ -172,6 +173,7 @@ pt-PT:
         staff: Equipa
         user: Utilizador
       search: Pesquisar
+      search_same_email_domain: Outros utilizadores com o mesmo domínio de email
       search_same_ip: Outros utilizadores com o mesmo IP
       shared_inbox_url: URL da caixa de entrada compartilhada
       show:
@@ -193,6 +195,42 @@ pt-PT:
       web: Web
       whitelisted: Está na lista branca
     action_logs:
+      action_types:
+        assigned_to_self_report: Atribuir Relatório
+        change_email_user: Alterar E-mail do Utilizador
+        confirm_user: Confirmar Utilizador
+        create_account_warning: Criar Aviso
+        create_announcement: Criar Anúncio
+        create_custom_emoji: Criar Emoji Personalizado
+        create_domain_allow: Criar Permissão de Domínio
+        create_domain_block: Criar Bloqueio de Domínio
+        create_email_domain_block: Criar Bloqueio de Domínio de E-mail
+        demote_user: Despromover Utilizador
+        destroy_announcement: Remover Anúncio
+        destroy_custom_emoji: Remover Emoji Personalizado
+        destroy_domain_allow: Remover Permissão de Domínio
+        destroy_domain_block: Remover Bloqueio de Domínio
+        destroy_email_domain_block: Remover Bloqueio de Domínio de E-mail
+        destroy_status: Remover Estado
+        disable_2fa_user: Desativar 2FA
+        disable_custom_emoji: Desativar Emoji Personalizado
+        disable_user: Desativar Utilizador
+        enable_custom_emoji: Ativar Emoji Personalizado
+        enable_user: Ativar Utilizador
+        memorialize_account: Memorizar Conta
+        promote_user: Promover Utilizador
+        remove_avatar_user: Remover Imagem de Perfil
+        reopen_report: Reabrir Relatório
+        reset_password_user: Repor Password
+        resolve_report: Resolver Relatório
+        silence_account: Silenciar Conta
+        suspend_account: Suspender Conta
+        unassigned_report: Desatribuir Relatório
+        unsilence_account: Deixar de Silenciar Conta
+        unsuspend_account: Retirar Suspensão à Conta
+        update_announcement: Atualizar Anúncio
+        update_custom_emoji: Atualizar Emoji Personalizado
+        update_status: Atualizar Estado
       actions:
         assigned_to_self_report: "%{name} atribuiu o relatório %{target} a si próprios"
         change_email_user: "%{name} alterou o endereço de e-mail do utilizador %{target}"
@@ -230,6 +268,9 @@ pt-PT:
         update_custom_emoji: "%{name} atualizou o emoji %{target}"
         update_status: "%{name} atualizou o estado de %{target}"
       deleted_status: "(apagou a publicação)"
+      empty: Não foram encontrados registos.
+      filter_by_action: Filtrar por ação
+      filter_by_user: Filtrar por utilizador
       title: Registo de auditoria
     announcements:
       destroyed_msg: Anúncio excluído com sucesso!
@@ -322,7 +363,7 @@ pt-PT:
         create: Criar bloqueio
         hint: O bloqueio de dominio não vai previnir a criação de entradas na base de dados, mas irá retroativamente e automaticamente aplicar métodos de moderação específica nessas contas.
         severity:
-          desc_html: "<strong>Silenciar</strong> irá fazer com que os posts dessas contas sejam invisíveis para todos que não a seguem. <strong>Supender</strong> irá eliminar todo o conteúdo guardado dessa conta, media e informação de perfil.Usa <strong>Nenhum</strong> se  apenas desejas rejeitar arquivos de media."
+          desc_html: "<strong>Silenciar</strong> irá fazer com que as publicações dessa conta sejam invisíveis para quem não a segue. <strong>Supender</strong> irá eliminar todo o conteúdo guardado dessa conta, média e informação de perfil. Use <strong>Nenhum</strong> se apenas deseja rejeitar arquivos de média."
           noop: Nenhum
           silence: Silenciar
           suspend: Suspender
@@ -331,11 +372,11 @@ pt-PT:
       private_comment_hint: Comentário sobre essa limitação de domínio para uso interno pelos moderadores.
       public_comment: Comentário público
       public_comment_hint: Comentário sobre essa limitação de domínio para o público geral, se ativada a divulgação da lista de limitações de domínio.
-      reject_media: Rejeitar ficheiros de media
-      reject_media_hint: Remove localmente arquivos armazenados e rejeita fazer guardar novos no futuro. Irrelevante na suspensão
+      reject_media: Rejeitar ficheiros de média
+      reject_media_hint: Remove arquivos de média armazenados localmente e rejeita descarregar novos arquivos no futuro. Irrelevante para suspensões
       reject_reports: Rejeitar relatórios
       reject_reports_hint: Ignorar todos os relatórios vindos deste domínio. Irrelevantes para efectuar suspensões
-      rejecting_media: a rejeitar ficheiros de media
+      rejecting_media: a rejeitar ficheiros de média
       rejecting_reports: a rejeitar relatórios
       severity:
         silence: silenciado
@@ -345,7 +386,7 @@ pt-PT:
           one: Uma conta na base de dados afectada
           other: "%{count} contas na base de dados afectadas"
         retroactive:
-          silence: Não silenciar todas as contas existentes nesse domínio
+          silence: Não silenciar contas afetadas existentes deste domínio
           suspend: Não suspender todas as contas existentes nesse domínio
         title: Remover o bloqueio de domínio de %{domain}
         undo: Anular
@@ -358,6 +399,7 @@ pt-PT:
       destroyed_msg: Bloqueio de domínio de email excluído com sucesso
       domain: Domínio
       empty: Nenhum domínio de e-mail atualmente na lista negra.
+      from_html: de %{domain}
       new:
         create: Adicionar domínio
         title: Novo bloqueio de domínio de email
@@ -379,7 +421,7 @@ pt-PT:
       total_followed_by_them: Seguidas por eles
       total_followed_by_us: Seguidas por nós
       total_reported: Relatórios sobre eles
-      total_storage: Anexos de media
+      total_storage: Anexos de média
     invites:
       deactivate_all: Desactivar todos
       filter:
@@ -395,7 +437,7 @@ pt-PT:
     relays:
       add_new: Adicionar novo repetidor
       delete: Apagar
-      description_html: Um <strong>repetidor da federação</strong> é um servidor intermediário que troca grandes volumes de publicações públicas entre servidores que o subscrevem e publicam. <strong>Ele pode ajudar pequenos e médios servidores a descobrir conteúdo do "fediverse"</strong>que, de outro modo, exigiria que os utilizadores locais seguissem manualmente outras pessoas em servidores remotos.
+      description_html: Um <strong>repetidor da federação</strong> é um servidor intermediário que troca grandes volumes de publicações públicas entre servidores que o subscrevem e publicam. <strong>Ele pode ajudar pequenos e médios servidores a descobrir conteúdo do "fediverse"</strong> que, de outro modo, exigiria que os utilizadores locais seguissem manualmente outras pessoas em servidores remotos.
       disable: Desactivar
       disabled: Desactivado
       enable: Activar
@@ -481,8 +523,8 @@ pt-PT:
         desc_html: Nomes de domínio que esta instância encontrou no fediverso
         title: Publicar lista de instâncias descobertas
       preview_sensitive_media:
-        desc_html: Previsualização de links noutros websites irá apresentar uma miniatura, mesmo que a media seja marcada como sensível
-        title: Mostrar media sensível em previsualizações OpenGraph
+        desc_html: A pre-visualização de links noutros sites irá apresentar uma miniatura, mesmo que a média seja marcada como sensível
+        title: Mostrar média sensível em pre-visualizações OpenGraph
       profile_directory:
         desc_html: Permite aos utilizadores serem descobertos
         title: Ativar directório do perfil
@@ -537,6 +579,9 @@ pt-PT:
       trends:
         desc_html: Exibir publicamente hashtags atualmente em destaque que já tenham sido revistas anteriormente
         title: Hashtags em destaque
+    site_uploads:
+      delete: Excluir arquivo carregado
+      destroyed_msg: Upload do site excluído com sucesso!
     statuses:
       back_to_account: Voltar para página da conta
       batch:
@@ -550,7 +595,7 @@ pt-PT:
       no_media: Não há média
       no_status_selected: Nenhum estado foi alterado porque nenhum foi selecionado
       title: Estado das contas
-      with_media: Com media
+      with_media: Com média
     tags:
       accounts_today: Usos únicos hoje
       accounts_week: Usos únicos desta semana
@@ -573,7 +618,6 @@ pt-PT:
     warning_presets:
       add_new: Adicionar novo
       delete: Apagar
-      edit: Editar
       edit_preset: Editar o aviso predefinido
       title: Gerir os avisos predefinidos
   admin_mailer:
@@ -661,6 +705,7 @@ pt-PT:
     trouble_logging_in: Problemas em iniciar sessão?
   authorize_follow:
     already_following: Tu já estás a seguir esta conta
+    already_requested: Já enviou anteriormente um pedido para seguir esta conta
     error: Infelizmente, ocorreu um erro ao buscar a conta remota
     follow: Seguir
     follow_request: 'Enviaste uma solicitação de seguidor para:'
@@ -737,7 +782,7 @@ pt-PT:
     archive_takeout:
       date: Data
       download: Descarregar o teu arquivo
-      hint_html: Podes pedir um arquivo das tuas <strong> publicações e ficheiros de media carregados</strong>. Os dados do ficheiro exportado estarão no formato ActivityPub, que pode ser lido com qualquer software compatível. Tu podes pedir um arquivo destes a cada 7 dias.
+      hint_html: Pode pedir um arquivo das suas <strong>publicações e ficheiros de média carregados</strong>. Os dados no ficheiro exportado estarão no formato ActivityPub, que pode ser lido com qualquer software compatível. Pode solicitar um arquivo a cada 7 dias.
       in_progress: A compilar o seu arquivo...
       request: Pede o teu arquivo
       size: Tamanho
@@ -849,6 +894,7 @@ pt-PT:
   media_attachments:
     validations:
       images_and_video: Não é possível anexar um vídeo a uma publicação que já contém imagens
+      not_ready: Não é possível anexar arquivos que não terminaram de ser processados. Tente novamente daqui a pouco!
       too_many: Não é possível anexar mais de 4 arquivos
   migrations:
     acct: username@domain da nova conta
@@ -1070,6 +1116,8 @@ pt-PT:
     disallowed_hashtags:
       one: 'continha uma hashtag proibida: %{tags}'
       other: 'continha as hashtags proibidas: %{tags}'
+    errors:
+      in_reply_not_found: A publicação a que está a tentar responder parece não existir.
     language_detection: Detectar automaticamente a língua
     open_in_web: Abrir no browser
     over_character_limit: limite de caracter excedeu %{max}
@@ -1109,9 +1157,9 @@ pt-PT:
       <h3 id="collect">Que informação nós recolhemos?</h3>
 
       <ul>
-      <li><em>Informação básica da conta</em>: Se te registares neste servidor, pode-te ser pedido que indiques um nome de utilizador, um endereço de e-mail e uma palavra-passe. Também podes introduzir informação adicional de perfil, tal como um nome a mostrar e dados biográficos, que carregues uma fotografia para o teu perfil e para o cabeçalho. O nome de utilizador, o nome a mostrar, a biografia, a imagem de perfil e a imagem de cabeçalho são sempre listados publicamente.</li>
-      <li><em>Publicações, seguimento e outra informação pública</em>: A lista de pessoas que tu segues é pública, o mesmo é verdade para os teus seguidores. Quando tu publicas uma mensagem, a data e a hora são guardados, tal como a aplicação a partir da qual a mensagem foi enviada. As mensagens podem conter anexos multimédia, tais como fotografias ou vídeos. Publicações públicas e não listadas são acessíveis publicamente. Quando expões uma publicação no teu perfil, isso é também informação disponível publicamente. As tuas publicações são enviadas aos teus seguidores. Em alguns casos isso significa que elas são enviadas para servidores diferentes onde são guardadas cópias. Quando tu apagas publicações, isso também é enviado para os teus seguidores. A acção de republicar ou favoritar outra publicação é sempre pública.</li>
-      <li><em>Publicações directas e exclusivas para seguidores</em>: Todas as publicações são guardadas e processadas no servidor. Publicações exclusivas para seguidores são enviadas para os teus seguidores e para utilizadores que são nelas mencionados. As publicações directas são enviadas apenas para os utilizadores nelas mencionados. Em alguns casos isso significa que elas são enviadas para diferentes servidores onde são guardadas cópias das mesmas. Nós fazemos um grande esforço para limitar o acesso a estas publicações aos utilizadores autorizados, mas outros servidores podem falhar neste objectivo.  Por isso, tu deves rever os servidores a que os teus seguidores pertencem. Tu podes activar uma opção para aprovar e rejeitar manualmente novos seguidores nas configurações. <em>Por favor, tem em mente que os gestores do servidor e qualquer servidor que receba a publicação pode lê-la</em>e que os destinatários podem fazer uma captura de tela, copiar ou partilhar a publicação. <em>Não partilhes qualquer informação perigosa no Mastodon.</em></li>
+      <li><em>Informação básica da conta</em>: Se te registares neste servidor, pode-te ser pedido que indiques um nome de utilizador, um endereço de email e uma palavra-passe. Também podes introduzir informação adicional de perfil, tal como um nome a mostrar e dados biográficos, que carregues uma fotografia para o teu perfil e para o cabeçalho. O nome de utilizador, o nome a mostrar, a biografia, a imagem de perfil e a imagem de cabeçalho são sempre listados publicamente.</li>
+      <li><em>Publicações, seguimento e outra informação pública</em>: A lista de pessoas que tu segues é pública, o mesmo é verdade para os teus seguidores. Quando tu publicas uma mensagem, a data e a hora são guardados, tal como a aplicação a partir da qual a mensagem foi enviada. As mensagens podem conter anexos média, tais como fotografias ou vídeos. Publicações públicas e não listadas são acessíveis publicamente. Quando expões uma publicação no teu perfil, isso é também informação disponível publicamente. As tuas publicações são enviadas aos teus seguidores. Em alguns casos isso significa que elas são enviadas para servidores diferentes onde são guardadas cópias. Quando tu apagas publicações, isso também é enviado para os teus seguidores. A ação de republicar ou favoritar outra publicação é sempre pública.</li>
+      <li><em>Publicações diretas e exclusivas para seguidores</em>: Todas as publicações são guardadas e processadas no servidor. Publicações exclusivas para seguidores são enviadas para os teus seguidores e para utilizadores que são nelas mencionados. As publicações diretas são enviadas apenas para os utilizadores nelas mencionados. Em alguns casos isso significa que elas são enviadas para diferentes servidores onde são guardadas cópias das mesmas. Nós fazemos um grande esforço para limitar o acesso a estas publicações aos utilizadores autorizados, mas outros servidores podem falhar neste objetivo. Por isso, tu deves rever os servidores a que os teus seguidores pertencem. Tu podes ativar uma opção para aprovar e rejeitar manualmente novos seguidores nas configurações. <em>Por favor, tem em mente que os gestores do servidor e qualquer servidor que receba a publicação pode lê-la</em> e que os destinatários podem fazer uma captura de tela, copiar ou partilhar a publicação. <em>Não partilhes qualquer informação perigosa no Mastodon.</em></li>
       <li><em>IPs e outros metadados</em>: Quando inicias sessão, nós guardamos o endereço de IP a partir do qual iniciaste a sessão, tal como o nome do teu navegador. Todas as sessões estão disponíveis para verificação e revogação nas configurações. O último endereço de IP usado é guardado até 12 meses. Nós também podemos guardar registos de servidor, os quais incluem o endereço de IP de cada pedido dirigido ao nosso servidor.</li>
       </ul>
 
@@ -1140,7 +1188,7 @@ pt-PT:
       <p>Nós envidaremos todos os esforços no sentido de:</p>
 
       <ul>
-      <li>Guardar registos do servidor contendo o endereço de IP de todos os pedidos feitos a este  servidor, considerando que estes registos não serão guardados por mais de 90 dias.</li>
+      <li>Guardar registos do servidor contendo o endereço de IP de todos os pedidos feitos a este servidor, considerando que estes registos não serão guardados por mais de 90 dias.</li>
       <li>Guardar os endereços de IP associados aos utilizadores registados durante um período que não ultrapassará os 12 meses.</li>
       </ul>
 
@@ -1246,7 +1294,7 @@ pt-PT:
       subject: Bem-vindo ao Mastodon
       tip_federated_timeline: A cronologia federativa é uma visão global da rede Mastodon. Mas só inclui pessoas que os teus vizinhos subscrevem, por isso não é uma visão completa.
       tip_following: Tu segues o(s) administrador(es) do teu servidor por defeito. Para encontrares mais pessoas interessantes, procura nas cronologias local e federativa.
-      tip_local_timeline: A cronologia local é uma visão global das pessoas em %{instance}. Estes são os teus vizinhos próximos!
+      tip_local_timeline: A cronologia local é uma visão global das pessoas em %{instance}. Estes são os teus vizinhos mais próximos!
       tip_mobile_webapp: Se o teu navegador móvel te oferecer a possibilidade de adicionar o Mastodon ao teu homescreen, tu podes receber notificações push. Ele age como uma aplicação nativa de vários modos!
       tips: Dicas
       title: Bem-vindo a bordo, %{name}!
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 6196ac3eb..30f237780 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -100,6 +100,7 @@ ru:
       delete: Удалить
       destroyed_msg: Заметка модератора успешно удалена!
     accounts:
+      add_email_domain_block: Добавить домен электронной почты в чёрный список
       approve: Подтвердить
       approve_all: Подтвердить все
       are_you_sure: Вы уверены?
@@ -180,6 +181,7 @@ ru:
         staff: Персонал
         user: Пользователь
       search: Поиск
+      search_same_email_domain: Другие пользователи с тем же доменом электронной почты
       search_same_ip: Другие пользователи с таким же IP
       shared_inbox_url: URL общих входящих
       show:
@@ -201,6 +203,39 @@ ru:
       web: Веб
       whitelisted: В белом списке
     action_logs:
+      action_types:
+        assigned_to_self_report: Присвоение жалоб
+        change_email_user: Изменение e-mail пользователей
+        confirm_user: Подтверждение пользователей
+        create_account_warning: Выдача предупреждения
+        create_announcement: Создание объявлений
+        create_custom_emoji: Добавление эмодзи
+        create_domain_block: Блокировка доменов
+        create_email_domain_block: Блокировка e-mail доменов
+        demote_user: Разжалование пользователей
+        destroy_announcement: Удаление объявлений
+        destroy_custom_emoji: Удаление эмодзи
+        destroy_domain_block: Разблокировка доменов
+        destroy_email_domain_block: Разблокировка e-mail доменов
+        destroy_status: Удаление постов
+        disable_2fa_user: Отключение 2FA
+        disable_custom_emoji: Отключение эмодзи
+        disable_user: Заморозка пользователей
+        enable_custom_emoji: Включение эмодзи
+        enable_user: Разморозка пользователей
+        promote_user: Повышение пользователей
+        remove_avatar_user: Удаление аватаров
+        reopen_report: Возобновление жалоб
+        reset_password_user: Сброс пароля пользователей
+        resolve_report: Отметка жалоб «решёнными»
+        silence_account: Скрытие пользователей
+        suspend_account: Блокировка пользователей
+        unassigned_report: Снятие жалоб
+        unsilence_account: Отмена скрытия пользователей
+        unsuspend_account: Разблокировка пользователей
+        update_announcement: Обновление объявлений
+        update_custom_emoji: Обновление эмодзи
+        update_status: Изменение постов
       actions:
         assigned_to_self_report: "%{name} назначил(а) себя для решения жалобы %{target}"
         change_email_user: "%{name} сменил(а) e-mail пользователя %{target}"
@@ -218,7 +253,7 @@ ru:
         destroy_domain_block: "%{name} разблокировал(а) домен %{target}"
         destroy_email_domain_block: "%{name} добавил(а) e-mail домен %{target} в белый список"
         destroy_status: "%{name} удалил(а) пост пользователя %{target}"
-        disable_2fa_user: "%{name} отключил(а) двухэтапную авторизацию у пользователя %{target}"
+        disable_2fa_user: "%{name} отключил(а) требование двухэтапной авторизации для пользователя %{target}"
         disable_custom_emoji: "%{name} отключил(а) эмодзи %{target}"
         disable_user: "%{name} заморозил(а) пользователя %{target}"
         enable_custom_emoji: "%{name} включил(а) эмодзи %{target}"
@@ -238,6 +273,9 @@ ru:
         update_custom_emoji: "%{name} обновил(а) эмодзи %{target}"
         update_status: "%{name} изменил(а) пост пользователя %{target}"
       deleted_status: "(удалённый пост)"
+      empty: Журнал пуст.
+      filter_by_action: Фильтр по действию
+      filter_by_user: Фильтр по пользователю
       title: Журнал событий
     announcements:
       destroyed_msg: Объявление удалено.
@@ -373,6 +411,7 @@ ru:
       destroyed_msg: Домен убран из списка e-mail блокировки
       domain: Домен
       empty: Никакие e-mail домены не блокируются.
+      from_html: с %{domain}
       new:
         create: Создать блокировку
         title: Новая блокировка по домену
@@ -381,9 +420,9 @@ ru:
       by_domain: Домен
       delivery_available: Доставка возможна
       known_accounts:
-        few: "%{count} известных учётных записей"
+        few: "%{count} известные учётные записи"
         many: "%{count} известных учётных записей"
-        one: "%{count} известных учётных записей"
+        one: "%{count} известная учётная запись"
         other: "%{count} известных учётных записей"
       moderation:
         all: Все
@@ -434,12 +473,12 @@ ru:
           few: "%{count} заметки"
           many: "%{count} заметок"
           one: "%{count} заметка"
-          other: "%{count} заметки"
+          other: "%{count} заметок"
         reports:
           few: "%{count} жалобы"
           many: "%{count} жалоб"
           one: "%{count} жалоба"
-          other: "%{count} жалобы"
+          other: "%{count} жалоб"
       action_taken_by: 'Действие предпринято:'
       are_you_sure: Вы уверены?
       assign_to_self: Назначить себе
@@ -558,6 +597,9 @@ ru:
       trends:
         desc_html: Публично отобразить проверенные хэштеги, актуальные на данный момент
         title: Популярные хэштеги
+    site_uploads:
+      delete: Удалить загруженный файл
+      destroyed_msg: Файл успешно удалён.
     statuses:
       back_to_account: Назад к учётной записи
       batch:
@@ -594,7 +636,6 @@ ru:
     warning_presets:
       add_new: Добавить
       delete: Удалить
-      edit: Изменить
       edit_preset: Удалить шаблон предупреждения
       title: Управление шаблонами предупреждений
   admin_mailer:
@@ -678,16 +719,17 @@ ru:
       confirming: Ожидание подтверждения e-mail.
       functional: Ваша учётная запись в полном порядке.
       pending: Ваша заявка ожидает одобрения администраторами, это может занять немного времени. Вы получите письмо, как только заявку одобрят.
-      redirecting_to: Ваша учётная запись признана неактивным, потому что она перенаправляется на %{acct}.
+      redirecting_to: Ваша учётная запись деактивированна, потому что вы настроили перенаправление на %{acct}.
     trouble_logging_in: Не удаётся войти?
   authorize_follow:
     already_following: Вы уже подписаны на эту учётную запись
+    already_requested: Вы уже отправили запрос на подписку на эту учётную запись
     error: К сожалению, при поиске удалённой учётной записи возникла ошибка
     follow: Подписаться
     follow_request: 'Вы отправили запрос на подписку:'
-    following: 'Ура! Теперь Вы подписаны на:'
+    following: 'Готово! Вы подписались на:'
     post_follow:
-      close: Или просто закрыть это окно.
+      close: Или просто закройте это окно.
       return: Вернуться к профилю пользователя
       web: Открыть в веб-версии
     title: Подписаться на %{acct}
@@ -723,7 +765,7 @@ ru:
       before: 'Внимательно прочитайте следующую информацию перед началом:'
       caches: Некоторые данные, обработанные другими узлами, однако, могут храниться ещё какое-то время
       data_removal: Все ваши золотые посты, шикарный профиль и прочие данные будут безвозвратно уничтожены
-      email_change_html: <a href="%{path}">Поменять свой e-mail</a> можно не удаляя учётной записи
+      email_change_html: <a href="%{path}">Поменять свой e-mail</a> можно не удаляя учётную запись
       email_contact_html: Если письмо не приходит, обратитесь за помощю на <a href="mailto:%{email}">%{email}</a>
       email_reconfirmation_html: Если вы не получили письмо с подтверждением, его можно <a href="%{path}">запросить ещё раз</a>
       irreversible: После удаления восстановить или повторно активировать учётную запись не получится
@@ -874,6 +916,7 @@ ru:
   media_attachments:
     validations:
       images_and_video: Нельзя добавить видео к посту с изображениями
+      not_ready: Не удаётся прикрепить файлы, обработка которых не завершена. Повторите попытку чуть позже!
       too_many: Нельзя добавить более 4 файлов
   migrations:
     acct: имя@домен новой учётной записи
@@ -924,8 +967,8 @@ ru:
         other: "%{count} новых уведомлений с вашего последнего захода \U0001F418"
       title: В ваше отсутствие…
     favourite:
-      body: "%{name} добавил ваш пост в избранное:"
-      subject: "%{name} добавил ваш пост в избранное"
+      body: "%{name} добавил(а) ваш пост в избранное:"
+      subject: "%{name} добавил(а) ваш пост в избранное"
       title: Понравившийся статус
     follow:
       body: "%{name} теперь подписан(а) на вас!"
@@ -939,7 +982,7 @@ ru:
     mention:
       action: Ответить
       body: 'Вас упомянул(а) %{name} в:'
-      subject: Вы были упомянуты %{name}
+      subject: "%{name} упомянул(а) вас"
       title: Новое упоминание
     reblog:
       body: 'Ваш пост был продвинут %{name}:'
@@ -1010,7 +1053,7 @@ ru:
   remote_interaction:
     favourite:
       proceed: Добавить в избранное
-      prompt: 'Вы собираетесь поставить отметку "нравится" этому посту:'
+      prompt: 'Вы собираетесь добавить в избранное следующий пост:'
     reblog:
       proceed: Продвинуть пост
       prompt: 'Вы хотите продвинуть этот пост:'
@@ -1105,6 +1148,8 @@ ru:
       many: 'содержались запрещённые хэштеги: %{tags}'
       one: 'содержался запрещённый хэштег: %{tags}'
       other: 'содержались запрещённые хэштеги: %{tags}'
+    errors:
+      in_reply_not_found: Пост, на который вы пытаетесь ответить, не существует или удалён.
     language_detection: Определять язык автоматически
     open_in_web: Открыть в веб-версии
     over_character_limit: превышен лимит символов (%{max})
@@ -1115,7 +1160,7 @@ ru:
       reblog: Нельзя закрепить продвинутый пост
     poll:
       total_people:
-        few: "%{count} человек"
+        few: "%{count} человека"
         many: "%{count} человек"
         one: "%{count} человек"
         other: "%{count} человек"
@@ -1239,7 +1284,7 @@ ru:
     generate_recovery_codes: Сгенерировать коды восстановления
     instructions_html: "<strong>Отсканируйте этот QR-код с помощью Google Authenticator, Яндекс.Ключа или любого другого подобного приложения</strong>. После сканирования и добавления, приложение начнёт генерировать коды, которые потребуется вводить для завершения входа в учётную запись."
     lost_recovery_codes: Коды восстановления позволяются войти в учётную запись в случае утери смартфона. Если вы потеряли свои коды восстановления, вы можете создать новые здесь. Прошлые коды работать перестанут.
-    manual_instructions: 'Если Вы не можете отсканировать QR-код и хотите ввести его вручную, секрет представлен здесь открытым текстом:'
+    manual_instructions: 'Если отсканировать QR-код не получается или не представляется возможным, вы можете ввести его вручную:'
     recovery_codes: Коды восстановления
     recovery_codes_regenerated: Коды восстановления успешно сгенерированы
     recovery_instructions_html: 'Пожалуйста, сохраните коды ниже в надёжном месте: они понадобятся, чтобы войти в учётную запись, если вы потеряете доступ к своему смартфону. Вы можете вручную переписать их, распечатать и спрятать среди важных документов или, например, в любимой книжке. <strong>Каждый код действителен один раз</strong>.'
@@ -1260,8 +1305,8 @@ ru:
       statuses: 'В частности, для:'
       subject:
         disable: Ваша учётная запись %{acct} заморожена
-        none: "%{acct}, вам вынесено предупреждение"
-        silence: На вашу учётную запись, %{acct}, были наложены ограничения
+        none: "%{acct} вынесено предупреждение"
+        silence: На учётную запись %{acct} наложены ограничения
         suspend: Ваша учётная запись %{acct} была заблокирована
       title:
         disable: Учётная запись заморожена
diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml
index 52933da12..a4a77e20f 100644
--- a/config/locales/simple_form.ar.yml
+++ b/config/locales/simple_form.ar.yml
@@ -8,6 +8,7 @@ ar:
         acct: ادخِل عنون الحساب username@domain الذي تودّ الإنتقال إليه
       account_warning_preset:
         text: بإمكانك استخدام نفس القواعد التي نجدها في التبويقات كعناوين الروابط والوسوم والإشارات
+        title: اختياري. غير مرئي للمُستَلِم
       admin_account_action:
         send_email_notification: سوف يتلقى المستخدم رسالة تُفسِّر ما حدث على حسابه
         type_html: اختر ما تود إجراؤه على <strong>%{acct}</strong>
@@ -70,6 +71,7 @@ ar:
         acct: مُعرّف الحساب الجديد
       account_warning_preset:
         text: نموذج نصي
+        title: العنوان
       admin_account_action:
         include_statuses: أدرج التبويقات التي تم الإبلاغ عنها ضمن الرسالة الإلكترونية
         send_email_notification: إشعار المستخدِم عبر البريد الإلكتروني
diff --git a/config/locales/simple_form.ast.yml b/config/locales/simple_form.ast.yml
index 39cfa32c4..1a62eb76b 100644
--- a/config/locales/simple_form.ast.yml
+++ b/config/locales/simple_form.ast.yml
@@ -28,6 +28,8 @@ ast:
         fields:
           name: Etiqueta
           value: Conteníu
+      account_warning_preset:
+        title: Títulu
       admin_account_action:
         type: Aición
         types:
diff --git a/config/locales/simple_form.br.yml b/config/locales/simple_form.br.yml
index c7677c850..b67db471f 100644
--- a/config/locales/simple_form.br.yml
+++ b/config/locales/simple_form.br.yml
@@ -1 +1,23 @@
+---
 br:
+  simple_form:
+    labels:
+      account_warning_preset:
+        title: Titl
+      announcement:
+        text: Kemenn
+      defaults:
+        display_name: Anv diskouezet
+        header: Talbenn
+        locale: Yezh ar c'hetal
+        new_password: Ger-tremen nevez
+        password: Ger-tremen
+        setting_display_media_default: Dre ziouer
+        setting_display_media_hide_all: Kuzhat pep tra
+        setting_display_media_show_all: Diskouez pep tra
+      tag:
+        name: Ger-klik
+    'no': Ket
+    required:
+      mark: "*"
+    'yes': Ya
diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml
index e91b74f85..f912e2e9e 100644
--- a/config/locales/simple_form.ca.yml
+++ b/config/locales/simple_form.ca.yml
@@ -8,6 +8,7 @@ ca:
         acct: Especifica l'usuari@domini del compte al que et vols moure
       account_warning_preset:
         text: Pots utilitzar totes les sintaxi com ara URL, etiquetes i mencions
+        title: Opcional. No és visible per al destinatari
       admin_account_action:
         include_statuses: L'usuari veurà quins tuts han causat l'acció de moderació o avís
         send_email_notification: L'usuari rebrà una explicació del que ha passat amb el seu compte
@@ -53,6 +54,9 @@ ca:
         whole_word: Quan la paraula clau o la frase sigui només alfanumèrica, s'aplicarà si coincideix amb la paraula sencera
       domain_allow:
         domain: Aquest domini podrà obtenir dades d’aquest servidor i les dades entrants d’aquests seran processades i emmagatzemades
+      email_domain_block:
+        domain: Això pot ser el nom del domini que es veu en l’adreça de correu electrònic, el registre MX al que resol el domini o l’IP del servidor al que resol el registre MX. Es comprovaran amb el registre d’usuari i es rebutjarà la inscripció.
+        with_dns_records: Es procurarà resoldre els registres DNS del domini determinat i els resultats també es llistaran a la llista negra
       featured_tag:
         name: 'És possible que vulguis utilitzar un d''aquests:'
       form_challenge:
@@ -78,6 +82,7 @@ ca:
         acct: Nom del nou compte
       account_warning_preset:
         text: Text predefinit
+        title: Títol
       admin_account_action:
         include_statuses: Inclou tuts reportats en el correu electrònic
         send_email_notification: Notifica l'usuari per correu electrònic
@@ -150,6 +155,8 @@ ca:
         username: Nom d'usuari
         username_or_email: Nom d'usuari o adreça electrònica
         whole_word: Paraula sencera
+      email_domain_block:
+        with_dns_records: Incloure registres MX i IP del domini
       featured_tag:
         name: Etiqueta
       interactions:
diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml
index f4737069b..9ea83a6e7 100644
--- a/config/locales/simple_form.co.yml
+++ b/config/locales/simple_form.co.yml
@@ -8,6 +8,7 @@ co:
         acct: Entrate u cugnome@duminiu di u contu induve vulete traslucà
       account_warning_preset:
         text: Pudete utilizà a sintassa di i statuti, per esempiu l'URL, hashtag, minzione
+        title: In uzzione. Micca visibile per u distinatariu
       admin_account_action:
         include_statuses: L'utilizatore viderà i statuti rispunsevuli di l'azzione o l'avertimentu di muderazione
         send_email_notification: L'utilizatore hà da riceve una spiegazione di cio chì hè accadutu à u so contu
@@ -53,6 +54,9 @@ co:
         whole_word: Quandu a parolla o a frasa sana hè alfanumerica, sarà applicata solu s'ella currisponde à a parolla sana
       domain_allow:
         domain: Stu duminiu puderà ricuperà i dati di stu servore è i dati ch'affaccanu da quallà saranu trattati è cunservati
+      email_domain_block:
+        domain: Pò esse u duminiu affissatu nant'à l'indirizzu e-mail, l'intrata MX assuciata à u duminiu, o l'IP di u servore assuciatu à l'intrata MX. Quessi anu da esse verificati durante l'arregistramente di l'utilizatore, chì sarà righjittatu.
+        with_dns_records: Un tintativu di cunsultà i dati DNS di u duminiu sarà fattu, è i risultati saranu ancu messi nant'à a lista nera
       featured_tag:
         name: 'Pudete vulè utilizà unu di quelli:'
       form_challenge:
@@ -78,6 +82,7 @@ co:
         acct: Cugnome di u novu contu
       account_warning_preset:
         text: Testu preselezziunatu
+        title: Titulu
       admin_account_action:
         include_statuses: Inchjude i statuti palisati indè l'e-mail
         send_email_notification: Nutificà l'utilizatore cù un'e-mail
@@ -150,6 +155,8 @@ co:
         username: Cugnome
         username_or_email: Cugnome o Email
         whole_word: Parolla sana
+      email_domain_block:
+        with_dns_records: Inchjude intrate MX è indirizze IP di u duminiu
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml
index 19aca7334..d8e272c8b 100644
--- a/config/locales/simple_form.cy.yml
+++ b/config/locales/simple_form.cy.yml
@@ -8,6 +8,7 @@ cy:
         acct: Rhowch enwdefnyddiwr@parth y cyfrif rydych chi am symud iddo
       account_warning_preset:
         text: Gallwch defnyddio cystrawen tŵt, fel URLs, hashnodau a sôniadau
+        title: Yn ddewisiol. Ddim yn weladwy i'r derbynydd
       admin_account_action:
         include_statuses: Bydd y defnyddiwr yn gweld pa tŵtiau sydd wedi achosi'r weithred gymedroli neu'r rhybudd
         send_email_notification: Bydd y defnyddiwr yn derbyn esboniad o beth digwyddodd gyda'i cyfrif
@@ -78,6 +79,7 @@ cy:
         acct: Enw'r cyfrif newydd
       account_warning_preset:
         text: Testun rhagosodedig
+        title: Teitl
       admin_account_action:
         include_statuses: Cynhwyswch tŵtiau yr adroddwyd amdanynt yn yr e-bost
         send_email_notification: Hysbysu'r defnyddiwr trwy e-bost
diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml
index 0863cc4a8..02d8ffbaa 100644
--- a/config/locales/simple_form.de.yml
+++ b/config/locales/simple_form.de.yml
@@ -8,6 +8,7 @@ de:
         acct: Gib den benutzernamen@domain des Kontos an, zu dem du umziehen möchtest
       account_warning_preset:
         text: Du kannst Beitragssyntax benutzen, wie z.B. URLs, Hashtags und Erwähnungen
+        title: Optional. Für den Empfänger nicht sichtbar
       admin_account_action:
         include_statuses: Der Benutzer wird sehen, welche Beiträge diese Maßnahme verursacht haben
         send_email_notification: Benutzer_in wird Bescheid gegeben, was mit dem Konto geschehen ist
@@ -43,7 +44,7 @@ de:
         setting_default_sensitive: Heikle Medien werden erst nach einem Klick sichtbar
         setting_display_media_default: Verstecke Medien, die als sensibel markiert sind
         setting_display_media_hide_all: Alle Medien immer verstecken
-        setting_display_media_show_all: Medien, die als sensibel markiert sind, immer anzeigen
+        setting_display_media_show_all: Alle Medien immer anzeigen
         setting_hide_network: Wem du folgst und wer dir folgt, wird in deinem Profil nicht angezeigt
         setting_noindex: Betrifft dein öffentliches Profil und deine Beiträge
         setting_show_application: Die Anwendung die du nutzst wird in der detaillierten Ansicht deiner Beiträge angezeigt
@@ -53,6 +54,9 @@ de:
         whole_word: Wenn das Schlagwort nur aus Buchstaben und Zahlen besteht, wird es nur angewendet, wenn es dem ganzen Wort entspricht
       domain_allow:
         domain: Diese Domain kann Daten von diesem Server abrufen und eingehende Daten werden verarbeitet und gespeichert
+      email_domain_block:
+        domain: Dies kann der Domainname sein, der in der E-Mail-Adresse angezeigt wird, den MX-Datensatz, der aufgelöst wird oder die IP des Servers, auf dem der MX-Eintrag aufgelöst wird. Diese werden bei der Registrierung überprüft und die Registrierung wird abgelehnt.
+        with_dns_records: Ein Versuch die DNS-Einträge der Domain aufzulösen wurde unternommen und diese Ergebnisse werden unter anderem auch geblacklistet
       featured_tag:
         name: 'Du möchtest vielleicht einen von diesen benutzen:'
       form_challenge:
@@ -78,6 +82,7 @@ de:
         acct: Adresse des neuen Kontos
       account_warning_preset:
         text: Vorlagentext
+        title: Titel
       admin_account_action:
         include_statuses: Meldungen der E-Mail beifügen
         send_email_notification: Benachrichtige den Nutzer per E-Mail
@@ -150,6 +155,8 @@ de:
         username: Profilname
         username_or_email: Profilname oder E-Mail
         whole_word: Ganzes Wort
+      email_domain_block:
+        with_dns_records: MX-Einträge und IPs der Domain einbeziehen
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml
index 231c32959..bb9033085 100644
--- a/config/locales/simple_form.el.yml
+++ b/config/locales/simple_form.el.yml
@@ -7,7 +7,8 @@ el:
       account_migration:
         acct: Όρισε το username@domain του λογαριασμού στον οποίο θέλεις να μετακινηθείς
       account_warning_preset:
-        text: Μπορείς να χρησιμοποιήσεις το ίδιο συντακτικό των τουτ όπως URL, ταμπέλες και αναφορές
+        text: Μπορείς να χρησιμοποιήσεις το ίδιο συντακτικό των τουτ όπως URL, ετικέτες και αναφορές
+        title: Προαιρετικό. Δεν εμφανίζεται στον παραλήπτη
       admin_account_action:
         include_statuses: Ο χρήστης θα δει ποια τουτ προκάλεσαν την προειδοποίηση ή την ενέργεια των διαχειριστών
         send_email_notification: Ο χρήστης θα λάβει μια εξήγηση του τι συνέβη με τον λογαριασμό του
@@ -70,7 +71,7 @@ el:
     labels:
       account:
         fields:
-          name: Ταμπέλα
+          name: Περιγραφή
           value: Περιεχόμενο
       account_alias:
         acct: Διακριτικό του παλιού λογαριασμού
@@ -78,6 +79,7 @@ el:
         acct: Διακριτικό του νέου λογαριασμού
       account_warning_preset:
         text: Προκαθορισμένο κείμενο
+        title: Τίτλος
       admin_account_action:
         include_statuses: Συμπερίληψη των καταγγελλομένων τουτ στο email
         send_email_notification: Ενημέρωση χρήστη μέσω email
@@ -150,8 +152,10 @@ el:
         username: Όνομα χρηστη
         username_or_email: Όνομα ή διεύθυνση email χρήστη
         whole_word: Ολόκληρη λέξη
+      email_domain_block:
+        with_dns_records: Συμπερίληψη εγγραφών MX και διευθύνσεων IP του τομέα
       featured_tag:
-        name: Ταμπέλα
+        name: Ετικέτα
       interactions:
         must_be_follower: Μπλόκαρε τις ειδοποιήσεις από όσους δεν σε ακολουθούν
         must_be_following: Μπλόκαρε τις ειδοποιήσεις από όσους δεν ακολουθείς
@@ -169,12 +173,12 @@ el:
         pending_account: Αποστολή email όταν υπάρχει νέος λογαριασμός για επιθεώρηση
         reblog: Αποστολή email όταν κάποιος προωθεί τη δημοσίευση σου
         report: Αποστολή email όταν υποβάλλεται νέα καταγγελία
-        trending_tag: Αποστολή email όταν μια μη-εγκεκριμένη ταμπέλα γίνεται δημοφιλής
+        trending_tag: Αποστολή email όταν μια μη-εγκεκριμένη ετικέτα γίνεται δημοφιλής
       tag:
-        listable: Εμφάνιση αυτής της ταμπέλας στο δημόσιο κατάλογο
-        name: Ταμπέλα
-        trendable: Εμφάνιση της ταμπέλας στις τάσεις
-        usable: Χρήση της ταμπέλας σε τουτ
+        listable: Εμφάνιση αυτής της ετικέτας στο δημόσιο κατάλογο
+        name: Ετικέτα
+        trendable: Εμφάνιση της ετικέτας στις τάσεις
+        usable: Χρήση της ετικέτας σε τουτ
     'no': Όχι
     recommended: Προτείνεται
     required:
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index c6a301804..49a6007e9 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -8,6 +8,7 @@ en:
         acct: Specify the username@domain of the account you want to move to
       account_warning_preset:
         text: You can use toot syntax, such as URLs, hashtags and mentions
+        title: Optional. Not visible to the recipient
       admin_account_action:
         include_statuses: The user will see which toots have caused the moderation action or warning
         send_email_notification: The user will receive an explanation of what happened with their account
@@ -46,8 +47,8 @@ en:
         setting_default_language: The language of your toots can be detected automatically, but it's not always accurate
         setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click
         setting_display_media_default: Hide media marked as sensitive
-        setting_display_media_hide_all: Always hide all media
-        setting_display_media_show_all: Always show media marked as sensitive
+        setting_display_media_hide_all: Always hide media
+        setting_display_media_show_all: Always show media
         setting_hide_network: Who you follow and who follows you will not be shown on your profile
         setting_noindex: Affects your public profile and status pages
         setting_show_application: The application you use to toot will be displayed in the detailed view of your toots
@@ -58,6 +59,9 @@ en:
         whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word
       domain_allow:
         domain: This domain will be able to fetch data from this server and incoming data from it will be processed and stored
+      email_domain_block:
+        domain: This can be the domain name that shows up in the e-mail address, the MX record that domain resolves to, or IP of the server that MX record resolves to. Those will be checked upon user sign-up and the sign-up will be rejected.
+        with_dns_records: An attempt to resolve the given domain's DNS records will be made and the results will also be blacklisted
       featured_tag:
         name: 'You might want to use one of these:'
       form_challenge:
@@ -83,6 +87,7 @@ en:
         acct: Handle of the new account
       account_warning_preset:
         text: Preset text
+        title: Title
       admin_account_action:
         include_statuses: Include reported toots in the e-mail
         send_email_notification: Notify the user per e-mail
@@ -163,6 +168,8 @@ en:
         username: Username
         username_or_email: Username or Email
         whole_word: Whole word
+      email_domain_block:
+        with_dns_records: Include MX records and IPs of the domain
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml
index ee7ec769a..3bd77a8e8 100644
--- a/config/locales/simple_form.eo.yml
+++ b/config/locales/simple_form.eo.yml
@@ -35,6 +35,7 @@ eo:
         setting_hide_network: Tiuj, kiujn vi sekvas, kaj tiuj, kiuj sekvas vin ne estos videblaj en via profilo
         setting_noindex: Influas vian publikan profilon kaj mesaĝajn paĝojn
         setting_show_application: La aplikaĵo, kiun vi uzas por afiŝi, estos montrita en la detala vido de viaj mesaĝoj
+        setting_use_blurhash: Transirojn estas bazita sur la koloroj de la kaŝitaj aŭdovidaĵoj sed ne montri iun ajn detalon
         username: Via uzantnomo estos unika ĉe %{domain}
         whole_word: Kiam la vorto aŭ frazo estas nur litera aŭ cifera, ĝi estos uzata nur se ĝi kongruas kun la tuta vorto
       featured_tag:
@@ -105,7 +106,8 @@ eo:
         setting_advanced_layout: Ebligi altnivelan retpaĝan interfacon
         setting_aggregate_reblogs: Grupigi diskonigojn en tempolinioj
         setting_auto_play_gif: Aŭtomate ekigi GIF-ojn
-        setting_boost_modal: Montri fenestron por konfirmi antaŭ ol diskonigi
+        setting_boost_modal: Montri fenestron por konfirmi antaŭ ol diskonigi mesaĝon
+        setting_crop_images: Stuci bildojn en negrandigitaj mesaĝoj al 16x9
         setting_default_language: Publikada lingvo
         setting_default_privacy: Mesaĝa videbleco
         setting_default_sensitive: Ĉiam marki aŭdovidaĵojn tiklaj
@@ -114,7 +116,7 @@ eo:
         setting_display_media_default: Dekomenca
         setting_display_media_hide_all: Kaŝi ĉiujn
         setting_display_media_show_all: Montri ĉiujn
-        setting_expand_spoilers: Ĉiam grandigi mesaĝojn markitajn per avertoj pri enhavo
+        setting_expand_spoilers: Ĉiam malfoldas mesaĝojn markitajn per averto pri enhavo
         setting_hide_network: Kaŝi viajn sekvantojn kaj sekvatojn
         setting_noindex: Ellistiĝi de retserĉila indeksado
         setting_reduce_motion: Malrapidigi animaciojn
diff --git a/config/locales/simple_form.es-AR.yml b/config/locales/simple_form.es-AR.yml
index 78bb3e275..ad35135e4 100644
--- a/config/locales/simple_form.es-AR.yml
+++ b/config/locales/simple_form.es-AR.yml
@@ -8,6 +8,7 @@ es-AR:
         acct: Especificá el nombredeusuario@dominio de la cuenta a la que querés mudarte
       account_warning_preset:
         text: Podés usar sintaxis de toots, como direcciones web, etiquetas y menciones
+        title: Opcional. No visible para el destinatario
       admin_account_action:
         include_statuses: El usuario verá qué toots causaron la acción de moderación o advertencia
         send_email_notification: El usuario recibirá una explicación de lo que sucedió con su cuenta
@@ -53,6 +54,9 @@ es-AR:
         whole_word: Cuando la palabra clave o frase es sólo alfanumérica, sólo será aplicado si coincide con toda la palabra
       domain_allow:
         domain: Este dominio podrá recolectar datos de este servidor, y los datos entrantes serán procesados y archivados
+      email_domain_block:
+        domain: Puede ser el nombre de dominio que aparece en la dirección de correo electrónico, el registro MX hacia el cual resuelve el dominio, o la dirección IP del servidor hacia el cual resuelve ese registro MX. Esto se comprobará en el momento del registro del usuario, y el registro será rechazado.
+        with_dns_records: Se hará un intento de resolver los registros DNS del dominio dado y los resultados serán también puestos en la lista de desaprobados
       featured_tag:
         name: 'Puede que quieras usar una de estas:'
       form_challenge:
@@ -78,6 +82,7 @@ es-AR:
         acct: Alias de la cuenta nueva
       account_warning_preset:
         text: Texto predefinido
+        title: Título
       admin_account_action:
         include_statuses: Incluir en el correo electrónico a los toots denunciados
         send_email_notification: Notificar al usuario por correo electrónico
@@ -150,6 +155,8 @@ es-AR:
         username: Nombre de usuario
         username_or_email: Nombre de usuario o correo electrónico
         whole_word: Palabra entera
+      email_domain_block:
+        with_dns_records: Incluir los registros MX y las direcciones IP del dominio
       featured_tag:
         name: Etiqueta
       interactions:
diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml
index 745de3332..b114b1424 100644
--- a/config/locales/simple_form.es.yml
+++ b/config/locales/simple_form.es.yml
@@ -8,6 +8,7 @@ es:
         acct: Especifique el nombre de usuario@dominio de la cuenta a la cual se desea migrar
       account_warning_preset:
         text: Puede usar sintaxis de toots, como URLs, hashtags y menciones
+        title: Opcional. No visible para el destinatario
       admin_account_action:
         include_statuses: El usuario verá qué toots han causado la acción de moderación o advertencia
         send_email_notification: El usuario recibirá una explicación de lo que sucedió con respecto a su cuenta
@@ -53,6 +54,9 @@ es:
         whole_word: Cuando la palabra clave o frase es solo alfanumérica, solo será aplicado si concuerda con toda la palabra
       domain_allow:
         domain: Este dominio podrá obtener datos de este servidor y los datos entrantes serán procesados y archivados
+      email_domain_block:
+        domain: Puede ser el nombre de dominio que aparece en la dirección de correo, el registro MX hacia el cual resuelve el dominio, o la IP del servidor hacia el cual resuelve ese registro MX. Esto se comprobará en el momento del alta del usuario y el alta se rechazará.
+        with_dns_records: Se hará un intento de resolver los registros DNS del dominio dado y los resultados serán también puestos en lista negra
       featured_tag:
         name: 'Puede que quieras usar uno de estos:'
       form_challenge:
@@ -78,6 +82,7 @@ es:
         acct: Maneja la cuenta nueva
       account_warning_preset:
         text: Texto predefinido
+        title: Título
       admin_account_action:
         include_statuses: Incluir en el correo electrónico a los toots denunciados
         send_email_notification: Notificar al usuario por correo electrónico
@@ -150,6 +155,8 @@ es:
         username: Nombre de usuario
         username_or_email: Usuario o Email
         whole_word: Toda la palabra
+      email_domain_block:
+        with_dns_records: Incluye los registros MX y las IP del dominio
       featured_tag:
         name: Etiqueta
       interactions:
diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml
index 9e45fb032..c0f36df77 100644
--- a/config/locales/simple_form.eu.yml
+++ b/config/locales/simple_form.eu.yml
@@ -8,8 +8,9 @@ eu:
         acct: Zehaztu migrazioaren xede den kontuaren erabiltzaile@domeinua
       account_warning_preset:
         text: Toot sintaxia erabili dezakezu, URLak, traolak eta aipamenak
+        title: Aukerakoa. Hartzaileak ez du ikusiko
       admin_account_action:
-        include_statuses: Erabiltzaileak moderazio ekintza edo abisu bat eragin duten toot-ak ikusi ahal izango ditu
+        include_statuses: Erabiltzaileak moderazio ekintza edo abisu bat eragin duten tootak ikusi ahal izango ditu
         send_email_notification: Erabiltzaileak bere kontuarekin gertatutakoaren azalpen bat jasoko du
         text_html: Aukerakoa. Toot sintaxia erabili dezakezu. <a href="%{path}">Abisu aurre-ezarpenak</a> gehitu ditzakezu denbora aurrezteko
         type_html: Erabaki zer egin <strong>%{acct}</strong> kontuarekin
@@ -19,7 +20,7 @@ eu:
         ends_at: Aukerakoa. Iragapena une honetan automatikoki desargitaratuko da
         scheduled_at: Laga hutsik iragarpena berehala argitaratzeko
         starts_at: Aukerakoa. Zure iragarpena denbora-tarte batera lotuta dagoenerako
-        text: Toot-etako sintaxia erabili dezakezu. Kontuan izan iragarpenak erabiltzailearen pantailan hartuko duen neurria
+        text: Tootetako sintaxia erabili dezakezu. Kontuan izan iragarpenak erabiltzailearen pantailan hartuko duen neurria
       defaults:
         autofollow: Gonbidapena erabiliz izena ematen dutenek automatikoki jarraituko dizute
         avatar: PNG, GIF edo JPG. Gehienez %{size}. %{dimensions}px neurrira eskalatuko da
@@ -33,19 +34,19 @@ eu:
         fields: 4 elementu bistaratu ditzakezu taula batean zure profilean
         header: PNG, GIF edo JPG. Gehienez %{size}. %{dimensions}px eskalara txikituko da
         inbox_url: Kopiatu erabili nahi duzun errelearen hasiera orriaren URLa
-        irreversible: Iragazitako Toot-ak betirako galduko dira, geroago iragazkia kentzen baduzu ere
+        irreversible: Iragazitako tootak betirako galduko dira, geroago iragazkia kentzen baduzu ere
         locale: Erabiltzaile-interfazea, e-mail mezuen eta jakinarazpenen hizkuntza
         locked: Jarraitzaileak eskuz onartu behar dituzu
         password: Erabili 8 karaktere gutxienez
         phrase: Bat egingo du Maiuskula/minuskula kontuan hartu gabe eta edukiaren abisua kontuan hartu gabe
         scopes: Zeintzuk API atzitu ditzakeen aplikazioak. Goi mailako arloa aukeratzen baduzu, ez dituzu azpikoak aukeratu behar.
-        setting_aggregate_reblogs: Ez erakutsi bultzada berriak berriki bultzada jaso duten toot-entzat (berriki jasotako bultzadei eragiten die bakarrik)
+        setting_aggregate_reblogs: Ez erakutsi bultzada berriak berriki bultzada jaso duten tootentzat (berriki jasotako bultzadei eragiten die bakarrik)
         setting_default_sensitive: Multimedia hunkigarria lehenetsita ezkutatzen da, eta sakatuz ikusi daiteke
         setting_display_media_default: Ezkutatu hunkigarri gisa markatutako multimedia
         setting_display_media_hide_all: Ezkutatu multimedia guztia beti
         setting_display_media_show_all: Erakutsi beti hunkigarri gisa markatutako multimedia
         setting_hide_network: Nor jarraitzen duzun eta nork jarraitzen zaituen ez da bistaratuko zure profilean
-        setting_noindex: Zure profil publiko eta Toot-en orrietan eragina du
+        setting_noindex: Zure profil publiko eta tooten orrietan eragina du
         setting_show_application: Tootak bidaltzeko erabiltzen duzun aplikazioa zure tooten ikuspegi xehetsuan bistaratuko da
         setting_use_blurhash: Gradienteak ezkutatutakoaren koloreetan oinarritzen dira, baina xehetasunak ezkutatzen dituzte
         setting_use_pending_items: Ezkutatu denbora-lerroko eguneraketak klik baten atzean jarioa automatikoki korritu ordez
@@ -53,6 +54,9 @@ eu:
         whole_word: Hitz eta esaldi gakoa alfanumerikoa denean, hitz osoarekin bat datorrenean besterik ez da aplikatuko
       domain_allow:
         domain: Domeinu honek zerbitzari honetatik datuak hartu ahal izango ditu eta bertatik jasotako informazioa prozesatu eta gordeko da
+      email_domain_block:
+        domain: Hau e-mail helbidean agertzen den domeinua izan daiteke, honen MX erregistroa, edo MX erregistroaren IP helbidea. Hauek erabiltzaileak izena ematean egiaztatuko dira eta atzera botako da.
+        with_dns_records: Emandako domeinuaren DNS erregistroak ebazteko saiakera bat egingo da eta emaitzak ere zerrenda beltzean sartuko dira
       featured_tag:
         name: 'Hauetakoren bat erabili zenezake:'
       form_challenge:
@@ -66,7 +70,7 @@ eu:
       tag:
         name: Letrak maiuskula/minuskulara aldatu ditzakezu besterik ez, adibidez irakurterrazago egiteko
       user:
-        chosen_languages: Ezer markatzekotan, hautatutako hizkuntzetan dauden toot-ak besterik ez dira erakutsiko
+        chosen_languages: Ezer markatzekotan, hautatutako hizkuntzetan dauden tootak besterik ez dira erakutsiko
     labels:
       account:
         fields:
@@ -78,8 +82,9 @@ eu:
         acct: Kontu berriaren helbidea
       account_warning_preset:
         text: Aurrez ezarritako testua
+        title: Izenburua
       admin_account_action:
-        include_statuses: Txertatu salatutako toot-ak e-mailean
+        include_statuses: Txertatu salatutako tootak e-mailean
         send_email_notification: Jakinarazi erabiltzaileari e-mail bidez
         text: Abisu pertsonalizatua
         type: Ekintza
@@ -125,7 +130,7 @@ eu:
         setting_aggregate_reblogs: Taldekatu bultzadak denbora-lerroetan
         setting_auto_play_gif: Erreproduzitu GIF animatuak automatikoki
         setting_boost_modal: Erakutsi baieztapen elkarrizketa-koadroa bultzada eman aurretik
-        setting_crop_images: Moztu irudiak hedatu gabeko toot-etan 16x9 proportzioan
+        setting_crop_images: Moztu irudiak hedatu gabeko tootetan 16x9 proportzioan
         setting_default_language: Argitalpenen hizkuntza
         setting_default_privacy: Mezuen pribatutasuna
         setting_default_sensitive: Beti markatu edukiak hunkigarri gisa
@@ -150,6 +155,8 @@ eu:
         username: Erabiltzaile-izena
         username_or_email: Erabiltzaile-izena edo e-mail helbidea
         whole_word: Hitz osoa
+      email_domain_block:
+        with_dns_records: Sartu ere domeinuaren MX erregistroak eta IPak
       featured_tag:
         name: Traola
       interactions:
@@ -174,7 +181,7 @@ eu:
         listable: Baimendu traola hau bilaketetan agertzea eta profilen direktorioan
         name: Traola
         trendable: Baimendu traola hau joeretan agertzea
-        usable: Baimendu toot-ek traola hau erabiltzea
+        usable: Baimendu tootek traola hau erabiltzea
     'no': Ez
     recommended: Aholkatua
     required:
diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml
index 0001efaf5..dea53ddbb 100644
--- a/config/locales/simple_form.fa.yml
+++ b/config/locales/simple_form.fa.yml
@@ -8,6 +8,7 @@ fa:
         acct: نشانی username@domain را برای حسابی که می‌خواهید به آن منتقل شوید بنویسید
       account_warning_preset:
         text: می‌توانید مانند بوق‌های معمولی کاربران دیگر را نام ببرید یا پیوند و برچسب بگذارید
+        title: اختیاری. برای گیرنده قابل مشاهده نیست
       admin_account_action:
         include_statuses: این کاربر خواهد دید که کدام بوق او موجب اقدام مدیریتی یا هشدار شده است
         send_email_notification: توضیحی که کاربر می‌بینید که برای حسابش چه رخ داده است
@@ -24,7 +25,7 @@ fa:
         autofollow: کسانی که از راه دعوت‌نامه عضو می‌شوند به طور خودکار پیگیر شما خواهند شد
         avatar: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد
         bot: این حساب بیشتر به طور خودکار فعالیت می‌کند و نظارت پیوسته‌ای روی آن وجود ندارد
-        context: یک یا چند زمینه که فیلتر باید در آن‌ها اعمال شود
+        context: یک یا چند زمینه که پالایه باید در آن‌ها اعمال شود
         current_password: به دلایل امنیتی لطفاً رمز این حساب را وارد کنید
         current_username: برای تأیید، لطفاً نام کاربری حساب فعلی را وارد کنید
         digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد
@@ -33,7 +34,7 @@ fa:
         fields: شما می‌توانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید
         header: یکی از قالب‌های PNG یا  GIF یا JPG. بیشترین اندازه %{size}. تصویر به اندازهٔ %{dimensions} پیکسل تبدیل خواهد شد
         inbox_url: نشانی صفحهٔ اصلی رله‌ای را که می‌خواهید به کار ببرید کپی کنید
-        irreversible: بوق‌های فیلترشده به طور برگشت‌ناپذیری ناپدید می‌شوند، حتی اگر فیلتر را بعداً بردارید
+        irreversible: بوق‌های پالوده به طور برگشت‌ناپذیری ناپدید می‌شوند، حتا اگر بعدها پالایه برداشته شود
         locale: زبان محیط کاربری، ایمیل‌ها، و اعلان‌ها
         locked: باید پیگیران تازه را خودتان تأیید کنید
         password: دست‌کم باید ۸ نویسه داشته باشد
@@ -53,6 +54,9 @@ fa:
         whole_word: اگر کلیدواژه فقط دارای حروف و اعداد باشد، تنها وقتی پیدا می‌شود که با کل یک واژه در متن منطبق باشد، نه با بخشی از یک واژه
       domain_allow:
         domain: این دامین خواهد توانست داده‌ها از این سرور را دریافت کند و داده‌های از این دامین در این‌جا پردازش و ذخیره خواهند شد
+      email_domain_block:
+        domain: می‌تواند نام دامنه که در نشانی رایانامه ظاهر می‌شود، رکورد MX که دامنه به آن resolve می‌شود یا IP کارسازی که رکورد MX به آن resolve می‌شود باشد. این موارد هنگام ثبت‌نام کاربر بررسی شده و ثبت‌نام رد می‌شود.
+        with_dns_records: تلاشی برای resolve کردن رکوردهای ساناد دامنهٔ داده‌شده انجام شده و نتیجه نیز مسدود خواهد شد
       featured_tag:
         name: 'شاید بخواهید چنین چیزهایی را به کار ببرید:'
       form_challenge:
@@ -78,6 +82,7 @@ fa:
         acct: نشانی حساب تازه
       account_warning_preset:
         text: متن از پیش آماده‌شده
+        title: عنوان
       admin_account_action:
         include_statuses: بوق‌های گزارش‌شده را در ایمیل بگنجان
         send_email_notification: اطلاع‌رسانی به کاربر از راه ایمیل
@@ -102,7 +107,7 @@ fa:
         chosen_languages: جدا کردن زبان‌ها
         confirm_new_password: تأیید رمز تازه
         confirm_password: تأیید رمز
-        context: زمینه‌های فیلترکردن
+        context: زمینه‌های پالایش
         current_password: رمز فعلی
         data: داده‌ها
         discoverable: این حساب را در فهرست گزیدهٔ کاربران نشان بده
@@ -150,6 +155,8 @@ fa:
         username: نام کاربری (لاتین)
         username_or_email: نام کاربری یا ایمیل
         whole_word: تطابق واژهٔ کامل
+      email_domain_block:
+        with_dns_records: شامل رکوردهای MX و‌IPهای دامنه
       featured_tag:
         name: برچسب
       interactions:
diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml
index 0e5332f1e..77e91329a 100644
--- a/config/locales/simple_form.fr.yml
+++ b/config/locales/simple_form.fr.yml
@@ -8,6 +8,7 @@ fr:
         acct: Spécifiez le nom d’utilisateur@domaine du compte vers lequel vous souhaitez déménager
       account_warning_preset:
         text: Vous pouvez utiliser la syntaxe des pouets, comme les URLs, les hashtags et les mentions
+        title: Facultatif. Invisible pour le destinataire
       admin_account_action:
         include_statuses: L’utilisateur·rice verra quels sont les pouets qui ont provoqué l’action de modération ou l’avertissement
         send_email_notification: L’utilisateur recevra une explication de ce qu’il s’est passé avec son compte
@@ -35,24 +36,27 @@ fr:
         inbox_url: Copiez l’URL depuis la page d’accueil du relais que vous souhaitez utiliser
         irreversible: Les pouets filtrés disparaîtront irrémédiablement, même si le filtre est supprimé plus tard
         locale: La langue de l’interface, des courriels et des notifications
-        locked: Vous devrez approuver chaque abonné⋅e et vos statuts ne s’afficheront qu’à vos abonné⋅es
+        locked: Vous devrez approuver chaque abonné·e et vos statuts ne s’afficheront qu’à vos abonné·e·s
         password: Utilisez au moins 8 caractères
-        phrase: Sera trouvé sans que la case ou l’avertissement de contenu du pouet soit pris en compte
+        phrase: Sera filtré sans que la casse ou l’avertissement sur le contenu du pouet soit pris en compte
         scopes: À quelles APIs l’application sera autorisée à accéder. Si vous sélectionnez une permission générale, vous n’avez pas besoin de sélectionner les permissions plus précises.
         setting_aggregate_reblogs: Ne pas afficher de nouveaux partages pour les pouets qui ont été récemment partagés (n’affecte que les partages nouvellement reçus)
         setting_default_sensitive: Les médias sensibles sont cachés par défaut et peuvent être révélés d’un simple clic
         setting_display_media_default: Masquer les médias marqués comme sensibles
-        setting_display_media_hide_all: Toujours masquer tous les médias
+        setting_display_media_hide_all: Toujours cacher les médias
         setting_display_media_show_all: Toujours afficher les médias marqués comme sensibles
         setting_hide_network: Ceux que vous suivez et ceux qui vous suivent ne seront pas affichés sur votre profil
         setting_noindex: Affecte votre profil public ainsi que vos statuts
         setting_show_application: Le nom de l’application que vous utilisez afin d’envoyer des pouets sera affiché dans la vue détaillée de ceux-ci
-        setting_use_blurhash: Les dégradés sont basés sur les couleurs des visuels cachés mais ne divulgent pas les détails
-        setting_use_pending_items: Masquer les mises à jour chronologiques derrière un clic au lieu de les montrer automatiquement en faisant défiler le flux d'actualités
+        setting_use_blurhash: Les dégradés sont basés sur les couleurs des images cachées mais n’en montrent pas les détails
+        setting_use_pending_items: Cacher les mises à jour des fils d’actualités derrière un clic, au lieu de les afficher automatiquement
         username: Votre nom d’utilisateur sera unique sur %{domain}
-        whole_word: Lorsque le mot-clef ou la phrase-clef est uniquement alphanumérique, ça sera uniquement appliqué s’il correspond au mot entier
+        whole_word: Si le mot-clé ou la phrase est alphanumérique, alors le filtre ne sera appliqué que s’il correspond au mot entier
       domain_allow:
         domain: Ce domaine pourra récupérer des données de ce serveur et les données entrantes seront traitées et stockées
+      email_domain_block:
+        domain: Ceci peut être le nom de domaine qui apparaît dans le courriel, l’enregistrement MX que le domaine résout, ou l’IP du serveur auquel l’enregistrement MX résout. Celles-ci seront vérifiées lors de l’inscription de l’utilisateur et l’inscription sera rejetée.
+        with_dns_records: Une tentative de résolution des enregistrements DNS du domaine donné sera effectuée et les résultats seront également mis sur liste noire
       featured_tag:
         name: 'Vous pourriez vouloir utiliser l’un d’entre eux :'
       form_challenge:
@@ -78,6 +82,7 @@ fr:
         acct: L’identifiant du nouveau compte
       account_warning_preset:
         text: Texte de présélection
+        title: Titre
       admin_account_action:
         include_statuses: Inclure les pouets signalés dans le courriel
         send_email_notification: Notifier l’utilisateur par courriel
@@ -87,7 +92,7 @@ fr:
           disable: Désactiver
           none: Ne rien faire
           silence: Masquer
-          suspend: Suspendre et effacer les données du compte de manière irréversible
+          suspend: Suspendre et supprimer les données du compte de manière irréversible
         warning_preset_id: Utiliser un modèle d’avertissement
       announcement:
         all_day: Événement de toute la journée
@@ -112,7 +117,7 @@ fr:
         fields: Métadonnées du profil
         header: Image d’en-tête
         inbox_url: URL de la boîte de relais
-        irreversible: Supprimer plutôt que de cacher
+        irreversible: Supprimer plutôt que masquer
         locale: Langue de l’interface
         locked: Verrouiller le compte
         max_uses: Nombre maximum d’utilisations
@@ -122,10 +127,10 @@ fr:
         password: Mot de passe
         phrase: Mot-clé ou phrase
         setting_advanced_layout: Activer l’interface Web avancée
-        setting_aggregate_reblogs: Partages groupés dans les fils d’actualités
+        setting_aggregate_reblogs: Grouper les partages dans les fils d’actualités
         setting_auto_play_gif: Lire automatiquement les GIFs animés
-        setting_boost_modal: Afficher une fenêtre de confirmation avant de partager
-        setting_crop_images: Recadrer les images dans les pouets non-expansés à 16x9
+        setting_boost_modal: Afficher une fenêtre de confirmation avant de partager un pouet
+        setting_crop_images: Recadrer les images des pouets non-dépliés en 16x9
         setting_default_language: Langue de publication
         setting_default_privacy: Confidentialité des statuts
         setting_default_sensitive: Toujours marquer les médias comme sensibles
@@ -134,7 +139,7 @@ fr:
         setting_display_media_default: Défaut
         setting_display_media_hide_all: Masquer tout
         setting_display_media_show_all: Montrer tout
-        setting_expand_spoilers: Toujours développer les pouets marqués d’un avertissement de contenu
+        setting_expand_spoilers: Toujours déplier les pouets marqués d’un avertissement sur le contenu
         setting_hide_network: Cacher votre réseau
         setting_noindex: Demander aux moteurs de recherche de ne pas indexer vos informations personnelles
         setting_reduce_motion: Réduire la vitesse des animations
@@ -143,13 +148,15 @@ fr:
         setting_theme: Thème du site
         setting_trends: Afficher les tendances du jour
         setting_unfollow_modal: Afficher une fenêtre de confirmation avant de vous désabonner d’un compte
-        setting_use_blurhash: Afficher les dégradés colorés pour les médias cachés
+        setting_use_blurhash: Afficher des dégradés colorés pour les médias cachés
         setting_use_pending_items: Mode lent
         severity: Sévérité
         type: Type d’import
         username: Identifiant
-        username_or_email: Nom d’utilisateur·ice ou courriel
+        username_or_email: Nom d’utilisateur·rice ou courriel
         whole_word: Mot entier
+      email_domain_block:
+        with_dns_records: Inclure les enregistrements MX et IP du domaine
       featured_tag:
         name: Hashtag
       interactions:
@@ -166,14 +173,14 @@ fr:
         follow: Envoyer un courriel lorsque quelqu’un me suit
         follow_request: Envoyer un courriel lorsque quelqu’un demande à me suivre
         mention: Envoyer un courriel lorsque quelqu’un me mentionne
-        pending_account: Envoyer un courriel lorsqu’un nouveau compte est en attente d’approbation
-        reblog: Quelqu’un a partagé votre statut
+        pending_account: Nouveau compte en attente d’approbation
+        reblog: Quelqu’un a partagé votre pouet
         report: Envoyer un courriel lorsqu’un nouveau rapport est soumis
-        trending_tag: Envoyer un e-mail quand un hashtag non contrôlé est en tendance actuelle
+        trending_tag: Un hashtag non approuvé est dans les tendances
       tag:
         listable: Autoriser ce hashtag à apparaître dans les recherches et dans l’annuaire des profils
         name: Hashtag
-        trendable: Autoriser ce hashtag à apparaître sous les tendances du jour
+        trendable: Autoriser ce hashtag à apparaitre dans les tendances
         usable: Autoriser les pouets à utiliser ce hashtag
     'no': Non
     recommended: Recommandé
diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml
index d6768a17d..86d4bea5f 100644
--- a/config/locales/simple_form.gl.yml
+++ b/config/locales/simple_form.gl.yml
@@ -8,6 +8,7 @@ gl:
         acct: Indica o usuaria@servidor da conta a cal queres migrar
       account_warning_preset:
         text: Pódeslle dar formato ao toot, como URLs, etiquetas e mencións
+        title: Optativo. Non visible para a correspondente
       admin_account_action:
         include_statuses: A usuaria verá que toots causaron a acción da moderación ou aviso
         send_email_notification: A usuaria recibirá unha explicación sobre o que lle aconteceu a súa conta
@@ -53,6 +54,9 @@ gl:
         whole_word: Se a chave ou frase de paso é só alfanumérica, só se aplicará se concorda a palabra completa
       domain_allow:
         domain: Este dominio estará en disposición de obter datos desde este servidor e datos de entrada a el poderán ser procesados e gardados
+      email_domain_block:
+        domain: Esto pode ser o nome de dominio que aparece no enderezo do correo, o rexistro MX que resolve o dominio, ou o IP do servidor que resolve o rexistro MX. Estos confrontaranse contra o rexistro da usuaria e o rexistro será rexeitado.
+        with_dns_records: Vaise facer un intento de resolver os rexistros DNS propocionados e os resultados tamén irán a lista negra
       featured_tag:
         name: 'Podería utilizar algunha de estas:'
       form_challenge:
@@ -78,6 +82,7 @@ gl:
         acct: Xestiona a nova conta
       account_warning_preset:
         text: Texto preestablecido
+        title: Título
       admin_account_action:
         include_statuses: Incluír toots reportados no correo
         send_email_notification: Notificar a usuaria por correo-e
@@ -150,6 +155,8 @@ gl:
         username: Nome de usuaria
         username_or_email: Nome de usuaria ou Correo-e
         whole_word: Palabra completa
+      email_domain_block:
+        with_dns_records: Incluír rexistros MX e IPs do dominio
       featured_tag:
         name: Etiqueta
       interactions:
diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml
index cee6bdb45..2063446f1 100644
--- a/config/locales/simple_form.hu.yml
+++ b/config/locales/simple_form.hu.yml
@@ -8,6 +8,7 @@ hu:
         acct: Add meg a fióknév@domain fiókot, melybe költözni szeretnél
       account_warning_preset:
         text: Használhatod a tülkökben szokásos szintaxist, URL-eket, hashtageket, megemlítéseket
+        title: Opcionális. Címzett számára nem látható
       admin_account_action:
         include_statuses: A felhasználó látni fogja, melyik tülk okozta a moderációt vagy figyelmeztetést
         send_email_notification: A felhasználó magyarázatot kap arra, mi történt a fiókjával
@@ -53,6 +54,9 @@ hu:
         whole_word: Ha a kulcsszó alfanumerikus, csak akkor minősül majd találatnak, ha teljes szóra illeszkedik
       domain_allow:
         domain: Ez a domain adatot kérhet le a szerverünkről és az ettől érkező adatokat feldolgozzuk és mentjük
+      email_domain_block:
+        domain: Lehet domain név, mely az email címben szerepel, MX rekord, amire a domain hivatkozik vagy a szerver IP címe, amire az MX rekord hivatkozik. Ezeket regisztrációkor ellenőrizzük és visszautasítjuk a regisztrációt, ha szükséges.
+        with_dns_records: Megpróbáljuk a megadott domain DNS rekordjait lekérni, és az eredményeket hozzáadjuk a tiltólistához
       featured_tag:
         name: 'Ezeket esetleg használhatod:'
       form_challenge:
@@ -78,6 +82,7 @@ hu:
         acct: Új fiók kezelése
       account_warning_preset:
         text: Figyelmeztető szöveg
+        title: Cím
       admin_account_action:
         include_statuses: Helyezd az e-mailbe a jelentett tülköket
         send_email_notification: Figyelmeztessük a felhasználót e-mailben
@@ -150,6 +155,8 @@ hu:
         username: Felhasználónév
         username_or_email: Felhasználónév vagy E-mail
         whole_word: Teljes szó
+      email_domain_block:
+        with_dns_records: Domain MX rekordjainak és IP címeinek hozzávétele
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.id.yml b/config/locales/simple_form.id.yml
index ada83fc86..1717d0722 100644
--- a/config/locales/simple_form.id.yml
+++ b/config/locales/simple_form.id.yml
@@ -8,6 +8,7 @@ id:
         acct: Tentukan namapengguna@domain akun yang ingin Anda pindah
       account_warning_preset:
         text: Anda dapat memakai sintaks toot, seperti URL, tagar, dan sebutan
+        title: Opsional. Tidak terlihat penerima
       admin_account_action:
         include_statuses: Pengguna dapat melihat toot mana yang menyebabkan aksi atau peringatan moderasi
         send_email_notification: Pengguna akan menerima penjelasan tentang apa yang terjadi pada akun mereka
@@ -53,6 +54,9 @@ id:
         whole_word: Ketika kata kunci/frasa hanya alfanumerik, maka itu hanya akan diterapkan jika cocok dengan semua kata
       domain_allow:
         domain: Domain ini dapat mengambil data dari server ini dan data yang diterima akan diproses dan disimpan
+      email_domain_block:
+        domain: Ini bisa nama domain yang muncul di alamat surel, data MX yang sedang diselesaikan oleh domain, atau IP server yang dipecahkan oleh data MX. Mereka akan dicek saat pendaftaran pengguna dan pendaftaran akan ditolak.
+        with_dns_records: Usaha untuk menyelesaikan data DNS domain yang diberikan akan dilakukan dan hasilnya akan masuk daftar hitam
       featured_tag:
         name: 'Anda mungkin ingin pakai salah satu dari ini:'
       form_challenge:
@@ -78,6 +82,7 @@ id:
         acct: Menangani akun baru
       account_warning_preset:
         text: Teks preset
+        title: Judul
       admin_account_action:
         include_statuses: Sertakan toot terlapor pada surel
         send_email_notification: Beritahu pengguna per surel
@@ -150,6 +155,8 @@ id:
         username: Nama pengguna
         username_or_email: Nama pengguna atau Surel
         whole_word: Seluruh kata
+      email_domain_block:
+        with_dns_records: Termasuk data MX dan IP domain
       featured_tag:
         name: Tagar
       interactions:
diff --git a/config/locales/simple_form.is.yml b/config/locales/simple_form.is.yml
index 65041f19c..3275b15f7 100644
--- a/config/locales/simple_form.is.yml
+++ b/config/locales/simple_form.is.yml
@@ -8,6 +8,7 @@ is:
         acct: Tilgreindu notandanafn@lén á notandaaðgangnum sem þú vilt flytjast til
       account_warning_preset:
         text: Þú getur notað sömu skilgreiningar og fyrir tíst, svo sem URL-slóðir, myllumerki og tilvísanir
+        title: Valkvætt. Ekki sýnilegt viðtakandanum
       admin_account_action:
         include_statuses: Notandinn mun sjá hvaða tíst hafa valdið viðbrögðum umsjónarmanns eða aðvörun kerfisins
         send_email_notification: Notandinn mun fá útskýringar á því hvað gerðist með notandaaðganginn hans
@@ -53,6 +54,9 @@ is:
         whole_word: Þegar stikkorð eða frasi er einungis tölur og bókstafir, verður það aðeins notað ef það samsvarar heilu orði
       domain_allow:
         domain: Þetta lén mun geta sótt gögn af þessum vefþjóni og tekið verður á móti innsendum gögnum frá léninu til vinnslu og geymslu
+      email_domain_block:
+        domain: Þetta getur verið heiti lénsins sem birtist í tölvupóstfanginu, MX-færslan sem það lén beinist að, eða IP-vistfang netþjónsins sem sú MX-færsla beinist að. Þetta verður athugað um leið og notandi skráir sig, og verður þá skráningunni hafnað.
+        with_dns_records: Tilraun verður gerð til að leysa DNS-færslur uppgefins léns og munu niðurstöðurnar einnig verða útilokaðar
       featured_tag:
         name: 'Þú gætir viljað nota eitt af þessum:'
       form_challenge:
@@ -78,6 +82,7 @@ is:
         acct: Auðkenni nýja aðgangsins
       account_warning_preset:
         text: Forstilltur texti
+        title: Titill
       admin_account_action:
         include_statuses: Innifela kærð tíst í tölvupóstinum
         send_email_notification: Láta notanda vita með tölvupósti
@@ -150,6 +155,8 @@ is:
         username: Notandanafn
         username_or_email: Notandanafn eða tölvupóstfang
         whole_word: Heil orð
+      email_domain_block:
+        with_dns_records: Hafa með MX-færslur og IP-vistföng lénsins
       featured_tag:
         name: Myllumerki
       interactions:
diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml
index 35c4f80cf..61128bb38 100644
--- a/config/locales/simple_form.it.yml
+++ b/config/locales/simple_form.it.yml
@@ -8,6 +8,7 @@ it:
         acct: Indica il nomeutente@dominio dell'account al quale vuoi trasferirti
       account_warning_preset:
         text: Puoi usare la sintassi dei toot, come URL, hashtag e menzioni
+        title: Opzionale. Non visibile al destinatario
       admin_account_action:
         include_statuses: L'utente vedrà quali toot hanno causato l'azione di moderazione o l'avviso
         send_email_notification: L'utente riceverà una spiegazione di ciò che è successo con suo account
@@ -53,6 +54,9 @@ it:
         whole_word: Quando la parola chiave o la frase è solo alfanumerica, si applica solo se corrisponde alla parola intera
       domain_allow:
         domain: Questo dominio potrà recuperare i dati da questo server e i dati in arrivo da esso verranno elaborati e memorizzati
+      email_domain_block:
+        domain: Questo può essere il nome del dominio che fa parte dell'indirizzo email, il record MX a cui il dominio si risolve o l'indirizzo IP del server a cui il record MX si risolve. Saranno verificati alla registrazione da parte dell'utente e la sua iscrizione sarà respinta.
+        with_dns_records: Sarà effettuato un tentativo di risolvere i record DNS del dominio in questione e i risultati saranno inseriti anche nella blacklist
       featured_tag:
         name: 'Eccone alcuni che potresti usare:'
       form_challenge:
@@ -78,6 +82,7 @@ it:
         acct: Handle del nuovo account
       account_warning_preset:
         text: Testo preimpostato
+        title: Titolo
       admin_account_action:
         include_statuses: Includi i toots segnalati nell'email
         send_email_notification: Informa l'utente via email
@@ -150,12 +155,16 @@ it:
         username: Nome utente
         username_or_email: Nome utente o email
         whole_word: Parola intera
+      email_domain_block:
+        with_dns_records: Includi record MX e indirizzi IP del dominio
       featured_tag:
         name: Etichetta
       interactions:
         must_be_follower: Blocca notifiche da chi non ti segue
         must_be_following: Blocca notifiche dalle persone che non segui
         must_be_following_dm: Blocca i messaggi diretti dalle persone che non segui
+      invite:
+        comment: Commento
       invite_request:
         text: Perché vuoi iscriverti?
       notification_emails:
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 9938e08b3..d9652d13c 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -8,6 +8,7 @@ ja:
         acct: 引っ越し先のユーザー名@ドメインを指定してください
       account_warning_preset:
         text: URL、ハッシュタグ、メンションなど、投稿に用いる構文が使用できます
+        title: オプションです。受信者には表示されません。
       admin_account_action:
         include_statuses: ユーザーは取られた制限や警告の原因となったトゥートを確認できるようになります
         send_email_notification: ユーザーは自分のアカウントに何が起こったのか説明を受け取ります
@@ -42,8 +43,8 @@ ja:
         setting_aggregate_reblogs: 最近ブーストされたトゥートが新たにブーストされても表示しません (設定後受信したものにのみ影響)
         setting_default_sensitive: 閲覧注意状態のメディアはデフォルトでは内容が伏せられ、クリックして初めて閲覧できるようになります
         setting_display_media_default: 閲覧注意としてマークされたメディアは隠す
-        setting_display_media_hide_all: 全てのメディアを常に隠す
-        setting_display_media_show_all: 閲覧注意としてマークされたメディアも常に表示する
+        setting_display_media_hide_all: メディアを常に隠す
+        setting_display_media_show_all: メディアを常に表示する
         setting_hide_network: フォローとフォロワーの情報がプロフィールページで見られないようにします
         setting_noindex: 公開プロフィールおよび各投稿ページに影響します
         setting_show_application: トゥートするのに使用したアプリがトゥートの詳細ビューに表示されるようになります
@@ -53,6 +54,9 @@ ja:
         whole_word: キーワードまたはフレーズが英数字のみの場合、単語全体と一致する場合のみ適用されるようになります
       domain_allow:
         domain: 登録するとこのサーバーからデータを受信したり、このドメインから受信するデータを処理して保存できるようになります
+      email_domain_block:
+        domain: メールアドレスのドメイン名および、名前解決したMXレコード、IPアドレスを指定できます。ユーザー登録時にこれらをチェックし、該当する場合はユーザー登録を拒否します。
+        with_dns_records: 指定したドメインの名前解決ができない場合、ブラックリストに登録されます
       featured_tag:
         name: 'これらを使うといいかもしれません:'
       form_challenge:
@@ -78,13 +82,14 @@ ja:
         acct: 引っ越し先のユーザー ID
       account_warning_preset:
         text: プリセット警告文
+        title: タイトル
       admin_account_action:
         include_statuses: 通報されたトゥートをメールに含める
         send_email_notification: メールでユーザーに通知
         text: カスタム警告文
         type: アクション
         types:
-          disable: 無効化
+          disable: ログインを無効化
           none: 何もしない
           silence: サイレンス
           suspend: 停止しアカウントのデータを恒久的に削除する
@@ -151,6 +156,8 @@ ja:
         username: ユーザー名
         username_or_email: ユーザー名またはメールアドレス
         whole_word: 単語全体にマッチ
+      email_domain_block:
+        with_dns_records: ドメインのMXレコードとIPアドレスを含む
       featured_tag:
         name: ハッシュタグ
       interactions:
diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml
index db4369e92..c9936c49a 100644
--- a/config/locales/simple_form.kab.yml
+++ b/config/locales/simple_form.kab.yml
@@ -3,7 +3,7 @@ kab:
   simple_form:
     hints:
       account_alias:
-        acct: Specify the username@domain of the account you want to move from
+        acct: Sekcem isem n umseqdac@domain n umiḍan s wansa itebγiḍ ad gujjeḍ
       account_migration:
         acct: Sekcem isem n umseqdac@taγult n umiḍan anida itebγiḍ ad gujjeḍ
       admin_account_action:
@@ -15,7 +15,11 @@ kab:
         email: Ad n-teṭṭfeḍ imayl i usentem
         irreversible: Tijewwaqin i tessazedgeḍ ad ttwakksent i lebda, ula ma tekkseḍ imsizdeg-nni ar zdat
         locale: Tutlayt n ugrudem, imaylen d tilγa
+        locked: Isra asentem s wufus n ineḍfaren
         password: Seqdec ma drus 8 n yisekkilen
+        setting_display_media_default: Ffer teywalt yettwacreḍ d tanafrit
+        setting_display_media_hide_all: Ffer yal tikkelt akk taywalt
+        setting_display_media_show_all: Ffer yal tikkelt teywalt yettwacreḍ d tanafrit
         setting_hide_network: Wid i teṭṭafaṛeḍ d wid i k-yeṭṭafaṛen ur d-ttwaseknen ara deg umaγnu-inek
         username: Isem-ik n umseqdac ad yili d ayiwen, ulac am netta deg %{domain}
       featured_tag:
@@ -25,12 +29,19 @@ kab:
     labels:
       account:
         fields:
+          name: Tabzimt
           value: Agbur
       account_migration:
         acct: Tansa n umiḍan amaynut
       admin_account_action:
+        send_email_notification: Sileɣ aseqdac s imaylen
+        type: Tigawt
         types:
+          disable: Sens anekcum
+          none: Ur teg kra
           silence: Sgugem
+      announcement:
+        ends_at: Tagara n tedyant
       defaults:
         bot: Wagi d amiḍan aṛubut
         chosen_languages: Sizdeg tutlayin
@@ -43,7 +54,10 @@ kab:
         email: Tansa imayl
         header: Ixef
         locale: Tutlayt n ugrudem
+        locked: Rgel amiḍan
+        max_uses: Amḍan afellay n iseqdacen
         new_password: Awal uffir amaynut
+        otp_attempt: Tangalt n snat n tarayin
         password: Awal uffir
         setting_default_language: Tutlayt n tira
         setting_default_privacy: Tabaḍnit n tira
@@ -52,6 +66,7 @@ kab:
         setting_display_media_show_all: Sken kullec
         setting_hide_network: Ffer azetta-k·m
         setting_theme: Asental n wesmel
+        setting_use_pending_items: Askar aleγwayan
         username: Isem n useqdac
         username_or_email: Isem n useqdac neγ imal
         whole_word: Awal akk
@@ -61,7 +76,10 @@ kab:
         comment: Awennit
       invite_request:
         text: Acimi tebγiḍ ad ternuḍ iman-ik?
+      tag:
+        name: Ahacṭag
     'no': Ala
+    recommended: Yettuwelleh
     required:
       mark: "*"
       text: ilaq
diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml
index 028aa59d9..0bf46b0ff 100644
--- a/config/locales/simple_form.ko.yml
+++ b/config/locales/simple_form.ko.yml
@@ -8,6 +8,7 @@ ko:
         acct: 이동하고자 하는 목적지 계정의 사용자이름@도메인을 설정하세요
       account_warning_preset:
         text: URL, 해시태그, 멘션과 같은 툿 문법을 사용할 수 있습니다
+        title: 선택사항. 수신자에게는 보이지 않습니다
       admin_account_action:
         include_statuses: 사용자는 어떤 툿에 대해 경고나 조치가 취해졌는지 볼 수 있게 됩니다
         send_email_notification: 유저는 어떤 일이 일어났는 지에 대한 설명을 받게 됩니다
@@ -53,6 +54,9 @@ ko:
         whole_word: 키워드가 영문과 숫자로만 이루어 진 경우, 단어 전체에 매칭 되었을 때에만 작동하게 합니다
       domain_allow:
         domain: 이 도메인은 이 서버에서 데이터를 가져갈 수 있고 이 도메인에서 보내진 데이터는 처리되고 저장 됩니다
+      email_domain_block:
+        domain: 이것은 이메일 주소에 보이는 도메인 네임이거나, 도메인이 향하는 MX 레코드이거나, 또는 MX 레코드가 향하는 IP 주소일 수 있습니다. 이것들은 사용자가 가입 할 때 확인 되며 가입은 반려될 것입니다.
+        with_dns_records: 입력한 도메인의 DNS를 조회를 시도하여 나온 값도 차단됩니다
       featured_tag:
         name: '이것들을 사용하면 좋을 것 같습니다:'
       form_challenge:
@@ -78,6 +82,7 @@ ko:
         acct: 새 계정의 핸들
       account_warning_preset:
         text: 프리셋 텍스트
+        title: 제목
       admin_account_action:
         include_statuses: 신고된 툿을 이메일에 포함
         send_email_notification: 이메일로 유저에게 알리기
@@ -150,6 +155,8 @@ ko:
         username: 유저 이름
         username_or_email: 유저네임 또는 이메일
         whole_word: 단어 전체에 매칭
+      email_domain_block:
+        with_dns_records: 도메인의 IP와 MX 레코드 값을 포함
       featured_tag:
         name: 해시태그
       interactions:
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index ec6ba52eb..c65608d95 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -43,7 +43,7 @@ nl:
         setting_default_sensitive: Gevoelige media wordt standaard verborgen en kan met één klik worden getoond
         setting_display_media_default: Als gevoelig gemarkeerde media verbergen
         setting_display_media_hide_all: Media altijd verbergen
-        setting_display_media_show_all: Als gevoelig gemarkeerde media altijd verbergen
+        setting_display_media_show_all: Media altijd tonen
         setting_hide_network: Wie jij volgt en wie jou volgen wordt niet op jouw profiel getoond
         setting_noindex: Heeft invloed op jouw openbare profiel en toots
         setting_show_application: De toepassing de je gebruikt om te tooten wordt in de gedetailleerde weergave van de toot getoond
diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml
index b7495c56d..f1daa0e6e 100644
--- a/config/locales/simple_form.oc.yml
+++ b/config/locales/simple_form.oc.yml
@@ -8,6 +8,7 @@ oc:
         acct: Donatz l’utilizaire@domeni del compte ont volètz anar
       account_warning_preset:
         text: Podètz utilizar la sintaxi dels tuts, coma las URL, las etiquetas e las mencions
+        title: Opcional. Pas visible pel destinari
       admin_account_action:
         include_statuses: L’utilizaire veiràs quals tuts a provocat l’accion de moderacion o avertiment
         send_email_notification: L’utilizaire recebrà una explicacion de çò qu’arribèt a son compte
@@ -78,6 +79,7 @@ oc:
         acct: Identificant del nòu compte
       account_warning_preset:
         text: Tèxt predefinit
+        title: Títol
       admin_account_action:
         include_statuses: Inclure los tuts senhalats dins lo corrièl
         send_email_notification: Avisar l’utilizaire per corrièl
@@ -150,6 +152,8 @@ oc:
         username: Nom d’utilizaire
         username_or_email: Nom d’utilizaire o corrièl
         whole_word: Mot complèt
+      email_domain_block:
+        with_dns_records: Inclure los enregistraments MX e las IP del domeni
       featured_tag:
         name: Etiqueta
       interactions:
diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml
index c985badb4..10e9f3d2b 100644
--- a/config/locales/simple_form.pl.yml
+++ b/config/locales/simple_form.pl.yml
@@ -2,19 +2,34 @@
 pl:
   simple_form:
     hints:
+      account_alias:
+        acct: Określ nazwę@domenę konta z którego chcesz się przenieść
+      account_migration:
+        acct: Określ nazwę@domenę konta na które chcesz się przenieść
       account_warning_preset:
         text: Możesz korzystać ze składni której używasz we wpisach, takiej jak adresy URL, hashtagi i wspomnienia
+        title: Nieobowiązkowe. Niewidoczne dla odbiorcy
       admin_account_action:
+        include_statuses: Użytkownik zobaczy, których wpisów dotyczyło działanie moderacji lub ostrzeżenie
         send_email_notification: Użytkownik otrzyma informację, co stało się z jego kontem
         text_html: Możesz używać składni której używasz we wpisach. Możesz <a href="%{path}">dodać szablon ostrzeżenia</a> aby zaoszczędzić czas
         type_html: Wybierz co chcesz zrobić z <strong>%{acct}</strong>
         warning_preset_id: Nieobowiązkowe. Możesz dodać niestandardowy tekst do końcowki szablonu
+      announcement:
+        all_day: Jeżeli zaznaczone, tylko daty z przedziału czasu będą wyświetlane
+        ends_at: Nieobowiązkowe. Ogłoszenie zostanie automatycznie wycofane w tym czasie
+        scheduled_at: Pozostaw puste, aby opublikować ogłoszenie natychmiastowo
+        starts_at: Nieobowiązkowe. Jeżeli ogłoszenie jest związane z danym przedziałem czasu
+        text: Możesz używać składni wpisu. Pamiętaj o tym, ile miejsca zajmie ogłoszenie na ekranie użytkownika
       defaults:
         autofollow: Osoby, które zarejestrują się z Twojego zaproszenia automatycznie zaczną Cię śledzić
         avatar: PNG, GIF lub JPG. Maksymalnie %{size}. Zostanie zmniejszony do %{dimensions}px
         bot: To konto wykonuje głównie zautomatyzowane działania i może nie być monitorowane
         context: Jedno lub wiele miejsc, w których filtr zostanie zastosowany
+        current_password: Ze względów bezpieczeństwa wprowadź hasło obecnego konta
+        current_username: Aby potwierdzić, wprowadź nazwę użytkownika obecnego konta
         digest: Wysyłane tylko po długiej nieaktywności, jeżeli w tym czasie otrzymaleś jakąś wiadomość bezpośrednią
+        discoverable: Katalog profilu jest jednym ze sposobów, dzięki którym Twoje konto dotrze do szerszego grona
         email: Otrzymasz e-mail potwierdzający
         fields: Możesz ustawić maksymalnie 4 niestandardowe pola wyświetlane jako tabela na Twoim profilu
         header: PNG, GIF lub JPG. Maksymalnie %{size}. Zostanie zmniejszony do %{dimensions}px
@@ -35,8 +50,14 @@ pl:
         setting_show_application: W informacjach o wpisie będzie widoczna informacja o aplikacji, z której został wysłany
         setting_skin: Zmienia wygląd używanej odmiany Mastodona
         setting_use_blurhash: Gradienty są oparte na kolorach ukrywanej zawartości, ale uniewidaczniają wszystkie szczegóły
+        setting_use_pending_items: Ukryj aktualizacje osi czasu za kliknięciem, zamiast automatycznego przewijania strumienia
         username: Twoja nazwa użytkownika będzie niepowtarzalna na %{domain}
         whole_word: Jeśli słowo lub fraza składa się jedynie z liter lub cyfr, filtr będzie zastosowany tylko do pełnych wystąpień
+      domain_allow:
+        domain: Ta domena będzie mogła pobierać dane z serwera, a dane przychodzące z niej będą przetwarzane i przechowywane
+      email_domain_block:
+        domain: Może to być nazwa domeny pojawiająca się w adresu e-mail, rekord MX na który rozwiązuje domena lub IP serwera na który rozwiązuje rekord MX. Będą one wykrywane i odrzucane przy rejestracji.
+        with_dns_records: Zostanie wykonana próba rozwiązania rekordów DNS podanej domeny, a wyniki również zostaną dodane na czarną listę
       featured_tag:
         name: 'Sugerujemy użycie jednego z następujących:'
       form_challenge:
@@ -62,6 +83,7 @@ pl:
         acct: Nazwa nowego konta
       account_warning_preset:
         text: Tekst szablonu
+        title: Tytuł
       admin_account_action:
         include_statuses: Uwzględniaj zgłoszone wpisy w wiadomości e-mail
         send_email_notification: Powiadom użytkownika mailem
@@ -136,6 +158,8 @@ pl:
         username: Nazwa użytkownika
         username_or_email: Nazwa użytkownika lub adres e-mail
         whole_word: Całe słowo
+      email_domain_block:
+        with_dns_records: Uwzględnij rekordy MX i adresy IP domeny
       featured_tag:
         name: Hasztag
       interactions:
diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml
index 503b48d83..1f72f278d 100644
--- a/config/locales/simple_form.pt-BR.yml
+++ b/config/locales/simple_form.pt-BR.yml
@@ -8,6 +8,7 @@ pt-BR:
         acct: Especifique o usuário@domínio da conta para a qual você deseja se mudar
       account_warning_preset:
         text: Você pode usar a sintaxe do toot, como links, hashtags e menções
+        title: Opcional. Não visível para o destinatário
       admin_account_action:
         include_statuses: O usuário verá quais toots causaram o aviso ou ação da moderação
         send_email_notification: O usuário receberá uma explicação do que aconteceu com a própria conta
@@ -15,7 +16,7 @@ pt-BR:
         type_html: Decida o que fazer com <strong>%{acct}</strong>
         warning_preset_id: Opcional. Você ainda pode adicionar texto personalizado no final do aviso pré-definido
       announcement:
-        all_day: Quando marcado, apenas as datas do período serão exibidas
+        all_day: Quando marcada, apenas as datas do período serão mostradas
         ends_at: Opcional. O anúncio será automaticamente não publicado no momento
         scheduled_at: Deixe em branco para publicar o anúncio imediatamente
         starts_at: Opcional. Caso seu anúncio esteja vinculado a um período específico
@@ -53,6 +54,9 @@ pt-BR:
         whole_word: Quando a palavra-chave ou frase é inteiramente alfanumérica, ela será aplicada somente se corresponder a palavra inteira
       domain_allow:
         domain: Este domínio poderá obter dados deste servidor e os dados recebidos dele serão processados e armazenados
+      email_domain_block:
+        domain: Este pode ser o nome de domínio que aparece no endereço de email, o registro MX para o qual o domínio resolve, ou o IP do servidor para o qual o registro MX resolve. Estes serão verificados no momento da inscrição do usuário e a inscrição será rejeitada.
+        with_dns_records: Será feita uma tentativa de resolver os registros DNS do domínio em questão e os resultados também serão colocados na lista negra
       featured_tag:
         name: 'Você pode querer usar um destes:'
       form_challenge:
@@ -78,6 +82,7 @@ pt-BR:
         acct: Nome de usuário da nova conta
       account_warning_preset:
         text: Aviso pré-definido
+        title: Título
       admin_account_action:
         include_statuses: Incluir toots denunciados no e-mail
         send_email_notification: Notificar o usuário por e-mail
@@ -150,6 +155,8 @@ pt-BR:
         username: Nome de usuário
         username_or_email: Nome de usuário ou e-mail
         whole_word: Palavra inteira
+      email_domain_block:
+        with_dns_records: Incluir registros MX e IPs do domínio
       featured_tag:
         name: Hashtag
       interactions:
@@ -169,11 +176,11 @@ pt-BR:
         pending_account: Enviar e-mail quando uma nova conta precisar ser revisada
         reblog: Enviar e-mail quando alguém der boost nos seus toots
         report: Enviar e-mail quando uma nova denúncia for enviada
-        trending_tag: Enviar e-mail quando uma hashtag não revisada estiver em alta
+        trending_tag: Uma hashtag não-revisada está em alta
       tag:
         listable: Permitir que esta hashtag apareça em pesquisas e no diretório de perfis
         name: Hashtag
-        trendable: Permitir que esta hashtag apareça em alta
+        trendable: Permitir que esta hashtag fique em alta
         usable: Permitir que toots usem esta hashtag
     'no': Não
     recommended: Recomendado
diff --git a/config/locales/simple_form.pt-PT.yml b/config/locales/simple_form.pt-PT.yml
index f346005f7..3bec60f38 100644
--- a/config/locales/simple_form.pt-PT.yml
+++ b/config/locales/simple_form.pt-PT.yml
@@ -8,6 +8,7 @@ pt-PT:
         acct: Especifique o nome de usuário@domínio da conta para onde você deseja mover
       account_warning_preset:
         text: Tu podes usar sintaxe de escrita, como URLs, hashtags e referências
+        title: Opcional. Não visível para o destinatário
       admin_account_action:
         include_statuses: O usuário verá quais ferramentas causaram a ação de moderação ou aviso
         send_email_notification: O utilizador receberá uma explicação sobre o que aconteceu com a sua conta
@@ -41,9 +42,9 @@ pt-PT:
         scopes: Quais as APIs a que será concedido acesso. Se escolheres uma abrangência de nível superior, não precisarás de as seleccionar individualmente.
         setting_aggregate_reblogs: Não mostrar novas partilhas que foram partilhadas recentemente (só afecta as novas partilhas)
         setting_default_sensitive: Média sensível está oculta por padrão e pode ser revelada com um clique
-        setting_display_media_default: Esconder media marcada como sensível
-        setting_display_media_hide_all: Esconder sempre toda a media
-        setting_display_media_show_all: Mostrar sempre a media marcada como sensível
+        setting_display_media_default: Esconder média marcada como sensível
+        setting_display_media_hide_all: Esconder sempre toda a média
+        setting_display_media_show_all: Mostrar sempre a média marcada como sensível
         setting_hide_network: Quem tu segues e quem te segue não será mostrado no teu perfil
         setting_noindex: Afecta o teu perfil público e as páginas das tuas publicações
         setting_show_application: A aplicação que tu usas para publicar será mostrada na vista detalhada das tuas publicações
@@ -53,6 +54,9 @@ pt-PT:
         whole_word: Quando a palavra-chave ou expressão-chave é somente alfanumérica, ela só será aplicada se corresponder à palavra completa
       domain_allow:
         domain: Este domínio será capaz de obter dados deste servidor e os dados dele recebidos serão processados e armazenados
+      email_domain_block:
+        domain: Este pode ser o nome de domínio que aparece no endereço de email, o registro MX para o qual o domínio resolve, ou o IP do servidor para o qual o registro MX resolve. Estes serão verificados no momento da inscrição do utilizador e a inscrição será rejeitada.
+        with_dns_records: Será feita uma tentativa de resolver os registros DNS do domínio em questão e os resultados também serão colocados na lista negra
       featured_tag:
         name: 'Poderás querer usar um destes:'
       form_challenge:
@@ -78,6 +82,7 @@ pt-PT:
         acct: Nome de utilizador da nova conta
       account_warning_preset:
         text: Texto pré-definido
+        title: Título
       admin_account_action:
         include_statuses: Incluir no e-mail os toots reportados
         send_email_notification: Notificar o utilizador por e-mail
@@ -128,9 +133,9 @@ pt-PT:
         setting_crop_images: Cortar imagens em toots não expandidos para o formato 16x9
         setting_default_language: Língua de publicação
         setting_default_privacy: Privacidade da publicação
-        setting_default_sensitive: Sempre marcar media como sensível
+        setting_default_sensitive: Sempre marcar média como sensível
         setting_delete_modal: Solicitar confirmação antes de eliminar uma publicação
-        setting_display_media: Exposição de media
+        setting_display_media: Exposição de média
         setting_display_media_default: Pré-definição
         setting_display_media_hide_all: Esconder todos
         setting_display_media_show_all: Mostrar todos
@@ -150,6 +155,8 @@ pt-PT:
         username: Nome de utilizador
         username_or_email: Nome de utilizador ou e-mail
         whole_word: Palavra completa
+      email_domain_block:
+        with_dns_records: Incluir registros MX e IPs do domínio
       featured_tag:
         name: Hashtag
       interactions:
diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml
index 0ec9d0d6b..7bc585c64 100644
--- a/config/locales/simple_form.ru.yml
+++ b/config/locales/simple_form.ru.yml
@@ -8,6 +8,7 @@ ru:
         acct: Укажите имя_пользователя@домен учётной записи, на которую вы собираетесь мигрировать
       account_warning_preset:
         text: Вы можете использовать всё, что в обычных постах — ссылки, хэштеги, упоминания и т.д.
+        title: Необязательно. Не видно получателю
       admin_account_action:
         include_statuses: Пользователь будет видеть к каким постами применялись модераторские действия и выносились предупреждения
         send_email_notification: Пользователь получит сообщение о том, что случилось с его/её учётной записью
@@ -53,6 +54,9 @@ ru:
         whole_word: Если слово или фраза состоит только из букв и цифр, сопоставление произойдёт только по полному совпадению
       domain_allow:
         domain: Этот домен сможет получать данные с этого сервера и его входящие данные будут обрабатываться и сохранены
+      email_domain_block:
+        domain: Это может быть домен, отображаемый в адресе электронной почты, MX-запись, на которую разрешается домен или IP сервера, на который разрешается MX-запись. Они будут проверены при регистрации пользователя, и регистрация будет отклонена.
+        with_dns_records: Будет сделана попытка разрешить DNS-записи данного домена и результаты также будут внесены в чёрный список
       featured_tag:
         name: 'Возможно, вы захотите добавить что-то из этого:'
       form_challenge:
@@ -78,6 +82,7 @@ ru:
         acct: Имя новой учётной записи
       account_warning_preset:
         text: Текст шаблона
+        title: Заголовок
       admin_account_action:
         include_statuses: Включать в письмо жалобы на посты
         send_email_notification: Уведомить пользователя по e-mail
@@ -118,7 +123,7 @@ ru:
         max_uses: Максимальное число использований
         new_password: Новый пароль
         note: О себе
-        otp_attempt: Двухфакторный код
+        otp_attempt: Код из приложения-аутентификатора
         password: Пароль
         phrase: Слово или фраза
         setting_advanced_layout: Включить многоколоночный интерфейс
@@ -150,6 +155,8 @@ ru:
         username: Имя пользователя
         username_or_email: Имя пользователя или e-mail
         whole_word: Слово целиком
+      email_domain_block:
+        with_dns_records: Включить MX-записи и IP-адреса домена
       featured_tag:
         name: Хэштег
       interactions:
diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml
index c10df08d0..9e03d7254 100644
--- a/config/locales/simple_form.sk.yml
+++ b/config/locales/simple_form.sk.yml
@@ -72,6 +72,7 @@ sk:
         acct: Adresa nového účtu
       account_warning_preset:
         text: Text predlohy
+        title: Názov
       admin_account_action:
         include_statuses: Zahrnúť nahlásené príspevky v emaile
         send_email_notification: Oznam užívateľovi cez email
@@ -83,6 +84,11 @@ sk:
           silence: Utíš
           suspend: Vylúč a nenávratne vymaž dáta na účte
         warning_preset_id: Použi varovnú predlohu
+      announcement:
+        all_day: Celodenná udalosť
+        ends_at: Koniec udalosti
+        starts_at: Začiatok udalosti
+        text: Oboznámenie
       defaults:
         autofollow: Pozvi k následovaniu tvojho profilu
         avatar: Maskot
@@ -141,7 +147,7 @@ sk:
       featured_tag:
         name: Haštag
       interactions:
-        must_be_follower: Blokuj oboznámenia od užívateľov, ktorí ma nenásledujú
+        must_be_follower: Blokuj oboznámenia od užívateľov, ktorí ma nenasledujú
         must_be_following: Blokuj oboznámenia od ľudí, ktorých nesledujem
         must_be_following_dm: Blokuj priame správy od ľudí, ktorých nesleduješ
       invite:
diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml
index de0a14bd7..80b699c28 100644
--- a/config/locales/simple_form.sv.yml
+++ b/config/locales/simple_form.sv.yml
@@ -8,6 +8,7 @@ sv:
         acct: Ange användarnamn@domän för kontot du flyttar till
       account_warning_preset:
         text: Du kan använda inläggssyntax som webbadresser, hashtaggar och omnämnanden
+        title: Valfri. Inte synlig för mottagaren
       admin_account_action:
         include_statuses: Användaren ser de toots som orsakat moderering eller varning
         send_email_notification: Användaren kommer att få en förklaring av vad som hände med sitt konto
@@ -45,6 +46,8 @@ sv:
         fields:
           name: Etikett
           value: Innehåll
+      account_warning_preset:
+        title: Rubrik
       admin_account_action:
         types:
           none: Gör ingenting
diff --git a/config/locales/simple_form.ta.yml b/config/locales/simple_form.ta.yml
index bac29f158..74c641901 100644
--- a/config/locales/simple_form.ta.yml
+++ b/config/locales/simple_form.ta.yml
@@ -6,6 +6,8 @@ ta:
         acct: நீங்கள் இங்கே நகர்த்த விரும்பும் கணக்கின் பயனர் பெயர்
       account_migration:
         acct: நீங்கள் இங்கே நகர்த்த விரும்பும் கணக்கின் பயனர் பெயர் username@domain
+      account_warning_preset:
+        title: விருப்பத் தேர்வு. பெறுநரால் பார்க்கமுடியாது
       admin_account_action:
         send_email_notification: தங்கள் கணக்கிற்கு என்ன நேர்ந்தது என்ற விவரம் பயனரால் பெறப்படும்
       announcement:
@@ -23,10 +25,15 @@ ta:
         password: குறைந்தது 8 எழுத்துக்களைப் பயன்படுத்தவும்
         setting_display_media_hide_all: எப்போதும் எல்லா ஊடகங்களையும் மறைக்கவும்
         setting_display_media_show_all: உணர்ச்சி வயப்படு (Sensitive) குறிக்கப்பட்ட மீடியாவை எப்போதும் காட்டுங்கள்
+      email_domain_block:
+        domain: இது மின்னஞ்சலில் காணப்படும் களத்தின் பெயராக இருக்கலாம், அல்லது அக்களம் சார்ந்திருக்கும் MX record-ஆக இருக்கலாம், அல்லது அந்த MX record சார்ந்திருக்கும் சர்வரின் IP முகவரியாக இருக்கலாம். பயனர் கணக்கைத் துவங்கும்போது அவை கண்காணிக்கப்பட்டு, கணக்குத் துவக்கம் நிராகரிக்கப்படும்.
+        with_dns_records: இக்களத்தின் DNS record-களை சரிசெய்யும் முயற்சி மேற்கொள்ளப்படும், மற்றும் அதன் முடிவுகள் தடுப்புப்பட்டியலில் சேர்க்கப்படும்
     labels:
       account:
         fields:
           name: லேபிள்
+      account_warning_preset:
+        title: தலைப்பு
       admin_account_action:
         types:
           disable: உள்நுழைவை முடக்கு
@@ -59,6 +66,8 @@ ta:
         setting_use_pending_items: மெதுவான பயன்முறை
         username: பயனர்பெயர்
         username_or_email: பயனர் பெயர் அல்லது மின்னஞ்சல்
+      email_domain_block:
+        with_dns_records: களத்தின் IP மற்றும் MX records-ஐ உள்ளடக்கு
     required:
       text: தேவை
     'yes': ஆம்
diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml
index 33a255e8d..22a2647a3 100644
--- a/config/locales/simple_form.th.yml
+++ b/config/locales/simple_form.th.yml
@@ -8,6 +8,7 @@ th:
         acct: ระบุ username@domain ของบัญชีที่คุณต้องการย้ายไป
       account_warning_preset:
         text: คุณสามารถใช้ไวยากรณ์โพสต์ เช่น URL, แฮชแท็ก และการกล่าวถึง
+        title: ตัวเลือกเพิ่มเติม ไม่ปรากฏแก่ผู้รับ
       admin_account_action:
         include_statuses: ผู้ใช้จะเห็นว่าโพสต์ใดก่อให้เกิดการกระทำการควบคุมหรือคำเตือน
         send_email_notification: ผู้ใช้จะได้รับคำอธิบายว่าเกิดอะไรขึ้นกับบัญชีของเขา
@@ -42,8 +43,8 @@ th:
         setting_aggregate_reblogs: ไม่แสดงการดันใหม่สำหรับโพสต์ที่เพิ่งดัน (มีผลต่อการดันที่ได้รับใหม่เท่านั้น)
         setting_default_sensitive: ซ่อนสื่อที่ละเอียดอ่อนโดยค่าเริ่มต้นและสามารถเปิดเผยได้ด้วยการคลิก
         setting_display_media_default: ซ่อนสื่อที่ถูกทำเครื่องหมายว่าละเอียดอ่อน
-        setting_display_media_hide_all: ซ่อนสื่อทั้งหมดเสมอ
-        setting_display_media_show_all: แสดงสื่อที่ถูกทำเครื่องหมายว่าละเอียดอ่อนเสมอ
+        setting_display_media_hide_all: ซ่อนสื่อเสมอ
+        setting_display_media_show_all: แสดงสื่อเสมอ
         setting_hide_network: จะไม่แสดงผู้ที่คุณติดตามและผู้ที่ติดตามคุณในโปรไฟล์ของคุณ
         setting_noindex: มีผลต่อโปรไฟล์สาธารณะและหน้าสถานะของคุณ
         setting_show_application: จะแสดงแอปพลิเคชันที่คุณใช้เพื่อโพสต์ในมุมมองโดยละเอียดของโพสต์ของคุณ
@@ -78,6 +79,7 @@ th:
         acct: การจัดการบัญชีใหม่
       account_warning_preset:
         text: ข้อความที่ตั้งไว้ล่วงหน้า
+        title: ชื่อเรื่อง
       admin_account_action:
         include_statuses: รวมโพสต์ที่รายงานไว้ในอีเมล
         send_email_notification: แจ้งเตือนผู้ใช้ทางอีเมล
@@ -86,7 +88,7 @@ th:
         types:
           disable: ปิดใช้งานการเข้าสู่ระบบ
           none: ไม่ทำสิ่งใด
-          silence: เงียบ
+          silence: ทำให้เงียบ
           suspend: ระงับและลบข้อมูลบัญชีอย่างถาวร
         warning_preset_id: ใช้คำเตือนที่ตั้งไว้ล่วงหน้า
       announcement:
@@ -126,8 +128,8 @@ th:
         setting_auto_play_gif: เล่น GIF แบบเคลื่อนไหวโดยอัตโนมัติ
         setting_boost_modal: แสดงกล่องโต้ตอบการยืนยันก่อนดัน
         setting_crop_images: ครอบตัดภาพในโพสต์ที่ไม่ได้ขยายเป็น 16x9
-        setting_default_language: ภาษาที่โพสต์
-        setting_default_privacy: ความเป็นส่วนตัวของโพสต์
+        setting_default_language: ภาษาของการโพสต์
+        setting_default_privacy: ความเป็นส่วนตัวของการโพสต์
         setting_default_sensitive: ทำเครื่องหมายสื่อว่าละเอียดอ่อนเสมอ
         setting_delete_modal: แสดงกล่องโต้ตอบการยืนยันก่อนลบโพสต์
         setting_display_media: การแสดงสื่อ
@@ -150,6 +152,8 @@ th:
         username: ชื่อผู้ใช้
         username_or_email: ชื่อผู้ใช้หรืออีเมล
         whole_word: ทั้งคำ
+      email_domain_block:
+        with_dns_records: รวมระเบียน MX และ IP ของโดเมน
       featured_tag:
         name: แฮชแท็ก
       interactions:
@@ -166,10 +170,10 @@ th:
         follow: ใครสักคนได้ติดตามคุณ
         follow_request: ใครสักคนได้ขอติดตามคุณ
         mention: ใครสักคนได้กล่าวถึงคุณ
-        pending_account: ส่งอีเมลเมื่อบัญชีใหม่ต้องการการตรวจทาน
+        pending_account: บัญชีใหม่ต้องมีการตรวจทาน
         reblog: ใครสักคนได้ดันสถานะของคุณ
-        report: ส่งอีเมลเมื่อมีการส่งรายงานใหม่
-        trending_tag: ส่งอีเมลเมื่อแฮชแท็กที่ยังไม่ได้ตรวจทานกำลังนิยม
+        report: มีการส่งรายงานใหม่
+        trending_tag: แฮชแท็กที่ยังไม่ได้ตรวจทานกำลังนิยม
       tag:
         listable: อนุญาตให้แฮชแท็กนี้ปรากฏในการค้นหาและในไดเรกทอรีโปรไฟล์
         name: แฮชแท็ก
diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml
index 1a7b7de99..a617df62e 100644
--- a/config/locales/simple_form.zh-CN.yml
+++ b/config/locales/simple_form.zh-CN.yml
@@ -8,6 +8,7 @@ zh-CN:
         acct: 指定你想迁移过去的帐号的 用户名@站点域名
       account_warning_preset:
         text: 你可以使用嘟文格式,在嘟文中加入 URL、话题标签和提及“@”
+        title: 可选。对接收者不可见
       admin_account_action:
         include_statuses: 用户将会看到哪些嘟文导致了审核行为或警告
         send_email_notification: 用户将收到对其账号上发生的事的解释
@@ -53,6 +54,9 @@ zh-CN:
         whole_word: 如果关键词只包含字母和数字,就只会在整个词被匹配时才会套用
       domain_allow:
         domain: 该站点将能够从该服务器上拉取数据,并且从那里发过来的数据也会被处理和存储。
+      email_domain_block:
+        domain: 这里可以是邮箱地址中的域名部分、域名解析到的 MX 记录,或者 MX 记录解析到的域名。这些检查会在用户注册时进行,如果在黑名单中,那么注册会被拒绝。
+        with_dns_records: Mastodon 会尝试解析所给域名的 DNS 记录,然后把解析结果一并加入黑名单
       featured_tag:
         name: 你可能想要使用以下之一:
       form_challenge:
@@ -78,6 +82,7 @@ zh-CN:
         acct: 处理新账号
       account_warning_preset:
         text: 预置文本
+        title: 标题
       admin_account_action:
         include_statuses: 在电子邮件中包括已举报的嘟文
         send_email_notification: 通过邮件提醒此用户
@@ -150,6 +155,8 @@ zh-CN:
         username: 用户名
         username_or_email: 用户名或电子邮件地址
         whole_word: 整个词条
+      email_domain_block:
+        with_dns_records: 包括改域名的 MX 记录和 IP 地址
       featured_tag:
         name: 话题标签
       interactions:
diff --git a/config/locales/simple_form.zh-HK.yml b/config/locales/simple_form.zh-HK.yml
index 235d9c764..57befb139 100644
--- a/config/locales/simple_form.zh-HK.yml
+++ b/config/locales/simple_form.zh-HK.yml
@@ -13,11 +13,16 @@ zh-HK:
         text_html: 選用。您能使用嘟文語法。您可 <a href="%{path}">新增警告預設</a> 來節省時間
         type_html: 設定要使用 <strong>%{acct}</strong> 做的事
         warning_preset_id: 選用。您仍可在預設的結尾新增自訂文字
+      announcement:
+        all_day: 核取後,只會顯示出時間範圍中的日期部分
+        scheduled_at: 空白則立即發布公告
       defaults:
         autofollow: 通過邀請網址註冊的用戶將會自動關注你
         avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會縮裁成 %{dimensions}px
         bot: 提醒用戶本帳號是機械人
         context: 應該套用過濾器的一項或多項內容
+        current_password: 因安全因素,請輸入目前帳戶的密碼
+        current_username: 請輸入目前帳戶的使用者名稱以確認
         digest: 僅在你長時間未登錄,且收到了私信時發送
         email: 您將收到一封確認電子郵件
         fields: 個人資料頁可顯示多至 4 個項目
@@ -30,6 +35,7 @@ zh-HK:
         phrase: 無論是嘟文的本文或是內容警告都會被過濾
         scopes: 允許讓應用程式存取的 API。 若您選擇最高階範圍,則無須選擇個別項目。
         setting_aggregate_reblogs: 請勿顯示最近已被轉嘟之嘟文的最新轉嘟(只影響最新收到的嘟文)
+        setting_default_sensitive: 敏感媒體預設隱藏,且按一下即可重新顯示
         setting_display_media_default: 隱藏標為敏感的媒體
         setting_display_media_hide_all: 總是隱藏所有媒體
         setting_display_media_show_all: 總是顯示標為敏感的媒體
@@ -40,10 +46,16 @@ zh-HK:
         whole_word: 如果關鍵字或詞組僅有字母與數字,則其將只在符合整個單字的時候才會套用
       featured_tag:
         name: 您可能想使用其中一個:
+      form_challenge:
+        current_password: 您正要進入安全區域
       imports:
         data: 自其他服務站匯出的 CSV 檔案
+      invite_request:
+        text: 這會協助我們審核您的應用程式
       sessions:
         otp: 輸入你手機上生成的雙重認證碼,或者任意一個恢復代碼:
+      tag:
+        name: 您只能變更大小寫,例如,以使其更易讀。
       user:
         chosen_languages: 只有被選擇的語言會在公開時間軸內顯示
     labels:
@@ -54,6 +66,7 @@ zh-HK:
       account_warning_preset:
         text: 預設文字
       admin_account_action:
+        include_statuses: 在電子郵件中加入檢舉的嘟文
         send_email_notification: 透過電子信件通知使用者
         text: 自訂警告
         type: 動作
@@ -63,6 +76,12 @@ zh-HK:
           silence: 安靜
           suspend: 停權並不可逆的刪除帳戶資料
         warning_preset_id: 使用警告預設
+      announcement:
+        all_day: 全天活動
+        ends_at: 活動結束時間
+        scheduled_at: 排程發佈
+        starts_at: 活動開始時間
+        text: 公告
       defaults:
         autofollow: 邀請別人關注你的賬號
         avatar: 個人頭像
@@ -89,6 +108,7 @@ zh-HK:
         otp_attempt: 雙重認證碼
         password: 密碼
         phrase: 關鍵字或片語
+        setting_advanced_layout: 啟用進階網頁介面
         setting_aggregate_reblogs: 時間軸中的群組轉嘟
         setting_auto_play_gif: 自動播放 GIF
         setting_boost_modal: 在轉推前詢問我
@@ -107,7 +127,9 @@ zh-HK:
         setting_show_application: 顯示用來傳送嘟文的應用程式
         setting_system_font_ui: 使用系統預設字型
         setting_theme: 網站主題
+        setting_trends: 顯示本日趨勢
         setting_unfollow_modal: 取消關注前跳出詢問我
+        setting_use_pending_items: 限速模式
         severity: 等級
         type: 匯入資料類型
         username: 用戶名稱
@@ -119,15 +141,26 @@ zh-HK:
         must_be_follower: 隱藏沒有關注你的用戶的通知
         must_be_following: 隱藏你不關注的用戶的通知
         must_be_following_dm: 隱藏你不關注的用戶的私信
+      invite:
+        comment: 備註
+      invite_request:
+        text: 加入的原因
       notification_emails:
         digest: 定期電郵摘要
         favourite: 當有用戶喜歡你的文章時,發電郵通知
         follow: 當有用戶關注你時,發電郵通知
         follow_request: 當有用戶要求關注你時,發電郵通知
         mention: 當有用戶在文章提及你時,發電郵通知
+        pending_account: 需要審核的新帳戶
         reblog: 當有用戶轉推你的文章時,發電郵通知
         report: 當提交新檢舉時傳送電子郵件
+      tag:
+        listable: 允許此主題標籤在搜尋及個人檔案目錄中顯示
+        name: 主題標籤
+        trendable: 允許此主題標籤在趨勢下顯示
+        usable: 允許嘟文使用此主題標籤
     'no': 否
+    recommended: 建議
     required:
       mark: "*"
       text: 必須填寫
diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml
index 7de349ee3..6efebbe6d 100644
--- a/config/locales/simple_form.zh-TW.yml
+++ b/config/locales/simple_form.zh-TW.yml
@@ -13,11 +13,16 @@ zh-TW:
         text_html: 選用。您能使用嘟文語法。您可 <a href="%{path}">新增警告預設</a> 來節省時間
         type_html: 設定要使用 <strong>%{acct}</strong> 做的事
         warning_preset_id: 選用。您仍可在預設的結尾新增自訂文字
+      announcement:
+        all_day: 核取後,只會顯示出時間範圍中的日期部分
+        scheduled_at: 空白則立即發布公告
       defaults:
         autofollow: 通過邀請網址註冊的使用者將自動關注你
         avatar: 支援 PNG, GIF 或 JPG 圖片,檔案最大為 %{size},會等比例縮減成 %{dimensions} 像素
         bot: 此帳戶主要執行自動操作且可能未被監控
         context: 應該套用過濾器的一項或多項內容
+        current_password: 因安全因素,請輸入目前帳戶的密碼
+        current_username: 請輸入目前帳戶的使用者名稱以確認
         digest: 僅在你長時間未登入且在未登入期間收到私訊時傳送
         email: 您將收到一封確認電子郵件
         fields: 您可在個人資料上有至多 4 個以表格形式顯示的項目
@@ -30,6 +35,7 @@ zh-TW:
         phrase: 無論是嘟文的本文或是內容警告都會被過濾
         scopes: 允許讓應用程式存取的 API。 若您選擇最高階範圍,則無須選擇個別項目。
         setting_aggregate_reblogs: 請勿顯示最近已被轉嘟之嘟文的最新轉嘟(只影響最新收到的嘟文)
+        setting_default_sensitive: 敏感媒體預設隱藏,且按一下即可重新顯示
         setting_display_media_default: 隱藏標為敏感的媒體
         setting_display_media_hide_all: 總是隱藏所有媒體
         setting_display_media_show_all: 總是顯示標為敏感的媒體
@@ -40,10 +46,16 @@ zh-TW:
         whole_word: 如果關鍵字或詞組僅有字母與數字,則其將只在符合整個單字的時候才會套用
       featured_tag:
         name: 您可能想使用其中一個:
+      form_challenge:
+        current_password: 您正要進入安全區域
       imports:
         data: 從其他 Mastodon 伺服器匯出的 CSV 檔案
+      invite_request:
+        text: 這會協助我們審核您的應用程式
       sessions:
         otp: 請輸入產生自您手機 App 的兩步驟驗證碼,或輸入其中一個復原代碼:
+      tag:
+        name: 您只能變更大小寫,例如,以使其更易讀。
       user:
         chosen_languages: 當核取時,只有選取語言的嘟文會在公開時間軸中顯示
     labels:
@@ -54,6 +66,7 @@ zh-TW:
       account_warning_preset:
         text: 預設文字
       admin_account_action:
+        include_statuses: 在電子郵件中加入檢舉的嘟文
         send_email_notification: 透過電子信件通知使用者
         text: 自訂警告
         type: 動作
@@ -63,6 +76,12 @@ zh-TW:
           silence: 安靜
           suspend: 停權並不可逆的刪除帳戶資料
         warning_preset_id: 使用警告預設
+      announcement:
+        all_day: 全天活動
+        ends_at: 活動結束時間
+        scheduled_at: 排程發佈
+        starts_at: 活動開始時間
+        text: 公告
       defaults:
         autofollow: 邀請別人關注你的帳戶
         avatar: 大頭貼
@@ -89,6 +108,7 @@ zh-TW:
         otp_attempt: 兩步驟驗證碼
         password: 密碼
         phrase: 關鍵字或片語
+        setting_advanced_layout: 啟用進階網頁介面
         setting_aggregate_reblogs: 時間軸中的群組轉嘟
         setting_auto_play_gif: 自動播放 GIF 動畫
         setting_boost_modal: 在轉嘟前先詢問我
@@ -107,7 +127,9 @@ zh-TW:
         setting_show_application: 顯示用來傳送嘟文的應用程式
         setting_system_font_ui: 使用系統預設字型
         setting_theme: 站點主題
+        setting_trends: 顯示本日趨勢
         setting_unfollow_modal: 取消關注某人前先詢問我
+        setting_use_pending_items: 限速模式
         severity: 優先級
         type: 匯入類型
         username: 使用者名稱
@@ -119,15 +141,26 @@ zh-TW:
         must_be_follower: 封鎖非關注者的通知
         must_be_following: 封鎖您未關注之使用者的通知
         must_be_following_dm: 封鎖您未關注之使用者的私訊
+      invite:
+        comment: 備註
+      invite_request:
+        text: 加入的原因
       notification_emails:
         digest: 傳送摘要信件
         favourite: 當有使用者喜歡你的嘟文時,傳送電子信件通知
         follow: 當有使用者關注你時,傳送電子信件通知
         follow_request: 當有使用者請求關注你時,傳送電子信件通知
         mention: 當有使用者在嘟文提及你時,傳送電子信件通知
+        pending_account: 需要審核的新帳戶
         reblog: 當有使用者轉嘟你的嘟文時,傳送電子信件通知
         report: 當提交新檢舉時傳送電子郵件
+      tag:
+        listable: 允許此主題標籤在搜尋及個人檔案目錄中顯示
+        name: 主題標籤
+        trendable: 允許此主題標籤在趨勢下顯示
+        usable: 允許嘟文使用此主題標籤
     'no': 否
+    recommended: 建議
     required:
       mark: "*"
       text: 必須填寫
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index dbee6bb12..3a327c1d0 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -35,7 +35,7 @@ sk:
       one: príspevok
       other: príspevky
     status_count_before: Ktorí napísali
-    tagline: Následuj kamarátov, a objavuj nových
+    tagline: Nasleduj kamarátov, a objavuj nových
     terms: Podmienky užitia
     unavailable_content: Nedostupný obsah
     unavailable_content_description:
@@ -43,6 +43,7 @@ sk:
       reason: 'Dôvod:'
       rejecting_media: 'Mediálne súbory z týchto serverov nebudú spracované, alebo ukladané, a nebudú z nich zobrazované žiadne náhľady, vyžadujúc ručné prekliknutie priamo až k pôvodnému súboru:'
       silenced: 'Príspevky z týchto serverov budú skryté z verejných osí a z konverzácií, a nebudú vytvorené žiadné oboznámena ohľadom aktivity ich užívateľov, pokiaľ ich nenásleduješ:'
+    unavailable_content_html: Vo všeobecnosti, Mastodon ti dovoľuje vidieť obsah, a komunikovať s užívateľmi akéhokoľvek iného serveru v rámci fediversa. Toto sú výnimky, ktoré boli vytvorené na tomto konkrétnom serveri.
     user_count_after:
       few: užívateľov
       many: užívatelia
@@ -98,6 +99,7 @@ sk:
       delete: Vymaž
       destroyed_msg: Moderátorska poznámka bola úspešne zmazaná!
     accounts:
+      add_email_domain_block: Pridaj e-mailovú doménu na zoznam zakázaných
       approve: Schváľ
       approve_all: Schváľ všetky
       are_you_sure: Si si istý/á?
@@ -178,6 +180,7 @@ sk:
         staff: Člen
         user: Užívateľ
       search: Hľadaj
+      search_same_email_domain: Iní užívatelia s tou istou emailovou doménou
       search_same_ip: Ostatní užívatelia s rovnakou IP adresou
       shared_inbox_url: URL zdieľanej schránky
       show:
@@ -244,6 +247,8 @@ sk:
         create: Vytvor oznam
         title: Nové oznámenie
       published_msg: Oboznámenie úspešne zverejnené!
+      scheduled_for: Načasované na %{time}
+      scheduled_msg: Oboznámenie bolo naplánované na zverejnenie!
       title: Oboznámenia
     custom_emojis:
       assign_category: Priraď kategóriu
@@ -358,6 +363,7 @@ sk:
       destroyed_msg: Emailová doména bola úspešne vymazaná zo zoznamu zakázaných
       domain: Doména
       empty: Žiadné emailové domény niesú v súčasnosti na čiernej listine.
+      from_html: z %{domain}
       new:
         create: Pridaj doménu
         title: Nový email na zablokovanie
@@ -538,6 +544,9 @@ sk:
       trends:
         desc_html: Verejne zobraz už schválené haštagy, ktoré práve trendujú
         title: Populárne haštagy
+    site_uploads:
+      delete: Vymaž nahratý súbor
+      destroyed_msg: Nahratie bolo zo stránky úspešne vymazané!
     statuses:
       back_to_account: Späť na účet
       batch:
@@ -574,7 +583,6 @@ sk:
     warning_presets:
       add_new: Pridaj nové
       delete: Vymaž
-      edit: Uprav
       edit_preset: Uprav varovnú predlohu
       title: Spravuj varovné predlohy
   admin_mailer:
@@ -657,9 +665,9 @@ sk:
   authorize_follow:
     already_following: Tento účet už následuješ
     error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu
-    follow: Následuj
+    follow: Nasleduj
     follow_request: 'Poslal/a si žiadosť následovať užívateľa:'
-    following: 'Podarilo sa! Teraz už následuješ užívateľa:'
+    following: 'Podarilo sa! Teraz nasleduješ užívateľa:'
     post_follow:
       close: Alebo môžeš iba zatvoriť toto okno.
       return: Ukáž užívateľov profil
@@ -686,7 +694,7 @@ sk:
       x_seconds: "%{count}sek"
   deletes:
     challenge_not_passed: Údaje, ktoré si zadal/a, sú nesprávne
-    confirm_password: Napíšte svoje terajšie heslo pre overenie vašej identity
+    confirm_password: Napíš svoje terajšie heslo pre overenie tvojej identity
     confirm_username: Zadaj svoju prezývku, na potvrdenie úkonu
     proceed: Vymaž účet
     success_msg: Tvoj účet bol úspešne vymazaný
@@ -745,6 +753,7 @@ sk:
       limit: Už si si predvolil/a najvyšší možný počet obľúbených haštagov
   filters:
     contexts:
+      account: Profily
       home: Domáca os
       notifications: Oznámenia
       public: Verejné osi
@@ -769,6 +778,7 @@ sk:
     all: Všetko
     changes_saved_msg: Zmeny boli úspešne uložené!
     copy: Kopíruj
+    delete: Vymaž
     no_batch_actions_available: Na tejto stránke niesú k dispozícii žiadne hromadné akcie
     order_by: Zoraď podľa
     save_changes: Ulož zmeny
@@ -899,7 +909,7 @@ sk:
       title: Nové obľúbené
     follow:
       body: "%{name} ťa teraz následuje!"
-      subject: "%{name} ťa teraz následuje"
+      subject: "%{name} ťa teraz nasleduje"
       title: Nový sledovateľ
     follow_request:
       action: Spravuj žiadosti o sledovanie
@@ -939,6 +949,10 @@ sk:
     other: Ostatné
     posting_defaults: Východiskové nastavenia príspevkov
     public_timelines: Verejné časové osi
+  reactions:
+    errors:
+      limit_reached: Maximálny počet rôznorodých reakcií bol dosiahnutý
+      unrecognized_emoji: je neznámy smajlík
   relationships:
     activity: Aktivita účtu
     dormant: Spiace
@@ -1046,6 +1060,8 @@ sk:
       many: 'obsah nepovolených haštagov: %{tags}'
       one: 'obsahoval nepovolený haštag: %{tags}'
       other: 'obsahoval nepovolené haštagy: %{tags}'
+    errors:
+      in_reply_not_found: Príspevok, na ktorý sa snažíš odpovedať, už pravdepodobne neexistuje.
     language_detection: Zisti automaticky
     open_in_web: Otvor v okne na webe
     over_character_limit: limit %{max} znakov bol presiahnutý
@@ -1067,6 +1083,7 @@ sk:
         other: "%{count} hlasy"
       vote: Hlasuj
     show_more: Ukáž viac
+    show_thread: Ukáž diskusné vlákno
     sign_in_to_participate: Prihlás sa pre zapojenie do diskusie
     title: '%{name}: „%{quote}"'
     visibilities:
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index afb928f11..91720c602 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -485,7 +485,6 @@ sl:
     warning_presets:
       add_new: Dodaj novo
       delete: Izbriši
-      edit: Uredi
       edit_preset: Uredi prednastavitev opozoril
       title: Upravljaj prednastavitev opozoril
   admin_mailer:
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index 6a7a945c4..0e20902ff 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -415,7 +415,6 @@ sq:
     warning_presets:
       add_new: Shtoni të ri
       delete: Fshije
-      edit: Përpunoni
       edit_preset: Përpunoni sinjalizim të paracaktuar
       title: Administroni sinjalizime të paracaktuara
   admin_mailer:
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index c68681215..d7fb6f74d 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -431,7 +431,6 @@ sr:
     warning_presets:
       add_new: Додај нови
       delete: Избриши
-      edit: Уреди
       edit_preset: Уреди пресет упозорења
       title: Управљај пресетима упозорења
   admin_mailer:
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 0094ff06b..3f06878f8 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -219,6 +219,8 @@ sv:
         update_status: "%{name} uppdaterade status för %{target}"
       deleted_status: "(raderad status)"
       title: Revisionslogg
+    announcements:
+      scheduled_for: Schemalagd för %{time}
     custom_emojis:
       assign_category: Ange kategori
       by_domain: Domän
@@ -430,6 +432,8 @@ sv:
         desc_html: Visa offentlig tidslinje på landingsidan
         title: Förhandsgranska tidslinje
       title: Sidans inställningar
+    site_uploads:
+      delete: Radera uppladdad fil
     statuses:
       back_to_account: Tillbaka till kontosidan
       batch:
@@ -448,7 +452,6 @@ sv:
     warning_presets:
       add_new: Lägg till ny
       delete: Radera
-      edit: Redigera
   admin_mailer:
     new_report:
       body: "%{reporter} har rapporterat %{target}"
@@ -505,6 +508,7 @@ sv:
       account_status: Kontostatus
   authorize_follow:
     already_following: Du följer redan detta konto
+    already_requested: Du har redan skickat en vänförfrågan till det kontot
     error: Tyvärr inträffade ett fel när vi kontrollerade fjärrkontot
     follow: Följ
     follow_request: 'Du har skickat en följaförfrågan till:'
@@ -751,6 +755,8 @@ sv:
     disallowed_hashtags:
       one: 'innehöll en otillåten hashtag: %{tags}'
       other: 'innehöll de otillåtna hashtagarna: %{tags}'
+    errors:
+      in_reply_not_found: Statusen du försöker svara på existerar inte.
     language_detection: Lista ut språk automatiskt
     open_in_web: Öppna på webben
     over_character_limit: teckengräns på %{max} har överskridits
@@ -760,6 +766,7 @@ sv:
       private: Icke-offentliga toot kan inte fästas
       reblog: Knuffar kan inte fästas
     show_more: Visa mer
+    show_thread: Visa tråd
     visibilities:
       private: Endast följare
       private_long: Visa endast till följare
diff --git a/config/locales/ta.yml b/config/locales/ta.yml
index c3da99c48..b4fc2ffac 100644
--- a/config/locales/ta.yml
+++ b/config/locales/ta.yml
@@ -78,6 +78,7 @@ ta:
       delete: அகற்று
       destroyed_msg: நடுநிலை குறிப்பு வெற்றிகரமாக அகற்றப்பட்டது!
     accounts:
+      add_email_domain_block: இம்மின்னஞ்சல் களத்தைத் தடுப்புப்பட்டியலில் சேர்
       approve: அங்கீகரி
       approve_all: அனைத்தும் அங்கீகரி
       are_you_sure: நிச்சயமா?
@@ -149,6 +150,7 @@ ta:
         staff: பணியாளர்
         user: பயனர்
       search: தேடு
+      search_same_email_domain: இம்மின்னஞ்சல் களத்தில் உள்ள மற்ற பயனர்கள்
       shared_inbox_url: குழு மின்னஞ்சல் முகவரி
       show:
         created_reports: உறுவாக்கிய அறிக்கைகள்
@@ -200,6 +202,7 @@ ta:
           suspend: தற்காலீகமாக நீக்குக
     email_domain_blocks:
       empty: மின்னஞ்சற் களங்கள் எதுவும் தடுக்கப்படவில்லை.
+      from_html: "%{domain} -இலிருந்து"
     invites:
       filter:
         all: அனைத்தும்
@@ -221,10 +224,15 @@ ta:
           other: "%{count} புகார்கள்"
       comment:
         none: எதுவுமில்லை
+    site_uploads:
+      delete: பதிவேற்றப்பட்டப் படம் அழிக்கப்பட்டது
+      destroyed_msg: பதிவேற்றப்பட்ட வலைதளம் வெற்றிக்கரமாக அழிக்கப்பட்டது!
   appearance:
     localization:
       body: மாஸ்டோடான் தன்னார்வலர்களால் மொழிபெயர்க்கப்படுகிறது.
       guide_link_text: அனைவரும் பங்களிக்கலாம்.
+  authorize_follow:
+    already_requested: இக்கணக்கைப் பின்தொடரும் கோரிக்கையை நீங்கள் ஏற்கனவே அனுப்பிவிட்டீர்கள்
   date:
     formats:
       default: "%b %d, %Y"
@@ -235,7 +243,7 @@ ta:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   filters:
@@ -251,6 +259,9 @@ ta:
       '43200': 12 hours
       '604800': 1 week
       '86400': 1 day
+  media_attachments:
+    validations:
+      not_ready: பதிவேற்றம் முடிவடையாத கோப்புகளை இணைக்க முடியாது. சிறிது நேரம் கழித்து மீண்டும் முயற்சி செய்யவும்!
   notifications:
     email_events: மின்னஞ்சல் அறிவிப்புகளுக்கான நிகழ்வுகள்
     email_events_hint: 'எந்த நிகழ்வுகளுக்கு அறிவிப்புகளைப் பெற வேண்டும் என்று தேர்வு செய்க:'
@@ -263,4 +274,6 @@ ta:
       limit_reached: எதிர்வினைகளுக்கான உச்சவரம்பு எட்டப்பட்டது
       unrecognized_emoji: அங்கீகரிக்கப்பட்ட ஈமோஜி அல்ல
   statuses:
+    errors:
+      in_reply_not_found: நீங்கள் மறுமொழி அளிக்க முயலும் பதிவு இருப்பதுபோல் தெரியவில்லை.
     show_thread: தொடரைக் காட்டு
diff --git a/config/locales/te.yml b/config/locales/te.yml
index dd6c878e7..79415b1d1 100644
--- a/config/locales/te.yml
+++ b/config/locales/te.yml
@@ -113,7 +113,7 @@ te:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 7d6ec0b13..10f25549b 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -34,7 +34,7 @@ th:
     unavailable_content: เนื้อหาไม่พร้อมใช้งาน
     unavailable_content_description:
       domain: เซิร์ฟเวอร์
-      reason: 'เหตุผล:'
+      reason: เหตุผล
       rejecting_media: 'ไฟล์สื่อจากเซิร์ฟเวอร์เหล่านี้จะไม่ได้รับการประมวลผลหรือจัดเก็บ และจะไม่แสดงภาพขนาดย่อ ต้องมีการคลิกไปยังไฟล์ต้นฉบับด้วยตนเอง:'
     user_count_after:
       other: ผู้ใช้
@@ -113,12 +113,12 @@ th:
       joined: เข้าร่วมเมื่อ
       location:
         all: ทั้งหมด
-        local: ในเว็บ
+        local: ในเซิร์ฟเวอร์
         remote: ระยะไกล
         title: ตำแหน่งที่ตั้ง
       login_status: สถานะการเข้าสู่ระบบ
       media_attachments: ไฟล์แนบสื่อ
-      memorialize: เปลี่ยนเป็นระลึกถึง
+      memorialize: เปลี่ยนเป็นอนุสรณ์
       moderation:
         active: ใช้งานอยู่
         all: ทั้งหมด
@@ -159,7 +159,7 @@ th:
       show:
         created_reports: รายงานที่สร้าง
         targeted_reports: รายงานโดยผู้อื่น
-      silence: เงียบ
+      silence: ทำให้เงียบ
       silenced: เงียบอยู่
       statuses: สถานะ
       subscribe: บอกรับ
@@ -167,7 +167,7 @@ th:
       time_in_queue: กำลังรออยู่ในคิว %{time}
       title: บัญชี
       unconfirmed_email: อีเมลที่ยังไม่ได้ยืนยัน
-      undo_silenced: เลิกทำการเงียบ
+      undo_silenced: เลิกทำการทำให้เงียบ
       undo_suspension: เลิกทำการระงับ
       unsubscribe: เลิกบอกรับ
       username: ชื่อผู้ใช้
@@ -175,6 +175,42 @@ th:
       web: เว็บ
       whitelisted: ขึ้นบัญชีขาวแล้ว
     action_logs:
+      action_types:
+        assigned_to_self_report: มอบหมายรายงาน
+        change_email_user: เปลี่ยนอีเมลสำหรับผู้ใช้
+        confirm_user: ยืนยันผู้ใช้
+        create_account_warning: สร้างคำเตือน
+        create_announcement: สร้างประกาศ
+        create_custom_emoji: สร้างอีโมจิที่กำหนดเอง
+        create_domain_allow: สร้างการอนุญาตโดเมน
+        create_domain_block: สร้างการปิดกั้นโดเมน
+        create_email_domain_block: สร้างการปิดกั้นโดเมนอีเมล
+        demote_user: ลดขั้นผู้ใช้
+        destroy_announcement: ลบประกาศ
+        destroy_custom_emoji: ลบอีโมจิที่กำหนดเอง
+        destroy_domain_allow: ลบการอนุญาตโดเมน
+        destroy_domain_block: ลบการปิดกั้นโดเมน
+        destroy_email_domain_block: ลบการปิดกั้นโดเมนอีเมล
+        destroy_status: ลบสถานะ
+        disable_2fa_user: ปิดใช้งาน 2FA
+        disable_custom_emoji: ปิดใช้งานอีโมจิที่กำหนดเอง
+        disable_user: ปิดใช้งานผู้ใช้
+        enable_custom_emoji: เปิดใช้งานอีโมจิที่กำหนดเอง
+        enable_user: เปิดใช้งานผู้ใช้
+        memorialize_account: ทำให้บัญชีเป็นอนุสรณ์
+        promote_user: เลื่อนขั้นผู้ใช้
+        remove_avatar_user: เอาภาพประจำตัวออก
+        reopen_report: เปิดรายงานใหม่
+        reset_password_user: ตั้งรหัสผ่านใหม่
+        resolve_report: แก้ปัญหารายงาน
+        silence_account: ทำให้บัญชีเงียบ
+        suspend_account: ระงับบัญชี
+        unassigned_report: เลิกมอบหมายรายงาน
+        unsilence_account: เลิกทำให้บัญชีเงียบ
+        unsuspend_account: เลิกระงับบัญชี
+        update_announcement: อัปเดตประกาศ
+        update_custom_emoji: อัปเดตอีโมจิที่กำหนดเอง
+        update_status: อัปเดตสถานะ
       actions:
         change_email_user: "%{name} ได้เปลี่ยนที่อยู่อีเมลของผู้ใช้ %{target}"
         confirm_user: "%{name} ได้ยืนยันที่อยู่อีเมลของผู้ใช้ %{target}"
@@ -196,17 +232,23 @@ th:
         disable_user: "%{name} ได้ปิดใช้งานการเข้าสู่ระบบสำหรับผู้ใช้ %{target}"
         enable_custom_emoji: "%{name} ได้เปิดใช้งานอีโมจิ %{target}"
         enable_user: "%{name} ได้เปิดใช้งานการเข้าสู่ระบบสำหรับผู้ใช้ %{target}"
+        memorialize_account: "%{name} ได้เปลี่ยนบัญชีของ %{target} เป็นหน้าอนุสรณ์"
         promote_user: "%{name} ได้เลื่อนขั้นผู้ใช้ %{target}"
         remove_avatar_user: "%{name} ได้เอาภาพประจำตัวของ %{target} ออก"
         reopen_report: "%{name} ได้เปิดรายงาน %{target} ใหม่"
         resolve_report: "%{name} ได้แก้ปัญหารายงาน %{target}"
+        silence_account: "%{name} ได้ทำให้บัญชีของ %{target} เงียบ"
         suspend_account: "%{name} ได้ระงับบัญชีของ %{target}"
         unassigned_report: "%{name} ได้เลิกมอบหมายรายงาน %{target}"
+        unsilence_account: "%{name} ได้เลิกทำให้บัญชีของ %{target} เงียบ"
         unsuspend_account: "%{name} ได้เลิกระงับบัญชีของ %{target}"
         update_announcement: "%{name} ได้อัปเดตประกาศ %{target}"
         update_custom_emoji: "%{name} ได้อัปเดตอีโมจิ %{target}"
         update_status: "%{name} ได้อัปเดตสถานะโดย %{target}"
       deleted_status: "(สถานะที่ลบแล้ว)"
+      empty: ไม่พบรายการบันทึก
+      filter_by_action: กรองตามการกระทำ
+      filter_by_user: กรองตามผู้ใช้
       title: รายการบันทึกการตรวจสอบ
     announcements:
       destroyed_msg: ลบประกาศสำเร็จ!
@@ -259,6 +301,7 @@ th:
       feature_invites: ลิงก์เชิญ
       feature_profile_directory: ไดเรกทอรีโปรไฟล์
       feature_registrations: การลงทะเบียน
+      feature_relay: รีเลย์การติดต่อกับภายนอก
       feature_spam_check: การป้องกันสแปม
       feature_timeline_preview: ตัวอย่างเส้นเวลา
       features: คุณลักษณะ
@@ -292,15 +335,15 @@ th:
         create: สร้างการปิดกั้น
         hint: การปิดกั้นโดเมนจะไม่ป้องกันการสร้างรายการบัญชีในฐานข้อมูล แต่จะใช้วิธีการควบคุมเฉพาะกับบัญชีเหล่านั้นย้อนหลังและโดยอัตโนมัติ
         severity:
-          desc_html: "<strong>เงียบ</strong> จะทำให้โพสต์ของบัญชีมองไม่เห็นกับใครก็ตามที่ไม่ได้กำลังติดตามบัญชี <strong>ระงับ</strong> จะเอาเนื้อหา, สื่อ และข้อมูลโปรไฟล์ทั้งหมดของบัญชีออก ใช้ <strong>ไม่มี</strong> หากคุณเพียงแค่ต้องการปฏิเสธไฟล์สื่อ"
+          desc_html: "<strong>ทำให้เงียบ</strong> จะทำให้โพสต์ของบัญชีไม่ปรากฏแก่ใครก็ตามที่ไม่ได้กำลังติดตามบัญชี <strong>ระงับ</strong> จะเอาเนื้อหา, สื่อ และข้อมูลโปรไฟล์ทั้งหมดของบัญชีออก ใช้ <strong>ไม่มี</strong> หากคุณเพียงแค่ต้องการปฏิเสธไฟล์สื่อ"
           noop: ไม่มี
-          silence: เงียบ
+          silence: ทำให้เงียบ
           suspend: ระงับ
         title: การปิดกั้นโดเมนใหม่
       private_comment: ความคิดเห็นส่วนตัว
       public_comment: ความคิดเห็นสาธารณะ
       reject_media: ปฏิเสธไฟล์สื่อ
-      reject_media_hint: เอาไฟล์สื่อที่จัดเก็บไว้ในเว็บออกและปฏิเสธที่จะดาวน์โหลดไฟล์ใด ๆ ในอนาคต ไม่เกี่ยวข้องกับการระงับ
+      reject_media_hint: เอาไฟล์สื่อที่จัดเก็บไว้ในเซิร์ฟเวอร์ออกและปฏิเสธที่จะดาวน์โหลดไฟล์ใด ๆ ในอนาคต ไม่เกี่ยวข้องกับการระงับ
       reject_reports: ปฏิเสธรายงาน
       severity:
         silence: เงียบอยู่
@@ -309,7 +352,7 @@ th:
         affected_accounts:
           other: มีผลต่อ %{count} บัญชีในฐานข้อมูล
         retroactive:
-          silence: เลิกเงียบบัญชีที่มีอยู่ทั้งหมดจากโดเมนนี้
+          silence: เลิกทำให้บัญชีที่มีอยู่ทั้งหมดจากโดเมนนี้เงียบ
           suspend: เลิกระงับบัญชีที่มีอยู่ทั้งหมดจากโดเมนนี้
         title: เลิกทำการปิดกั้นโดเมนสำหรับ %{domain}
         undo: เลิกทำ
@@ -322,6 +365,7 @@ th:
       destroyed_msg: ลบโดเมนอีเมลออกจากบัญชีดำสำเร็จ
       domain: โดเมน
       empty: ไม่มีโดเมนอีเมลที่ขึ้นบัญชีดำอยู่
+      from_html: จาก %{domain}
       new:
         create: เพิ่มโดเมน
         title: รายการบัญชีดำอีเมลใหม่
@@ -408,7 +452,7 @@ th:
         all: ให้กับทุกคน
         disabled: ให้กับไม่มีใคร
         title: แสดงการปิดกั้นโดเมน
-        users: ให้กับผู้ใช้ในเว็บที่เข้าสู่ระบบ
+        users: ให้กับผู้ใช้ในเซิร์ฟเวอร์ที่เข้าสู่ระบบ
       domain_blocks_rationale:
         title: แสดงคำชี้แจงเหตุผล
       enable_bootstrap_timeline_accounts:
@@ -488,7 +532,6 @@ th:
     warning_presets:
       add_new: เพิ่มใหม่
       delete: ลบ
-      edit: แก้ไข
       edit_preset: แก้ไขคำเตือนที่ตั้งไว้ล่วงหน้า
       title: จัดการคำเตือนที่ตั้งไว้ล่วงหน้า
   admin_mailer:
@@ -603,7 +646,7 @@ th:
     '422':
       content: การตรวจสอบความปลอดภัยล้มเหลว คุณกำลังปิดกั้นคุกกี้หรือไม่?
       title: การตรวจสอบความปลอดภัยล้มเหลว
-    '429': Throttled
+    '429': Too many requests
     '500':
       title: หน้านี้ไม่ถูกต้อง
     '503': The page could not be served due to a temporary server failure.
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index cde7f1c83..1dcf9ccea 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -573,7 +573,6 @@ tr:
     warning_presets:
       add_new: Yeni ekle
       delete: Sil
-      edit: Düzenle
       edit_preset: Uyarı ön-ayarını düzenle
       title: Uyarı ön-ayarlarını yönet
   admin_mailer:
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 967a02717..3df83e756 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -591,7 +591,6 @@ uk:
     warning_presets:
       add_new: Додати новий
       delete: Видалити
-      edit: Редагувати
       edit_preset: Редагувати шаблон попередження
       title: Управління шаблонами попереджень
   admin_mailer:
diff --git a/config/locales/ur.yml b/config/locales/ur.yml
index 114261859..2aa72a8f8 100644
--- a/config/locales/ur.yml
+++ b/config/locales/ur.yml
@@ -7,7 +7,7 @@ ur:
     '406': This page is not available in the requested format.
     '410': The page you were looking for doesn't exist here anymore.
     '422': 
-    '429': Throttled
+    '429': Too many requests
     '500': 
     '503': The page could not be served due to a temporary server failure.
   invites:
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index ec8e853fe..cba773417 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -534,7 +534,6 @@ vi:
     warning_presets:
       add_new: Thêm mới
       delete: Xóa bỏ
-      edit: Biên tập
       edit_preset: Chỉnh sửa cảnh báo đặt trước
       title: Quản lý cài đặt trước cảnh báo
   admin_mailer:
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index d6618dbbe..33f25eaa6 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -41,7 +41,7 @@ zh-CN:
       rejecting_media: 来自这些服务器的媒体文件将不会被处理或存储,缩略图也不会显示,需要手动点击打开原始文件。
       silenced: 来自这些服务器上的帖子将不会出现在公共时间线和会话中;此外,除非你关注了这些服务器上的用户,否则他们的互动不会产生通知。
       suspended: 这些服务器的数据将不会被处理、存储或者交换,本站也将无法和来自这些服务器的用户互动或者交流。
-    unavailable_content_html: 通常来说,在Mastodon上,你可以浏览联邦宇宙中任何一台服务器上的内容,并且和上面的用户互动。但是这台服务器上会有一些挟制。
+    unavailable_content_html: 通常来说,在Mastodon上,你可以浏览联邦宇宙中任何一台服务器上的内容,并且和上面的用户互动。但是某些站点上不排除会有例外。
     user_count_after:
       other: 位用户
     user_count_before: 这里共注册有
@@ -88,6 +88,7 @@ zh-CN:
       delete: 删除
       destroyed_msg: 管理备忘删除成功!
     accounts:
+      add_email_domain_block: 把电子邮箱域名加入黑名单
       approve: 批准
       approve_all: 批准全部
       are_you_sure: 你确定吗?
@@ -168,6 +169,7 @@ zh-CN:
         staff: 管理人员
         user: 普通用户
       search: 搜索
+      search_same_email_domain: 其他具有相同电子邮箱域名的用户
       search_same_ip: 具有相同IP的其他用户
       shared_inbox_url: 公用收件箱(Shared Inbox)URL
       show:
@@ -353,6 +355,7 @@ zh-CN:
       destroyed_msg: 电子邮件域名屏蔽删除成功
       domain: 域名
       empty: 当前没有邮件域名黑名单。
+      from_html: 来自 %{domain}
       new:
         create: 添加域名
         title: 添加电子邮件域名屏蔽
@@ -495,8 +498,8 @@ zh-CN:
           open: 开放注册
         title: 注册模式
       show_known_fediverse_at_about_page:
-        desc_html: 启用此选项将会在预览中显示来自已知实例的嘟文,否则只会显示本站时间轴的内容.
-        title: 在时间轴预览中显示已知实例
+        desc_html: 如果开启,就会在时间轴预览显示其他站点嘟文,否则就只会只显示本站嘟文。
+        title: 在时间轴预览中显示其他站点嘟文
       show_staff_badge:
         desc_html: 在个人资料页上显示管理人员标志
         title: 显示管理人员标志
@@ -529,6 +532,9 @@ zh-CN:
       trends:
         desc_html: 公开显示先前已通过审核的当前热门话题
         title: 热门标签
+    site_uploads:
+      delete: 删除已上传的文件
+      destroyed_msg: 站点上传的文件已经成功删除!
     statuses:
       back_to_account: 返回帐户信息页
       batch:
@@ -565,7 +571,6 @@ zh-CN:
     warning_presets:
       add_new: 添加新条目
       delete: 删除
-      edit: 编辑
       edit_preset: 编辑预置警告
       title: 管理预设警告
   admin_mailer:
@@ -653,6 +658,7 @@ zh-CN:
     trouble_logging_in: 登录有问题?
   authorize_follow:
     already_following: 你已经在关注此用户了
+    already_requested: 你已经向那个账户发送过关注请求了
     error: 对不起,寻找这个跨站用户时出错
     follow: 关注
     follow_request: 关注请求已发送给:
@@ -839,6 +845,7 @@ zh-CN:
   media_attachments:
     validations:
       images_and_video: 无法在嘟文中同时插入视频和图片
+      not_ready: 不能附加还在处理中的文件。请稍后再试!
       too_many: 最多只能添加 4 张图片
   migrations:
     acct: 新帐户的 用户名@域名
@@ -1055,6 +1062,8 @@ zh-CN:
     content_warning: 内容警告:%{warning}
     disallowed_hashtags:
       other: 包含了这些禁止的话题标签:%{tags}
+    errors:
+      in_reply_not_found: 你回复的嘟文似乎不存在
     language_detection: 自动检测语言
     open_in_web: 在站内打开
     over_character_limit: 超过了 %{max} 字的限制
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index ffd5ba5e9..92233dcc6 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -11,12 +11,14 @@ zh-HK:
     apps: 行動應用程式
     apps_platforms: 在 iOS、Android 和其他平台使用 Mastodon
     browse_directory: 依興趣瀏覽個人資料目錄和過濾器
+    browse_local_posts: 瀏覽這台伺服器中公開嘟文的直播串流
     browse_public_posts: 在 Mastodon 瀏覽公開嘟文的即時串流
     contact: 聯絡
     contact_missing: 未設定
     contact_unavailable: 未公開
     discover_users: 探索使用者
     documentation: 文件
+    federation_hint_html: 你只需要擁有 %{instance} 的帳戶,就可以追蹤隨便一台 Mastodon 伺服器上的人等等。
     get_apps: 嘗試行動應用程式
     hosted_on: 在 %{domain} 運作的 Mastodon 服務站
     learn_more: 了解更多
@@ -29,6 +31,7 @@ zh-HK:
     status_count_before: 他們共發佈了
     tagline: 關注朋友並探索新朋友
     terms: 使用條款
+    unavailable_content: 無法取得的內容
     unavailable_content_description:
       domain: 伺服器
       reason: 原因
@@ -60,7 +63,9 @@ zh-HK:
     roles:
       admin: 管理員
       bot: 機械人
+      group: 群組
       moderator: 監察員
+    unavailable: 無法取得個人檔案
     unfollow: 取消關注
   admin:
     account_actions:
@@ -72,6 +77,7 @@ zh-HK:
       delete: 刪除
       destroyed_msg: 管理記錄已被刪除
     accounts:
+      add_email_domain_block: 將電子郵件網域加入黑名單
       approve: 核准
       approve_all: 全部批准
       are_you_sure: 你確定嗎?
@@ -151,6 +157,8 @@ zh-HK:
         staff: 管理人員
         user: 普通用戶
       search: 搜索
+      search_same_email_domain: 其他有同個電子郵件網域的使用者
+      search_same_ip: 其他有同個 IP 的使用者
       shared_inbox_url: 公共收件箱(Shared Inbox)URL
       show:
         created_reports: 此用戶所提舉報的紀錄
@@ -160,6 +168,7 @@ zh-HK:
       statuses: 文章
       subscribe: 訂閱
       suspended: 已停權
+      time_in_queue: 正在佇列等待 %{time}
       title: 用戶
       unconfirmed_email: 未確認的電郵
       undo_silenced: 解除靜音
@@ -168,17 +177,22 @@ zh-HK:
       username: 用戶名稱
       warn: 警告
       web: 用戶頁面
+      whitelisted: 已加入白名單
     action_logs:
       actions:
         assigned_to_self_report: "%{name} 指派了 %{target} 的舉報給自己"
         change_email_user: "%{name} 改變了用戶 %{target} 的電郵地址"
         confirm_user: "%{name} 確認了用戶 %{target} 的電郵地址"
         create_account_warning: "%{name} 已對 %{target} 送出警告"
+        create_announcement: "%{name} 建立了新公告 %{target}"
         create_custom_emoji: "%{name} 加入自訂表情符號 %{target}"
+        create_domain_allow: "%{name} 將 %{target} 網域加入黑名單了"
         create_domain_block: "%{name} 阻隔了網域 %{target}"
         create_email_domain_block: "%{name} 阻隔了電郵網域 %{target}"
         demote_user: "%{name} 把用戶 %{target} 降任"
+        destroy_announcement: "%{name} 刪除了公告 %{target}"
         destroy_custom_emoji: "%{name} 破壞了 %{target} 表情符號"
+        destroy_domain_allow: "%{name} 從白名單中移除了 %{target} 網域"
         destroy_domain_block: "%{name} 取消了對網域 %{target} 的阻隔"
         destroy_email_domain_block: "%{name} 取消了對電郵網域 %{target} 的阻隔"
         destroy_status: "%{name} 刪除了 %{target} 的文章"
@@ -198,15 +212,33 @@ zh-HK:
         unassigned_report: "%{name} 取消指派 %{target} 的舉報"
         unsilence_account: "%{name} 取消了用戶 %{target} 的靜音狀態"
         unsuspend_account: "%{name} 取消了用戶 %{target} 的停權狀態"
+        update_announcement: "%{name} 更新了公告 %{target}"
         update_custom_emoji: "%{name} 更新了自訂表情符號 %{target}"
         update_status: "%{name} 刷新了 %{target} 的文章"
       deleted_status: "(已刪除嘟文)"
       title: 營運日誌
+    announcements:
+      destroyed_msg: 成功刪除公告!
+      edit:
+        title: 編輯公告
+      empty: 找不到公告。
+      live: 直播
+      new:
+        create: 建立公告
+        title: 新增公告
+      published_msg: 成功發布公告!
+      scheduled_for: 排定 %{time}
+      scheduled_msg: 公告已排定公開!
+      title: 公告
+      unpublished_msg: 成功取消發布公告!
+      updated_msg: 成功更新公告!
     custom_emojis:
+      assign_category: 指定分類
       by_domain: 網域
       copied_msg: 成功將表情複製到本地
       copy: 複製
       copy_failed_msg: 無法將表情複製到本地
+      create_new_category: 建立新分類
       created_msg: 已新增表情符號
       delete: 刪除
       destroyed_msg: 已刪除表情符號
@@ -226,11 +258,13 @@ zh-HK:
       shortcode: 短代碼
       shortcode_hint: 至少 2 個字元,只能使用字母、數字和下劃線
       title: 自訂 emoji
+      uncategorized: 未分類
       unlisted: 已隱藏
       update_failed_msg: 無法更新表情符號
       updated_msg: 已更新表情符號
       upload: 上傳新的表情符號
     dashboard:
+      authorized_fetch_mode: 安全模式
       backlog: 未處理工作數
       config: 設定
       feature_deletions: 帳戶刪除
@@ -238,9 +272,13 @@ zh-HK:
       feature_profile_directory: 個人資料目錄
       feature_registrations: 註冊
       feature_relay: 聯邦中繼站
+      feature_spam_check: 防垃圾訊息
+      feature_timeline_preview: 時間軸預覽
       features: 功能
       hidden_service: 與隱密服務互連
       open_reports: 待處理檢舉數
+      pending_tags: 等待審核的主題標籤
+      pending_users: 等待審核的使用者
       recent_users: 最近加入的使用者
       search: 全文搜尋
       single_user_mode: 單一使用者模式
@@ -252,6 +290,12 @@ zh-HK:
       week_interactions: 本週互動次數
       week_users_active: 本週活躍使用者數
       week_users_new: 本週新使用者數
+      whitelist_mode: 白名單模式
+    domain_allows:
+      add_new: 將網域加入白名單
+      created_msg: 網域已成功加入白名單
+      destroyed_msg: 網域已成功從白名單移除
+      undo: 從白名單移除
     domain_blocks:
       add_new: 新增
       created_msg: 正處理域名阻隔
@@ -352,12 +396,23 @@ zh-HK:
       contact_information:
         email: 輸入一個公開的電郵地址
         username: 輸入用戶名稱
+      domain_blocks:
+        all: 給任何人
+        disabled: 給沒有人
+        title: 顯示封鎖的網域
+      enable_bootstrap_timeline_accounts:
+        title: 啟用新使用者的預設追蹤
       hero:
         desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會默認為服務站縮圖
         title: 主題圖片
       peers_api_enabled:
         desc_html: 現時本服務站在網絡中已發現的域名
         title: 公開已知服務站的列表
+      preview_sensitive_media:
+        title: 在 OpenGraph 預覽中顯示敏感媒體
+      profile_directory:
+        desc_html: 允許能探索使用者
+        title: 啟用個人資料目錄
       registrations:
         closed_message:
           desc_html: 當本站暫停接受註冊時,會顯示這個訊息。<br/> 可使用 HTML
@@ -368,6 +423,12 @@ zh-HK:
         min_invite_role:
           disabled: 沒有人
           title: 允許發送邀請的身份
+      registrations_mode:
+        modes:
+          approved: 註冊需要核准
+          none: 沒有人可註冊
+          open: 任何人皆能註冊
+        title: 註冊模式
       show_known_fediverse_at_about_page:
         desc_html: 如果開啟,就會在時間軸預覽顯示跨站文章,否則就只會顯示本站文章。
         title: 在時間軸預覽顯示跨站文章
@@ -380,10 +441,14 @@ zh-HK:
       site_description_extended:
         desc_html: 本站詳細資訊頁的內文<br/>你可以在此使用 HTML
         title: 本站詳細資訊
+      site_short_description:
+        title: 伺服器短描述
       site_terms:
         desc_html: 可以填寫自己的隱私權政策、使用條款或其他法律文本。可以使用 HTML 標籤
         title: 自訂使用條款
       site_title: 本站名稱
+      spam_check_enabled:
+        title: 自動防廣告訊息
       thumbnail:
         desc_html: 用於在 OpenGraph 和 API 中顯示預覽圖。推薦大小 1200×630px
         title: 本站縮圖
@@ -391,25 +456,44 @@ zh-HK:
         desc_html: 在主頁顯示本站時間軸
         title: 時間軸預覽
       title: 網站設定
+      trends:
+        title: 趨勢主題標籤
+    site_uploads:
+      delete: 刪除上傳的檔案
+      destroyed_msg: 成功刪除站台的上傳項目!
     statuses:
       back_to_account: 返回帳戶信息頁
       batch:
         delete: 刪除
         nsfw_off: 取消 NSFW 標記
         nsfw_on: 添加 NSFW 標記
+      deleted: 已刪除
       failed_to_execute: 執行失敗
       media:
         title: 媒體檔案
       no_media: 不含媒體檔案
+      no_status_selected: 因未選擇嘟文而未變更。
       title: 帳戶文章
       with_media: 含有媒體檔案
     tags:
+      context: 上下文
+      directory: 在目錄中
+      in_directory: 目錄中有 %{count} 個
+      last_active: 上次活躍
+      most_popular: 最熱門
+      most_recent: 最近
       name: Hashtag
+      review: 審核嘟文
+      reviewed: 已審核
+      title: 主題標籤
+      trending_right_now: 最新趨勢
+      unique_uses_today: 今天嘟了 %{count} 則
+      unreviewed: 未審核
+      updated_msg: 成功更新主題標籤設定
     title: 管理
     warning_presets:
       add_new: 新增
       delete: 刪除
-      edit: 編輯
   admin_mailer:
     new_report:
       body: "%{reporter} 舉報了用戶 %{target}"
@@ -456,6 +540,7 @@ zh-HK:
     set_new_password: 設定新密碼
   authorize_follow:
     already_following: 你已經關注了這個帳號
+    already_requested: 您早已向該帳戶寄送追蹤請求
     error: 對不起,尋找這個跨站用戶的過程發生錯誤
     follow: 關注
     follow_request: 關注請求已發送给:
@@ -673,6 +758,8 @@ zh-HK:
     content_warning: 內容警告: %{warning}
     disallowed_hashtags:
       other: 包含不允許的標籤: %{tags}
+    errors:
+      in_reply_not_found: 您嘗試回覆的嘟文看起來不存在。
     language_detection: 自動偵測語言
     open_in_web: 開啟網頁
     over_character_limit: 超過了 %{max} 字的限制
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 5b25688ed..3f82428de 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -11,12 +11,14 @@ zh-TW:
     apps: 行動應用程式
     apps_platforms: 在 iOS、Android 和其他平台使用 Mastodon
     browse_directory: 依興趣瀏覽個人資料目錄和過濾器
+    browse_local_posts: 瀏覽這台伺服器中公開嘟文的直播串流
     browse_public_posts: 在 Mastodon 瀏覽公開嘟文的即時串流
     contact: 聯絡我們
     contact_missing: 未設定
     contact_unavailable: 未公開
     discover_users: 探索使用者
     documentation: 文件
+    federation_hint_html: 你只需要擁有 %{instance} 的帳戶,就可以追蹤隨便一台 Mastodon 伺服器上的人等等。
     get_apps: 嘗試行動應用程式
     hosted_on: 在 %{domain} 運作的 Mastodon 站點
     learn_more: 了解詳細
@@ -29,6 +31,7 @@ zh-TW:
     status_count_before: 他們共嘟出了
     tagline: 關注朋友並探索新朋友
     terms: 使用條款
+    unavailable_content: 無法取得的內容
     unavailable_content_description:
       domain: 伺服器
       reason: 原因
@@ -60,7 +63,9 @@ zh-TW:
     roles:
       admin: 管理員
       bot: 機器人
+      group: 群組
       moderator: 版主
+    unavailable: 無法取得個人檔案
     unfollow: 取消關注
   admin:
     account_actions:
@@ -72,6 +77,7 @@ zh-TW:
       delete: 刪除
       destroyed_msg: 成功刪除管理備忘!
     accounts:
+      add_email_domain_block: 將電子郵件網域加入黑名單
       approve: 核准
       approve_all: 全部批准
       are_you_sure: 您確定嗎?
@@ -151,6 +157,8 @@ zh-TW:
         staff: 管理人員
         user: 普通使用者
       search: 搜尋
+      search_same_email_domain: 其他有同個電子郵件網域的使用者
+      search_same_ip: 其他有同個 IP 的使用者
       shared_inbox_url: 共享收件箱網址
       show:
         created_reports: 建立檢舉
@@ -160,6 +168,7 @@ zh-TW:
       statuses: 嘟文
       subscribe: 訂閱
       suspended: 已停權
+      time_in_queue: 正在佇列等待 %{time}
       title: 帳戶
       unconfirmed_email: 未確認的電子信箱位址
       undo_silenced: 取消靜音
@@ -168,17 +177,22 @@ zh-TW:
       username: 使用者名稱
       warn: 警告
       web: 頁面
+      whitelisted: 已加入白名單
     action_logs:
       actions:
         assigned_to_self_report: "%{name} 接受了檢舉 %{target}"
         change_email_user: "%{name} 變更了使用者 %{target} 的電子信箱位址"
         confirm_user: "%{name} 確認了使用者 %{target} 的電子信箱位址"
         create_account_warning: "%{name} 已對 %{target} 送出警告"
+        create_announcement: "%{name} 建立了新公告 %{target}"
         create_custom_emoji: "%{name} 加入自訂表情符號 %{target}"
+        create_domain_allow: "%{name} 將 %{target} 網域加入黑名單了"
         create_domain_block: "%{name} 封鎖了站點 %{target}"
         create_email_domain_block: "%{name} 封鎖了電子信箱網域 %{target}"
         demote_user: "%{name} 把使用者 %{target} 降級"
+        destroy_announcement: "%{name} 刪除了公告 %{target}"
         destroy_custom_emoji: "%{name} 破壞了 %{target} 表情符號"
+        destroy_domain_allow: "%{name} 從白名單中移除了 %{target} 網域"
         destroy_domain_block: "%{name} 取消了對站點 %{target} 的封鎖"
         destroy_email_domain_block: "%{name} 取消了對電子信箱網域 %{target} 的封鎖"
         destroy_status: "%{name} 刪除了 %{target} 的嘟文"
@@ -198,15 +212,33 @@ zh-TW:
         unassigned_report: "%{name} 取消指派 %{target} 的檢舉"
         unsilence_account: "%{name} 取消了使用者 %{target} 的靜音狀態"
         unsuspend_account: "%{name} 取消了使用者 %{target} 的停權狀態"
+        update_announcement: "%{name} 更新了公告 %{target}"
         update_custom_emoji: "%{name} 更新了自訂表情符號 %{target}"
         update_status: "%{name} 重整了 %{target} 的嘟文"
       deleted_status: "(已刪除嘟文)"
       title: 營運日誌
+    announcements:
+      destroyed_msg: 成功刪除公告!
+      edit:
+        title: 編輯公告
+      empty: 找不到公告。
+      live: 直播
+      new:
+        create: 建立公告
+        title: 新增公告
+      published_msg: 成功發布公告!
+      scheduled_for: 排定 %{time}
+      scheduled_msg: 公告已排定公開!
+      title: 公告
+      unpublished_msg: 成功取消發布公告!
+      updated_msg: 成功更新公告!
     custom_emojis:
+      assign_category: 指定分類
       by_domain: 站點
       copied_msg: 成功將表情複製到本地
       copy: 複製
       copy_failed_msg: 無法將表情複製到本地
+      create_new_category: 建立新分類
       created_msg: 已新增表情符號!
       delete: 刪除
       destroyed_msg: 已刪除表情符號!
@@ -226,11 +258,13 @@ zh-TW:
       shortcode: 短代碼
       shortcode_hint: 至少 2 個字元,只能使用字母、數字和下劃線
       title: 自訂表情符號
+      uncategorized: 未分類
       unlisted: 已隱藏
       update_failed_msg: 無法更新表情符號
       updated_msg: 已更新表情符號!
       upload: 上傳新的表情符號
     dashboard:
+      authorized_fetch_mode: 安全模式
       backlog: 未處理工作數
       config: 設定
       feature_deletions: 帳戶刪除
@@ -238,9 +272,13 @@ zh-TW:
       feature_profile_directory: 個人資料目錄
       feature_registrations: 註冊
       feature_relay: 聯邦中繼站
+      feature_spam_check: 防垃圾訊息
+      feature_timeline_preview: 時間軸預覽
       features: 功能
       hidden_service: 與隱密服務互連
       open_reports: 待處理檢舉數
+      pending_tags: 等待審核的主題標籤
+      pending_users: 等待審核的使用者
       recent_users: 最近加入的使用者
       search: 全文搜尋
       single_user_mode: 單一使用者模式
@@ -252,6 +290,12 @@ zh-TW:
       week_interactions: 本週互動次數
       week_users_active: 本週活躍使用者數
       week_users_new: 本週新使用者數
+      whitelist_mode: 白名單模式
+    domain_allows:
+      add_new: 將網域加入白名單
+      created_msg: 網域已成功加入白名單
+      destroyed_msg: 網域已成功從白名單移除
+      undo: 從白名單移除
     domain_blocks:
       add_new: 新增欲封鎖域名
       created_msg: 正在進行站點封鎖
@@ -351,12 +395,23 @@ zh-TW:
       contact_information:
         email: 用於聯絡的公開電子信箱位址
         username: 請輸入使用者名稱
+      domain_blocks:
+        all: 給任何人
+        disabled: 給沒有人
+        title: 顯示封鎖的網域
+      enable_bootstrap_timeline_accounts:
+        title: 啟用新使用者的預設追蹤
       hero:
         desc_html: 在首頁顯示。推薦最小 600x100px。如果留空,就會重設回伺服器預覽圖
         title: 主題圖片
       peers_api_enabled:
         desc_html: 本伺服器在聯邦中發現的站點
         title: 發布已知伺服器的列表
+      preview_sensitive_media:
+        title: 在 OpenGraph 預覽中顯示敏感媒體
+      profile_directory:
+        desc_html: 允許能探索使用者
+        title: 啟用個人資料目錄
       registrations:
         closed_message:
           desc_html: 關閉註冊時顯示在首頁的內容,可使用 HTML 標籤
@@ -367,6 +422,12 @@ zh-TW:
         min_invite_role:
           disabled: 沒有人
           title: 允許發送邀請的身份
+      registrations_mode:
+        modes:
+          approved: 註冊需要核准
+          none: 沒有人可註冊
+          open: 任何人皆能註冊
+        title: 註冊模式
       show_known_fediverse_at_about_page:
         desc_html: 如果開啟,就會在時間軸預覽顯示其他站點嘟文,否則就只會顯示本站點嘟文。
         title: 在時間軸預覽顯示其他站點嘟文
@@ -379,10 +440,14 @@ zh-TW:
       site_description_extended:
         desc_html: 可放置行為準則、規定以及其他此伺服器特有的內容。可使用 HTML 標籤
         title: 本站詳細資訊
+      site_short_description:
+        title: 伺服器短描述
       site_terms:
         desc_html: 可以填寫自己的隱私權政策、使用條款或其他法律文本。可以使用 HTML 標籤
         title: 自訂使用條款
       site_title: 伺服器名稱
+      spam_check_enabled:
+        title: 自動防廣告訊息
       thumbnail:
         desc_html: 用於在 OpenGraph 和 API 中顯示預覽圖。推薦大小 1200×630px
         title: 伺服器縮圖
@@ -390,25 +455,44 @@ zh-TW:
         desc_html: 在主頁顯示本站時間軸
         title: 時間軸預覽
       title: 網站設定
+      trends:
+        title: 趨勢主題標籤
+    site_uploads:
+      delete: 刪除上傳的檔案
+      destroyed_msg: 成功刪除站台的上傳項目!
     statuses:
       back_to_account: 返回帳戶訊息頁
       batch:
         delete: 刪除
         nsfw_off: 標記為非敏感內容
         nsfw_on: 標記為敏感內容
+      deleted: 已刪除
       failed_to_execute: 執行失敗
       media:
         title: 媒體檔案
       no_media: 不含媒體檔案
+      no_status_selected: 因未選擇嘟文而未變更。
       title: 帳戶嘟文
       with_media: 含有媒體檔案
     tags:
+      context: 上下文
+      directory: 在目錄中
+      in_directory: 目錄中有 %{count} 個
+      last_active: 上次活躍
+      most_popular: 最熱門
+      most_recent: 最近
       name: Hashtag
+      review: 審核嘟文
+      reviewed: 已審核
+      title: 主題標籤
+      trending_right_now: 最新趨勢
+      unique_uses_today: 今天嘟了 %{count} 則
+      unreviewed: 未審核
+      updated_msg: 成功更新主題標籤設定
     title: 管理介面
     warning_presets:
       add_new: 新增
       delete: 刪除
-      edit: 編輯
   admin_mailer:
     new_report:
       body: "%{reporter} 檢舉了使用者 %{target}"
@@ -455,6 +539,7 @@ zh-TW:
     set_new_password: 設定新密碼
   authorize_follow:
     already_following: 你已經關注了這個使用者
+    already_requested: 您早已向該帳戶寄送追蹤請求
     error: 對不起,搜尋其他站點使用者出現錯誤
     follow: 關注
     follow_request: 關注請求已經發送給:
@@ -655,6 +740,8 @@ zh-TW:
       description: 附件: %{attached}
     boosted_from_html: 轉嘟自 %{acct_link}
     content_warning: 內容警告: %{warning}
+    errors:
+      in_reply_not_found: 您嘗試回覆的嘟文看起來不存在。
     language_detection: 自動偵測語言
     open_in_web: 以網頁開啟
     over_character_limit: 超過了 %{max} 字的限制
diff --git a/config/routes.rb b/config/routes.rb
index b56f7fd87..450d3222f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-require 'sidekiq/web'
+require 'sidekiq_unique_jobs/web'
 require 'sidekiq-scheduler/web'
 
 Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base]
@@ -188,6 +188,7 @@ Rails.application.routes.draw do
     end
 
     resource :settings, only: [:edit, :update]
+    resources :site_uploads, only: [:destroy]
 
     resources :invites, only: [:index, :create, :destroy] do
       collection do
@@ -345,7 +346,7 @@ Rails.application.routes.draw do
         end
       end
 
-      resources :media,        only: [:create, :update]
+      resources :media,        only: [:create, :update, :show]
       resources :blocks,       only: [:index]
       resources :mutes,        only: [:index] do
         collection do
@@ -462,6 +463,7 @@ Rails.application.routes.draw do
     end
 
     namespace :v2 do
+      resources :media, only: [:create]
       get '/search', to: 'search#index', as: :search
     end
 
diff --git a/config/webpack/development.js b/config/webpack/development.js
index 56f6e43f0..774ecbc07 100644
--- a/config/webpack/development.js
+++ b/config/webpack/development.js
@@ -54,7 +54,7 @@ module.exports = merge(sharedConfig, {
     watchOptions: Object.assign(
       {},
       settings.dev_server.watch_options,
-      watchOptions
+      watchOptions,
     ),
     writeToDisk: filePath => /ocr/.test(filePath),
   },
diff --git a/config/webpack/shared.js b/config/webpack/shared.js
index 1741ffdb9..08526957b 100644
--- a/config/webpack/shared.js
+++ b/config/webpack/shared.js
@@ -98,7 +98,7 @@ module.exports = {
         // temporary fix for https://github.com/ReactTraining/react-router/issues/5576
         // to reduce bundle size
         resource.request = resource.request.replace(/^history/, 'history/es');
-      }
+      },
     ),
     new MiniCssExtractPlugin({
       filename: 'css/[name]-[contenthash:8].css',
diff --git a/db/migrate/20191212163405_add_hide_collections_to_accounts.rb b/db/migrate/20191212163405_add_hide_collections_to_accounts.rb
new file mode 100644
index 000000000..fa99b32e5
--- /dev/null
+++ b/db/migrate/20191212163405_add_hide_collections_to_accounts.rb
@@ -0,0 +1,5 @@
+class AddHideCollectionsToAccounts < ActiveRecord::Migration[5.2]
+  def change
+    add_column :accounts, :hide_collections, :boolean
+  end
+end
diff --git a/db/migrate/20200306035625_add_processing_to_media_attachments.rb b/db/migrate/20200306035625_add_processing_to_media_attachments.rb
new file mode 100644
index 000000000..131ffa52a
--- /dev/null
+++ b/db/migrate/20200306035625_add_processing_to_media_attachments.rb
@@ -0,0 +1,5 @@
+class AddProcessingToMediaAttachments < ActiveRecord::Migration[5.2]
+  def change
+    add_column :media_attachments, :processing, :integer
+  end
+end
diff --git a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb
new file mode 100644
index 000000000..46a5350e7
--- /dev/null
+++ b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb
@@ -0,0 +1,15 @@
+require Rails.root.join('lib', 'mastodon', 'migration_helpers')
+
+class AddTitleToAccountWarningPresets < ActiveRecord::Migration[5.2]
+  include Mastodon::MigrationHelpers
+
+  disable_ddl_transaction!
+
+  def up
+    safety_assured { add_column_with_default :account_warning_presets, :title, :string, default: '', allow_null: false }
+  end
+
+  def down
+    remove_column :account_warning_presets, :title
+  end
+end
diff --git a/db/migrate/20200312162302_add_status_ids_to_announcements.rb b/db/migrate/20200312162302_add_status_ids_to_announcements.rb
new file mode 100644
index 000000000..42aa6513d
--- /dev/null
+++ b/db/migrate/20200312162302_add_status_ids_to_announcements.rb
@@ -0,0 +1,6 @@
+class AddStatusIdsToAnnouncements < ActiveRecord::Migration[5.2]
+  def change
+    add_column :announcements, :status_ids, :bigint, array: true
+  end
+end
+
diff --git a/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb b/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb
new file mode 100644
index 000000000..03915040c
--- /dev/null
+++ b/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb
@@ -0,0 +1,5 @@
+class AddParentIdToEmailDomainBlocks < ActiveRecord::Migration[5.2]
+  def change
+    add_reference :email_domain_blocks, :parent, null: true, default: nil, foreign_key: { on_delete: :cascade, to_table: :email_domain_blocks }, index: false
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 73ac78b80..c294d762b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2020_01_26_203551) do
+ActiveRecord::Schema.define(version: 2020_03_12_185443) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -114,6 +114,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do
     t.text "text", default: "", null: false
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.string "title", default: "", null: false
   end
 
   create_table "account_warnings", force: :cascade do |t|
@@ -170,6 +171,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do
     t.datetime "silenced_at"
     t.datetime "suspended_at"
     t.integer "trust_level"
+    t.boolean "hide_collections"
     t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
     t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower", unique: true
     t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id"
@@ -229,6 +231,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.datetime "published_at"
+    t.bigint "status_ids", array: true
   end
 
   create_table "backups", force: :cascade do |t|
@@ -334,6 +337,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do
     t.string "domain", default: "", null: false
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
+    t.bigint "parent_id"
     t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true
   end
 
@@ -460,6 +464,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do
     t.text "description"
     t.bigint "scheduled_status_id"
     t.string "blurhash"
+    t.integer "processing"
     t.index ["account_id"], name: "index_media_attachments_on_account_id"
     t.index ["scheduled_status_id"], name: "index_media_attachments_on_scheduled_status_id"
     t.index ["shortcode"], name: "index_media_attachments_on_shortcode", unique: true
@@ -869,6 +874,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do
   add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade
   add_foreign_key "conversation_mutes", "conversations", on_delete: :cascade
   add_foreign_key "custom_filters", "accounts", on_delete: :cascade
+  add_foreign_key "email_domain_blocks", "email_domain_blocks", column: "parent_id", on_delete: :cascade
   add_foreign_key "favourites", "accounts", name: "fk_5eb6c2b873", on_delete: :cascade
   add_foreign_key "favourites", "statuses", name: "fk_b0e856845e", on_delete: :cascade
   add_foreign_key "featured_tags", "accounts", on_delete: :cascade
diff --git a/dist/nginx.conf b/dist/nginx.conf
index b6591e897..2d5f3a389 100644
--- a/dist/nginx.conf
+++ b/dist/nginx.conf
@@ -3,6 +3,14 @@ map $http_upgrade $connection_upgrade {
   ''      close;
 }
 
+upstream backend {
+    server 127.0.0.1:3000 fail_timeout=0;
+}
+
+upstream streaming {
+    server 127.0.0.1:4000 fail_timeout=0;
+}
+
 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
 
 server {
@@ -69,7 +77,7 @@ server {
     proxy_set_header Proxy "";
     proxy_pass_header Server;
 
-    proxy_pass http://127.0.0.1:3000;
+    proxy_pass http://backend;
     proxy_buffering on;
     proxy_redirect off;
     proxy_http_version 1.1;
@@ -93,7 +101,7 @@ server {
     proxy_set_header X-Forwarded-Proto https;
     proxy_set_header Proxy "";
 
-    proxy_pass http://127.0.0.1:4000;
+    proxy_pass http://streaming;
     proxy_buffering off;
     proxy_redirect off;
     proxy_http_version 1.1;
diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/media_cli.rb
index d842b986f..08a8f1093 100644
--- a/lib/mastodon/media_cli.rb
+++ b/lib/mastodon/media_cli.rb
@@ -45,6 +45,7 @@ module Mastodon
     end
 
     option :start_after
+    option :prefix
     option :dry_run, type: :boolean, default: false
     desc 'remove-orphans', 'Scan storage and check for files that do not belong to existing media attachments'
     long_desc <<~LONG_DESC
@@ -58,6 +59,7 @@ module Mastodon
       reclaimed_bytes = 0
       removed         = 0
       dry_run         = options[:dry_run] ? ' (DRY RUN)' : ''
+      prefix          = options[:prefix]
 
       case Paperclip::Attachment.default_options[:storage]
       when :s3
@@ -69,7 +71,7 @@ module Mastodon
         loop do
           objects = begin
             begin
-              bucket.objects(start_after: last_key, prefix: 'media_attachments/files/').limit(1000).map { |x| x }
+              bucket.objects(start_after: last_key, prefix: prefix).limit(1000).map { |x| x }
             rescue => e
               progress.log(pastel.red("Error fetching list of files: #{e}"))
               progress.log("If you want to continue from this point, add --start-after=#{last_key} to your command") if last_key
@@ -79,16 +81,21 @@ module Mastodon
 
           break if objects.empty?
 
-          last_key        = objects.last.key
-          attachments_map = MediaAttachment.where(id: objects.map { |object| object.key.split('/')[2..-2].join.to_i }).each_with_object({}) { |attachment, map| map[attachment.id] = attachment }
+          last_key   = objects.last.key
+          record_map = preload_records_from_mixed_objects(objects)
 
           objects.each do |object|
-            attachment_id = object.key.split('/')[2..-2].join.to_i
-            filename      = object.key.split('/').last
+            path_segments   = object.key.split('/')
+            model_name      = path_segments.first.classify
+            attachment_name = path_segments[1].singularize
+            record_id       = path_segments[2..-2].join.to_i
+            file_name       = path_segments.last
+            record          = record_map.dig(model_name, record_id)
+            attachment      = record&.public_send(attachment_name)
 
             progress.increment
 
-            next unless attachments_map[attachment_id].nil? || !attachments_map[attachment_id].variant?(filename)
+            next unless attachment.blank? || !attachment.variant?(file_name)
 
             begin
               object.delete unless options[:dry_run]
@@ -108,19 +115,26 @@ module Mastodon
       when :filesystem
         require 'find'
 
-        root_path = ENV.fetch('RAILS_ROOT_PATH', File.join(':rails_root', 'public', 'system')).gsub(':rails_root', Rails.root.to_s)
+        root_path = ENV.fetch('PAPERCLIP_ROOT_PATH', File.join(':rails_root', 'public', 'system')).gsub(':rails_root', Rails.root.to_s)
 
-        Find.find(File.join(root_path, 'media_attachments', 'files')) do |path|
+        Find.find(File.join(*[root_path, prefix].compact)) do |path|
           next if File.directory?(path)
 
-          key           = path.gsub("#{root_path}#{File::SEPARATOR}", '')
-          attachment_id = key.split(File::SEPARATOR)[2..-2].join.to_i
-          filename      = key.split(File::SEPARATOR).last
-          attachment    = MediaAttachment.find_by(id: attachment_id)
+          key             = path.gsub("#{root_path}#{File::SEPARATOR}", '')
+          path_segments   = key.split(File::SEPARATOR)
+          model_name      = path_segments.first.classify
+          record_id       = path_segments[2..-2].join.to_i
+          attachment_name = path_segments[1].singularize
+          file_name       = path_segments.last
+
+          next unless PRELOAD_MODEL_WHITELIST.include?(model_name)
+
+          record     = model_name.constantize.find_by(id: record_id)
+          attachment = record&.public_send(attachment_name)
 
           progress.increment
 
-          next unless attachment.nil? || !attachment.variant?(filename)
+          next unless attachment.blank? || !attachment.variant?(file_name)
 
           begin
             size = File.size(path)
@@ -213,25 +227,66 @@ module Mastodon
       say("Settings:\t#{number_to_human_size(SiteUpload.sum(:file_file_size))}")
     end
 
-    desc 'lookup', 'Lookup where media is displayed by passing a media URL'
-    def lookup
-      prompt = TTY::Prompt.new
+    desc 'lookup URL', 'Lookup where media is displayed by passing a media URL'
+    def lookup(url)
+      path          = Addressable::URI.parse(url).path
+      path_segments = path.split('/')[2..-1]
+      model_name    = path_segments.first.classify
+      record_id     = path_segments[2..-2].join.to_i
 
-      url = prompt.ask('Please enter a URL to the media to lookup:', required: true)
+      unless PRELOAD_MODEL_WHITELIST.include?(model_name)
+        say("Cannot find corresponding model: #{model_name}", :red)
+        exit(1)
+      end
 
-      attachment_id = url
-                      .split('/')[0..-2]
-                      .grep(/\A\d+\z/)
-                      .join('')
+      record = model_name.constantize.find_by(id: record_id)
+      record = record.status if record.respond_to?(:status)
 
-      if url.split('/')[0..-2].include? 'media_attachments'
-        model = MediaAttachment.find(attachment_id).status
-        prompt.say(ActivityPub::TagManager.instance.url_for(model))
-      elsif url.split('/')[0..-2].include? 'accounts'
-        model = Account.find(attachment_id)
-        prompt.say(ActivityPub::TagManager.instance.url_for(model))
-      else
-        prompt.say('Not found')
+      unless record
+        say('Cannot find corresponding record', :red)
+        exit(1)
+      end
+
+      display_url = ActivityPub::TagManager.instance.url_for(record)
+
+      if display_url.blank?
+        say('No public URL for this type of record', :red)
+        exit(1)
+      end
+
+      say(display_url, :blue)
+    rescue Addressable::URI::InvalidURIError
+      say('Invalid URL', :red)
+      exit(1)
+    end
+
+    private
+
+    PRELOAD_MODEL_WHITELIST = %w(
+      Account
+      Backup
+      CustomEmoji
+      Import
+      MediaAttachment
+      PreviewCard
+      SiteUpload
+    ).freeze
+
+    def preload_records_from_mixed_objects(objects)
+      preload_map = Hash.new { |hash, key| hash[key] = [] }
+
+      objects.map do |object|
+        segments   = object.key.split('/').first
+        model_name = segments.first.classify
+        record_id  = segments[2..-2].join.to_i
+
+        next unless PRELOAD_MODEL_WHITELIST.include?(model_name)
+
+        preload_map[model_name] << record_id
+      end
+
+      preload_map.each_with_object({}) do |(model_name, record_ids), model_map|
+        model_map[model_name] = model_name.constantize.where(id: record_ids).each_with_object({}) { |record, record_map| record_map[record.id] = record }
       end
     end
   end
diff --git a/lib/mastodon/statuses_cli.rb b/lib/mastodon/statuses_cli.rb
index 875183372..8a18a3b2f 100644
--- a/lib/mastodon/statuses_cli.rb
+++ b/lib/mastodon/statuses_cli.rb
@@ -14,6 +14,7 @@ module Mastodon
 
     option :days, type: :numeric, default: 90
     option :clean_followed, type: :boolean
+    option :skip_media_remove, type: :boolean
     desc 'remove', 'Remove unreferenced statuses'
     long_desc <<~LONG_DESC
       Remove statuses that are not referenced by local user activity, such as
@@ -58,9 +59,10 @@ module Mastodon
 
       scope.in_batches.delete_all
 
-      say('Beginning removal of now-orphaned media attachments to free up disk space...')
-
-      Scheduler::MediaCleanupScheduler.new.perform
+      unless options[:skip_media_remove]
+        say('Beginning removal of now-orphaned media attachments to free up disk space...')
+        Scheduler::MediaCleanupScheduler.new.perform
+      end
 
       say("Done after #{Time.now.to_f - start_at}s", :green)
     ensure
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index 49fe73043..ba78a3c30 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -13,7 +13,7 @@ module Mastodon
     end
 
     def patch
-      2
+      3
     end
 
     def flags
diff --git a/lib/paperclip/attachment_extensions.rb b/lib/paperclip/attachment_extensions.rb
new file mode 100644
index 000000000..d9ec0159a
--- /dev/null
+++ b/lib/paperclip/attachment_extensions.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Paperclip
+  module AttachmentExtensions
+    # We overwrite this method to support delayed processing in
+    # Sidekiq. Since we process the original file to reduce disk
+    # usage, and we still want to generate thumbnails straight
+    # away, it's the only style we need to exclude
+    def process_style?(style_name, style_args)
+      if style_name == :original && instance.respond_to?(:delay_processing?) && instance.delay_processing?
+        false
+      else
+        style_args.empty? || style_args.include?(style_name)
+      end
+    end
+
+    def reprocess_original!
+      old_original_path = path(:original)
+      reprocess!(:original)
+      new_original_path = path(:original)
+
+      if new_original_path != old_original_path
+        @queued_for_delete << old_original_path
+        flush_deletes
+      end
+    end
+
+    def variant?(other_filename)
+      return true  if original_filename == other_filename
+      return false if original_filename.nil?
+
+      formats = styles.values.map(&:format).compact
+
+      return false if formats.empty?
+
+      other_extension = File.extname(other_filename)
+
+      formats.include?(other_extension.delete('.')) && File.basename(other_filename, other_extension) == File.basename(original_filename, File.extname(original_filename))
+    end
+  end
+end
+
+Paperclip::Attachment.prepend(Paperclip::AttachmentExtensions)
diff --git a/lib/paperclip/url_generator_extensions.rb b/lib/paperclip/url_generator_extensions.rb
new file mode 100644
index 000000000..1079efdbc
--- /dev/null
+++ b/lib/paperclip/url_generator_extensions.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Paperclip
+  module UrlGeneratorExtensions
+    # Monkey-patch Paperclip to use Addressable::URI's normalization instead
+    # of the long-deprecated URI.esacpe
+    def escape_url(url)
+      if url.respond_to?(:escape)
+        url.escape
+      else
+        Addressable::URI.parse(url).normalize.to_str.gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
+      end
+    end
+  end
+end
+
+Paperclip::UrlGenerator.prepend(Paperclip::UrlGeneratorExtensions)
diff --git a/lib/paperclip/video_transcoder.rb b/lib/paperclip/video_transcoder.rb
index 66f7feda5..4d9544231 100644
--- a/lib/paperclip/video_transcoder.rb
+++ b/lib/paperclip/video_transcoder.rb
@@ -5,12 +5,22 @@ module Paperclip
   # to check when uploaded videos are actually gifv's
   class VideoTranscoder < Paperclip::Processor
     def make
-      meta = ::Av.cli.identify(@file.path)
+      movie = FFMPEG::Movie.new(@file.path)
 
-      attachment.instance.type = MediaAttachment.types[:gifv] unless meta[:audio_encode]
-      options[:format] = File.extname(attachment.instance.file_file_name)[1..-1] if options[:keep_same_format]
+      attachment.instance.type = MediaAttachment.types[:gifv] unless movie.audio_codec
 
-      Paperclip::Transcoder.make(file, options, attachment)
+      Paperclip::Transcoder.make(file, actual_options(movie), attachment)
+    end
+
+    private
+
+    def actual_options(movie)
+      opts = options[:passthrough_options]
+      if opts && opts[:video_codecs].include?(movie.video_codec) && opts[:audio_codecs].include?(movie.audio_codec) && opts[:colorspaces].include?(movie.colorspace)
+        opts[:options]
+      else
+        options
+      end
     end
   end
 end
diff --git a/package.json b/package.json
index 789baf842..82f918456 100644
--- a/package.json
+++ b/package.json
@@ -60,24 +60,25 @@
   },
   "private": true,
   "dependencies": {
-    "@babel/core": "^7.8.4",
+    "@babel/core": "^7.9.0",
     "@babel/plugin-proposal-class-properties": "^7.8.3",
     "@babel/plugin-proposal-decorators": "^7.8.3",
-    "@babel/plugin-transform-react-inline-elements": "^7.8.3",
-    "@babel/plugin-transform-runtime": "^7.8.3",
-    "@babel/preset-env": "^7.8.3",
-    "@babel/preset-react": "^7.8.3",
-    "@babel/runtime": "^7.8.3",
+    "@babel/plugin-transform-react-inline-elements": "^7.9.0",
+    "@babel/plugin-transform-runtime": "^7.9.0",
+    "@babel/preset-env": "^7.9.0",
+    "@babel/preset-react": "^7.9.4",
+    "@babel/runtime": "^7.8.4",
     "@clusterws/cws": "^0.17.3",
     "@gamestdio/websocket": "^0.3.2",
+    "@rails/ujs": "^6.0.2",
     "array-includes": "^3.1.1",
     "arrow-key-navigation": "^1.1.0",
     "atrament": "0.2.4",
-    "autoprefixer": "^9.7.4",
+    "autoprefixer": "^9.7.5",
     "axios": "^0.19.2",
-    "babel-loader": "^8.0.6",
+    "babel-loader": "^8.1.0",
     "babel-plugin-lodash": "^3.3.4",
-    "babel-plugin-preval": "^4.0.0",
+    "babel-plugin-preval": "^5.0.0",
     "babel-plugin-react-intl": "^3.4.1",
     "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
     "babel-runtime": "^6.26.0",
@@ -85,7 +86,7 @@
     "classnames": "^2.2.5",
     "compression-webpack-plugin": "^3.1.0",
     "copy-webpack-plugin": "^5.1.1",
-    "cross-env": "^6.0.3",
+    "cross-env": "^7.0.2",
     "css-loader": "^3.4.2",
     "cssnano": "^4.1.10",
     "detect-passive-events": "^1.0.2",
@@ -96,7 +97,7 @@
     "exif-js": "^2.3.0",
     "express": "^4.17.1",
     "favico.js": "^0.3.10",
-    "file-loader": "^5.0.2",
+    "file-loader": "^5.1.0",
     "font-awesome": "^4.7.0",
     "glob": "^7.1.6",
     "history": "^4.10.1",
@@ -113,7 +114,7 @@
     "mark-loader": "^0.1.6",
     "marky": "^1.2.1",
     "mini-css-extract-plugin": "^0.9.0",
-    "mkdirp": "^0.5.1",
+    "mkdirp": "^1.0.3",
     "npmlog": "^4.1.2",
     "object-assign": "^4.1.1",
     "object-fit-images": "^3.2.3",
@@ -126,11 +127,10 @@
     "promise.prototype.finally": "^3.1.2",
     "prop-types": "^15.5.10",
     "punycode": "^2.1.0",
-    "rails-ujs": "^5.2.4",
-    "react": "^16.12.0",
-    "react-dom": "^16.12.0",
+    "react": "^16.13.1",
+    "react-dom": "^16.13.0",
     "react-hotkeys": "^1.1.4",
-    "react-immutable-proptypes": "^2.1.0",
+    "react-immutable-proptypes": "^2.2.0",
     "react-immutable-pure-component": "^1.1.1",
     "react-intl": "^2.9.0",
     "react-masonry-infinite": "^1.2.2",
@@ -141,12 +141,12 @@
     "react-redux-loading-bar": "^4.0.8",
     "react-router-dom": "^4.1.1",
     "react-router-scroll-4": "^1.0.0-beta.1",
-    "react-select": "^3.0.8",
+    "react-select": "^3.1.0",
     "react-sparklines": "^1.7.0",
     "react-swipeable-views": "^0.13.9",
     "react-textarea-autosize": "^7.1.2",
     "react-toggle": "^4.1.1",
-    "redis": "^2.7.1",
+    "redis": "^3.0.2",
     "redux": "^4.0.5",
     "redux-immutable": "^4.0.0",
     "redux-thunk": "^2.2.0",
@@ -154,40 +154,43 @@
     "requestidlecallback": "^0.3.0",
     "reselect": "^4.0.0",
     "rimraf": "^3.0.2",
-    "sass": "^1.25.0",
+    "sass": "^1.26.3",
     "sass-loader": "^8.0.2",
     "stacktrace-js": "^2.0.2",
-    "stringz": "^2.0.0",
+    "stringz": "^2.1.0",
     "substring-trie": "^1.0.2",
     "terser-webpack-plugin": "^2.3.5",
     "tesseract.js": "^2.0.0-alpha.16",
     "throng": "^4.0.0",
     "tiny-queue": "^0.2.1",
-    "uuid": "^3.4.0",
+    "uuid": "^7.0.2",
     "wavesurfer.js": "^3.3.1",
-    "webpack": "^4.41.5",
+    "webpack": "^4.42.1",
     "webpack-assets-manifest": "^3.1.1",
-    "webpack-bundle-analyzer": "^3.6.0",
+    "webpack-bundle-analyzer": "^3.6.1",
     "webpack-cli": "^3.3.11",
     "webpack-merge": "^4.2.1",
-    "wicg-inert": "^3.0.0"
+    "wicg-inert": "^3.0.2"
   },
   "devDependencies": {
     "babel-eslint": "^10.0.3",
-    "babel-jest": "^24.9.0",
+    "babel-jest": "^25.2.4",
     "enzyme": "^3.11.0",
     "enzyme-adapter-react-16": "^1.15.2",
     "eslint": "^6.8.0",
     "eslint-plugin-import": "~2.20.1",
     "eslint-plugin-jsx-a11y": "~6.2.3",
     "eslint-plugin-promise": "~4.2.1",
-    "eslint-plugin-react": "~7.17.0",
+    "eslint-plugin-react": "~7.19.0",
     "jest": "^24.9.0",
     "raf": "^3.4.1",
     "react-intl-translations-manager": "^5.0.3",
-    "react-test-renderer": "^16.12.0",
+    "react-test-renderer": "^16.13.0",
     "sass-lint": "^1.13.1",
-    "webpack-dev-server": "^3.10.1",
-    "yargs": "^15.1.0"
+    "webpack-dev-server": "^3.10.3",
+    "yargs": "^15.3.1"
+  },
+  "resolutions": {
+    "kind-of": "^6.0.3"
   }
 }
diff --git a/spec/controllers/account_follow_controller_spec.rb b/spec/controllers/account_follow_controller_spec.rb
index ac15499be..9a93e1ebe 100644
--- a/spec/controllers/account_follow_controller_spec.rb
+++ b/spec/controllers/account_follow_controller_spec.rb
@@ -25,7 +25,7 @@ describe AccountFollowController do
       sign_in(user)
       subject
 
-      expect(service).to have_received(:call).with(user.account, 'alice')
+      expect(service).to have_received(:call).with(user.account, alice, with_rate_limit: true)
       expect(response).to redirect_to(account_path(alice))
     end
   end
diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb
index b428299ee..49d3e9707 100644
--- a/spec/controllers/admin/reports_controller_spec.rb
+++ b/spec/controllers/admin/reports_controller_spec.rb
@@ -46,6 +46,26 @@ describe Admin::ReportsController do
     end
   end
 
+  describe 'POST #resolve' do
+    it 'resolves the report' do
+      report = Fabricate(:report)
+
+      put :resolve, params: { id: report }
+      expect(response).to redirect_to(admin_reports_path)
+      report.reload
+      expect(report.action_taken_by_account).to eq user.account
+      expect(report.action_taken).to eq true
+    end
+
+    it 'sets trust level when the report is an antispam one' do
+      report = Fabricate(:report, account: Account.representative)
+
+      put :resolve, params: { id: report }
+      report.reload
+      expect(report.target_account.trust_level).to eq Account::TRUST_LEVELS[:trusted]
+    end
+  end
+
   describe 'POST #reopen' do
     it 'reopens the report' do
       report = Fabricate(:report)
diff --git a/spec/controllers/api/v1/statuses_controller_spec.rb b/spec/controllers/api/v1/statuses_controller_spec.rb
index 9ff5fcd3b..df8037038 100644
--- a/spec/controllers/api/v1/statuses_controller_spec.rb
+++ b/spec/controllers/api/v1/statuses_controller_spec.rb
@@ -39,12 +39,50 @@ RSpec.describe Api::V1::StatusesController, type: :controller do
     describe 'POST #create' do
       let(:scopes) { 'write:statuses' }
 
-      before do
-        post :create, params: { status: 'Hello world' }
+      context do
+        before do
+          post :create, params: { status: 'Hello world' }
+        end
+
+        it 'returns http success' do
+          expect(response).to have_http_status(200)
+        end
+
+        it 'returns rate limit headers' do
+          expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
+          expect(response.headers['X-RateLimit-Remaining']).to eq (RateLimiter::FAMILIES[:statuses][:limit] - 1).to_s
+        end
       end
 
-      it 'returns http success' do
-        expect(response).to have_http_status(200)
+      context 'with missing parameters' do
+        before do
+          post :create, params: {}
+        end
+
+        it 'returns http unprocessable entity' do
+          expect(response).to have_http_status(422)
+        end
+
+        it 'returns rate limit headers' do
+          expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
+        end
+      end
+
+      context 'when exceeding rate limit' do
+        before do
+          rate_limiter = RateLimiter.new(user.account, family: :statuses)
+          300.times { rate_limiter.record! }
+          post :create, params: { status: 'Hello world' }
+        end
+
+        it 'returns http too many requests' do
+          expect(response).to have_http_status(429)
+        end
+
+        it 'returns rate limit headers' do
+          expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
+          expect(response.headers['X-RateLimit-Remaining']).to eq '0'
+        end
       end
     end
 
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 3202167ca..b6de3e9d1 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -39,7 +39,7 @@ feature 'Profile' do
     visit settings_profile_path
     fill_in 'Display name', with: 'Bob'
     fill_in 'Bio', with: 'Bob is silent'
-    click_on 'Save changes'
+    first('.btn[type=submit]').click
     is_expected.to have_content 'Changes successfully saved!'
 
     # View my own public profile and see the changes
diff --git a/spec/helpers/admin/action_log_helper_spec.rb b/spec/helpers/admin/action_log_helper_spec.rb
index d7af6b939..60f5ecdcc 100644
--- a/spec/helpers/admin/action_log_helper_spec.rb
+++ b/spec/helpers/admin/action_log_helper_spec.rb
@@ -31,242 +31,4 @@ RSpec.describe Admin::ActionLogsHelper, type: :helper do
       end
     end
   end
-
-  describe '#relevant_log_changes' do
-    let(:log) { double(target_type: target_type, action: log_action, recorded_changes: recorded_changes) }
-    let(:recorded_changes) { double }
-
-    after do
-      hoge.relevant_log_changes(log)
-    end
-
-    context "log.target_type == 'CustomEmoji' && [:enable, :disable, :destroy].include?(log.action)" do
-      let(:target_type) { 'CustomEmoji' }
-      let(:log_action)  { :enable }
-
-      it "calls log.recorded_changes.slice('domain')" do
-        expect(recorded_changes).to receive(:slice).with('domain')
-      end
-    end
-
-    context "log.target_type == 'CustomEmoji' && log.action == :update" do
-      let(:target_type) { 'CustomEmoji' }
-      let(:log_action)  { :update }
-
-      it "calls log.recorded_changes.slice('domain', 'visible_in_picker')" do
-        expect(recorded_changes).to receive(:slice).with('domain', 'visible_in_picker')
-      end
-    end
-
-    context "log.target_type == 'User' && [:promote, :demote].include?(log.action)" do
-      let(:target_type) { 'User' }
-      let(:log_action)  { :promote }
-
-      it "calls log.recorded_changes.slice('moderator', 'admin')" do
-        expect(recorded_changes).to receive(:slice).with('moderator', 'admin')
-      end
-    end
-
-    context "log.target_type == 'User' && [:change_email].include?(log.action)" do
-      let(:target_type) { 'User' }
-      let(:log_action)  { :change_email }
-
-      it "calls log.recorded_changes.slice('email', 'unconfirmed_email')" do
-        expect(recorded_changes).to receive(:slice).with('email', 'unconfirmed_email')
-      end
-    end
-
-    context "log.target_type == 'DomainBlock'" do
-      let(:target_type) { 'DomainBlock' }
-      let(:log_action)  { nil }
-
-      it "calls log.recorded_changes.slice('severity', 'reject_media')" do
-        expect(recorded_changes).to receive(:slice).with('severity', 'reject_media')
-      end
-    end
-
-    context "log.target_type == 'Status' && log.action == :update" do
-      let(:target_type) { 'Status' }
-      let(:log_action)  { :update }
-
-      it "log.recorded_changes.slice('sensitive')" do
-        expect(recorded_changes).to receive(:slice).with('sensitive')
-      end
-    end
-  end
-
-  describe '#log_extra_attributes' do
-    after do
-      hoge.log_extra_attributes(hoge: 'hoge')
-    end
-
-    it "calls content_tag(:span, key, class: 'diff-key')" do
-      allow(hoge).to receive(:log_change).with(anything)
-      expect(hoge).to receive(:content_tag).with(:span, :hoge, class: 'diff-key')
-    end
-
-    it 'calls safe_join twice' do
-      expect(hoge).to receive(:safe_join).with(
-        ['<span class="diff-key">hoge</span>',
-         '=',
-         '<span class="diff-neutral">hoge</span>']
-      )
-
-      expect(hoge).to receive(:safe_join).with([nil], ' ')
-    end
-  end
-
-  describe '#log_change' do
-    after do
-      hoge.log_change(val)
-    end
-
-    context '!val.is_a?(Array)' do
-      let(:val) { 'hoge' }
-
-      it "calls content_tag(:span, val, class: 'diff-neutral')" do
-        expect(hoge).to receive(:content_tag).with(:span, val, class: 'diff-neutral')
-      end
-    end
-
-    context 'val.is_a?(Array)' do
-      let(:val) { %w(foo bar) }
-
-      it 'calls #content_tag twice and #safe_join' do
-        expect(hoge).to receive(:content_tag).with(:span, 'foo', class: 'diff-old')
-        expect(hoge).to receive(:content_tag).with(:span, 'bar', class: 'diff-new')
-        expect(hoge).to receive(:safe_join).with([nil, nil], '→')
-      end
-    end
-  end
-
-  describe '#icon_for_log' do
-    subject   { hoge.icon_for_log(log) }
-
-    context "log.target_type == 'Account'" do
-      let(:log) { double(target_type: 'Account') }
-
-      it 'returns "user"' do
-        expect(subject).to be 'user'
-      end
-    end
-
-    context "log.target_type == 'User'" do
-      let(:log) { double(target_type: 'User') }
-
-      it 'returns "user"' do
-        expect(subject).to be 'user'
-      end
-    end
-
-    context "log.target_type == 'CustomEmoji'" do
-      let(:log) { double(target_type: 'CustomEmoji') }
-
-      it 'returns "file"' do
-        expect(subject).to be 'file'
-      end
-    end
-
-    context "log.target_type == 'Report'" do
-      let(:log) { double(target_type: 'Report') }
-
-      it 'returns "flag"' do
-        expect(subject).to be 'flag'
-      end
-    end
-
-    context "log.target_type == 'DomainBlock'" do
-      let(:log) { double(target_type: 'DomainBlock') }
-
-      it 'returns "lock"' do
-        expect(subject).to be 'lock'
-      end
-    end
-
-    context "log.target_type == 'EmailDomainBlock'" do
-      let(:log) { double(target_type: 'EmailDomainBlock') }
-
-      it 'returns "envelope"' do
-        expect(subject).to be 'envelope'
-      end
-    end
-
-    context "log.target_type == 'Status'" do
-      let(:log) { double(target_type: 'Status') }
-
-      it 'returns "pencil"' do
-        expect(subject).to be 'pencil'
-      end
-    end
-  end
-
-  describe '#class_for_log_icon' do
-    subject   { hoge.class_for_log_icon(log) }
-
-    %i(enable unsuspend unsilence confirm promote resolve).each do |action|
-      context "log.action == #{action}" do
-        let(:log) { double(action: action) }
-
-        it 'returns "positive"' do
-          expect(subject).to be 'positive'
-        end
-      end
-    end
-
-    context 'log.action == :create' do
-      context 'opposite_verbs?(log)' do
-        let(:log) { double(action: :create, target_type: 'DomainBlock') }
-
-        it 'returns "negative"' do
-          expect(subject).to be 'negative'
-        end
-      end
-
-      context '!opposite_verbs?(log)' do
-        let(:log) { double(action: :create, target_type: '') }
-
-        it 'returns "positive"' do
-          expect(subject).to be 'positive'
-        end
-      end
-    end
-
-    %i(update reset_password disable_2fa memorialize change_email).each do |action|
-      context "log.action == #{action}" do
-        let(:log) { double(action: action) }
-
-        it 'returns "neutral"' do
-          expect(subject).to be 'neutral'
-        end
-      end
-    end
-
-    %i(demote silence disable suspend remove_avatar remove_header reopen).each do |action|
-      context "log.action == #{action}" do
-        let(:log) { double(action: action) }
-
-        it 'returns "negative"' do
-          expect(subject).to be 'negative'
-        end
-      end
-    end
-
-    context 'log.action == :destroy' do
-      context 'opposite_verbs?(log)' do
-        let(:log) { double(action: :destroy, target_type: 'DomainBlock') }
-
-        it 'returns "positive"' do
-          expect(subject).to be 'positive'
-        end
-      end
-
-      context '!opposite_verbs?(log)' do
-        let(:log) { double(action: :destroy, target_type: '') }
-
-        it 'returns "negative"' do
-          expect(subject).to be 'negative'
-        end
-      end
-    end
-  end
 end
diff --git a/spec/lib/sanitize_config_spec.rb b/spec/lib/sanitize_config_spec.rb
index 50558a0d8..7370c536b 100644
--- a/spec/lib/sanitize_config_spec.rb
+++ b/spec/lib/sanitize_config_spec.rb
@@ -7,6 +7,12 @@ describe Sanitize::Config do
   describe '::MASTODON_STRICT' do
     subject { Sanitize::Config::MASTODON_STRICT }
 
+    around do |example|
+      original_web_domain = Rails.configuration.x.web_domain
+      example.run
+      Rails.configuration.x.web_domain = original_web_domain
+    end
+
     it 'keeps h1' do
       expect(Sanitize.fragment('<h1>Foo</h1>', subject)).to eq '<h1>Foo</h1>'
     end
@@ -28,7 +34,16 @@ describe Sanitize::Config do
     end
 
     it 'keeps a with href' do
-      expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener tag noreferrer" target="_blank">Test</a>'
+      expect(Sanitize.fragment('<a href="http://example.com">Test</a>', subject)).to eq '<a href="http://example.com" rel="nofollow noopener noreferrer" target="_blank">Test</a>'
+    end
+
+    it 'keeps a with href and rel tag' do
+      expect(Sanitize.fragment('<a href="http://example.com" rel="tag">Test</a>', subject)).to eq '<a href="http://example.com" rel="tag nofollow noopener noreferrer" target="_blank">Test</a>'
+    end
+
+    it 'keeps a with href and rel tag, not adding to rel if url is local' do
+      Rails.configuration.x.web_domain = 'domain.test'
+      expect(Sanitize.fragment('<a href="http://domain.test/tags/foo" rel="tag">Test</a>', subject.merge(outgoing: true))).to eq '<a href="http://domain.test/tags/foo" rel="tag" target="_blank">Test</a>'
     end
   end
 end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 6fbceca53..40ddf1f95 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -15,7 +15,7 @@ ActiveRecord::Migration.maintain_test_schema!
 WebMock.disable_net_connect!(allow: Chewy.settings[:host])
 Redis.current = Redis::Namespace.new("mastodon_test#{ENV['TEST_ENV_NUMBER']}", redis: Redis.current)
 Sidekiq::Testing.inline!
-Sidekiq::Logging.logger = nil
+Sidekiq.logger = nil
 
 Devise::Test::ControllerHelpers.module_eval do
   alias_method :original_sign_in, :sign_in
diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb
index 5355133f4..7618e9076 100644
--- a/spec/services/import_service_spec.rb
+++ b/spec/services/import_service_spec.rb
@@ -91,10 +91,6 @@ RSpec.describe ImportService, type: :service do
 
     let(:csv) { attachment_fixture('mute-imports.txt') }
 
-    before do
-      allow(NotificationWorker).to receive(:perform_async)
-    end
-
     describe 'when no accounts are followed' do
       let(:import) { Import.create(account: account, type: 'following', data: csv) }
       it 'follows the listed accounts, including boosts' do
@@ -135,10 +131,6 @@ RSpec.describe ImportService, type: :service do
 
     let(:csv) { attachment_fixture('new-following-imports.txt') }
 
-    before do
-      allow(NotificationWorker).to receive(:perform_async)
-    end
-
     describe 'when no accounts are followed' do
       let(:import) { Import.create(account: account, type: 'following', data: csv) }
       it 'follows the listed accounts, respecting boosts' do
diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb
index 025a3da40..147a59fc3 100644
--- a/spec/services/post_status_service_spec.rb
+++ b/spec/services/post_status_service_spec.rb
@@ -79,6 +79,13 @@ RSpec.describe PostStatusService, type: :service do
     expect(status.spoiler_text).to eq spoiler_text
   end
 
+  it 'creates a sensitive status when there is a CW but no text' do
+    status = subject.call(Fabricate(:account), text: '', spoiler_text: 'foo')
+
+    expect(status).to be_persisted
+    expect(status).to be_sensitive
+  end
+
   it 'creates a status with empty default spoiler text' do
     status = create_status_with_options(spoiler_text: nil)
 
diff --git a/yarn.lock b/yarn.lock
index ceea5e811..98ce194be 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9,42 +9,43 @@
   dependencies:
     "@babel/highlight" "^7.8.3"
 
-"@babel/compat-data@^7.8.0", "@babel/compat-data@^7.8.1":
-  version "7.8.1"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.8.1.tgz#fc0bbbb7991e4fb2b47e168e60f2cc2c41680be9"
-  integrity sha512-Z+6ZOXvyOWYxJ50BwxzdhRnRsGST8Y3jaZgxYig575lTjVSs3KtJnmESwZegg6e2Dn0td1eDhoWlp1wI4BTCPw==
+"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c"
+  integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==
   dependencies:
-    browserslist "^4.8.2"
+    browserslist "^4.9.1"
     invariant "^2.2.4"
     semver "^5.5.0"
 
-"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.8.4":
-  version "7.8.4"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e"
-  integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==
+"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.5", "@babel/core@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e"
+  integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==
   dependencies:
     "@babel/code-frame" "^7.8.3"
-    "@babel/generator" "^7.8.4"
-    "@babel/helpers" "^7.8.4"
-    "@babel/parser" "^7.8.4"
-    "@babel/template" "^7.8.3"
-    "@babel/traverse" "^7.8.4"
-    "@babel/types" "^7.8.3"
+    "@babel/generator" "^7.9.0"
+    "@babel/helper-module-transforms" "^7.9.0"
+    "@babel/helpers" "^7.9.0"
+    "@babel/parser" "^7.9.0"
+    "@babel/template" "^7.8.6"
+    "@babel/traverse" "^7.9.0"
+    "@babel/types" "^7.9.0"
     convert-source-map "^1.7.0"
     debug "^4.1.0"
     gensync "^1.0.0-beta.1"
-    json5 "^2.1.0"
+    json5 "^2.1.2"
     lodash "^4.17.13"
     resolve "^1.3.2"
     semver "^5.4.1"
     source-map "^0.5.0"
 
-"@babel/generator@^7.0.0", "@babel/generator@^7.8.4":
-  version "7.8.4"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e"
-  integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==
+"@babel/generator@^7.0.0", "@babel/generator@^7.9.0":
+  version "7.9.3"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.3.tgz#7c8b2956c6f68b3ab732bd16305916fbba521d94"
+  integrity sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==
   dependencies:
-    "@babel/types" "^7.8.3"
+    "@babel/types" "^7.9.0"
     jsesc "^2.5.1"
     lodash "^4.17.13"
     source-map "^0.5.0"
@@ -64,32 +65,32 @@
     "@babel/helper-explode-assignable-expression" "^7.8.3"
     "@babel/types" "^7.8.3"
 
-"@babel/helper-builder-react-jsx@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz#dee98d7d79cc1f003d80b76fe01c7f8945665ff6"
-  integrity sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==
+"@babel/helper-builder-react-jsx-experimental@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.0.tgz#066d80262ade488f9c1b1823ce5db88a4cedaa43"
+  integrity sha512-3xJEiyuYU4Q/Ar9BsHisgdxZsRlsShMe90URZ0e6przL26CCs8NJbDoxH94kKT17PcxlMhsCAwZd90evCo26VQ==
   dependencies:
-    "@babel/types" "^7.8.3"
-    esutils "^2.0.0"
+    "@babel/helper-annotate-as-pure" "^7.8.3"
+    "@babel/helper-module-imports" "^7.8.3"
+    "@babel/types" "^7.9.0"
 
-"@babel/helper-call-delegate@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz#de82619898aa605d409c42be6ffb8d7204579692"
-  integrity sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==
+"@babel/helper-builder-react-jsx@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz#16bf391990b57732700a3278d4d9a81231ea8d32"
+  integrity sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==
   dependencies:
-    "@babel/helper-hoist-variables" "^7.8.3"
-    "@babel/traverse" "^7.8.3"
-    "@babel/types" "^7.8.3"
+    "@babel/helper-annotate-as-pure" "^7.8.3"
+    "@babel/types" "^7.9.0"
 
-"@babel/helper-compilation-targets@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.3.tgz#2deedc816fd41dca7355ef39fd40c9ea69f0719a"
-  integrity sha512-JLylPCsFjhLN+6uBSSh3iYdxKdeO9MNmoY96PE/99d8kyBFaXLORtAVhqN6iHa+wtPeqxKLghDOZry0+Aiw9Tw==
+"@babel/helper-compilation-targets@^7.8.7":
+  version "7.8.7"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde"
+  integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==
   dependencies:
-    "@babel/compat-data" "^7.8.1"
-    browserslist "^4.8.2"
+    "@babel/compat-data" "^7.8.6"
+    browserslist "^4.9.1"
     invariant "^2.2.4"
-    levenary "^1.1.0"
+    levenary "^1.1.1"
     semver "^5.5.0"
 
 "@babel/helper-create-class-features-plugin@^7.8.3":
@@ -112,6 +113,15 @@
     "@babel/helper-regex" "^7.8.3"
     regexpu-core "^4.6.0"
 
+"@babel/helper-create-regexp-features-plugin@^7.8.8":
+  version "7.8.8"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087"
+  integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.8.3"
+    "@babel/helper-regex" "^7.8.3"
+    regexpu-core "^4.7.0"
+
 "@babel/helper-define-map@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15"
@@ -166,16 +176,17 @@
   dependencies:
     "@babel/types" "^7.8.3"
 
-"@babel/helper-module-transforms@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz#d305e35d02bee720fbc2c3c3623aa0c316c01590"
-  integrity sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==
+"@babel/helper-module-transforms@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5"
+  integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==
   dependencies:
     "@babel/helper-module-imports" "^7.8.3"
+    "@babel/helper-replace-supers" "^7.8.6"
     "@babel/helper-simple-access" "^7.8.3"
     "@babel/helper-split-export-declaration" "^7.8.3"
-    "@babel/template" "^7.8.3"
-    "@babel/types" "^7.8.3"
+    "@babel/template" "^7.8.6"
+    "@babel/types" "^7.9.0"
     lodash "^4.17.13"
 
 "@babel/helper-optimise-call-expression@^7.8.3":
@@ -218,6 +229,16 @@
     "@babel/traverse" "^7.8.3"
     "@babel/types" "^7.8.3"
 
+"@babel/helper-replace-supers@^7.8.6":
+  version "7.8.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8"
+  integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==
+  dependencies:
+    "@babel/helper-member-expression-to-functions" "^7.8.3"
+    "@babel/helper-optimise-call-expression" "^7.8.3"
+    "@babel/traverse" "^7.8.6"
+    "@babel/types" "^7.8.6"
+
 "@babel/helper-simple-access@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae"
@@ -233,6 +254,11 @@
   dependencies:
     "@babel/types" "^7.8.3"
 
+"@babel/helper-validator-identifier@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed"
+  integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==
+
 "@babel/helper-wrap-function@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610"
@@ -243,14 +269,14 @@
     "@babel/traverse" "^7.8.3"
     "@babel/types" "^7.8.3"
 
-"@babel/helpers@^7.8.4":
-  version "7.8.4"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73"
-  integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==
+"@babel/helpers@^7.9.0":
+  version "7.9.2"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f"
+  integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==
   dependencies:
     "@babel/template" "^7.8.3"
-    "@babel/traverse" "^7.8.4"
-    "@babel/types" "^7.8.3"
+    "@babel/traverse" "^7.9.0"
+    "@babel/types" "^7.9.0"
 
 "@babel/highlight@^7.8.3":
   version "7.8.3"
@@ -261,10 +287,10 @@
     esutils "^2.0.2"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4":
-  version "7.8.4"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8"
-  integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==
+"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0":
+  version "7.9.3"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.3.tgz#043a5fc2ad8b7ea9facddc4e802a1f0f25da7255"
+  integrity sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==
 
 "@babel/plugin-proposal-async-generator-functions@^7.8.3":
   version "7.8.3"
@@ -316,10 +342,18 @@
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
 
-"@babel/plugin-proposal-object-rest-spread@^7.8.3":
+"@babel/plugin-proposal-numeric-separator@^7.8.3":
   version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb"
-  integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8"
+  integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.8.3"
+    "@babel/plugin-syntax-numeric-separator" "^7.8.3"
+
+"@babel/plugin-proposal-object-rest-spread@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz#a28993699fc13df165995362693962ba6b061d6f"
+  integrity sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-object-rest-spread" "^7.8.0"
@@ -332,20 +366,20 @@
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
 
-"@babel/plugin-proposal-optional-chaining@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz#ae10b3214cb25f7adb1f3bc87ba42ca10b7e2543"
-  integrity sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==
+"@babel/plugin-proposal-optional-chaining@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58"
+  integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-optional-chaining" "^7.8.0"
 
-"@babel/plugin-proposal-unicode-property-regex@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz#b646c3adea5f98800c9ab45105ac34d06cd4a47f"
-  integrity sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==
+"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3":
+  version "7.8.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d"
+  integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==
   dependencies:
-    "@babel/helper-create-regexp-features-plugin" "^7.8.3"
+    "@babel/helper-create-regexp-features-plugin" "^7.8.8"
     "@babel/helper-plugin-utils" "^7.8.3"
 
 "@babel/plugin-syntax-async-generators@^7.8.0":
@@ -355,6 +389,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
+"@babel/plugin-syntax-bigint@^7.0.0":
+  version "7.8.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea"
+  integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.8.0"
+
 "@babel/plugin-syntax-decorators@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz#8d2c15a9f1af624b0025f961682a9d53d3001bda"
@@ -390,6 +431,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.0"
 
+"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3":
+  version "7.8.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f"
+  integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.8.3"
+
 "@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
@@ -449,17 +497,17 @@
     "@babel/helper-plugin-utils" "^7.8.3"
     lodash "^4.17.13"
 
-"@babel/plugin-transform-classes@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz#46fd7a9d2bb9ea89ce88720477979fe0d71b21b8"
-  integrity sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==
+"@babel/plugin-transform-classes@^7.9.0":
+  version "7.9.2"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz#8603fc3cc449e31fdbdbc257f67717536a11af8d"
+  integrity sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==
   dependencies:
     "@babel/helper-annotate-as-pure" "^7.8.3"
     "@babel/helper-define-map" "^7.8.3"
     "@babel/helper-function-name" "^7.8.3"
     "@babel/helper-optimise-call-expression" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
-    "@babel/helper-replace-supers" "^7.8.3"
+    "@babel/helper-replace-supers" "^7.8.6"
     "@babel/helper-split-export-declaration" "^7.8.3"
     globals "^11.1.0"
 
@@ -477,7 +525,7 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-dotall-regex@^7.8.3":
+"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3":
   version "7.8.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e"
   integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==
@@ -500,10 +548,10 @@
     "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-for-of@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.3.tgz#15f17bce2fc95c7d59a24b299e83e81cedc22e18"
-  integrity sha512-ZjXznLNTxhpf4Q5q3x1NsngzGA38t9naWH8Gt+0qYZEJAcvPI9waSStSh56u19Ofjr7QmD0wUsQ8hw8s/p1VnA==
+"@babel/plugin-transform-for-of@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e"
+  integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
@@ -529,41 +577,41 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-modules-amd@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz#65606d44616b50225e76f5578f33c568a0b876a5"
-  integrity sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==
+"@babel/plugin-transform-modules-amd@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4"
+  integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==
   dependencies:
-    "@babel/helper-module-transforms" "^7.8.3"
+    "@babel/helper-module-transforms" "^7.9.0"
     "@babel/helper-plugin-utils" "^7.8.3"
     babel-plugin-dynamic-import-node "^2.3.0"
 
-"@babel/plugin-transform-modules-commonjs@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz#df251706ec331bd058a34bdd72613915f82928a5"
-  integrity sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==
+"@babel/plugin-transform-modules-commonjs@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940"
+  integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==
   dependencies:
-    "@babel/helper-module-transforms" "^7.8.3"
+    "@babel/helper-module-transforms" "^7.9.0"
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/helper-simple-access" "^7.8.3"
     babel-plugin-dynamic-import-node "^2.3.0"
 
-"@babel/plugin-transform-modules-systemjs@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz#d8bbf222c1dbe3661f440f2f00c16e9bb7d0d420"
-  integrity sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==
+"@babel/plugin-transform-modules-systemjs@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90"
+  integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==
   dependencies:
     "@babel/helper-hoist-variables" "^7.8.3"
-    "@babel/helper-module-transforms" "^7.8.3"
+    "@babel/helper-module-transforms" "^7.9.0"
     "@babel/helper-plugin-utils" "^7.8.3"
     babel-plugin-dynamic-import-node "^2.3.0"
 
-"@babel/plugin-transform-modules-umd@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz#592d578ce06c52f5b98b02f913d653ffe972661a"
-  integrity sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==
+"@babel/plugin-transform-modules-umd@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697"
+  integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==
   dependencies:
-    "@babel/helper-module-transforms" "^7.8.3"
+    "@babel/helper-module-transforms" "^7.9.0"
     "@babel/helper-plugin-utils" "^7.8.3"
 
 "@babel/plugin-transform-named-capturing-groups-regex@^7.8.3":
@@ -588,12 +636,11 @@
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/helper-replace-supers" "^7.8.3"
 
-"@babel/plugin-transform-parameters@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.3.tgz#7890576a13b17325d8b7d44cb37f21dc3bbdda59"
-  integrity sha512-/pqngtGb54JwMBZ6S/D3XYylQDFtGjWrnoCF4gXZOUpFV/ujbxnoNGNvDGu6doFWRPBveE72qTx/RRU44j5I/Q==
+"@babel/plugin-transform-parameters@^7.8.7":
+  version "7.9.3"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz#3028d0cc20ddc733166c6e9c8534559cee09f54a"
+  integrity sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==
   dependencies:
-    "@babel/helper-call-delegate" "^7.8.3"
     "@babel/helper-get-function-arity" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
 
@@ -611,45 +658,55 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-react-inline-elements@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.8.3.tgz#fc234d02a35bb188ee3f933d068824e067e42b23"
-  integrity sha512-CGKUlW3vtgk6YYrIMyfpohmmpILnaeFwszqwTIcem2LQkK1qWJj5w2yTZ7LJr2IR8F0XQ60AZoM8jgAB4zpxCg==
+"@babel/plugin-transform-react-inline-elements@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.9.0.tgz#19a39843431803765c9976132198bd8dee3d8058"
+  integrity sha512-iqqKXtOfVZpbgJ+9D4TG+JO/vgxa29FlpPUSIATzIcopKMUd3/bdwIjrrEneNp+SeiJs74nqKfUFYAUPDEu/qw==
   dependencies:
-    "@babel/helper-builder-react-jsx" "^7.8.3"
+    "@babel/helper-builder-react-jsx" "^7.9.0"
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-react-jsx-self@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.8.3.tgz#c4f178b2aa588ecfa8d077ea80d4194ee77ed702"
-  integrity sha512-01OT7s5oa0XTLf2I8XGsL8+KqV9lx3EZV+jxn/L2LQ97CGKila2YMroTkCEIE0HV/FF7CMSRsIAybopdN9NTdg==
+"@babel/plugin-transform-react-jsx-development@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz#3c2a130727caf00c2a293f0aed24520825dbf754"
+  integrity sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw==
   dependencies:
+    "@babel/helper-builder-react-jsx-experimental" "^7.9.0"
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-jsx" "^7.8.3"
 
-"@babel/plugin-transform-react-jsx-source@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.8.3.tgz#951e75a8af47f9f120db731be095d2b2c34920e0"
-  integrity sha512-PLMgdMGuVDtRS/SzjNEQYUT8f4z1xb2BAT54vM1X5efkVuYBf5WyGUMbpmARcfq3NaglIwz08UVQK4HHHbC6ag==
+"@babel/plugin-transform-react-jsx-self@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.9.0.tgz#f4f26a325820205239bb915bad8e06fcadabb49b"
+  integrity sha512-K2ObbWPKT7KUTAoyjCsFilOkEgMvFG+y0FqOl6Lezd0/13kMkkjHskVsZvblRPj1PHA44PrToaZANrryppzTvQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-jsx" "^7.8.3"
 
-"@babel/plugin-transform-react-jsx@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz#4220349c0390fdefa505365f68c103562ab2fc4a"
-  integrity sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==
+"@babel/plugin-transform-react-jsx-source@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz#89ef93025240dd5d17d3122294a093e5e0183de0"
+  integrity sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw==
   dependencies:
-    "@babel/helper-builder-react-jsx" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-syntax-jsx" "^7.8.3"
 
-"@babel/plugin-transform-regenerator@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz#b31031e8059c07495bf23614c97f3d9698bc6ec8"
-  integrity sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==
+"@babel/plugin-transform-react-jsx@^7.9.4":
+  version "7.9.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz#86f576c8540bd06d0e95e0b61ea76d55f6cbd03f"
+  integrity sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==
   dependencies:
-    regenerator-transform "^0.14.0"
+    "@babel/helper-builder-react-jsx" "^7.9.0"
+    "@babel/helper-builder-react-jsx-experimental" "^7.9.0"
+    "@babel/helper-plugin-utils" "^7.8.3"
+    "@babel/plugin-syntax-jsx" "^7.8.3"
+
+"@babel/plugin-transform-regenerator@^7.8.7":
+  version "7.8.7"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8"
+  integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==
+  dependencies:
+    regenerator-transform "^0.14.2"
 
 "@babel/plugin-transform-reserved-words@^7.8.3":
   version "7.8.3"
@@ -658,10 +715,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-runtime@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz#c0153bc0a5375ebc1f1591cb7eea223adea9f169"
-  integrity sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ==
+"@babel/plugin-transform-runtime@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b"
+  integrity sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==
   dependencies:
     "@babel/helper-module-imports" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
@@ -698,10 +755,10 @@
     "@babel/helper-annotate-as-pure" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/plugin-transform-typeof-symbol@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.3.tgz#5cffb216fb25c8c64ba6bf5f76ce49d3ab079f4d"
-  integrity sha512-3TrkKd4LPqm4jHs6nPtSDI/SV9Cm5PRJkHLUgTcqRQQTMAZ44ZaAdDZJtvWFSaRcvT0a1rTmJ5ZA5tDKjleF3g==
+"@babel/plugin-transform-typeof-symbol@^7.8.4":
+  version "7.8.4"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412"
+  integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
 
@@ -713,27 +770,29 @@
     "@babel/helper-create-regexp-features-plugin" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
 
-"@babel/preset-env@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.8.3.tgz#dc0fb2938f52bbddd79b3c861a4b3427dd3a6c54"
-  integrity sha512-Rs4RPL2KjSLSE2mWAx5/iCH+GC1ikKdxPrhnRS6PfFVaiZeom22VFKN4X8ZthyN61kAaR05tfXTbCvatl9WIQg==
+"@babel/preset-env@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8"
+  integrity sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==
   dependencies:
-    "@babel/compat-data" "^7.8.0"
-    "@babel/helper-compilation-targets" "^7.8.3"
+    "@babel/compat-data" "^7.9.0"
+    "@babel/helper-compilation-targets" "^7.8.7"
     "@babel/helper-module-imports" "^7.8.3"
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-proposal-async-generator-functions" "^7.8.3"
     "@babel/plugin-proposal-dynamic-import" "^7.8.3"
     "@babel/plugin-proposal-json-strings" "^7.8.3"
     "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3"
-    "@babel/plugin-proposal-object-rest-spread" "^7.8.3"
+    "@babel/plugin-proposal-numeric-separator" "^7.8.3"
+    "@babel/plugin-proposal-object-rest-spread" "^7.9.0"
     "@babel/plugin-proposal-optional-catch-binding" "^7.8.3"
-    "@babel/plugin-proposal-optional-chaining" "^7.8.3"
+    "@babel/plugin-proposal-optional-chaining" "^7.9.0"
     "@babel/plugin-proposal-unicode-property-regex" "^7.8.3"
     "@babel/plugin-syntax-async-generators" "^7.8.0"
     "@babel/plugin-syntax-dynamic-import" "^7.8.0"
     "@babel/plugin-syntax-json-strings" "^7.8.0"
     "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
+    "@babel/plugin-syntax-numeric-separator" "^7.8.0"
     "@babel/plugin-syntax-object-rest-spread" "^7.8.0"
     "@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
     "@babel/plugin-syntax-optional-chaining" "^7.8.0"
@@ -742,50 +801,71 @@
     "@babel/plugin-transform-async-to-generator" "^7.8.3"
     "@babel/plugin-transform-block-scoped-functions" "^7.8.3"
     "@babel/plugin-transform-block-scoping" "^7.8.3"
-    "@babel/plugin-transform-classes" "^7.8.3"
+    "@babel/plugin-transform-classes" "^7.9.0"
     "@babel/plugin-transform-computed-properties" "^7.8.3"
     "@babel/plugin-transform-destructuring" "^7.8.3"
     "@babel/plugin-transform-dotall-regex" "^7.8.3"
     "@babel/plugin-transform-duplicate-keys" "^7.8.3"
     "@babel/plugin-transform-exponentiation-operator" "^7.8.3"
-    "@babel/plugin-transform-for-of" "^7.8.3"
+    "@babel/plugin-transform-for-of" "^7.9.0"
     "@babel/plugin-transform-function-name" "^7.8.3"
     "@babel/plugin-transform-literals" "^7.8.3"
     "@babel/plugin-transform-member-expression-literals" "^7.8.3"
-    "@babel/plugin-transform-modules-amd" "^7.8.3"
-    "@babel/plugin-transform-modules-commonjs" "^7.8.3"
-    "@babel/plugin-transform-modules-systemjs" "^7.8.3"
-    "@babel/plugin-transform-modules-umd" "^7.8.3"
+    "@babel/plugin-transform-modules-amd" "^7.9.0"
+    "@babel/plugin-transform-modules-commonjs" "^7.9.0"
+    "@babel/plugin-transform-modules-systemjs" "^7.9.0"
+    "@babel/plugin-transform-modules-umd" "^7.9.0"
     "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3"
     "@babel/plugin-transform-new-target" "^7.8.3"
     "@babel/plugin-transform-object-super" "^7.8.3"
-    "@babel/plugin-transform-parameters" "^7.8.3"
+    "@babel/plugin-transform-parameters" "^7.8.7"
     "@babel/plugin-transform-property-literals" "^7.8.3"
-    "@babel/plugin-transform-regenerator" "^7.8.3"
+    "@babel/plugin-transform-regenerator" "^7.8.7"
     "@babel/plugin-transform-reserved-words" "^7.8.3"
     "@babel/plugin-transform-shorthand-properties" "^7.8.3"
     "@babel/plugin-transform-spread" "^7.8.3"
     "@babel/plugin-transform-sticky-regex" "^7.8.3"
     "@babel/plugin-transform-template-literals" "^7.8.3"
-    "@babel/plugin-transform-typeof-symbol" "^7.8.3"
+    "@babel/plugin-transform-typeof-symbol" "^7.8.4"
     "@babel/plugin-transform-unicode-regex" "^7.8.3"
-    "@babel/types" "^7.8.3"
-    browserslist "^4.8.2"
+    "@babel/preset-modules" "^0.1.3"
+    "@babel/types" "^7.9.0"
+    browserslist "^4.9.1"
     core-js-compat "^3.6.2"
     invariant "^2.2.2"
-    levenary "^1.1.0"
+    levenary "^1.1.1"
     semver "^5.5.0"
 
-"@babel/preset-react@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.8.3.tgz#23dc63f1b5b0751283e04252e78cf1d6589273d2"
-  integrity sha512-9hx0CwZg92jGb7iHYQVgi0tOEHP/kM60CtWJQnmbATSPIQQ2xYzfoCI3EdqAhFBeeJwYMdWQuDUHMsuDbH9hyQ==
+"@babel/preset-modules@^0.1.3":
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72"
+  integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
+    "@babel/plugin-transform-dotall-regex" "^7.4.4"
+    "@babel/types" "^7.4.4"
+    esutils "^2.0.2"
+
+"@babel/preset-react@^7.9.4":
+  version "7.9.4"
+  resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.9.4.tgz#c6c97693ac65b6b9c0b4f25b948a8f665463014d"
+  integrity sha512-AxylVB3FXeOTQXNXyiuAQJSvss62FEotbX2Pzx3K/7c+MKJMdSg6Ose6QYllkdCFA8EInCJVw7M/o5QbLuA4ZQ==
   dependencies:
     "@babel/helper-plugin-utils" "^7.8.3"
     "@babel/plugin-transform-react-display-name" "^7.8.3"
-    "@babel/plugin-transform-react-jsx" "^7.8.3"
-    "@babel/plugin-transform-react-jsx-self" "^7.8.3"
-    "@babel/plugin-transform-react-jsx-source" "^7.8.3"
+    "@babel/plugin-transform-react-jsx" "^7.9.4"
+    "@babel/plugin-transform-react-jsx-development" "^7.9.0"
+    "@babel/plugin-transform-react-jsx-self" "^7.9.0"
+    "@babel/plugin-transform-react-jsx-source" "^7.9.0"
+
+"@babel/runtime-corejs3@^7.8.3":
+  version "7.8.7"
+  resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.8.7.tgz#8209d9dff2f33aa2616cb319c83fe159ffb07b8c"
+  integrity sha512-sc7A+H4I8kTd7S61dgB9RomXu/C+F4IrRr4Ytze4dnfx7AXEpCrejSNpjx7vq6y/Bak9S6Kbk65a/WgMLtg43Q==
+  dependencies:
+    core-js-pure "^3.0.0"
+    regenerator-runtime "^0.13.4"
 
 "@babel/runtime@7.0.0":
   version "7.0.0"
@@ -801,43 +881,43 @@
   dependencies:
     regenerator-runtime "^0.12.0"
 
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1"
-  integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==
+"@babel/runtime@^7.1.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+  version "7.9.2"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
+  integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
   dependencies:
-    regenerator-runtime "^0.13.2"
+    regenerator-runtime "^0.13.4"
 
-"@babel/template@^7.0.0", "@babel/template@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8"
-  integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==
+"@babel/template@^7.0.0", "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6":
+  version "7.8.6"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b"
+  integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==
   dependencies:
     "@babel/code-frame" "^7.8.3"
-    "@babel/parser" "^7.8.3"
-    "@babel/types" "^7.8.3"
+    "@babel/parser" "^7.8.6"
+    "@babel/types" "^7.8.6"
 
-"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4":
-  version "7.8.4"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c"
-  integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==
+"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892"
+  integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==
   dependencies:
     "@babel/code-frame" "^7.8.3"
-    "@babel/generator" "^7.8.4"
+    "@babel/generator" "^7.9.0"
     "@babel/helper-function-name" "^7.8.3"
     "@babel/helper-split-export-declaration" "^7.8.3"
-    "@babel/parser" "^7.8.4"
-    "@babel/types" "^7.8.3"
+    "@babel/parser" "^7.9.0"
+    "@babel/types" "^7.9.0"
     debug "^4.1.0"
     globals "^11.1.0"
     lodash "^4.17.13"
 
-"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.8.3":
-  version "7.8.3"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
-  integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==
+"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0":
+  version "7.9.0"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5"
+  integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==
   dependencies:
-    esutils "^2.0.2"
+    "@babel/helper-validator-identifier" "^7.9.0"
     lodash "^4.17.13"
     to-fast-properties "^2.0.0"
 
@@ -936,6 +1016,21 @@
   resolved "https://registry.yarnpkg.com/@gamestdio/websocket/-/websocket-0.3.2.tgz#321ba0976ee30fd14e51dbf8faa85ce7b325f76a"
   integrity sha512-J3n5SKim+ZoLbe44hRGI/VYAwSMCeIJuBy+FfP6EZaujEpNchPRFcIsVQLWAwpU1bP2Ji63rC+rEUOd1vjUB6Q==
 
+"@istanbuljs/load-nyc-config@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b"
+  integrity sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==
+  dependencies:
+    camelcase "^5.3.1"
+    find-up "^4.1.0"
+    js-yaml "^3.13.1"
+    resolve-from "^5.0.0"
+
+"@istanbuljs/schema@^0.1.2":
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
+  integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
+
 "@jest/console@^24.7.1":
   version "24.7.1"
   resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545"
@@ -1093,6 +1188,28 @@
     source-map "^0.6.1"
     write-file-atomic "2.4.1"
 
+"@jest/transform@^25.2.4":
+  version "25.2.4"
+  resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.2.4.tgz#34336f37f13f62f7d1f5b93d5d150ba9eb3e11b9"
+  integrity sha512-6eRigvb+G6bs4kW5j1/y8wu4nCrmVuIe0epPBbiWaYlwawJ8yi1EIyK3d/btDqmBpN5GpN4YhR6iPPnDmkYdTA==
+  dependencies:
+    "@babel/core" "^7.1.0"
+    "@jest/types" "^25.2.3"
+    babel-plugin-istanbul "^6.0.0"
+    chalk "^3.0.0"
+    convert-source-map "^1.4.0"
+    fast-json-stable-stringify "^2.0.0"
+    graceful-fs "^4.2.3"
+    jest-haste-map "^25.2.3"
+    jest-regex-util "^25.2.1"
+    jest-util "^25.2.3"
+    micromatch "^4.0.2"
+    pirates "^4.0.1"
+    realpath-native "^2.0.0"
+    slash "^3.0.0"
+    source-map "^0.6.1"
+    write-file-atomic "^3.0.0"
+
 "@jest/types@^24.9.0":
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59"
@@ -1102,6 +1219,21 @@
     "@types/istanbul-reports" "^1.1.1"
     "@types/yargs" "^13.0.0"
 
+"@jest/types@^25.2.3":
+  version "25.2.3"
+  resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.2.3.tgz#035c4fb94e2da472f359ff9a211915d59987f6b6"
+  integrity sha512-6oLQwO9mKif3Uph3RX5J1i3S7X7xtDHWBaaaoeKw8hOzV6YUd0qDcYcHZ6QXMHDIzSr7zzrEa51o2Ovlj6AtKQ==
+  dependencies:
+    "@types/istanbul-lib-coverage" "^2.0.0"
+    "@types/istanbul-reports" "^1.1.1"
+    "@types/yargs" "^15.0.0"
+    chalk "^3.0.0"
+
+"@rails/ujs@^6.0.2":
+  version "6.0.2"
+  resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.0.2.tgz#8d32452d51c5e115374a218fb5475803dc17f4c0"
+  integrity sha512-KSQjJG8yzSWC1IT+UtFQglefABU37hpJ7uAz39K1/iWtoaJaI9ydGIaxxpJBT/PmYv4kS6lCSjXq13DELeJocw==
+
 "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.2":
   version "7.1.3"
   resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30"
@@ -1218,150 +1350,156 @@
   dependencies:
     "@types/yargs-parser" "*"
 
-"@webassemblyjs/ast@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
-  integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==
-  dependencies:
-    "@webassemblyjs/helper-module-context" "1.8.5"
-    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
-    "@webassemblyjs/wast-parser" "1.8.5"
-
-"@webassemblyjs/floating-point-hex-parser@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721"
-  integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==
-
-"@webassemblyjs/helper-api-error@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7"
-  integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==
-
-"@webassemblyjs/helper-buffer@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204"
-  integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==
-
-"@webassemblyjs/helper-code-frame@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e"
-  integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==
-  dependencies:
-    "@webassemblyjs/wast-printer" "1.8.5"
-
-"@webassemblyjs/helper-fsm@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452"
-  integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==
-
-"@webassemblyjs/helper-module-context@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245"
-  integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    mamacro "^0.0.3"
-
-"@webassemblyjs/helper-wasm-bytecode@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61"
-  integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==
-
-"@webassemblyjs/helper-wasm-section@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf"
-  integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/helper-buffer" "1.8.5"
-    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
-    "@webassemblyjs/wasm-gen" "1.8.5"
-
-"@webassemblyjs/ieee754@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e"
-  integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==
+"@types/yargs@^15.0.0":
+  version "15.0.4"
+  resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299"
+  integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==
+  dependencies:
+    "@types/yargs-parser" "*"
+
+"@webassemblyjs/ast@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
+  integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==
+  dependencies:
+    "@webassemblyjs/helper-module-context" "1.9.0"
+    "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
+    "@webassemblyjs/wast-parser" "1.9.0"
+
+"@webassemblyjs/floating-point-hex-parser@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4"
+  integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==
+
+"@webassemblyjs/helper-api-error@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2"
+  integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==
+
+"@webassemblyjs/helper-buffer@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00"
+  integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==
+
+"@webassemblyjs/helper-code-frame@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27"
+  integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==
+  dependencies:
+    "@webassemblyjs/wast-printer" "1.9.0"
+
+"@webassemblyjs/helper-fsm@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8"
+  integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==
+
+"@webassemblyjs/helper-module-context@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07"
+  integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+
+"@webassemblyjs/helper-wasm-bytecode@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790"
+  integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==
+
+"@webassemblyjs/helper-wasm-section@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346"
+  integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/helper-buffer" "1.9.0"
+    "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
+    "@webassemblyjs/wasm-gen" "1.9.0"
+
+"@webassemblyjs/ieee754@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4"
+  integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==
   dependencies:
     "@xtuc/ieee754" "^1.2.0"
 
-"@webassemblyjs/leb128@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10"
-  integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==
+"@webassemblyjs/leb128@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95"
+  integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==
   dependencies:
     "@xtuc/long" "4.2.2"
 
-"@webassemblyjs/utf8@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc"
-  integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==
-
-"@webassemblyjs/wasm-edit@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a"
-  integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/helper-buffer" "1.8.5"
-    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
-    "@webassemblyjs/helper-wasm-section" "1.8.5"
-    "@webassemblyjs/wasm-gen" "1.8.5"
-    "@webassemblyjs/wasm-opt" "1.8.5"
-    "@webassemblyjs/wasm-parser" "1.8.5"
-    "@webassemblyjs/wast-printer" "1.8.5"
-
-"@webassemblyjs/wasm-gen@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc"
-  integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
-    "@webassemblyjs/ieee754" "1.8.5"
-    "@webassemblyjs/leb128" "1.8.5"
-    "@webassemblyjs/utf8" "1.8.5"
-
-"@webassemblyjs/wasm-opt@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264"
-  integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/helper-buffer" "1.8.5"
-    "@webassemblyjs/wasm-gen" "1.8.5"
-    "@webassemblyjs/wasm-parser" "1.8.5"
-
-"@webassemblyjs/wasm-parser@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d"
-  integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/helper-api-error" "1.8.5"
-    "@webassemblyjs/helper-wasm-bytecode" "1.8.5"
-    "@webassemblyjs/ieee754" "1.8.5"
-    "@webassemblyjs/leb128" "1.8.5"
-    "@webassemblyjs/utf8" "1.8.5"
-
-"@webassemblyjs/wast-parser@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c"
-  integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==
-  dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/floating-point-hex-parser" "1.8.5"
-    "@webassemblyjs/helper-api-error" "1.8.5"
-    "@webassemblyjs/helper-code-frame" "1.8.5"
-    "@webassemblyjs/helper-fsm" "1.8.5"
+"@webassemblyjs/utf8@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab"
+  integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==
+
+"@webassemblyjs/wasm-edit@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf"
+  integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/helper-buffer" "1.9.0"
+    "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
+    "@webassemblyjs/helper-wasm-section" "1.9.0"
+    "@webassemblyjs/wasm-gen" "1.9.0"
+    "@webassemblyjs/wasm-opt" "1.9.0"
+    "@webassemblyjs/wasm-parser" "1.9.0"
+    "@webassemblyjs/wast-printer" "1.9.0"
+
+"@webassemblyjs/wasm-gen@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c"
+  integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
+    "@webassemblyjs/ieee754" "1.9.0"
+    "@webassemblyjs/leb128" "1.9.0"
+    "@webassemblyjs/utf8" "1.9.0"
+
+"@webassemblyjs/wasm-opt@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61"
+  integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/helper-buffer" "1.9.0"
+    "@webassemblyjs/wasm-gen" "1.9.0"
+    "@webassemblyjs/wasm-parser" "1.9.0"
+
+"@webassemblyjs/wasm-parser@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e"
+  integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/helper-api-error" "1.9.0"
+    "@webassemblyjs/helper-wasm-bytecode" "1.9.0"
+    "@webassemblyjs/ieee754" "1.9.0"
+    "@webassemblyjs/leb128" "1.9.0"
+    "@webassemblyjs/utf8" "1.9.0"
+
+"@webassemblyjs/wast-parser@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914"
+  integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==
+  dependencies:
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/floating-point-hex-parser" "1.9.0"
+    "@webassemblyjs/helper-api-error" "1.9.0"
+    "@webassemblyjs/helper-code-frame" "1.9.0"
+    "@webassemblyjs/helper-fsm" "1.9.0"
     "@xtuc/long" "4.2.2"
 
-"@webassemblyjs/wast-printer@1.8.5":
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc"
-  integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==
+"@webassemblyjs/wast-printer@1.9.0":
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899"
+  integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==
   dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/wast-parser" "1.8.5"
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/wast-parser" "1.9.0"
     "@xtuc/long" "4.2.2"
 
 "@xtuc/ieee754@^1.2.0":
@@ -1412,11 +1550,16 @@ acorn-jsx@^5.1.0:
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384"
   integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==
 
-acorn-walk@^6.0.1, acorn-walk@^6.1.1:
+acorn-walk@^6.0.1:
   version "6.2.0"
   resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c"
   integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
 
+acorn-walk@^7.1.1:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
+  integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==
+
 acorn@^3.0.4:
   version "3.3.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
@@ -1427,15 +1570,15 @@ acorn@^5.5.0, acorn@^5.5.3:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
   integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
 
-acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.1:
+acorn@^6.0.1, acorn@^6.2.1:
   version "6.3.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
   integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
 
-acorn@^7.1.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
-  integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
+acorn@^7.1.0, acorn@^7.1.1:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
+  integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
 
 aggregate-error@^3.0.0:
   version "3.0.1"
@@ -1494,6 +1637,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5, ajv@^6.9.1:
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
+ajv@^6.12.0:
+  version "6.12.0"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7"
+  integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==
+  dependencies:
+    fast-deep-equal "^3.1.1"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.4.1"
+    uri-js "^4.2.2"
+
 alphanum-sort@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
@@ -1571,6 +1724,14 @@ ansi-styles@^4.0.0:
     "@types/color-name" "^1.1.1"
     color-convert "^2.0.1"
 
+ansi-styles@^4.1.0:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
+  integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
+  dependencies:
+    "@types/color-name" "^1.1.1"
+    color-convert "^2.0.1"
+
 anymatch@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -1587,6 +1748,14 @@ anymatch@^3.0.1:
     normalize-path "^3.0.0"
     picomatch "^2.0.4"
 
+anymatch@^3.0.3:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
+  integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
+  dependencies:
+    normalize-path "^3.0.0"
+    picomatch "^2.0.4"
+
 aproba@^1.0.3, aproba@^1.1.1:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -1778,18 +1947,18 @@ atrament@0.2.4:
   resolved "https://registry.yarnpkg.com/atrament/-/atrament-0.2.4.tgz#6f78196edfcd194e568b7c0b9c88201ec371ac66"
   integrity sha512-hSA9VwW6COMwvRhSEO4uZweZ91YGOdHqwvslNyrJZG+8mzc4qx/qMsDZBuAeXFeWZO/QKtRjIXguOUy1aNMl3A==
 
-autoprefixer@^9.7.4:
-  version "9.7.4"
-  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.4.tgz#f8bf3e06707d047f0641d87aee8cfb174b2a5378"
-  integrity sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==
+autoprefixer@^9.7.5:
+  version "9.7.5"
+  resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.5.tgz#8df10b9ff9b5814a8d411a5cfbab9c793c392376"
+  integrity sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg==
   dependencies:
-    browserslist "^4.8.3"
-    caniuse-lite "^1.0.30001020"
+    browserslist "^4.11.0"
+    caniuse-lite "^1.0.30001036"
     chalk "^2.4.2"
     normalize-range "^0.1.2"
     num2fraction "^1.2.2"
-    postcss "^7.0.26"
-    postcss-value-parser "^4.0.2"
+    postcss "^7.0.27"
+    postcss-value-parser "^4.0.3"
 
 aws-sign2@~0.7.0:
   version "0.7.0"
@@ -1848,15 +2017,29 @@ babel-jest@^24.9.0:
     chalk "^2.4.2"
     slash "^2.0.0"
 
-babel-loader@^8.0.6:
-  version "8.0.6"
-  resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb"
-  integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==
+babel-jest@^25.2.4:
+  version "25.2.4"
+  resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.2.4.tgz#b21b68d3af8f161c3e6e501e91f0dea8e652e344"
+  integrity sha512-+yDzlyJVWrqih9i2Cvjpt7COaN8vUwCsKGtxJLzg6I0xhxD54K8mvDUCliPKLufyzHh/c5C4MRj4Vk7VMjOjIg==
   dependencies:
-    find-cache-dir "^2.0.0"
-    loader-utils "^1.0.2"
-    mkdirp "^0.5.1"
+    "@jest/transform" "^25.2.4"
+    "@jest/types" "^25.2.3"
+    "@types/babel__core" "^7.1.0"
+    babel-plugin-istanbul "^6.0.0"
+    babel-preset-jest "^25.2.1"
+    chalk "^3.0.0"
+    slash "^3.0.0"
+
+babel-loader@^8.1.0:
+  version "8.1.0"
+  resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3"
+  integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==
+  dependencies:
+    find-cache-dir "^2.1.0"
+    loader-utils "^1.4.0"
+    mkdirp "^0.5.3"
     pify "^4.0.1"
+    schema-utils "^2.6.5"
 
 babel-plugin-dynamic-import-node@^2.3.0:
   version "2.3.0"
@@ -1890,6 +2073,17 @@ babel-plugin-istanbul@^5.1.0:
     istanbul-lib-instrument "^3.0.0"
     test-exclude "^5.0.0"
 
+babel-plugin-istanbul@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765"
+  integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.0.0"
+    "@istanbuljs/load-nyc-config" "^1.0.0"
+    "@istanbuljs/schema" "^0.1.2"
+    istanbul-lib-instrument "^4.0.0"
+    test-exclude "^6.0.0"
+
 babel-plugin-jest-hoist@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756"
@@ -1897,6 +2091,13 @@ babel-plugin-jest-hoist@^24.9.0:
   dependencies:
     "@types/babel__traverse" "^7.0.6"
 
+babel-plugin-jest-hoist@^25.2.1:
+  version "25.2.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.1.tgz#d0003a1f3d5caa281e1107fe03bbf16b799f9955"
+  integrity sha512-HysbCQfJhxLlyxDbKcB2ucGYV0LjqK4h6dBoI3RtFuOxTiTWK6XGZMsHb0tGh8iJdV4hC6Z2GCHzVvDeh9i0lQ==
+  dependencies:
+    "@types/babel__traverse" "^7.0.6"
+
 babel-plugin-lodash@^3.3.4:
   version "3.3.4"
   resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz#4f6844358a1340baed182adbeffa8df9967bc196"
@@ -1908,22 +2109,22 @@ babel-plugin-lodash@^3.3.4:
     lodash "^4.17.10"
     require-package-name "^2.0.1"
 
-babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.6.1:
-  version "2.6.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.2.tgz#98ae30a02645dfa8033628fe613854ec9541bbc8"
-  integrity sha512-Ntviq8paRTkXIxvrJBauib+2KqQbZQuh4593CEZFF8qz3IVP8VituTZmkGe6N7rsuiOIbejxXj6kx3LMlEq0UA==
+babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.8.0:
+  version "2.8.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138"
+  integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==
   dependencies:
     "@babel/runtime" "^7.7.2"
     cosmiconfig "^6.0.0"
     resolve "^1.12.0"
 
-babel-plugin-preval@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/babel-plugin-preval/-/babel-plugin-preval-4.0.0.tgz#edb8501167985752aafcc31086791e1314052e9d"
-  integrity sha512-fZI/4cYneinlj2k/FsXw0/lTWSC5KKoepUueS1g25Gb5vx3GrRyaVwxWCshYqx11GEU4mZnbbFhee8vpquFS2w==
+babel-plugin-preval@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-preval/-/babel-plugin-preval-5.0.0.tgz#6cabb947ecc241664966e1f99eb56a3b4bb63d1e"
+  integrity sha512-8DqJq6/LPUjSZ0Qq6bVIFpsj2flCEE0Cbnbut9TvGU6jP9g3dOWEXtQ/sdvsA9d6souza8eNGh04WRXpuH9ThA==
   dependencies:
-    "@babel/runtime" "^7.7.2"
-    babel-plugin-macros "^2.6.1"
+    "@babel/runtime" "^7.9.2"
+    babel-plugin-macros "^2.8.0"
     require-from-string "^2.0.2"
 
 babel-plugin-react-intl@^3.4.1:
@@ -1955,6 +2156,15 @@ babel-preset-jest@^24.9.0:
     "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
     babel-plugin-jest-hoist "^24.9.0"
 
+babel-preset-jest@^25.2.1:
+  version "25.2.1"
+  resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.2.1.tgz#4ccd0e577f69aa11b71806edfe8b25a5c3ac93a2"
+  integrity sha512-zXHJBM5iR8oEO4cvdF83AQqqJf3tJrXy3x8nfu2Nlqvn4cneg4Ca8M7cQvC5S9BzDDy1O0tZ9iXru9J6E3ym+A==
+  dependencies:
+    "@babel/plugin-syntax-bigint" "^7.0.0"
+    "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
+    babel-plugin-jest-hoist "^25.2.1"
+
 babel-runtime@^6.26.0:
   version "6.26.0"
   resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
@@ -2105,7 +2315,7 @@ braces@^2.3.1, braces@^2.3.2:
     split-string "^3.0.2"
     to-regex "^3.0.1"
 
-braces@^3.0.2:
+braces@^3.0.1, braces@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
   integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
@@ -2195,14 +2405,15 @@ browserify-zlib@^0.2.0:
   dependencies:
     pako "~1.0.5"
 
-browserslist@^4.0.0, browserslist@^4.8.2, browserslist@^4.8.3:
-  version "4.8.3"
-  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.3.tgz#65802fcd77177c878e015f0e3189f2c4f627ba44"
-  integrity sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==
+browserslist@^4.0.0, browserslist@^4.11.0, browserslist@^4.8.3, browserslist@^4.9.1:
+  version "4.11.1"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b"
+  integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==
   dependencies:
-    caniuse-lite "^1.0.30001017"
-    electron-to-chromium "^1.3.322"
-    node-releases "^1.1.44"
+    caniuse-lite "^1.0.30001038"
+    electron-to-chromium "^1.3.390"
+    node-releases "^1.1.53"
+    pkg-up "^2.0.0"
 
 bser@^2.0.0:
   version "2.0.0"
@@ -2371,10 +2582,10 @@ caniuse-api@^3.0.0:
     lodash.memoize "^4.1.2"
     lodash.uniq "^4.5.0"
 
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001017, caniuse-lite@^1.0.30001020:
-  version "1.0.30001021"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001021.tgz#e75ed1ef6dbadd580ac7e7720bb16f07b083f254"
-  integrity sha512-wuMhT7/hwkgd8gldgp2jcrUjOU9RXJ4XxGumQeOsUr91l3WwmM68Cpa/ymCnWEDqakwFXhuDQbaKNHXBPgeE9g==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001036, caniuse-lite@^1.0.30001038:
+  version "1.0.30001038"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz#44da3cbca2ab6cb6aa83d1be5d324e17f141caff"
+  integrity sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ==
 
 capture-exit@^1.2.0:
   version "1.2.0"
@@ -2408,6 +2619,19 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
+chalk@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
+  integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
+  dependencies:
+    ansi-styles "^4.1.0"
+    supports-color "^7.1.0"
+
+char-regex@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
+  integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
+
 chardet@^0.7.0:
   version "0.7.0"
   resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@@ -2653,12 +2877,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@^2.11.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1:
-  version "2.20.1"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.1.tgz#3863ce3ca92d0831dcf2a102f5fb4b5926afd0f9"
-  integrity sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg==
-
-commander@~2.20.3:
+commander@^2.11.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1, commander@~2.20.3:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -2819,6 +3038,11 @@ core-js-compat@^3.6.2:
     browserslist "^4.8.3"
     semver "7.0.0"
 
+core-js-pure@^3.0.0:
+  version "3.6.4"
+  resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a"
+  integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==
+
 core-js@^2.4.0:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042"
@@ -2891,12 +3115,12 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
-cross-env@^6.0.3:
-  version "6.0.3"
-  resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941"
-  integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==
+cross-env@^7.0.2:
+  version "7.0.2"
+  resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9"
+  integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==
   dependencies:
-    cross-spawn "^7.0.0"
+    cross-spawn "^7.0.1"
 
 cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
   version "6.0.5"
@@ -2909,7 +3133,7 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
     shebang-command "^1.2.0"
     which "^1.2.9"
 
-cross-spawn@^7.0.0:
+cross-spawn@^7.0.1:
   version "7.0.1"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14"
   integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==
@@ -3166,6 +3390,11 @@ csstype@^2.5.7:
   resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41"
   integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==
 
+csstype@^2.6.7:
+  version "2.6.9"
+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098"
+  integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q==
+
 cyclist@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
@@ -3330,6 +3559,11 @@ delegates@^1.0.0:
   resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
   integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
 
+denque@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf"
+  integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==
+
 depd@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -3448,6 +3682,14 @@ dom-helpers@^3.2.1, dom-helpers@^3.3.1:
   dependencies:
     "@babel/runtime" "^7.1.2"
 
+dom-helpers@^5.0.1:
+  version "5.1.3"
+  resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821"
+  integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==
+  dependencies:
+    "@babel/runtime" "^7.6.3"
+    csstype "^2.6.7"
+
 dom-serializer@0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -3521,11 +3763,6 @@ dotenv@^8.2.0:
   resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
   integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
 
-double-ended-queue@^2.1.0-0:
-  version "2.1.0-0"
-  resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
-  integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=
-
 duplexer@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@@ -3559,10 +3796,10 @@ ejs@^2.3.4, ejs@^2.6.1:
   resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.1.tgz#5b5ab57f718b79d4aca9254457afecd36fa80228"
   integrity sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==
 
-electron-to-chromium@^1.3.322:
-  version "1.3.322"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8"
-  integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==
+electron-to-chromium@^1.3.390:
+  version "1.3.391"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.391.tgz#9b7ee2f387814ad7d37addaafe41c8f4c4498d24"
+  integrity sha512-WOi6loSnDmfICOqGRrgeK7bZeWDAbGjCptDhI5eyJAqSzWfoeRuOOU1rOTZRL29/9AaxTndZB6Uh8YrxRfZJqw==
 
 elliptic@^6.0.0:
   version "6.5.1"
@@ -3596,6 +3833,11 @@ emojis-list@^2.0.0:
   resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
   integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
 
+emojis-list@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
+  integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
+
 encodeurl@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@@ -3706,7 +3948,7 @@ error-stack-parser@^2.0.6:
   dependencies:
     stackframe "^1.1.1"
 
-es-abstract@^1.13.0, es-abstract@^1.15.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.5.1:
+es-abstract@^1.13.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.5.1:
   version "1.17.0"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1"
   integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==
@@ -3864,11 +4106,6 @@ eslint-module-utils@^2.4.1:
     debug "^2.6.9"
     pkg-dir "^2.0.0"
 
-eslint-plugin-eslint-plugin@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5"
-  integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg==
-
 eslint-plugin-import@~2.20.1:
   version "2.20.1"
   resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3"
@@ -3907,21 +4144,23 @@ eslint-plugin-promise@~4.2.1:
   resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
   integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
 
-eslint-plugin-react@~7.17.0:
-  version "7.17.0"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz#a31b3e134b76046abe3cd278e7482bd35a1d12d7"
-  integrity sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A==
+eslint-plugin-react@~7.19.0:
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666"
+  integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==
   dependencies:
-    array-includes "^3.0.3"
+    array-includes "^3.1.1"
     doctrine "^2.1.0"
-    eslint-plugin-eslint-plugin "^2.1.0"
     has "^1.0.3"
     jsx-ast-utils "^2.2.3"
-    object.entries "^1.1.0"
-    object.fromentries "^2.0.1"
-    object.values "^1.1.0"
+    object.entries "^1.1.1"
+    object.fromentries "^2.0.2"
+    object.values "^1.1.1"
     prop-types "^15.7.2"
-    resolve "^1.13.1"
+    resolve "^1.15.1"
+    semver "^6.3.0"
+    string.prototype.matchall "^4.0.2"
+    xregexp "^4.3.0"
 
 eslint-scope@^4.0.3:
   version "4.0.3"
@@ -4079,7 +4318,7 @@ estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
   resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
   integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
 
-esutils@^2.0.0, esutils@^2.0.2:
+esutils@^2.0.2:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
   integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
@@ -4288,6 +4527,11 @@ fast-deep-equal@^2.0.1:
   resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
   integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
 
+fast-deep-equal@^3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
+  integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
+
 fast-json-stable-stringify@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
@@ -4359,12 +4603,12 @@ file-entry-cache@^5.0.1:
   dependencies:
     flat-cache "^2.0.1"
 
-file-loader@^5.0.2:
-  version "5.0.2"
-  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-5.0.2.tgz#7f3d8b4ac85a5e8df61338cfec95d7405f971caa"
-  integrity sha512-QMiQ+WBkGLejKe81HU8SZ9PovsU/5uaLo0JdTCEXOYv7i7jfAjHZi1tcwp9tSASJPOmmHZtbdCervFmXMH/Dcg==
+file-loader@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-5.1.0.tgz#cb56c070efc0e40666424309bd0d9e45ac6f2bb8"
+  integrity sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==
   dependencies:
-    loader-utils "^1.2.3"
+    loader-utils "^1.4.0"
     schema-utils "^2.5.0"
 
 file-type@^10.5.0:
@@ -4407,7 +4651,7 @@ finalhandler@~1.1.2:
     statuses "~1.5.0"
     unpipe "~1.0.0"
 
-find-cache-dir@^2.0.0, find-cache-dir@^2.1.0:
+find-cache-dir@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
   integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
@@ -4624,6 +4868,11 @@ fsevents@^2.0.6:
   resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
   integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==
 
+fsevents@^2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"
+  integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==
+
 function-bind@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -4844,7 +5093,7 @@ graceful-fs@^4.1.6:
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
   integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
 
-graceful-fs@^4.2.2:
+graceful-fs@^4.2.2, graceful-fs@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
   integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
@@ -5370,6 +5619,15 @@ internal-ip@^4.3.0:
     default-gateway "^4.2.0"
     ipaddr.js "^1.9.0"
 
+internal-slot@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3"
+  integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==
+  dependencies:
+    es-abstract "^1.17.0-next.1"
+    has "^1.0.3"
+    side-channel "^1.0.2"
+
 interpret@1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
@@ -5509,11 +5767,6 @@ is-boolean-object@^1.0.1:
   resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
   integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
 
-is-buffer@^1.1.5:
-  version "1.1.6"
-  resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
-  integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-
 is-buffer@^2.0.2:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
@@ -5772,7 +6025,7 @@ is-symbol@^1.0.2:
   dependencies:
     has-symbols "^1.0.1"
 
-is-typedarray@~1.0.0:
+is-typedarray@^1.0.0, is-typedarray@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
   integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
@@ -5834,6 +6087,11 @@ istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3:
   resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba"
   integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==
 
+istanbul-lib-coverage@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
+  integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==
+
 istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971"
@@ -5847,6 +6105,19 @@ istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1:
     istanbul-lib-coverage "^2.0.3"
     semver "^5.5.0"
 
+istanbul-lib-instrument@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6"
+  integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==
+  dependencies:
+    "@babel/core" "^7.7.5"
+    "@babel/parser" "^7.7.5"
+    "@babel/template" "^7.7.4"
+    "@babel/traverse" "^7.7.4"
+    "@istanbuljs/schema" "^0.1.2"
+    istanbul-lib-coverage "^3.0.0"
+    semver "^6.3.0"
+
 istanbul-lib-report@^2.0.4:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4"
@@ -6000,6 +6271,25 @@ jest-haste-map@^24.9.0:
   optionalDependencies:
     fsevents "^1.2.7"
 
+jest-haste-map@^25.2.3:
+  version "25.2.3"
+  resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.2.3.tgz#2649392b5af191f0167a27bfb62e5d96d7eaaade"
+  integrity sha512-pAP22OHtPr4qgZlJJFks2LLgoQUr4XtM1a+F5UaPIZNiCRnePA0hM3L7aiJ0gzwiNIYwMTfKRwG/S1L28J3A3A==
+  dependencies:
+    "@jest/types" "^25.2.3"
+    anymatch "^3.0.3"
+    fb-watchman "^2.0.0"
+    graceful-fs "^4.2.3"
+    jest-serializer "^25.2.1"
+    jest-util "^25.2.3"
+    jest-worker "^25.2.1"
+    micromatch "^4.0.2"
+    sane "^4.0.3"
+    walker "^1.0.7"
+    which "^2.0.2"
+  optionalDependencies:
+    fsevents "^2.1.2"
+
 jest-jasmine2@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0"
@@ -6076,6 +6366,11 @@ jest-regex-util@^24.9.0:
   resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636"
   integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==
 
+jest-regex-util@^25.2.1:
+  version "25.2.1"
+  resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.1.tgz#db64b0d15cd3642c93b7b9627801d7c518600584"
+  integrity sha512-wroFVJw62LdqTdkL508ZLV82FrJJWVJMIuYG7q4Uunl1WAPTf4ftPKrqqfec4SvOIlvRZUdEX2TFpWR356YG/w==
+
 jest-resolve-dependencies@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab"
@@ -6155,6 +6450,11 @@ jest-serializer@^24.9.0:
   resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73"
   integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==
 
+jest-serializer@^25.2.1:
+  version "25.2.1"
+  resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.1.tgz#51727a5fc04256f461abe0fa024a022ba165877a"
+  integrity sha512-fibDi7M5ffx6c/P66IkvR4FKkjG5ldePAK1WlbNoaU4GZmIAkS9Le/frAwRUFEX0KdnisSPWf+b1RC5jU7EYJQ==
+
 jest-snapshot@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba"
@@ -6192,6 +6492,16 @@ jest-util@^24.9.0:
     slash "^2.0.0"
     source-map "^0.6.0"
 
+jest-util@^25.2.3:
+  version "25.2.3"
+  resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.2.3.tgz#0abf95a1d6b96f2de5a3ecd61b36c40a182dc256"
+  integrity sha512-7tWiMICVSo9lNoObFtqLt9Ezt5exdFlWs5fLe1G4XLY2lEbZc814cw9t4YHScqBkWMfzth8ASHKlYBxiX2rdCw==
+  dependencies:
+    "@jest/types" "^25.2.3"
+    chalk "^3.0.0"
+    is-ci "^2.0.0"
+    make-dir "^3.0.0"
+
 jest-validate@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab"
@@ -6233,6 +6543,14 @@ jest-worker@^25.1.0:
     merge-stream "^2.0.0"
     supports-color "^7.0.0"
 
+jest-worker@^25.2.1:
+  version "25.2.1"
+  resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.1.tgz#209617015c768652646aa33a7828cc2ab472a18a"
+  integrity sha512-IHnpekk8H/hCUbBlfeaPZzU6v75bqwJp3n4dUrQuQOAgOneI4tx3jV2o8pvlXnDfcRsfkFIUD//HWXpCmR+evQ==
+  dependencies:
+    merge-stream "^2.0.0"
+    supports-color "^7.0.0"
+
 jest@^24.9.0:
   version "24.9.0"
   resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171"
@@ -6360,12 +6678,12 @@ json5@^1.0.1:
   dependencies:
     minimist "^1.2.0"
 
-json5@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
-  integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
+json5@^2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e"
+  integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==
   dependencies:
-    minimist "^1.2.0"
+    minimist "^1.2.5"
 
 jsonfile@^3.0.0:
   version "3.0.1"
@@ -6419,29 +6737,10 @@ killable@^1.0.1:
   resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
   integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==
 
-kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
-  version "3.2.2"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
-  integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
-  dependencies:
-    is-buffer "^1.1.5"
-
-kind-of@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
-  integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc=
-  dependencies:
-    is-buffer "^1.1.5"
-
-kind-of@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
-  integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
-
-kind-of@^6.0.0, kind-of@^6.0.2:
-  version "6.0.2"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
-  integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0, kind-of@^4.0.0, kind-of@^5.0.0, kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
+  version "6.0.3"
+  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
+  integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
 
 kleur@^3.0.2:
   version "3.0.2"
@@ -6475,10 +6774,10 @@ leven@^3.1.0:
   resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
   integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
 
-levenary@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.0.tgz#fc146fe75f32dc483a0a2c64aef720f602cd6210"
-  integrity sha512-VHcwhO0UTpUW7rLPN2/OiWJdgA1e9BqEDALhrgCe/F+uUJnep6CoUsTzMeP8Rh0NGr9uKquXxqe7lwLZo509nQ==
+levenary@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77"
+  integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==
   dependencies:
     leven "^3.1.0"
 
@@ -6530,7 +6829,7 @@ loader-utils@0.2.x:
     json5 "^0.5.0"
     object-assign "^4.0.1"
 
-loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3:
+loader-utils@1.2.3:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
   integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
@@ -6539,6 +6838,15 @@ loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.
     emojis-list "^2.0.0"
     json5 "^1.0.1"
 
+loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
+  integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==
+  dependencies:
+    big.js "^5.2.2"
+    emojis-list "^3.0.0"
+    json5 "^1.0.1"
+
 locate-path@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -6680,11 +6988,6 @@ makeerror@1.0.x:
   dependencies:
     tmpl "1.0.x"
 
-mamacro@^0.0.3:
-  version "0.0.3"
-  resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4"
-  integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==
-
 map-age-cleaner@^0.1.1:
   version "0.1.3"
   resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
@@ -6794,6 +7097,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
     snapdragon "^0.8.1"
     to-regex "^3.0.2"
 
+micromatch@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
+  integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
+  dependencies:
+    braces "^3.0.1"
+    picomatch "^2.0.5"
+
 miller-rabin@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -6873,11 +7184,6 @@ minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
   dependencies:
     brace-expansion "^1.1.7"
 
-minimist@0.0.8:
-  version "0.0.8"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
-  integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-
 minimist@1.1.x:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
@@ -6888,6 +7194,11 @@ minimist@^1.1.1, minimist@^1.2.0:
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
   integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
 
+minimist@^1.2.5:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+
 minimist@~0.0.1:
   version "0.0.10"
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
@@ -6960,12 +7271,17 @@ mixin-deep@^1.2.0:
     for-in "^1.0.2"
     is-extendable "^1.0.1"
 
-mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
-  integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
+mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1:
+  version "0.5.4"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512"
+  integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==
   dependencies:
-    minimist "0.0.8"
+    minimist "^1.2.5"
+
+mkdirp@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea"
+  integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==
 
 moo@^0.4.3:
   version "0.4.3"
@@ -7165,12 +7481,10 @@ node-pre-gyp@^0.12.0:
     semver "^5.3.0"
     tar "^4"
 
-node-releases@^1.1.44:
-  version "1.1.45"
-  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.45.tgz#4cf7e9175d71b1317f15ffd68ce63bce1d53e9f2"
-  integrity sha512-cXvGSfhITKI8qsV116u2FTzH5EWZJfgG7d4cpqwF8I8+1tWpD6AsvvGRKq2onR0DNj1jfqsjkXZsm14JMS7Cyg==
-  dependencies:
-    semver "^6.3.0"
+node-releases@^1.1.53:
+  version "1.1.53"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4"
+  integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==
 
 nopt@^4.0.1:
   version "4.0.1"
@@ -7345,16 +7659,6 @@ object.entries@^1.1.0, object.entries@^1.1.1:
     function-bind "^1.1.1"
     has "^1.0.3"
 
-object.fromentries@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704"
-  integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA==
-  dependencies:
-    define-properties "^1.1.3"
-    es-abstract "^1.15.0"
-    function-bind "^1.1.1"
-    has "^1.0.3"
-
 object.fromentries@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9"
@@ -7866,6 +8170,11 @@ picomatch@^2.0.4:
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6"
   integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==
 
+picomatch@^2.0.5:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a"
+  integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==
+
 pify@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -7921,6 +8230,13 @@ pkg-dir@^4.1.0:
   dependencies:
     find-up "^4.0.0"
 
+pkg-up@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
+  integrity sha1-yBmscoBZpGHKscOImivjxJoATX8=
+  dependencies:
+    find-up "^2.1.0"
+
 pluralize@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
@@ -8285,10 +8601,10 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.1:
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
   integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
 
-postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9"
-  integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==
+postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.0.3:
+  version "4.0.3"
+  resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d"
+  integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==
 
 postcss@^5.0.16:
   version "5.2.18"
@@ -8300,10 +8616,10 @@ postcss@^5.0.16:
     source-map "^0.5.6"
     supports-color "^3.2.3"
 
-postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.23, postcss@^7.0.26, postcss@^7.0.5, postcss@^7.0.6:
-  version "7.0.26"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.26.tgz#5ed615cfcab35ba9bbb82414a4fa88ea10429587"
-  integrity sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==
+postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.23, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6:
+  version "7.0.27"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9"
+  integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==
   dependencies:
     chalk "^2.4.2"
     source-map "^0.6.1"
@@ -8351,7 +8667,7 @@ pretty-format@^24.9.0:
     ansi-styles "^3.2.0"
     react-is "^16.8.4"
 
-private@^0.1.6:
+private@^0.1.8:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
   integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
@@ -8549,11 +8865,6 @@ railroad-diagrams@^1.0.0:
   resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
   integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=
 
-rails-ujs@^5.2.4:
-  version "5.2.4"
-  resolved "https://registry.yarnpkg.com/rails-ujs/-/rails-ujs-5.2.4.tgz#31056ccd62d868f7d044395f31d77a4440550ceb"
-  integrity sha512-Mzu6bnTBKn4IuJvP7BDJRy4lzvR1zMWVDeTdPwDubXBfxpFEKqwOi5Nb6tfE2SYtTd+bb3PRETf40I94jgKw3w==
-
 randexp@0.4.6:
   version "0.4.6"
   resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
@@ -8602,15 +8913,15 @@ rc@^1.2.7:
     minimist "^1.2.0"
     strip-json-comments "~2.0.1"
 
-react-dom@^16.12.0:
-  version "16.12.0"
-  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11"
-  integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==
+react-dom@^16.13.0:
+  version "16.13.0"
+  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866"
+  integrity sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
     prop-types "^15.6.2"
-    scheduler "^0.18.0"
+    scheduler "^0.19.0"
 
 react-event-listener@^0.6.0:
   version "0.6.5"
@@ -8632,10 +8943,12 @@ react-hotkeys@^1.1.4:
     mousetrap "^1.5.2"
     prop-types "^15.6.0"
 
-react-immutable-proptypes@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4"
-  integrity sha1-Aj1vObsVyXwHHp5g0A0TbqxfoLQ=
+react-immutable-proptypes@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz#cce96d68cc3c18e89617cbf3092d08e35126af4a"
+  integrity sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==
+  dependencies:
+    invariant "^2.2.2"
 
 react-immutable-pure-component@^1.1.1:
   version "1.2.3"
@@ -8778,10 +9091,10 @@ react-router@^4.3.1:
     prop-types "^15.6.1"
     warning "^4.0.1"
 
-react-select@^3.0.8:
-  version "3.0.8"
-  resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.0.8.tgz#06ff764e29db843bcec439ef13e196865242e0c1"
-  integrity sha512-v9LpOhckLlRmXN5A6/mGGEft4FMrfaBFTGAnuPHcUgVId7Je42kTq9y0Z+Ye5z8/j0XDT3zUqza8gaRaI1PZIg==
+react-select@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.1.0.tgz#ab098720b2e9fe275047c993f0d0caf5ded17c27"
+  integrity sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g==
   dependencies:
     "@babel/runtime" "^7.4.4"
     "@emotion/cache" "^10.0.9"
@@ -8790,7 +9103,7 @@ react-select@^3.0.8:
     memoize-one "^5.0.0"
     prop-types "^15.6.0"
     react-input-autosize "^2.2.2"
-    react-transition-group "^2.2.1"
+    react-transition-group "^4.3.0"
 
 react-sparklines@^1.7.0:
   version "1.7.0"
@@ -8830,15 +9143,15 @@ react-swipeable-views@^0.13.9:
     react-swipeable-views-utils "^0.13.9"
     warning "^4.0.1"
 
-react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0:
-  version "16.12.0"
-  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.12.0.tgz#11417ffda579306d4e841a794d32140f3da1b43f"
-  integrity sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w==
+react-test-renderer@^16.0.0-0, react-test-renderer@^16.13.0:
+  version "16.13.0"
+  resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.13.0.tgz#39ba3bf72cedc8210c3f81983f0bb061b14a3014"
+  integrity sha512-NQ2S9gdMUa7rgPGpKGyMcwl1d6D9MCF0lftdI3kts6kkiX+qvpC955jNjAZXlIDTjnN9jwFI8A8XhRh/9v0spA==
   dependencies:
     object-assign "^4.1.1"
     prop-types "^15.6.2"
     react-is "^16.8.6"
-    scheduler "^0.18.0"
+    scheduler "^0.19.0"
 
 react-textarea-autosize@^7.1.2:
   version "7.1.2"
@@ -8865,10 +9178,20 @@ react-transition-group@^2.2.1:
     prop-types "^15.6.2"
     react-lifecycles-compat "^3.0.4"
 
-react@^16.12.0:
-  version "16.12.0"
-  resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83"
-  integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==
+react-transition-group@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.3.0.tgz#fea832e386cf8796c58b61874a3319704f5ce683"
+  integrity sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw==
+  dependencies:
+    "@babel/runtime" "^7.5.5"
+    dom-helpers "^5.0.1"
+    loose-envify "^1.4.0"
+    prop-types "^15.6.2"
+
+react@^16.13.1:
+  version "16.13.1"
+  resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
+  integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
@@ -8962,24 +9285,37 @@ realpath-native@^1.1.0:
   dependencies:
     util.promisify "^1.0.0"
 
-redis-commands@^1.2.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.4.0.tgz#52f9cf99153efcce56a8f86af986bd04e988602f"
-  integrity sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==
+realpath-native@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866"
+  integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==
 
-redis-parser@^2.6.0:
-  version "2.6.0"
-  resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b"
-  integrity sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=
+redis-commands@^1.5.0:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.5.0.tgz#80d2e20698fe688f227127ff9e5164a7dd17e785"
+  integrity sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==
 
-redis@^2.7.1:
-  version "2.8.0"
-  resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02"
-  integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==
+redis-errors@^1.0.0, redis-errors@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
+  integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=
+
+redis-parser@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
+  integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=
+  dependencies:
+    redis-errors "^1.0.0"
+
+redis@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/redis/-/redis-3.0.2.tgz#bd47067b8a4a3e6a2e556e57f71cc82c7360150a"
+  integrity sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==
   dependencies:
-    double-ended-queue "^2.1.0-0"
-    redis-commands "^1.2.0"
-    redis-parser "^2.6.0"
+    denque "^1.4.1"
+    redis-commands "^1.5.0"
+    redis-errors "^1.2.0"
+    redis-parser "^3.0.0"
 
 redux-immutable@^4.0.0:
   version "4.0.0"
@@ -9011,6 +9347,13 @@ regenerate-unicode-properties@^8.1.0:
   dependencies:
     regenerate "^1.4.0"
 
+regenerate-unicode-properties@^8.2.0:
+  version "8.2.0"
+  resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
+  integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==
+  dependencies:
+    regenerate "^1.4.0"
+
 regenerate@^1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
@@ -9026,17 +9369,18 @@ regenerator-runtime@^0.12.0:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
   integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
 
-regenerator-runtime@^0.13.2:
-  version "0.13.2"
-  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447"
-  integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==
+regenerator-runtime@^0.13.4:
+  version "0.13.4"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz#e96bf612a3362d12bb69f7e8f74ffeab25c7ac91"
+  integrity sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==
 
-regenerator-transform@^0.14.0:
-  version "0.14.0"
-  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf"
-  integrity sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==
+regenerator-transform@^0.14.2:
+  version "0.14.4"
+  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7"
+  integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==
   dependencies:
-    private "^0.1.6"
+    "@babel/runtime" "^7.8.4"
+    private "^0.1.8"
 
 regex-not@^1.0.0, regex-not@^1.0.2:
   version "1.0.2"
@@ -9053,6 +9397,14 @@ regexp.prototype.flags@^1.2.0:
   dependencies:
     define-properties "^1.1.2"
 
+regexp.prototype.flags@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
+  integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
+  dependencies:
+    define-properties "^1.1.3"
+    es-abstract "^1.17.0-next.1"
+
 regexpp@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
@@ -9070,11 +9422,28 @@ regexpu-core@^4.6.0:
     unicode-match-property-ecmascript "^1.0.4"
     unicode-match-property-value-ecmascript "^1.1.0"
 
+regexpu-core@^4.7.0:
+  version "4.7.0"
+  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938"
+  integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==
+  dependencies:
+    regenerate "^1.4.0"
+    regenerate-unicode-properties "^8.2.0"
+    regjsgen "^0.5.1"
+    regjsparser "^0.6.4"
+    unicode-match-property-ecmascript "^1.0.4"
+    unicode-match-property-value-ecmascript "^1.2.0"
+
 regjsgen@^0.5.0:
   version "0.5.0"
   resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd"
   integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==
 
+regjsgen@^0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c"
+  integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==
+
 regjsparser@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c"
@@ -9082,6 +9451,13 @@ regjsparser@^0.6.0:
   dependencies:
     jsesc "~0.5.0"
 
+regjsparser@^0.6.4:
+  version "0.6.4"
+  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272"
+  integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==
+  dependencies:
+    jsesc "~0.5.0"
+
 rellax@^1.12.1:
   version "1.12.1"
   resolved "https://registry.yarnpkg.com/rellax/-/rellax-1.12.1.tgz#1b433ef7ac4aa3573449a33efab391c112f6b34d"
@@ -9222,6 +9598,11 @@ resolve-from@^4.0.0:
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
   integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
 
+resolve-from@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
+  integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
+
 resolve-pathname@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
@@ -9242,10 +9623,10 @@ resolve@1.1.7:
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
   integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
-resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1:
-  version "1.13.1"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16"
-  integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==
+resolve@^1.12.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1:
+  version "1.15.1"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
+  integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
   dependencies:
     path-parse "^1.0.6"
 
@@ -9428,10 +9809,10 @@ sass-loader@^8.0.2:
     schema-utils "^2.6.1"
     semver "^6.3.0"
 
-sass@^1.25.0:
-  version "1.25.0"
-  resolved "https://registry.yarnpkg.com/sass/-/sass-1.25.0.tgz#f8bd7dfbb39d6b0305e27704a8ebe637820693f3"
-  integrity sha512-uQMjye0Y70SEDGO56n0j91tauqS9E1BmpKHtiYNQScXDHeaE9uHwNEqQNFf4Bes/3DHMNinB6u79JsG10XWNyw==
+sass@^1.26.3:
+  version "1.26.3"
+  resolved "https://registry.yarnpkg.com/sass/-/sass-1.26.3.tgz#412df54486143b76b5a65cdf7569e86f44659f46"
+  integrity sha512-5NMHI1+YFYw4sN3yfKjpLuV9B5l7MqQ6FlkTcC4FT+oHbBRUZoSjHrrt/mE0nFXJyY2kQtU9ou9HxvFVjLFuuw==
   dependencies:
     chokidar ">=2.0.0 <4.0.0"
 
@@ -9440,10 +9821,10 @@ sax@^1.2.4, sax@~1.2.4:
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
   integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
 
-scheduler@^0.18.0:
-  version "0.18.0"
-  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4"
-  integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==
+scheduler@^0.19.0:
+  version "0.19.0"
+  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d"
+  integrity sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==
   dependencies:
     loose-envify "^1.1.0"
     object-assign "^4.1.1"
@@ -9457,12 +9838,12 @@ schema-utils@^1.0.0:
     ajv-errors "^1.0.0"
     ajv-keywords "^3.1.0"
 
-schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4:
-  version "2.6.4"
-  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.4.tgz#a27efbf6e4e78689d91872ee3ccfa57d7bdd0f53"
-  integrity sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==
+schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4, schema-utils@^2.6.5:
+  version "2.6.5"
+  resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a"
+  integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==
   dependencies:
-    ajv "^6.10.2"
+    ajv "^6.12.0"
     ajv-keywords "^3.4.1"
 
 scroll-behavior@^0.9.1:
@@ -9636,6 +10017,14 @@ shellwords@^0.1.1:
   resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
   integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
 
+side-channel@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
+  integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==
+  dependencies:
+    es-abstract "^1.17.0-next.1"
+    object-inspect "^1.7.0"
+
 signal-exit@^3.0.0, signal-exit@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@@ -9663,6 +10052,11 @@ slash@^2.0.0:
   resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
   integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
 
+slash@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
+  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+
 slice-ansi@0.0.4:
   version "0.0.4"
   resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
@@ -10021,6 +10415,18 @@ string-width@^4.1.0, string-width@^4.2.0:
     is-fullwidth-code-point "^3.0.0"
     strip-ansi "^6.0.0"
 
+string.prototype.matchall@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e"
+  integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==
+  dependencies:
+    define-properties "^1.1.3"
+    es-abstract "^1.17.0"
+    has-symbols "^1.0.1"
+    internal-slot "^1.0.2"
+    regexp.prototype.flags "^1.3.0"
+    side-channel "^1.0.2"
+
 string.prototype.trim@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782"
@@ -10060,12 +10466,12 @@ string_decoder@~1.1.1:
   dependencies:
     safe-buffer "~5.1.0"
 
-stringz@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/stringz/-/stringz-2.0.0.tgz#0a092bc64ed9b42eff2936d0401d2398393d54e9"
-  integrity sha512-pRWc5RGpedKEDvQ/ukYs8kS8tKj+cKu5ayOoyOvsavbpiLBcm1dGX6p1o5IagaN11cbfN8tKGpgQ4fHdEq5LBA==
+stringz@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/stringz/-/stringz-2.1.0.tgz#5896b4713eac31157556040fb90258fb02c1630c"
+  integrity sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A==
   dependencies:
-    unicode-astral-regex "^1.0.1"
+    char-regex "^1.0.2"
 
 strip-ansi@^3.0.0, strip-ansi@^3.0.1:
   version "3.0.1"
@@ -10160,7 +10566,7 @@ supports-color@^5.3.0:
   dependencies:
     has-flag "^3.0.0"
 
-supports-color@^7.0.0:
+supports-color@^7.0.0, supports-color@^7.1.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
   integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
@@ -10321,6 +10727,15 @@ test-exclude@^5.0.0:
     read-pkg-up "^4.0.0"
     require-main-filename "^1.0.1"
 
+test-exclude@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
+  integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==
+  dependencies:
+    "@istanbuljs/schema" "^0.1.2"
+    glob "^7.1.4"
+    minimatch "^3.0.4"
+
 text-table@^0.2.0, text-table@~0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -10522,6 +10937,13 @@ type@^2.0.0:
   resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3"
   integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==
 
+typedarray-to-buffer@^3.1.5:
+  version "3.1.5"
+  resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
+  integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==
+  dependencies:
+    is-typedarray "^1.0.0"
+
 typedarray@^0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@@ -10535,11 +10957,6 @@ uglify-js@^3.1.4:
     commander "~2.20.3"
     source-map "~0.6.1"
 
-unicode-astral-regex@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/unicode-astral-regex/-/unicode-astral-regex-1.0.1.tgz#2cab8529480646f9614ddbc7b62158ad05123feb"
-  integrity sha512-UP6cmDeiWi8bMDmkyXLRsDuVPTvPjh8Wsz+pHu1VkGgTBl4pUceYAdHXY0cdc6Q3+Z2q7QMzi/0E7L/S/yOvFw==
-
 unicode-canonical-property-names-ecmascript@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
@@ -10558,6 +10975,11 @@ unicode-match-property-value-ecmascript@^1.1.0:
   resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277"
   integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==
 
+unicode-match-property-value-ecmascript@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531"
+  integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==
+
 unicode-property-aliases-ecmascript@^1.0.4:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57"
@@ -10704,11 +11126,16 @@ utils-merge@1.0.1:
   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
   integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
 
-uuid@^3.0.1, uuid@^3.3.2, uuid@^3.4.0:
+uuid@^3.0.1, uuid@^3.3.2:
   version "3.4.0"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
   integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
 
+uuid@^7.0.2:
+  version "7.0.2"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.2.tgz#7ff5c203467e91f5e0d85cfcbaaf7d2ebbca9be6"
+  integrity sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==
+
 v8-compile-cache@2.0.3, v8-compile-cache@^2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"
@@ -10823,13 +11250,13 @@ webpack-assets-manifest@^3.1.1:
     tapable "^1.0.0"
     webpack-sources "^1.0.0"
 
-webpack-bundle-analyzer@^3.6.0:
-  version "3.6.0"
-  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.0.tgz#39b3a8f829ca044682bc6f9e011c95deb554aefd"
-  integrity sha512-orUfvVYEfBMDXgEKAKVvab5iQ2wXneIEorGNsyuOyVYpjYrI7CUOhhXNDd3huMwQ3vNNWWlGP+hzflMFYNzi2g==
+webpack-bundle-analyzer@^3.6.1:
+  version "3.6.1"
+  resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.1.tgz#bdb637c2304424f2fbff9a950c7be42a839ae73b"
+  integrity sha512-Nfd8HDwfSx1xBwC+P8QMGvHAOITxNBSvu/J/mCJvOwv+G4VWkU7zir9SSenTtyCi0LnVtmsc7G5SZo1uV+bxRw==
   dependencies:
-    acorn "^6.0.7"
-    acorn-walk "^6.1.1"
+    acorn "^7.1.1"
+    acorn-walk "^7.1.1"
     bfj "^6.1.1"
     chalk "^2.4.1"
     commander "^2.18.0"
@@ -10870,10 +11297,10 @@ webpack-dev-middleware@^3.7.2:
     range-parser "^1.2.1"
     webpack-log "^2.0.0"
 
-webpack-dev-server@^3.10.1:
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.10.1.tgz#1ff3e5cccf8e0897aa3f5909c654e623f69b1c0e"
-  integrity sha512-AGG4+XrrXn4rbZUueyNrQgO4KGnol+0wm3MPdqGLmmA+NofZl3blZQKxZ9BND6RDNuvAK9OMYClhjOSnxpWRoA==
+webpack-dev-server@^3.10.3:
+  version "3.10.3"
+  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz#f35945036813e57ef582c2420ef7b470e14d3af0"
+  integrity sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==
   dependencies:
     ansi-html "0.0.7"
     bonjour "^3.5.0"
@@ -10932,15 +11359,15 @@ webpack-sources@^1.0.0, webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-
     source-list-map "^2.0.0"
     source-map "~0.6.1"
 
-webpack@^4.41.5:
-  version "4.41.5"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.5.tgz#3210f1886bce5310e62bb97204d18c263341b77c"
-  integrity sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw==
+webpack@^4.42.1:
+  version "4.42.1"
+  resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.1.tgz#ae707baf091f5ca3ef9c38b884287cfe8f1983ef"
+  integrity sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg==
   dependencies:
-    "@webassemblyjs/ast" "1.8.5"
-    "@webassemblyjs/helper-module-context" "1.8.5"
-    "@webassemblyjs/wasm-edit" "1.8.5"
-    "@webassemblyjs/wasm-parser" "1.8.5"
+    "@webassemblyjs/ast" "1.9.0"
+    "@webassemblyjs/helper-module-context" "1.9.0"
+    "@webassemblyjs/wasm-edit" "1.9.0"
+    "@webassemblyjs/wasm-parser" "1.9.0"
     acorn "^6.2.1"
     ajv "^6.10.2"
     ajv-keywords "^3.4.1"
@@ -10952,7 +11379,7 @@ webpack@^4.41.5:
     loader-utils "^1.2.3"
     memory-fs "^0.4.1"
     micromatch "^3.1.10"
-    mkdirp "^0.5.1"
+    mkdirp "^0.5.3"
     neo-async "^2.6.1"
     node-libs-browser "^2.2.1"
     schema-utils "^1.0.0"
@@ -11024,10 +11451,17 @@ which@^2.0.1:
   dependencies:
     isexe "^2.0.0"
 
-wicg-inert@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/wicg-inert/-/wicg-inert-3.0.0.tgz#4f5797172fbf7ff01effd3839b52872e35d3cba2"
-  integrity sha512-sZsYZ8pk8y6CgDLkTxivfhLDBvZuDWTWBawU8OuDdO0Id6AOd1Gqjkvt9g9Ni7rgHIS7UbRvbLSv1z7MSJDYCA==
+which@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+  integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+  dependencies:
+    isexe "^2.0.0"
+
+wicg-inert@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/wicg-inert/-/wicg-inert-3.0.2.tgz#46d8b01142c1bda8f6fa5d78e2754ba56f6f70be"
+  integrity sha512-L2eSi1fx1M+WLLUccwzAulgK5hZtllRDvYk3UB/fe1ZqdkZS6dz718o6xfe3JUtBEJJnqvI6NF8m1bAHlg3JUg==
 
 wide-align@^1.1.0:
   version "1.1.3"
@@ -11093,6 +11527,16 @@ write-file-atomic@2.4.1:
     imurmurhash "^0.1.4"
     signal-exit "^3.0.2"
 
+write-file-atomic@^3.0.0:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8"
+  integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==
+  dependencies:
+    imurmurhash "^0.1.4"
+    is-typedarray "^1.0.0"
+    signal-exit "^3.0.2"
+    typedarray-to-buffer "^3.1.5"
+
 write@1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
@@ -11126,6 +11570,13 @@ xml-name-validator@^3.0.0:
   resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
   integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
 
+xregexp@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.3.0.tgz#7e92e73d9174a99a59743f67a4ce879a04b5ae50"
+  integrity sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==
+  dependencies:
+    "@babel/runtime-corejs3" "^7.8.3"
+
 xtend@^4.0.0, xtend@~4.0.1:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@@ -11169,10 +11620,10 @@ yargs-parser@^13.1.0, yargs-parser@^13.1.1:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
 
-yargs-parser@^16.1.0:
-  version "16.1.0"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1"
-  integrity sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==
+yargs-parser@^18.1.1:
+  version "18.1.2"
+  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1"
+  integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==
   dependencies:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
@@ -11228,10 +11679,10 @@ yargs@^13.3.0:
     y18n "^4.0.0"
     yargs-parser "^13.1.1"
 
-yargs@^15.1.0:
-  version "15.1.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219"
-  integrity sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==
+yargs@^15.3.1:
+  version "15.3.1"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b"
+  integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==
   dependencies:
     cliui "^6.0.0"
     decamelize "^1.2.0"
@@ -11243,7 +11694,7 @@ yargs@^15.1.0:
     string-width "^4.2.0"
     which-module "^2.0.0"
     y18n "^4.0.0"
-    yargs-parser "^16.1.0"
+    yargs-parser "^18.1.1"
 
 zlibjs@^0.3.1:
   version "0.3.1"